ETH Price: $2,553.01 (-0.31%)
Gas: 0.44 Gwei

Transaction Decoder

Block:
4979344 at Jan-27-2018 02:27:32 AM +UTC
Transaction Fee:
0.000544215 ETH $1.39
Gas Used:
25,915 Gas / 21 Gwei

Emitted Events:

53 TIOToken.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000002781cb66aa9db90529524c609d6c302d7a7ba5c2, 0x0000000000000000000000009abe588a2e46fc3e77f2dd46346451d99057da2f, 000000000000000000000000000000000000000000000002b5e3af16b1880000 )

Account State Difference:

  Address   Before After State Difference Code
0x2781CB66...d7a7ba5C2
0.001511624 Eth
Nonce: 1
0.000967409 Eth
Nonce: 2
0.000544215
(Nanopool)
11,879.4746477423321233 Eth11,879.4751919573321233 Eth0.000544215
0x80BC5512...b370Fa1DF

Execution Trace

TIOToken.transfer( to=0x9AbE588a2e46Fc3E77f2dd46346451D99057da2f, value=50000000000000000000 ) => ( ok=True )
  • TokenLib.d4b1770a( )
    • BasicMathLib.minus( a=50000000000000000000, b=50000000000000000000 ) => ( err=False, res=0 )
      File 1 of 3: TIOToken
      pragma solidity ^0.4.15;
      
      /**
       * Standard ERC20 token
       *
       * https://github.com/ethereum/EIPs/issues/20
       * Based on code by FirstBlood:
       * https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
       *
       * This is the token contract for trade.io, join the trading revolution.
       * It utilizes Majoolr's TokenLib library to reduce custom source code surface
       * area and increase overall security. Majoolr provides smart contract services
       * and security reviews for contract deployments in addition to working on open
       * source projects in the Ethereum community.
       * For further information: trade.io, majoolr.io
       *
       * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
       * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
       * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
       * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       */
      
      contract TIOToken {
        using TokenLib for TokenLib.TokenStorage;
      
        TokenLib.TokenStorage token;
      
        function TIOToken(address owner,
                          string name, //TradeToken
                          string symbol, //TIO
                          uint8 decimals, //18
                          uint256 initialSupply, // 555000000000000000000000000
                          bool allowMinting) //false
        {
          token.init(owner, name, symbol, decimals, initialSupply, allowMinting);
        }
      
        function owner() constant returns (address) {
          return token.owner;
        }
      
        function name() constant returns (string) {
          return token.name;
        }
      
        function symbol() constant returns (string) {
          return token.symbol;
        }
      
        function decimals() constant returns (uint8) {
          return token.decimals;
        }
      
        function initialSupply() constant returns (uint256) {
          return token.INITIAL_SUPPLY;
        }
      
        function totalSupply() constant returns (uint256) {
          return token.totalSupply;
        }
      
        function balanceOf(address who) constant returns (uint256) {
          return token.balanceOf(who);
        }
      
        function allowance(address owner, address spender) constant returns (uint256) {
          return token.allowance(owner, spender);
        }
      
        function transfer(address to, uint value) returns (bool ok) {
          return token.transfer(to, value);
        }
      
        function transferFrom(address from, address to, uint value) returns (bool ok) {
          return token.transferFrom(from, to, value);
        }
      
        function approve(address spender, uint value) returns (bool ok) {
          return token.approve(spender, value);
        }
      
        function changeOwner(address newOwner) returns (bool ok) {
          return token.changeOwner(newOwner);
        }
      
        function burnToken(uint256 amount) returns (bool ok) {
          return token.burnToken(amount);
        }
      }
      
      library TokenLib {
        using BasicMathLib for uint256;
      
        struct TokenStorage {
          mapping (address => uint256) balances;
          mapping (address => mapping (address => uint256)) allowed;
      
          string name;
          string symbol;
          uint256 totalSupply;
          uint256 INITIAL_SUPPLY;
          address owner;
          uint8 decimals;
          bool stillMinting;
        }
      
        event Transfer(address indexed from, address indexed to, uint256 value);
        event Approval(address indexed owner, address indexed spender, uint256 value);
        event OwnerChange(address from, address to);
        event Burn(address indexed burner, uint256 value);
        event MintingClosed(bool mintingClosed);
      
        /// @dev Called by the Standard Token upon creation.
        /// @param self Stored token from token contract
        /// @param _name Name of the new token
        /// @param _symbol Symbol of the new token
        /// @param _decimals Decimal places for the token represented
        /// @param _initial_supply The initial token supply
        /// @param _allowMinting True if additional tokens can be created, false otherwise
        function init(TokenStorage storage self,
                      address _owner,
                      string _name,
                      string _symbol,
                      uint8 _decimals,
                      uint256 _initial_supply,
                      bool _allowMinting)
        {
          require(self.INITIAL_SUPPLY == 0);
          self.name = _name;
          self.symbol = _symbol;
          self.totalSupply = _initial_supply;
          self.INITIAL_SUPPLY = _initial_supply;
          self.decimals = _decimals;
          self.owner = _owner;
          self.stillMinting = _allowMinting;
          self.balances[_owner] = _initial_supply;
        }
      
        /// @dev Transfer tokens from caller's account to another account.
        /// @param self Stored token from token contract
        /// @param _to Address to send tokens
        /// @param _value Number of tokens to send
        /// @return True if completed
        function transfer(TokenStorage storage self, address _to, uint256 _value) returns (bool) {
          bool err;
          uint256 balance;
      
          (err,balance) = self.balances[msg.sender].minus(_value);
          require(!err);
          self.balances[msg.sender] = balance;
          //It's not possible to overflow token supply
          self.balances[_to] = self.balances[_to] + _value;
          Transfer(msg.sender, _to, _value);
          return true;
        }
      
        /// @dev Authorized caller transfers tokens from one account to another
        /// @param self Stored token from token contract
        /// @param _from Address to send tokens from
        /// @param _to Address to send tokens to
        /// @param _value Number of tokens to send
        /// @return True if completed
        function transferFrom(TokenStorage storage self,
                              address _from,
                              address _to,
                              uint256 _value)
                              returns (bool)
        {
          var _allowance = self.allowed[_from][msg.sender];
          bool err;
          uint256 balanceOwner;
          uint256 balanceSpender;
      
          (err,balanceOwner) = self.balances[_from].minus(_value);
          require(!err);
      
          (err,balanceSpender) = _allowance.minus(_value);
          require(!err);
      
          self.balances[_from] = balanceOwner;
          self.allowed[_from][msg.sender] = balanceSpender;
          self.balances[_to] = self.balances[_to] + _value;
      
          Transfer(_from, _to, _value);
          return true;
        }
      
        /// @dev Retrieve token balance for an account
        /// @param self Stored token from token contract
        /// @param _owner Address to retrieve balance of
        /// @return balance The number of tokens in the subject account
        function balanceOf(TokenStorage storage self, address _owner) constant returns (uint256 balance) {
          return self.balances[_owner];
        }
      
        /// @dev Authorize an account to send tokens on caller's behalf
        /// @param self Stored token from token contract
        /// @param _spender Address to authorize
        /// @param _value Number of tokens authorized account may send
        /// @return True if completed
        function approve(TokenStorage storage self, address _spender, uint256 _value) returns (bool) {
          self.allowed[msg.sender][_spender] = _value;
          Approval(msg.sender, _spender, _value);
          return true;
        }
      
        /// @dev Remaining tokens third party spender has to send
        /// @param self Stored token from token contract
        /// @param _owner Address of token holder
        /// @param _spender Address of authorized spender
        /// @return remaining Number of tokens spender has left in owner's account
        function allowance(TokenStorage storage self, address _owner, address _spender) constant returns (uint256 remaining) {
          return self.allowed[_owner][_spender];
        }
      
        /// @dev Authorize third party transfer by increasing/decreasing allowed rather than setting it
        /// @param self Stored token from token contract
        /// @param _spender Address to authorize
        /// @param _valueChange Increase or decrease in number of tokens authorized account may send
        /// @param _increase True if increasing allowance, false if decreasing allowance
        /// @return True if completed
        function approveChange (TokenStorage storage self, address _spender, uint256 _valueChange, bool _increase)
                                returns (bool)
        {
          uint256 _newAllowed;
          bool err;
      
          if(_increase) {
            (err, _newAllowed) = self.allowed[msg.sender][_spender].plus(_valueChange);
            require(!err);
      
            self.allowed[msg.sender][_spender] = _newAllowed;
          } else {
            if (_valueChange > self.allowed[msg.sender][_spender]) {
              self.allowed[msg.sender][_spender] = 0;
            } else {
              _newAllowed = self.allowed[msg.sender][_spender] - _valueChange;
              self.allowed[msg.sender][_spender] = _newAllowed;
            }
          }
      
          Approval(msg.sender, _spender, _newAllowed);
          return true;
        }
      
        /// @dev Change owning address of the token contract, specifically for minting
        /// @param self Stored token from token contract
        /// @param _newOwner Address for the new owner
        /// @return True if completed
        function changeOwner(TokenStorage storage self, address _newOwner) returns (bool) {
          require((self.owner == msg.sender) && (_newOwner > 0));
      
          self.owner = _newOwner;
          OwnerChange(msg.sender, _newOwner);
          return true;
        }
      
        /// @dev Mints additional tokens, new tokens go to owner
        /// @param self Stored token from token contract
        /// @param _amount Number of tokens to mint
        /// @return True if completed
        function mintToken(TokenStorage storage self, uint256 _amount) returns (bool) {
          require((self.owner == msg.sender) && self.stillMinting);
          uint256 _newAmount;
          bool err;
      
          (err, _newAmount) = self.totalSupply.plus(_amount);
          require(!err);
      
          self.totalSupply =  _newAmount;
          self.balances[self.owner] = self.balances[self.owner] + _amount;
          Transfer(0x0, self.owner, _amount);
          return true;
        }
      
        /// @dev Permanent stops minting
        /// @param self Stored token from token contract
        /// @return True if completed
        function closeMint(TokenStorage storage self) returns (bool) {
          require(self.owner == msg.sender);
      
          self.stillMinting = false;
          MintingClosed(true);
          return true;
        }
      
        /// @dev Permanently burn tokens
        /// @param self Stored token from token contract
        /// @param _amount Amount of tokens to burn
        /// @return True if completed
        function burnToken(TokenStorage storage self, uint256 _amount) returns (bool) {
            uint256 _newBalance;
            bool err;
      
            (err, _newBalance) = self.balances[msg.sender].minus(_amount);
            require(!err);
      
            self.balances[msg.sender] = _newBalance;
            self.totalSupply = self.totalSupply - _amount;
            Burn(msg.sender, _amount);
            Transfer(msg.sender, 0x0, _amount);
            return true;
        }
      }
      
      library BasicMathLib {
        event Err(string typeErr);
      
        /// @dev Multiplies two numbers and checks for overflow before returning.
        /// Does not throw but rather logs an Err event if there is overflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is overflow
        /// @return res The product of a and b, or 0 if there is overflow
        function times(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            res := mul(a,b)
            switch or(iszero(b), eq(div(res,b), a))
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("times func overflow");
        }
      
        /// @dev Divides two numbers but checks for 0 in the divisor first.
        /// Does not throw but rather logs an Err event if 0 is in the divisor.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if `b` is 0
        /// @return res The quotient of a and b, or 0 if `b` is 0
        function dividedBy(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            switch iszero(b)
            case 0 {
              res := div(a,b)
              mstore(add(mload(0x40),0x20),res)
              return(mload(0x40),0x40)
            }
          }
          Err("tried to divide by zero");
          return (true, 0);
        }
      
        /// @dev Adds two numbers and checks for overflow before returning.
        /// Does not throw but rather logs an Err event if there is overflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is overflow
        /// @return res The sum of a and b, or 0 if there is overflow
        function plus(uint256 a, uint256 b) constant returns (bool err, uint256 res) {
          assembly{
            res := add(a,b)
            switch and(eq(sub(res,b), a), or(gt(res,b),eq(res,b)))
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("plus func overflow");
        }
      
        /// @dev Subtracts two numbers and checks for underflow before returning.
        /// Does not throw but rather logs an Err event if there is underflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is underflow
        /// @return res The difference between a and b, or 0 if there is underflow
        function minus(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            res := sub(a,b)
            switch eq(and(eq(add(res,b), a), or(lt(res,a), eq(res,a))), 1)
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("minus func underflow");
        }
      }

      File 2 of 3: TokenLib
      pragma solidity ^0.4.15;
      
      /**
       * @title TokenLib
       * @author Majoolr.io
       *
       * version 1.1.0
       * Copyright (c) 2017 Majoolr, LLC
       * The MIT License (MIT)
       * https://github.com/Majoolr/ethereum-libraries/blob/master/LICENSE
       *
       * The Token Library provides functionality to create a variety of ERC20 tokens.
       * See https://github.com/Majoolr/ethereum-contracts for an example of how to
       * create a basic ERC20 token.
       *
       * Majoolr works on open source projects in the Ethereum community with the
       * purpose of testing, documenting, and deploying reusable code onto the
       * blockchain to improve security and usability of smart contracts. Majoolr
       * also strives to educate non-profits, schools, and other community members
       * about the application of blockchain technology.
       * For further information: majoolr.io
       *
       * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
       * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
       * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
       * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       */
      
      library TokenLib {
        using BasicMathLib for uint256;
      
        struct TokenStorage {
          mapping (address => uint256) balances;
          mapping (address => mapping (address => uint256)) allowed;
      
          string name;
          string symbol;
          uint256 totalSupply;
          uint256 INITIAL_SUPPLY;
          address owner;
          uint8 decimals;
          bool stillMinting;
        }
      
        event Transfer(address indexed from, address indexed to, uint256 value);
        event Approval(address indexed owner, address indexed spender, uint256 value);
        event OwnerChange(address from, address to);
        event Burn(address indexed burner, uint256 value);
        event MintingClosed(bool mintingClosed);
      
        /// @dev Called by the Standard Token upon creation.
        /// @param self Stored token from token contract
        /// @param _name Name of the new token
        /// @param _symbol Symbol of the new token
        /// @param _decimals Decimal places for the token represented
        /// @param _initial_supply The initial token supply
        /// @param _allowMinting True if additional tokens can be created, false otherwise
        function init(TokenStorage storage self,
                      address _owner,
                      string _name,
                      string _symbol,
                      uint8 _decimals,
                      uint256 _initial_supply,
                      bool _allowMinting)
        {
          require(self.INITIAL_SUPPLY == 0);
          self.name = _name;
          self.symbol = _symbol;
          self.totalSupply = _initial_supply;
          self.INITIAL_SUPPLY = _initial_supply;
          self.decimals = _decimals;
          self.owner = _owner;
          self.stillMinting = _allowMinting;
          self.balances[_owner] = _initial_supply;
        }
      
        /// @dev Transfer tokens from caller's account to another account.
        /// @param self Stored token from token contract
        /// @param _to Address to send tokens
        /// @param _value Number of tokens to send
        /// @return True if completed
        function transfer(TokenStorage storage self, address _to, uint256 _value) returns (bool) {
          bool err;
          uint256 balance;
      
          (err,balance) = self.balances[msg.sender].minus(_value);
          require(!err);
          self.balances[msg.sender] = balance;
          //It's not possible to overflow token supply
          self.balances[_to] = self.balances[_to] + _value;
          Transfer(msg.sender, _to, _value);
          return true;
        }
      
        /// @dev Authorized caller transfers tokens from one account to another
        /// @param self Stored token from token contract
        /// @param _from Address to send tokens from
        /// @param _to Address to send tokens to
        /// @param _value Number of tokens to send
        /// @return True if completed
        function transferFrom(TokenStorage storage self,
                              address _from,
                              address _to,
                              uint256 _value)
                              returns (bool)
        {
          var _allowance = self.allowed[_from][msg.sender];
          bool err;
          uint256 balanceOwner;
          uint256 balanceSpender;
      
          (err,balanceOwner) = self.balances[_from].minus(_value);
          require(!err);
      
          (err,balanceSpender) = _allowance.minus(_value);
          require(!err);
      
          self.balances[_from] = balanceOwner;
          self.allowed[_from][msg.sender] = balanceSpender;
          self.balances[_to] = self.balances[_to] + _value;
      
          Transfer(_from, _to, _value);
          return true;
        }
      
        /// @dev Retrieve token balance for an account
        /// @param self Stored token from token contract
        /// @param _owner Address to retrieve balance of
        /// @return balance The number of tokens in the subject account
        function balanceOf(TokenStorage storage self, address _owner) constant returns (uint256 balance) {
          return self.balances[_owner];
        }
      
        /// @dev Authorize an account to send tokens on caller's behalf
        /// @param self Stored token from token contract
        /// @param _spender Address to authorize
        /// @param _value Number of tokens authorized account may send
        /// @return True if completed
        function approve(TokenStorage storage self, address _spender, uint256 _value) returns (bool) {
          self.allowed[msg.sender][_spender] = _value;
          Approval(msg.sender, _spender, _value);
          return true;
        }
      
        /// @dev Remaining tokens third party spender has to send
        /// @param self Stored token from token contract
        /// @param _owner Address of token holder
        /// @param _spender Address of authorized spender
        /// @return remaining Number of tokens spender has left in owner's account
        function allowance(TokenStorage storage self, address _owner, address _spender) constant returns (uint256 remaining) {
          return self.allowed[_owner][_spender];
        }
      
        /// @dev Authorize third party transfer by increasing/decreasing allowed rather than setting it
        /// @param self Stored token from token contract
        /// @param _spender Address to authorize
        /// @param _valueChange Increase or decrease in number of tokens authorized account may send
        /// @param _increase True if increasing allowance, false if decreasing allowance
        /// @return True if completed
        function approveChange (TokenStorage storage self, address _spender, uint256 _valueChange, bool _increase)
                                returns (bool)
        {
          uint256 _newAllowed;
          bool err;
      
          if(_increase) {
            (err, _newAllowed) = self.allowed[msg.sender][_spender].plus(_valueChange);
            require(!err);
      
            self.allowed[msg.sender][_spender] = _newAllowed;
          } else {
            if (_valueChange > self.allowed[msg.sender][_spender]) {
              self.allowed[msg.sender][_spender] = 0;
            } else {
              _newAllowed = self.allowed[msg.sender][_spender] - _valueChange;
              self.allowed[msg.sender][_spender] = _newAllowed;
            }
          }
      
          Approval(msg.sender, _spender, _newAllowed);
          return true;
        }
      
        /// @dev Change owning address of the token contract, specifically for minting
        /// @param self Stored token from token contract
        /// @param _newOwner Address for the new owner
        /// @return True if completed
        function changeOwner(TokenStorage storage self, address _newOwner) returns (bool) {
          require((self.owner == msg.sender) && (_newOwner > 0));
      
          self.owner = _newOwner;
          OwnerChange(msg.sender, _newOwner);
          return true;
        }
      
        /// @dev Mints additional tokens, new tokens go to owner
        /// @param self Stored token from token contract
        /// @param _amount Number of tokens to mint
        /// @return True if completed
        function mintToken(TokenStorage storage self, uint256 _amount) returns (bool) {
          require((self.owner == msg.sender) && self.stillMinting);
          uint256 _newAmount;
          bool err;
      
          (err, _newAmount) = self.totalSupply.plus(_amount);
          require(!err);
      
          self.totalSupply =  _newAmount;
          self.balances[self.owner] = self.balances[self.owner] + _amount;
          Transfer(0x0, self.owner, _amount);
          return true;
        }
      
        /// @dev Permanent stops minting
        /// @param self Stored token from token contract
        /// @return True if completed
        function closeMint(TokenStorage storage self) returns (bool) {
          require(self.owner == msg.sender);
      
          self.stillMinting = false;
          MintingClosed(true);
          return true;
        }
      
        /// @dev Permanently burn tokens
        /// @param self Stored token from token contract
        /// @param _amount Amount of tokens to burn
        /// @return True if completed
        function burnToken(TokenStorage storage self, uint256 _amount) returns (bool) {
            uint256 _newBalance;
            bool err;
      
            (err, _newBalance) = self.balances[msg.sender].minus(_amount);
            require(!err);
      
            self.balances[msg.sender] = _newBalance;
            self.totalSupply = self.totalSupply - _amount;
            Burn(msg.sender, _amount);
            Transfer(msg.sender, 0x0, _amount);
            return true;
        }
      }
      
      pragma solidity ^0.4.13;
      
      /**
       * @title Basic Math Library
       * @author Majoolr.io
       *
       * version 1.1.0
       * Copyright (c) 2017 Majoolr, LLC
       * The MIT License (MIT)
       * https://github.com/Majoolr/ethereum-libraries/blob/master/LICENSE
       *
       * The Basic Math Library is inspired by the Safe Math library written by
       * OpenZeppelin at https://github.com/OpenZeppelin/zeppelin-solidity/ .
       * Majoolr works on open source projects in the Ethereum community with the
       * purpose of testing, documenting, and deploying reusable code onto the
       * blockchain to improve security and usability of smart contracts. Majoolr
       * also strives to educate non-profits, schools, and other community members
       * about the application of blockchain technology.
       * For further information: majoolr.io, openzeppelin.org
       *
       * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
       * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
       * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
       * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       */
      
      library BasicMathLib {
        event Err(string typeErr);
      
        /// @dev Multiplies two numbers and checks for overflow before returning.
        /// Does not throw but rather logs an Err event if there is overflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is overflow
        /// @return res The product of a and b, or 0 if there is overflow
        function times(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            res := mul(a,b)
            switch or(iszero(b), eq(div(res,b), a))
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("times func overflow");
        }
      
        /// @dev Divides two numbers but checks for 0 in the divisor first.
        /// Does not throw but rather logs an Err event if 0 is in the divisor.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if `b` is 0
        /// @return res The quotient of a and b, or 0 if `b` is 0
        function dividedBy(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            switch iszero(b)
            case 0 {
              res := div(a,b)
              mstore(add(mload(0x40),0x20),res)
              return(mload(0x40),0x40)
            }
          }
          Err("tried to divide by zero");
          return (true, 0);
        }
      
        /// @dev Adds two numbers and checks for overflow before returning.
        /// Does not throw but rather logs an Err event if there is overflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is overflow
        /// @return res The sum of a and b, or 0 if there is overflow
        function plus(uint256 a, uint256 b) constant returns (bool err, uint256 res) {
          assembly{
            res := add(a,b)
            switch and(eq(sub(res,b), a), or(gt(res,b),eq(res,b)))
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("plus func overflow");
        }
      
        /// @dev Subtracts two numbers and checks for underflow before returning.
        /// Does not throw but rather logs an Err event if there is underflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is underflow
        /// @return res The difference between a and b, or 0 if there is underflow
        function minus(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            res := sub(a,b)
            switch eq(and(eq(add(res,b), a), or(lt(res,a), eq(res,a))), 1)
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("minus func underflow");
        }
      }

      File 3 of 3: BasicMathLib
      pragma solidity ^0.4.13;
      
      /**
       * @title Basic Math Library
       * @author Majoolr.io
       *
       * version 1.1.0
       * Copyright (c) 2017 Majoolr, LLC
       * The MIT License (MIT)
       * https://github.com/Majoolr/ethereum-libraries/blob/master/LICENSE
       *
       * The Basic Math Library is inspired by the Safe Math library written by
       * OpenZeppelin at https://github.com/OpenZeppelin/zeppelin-solidity/ .
       * Majoolr works on open source projects in the Ethereum community with the
       * purpose of testing, documenting, and deploying reusable code onto the
       * blockchain to improve security and usability of smart contracts. Majoolr
       * also strives to educate non-profits, schools, and other community members
       * about the application of blockchain technology.
       * For further information: majoolr.io, openzeppelin.org
       *
       * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
       * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
       * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
       * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       */
      
      library BasicMathLib {
        event Err(string typeErr);
      
        /// @dev Multiplies two numbers and checks for overflow before returning.
        /// Does not throw but rather logs an Err event if there is overflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is overflow
        /// @return res The product of a and b, or 0 if there is overflow
        function times(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            res := mul(a,b)
            switch or(iszero(b), eq(div(res,b), a))
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("times func overflow");
        }
      
        /// @dev Divides two numbers but checks for 0 in the divisor first.
        /// Does not throw but rather logs an Err event if 0 is in the divisor.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if `b` is 0
        /// @return res The quotient of a and b, or 0 if `b` is 0
        function dividedBy(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            switch iszero(b)
            case 0 {
              res := div(a,b)
              mstore(add(mload(0x40),0x20),res)
              return(mload(0x40),0x40)
            }
          }
          Err("tried to divide by zero");
          return (true, 0);
        }
      
        /// @dev Adds two numbers and checks for overflow before returning.
        /// Does not throw but rather logs an Err event if there is overflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is overflow
        /// @return res The sum of a and b, or 0 if there is overflow
        function plus(uint256 a, uint256 b) constant returns (bool err, uint256 res) {
          assembly{
            res := add(a,b)
            switch and(eq(sub(res,b), a), or(gt(res,b),eq(res,b)))
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("plus func overflow");
        }
      
        /// @dev Subtracts two numbers and checks for underflow before returning.
        /// Does not throw but rather logs an Err event if there is underflow.
        /// @param a First number
        /// @param b Second number
        /// @return err False normally, or true if there is underflow
        /// @return res The difference between a and b, or 0 if there is underflow
        function minus(uint256 a, uint256 b) constant returns (bool err,uint256 res) {
          assembly{
            res := sub(a,b)
            switch eq(and(eq(add(res,b), a), or(lt(res,a), eq(res,a))), 1)
            case 0 {
              err := 1
              res := 0
            }
          }
          if (err)
            Err("minus func underflow");
        }
      }