diff --git a/contracts/ERC20.sol b/contracts/ERC20.sol index 2ed37f73e..157bd9077 100644 --- a/contracts/ERC20.sol +++ b/contracts/ERC20.sol @@ -1,4 +1,8 @@ pragma solidity ^0.4.0; + + +// see https://github.com/ethereum/EIPs/issues/20 + contract ERC20 { function totalSupply() constant returns (uint); function balanceOf(address who) constant returns (uint); diff --git a/contracts/SafeMath.sol b/contracts/SafeMath.sol new file mode 100644 index 000000000..2d4bebf77 --- /dev/null +++ b/contracts/SafeMath.sol @@ -0,0 +1,28 @@ +pragma solidity ^0.4.0; + +/** + * Math operations with safety checks + */ +contract SafeMath { + function safeMul(uint a, uint b) internal returns (uint) { + uint c = a * b; + assert(a == 0 || c / a == b); + return c; + } + + function safeSub(uint a, uint b) internal returns (uint) { + assert(b <= a); + return a - b; + } + + function safeAdd(uint a, uint b) internal returns (uint) { + uint c = a + b; + assert(c>=a && c>=b); + return c; + } + + function assert(bool assertion) internal { + if (!assertion) throw; + } +} + diff --git a/contracts/StandardToken.sol b/contracts/StandardToken.sol new file mode 100644 index 000000000..3d3c3e1d0 --- /dev/null +++ b/contracts/StandardToken.sol @@ -0,0 +1,57 @@ +pragma solidity ^0.4.0; + +import './ERC20.sol'; +import './SafeMath.sol'; + +/** + * 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 + */ +contract StandardToken is ERC20, SafeMath { + + mapping(address => uint256) balances; + mapping (address => mapping (address => uint256)) allowed; + uint256 public totalSupply; + + function transfer(address _to, uint256 _value) returns (bool success) { + if (balances[msg.sender] < _value) { + throw; + } + balances[msg.sender] = safeSub(balances[msg.sender], _value); + balances[_to] = safeAdd(balances[_to], _value); + Transfer(msg.sender, _to, _value); + return true; + } + + function transferFrom(address _from, address _to, uint256 _value) returns (bool success) { + var _allowance = allowed[_from][msg.sender]; + if (balances[_from] < _value || + _allowance < _value)) { + throw; + } + + balances[_to] = safeAdd(balances[_to], _value); + balances[_from] = safeSub(balances[_from], _value); + allowed[_from][msg.sender] = safeSub(_allowance, _value); + Transfer(_from, _to, _value); + return true; + } + + function balanceOf(address _owner) constant returns (uint256 balance) { + return balances[_owner]; + } + + function approve(address _spender, uint256 _value) returns (bool success) { + allowed[msg.sender][_spender] = _value; + Approval(msg.sender, _spender, _value); + return true; + } + + function allowance(address _owner, address _spender) constant returns (uint256 remaining) { + return allowed[_owner][_spender]; + } + +} diff --git a/contracts/Token.sol b/contracts/Token.sol deleted file mode 100644 index 5e22ec2eb..000000000 --- a/contracts/Token.sol +++ /dev/null @@ -1,73 +0,0 @@ -pragma solidity ^0.4.0; -// Source: https://github.com/nexusdev/erc20 -// Flat file implementation of `dappsys/token/base.sol::DSTokenBase` - -// Everything throws instead of returning false on failure. -import './ERC20.sol'; - -contract Token is ERC20 { - - mapping( address => uint ) _balances; - mapping( address => mapping( address => uint ) ) _approvals; - uint _supply; - - function Token( uint initial_balance ) { - _balances[msg.sender] = initial_balance; - _supply = initial_balance; - } - - function totalSupply() constant returns (uint supply) { - return _supply; - } - - function balanceOf( address who ) constant returns (uint value) { - return _balances[who]; - } - - function transfer( address to, uint value) returns (bool ok) { - if( _balances[msg.sender] < value ) { - throw; - } - if( !safeToAdd(_balances[to], value) ) { - throw; - } - _balances[msg.sender] -= value; - _balances[to] += value; - Transfer( msg.sender, to, value ); - return true; - } - - function transferFrom( address from, address to, uint value) returns (bool ok) { - // if you don't have enough balance, throw - if( _balances[from] < value ) { - throw; - } - // if you don't have approval, throw - if( _approvals[from][msg.sender] < value ) { - throw; - } - if( !safeToAdd(_balances[to], value) ) { - throw; - } - // transfer and return true - _approvals[from][msg.sender] -= value; - _balances[from] -= value; - _balances[to] += value; - Transfer( from, to, value ); - return true; - } - - function approve(address spender, uint value) returns (bool ok) { - _approvals[msg.sender][spender] = value; - Approval( msg.sender, spender, value ); - return true; - } - - function allowance(address owner, address spender) constant returns (uint _allowance) { - return _approvals[owner][spender]; - } - - function safeToAdd(uint a, uint b) internal returns (bool) { - return (a + b >= a); - } -}