ERC20Migrator.test.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. const { BN, constants, shouldFail } = require('openzeppelin-test-helpers');
  2. const { ZERO_ADDRESS } = constants;
  3. const ERC20Mock = artifacts.require('ERC20Mock');
  4. const ERC20Mintable = artifacts.require('ERC20Mintable');
  5. const ERC20Migrator = artifacts.require('ERC20Migrator');
  6. contract('ERC20Migrator', function ([_, owner, recipient, anotherAccount]) {
  7. const totalSupply = new BN('200');
  8. it('reverts with a null legacy token address', async function () {
  9. await shouldFail.reverting(ERC20Migrator.new(ZERO_ADDRESS));
  10. });
  11. describe('with tokens and migrator', function () {
  12. beforeEach('deploying tokens and migrator', async function () {
  13. this.legacyToken = await ERC20Mock.new(owner, totalSupply);
  14. this.migrator = await ERC20Migrator.new(this.legacyToken.address);
  15. this.newToken = await ERC20Mintable.new();
  16. });
  17. it('returns legacy token', async function () {
  18. (await this.migrator.legacyToken()).should.be.equal(this.legacyToken.address);
  19. });
  20. describe('beginMigration', function () {
  21. it('reverts with a null new token address', async function () {
  22. await shouldFail.reverting(this.migrator.beginMigration(ZERO_ADDRESS));
  23. });
  24. it('reverts if not a minter of the token', async function () {
  25. await shouldFail.reverting(this.migrator.beginMigration(this.newToken.address));
  26. });
  27. it('succeeds if it is a minter of the token', async function () {
  28. await this.newToken.addMinter(this.migrator.address);
  29. await this.migrator.beginMigration(this.newToken.address);
  30. });
  31. it('reverts the second time it is called', async function () {
  32. await this.newToken.addMinter(this.migrator.address);
  33. await this.migrator.beginMigration(this.newToken.address);
  34. await shouldFail.reverting(this.migrator.beginMigration(this.newToken.address));
  35. });
  36. });
  37. context('before starting the migration', function () {
  38. it('returns the zero address for the new token', async function () {
  39. (await this.migrator.newToken()).should.be.equal(ZERO_ADDRESS);
  40. });
  41. describe('migrateAll', function () {
  42. const amount = totalSupply;
  43. describe('when the approved balance is equal to the owned balance', function () {
  44. beforeEach('approving the whole balance to the new contract', async function () {
  45. await this.legacyToken.approve(this.migrator.address, amount, { from: owner });
  46. });
  47. it('reverts', async function () {
  48. await shouldFail.reverting(this.migrator.migrateAll(owner));
  49. });
  50. });
  51. });
  52. describe('migrate', function () {
  53. const amount = new BN(50);
  54. describe('when the amount is equal to the approved value', function () {
  55. beforeEach('approving tokens to the new contract', async function () {
  56. await this.legacyToken.approve(this.migrator.address, amount, { from: owner });
  57. });
  58. it('reverts', async function () {
  59. await shouldFail.reverting(this.migrator.migrate(owner, amount));
  60. });
  61. });
  62. });
  63. });
  64. describe('once migration began', function () {
  65. beforeEach('beginning migration', async function () {
  66. await this.newToken.addMinter(this.migrator.address);
  67. await this.migrator.beginMigration(this.newToken.address);
  68. });
  69. it('returns new token', async function () {
  70. (await this.migrator.newToken()).should.be.equal(this.newToken.address);
  71. });
  72. describe('migrateAll', function () {
  73. const baseAmount = totalSupply;
  74. describe('when the approved balance is equal to the owned balance', function () {
  75. const amount = baseAmount;
  76. beforeEach('approving the whole balance to the new contract', async function () {
  77. await this.legacyToken.approve(this.migrator.address, amount, { from: owner });
  78. });
  79. beforeEach('migrating token', async function () {
  80. const tx = await this.migrator.migrateAll(owner);
  81. this.logs = tx.receipt.logs;
  82. });
  83. it('mints the same balance of the new token', async function () {
  84. const currentBalance = await this.newToken.balanceOf(owner);
  85. currentBalance.should.be.bignumber.equal(amount);
  86. });
  87. it('burns a given amount of old tokens', async function () {
  88. const currentBurnedBalance = await this.legacyToken.balanceOf(this.migrator.address);
  89. currentBurnedBalance.should.be.bignumber.equal(amount);
  90. const currentLegacyTokenBalance = await this.legacyToken.balanceOf(owner);
  91. currentLegacyTokenBalance.should.be.bignumber.equal('0');
  92. });
  93. it('updates the total supply', async function () {
  94. const currentSupply = await this.newToken.totalSupply();
  95. currentSupply.should.be.bignumber.equal(amount);
  96. });
  97. });
  98. describe('when the approved balance is lower than the owned balance', function () {
  99. const amount = baseAmount.subn(1);
  100. beforeEach('approving part of the balance to the new contract', async function () {
  101. await this.legacyToken.approve(this.migrator.address, amount, { from: owner });
  102. await this.migrator.migrateAll(owner);
  103. });
  104. it('migrates only approved amount', async function () {
  105. const currentBalance = await this.newToken.balanceOf(owner);
  106. currentBalance.should.be.bignumber.equal(amount);
  107. });
  108. });
  109. });
  110. describe('migrate', function () {
  111. const baseAmount = new BN(50);
  112. beforeEach('approving tokens to the new contract', async function () {
  113. await this.legacyToken.approve(this.migrator.address, baseAmount, { from: owner });
  114. });
  115. describe('when the amount is equal to the one approved', function () {
  116. const amount = baseAmount;
  117. beforeEach('migrate token', async function () {
  118. ({ logs: this.logs } = await this.migrator.migrate(owner, amount));
  119. });
  120. it('mints that amount of the new token', async function () {
  121. const currentBalance = await this.newToken.balanceOf(owner);
  122. currentBalance.should.be.bignumber.equal(amount);
  123. });
  124. it('burns a given amount of old tokens', async function () {
  125. const currentBurnedBalance = await this.legacyToken.balanceOf(this.migrator.address);
  126. currentBurnedBalance.should.be.bignumber.equal(amount);
  127. const currentLegacyTokenBalance = await this.legacyToken.balanceOf(owner);
  128. currentLegacyTokenBalance.should.be.bignumber.equal(totalSupply.sub(amount));
  129. });
  130. it('updates the total supply', async function () {
  131. const currentSupply = await this.newToken.totalSupply();
  132. currentSupply.should.be.bignumber.equal(amount);
  133. });
  134. });
  135. describe('when the given amount is higher than the one approved', function () {
  136. const amount = baseAmount.addn(1);
  137. it('reverts', async function () {
  138. await shouldFail.reverting(this.migrator.migrate(owner, amount));
  139. });
  140. });
  141. });
  142. });
  143. });
  144. });