ERC20Burnable.behavior.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. const { BN, constants, expectEvent } = require('@openzeppelin/test-helpers');
  2. const { ZERO_ADDRESS } = constants;
  3. const { expect } = require('chai');
  4. const { expectRevertCustomError } = require('../../../helpers/customError');
  5. function shouldBehaveLikeERC20Burnable(owner, initialBalance, [burner]) {
  6. describe('burn', function () {
  7. describe('when the given amount is not greater than balance of the sender', function () {
  8. context('for a zero amount', function () {
  9. shouldBurn(new BN(0));
  10. });
  11. context('for a non-zero amount', function () {
  12. shouldBurn(new BN(100));
  13. });
  14. function shouldBurn(amount) {
  15. beforeEach(async function () {
  16. this.receipt = await this.token.burn(amount, { from: owner });
  17. });
  18. it('burns the requested amount', async function () {
  19. expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialBalance.sub(amount));
  20. });
  21. it('emits a transfer event', async function () {
  22. expectEvent(this.receipt, 'Transfer', {
  23. from: owner,
  24. to: ZERO_ADDRESS,
  25. value: amount,
  26. });
  27. });
  28. }
  29. });
  30. describe('when the given amount is greater than the balance of the sender', function () {
  31. const amount = initialBalance.addn(1);
  32. it('reverts', async function () {
  33. await expectRevertCustomError(this.token.burn(amount, { from: owner }), 'ERC20InsufficientBalance', [
  34. owner,
  35. initialBalance,
  36. amount,
  37. ]);
  38. });
  39. });
  40. });
  41. describe('burnFrom', function () {
  42. describe('on success', function () {
  43. context('for a zero amount', function () {
  44. shouldBurnFrom(new BN(0));
  45. });
  46. context('for a non-zero amount', function () {
  47. shouldBurnFrom(new BN(100));
  48. });
  49. function shouldBurnFrom(amount) {
  50. const originalAllowance = amount.muln(3);
  51. beforeEach(async function () {
  52. await this.token.approve(burner, originalAllowance, { from: owner });
  53. this.receipt = await this.token.burnFrom(owner, amount, { from: burner });
  54. });
  55. it('burns the requested amount', async function () {
  56. expect(await this.token.balanceOf(owner)).to.be.bignumber.equal(initialBalance.sub(amount));
  57. });
  58. it('decrements allowance', async function () {
  59. expect(await this.token.allowance(owner, burner)).to.be.bignumber.equal(originalAllowance.sub(amount));
  60. });
  61. it('emits a transfer event', async function () {
  62. expectEvent(this.receipt, 'Transfer', {
  63. from: owner,
  64. to: ZERO_ADDRESS,
  65. value: amount,
  66. });
  67. });
  68. }
  69. });
  70. describe('when the given amount is greater than the balance of the sender', function () {
  71. const amount = initialBalance.addn(1);
  72. it('reverts', async function () {
  73. await this.token.approve(burner, amount, { from: owner });
  74. await expectRevertCustomError(
  75. this.token.burnFrom(owner, amount, { from: burner }),
  76. 'ERC20InsufficientBalance',
  77. [owner, initialBalance, amount],
  78. );
  79. });
  80. });
  81. describe('when the given amount is greater than the allowance', function () {
  82. const allowance = new BN(100);
  83. it('reverts', async function () {
  84. await this.token.approve(burner, allowance, { from: owner });
  85. await expectRevertCustomError(
  86. this.token.burnFrom(owner, allowance.addn(1), { from: burner }),
  87. 'ERC20InsufficientAllowance',
  88. [burner, allowance, allowance.addn(1)],
  89. );
  90. });
  91. });
  92. });
  93. }
  94. module.exports = {
  95. shouldBehaveLikeERC20Burnable,
  96. };