Transaction Hash:
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 | ||
---|---|---|---|---|---|
0x2781CB66...d7a7ba5C2 |
0.001511624 Eth
Nonce: 1
|
0.000967409 Eth
Nonce: 2
| 0.000544215 | ||
0x52bc44d5...b7d7bE3b5
Miner
| (Nanopool) | 11,879.4746477423321233 Eth | 11,879.4751919573321233 Eth | 0.000544215 | |
0x80BC5512...b370Fa1DF |
Execution Trace
transfer[TIOToken (ln:73)]
transfer[TIOToken (ln:74)]
File 1 of 3: TIOToken
File 2 of 3: TokenLib
File 3 of 3: BasicMathLib
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"); } }