eip20.js 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. const { assertRevert } = require('../helpers/assertRevert');
  2. const EIP20Abstraction = artifacts.require('EIP20');
  3. let HST;
  4. contract('EIP20', (accounts) => {
  5. beforeEach(async () => {
  6. HST = await EIP20Abstraction.new(10000, 'Simon Bucks', 1, 'SBX', { from: accounts[0] });
  7. });
  8. it('creation: should create an initial balance of 10000 for the creator', async () => {
  9. const balance = await HST.balanceOf.call(accounts[0]);
  10. assert.strictEqual(balance.toNumber(), 10000);
  11. });
  12. it('creation: test correct setting of vanity information', async () => {
  13. const name = await HST.name.call();
  14. assert.strictEqual(name, 'Simon Bucks');
  15. const decimals = await HST.decimals.call();
  16. assert.strictEqual(decimals.toNumber(), 1);
  17. const symbol = await HST.symbol.call();
  18. assert.strictEqual(symbol, 'SBX');
  19. });
  20. it('creation: should succeed in creating over 2^256 - 1 (max) tokens', async () => {
  21. // 2^256 - 1
  22. const HST2 = await EIP20Abstraction.new('115792089237316195423570985008687907853269984665640564039457584007913129639935', 'Simon Bucks', 1, 'SBX', { from: accounts[0] });
  23. const totalSupply = await HST2.totalSupply();
  24. const match = totalSupply.equals('1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77');
  25. assert(match, 'result is not correct');
  26. });
  27. // TRANSERS
  28. // normal transfers without approvals
  29. it('transfers: ether transfer should be reversed.', async () => {
  30. const balanceBefore = await HST.balanceOf.call(accounts[0]);
  31. assert.strictEqual(balanceBefore.toNumber(), 10000);
  32. await assertRevert(new Promise((resolve, reject) => {
  33. web3.eth.sendTransaction({ from: accounts[0], to: HST.address, value: web3.toWei('10', 'Ether') }, (err, res) => {
  34. if (err) { reject(err); }
  35. resolve(res);
  36. });
  37. }));
  38. const balanceAfter = await HST.balanceOf.call(accounts[0]);
  39. assert.strictEqual(balanceAfter.toNumber(), 10000);
  40. });
  41. it('transfers: should transfer 10000 to accounts[1] with accounts[0] having 10000', async () => {
  42. await HST.transfer(accounts[1], 10000, { from: accounts[0] });
  43. const balance = await HST.balanceOf.call(accounts[1]);
  44. assert.strictEqual(balance.toNumber(), 10000);
  45. });
  46. it('transfers: should fail when trying to transfer 10001 to accounts[1] with accounts[0] having 10000', async () => {
  47. await assertRevert(HST.transfer.call(accounts[1], 10001, { from: accounts[0] }));
  48. });
  49. it('transfers: should handle zero-transfers normally', async () => {
  50. assert(await HST.transfer.call(accounts[1], 0, { from: accounts[0] }), 'zero-transfer has failed');
  51. });
  52. // NOTE: testing uint256 wrapping is impossible since you can't supply > 2^256 -1
  53. // todo: transfer max amounts
  54. // APPROVALS
  55. it('approvals: msg.sender should approve 100 to accounts[1]', async () => {
  56. await HST.approve(accounts[1], 100, { from: accounts[0] });
  57. const allowance = await HST.allowance.call(accounts[0], accounts[1]);
  58. assert.strictEqual(allowance.toNumber(), 100);
  59. });
  60. // bit overkill. But is for testing a bug
  61. it('approvals: msg.sender approves accounts[1] of 100 & withdraws 20 once.', async () => {
  62. const balance0 = await HST.balanceOf.call(accounts[0]);
  63. assert.strictEqual(balance0.toNumber(), 10000);
  64. await HST.approve(accounts[1], 100, { from: accounts[0] }); // 100
  65. const balance2 = await HST.balanceOf.call(accounts[2]);
  66. assert.strictEqual(balance2.toNumber(), 0, 'balance2 not correct');
  67. await HST.transferFrom.call(accounts[0], accounts[2], 20, { from: accounts[1] });
  68. await HST.allowance.call(accounts[0], accounts[1]);
  69. await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] }); // -20
  70. const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
  71. assert.strictEqual(allowance01.toNumber(), 80); // =80
  72. const balance22 = await HST.balanceOf.call(accounts[2]);
  73. assert.strictEqual(balance22.toNumber(), 20);
  74. const balance02 = await HST.balanceOf.call(accounts[0]);
  75. assert.strictEqual(balance02.toNumber(), 9980);
  76. });
  77. // should approve 100 of msg.sender & withdraw 50, twice. (should succeed)
  78. it('approvals: msg.sender approves accounts[1] of 100 & withdraws 20 twice.', async () => {
  79. await HST.approve(accounts[1], 100, { from: accounts[0] });
  80. const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
  81. assert.strictEqual(allowance01.toNumber(), 100);
  82. await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] });
  83. const allowance012 = await HST.allowance.call(accounts[0], accounts[1]);
  84. assert.strictEqual(allowance012.toNumber(), 80);
  85. const balance2 = await HST.balanceOf.call(accounts[2]);
  86. assert.strictEqual(balance2.toNumber(), 20);
  87. const balance0 = await HST.balanceOf.call(accounts[0]);
  88. assert.strictEqual(balance0.toNumber(), 9980);
  89. // FIRST tx done.
  90. // onto next.
  91. await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] });
  92. const allowance013 = await HST.allowance.call(accounts[0], accounts[1]);
  93. assert.strictEqual(allowance013.toNumber(), 60);
  94. const balance22 = await HST.balanceOf.call(accounts[2]);
  95. assert.strictEqual(balance22.toNumber(), 40);
  96. const balance02 = await HST.balanceOf.call(accounts[0]);
  97. assert.strictEqual(balance02.toNumber(), 9960);
  98. });
  99. // should approve 100 of msg.sender & withdraw 50 & 60 (should fail).
  100. it('approvals: msg.sender approves accounts[1] of 100 & withdraws 50 & 60 (2nd tx should fail)', async () => {
  101. await HST.approve(accounts[1], 100, { from: accounts[0] });
  102. const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
  103. assert.strictEqual(allowance01.toNumber(), 100);
  104. await HST.transferFrom(accounts[0], accounts[2], 50, { from: accounts[1] });
  105. const allowance012 = await HST.allowance.call(accounts[0], accounts[1]);
  106. assert.strictEqual(allowance012.toNumber(), 50);
  107. const balance2 = await HST.balanceOf.call(accounts[2]);
  108. assert.strictEqual(balance2.toNumber(), 50);
  109. const balance0 = await HST.balanceOf.call(accounts[0]);
  110. assert.strictEqual(balance0.toNumber(), 9950);
  111. // FIRST tx done.
  112. // onto next.
  113. await assertRevert(HST.transferFrom.call(accounts[0], accounts[2], 60, { from: accounts[1] }));
  114. });
  115. it('approvals: attempt withdrawal from account with no allowance (should fail)', async () => {
  116. await assertRevert(HST.transferFrom.call(accounts[0], accounts[2], 60, { from: accounts[1] }));
  117. });
  118. it('approvals: allow accounts[1] 100 to withdraw from accounts[0]. Withdraw 60 and then approve 0 & attempt transfer.', async () => {
  119. await HST.approve(accounts[1], 100, { from: accounts[0] });
  120. await HST.transferFrom(accounts[0], accounts[2], 60, { from: accounts[1] });
  121. await HST.approve(accounts[1], 0, { from: accounts[0] });
  122. await assertRevert(HST.transferFrom.call(accounts[0], accounts[2], 10, { from: accounts[1] }));
  123. });
  124. it('approvals: approve max (2^256 - 1)', async () => {
  125. await HST.approve(accounts[1], '115792089237316195423570985008687907853269984665640564039457584007913129639935', { from: accounts[0] });
  126. const allowance = await HST.allowance(accounts[0], accounts[1]);
  127. assert(allowance.equals('1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77'));
  128. });
  129. // should approve max of msg.sender & withdraw 20 without changing allowance (should succeed).
  130. it('approvals: msg.sender approves accounts[1] of max (2^256 - 1) & withdraws 20', async () => {
  131. const balance0 = await HST.balanceOf.call(accounts[0]);
  132. assert.strictEqual(balance0.toNumber(), 10000);
  133. const max = '1.15792089237316195423570985008687907853269984665640564039457584007913129639935e+77';
  134. await HST.approve(accounts[1], max, { from: accounts[0] });
  135. const balance2 = await HST.balanceOf.call(accounts[2]);
  136. assert.strictEqual(balance2.toNumber(), 0, 'balance2 not correct');
  137. await HST.transferFrom(accounts[0], accounts[2], 20, { from: accounts[1] });
  138. const allowance01 = await HST.allowance.call(accounts[0], accounts[1]);
  139. assert(allowance01.equals(max));
  140. const balance22 = await HST.balanceOf.call(accounts[2]);
  141. assert.strictEqual(balance22.toNumber(), 20);
  142. const balance02 = await HST.balanceOf.call(accounts[0]);
  143. assert.strictEqual(balance02.toNumber(), 9980);
  144. });
  145. /* eslint-disable no-underscore-dangle */
  146. it('events: should fire Transfer event properly', async () => {
  147. const res = await HST.transfer(accounts[1], '2666', { from: accounts[0] });
  148. const transferLog = res.logs.find(element => element.event.match('Transfer'));
  149. assert.strictEqual(transferLog.args._from, accounts[0]);
  150. assert.strictEqual(transferLog.args._to, accounts[1]);
  151. assert.strictEqual(transferLog.args._value.toString(), '2666');
  152. });
  153. it('events: should fire Transfer event normally on a zero transfer', async () => {
  154. const res = await HST.transfer(accounts[1], '0', { from: accounts[0] });
  155. const transferLog = res.logs.find(element => element.event.match('Transfer'));
  156. assert.strictEqual(transferLog.args._from, accounts[0]);
  157. assert.strictEqual(transferLog.args._to, accounts[1]);
  158. assert.strictEqual(transferLog.args._value.toString(), '0');
  159. });
  160. it('events: should fire Approval event properly', async () => {
  161. const res = await HST.approve(accounts[1], '2666', { from: accounts[0] });
  162. const approvalLog = res.logs.find(element => element.event.match('Approval'));
  163. assert.strictEqual(approvalLog.args._owner, accounts[0]);
  164. assert.strictEqual(approvalLog.args._spender, accounts[1]);
  165. assert.strictEqual(approvalLog.args._value.toString(), '2666');
  166. });
  167. });