ControlledERC20.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. import { expect } from "chai"
  2. import { ethers } from "hardhat"
  3. import { ControlledERC20 } from "../typechain-types"
  4. describe("ControlledERC20", function () {
  5. let controlledERC20: ControlledERC20
  6. let owner: any
  7. let user1: any
  8. let user2: any
  9. let user3: any
  10. const MINTER_ROLE = ethers.keccak256(ethers.toUtf8Bytes("MINTER_ROLE"))
  11. const PAUSER_ROLE = ethers.keccak256(ethers.toUtf8Bytes("PAUSER_ROLE"))
  12. const TRANSFER_CONTROLLER_ROLE = ethers.keccak256(ethers.toUtf8Bytes("TRANSFER_CONTROLLER_ROLE"))
  13. beforeEach(async function () {
  14. ;[owner, user1, user2, user3] = await ethers.getSigners()
  15. const ControlledERC20Factory = await ethers.getContractFactory("ControlledERC20")
  16. controlledERC20 = await ControlledERC20Factory.deploy("Controlled Token", "CTRL", owner.address)
  17. })
  18. describe("Deployment", function () {
  19. it("Should set the right owner with all roles", async function () {
  20. expect(await controlledERC20.hasRole(ethers.ZeroHash, owner.address)).to.be.true // DEFAULT_ADMIN_ROLE
  21. expect(await controlledERC20.hasRole(MINTER_ROLE, owner.address)).to.be.true
  22. expect(await controlledERC20.hasRole(PAUSER_ROLE, owner.address)).to.be.true
  23. expect(await controlledERC20.hasRole(TRANSFER_CONTROLLER_ROLE, owner.address)).to.be.true
  24. })
  25. it("Should have transfer enabled by default", async function () {
  26. expect(await controlledERC20.transferEnabled()).to.be.true
  27. })
  28. it("Should have owner in whitelist", async function () {
  29. expect(await controlledERC20.isWhitelisted(owner.address)).to.be.true
  30. })
  31. })
  32. describe("Role Management", function () {
  33. it("Should allow admin to grant minter role", async function () {
  34. await controlledERC20.connect(owner).grantRole(MINTER_ROLE, user1.address)
  35. expect(await controlledERC20.hasRole(MINTER_ROLE, user1.address)).to.be.true
  36. })
  37. it("Should allow admin to revoke minter role", async function () {
  38. await controlledERC20.connect(owner).grantRole(MINTER_ROLE, user1.address)
  39. await controlledERC20.connect(owner).revokeRole(MINTER_ROLE, user1.address)
  40. expect(await controlledERC20.hasRole(MINTER_ROLE, user1.address)).to.be.false
  41. })
  42. })
  43. describe("Minting", function () {
  44. it("Should allow minter to mint tokens", async function () {
  45. const mintAmount = ethers.parseEther("1000")
  46. await controlledERC20.connect(owner).mint(user1.address, mintAmount)
  47. expect(await controlledERC20.balanceOf(user1.address)).to.equal(mintAmount)
  48. })
  49. it("Should allow minter to batch mint tokens", async function () {
  50. const recipients = [user1.address, user2.address]
  51. const amounts = [ethers.parseEther("100"), ethers.parseEther("200")]
  52. await controlledERC20.connect(owner).mintBatch(recipients, amounts)
  53. expect(await controlledERC20.balanceOf(user1.address)).to.equal(amounts[0])
  54. expect(await controlledERC20.balanceOf(user2.address)).to.equal(amounts[1])
  55. })
  56. it("Should not allow non-minter to mint", async function () {
  57. const mintAmount = ethers.parseEther("1000")
  58. await expect(controlledERC20.connect(user1).mint(user2.address, mintAmount)).to.be.revertedWithCustomError(
  59. controlledERC20,
  60. "AccessControlUnauthorizedAccount"
  61. )
  62. })
  63. })
  64. describe("Transfer Control", function () {
  65. beforeEach(async function () {
  66. // Mint some tokens to users for testing
  67. await controlledERC20.connect(owner).mint(user1.address, ethers.parseEther("1000"))
  68. await controlledERC20.connect(owner).mint(user2.address, ethers.parseEther("1000"))
  69. })
  70. it("Should allow transfer when enabled", async function () {
  71. const transferAmount = ethers.parseEther("100")
  72. await controlledERC20.connect(user1).transfer(user3.address, transferAmount)
  73. expect(await controlledERC20.balanceOf(user3.address)).to.equal(transferAmount)
  74. })
  75. it("Should not allow transfer when disabled", async function () {
  76. await controlledERC20.connect(owner).setTransferEnabled(false)
  77. const transferAmount = ethers.parseEther("100")
  78. await expect(controlledERC20.connect(user1).transfer(user3.address, transferAmount)).to.be.revertedWith(
  79. "Transfer is disabled"
  80. )
  81. })
  82. it("Should allow whitelisted addresses to transfer when disabled", async function () {
  83. await controlledERC20.connect(owner).setTransferEnabled(false)
  84. await controlledERC20.connect(owner).updateWhitelist(user1.address, true)
  85. const transferAmount = ethers.parseEther("100")
  86. await controlledERC20.connect(user1).transfer(user3.address, transferAmount)
  87. expect(await controlledERC20.balanceOf(user3.address)).to.equal(transferAmount)
  88. })
  89. it("Should allow transfer to whitelisted addresses when disabled", async function () {
  90. await controlledERC20.connect(owner).setTransferEnabled(false)
  91. await controlledERC20.connect(owner).updateWhitelist(user3.address, true)
  92. const transferAmount = ethers.parseEther("100")
  93. await controlledERC20.connect(user1).transfer(user3.address, transferAmount)
  94. expect(await controlledERC20.balanceOf(user3.address)).to.equal(transferAmount)
  95. })
  96. })
  97. describe("Whitelist Management", function () {
  98. it("Should allow transfer controller to update whitelist", async function () {
  99. await controlledERC20.connect(owner).updateWhitelist(user1.address, true)
  100. expect(await controlledERC20.isWhitelisted(user1.address)).to.be.true
  101. })
  102. it("Should allow transfer controller to batch update whitelist", async function () {
  103. const accounts = [user1.address, user2.address]
  104. const isWhitelisted = [true, false]
  105. await controlledERC20.connect(owner).updateWhitelistBatch(accounts, isWhitelisted)
  106. expect(await controlledERC20.isWhitelisted(user1.address)).to.be.true
  107. expect(await controlledERC20.isWhitelisted(user2.address)).to.be.false
  108. })
  109. it("Should not allow non-transfer controller to update whitelist", async function () {
  110. await expect(
  111. controlledERC20.connect(user1).updateWhitelist(user2.address, true)
  112. ).to.be.revertedWithCustomError(controlledERC20, "AccessControlUnauthorizedAccount")
  113. })
  114. })
  115. describe("Pause/Unpause", function () {
  116. it("Should allow pauser to pause", async function () {
  117. await controlledERC20.connect(owner).pause()
  118. expect(await controlledERC20.paused()).to.be.true
  119. })
  120. it("Should allow pauser to unpause", async function () {
  121. await controlledERC20.connect(owner).pause()
  122. await controlledERC20.connect(owner).unpause()
  123. expect(await controlledERC20.paused()).to.be.false
  124. })
  125. it("Should not allow non-pauser to pause", async function () {
  126. await expect(controlledERC20.connect(user1).pause()).to.be.revertedWithCustomError(
  127. controlledERC20,
  128. "AccessControlUnauthorizedAccount"
  129. )
  130. })
  131. })
  132. describe("Burn", function () {
  133. beforeEach(async function () {
  134. await controlledERC20.connect(owner).mint(user1.address, ethers.parseEther("1000"))
  135. })
  136. it("Should allow burning tokens", async function () {
  137. const burnAmount = ethers.parseEther("100")
  138. const initialBalance = await controlledERC20.balanceOf(user1.address)
  139. await controlledERC20.connect(user1).burn(burnAmount)
  140. expect(await controlledERC20.balanceOf(user1.address)).to.equal(initialBalance - burnAmount)
  141. })
  142. })
  143. })