LPStaking.test.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. const { expect } = require("chai")
  2. const { ethers } = require("hardhat")
  3. const { BigNumber } = require("ethers")
  4. const { ZERO_ADDRESS } = require("./util/constants")
  5. const { getAddr, deployNew, getCurrentBlock, mineNBlocks, callAsContract } = require("./util/helpers")
  6. describe("LPStaking:", function () {
  7. let owner, alice, badUser1, fakeContract, mockToken, lpStaking
  8. let chainId, startBlock, bonusEndBlock, emissionsPerBlock, poolId, allocPoint, depositAmt, stargateToken
  9. before(async function () {
  10. ;({ owner, alice, badUser1, fakeContract } = await getAddr(ethers))
  11. poolId = 0
  12. chainId = 1
  13. allocPoint = 3
  14. bonusEndBlock = 1000000000
  15. emissionsPerBlock = "1000000000000000000"
  16. depositAmt = BigNumber.from("1000000000000000000")
  17. })
  18. beforeEach(async function () {
  19. startBlock = (await getCurrentBlock()) + 3
  20. stargateToken = await deployNew("MockToken", ["Token", "TKN", 18])
  21. lpStaking = await deployNew("LPStaking", [stargateToken.address, emissionsPerBlock, startBlock, bonusEndBlock])
  22. mockToken = await deployNew("MockToken", ["Token", "TKN", 18])
  23. await mockToken.transfer(lpStaking.address, "10000000000000000000000")
  24. })
  25. it("constructor() - reverts for bad params", async function () {
  26. await expect(deployNew("LPStaking", [mockToken.address, emissionsPerBlock, 0, 1])).to.be.revertedWith(
  27. "LPStaking: _startBlock must be >= current block"
  28. )
  29. await expect(deployNew("LPStaking", [mockToken.address, emissionsPerBlock, startBlock + 10, 0])).to.be.revertedWith(
  30. "LPStaking: _bonusEndBlock must be > than _startBlock"
  31. )
  32. await expect(deployNew("LPStaking", [ZERO_ADDRESS, emissionsPerBlock, startBlock + 10, bonusEndBlock])).to.be.revertedWith(
  33. "Stargate: _stargate cannot be 0x0"
  34. )
  35. })
  36. it("deposit()", async function () {
  37. await lpStaking.add(allocPoint, mockToken.address)
  38. await mockToken.approve(lpStaking.address, "100000000000000000000000")
  39. // deposit() into the pool
  40. await lpStaking.deposit(poolId, depositAmt)
  41. await lpStaking.deposit(poolId, depositAmt)
  42. await lpStaking.massUpdatePools()
  43. expect(await lpStaking.pendingStargate(poolId, owner.address)).to.be.gt(0)
  44. await lpStaking.deposit(poolId, depositAmt)
  45. // withdraw() from the pool
  46. await expect(lpStaking.withdraw(poolId, depositAmt.mul(3))).to.emit(lpStaking, "Withdraw")
  47. await lpStaking.emergencyWithdraw(poolId)
  48. })
  49. it("deposit()", async function () {
  50. lpStaking = await deployNew("LPStaking", [mockToken.address, emissionsPerBlock, (await getCurrentBlock()) + 2, bonusEndBlock])
  51. await lpStaking.add(allocPoint, mockToken.address)
  52. await mockToken.transfer(lpStaking.address, "10000000000000000000000")
  53. await mockToken.approve(lpStaking.address, "10000000000000000000000")
  54. // deposit() into the pool
  55. await lpStaking.deposit(poolId, depositAmt)
  56. await lpStaking.deposit(poolId, depositAmt)
  57. await lpStaking.updatePool(poolId)
  58. // check current pending stargate
  59. const pendingStargate = await lpStaking.pendingStargate(poolId, owner.address)
  60. await mineNBlocks(20)
  61. // updates the last reward block number
  62. await lpStaking.updatePool(poolId)
  63. await mineNBlocks(2)
  64. const _pendingStargate = await lpStaking.pendingStargate(poolId, owner.address)
  65. // ensure that the new amount of pending stargate has increased
  66. expect(_pendingStargate.gt(pendingStargate)).to.equal(true)
  67. })
  68. it("deposit() and withdraw() - changes the lp amount stored in lpBalance", async function () {
  69. await lpStaking.add(allocPoint, mockToken.address)
  70. await mockToken.approve(lpStaking.address, "100000000000000000000000")
  71. // deposit() into the pool
  72. await lpStaking.deposit(poolId, depositAmt)
  73. let lpBalance = await lpStaking.lpBalances(poolId)
  74. expect(depositAmt).to.be.equal(lpBalance)
  75. // withtdraw() from the pool
  76. await lpStaking.withdraw(poolId, depositAmt)
  77. lpBalance = await lpStaking.lpBalances(poolId)
  78. expect(lpBalance).to.equal(0)
  79. })
  80. it("emergencyWithdraw() - changes the lp amount stored in lpBalance", async function () {
  81. await lpStaking.add(allocPoint, mockToken.address)
  82. await mockToken.approve(lpStaking.address, "100000000000000000000000")
  83. await mockToken.transfer(alice.address, "7000000000000000000")
  84. await mockToken.connect(alice).approve(lpStaking.address, "100000000000000000000000")
  85. // emergencyWithtdraw() from the pool
  86. depositAmt2 = BigNumber.from("7000000000000000000")
  87. // owner deposits then alice deposits
  88. await lpStaking.deposit(poolId, depositAmt)
  89. await lpStaking.connect(alice).deposit(poolId, depositAmt2)
  90. lpBalance = await lpStaking.lpBalances(poolId)
  91. expect(depositAmt.add(depositAmt2)).to.equal(lpBalance)
  92. await lpStaking.connect(alice).emergencyWithdraw(poolId)
  93. lpBalance = await lpStaking.lpBalances(poolId)
  94. // should equal only owner's deposit
  95. expect(lpBalance).to.equal(depositAmt)
  96. })
  97. it("add() - reverts with duplicate token", async function () {
  98. await lpStaking.add(allocPoint, mockToken.address)
  99. await expect(lpStaking.add(allocPoint, mockToken.address)).to.be.reverted
  100. })
  101. it("add() - reverts with 0x0 token", async function () {
  102. await expect(lpStaking.add(allocPoint, ZERO_ADDRESS)).to.revertedWith("StarGate: lpToken cant be 0x0")
  103. })
  104. it("withdraw() - withdraws if amount is too large", async function () {
  105. await lpStaking.add(allocPoint, mockToken.address)
  106. await mockToken.approve(lpStaking.address, "100000000000000000000000")
  107. // deposit() into the pool
  108. await lpStaking.deposit(poolId, depositAmt)
  109. await lpStaking.deposit(poolId, depositAmt)
  110. await lpStaking.massUpdatePools()
  111. expect(await lpStaking.pendingStargate(poolId, owner.address)).to.be.gt(0)
  112. await lpStaking.deposit(poolId, depositAmt)
  113. // withdraw() from pool and revert
  114. await expect(lpStaking.withdraw(poolId, "4000000000000000000")).to.be.revertedWith("withdraw: _amount is too large")
  115. })
  116. it("withdraw() - withdraw exceeds the amount owned by the lp contract", async function () {
  117. await lpStaking.add(allocPoint, mockToken.address)
  118. await mockToken.approve(lpStaking.address, "100000000000000000000000")
  119. await stargateToken.mint(lpStaking.address, "100000000")
  120. // deposit() into the pool
  121. await lpStaking.deposit(poolId, depositAmt)
  122. await lpStaking.deposit(poolId, depositAmt)
  123. const amountToSend = 42
  124. // give lp staking some stargate to send back to owner
  125. await stargateToken.mint(lpStaking.address, amountToSend)
  126. const userBal = await stargateToken.balanceOf(owner.address)
  127. // add 1 more to make sure its capped at the balance of lpStaking
  128. await lpStaking.withdraw(poolId, amountToSend + 1)
  129. expect(await stargateToken.balanceOf(owner.address)).to.equal(userBal.add(amountToSend))
  130. })
  131. it("renounceOwnership() - onlyOwner modifiers dont block when owner doesnt exist", async function () {
  132. await lpStaking.add(allocPoint, mockToken.address)
  133. await lpStaking.renounceOwnership()
  134. await expect(lpStaking.set(poolId, allocPoint)).to.not.be.reverted
  135. })
  136. it("getMultiplier() - _to field equal to bonus end block", async function () {
  137. const result = await lpStaking.getMultiplier(1, 1)
  138. await expect(result._hex).to.equal("0x00")
  139. })
  140. it("getMultiplier() - _from field less than the bonus end block", async function () {
  141. const result = await lpStaking.getMultiplier(0, 2)
  142. await expect(result._hex).to.equal("0x02")
  143. })
  144. it("getMultiplier() - _from field greater than the bonus end block", async function () {
  145. const from = BigNumber.from(123).add(await lpStaking.bonusEndBlock())
  146. const to = BigNumber.from(555).add(await lpStaking.bonusEndBlock())
  147. const result = await lpStaking.getMultiplier(from, to)
  148. await expect(result).to.equal(to.sub(from))
  149. })
  150. it("getMultiplier() - _to is > bonusEndblock and _from is < bonusEndblock", async function () {
  151. const bonusEndBlock = await lpStaking.bonusEndBlock()
  152. const from = bonusEndBlock.sub(BigNumber.from(123))
  153. const to = bonusEndBlock.add(BigNumber.from(123))
  154. const bonusMultiplier = await lpStaking.BONUS_MULTIPLIER()
  155. const result = await lpStaking.getMultiplier(from, to)
  156. await expect(result).to.equal(bonusEndBlock.sub(from).mul(bonusMultiplier).add(to.sub(bonusEndBlock)))
  157. })
  158. it("setStargatePerBlock() - reverts when non owner", async function () {
  159. await expect(lpStaking.connect(badUser1).setStargatePerBlock(0)).to.revertedWith("Ownable: caller is not the owner")
  160. })
  161. it("setStargatePerBlock() - reverts when non owner", async function () {
  162. const stargatePerBlock = 123
  163. await lpStaking.setStargatePerBlock(stargatePerBlock)
  164. expect(await lpStaking.stargatePerBlock()).to.equal(stargatePerBlock)
  165. })
  166. it("poolLength() - reverts when non owner", async function () {
  167. expect(await lpStaking.poolLength()).to.equal(0)
  168. await lpStaking.add(allocPoint, mockToken.address)
  169. expect(await lpStaking.poolLength()).to.equal(1)
  170. })
  171. it("updatePool() - lpSupply is 0", async function () {
  172. // new token that hasnt transfered any tokens to the lp staking contract
  173. mockToken = await deployNew("MockToken", ["Token", "TKN", 18])
  174. await lpStaking.add(allocPoint, mockToken.address)
  175. const { lastRewardBlock } = await lpStaking.poolInfo(poolId)
  176. await lpStaking.updatePool(poolId)
  177. const { lastRewardBlock: _lastRewardBlock } = await lpStaking.poolInfo(poolId)
  178. // make sure the lp staking owns no tokens
  179. expect(await mockToken.balanceOf(lpStaking.address)).to.equal(0)
  180. // updated the lastRewardBlock to the current block number
  181. expect(_lastRewardBlock.gt(lastRewardBlock)).to.equal(true)
  182. expect(_lastRewardBlock.eq(await getCurrentBlock())).to.equal(true)
  183. })
  184. it("updatePool() - lp staking that starts in the future", async function () {
  185. lpStaking = await deployNew("LPStaking", [mockToken.address, emissionsPerBlock, (await getCurrentBlock()) + 50, bonusEndBlock])
  186. await lpStaking.add(allocPoint, mockToken.address)
  187. const { lastRewardBlock } = await lpStaking.poolInfo(poolId)
  188. await lpStaking.updatePool(poolId)
  189. const { lastRewardBlock: _lastRewardBlock } = await lpStaking.poolInfo(poolId)
  190. // lastRewardBlock isnt updated
  191. expect(_lastRewardBlock.eq(lastRewardBlock)).to.equal(true)
  192. })
  193. })