StandardToken.test.js 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. const { assertRevert } = require('../../helpers/assertRevert');
  2. const StandardToken = artifacts.require('StandardTokenMock');
  3. contract('StandardToken', function ([_, owner, recipient, anotherAccount]) {
  4. const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
  5. beforeEach(async function () {
  6. this.token = await StandardToken.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. const approvedAmount = amount;
  230. beforeEach(async function () {
  231. await this.token.approve(spender, approvedAmount, { from: owner });
  232. });
  233. it('decreases the spender allowance subtracting the requested amount', async function () {
  234. await this.token.decreaseApproval(spender, approvedAmount - 5, { from: owner });
  235. const allowance = await this.token.allowance(owner, spender);
  236. assert.equal(allowance, 5);
  237. });
  238. it('sets the allowance to zero when all allowance is removed', async function () {
  239. await this.token.decreaseApproval(spender, approvedAmount, { from: owner });
  240. const allowance = await this.token.allowance(owner, spender);
  241. assert.equal(allowance, 0);
  242. });
  243. it('sets the allowance to zero when more than the full allowance is removed', async function () {
  244. await this.token.decreaseApproval(spender, approvedAmount + 5, { from: owner });
  245. const allowance = await this.token.allowance(owner, spender);
  246. assert.equal(allowance, 0);
  247. });
  248. });
  249. });
  250. describe('when the sender does not have enough balance', function () {
  251. const amount = 101;
  252. it('emits an approval event', async function () {
  253. const { logs } = await this.token.decreaseApproval(spender, amount, { from: owner });
  254. assert.equal(logs.length, 1);
  255. assert.equal(logs[0].event, 'Approval');
  256. assert.equal(logs[0].args.owner, owner);
  257. assert.equal(logs[0].args.spender, spender);
  258. assert(logs[0].args.value.eq(0));
  259. });
  260. describe('when there was no approved amount before', function () {
  261. it('keeps the allowance to zero', async function () {
  262. await this.token.decreaseApproval(spender, amount, { from: owner });
  263. const allowance = await this.token.allowance(owner, spender);
  264. assert.equal(allowance, 0);
  265. });
  266. });
  267. describe('when the spender had an approved amount', function () {
  268. beforeEach(async function () {
  269. await this.token.approve(spender, amount + 1, { from: owner });
  270. });
  271. it('decreases the spender allowance subtracting 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, 1);
  275. });
  276. });
  277. });
  278. });
  279. describe('when the spender is the zero address', function () {
  280. const amount = 100;
  281. const spender = ZERO_ADDRESS;
  282. it('decreases the requested amount', async function () {
  283. await this.token.decreaseApproval(spender, amount, { from: owner });
  284. const allowance = await this.token.allowance(owner, spender);
  285. assert.equal(allowance, 0);
  286. });
  287. it('emits an approval event', async function () {
  288. const { logs } = await this.token.decreaseApproval(spender, amount, { from: owner });
  289. assert.equal(logs.length, 1);
  290. assert.equal(logs[0].event, 'Approval');
  291. assert.equal(logs[0].args.owner, owner);
  292. assert.equal(logs[0].args.spender, spender);
  293. assert(logs[0].args.value.eq(0));
  294. });
  295. });
  296. });
  297. describe('increase approval', function () {
  298. const amount = 100;
  299. describe('when the spender is not the zero address', function () {
  300. const spender = recipient;
  301. describe('when the sender has enough balance', function () {
  302. it('emits an approval event', async function () {
  303. const { logs } = await this.token.increaseApproval(spender, amount, { from: owner });
  304. assert.equal(logs.length, 1);
  305. assert.equal(logs[0].event, 'Approval');
  306. assert.equal(logs[0].args.owner, owner);
  307. assert.equal(logs[0].args.spender, spender);
  308. assert(logs[0].args.value.eq(amount));
  309. });
  310. describe('when there was no approved amount before', function () {
  311. it('approves the requested amount', async function () {
  312. await this.token.increaseApproval(spender, amount, { from: owner });
  313. const allowance = await this.token.allowance(owner, spender);
  314. assert.equal(allowance, amount);
  315. });
  316. });
  317. describe('when the spender had an approved amount', function () {
  318. beforeEach(async function () {
  319. await this.token.approve(spender, 1, { from: owner });
  320. });
  321. it('increases the spender allowance adding the requested amount', async function () {
  322. await this.token.increaseApproval(spender, amount, { from: owner });
  323. const allowance = await this.token.allowance(owner, spender);
  324. assert.equal(allowance, amount + 1);
  325. });
  326. });
  327. });
  328. describe('when the sender does not have enough balance', function () {
  329. const amount = 101;
  330. it('emits an approval event', async function () {
  331. const { logs } = await this.token.increaseApproval(spender, amount, { from: owner });
  332. assert.equal(logs.length, 1);
  333. assert.equal(logs[0].event, 'Approval');
  334. assert.equal(logs[0].args.owner, owner);
  335. assert.equal(logs[0].args.spender, spender);
  336. assert(logs[0].args.value.eq(amount));
  337. });
  338. describe('when there was no approved amount before', function () {
  339. it('approves the requested amount', async function () {
  340. await this.token.increaseApproval(spender, amount, { from: owner });
  341. const allowance = await this.token.allowance(owner, spender);
  342. assert.equal(allowance, amount);
  343. });
  344. });
  345. describe('when the spender had an approved amount', function () {
  346. beforeEach(async function () {
  347. await this.token.approve(spender, 1, { from: owner });
  348. });
  349. it('increases the spender allowance adding the requested amount', async function () {
  350. await this.token.increaseApproval(spender, amount, { from: owner });
  351. const allowance = await this.token.allowance(owner, spender);
  352. assert.equal(allowance, amount + 1);
  353. });
  354. });
  355. });
  356. });
  357. describe('when the spender is the zero address', function () {
  358. const spender = ZERO_ADDRESS;
  359. it('approves the requested amount', async function () {
  360. await this.token.increaseApproval(spender, amount, { from: owner });
  361. const allowance = await this.token.allowance(owner, spender);
  362. assert.equal(allowance, amount);
  363. });
  364. it('emits an approval event', async function () {
  365. const { logs } = await this.token.increaseApproval(spender, amount, { from: owner });
  366. assert.equal(logs.length, 1);
  367. assert.equal(logs[0].event, 'Approval');
  368. assert.equal(logs[0].args.owner, owner);
  369. assert.equal(logs[0].args.spender, spender);
  370. assert(logs[0].args.value.eq(amount));
  371. });
  372. });
  373. });
  374. });