StandardToken.test.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. import assertRevert from '../../helpers/assertRevert';
  2. const StandardTokenMock = artifacts.require('StandardTokenMock');
  3. contract('StandardToken', function ([_, owner, recipient, anotherAccount]) {
  4. const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
  5. beforeEach(async function () {
  6. this.token = await StandardTokenMock.new(owner, 100);
  7. });
  8. describe('total supply', function () {
  9. it('returns the total amount of tokens', async function () {
  10. const totalSupply = await this.token.totalSupply();
  11. assert.equal(totalSupply, 100);
  12. });
  13. });
  14. describe('balanceOf', function () {
  15. describe('when the requested account has no tokens', function () {
  16. it('returns zero', async function () {
  17. const balance = await this.token.balanceOf(anotherAccount);
  18. assert.equal(balance, 0);
  19. });
  20. });
  21. describe('when the requested account has some tokens', function () {
  22. it('returns the total amount of tokens', async function () {
  23. const balance = await this.token.balanceOf(owner);
  24. assert.equal(balance, 100);
  25. });
  26. });
  27. });
  28. describe('transfer', function () {
  29. describe('when the recipient is not the zero address', function () {
  30. const to = recipient;
  31. describe('when the sender does not have enough balance', function () {
  32. const amount = 101;
  33. it('reverts', async function () {
  34. await assertRevert(this.token.transfer(to, amount, { from: owner }));
  35. });
  36. });
  37. describe('when the sender has enough balance', function () {
  38. const amount = 100;
  39. it('transfers the requested amount', async function () {
  40. await this.token.transfer(to, amount, { from: owner });
  41. const senderBalance = await this.token.balanceOf(owner);
  42. assert.equal(senderBalance, 0);
  43. const recipientBalance = await this.token.balanceOf(to);
  44. assert.equal(recipientBalance, amount);
  45. });
  46. it('emits a transfer event', async function () {
  47. const { logs } = await this.token.transfer(to, amount, { from: owner });
  48. assert.equal(logs.length, 1);
  49. assert.equal(logs[0].event, 'Transfer');
  50. assert.equal(logs[0].args.from, owner);
  51. assert.equal(logs[0].args.to, to);
  52. assert(logs[0].args.value.eq(amount));
  53. });
  54. });
  55. });
  56. describe('when the recipient is the zero address', function () {
  57. const to = ZERO_ADDRESS;
  58. it('reverts', async function () {
  59. await assertRevert(this.token.transfer(to, 100, { from: owner }));
  60. });
  61. });
  62. });
  63. describe('approve', function () {
  64. describe('when the spender is not the zero address', function () {
  65. const spender = recipient;
  66. describe('when the sender has enough balance', function () {
  67. const amount = 100;
  68. it('emits an approval event', async function () {
  69. const { logs } = await this.token.approve(spender, amount, { from: owner });
  70. assert.equal(logs.length, 1);
  71. assert.equal(logs[0].event, 'Approval');
  72. assert.equal(logs[0].args.owner, owner);
  73. assert.equal(logs[0].args.spender, spender);
  74. assert(logs[0].args.value.eq(amount));
  75. });
  76. describe('when there was no approved amount before', function () {
  77. it('approves the requested amount', async function () {
  78. await this.token.approve(spender, amount, { from: owner });
  79. const allowance = await this.token.allowance(owner, spender);
  80. assert.equal(allowance, amount);
  81. });
  82. });
  83. describe('when the spender had an approved amount', function () {
  84. beforeEach(async function () {
  85. await this.token.approve(spender, 1, { from: owner });
  86. });
  87. it('approves the requested amount and replaces the previous one', async function () {
  88. await this.token.approve(spender, amount, { from: owner });
  89. const allowance = await this.token.allowance(owner, spender);
  90. assert.equal(allowance, amount);
  91. });
  92. });
  93. });
  94. describe('when the sender does not have enough balance', function () {
  95. const amount = 101;
  96. it('emits an approval event', async function () {
  97. const { logs } = await this.token.approve(spender, amount, { from: owner });
  98. assert.equal(logs.length, 1);
  99. assert.equal(logs[0].event, 'Approval');
  100. assert.equal(logs[0].args.owner, owner);
  101. assert.equal(logs[0].args.spender, spender);
  102. assert(logs[0].args.value.eq(amount));
  103. });
  104. describe('when there was no approved amount before', function () {
  105. it('approves the requested amount', async function () {
  106. await this.token.approve(spender, amount, { from: owner });
  107. const allowance = await this.token.allowance(owner, spender);
  108. assert.equal(allowance, amount);
  109. });
  110. });
  111. describe('when the spender had an approved amount', function () {
  112. beforeEach(async function () {
  113. await this.token.approve(spender, 1, { from: owner });
  114. });
  115. it('approves the requested amount and replaces the previous one', async function () {
  116. await this.token.approve(spender, amount, { from: owner });
  117. const allowance = await this.token.allowance(owner, spender);
  118. assert.equal(allowance, amount);
  119. });
  120. });
  121. });
  122. });
  123. describe('when the spender is the zero address', function () {
  124. const amount = 100;
  125. const spender = ZERO_ADDRESS;
  126. it('approves the requested amount', async function () {
  127. await this.token.approve(spender, amount, { from: owner });
  128. const allowance = await this.token.allowance(owner, spender);
  129. assert.equal(allowance, amount);
  130. });
  131. it('emits an approval event', async function () {
  132. const { logs } = await this.token.approve(spender, amount, { from: owner });
  133. assert.equal(logs.length, 1);
  134. assert.equal(logs[0].event, 'Approval');
  135. assert.equal(logs[0].args.owner, owner);
  136. assert.equal(logs[0].args.spender, spender);
  137. assert(logs[0].args.value.eq(amount));
  138. });
  139. });
  140. });
  141. describe('transfer from', function () {
  142. const spender = recipient;
  143. describe('when the recipient is not the zero address', function () {
  144. const to = anotherAccount;
  145. describe('when the spender has enough approved balance', function () {
  146. beforeEach(async function () {
  147. await this.token.approve(spender, 100, { from: owner });
  148. });
  149. describe('when the owner has enough balance', function () {
  150. const amount = 100;
  151. it('transfers the requested amount', async function () {
  152. await this.token.transferFrom(owner, to, amount, { from: spender });
  153. const senderBalance = await this.token.balanceOf(owner);
  154. assert.equal(senderBalance, 0);
  155. const recipientBalance = await this.token.balanceOf(to);
  156. assert.equal(recipientBalance, amount);
  157. });
  158. it('decreases the spender allowance', async function () {
  159. await this.token.transferFrom(owner, to, amount, { from: spender });
  160. const allowance = await this.token.allowance(owner, spender);
  161. assert(allowance.eq(0));
  162. });
  163. it('emits a transfer event', async function () {
  164. const { logs } = await this.token.transferFrom(owner, to, amount, { from: spender });
  165. assert.equal(logs.length, 1);
  166. assert.equal(logs[0].event, 'Transfer');
  167. assert.equal(logs[0].args.from, owner);
  168. assert.equal(logs[0].args.to, to);
  169. assert(logs[0].args.value.eq(amount));
  170. });
  171. });
  172. describe('when the owner does not have enough balance', function () {
  173. const amount = 101;
  174. it('reverts', async function () {
  175. await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender }));
  176. });
  177. });
  178. });
  179. describe('when the spender does not have enough approved balance', function () {
  180. beforeEach(async function () {
  181. await this.token.approve(spender, 99, { from: owner });
  182. });
  183. describe('when the owner has enough balance', function () {
  184. const amount = 100;
  185. it('reverts', async function () {
  186. await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender }));
  187. });
  188. });
  189. describe('when the owner does not have enough balance', function () {
  190. const amount = 101;
  191. it('reverts', async function () {
  192. await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender }));
  193. });
  194. });
  195. });
  196. });
  197. describe('when the recipient is the zero address', function () {
  198. const amount = 100;
  199. const to = ZERO_ADDRESS;
  200. beforeEach(async function () {
  201. await this.token.approve(spender, amount, { from: owner });
  202. });
  203. it('reverts', async function () {
  204. await assertRevert(this.token.transferFrom(owner, to, amount, { from: spender }));
  205. });
  206. });
  207. });
  208. describe('decrease approval', function () {
  209. describe('when the spender is not the zero address', function () {
  210. const spender = recipient;
  211. describe('when the sender has enough balance', function () {
  212. const amount = 100;
  213. it('emits an approval event', async function () {
  214. const { logs } = await this.token.decreaseApproval(spender, amount, { from: owner });
  215. assert.equal(logs.length, 1);
  216. assert.equal(logs[0].event, 'Approval');
  217. assert.equal(logs[0].args.owner, owner);
  218. assert.equal(logs[0].args.spender, spender);
  219. assert(logs[0].args.value.eq(0));
  220. });
  221. describe('when there was no approved amount before', function () {
  222. it('keeps the allowance to zero', async function () {
  223. await this.token.decreaseApproval(spender, amount, { from: owner });
  224. const allowance = await this.token.allowance(owner, spender);
  225. assert.equal(allowance, 0);
  226. });
  227. });
  228. describe('when the spender had an approved amount', function () {
  229. beforeEach(async function () {
  230. await this.token.approve(spender, amount + 1, { from: owner });
  231. });
  232. it('decreases the spender allowance subtracting the requested amount', async function () {
  233. await this.token.decreaseApproval(spender, amount, { from: owner });
  234. const allowance = await this.token.allowance(owner, spender);
  235. assert.equal(allowance, 1);
  236. });
  237. });
  238. });
  239. describe('when the sender does not have enough balance', function () {
  240. const amount = 101;
  241. it('emits an approval event', async function () {
  242. const { logs } = await this.token.decreaseApproval(spender, amount, { from: owner });
  243. assert.equal(logs.length, 1);
  244. assert.equal(logs[0].event, 'Approval');
  245. assert.equal(logs[0].args.owner, owner);
  246. assert.equal(logs[0].args.spender, spender);
  247. assert(logs[0].args.value.eq(0));
  248. });
  249. describe('when there was no approved amount before', function () {
  250. it('keeps the allowance to zero', async function () {
  251. await this.token.decreaseApproval(spender, amount, { from: owner });
  252. const allowance = await this.token.allowance(owner, spender);
  253. assert.equal(allowance, 0);
  254. });
  255. });
  256. describe('when the spender had an approved amount', function () {
  257. beforeEach(async function () {
  258. await this.token.approve(spender, amount + 1, { from: owner });
  259. });
  260. it('decreases the spender allowance subtracting the requested amount', async function () {
  261. await this.token.decreaseApproval(spender, amount, { from: owner });
  262. const allowance = await this.token.allowance(owner, spender);
  263. assert.equal(allowance, 1);
  264. });
  265. });
  266. });
  267. });
  268. describe('when the spender is the zero address', function () {
  269. const amount = 100;
  270. const spender = ZERO_ADDRESS;
  271. it('decreases the requested amount', async function () {
  272. await this.token.decreaseApproval(spender, amount, { from: owner });
  273. const allowance = await this.token.allowance(owner, spender);
  274. assert.equal(allowance, 0);
  275. });
  276. it('emits an approval event', async function () {
  277. const { logs } = await this.token.decreaseApproval(spender, amount, { from: owner });
  278. assert.equal(logs.length, 1);
  279. assert.equal(logs[0].event, 'Approval');
  280. assert.equal(logs[0].args.owner, owner);
  281. assert.equal(logs[0].args.spender, spender);
  282. assert(logs[0].args.value.eq(0));
  283. });
  284. });
  285. });
  286. describe('increase approval', function () {
  287. const amount = 100;
  288. describe('when the spender is not the zero address', function () {
  289. const spender = recipient;
  290. describe('when the sender has enough balance', function () {
  291. it('emits an approval event', async function () {
  292. const { logs } = await this.token.increaseApproval(spender, amount, { from: owner });
  293. assert.equal(logs.length, 1);
  294. assert.equal(logs[0].event, 'Approval');
  295. assert.equal(logs[0].args.owner, owner);
  296. assert.equal(logs[0].args.spender, spender);
  297. assert(logs[0].args.value.eq(amount));
  298. });
  299. describe('when there was no approved amount before', function () {
  300. it('approves the requested amount', async function () {
  301. await this.token.increaseApproval(spender, amount, { from: owner });
  302. const allowance = await this.token.allowance(owner, spender);
  303. assert.equal(allowance, amount);
  304. });
  305. });
  306. describe('when the spender had an approved amount', function () {
  307. beforeEach(async function () {
  308. await this.token.approve(spender, 1, { from: owner });
  309. });
  310. it('increases the spender allowance adding the requested amount', async function () {
  311. await this.token.increaseApproval(spender, amount, { from: owner });
  312. const allowance = await this.token.allowance(owner, spender);
  313. assert.equal(allowance, amount + 1);
  314. });
  315. });
  316. });
  317. describe('when the sender does not have enough balance', function () {
  318. const amount = 101;
  319. it('emits an approval event', async function () {
  320. const { logs } = await this.token.increaseApproval(spender, amount, { from: owner });
  321. assert.equal(logs.length, 1);
  322. assert.equal(logs[0].event, 'Approval');
  323. assert.equal(logs[0].args.owner, owner);
  324. assert.equal(logs[0].args.spender, spender);
  325. assert(logs[0].args.value.eq(amount));
  326. });
  327. describe('when there was no approved amount before', function () {
  328. it('approves the requested amount', async function () {
  329. await this.token.increaseApproval(spender, amount, { from: owner });
  330. const allowance = await this.token.allowance(owner, spender);
  331. assert.equal(allowance, amount);
  332. });
  333. });
  334. describe('when the spender had an approved amount', function () {
  335. beforeEach(async function () {
  336. await this.token.approve(spender, 1, { from: owner });
  337. });
  338. it('increases the spender allowance adding the requested amount', async function () {
  339. await this.token.increaseApproval(spender, amount, { from: owner });
  340. const allowance = await this.token.allowance(owner, spender);
  341. assert.equal(allowance, amount + 1);
  342. });
  343. });
  344. });
  345. });
  346. describe('when the spender is the zero address', function () {
  347. const spender = ZERO_ADDRESS;
  348. it('approves the requested amount', async function () {
  349. await this.token.increaseApproval(spender, amount, { from: owner });
  350. const allowance = await this.token.allowance(owner, spender);
  351. assert.equal(allowance, amount);
  352. });
  353. it('emits an approval event', async function () {
  354. const { logs } = await this.token.increaseApproval(spender, amount, { from: owner });
  355. assert.equal(logs.length, 1);
  356. assert.equal(logs[0].event, 'Approval');
  357. assert.equal(logs[0].args.owner, owner);
  358. assert.equal(logs[0].args.spender, spender);
  359. assert(logs[0].args.value.eq(amount));
  360. });
  361. });
  362. });
  363. });