Router.test.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. const { expect } = require("chai")
  2. const { ethers } = require("hardhat")
  3. const { ZERO_ADDRESS } = require("./util/constants")
  4. const { deployNew, getAddr, getPoolFromFactory } = require("./util/helpers")
  5. describe("Router", function () {
  6. let owner, alice, badUser1, fakeContract, lzEndpoint, factory, router, bridge
  7. let chainId, poolId, decimals, dstPoolId, dstChainId, defaultChainPathWeight
  8. let defaultAmountLD, defaultAmountSD, nonce
  9. before(async function () {
  10. ;({ owner, alice, badUser1, fakeContract } = await getAddr(ethers))
  11. defaultAmountLD = 123
  12. defaultAmountSD = 123
  13. chainId = 1
  14. poolId = 11
  15. dstChainId = 2
  16. dstPoolId = 22
  17. decimals = 18
  18. nonce = 1
  19. defaultChainPathWeight = 1
  20. })
  21. beforeEach(async function () {
  22. lzEndpoint = await deployNew("LZEndpointMock", [chainId])
  23. router = await deployNew("Router")
  24. bridge = await deployNew("Bridge", [lzEndpoint.address, router.address])
  25. factory = await deployNew("Factory", [router.address])
  26. await router.setBridgeAndFactory(bridge.address, factory.address)
  27. })
  28. it("setBridgeAndFactory() - reverts when bridge already initialized", async function () {
  29. router = await deployNew("Router")
  30. await router.setBridgeAndFactory(fakeContract.address, fakeContract.address)
  31. await expect(router.setBridgeAndFactory(fakeContract.address, fakeContract.address)).to.be.revertedWith(
  32. "Stargate: bridge and factory already initialized"
  33. )
  34. })
  35. it("setBridgeAndFactory() - reverts when factory already initialized", async function () {
  36. router = await deployNew("Router")
  37. const factoryPositionInStorage = "0x2" // position in contract storage
  38. const setFactoryStorage = "0x0000000000000000000000000000000000000000000000000000000000000001" // sets the factory address to 0x1
  39. // set factory to 0x1
  40. await network.provider.send("hardhat_setStorageAt", [router.address, factoryPositionInStorage, setFactoryStorage])
  41. await expect(router.setBridgeAndFactory(fakeContract.address, fakeContract.address)).to.be.revertedWith(
  42. "Stargate: bridge and factory already initialized"
  43. )
  44. })
  45. it("setBridgeAndFactory() - reverts when bridge is 0x0", async function () {
  46. router = await deployNew("Router")
  47. await expect(router.setBridgeAndFactory(ZERO_ADDRESS, fakeContract.address)).to.be.revertedWith("Stargate: bridge cant be 0x0")
  48. })
  49. it("setBridgeAndFactory() - reverts when factory is 0x0", async function () {
  50. router = await deployNew("Router")
  51. await expect(router.setBridgeAndFactory(fakeContract.address, ZERO_ADDRESS)).to.be.revertedWith("Stargate: factory cant be 0x0")
  52. })
  53. it("addLiquidity() - reverts for non existant pool ", async function () {
  54. await expect(router.addLiquidity(defaultAmountLD, poolId, owner.address)).to.be.revertedWith("Stargate: Pool does not exist")
  55. })
  56. it("createPool() - reverts when token is 0x0", async function () {
  57. await expect(router.createPool(poolId, ZERO_ADDRESS, decimals, decimals, "x", "x*")).to.be.revertedWith("Stargate: _token cannot be 0x0")
  58. })
  59. it("swap() - reverts when refund address is 0x0", async function () {
  60. await expect(
  61. router.swap(
  62. chainId,
  63. poolId,
  64. dstPoolId,
  65. ZERO_ADDRESS,
  66. 1,
  67. 0,
  68. { dstGasForCall: 0, dstNativeAmount: 0, dstNativeAddr: "0x" },
  69. "0x",
  70. "0x"
  71. )
  72. ).to.be.revertedWith("Stargate: _refundAddress cannot be 0x0")
  73. })
  74. it("redeemRemote() - reverts when refund address is 0x0", async function () {
  75. await expect(
  76. router.redeemRemote(chainId, poolId, dstPoolId, ZERO_ADDRESS, 1, 0, "0x", {
  77. dstGasForCall: 0,
  78. dstNativeAmount: 0,
  79. dstNativeAddr: "0x",
  80. })
  81. ).to.be.revertedWith("Stargate: _refundAddress cannot be 0x0")
  82. })
  83. it("redeemRemote() - reverts when amount LP is 0", async function () {
  84. await expect(
  85. router.redeemRemote(chainId, poolId, dstPoolId, fakeContract.address, 0, 0, "0x", {
  86. dstGasForCall: 0,
  87. dstNativeAmount: 0,
  88. dstNativeAddr: "0x",
  89. })
  90. ).to.be.revertedWith("Stargate: not enough lp to redeemRemote")
  91. })
  92. it("instantRedeemLocal() - reverts with 0 lp", async function () {
  93. await expect(router.instantRedeemLocal(poolId, 0, ZERO_ADDRESS)).to.revertedWith("Stargate: not enough lp to redeem")
  94. })
  95. it("redeemLocal() - reverts when refund address is 0x0", async function () {
  96. await expect(
  97. router.redeemLocal(chainId, poolId, dstPoolId, ZERO_ADDRESS, 1, "0x", { dstGasForCall: 0, dstNativeAmount: 0, dstNativeAddr: "0x" })
  98. ).to.be.revertedWith("Stargate: _refundAddress cannot be 0x0")
  99. })
  100. it("sendCredits() - Reverts when refund address is 0x0", async function () {
  101. await expect(router.sendCredits(dstChainId, poolId, dstPoolId, ZERO_ADDRESS)).to.be.revertedWith(
  102. "Stargate: _refundAddress cannot be 0x0"
  103. )
  104. })
  105. it("retryRevert() - reverts when theres nothing to retry", async function () {
  106. await expect(router.retryRevert(dstChainId, ZERO_ADDRESS, nonce)).to.be.revertedWith("Stargate: no retry revert")
  107. })
  108. it("revertRedeemLocal() - reverts when ZERO non refund address", async function () {
  109. await expect(
  110. router.revertRedeemLocal(dstChainId, ZERO_ADDRESS, nonce, ZERO_ADDRESS, {
  111. dstGasForCall: 0,
  112. dstNativeAmount: 0,
  113. dstNativeAddr: "0x",
  114. })
  115. ).to.be.revertedWith("Stargate: _refundAddress cannot be 0x0")
  116. })
  117. it("revertRedeemLocal() - reverts when theres nothing to try to retry", async function () {
  118. await expect(
  119. router.revertRedeemLocal(dstChainId, ZERO_ADDRESS, nonce, alice.address, {
  120. dstGasForCall: 0,
  121. dstNativeAmount: 0,
  122. dstNativeAddr: "0x",
  123. })
  124. ).to.be.revertedWith("Stargate: no retry revert")
  125. })
  126. it("clearCachedSwap() - reverts when nothing to clean", async function () {
  127. await expect(router.clearCachedSwap(dstChainId, ZERO_ADDRESS, nonce)).to.be.revertedWith("Stargate: cache already cleared")
  128. })
  129. it("creditChainPath() - reverts when caller is not Bridge", async function () {
  130. await expect(router.connect(alice).creditChainPath(dstChainId, dstPoolId, poolId, { credits: 1, idealBalance: 1 })).to.be.revertedWith(
  131. "Bridge: caller must be Bridge."
  132. )
  133. })
  134. it("removeLiquitidyRemote() - reverts when caller is not Bridge", async function () {
  135. await expect(
  136. router.connect(alice).redeemLocalCheckOnRemote(chainId, ZERO_ADDRESS, nonce, poolId, dstPoolId, defaultAmountSD, ZERO_ADDRESS)
  137. ).to.be.revertedWith("Bridge: caller must be Bridge.")
  138. })
  139. it("redeemLocalCallback() - reverts when caller is no Bridge", async function () {
  140. await expect(
  141. router
  142. .connect(alice)
  143. .redeemLocalCallback(chainId, ZERO_ADDRESS, nonce, poolId, dstPoolId, ZERO_ADDRESS, defaultAmountSD, defaultAmountSD)
  144. ).to.be.revertedWith("Bridge: caller must be Bridge.")
  145. })
  146. it("redeemLocalCallback() - emits event", async function () {
  147. await router.createPool(dstPoolId, fakeContract.address, decimals, decimals, "x", "x*")
  148. await expect(
  149. callAsContract(router, bridge.address, "redeemLocalCallback(uint16,bytes,uint256,uint256,uint256,address,uint256,uint256)", [
  150. chainId,
  151. alice.address,
  152. nonce,
  153. poolId,
  154. dstPoolId,
  155. alice.address,
  156. defaultAmountSD,
  157. defaultAmountSD,
  158. ])
  159. )
  160. .to.emit(router, "RedeemLocalCallback")
  161. .withArgs(chainId, alice.address, nonce, poolId, dstPoolId, alice.address, defaultAmountSD, defaultAmountSD)
  162. })
  163. it("swapRemote() - reverts when caller is no Bridge", async function () {
  164. const swapObj = {
  165. amount: 1,
  166. eqFee: 2,
  167. eqReward: 3,
  168. lpFee: 4,
  169. protocolFee: 5,
  170. lkbRemove: 6,
  171. }
  172. const dstGasForCall = 1
  173. await expect(
  174. router.connect(alice).swapRemote(chainId, ZERO_ADDRESS, nonce, poolId, dstPoolId, dstGasForCall, ZERO_ADDRESS, swapObj, "0x")
  175. ).to.be.revertedWith("Bridge: caller must be Bridge.")
  176. })
  177. it("createPool() - reverts with non owner", async function () {
  178. await expect(router.connect(alice).createPool(poolId, ZERO_ADDRESS, decimals, decimals, "x", "x*")).to.be.revertedWith(
  179. "Ownable: caller is not the owner"
  180. )
  181. })
  182. it("createChainPath() - reverts with non owner", async function () {
  183. await expect(router.connect(alice).createChainPath(poolId, dstChainId, dstPoolId, defaultChainPathWeight)).to.be.revertedWith(
  184. "Ownable: caller is not the owner"
  185. )
  186. })
  187. it("setWeightForChainPath() - reverts when caller is not the dao", async function () {
  188. await expect(router.connect(alice).setWeightForChainPath(poolId, dstChainId, dstPoolId, defaultChainPathWeight)).to.be.revertedWith(
  189. "Ownable: caller is not the owner"
  190. )
  191. })
  192. it("setWeightForChainPath()", async function () {
  193. await router.createPool(poolId, fakeContract.address, decimals, decimals, "x", "x*")
  194. await router.createChainPath(poolId, dstChainId, dstPoolId, defaultChainPathWeight)
  195. await router.activateChainPath(poolId, dstChainId, dstPoolId)
  196. const pool = await getPoolFromFactory(factory, poolId)
  197. expect((await pool.getChainPath(dstChainId, dstPoolId)).weight).to.equal(defaultChainPathWeight)
  198. await router.setWeightForChainPath(poolId, dstChainId, dstPoolId, defaultChainPathWeight + 1)
  199. expect((await pool.getChainPath(dstChainId, dstPoolId)).weight).to.equal(defaultChainPathWeight + 1)
  200. })
  201. it("setProtocolFeeOwner() - reverts when caller is not the dao", async function () {
  202. await expect(router.connect(alice).setProtocolFeeOwner(alice.address)).to.be.revertedWith("Ownable: caller is not the owner")
  203. })
  204. it("setProtocolFeeOwner() - reverts when fee owner is 0x0", async function () {
  205. await expect(router.setProtocolFeeOwner(ZERO_ADDRESS)).to.be.revertedWith("Stargate: _owner cannot be 0x0")
  206. })
  207. it("setMintFeeOwner() - reverts when non owner", async function () {
  208. await expect(router.connect(alice).setMintFeeOwner(alice.address)).to.be.revertedWith("Ownable: caller is not the owner")
  209. })
  210. it("setMintFeeOwner() - reverts when fee owner is 0x0", async function () {
  211. await expect(router.setMintFeeOwner(ZERO_ADDRESS)).to.be.revertedWith("Stargate: _owner cannot be 0x0")
  212. })
  213. it("setFees() - reverts when caller is not the dao", async function () {
  214. const mintFeeBP = 1
  215. await expect(router.connect(alice).setFees(poolId, mintFeeBP)).to.be.revertedWith("Ownable: caller is not the owner")
  216. })
  217. it("setFeeLibrary() - reverts when non owner", async function () {
  218. await expect(router.connect(alice).setFeeLibrary(poolId, ZERO_ADDRESS)).to.be.revertedWith("Ownable: caller is not the owner")
  219. })
  220. it("setSwapStop() - reverts when non owner", async function () {
  221. await expect(router.connect(alice).setSwapStop(poolId, true)).to.be.revertedWith("Ownable: caller is not the owner")
  222. })
  223. it("setFeeLibrary() - when caller is Owner", async function () {
  224. await router.createPool(poolId, alice.address, decimals, decimals, "x", "x*")
  225. await router.setFeeLibrary(poolId, alice.address)
  226. })
  227. it("setSwapStop() - when caller is the Owner", async function () {
  228. await router.createPool(poolId, fakeContract.address, decimals, decimals, "x", "x*")
  229. await router.setSwapStop(poolId, true)
  230. })
  231. it("callDelta() - anyone can call", async function () {
  232. await router.createPool(poolId, fakeContract.address, decimals, decimals, "x", "x*")
  233. await router.connect(alice).callDelta(poolId, true)
  234. })
  235. it("withdrawMintFee() - reverts when non owner", async function () {
  236. await expect(router.connect(alice).withdrawMintFee(poolId, alice.address)).to.be.revertedWith("Stargate: only mintFeeOwner")
  237. })
  238. it("withdrawMintFee()", async function () {
  239. await router.createPool(poolId, fakeContract.address, decimals, decimals, "x", "x*")
  240. await router.setMintFeeOwner(owner.address)
  241. await expect(router.withdrawMintFee(poolId, alice.address)).to.not.be.revertedWith("Stargate: only mintFeeOwner")
  242. })
  243. it("withdrawProtocolFee() - reverts when non owner", async function () {
  244. await expect(router.connect(alice).withdrawProtocolFee(poolId, alice.address)).to.be.revertedWith("Stargate: only protocolFeeOwner")
  245. })
  246. it("withdrawProtocolFee() - reverts when non owner", async function () {
  247. await router.createPool(poolId, fakeContract.address, decimals, decimals, "x", "x*")
  248. await router.setProtocolFeeOwner(owner.address)
  249. await expect(router.withdrawProtocolFee(poolId, alice.address)).to.not.be.revertedWith("Stargate: only protocolFeeOwner")
  250. })
  251. })