diff --git a/contracts/test-helpers/BasicTokenMock.sol b/contracts/test-helpers/BasicTokenMock.sol new file mode 100644 index 000000000..9f19e47ea --- /dev/null +++ b/contracts/test-helpers/BasicTokenMock.sol @@ -0,0 +1,12 @@ +pragma solidity ^0.4.4; +import '../token/BasicToken.sol'; + +// mock class using BasicToken +contract BasicTokenMock is BasicToken { + + function BasicTokenMock(address initialAccount, uint initialBalance) { + balances[initialAccount] = initialBalance; + totalSupply = initialBalance; + } + +} diff --git a/contracts/test-helpers/StandardTokenMock.sol b/contracts/test-helpers/StandardTokenMock.sol index 55a9fc38e..5b222be9a 100644 --- a/contracts/test-helpers/StandardTokenMock.sol +++ b/contracts/test-helpers/StandardTokenMock.sol @@ -1,5 +1,5 @@ pragma solidity ^0.4.4; -import '../StandardToken.sol'; +import '../token/StandardToken.sol'; // mock class using StandardToken contract StandardTokenMock is StandardToken { diff --git a/contracts/token/BasicToken.sol b/contracts/token/BasicToken.sol new file mode 100644 index 000000000..6e6a747c2 --- /dev/null +++ b/contracts/token/BasicToken.sol @@ -0,0 +1,28 @@ +pragma solidity ^0.4.4; + +import './ERC20Basic.sol'; +import '../SafeMath.sol'; + +/** + * Basic token + * Basic version of StandardToken, with no allowances + */ +contract BasicToken is ERC20Basic, SafeMath { + + mapping(address => uint) balances; + + function transfer(address _to, uint _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 balanceOf(address _owner) constant returns (uint balance) { + return balances[_owner]; + } + +} diff --git a/contracts/token/CrowdsaleToken.sol b/contracts/token/CrowdsaleToken.sol index 1172efe5d..ba3100cbc 100644 --- a/contracts/token/CrowdsaleToken.sol +++ b/contracts/token/CrowdsaleToken.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.4; -import "../StandardToken.sol"; +import "./StandardToken.sol"; /* * Simple ERC20 Token example, with crowdsale token creation diff --git a/contracts/ERC20.sol b/contracts/token/ERC20.sol similarity index 100% rename from contracts/ERC20.sol rename to contracts/token/ERC20.sol diff --git a/contracts/token/ERC20Basic.sol b/contracts/token/ERC20Basic.sol new file mode 100644 index 000000000..8128991e4 --- /dev/null +++ b/contracts/token/ERC20Basic.sol @@ -0,0 +1,9 @@ +pragma solidity ^0.4.4; + + +contract ERC20Basic { + uint public totalSupply; + function balanceOf(address who) constant returns (uint); + function transfer(address to, uint value) returns (bool ok); + event Transfer(address indexed from, address indexed to, uint value); +} diff --git a/contracts/token/SimpleToken.sol b/contracts/token/SimpleToken.sol index 3b115a6fd..fc7efd0d6 100644 --- a/contracts/token/SimpleToken.sol +++ b/contracts/token/SimpleToken.sol @@ -1,6 +1,6 @@ pragma solidity ^0.4.4; -import "../StandardToken.sol"; +import "./StandardToken.sol"; /* * Very simple ERC20 Token example, where all tokens are pre-assigned diff --git a/contracts/StandardToken.sol b/contracts/token/StandardToken.sol similarity index 98% rename from contracts/StandardToken.sol rename to contracts/token/StandardToken.sol index 9fe80f7d8..f2a2138bd 100644 --- a/contracts/StandardToken.sol +++ b/contracts/token/StandardToken.sol @@ -1,7 +1,7 @@ pragma solidity ^0.4.4; import './ERC20.sol'; -import './SafeMath.sol'; +import '../SafeMath.sol'; /** * ERC20 token diff --git a/test/BasicToken.js b/test/BasicToken.js new file mode 100644 index 000000000..12b411c41 --- /dev/null +++ b/test/BasicToken.js @@ -0,0 +1,49 @@ +contract('BasicToken', function(accounts) { + + it("should return the correct totalSupply after construction", function(done) { + return BasicTokenMock.new(accounts[0], 100) + .then(function(token) { + return token.totalSupply(); + }) + .then(function(totalSupply) { + assert.equal(totalSupply, 100); + }) + .then(done); + }) + + it("should return correct balances after transfer", function(done) { + var token; + return BasicTokenMock.new(accounts[0], 100) + .then(function(_token) { + token = _token; + return token.transfer(accounts[1], 100); + }) + .then(function() { + return token.balanceOf(accounts[0]); + }) + .then(function(balance) { + assert.equal(balance, 0); + }) + .then(function() { + return token.balanceOf(accounts[1]); + }) + .then(function(balance) { + assert.equal(balance, 100); + }) + .then(done); + }); + + it("should throw an error when trying to transfer more than balance", function(done) { + var token; + return BasicTokenMock.new(accounts[0], 100) + .then(function(_token) { + token = _token; + return token.transfer(accounts[1], 101); + }) + .catch(function(error) { + if (error.message.search('invalid JUMP') == -1) throw error + }) + .then(done); + }); + +});