diff --git a/test/forkMainnet/GenericSwap.t.sol b/test/forkMainnet/GenericSwap.t.sol index c356f9b2..af32c268 100644 --- a/test/forkMainnet/GenericSwap.t.sol +++ b/test/forkMainnet/GenericSwap.t.sol @@ -12,11 +12,14 @@ import { MockStrategy } from "test/mocks/MockStrategy.sol"; import { GenericSwap } from "contracts/GenericSwap.sol"; import { AllowanceTarget } from "contracts/AllowanceTarget.sol"; import { TokenCollector } from "contracts/abstracts/TokenCollector.sol"; -import { UniswapStrategy } from "contracts/UniswapStrategy.sol"; +import { SmartOrderStrategy } from "contracts/SmartOrderStrategy.sol"; import { Constant } from "contracts/libraries/Constant.sol"; +import { UniswapV3 } from "contracts/libraries/UniswapV3.sol"; import { GenericSwapData, getGSDataHash } from "contracts/libraries/GenericSwapData.sol"; import { IGenericSwap } from "contracts/interfaces/IGenericSwap.sol"; -import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol"; +import { ISmartOrderStrategy } from "contracts/interfaces/ISmartOrderStrategy.sol"; +import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol"; +import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol"; contract GenericSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelper { using BalanceSnapshot for Snapshot; @@ -37,8 +40,13 @@ contract GenericSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelper uint256 takerPrivateKey = uint256(1); address taker = vm.addr(takerPrivateKey); uint256 defaultExpiry = block.timestamp + 1; + address defaultInputToken = USDT_ADDRESS; + uint256 defaultInputAmount = 10 * 1e6; + address defaultOutputToken = DAI_ADDRESS; + address[] defaultPath = [defaultInputToken, defaultOutputToken]; + uint24[] defaultV3Fees = [3000]; bytes defaultTakerPermit; - UniswapStrategy uniswapStrategy; + SmartOrderStrategy smartStrategy; GenericSwap genericSwap; GenericSwapData defaultGSData; MockStrategy mockStrategy; @@ -53,16 +61,43 @@ contract GenericSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelper allowanceTarget = new AllowanceTarget(allowanceTargetOwner, trusted); genericSwap = new GenericSwap(UNISWAP_PERMIT2_ADDRESS, address(allowanceTarget)); - uniswapStrategy = new UniswapStrategy(strategyAdmin, address(genericSwap), UNISWAP_V2_ADDRESS); + smartStrategy = new SmartOrderStrategy(strategyAdmin, address(genericSwap), WETH_ADDRESS); mockStrategy = new MockStrategy(); vm.prank(strategyAdmin); - uniswapStrategy.approveToken(USDT_ADDRESS, UNISWAP_V2_ADDRESS, type(uint256).max); - - address[] memory defaultPath = new address[](2); - defaultPath[0] = USDT_ADDRESS; - defaultPath[1] = DAI_ADDRESS; - bytes memory makerSpecificData = abi.encode(defaultExpiry, defaultPath); - bytes memory swapData = abi.encode(UNISWAP_V2_ADDRESS, makerSpecificData); + address[] memory tokenList = new address[](1); + tokenList[0] = USDT_ADDRESS; + address[] memory ammList = new address[](1); + ammList[0] = UNISWAP_SWAP_ROUTER_02_ADDRESS; + smartStrategy.approveTokens(tokenList, ammList); + + IUniswapV3Quoter v3Quoter = IUniswapV3Quoter(UNISWAP_V3_QUOTER_ADDRESS); + bytes memory encodedPath = UniswapV3.encodePath(defaultPath, defaultV3Fees); + uint256 expectedOut = v3Quoter.quoteExactInput(encodedPath, defaultInputAmount); + uint256 minOutputAmount = (expectedOut * 95) / 100; // default 5% slippage tolerance + bytes memory routerPayload = abi.encodeCall( + IUniswapSwapRouter02.exactInputSingle, + ( + IUniswapSwapRouter02.ExactInputSingleParams({ + tokenIn: defaultInputToken, + tokenOut: defaultOutputToken, + fee: defaultV3Fees[0], + recipient: address(smartStrategy), + amountIn: defaultInputAmount, + amountOutMinimum: minOutputAmount, + sqrtPriceLimitX96: 0 + }) + ) + ); + ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation[](1); + operations[0] = ISmartOrderStrategy.Operation({ + dest: UNISWAP_SWAP_ROUTER_02_ADDRESS, + inputToken: defaultInputToken, + inputRatio: 0, // zero ratio indicate no replacement + dataOffset: 0, + value: 0, + data: routerPayload + }); + bytes memory swapData = abi.encode(operations); deal(taker, 100 ether); setTokenBalanceAndApprove(taker, UNISWAP_PERMIT2_ADDRESS, tokens, 100000); @@ -70,12 +105,12 @@ contract GenericSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelper setTokenBalanceAndApprove(address(mockStrategy), UNISWAP_PERMIT2_ADDRESS, tokens, 100000); defaultGSData = GenericSwapData({ - maker: payable(address(uniswapStrategy)), - takerToken: USDT_ADDRESS, - takerTokenAmount: 10 * 1e6, - makerToken: DAI_ADDRESS, - makerTokenAmount: 0, // to be filled later - minMakerTokenAmount: 0, // to be filled later + maker: payable(address(smartStrategy)), + takerToken: defaultInputToken, + takerTokenAmount: defaultInputAmount, + makerToken: defaultOutputToken, + makerTokenAmount: expectedOut, + minMakerTokenAmount: minOutputAmount, expiry: defaultExpiry, salt: 5678, recipient: payable(taker), @@ -83,13 +118,6 @@ contract GenericSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelper }); defaultTakerPermit = getTokenlonPermit2Data(taker, takerPrivateKey, defaultGSData.takerToken, address(genericSwap)); - - IUniswapRouterV2 router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = router.getAmountsOut(defaultGSData.takerTokenAmount, defaultPath); - uint256 expectedOut = amounts[amounts.length - 1]; - // update defaultGSData - defaultGSData.makerTokenAmount = expectedOut; - defaultGSData.minMakerTokenAmount = (expectedOut * 95) / 100; // default 5% slippage tolerance } function testGenericSwapWithUniswap() public { diff --git a/test/forkMainnet/LimitOrderSwap/CoordinatedTaker.t.sol b/test/forkMainnet/LimitOrderSwap/CoordinatedTaker.t.sol index 778cc351..078005e0 100644 --- a/test/forkMainnet/LimitOrderSwap/CoordinatedTaker.t.sol +++ b/test/forkMainnet/LimitOrderSwap/CoordinatedTaker.t.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.17; -import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol"; import { ILimitOrderSwap } from "contracts/interfaces/ILimitOrderSwap.sol"; import { ICoordinatedTaker } from "contracts/interfaces/ICoordinatedTaker.sol"; import { IWETH } from "contracts/interfaces/IWETH.sol"; @@ -25,7 +24,7 @@ contract CoordinatedTakerTest is LimitOrderSwapTest { address user = vm.addr(userPrivateKey); address[] tokenList = [USDC_ADDRESS, USDT_ADDRESS, DAI_ADDRESS, WETH_ADDRESS, WBTC_ADDRESS]; - address[] ammList = [UNISWAP_V2_ADDRESS, SUSHISWAP_ADDRESS]; + address[] ammList = [UNISWAP_SWAP_ROUTER_02_ADDRESS, SUSHISWAP_ADDRESS]; uint256 crdPrivateKey = uint256(2); address coordinator = vm.addr(crdPrivateKey); diff --git a/test/forkMainnet/LimitOrderSwap/Fill.t.sol b/test/forkMainnet/LimitOrderSwap/Fill.t.sol index 001f2e96..88f62088 100644 --- a/test/forkMainnet/LimitOrderSwap/Fill.t.sol +++ b/test/forkMainnet/LimitOrderSwap/Fill.t.sol @@ -4,11 +4,11 @@ pragma solidity 0.8.17; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; -import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol"; import { ILimitOrderSwap } from "contracts/interfaces/ILimitOrderSwap.sol"; import { Constant } from "contracts/libraries/Constant.sol"; import { LimitOrder, getLimitOrderHash } from "contracts/libraries/LimitOrder.sol"; import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol"; +import { UniswapV2Library } from "test/utils/UniswapV2Library.sol"; import { LimitOrderSwapTest } from "test/forkMainnet/LimitOrderSwap/Setup.t.sol"; import { MockStrategy } from "test/mocks/MockStrategy.sol"; @@ -74,8 +74,7 @@ contract FillTest is LimitOrderSwapTest { uint256 fee = (order.makerTokenAmount * defaultFeeFactor) / Constant.BPS_MAX; { // update order takerTokenAmount by AMM quote - IUniswapRouterV2 router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = router.getAmountsOut(defaultOrder.makerTokenAmount - fee, defaultAMMPath); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultOrder.makerTokenAmount - fee, defaultAMMPath); order.takerTokenAmount = amounts[amounts.length - 1]; } @@ -83,8 +82,8 @@ contract FillTest is LimitOrderSwapTest { bytes memory extraAction; { - bytes memory makerSpecificData = abi.encode(defaultExpiry, defaultAMMPath); - bytes memory strategyData = abi.encode(UNISWAP_V2_ADDRESS, makerSpecificData); + bytes memory makerSpecificData = abi.encode(defaultAMMPath); + bytes memory strategyData = abi.encode(UNISWAP_SWAP_ROUTER_02_ADDRESS, makerSpecificData); extraAction = abi.encode(address(mockLimitOrderTaker), strategyData); } diff --git a/test/forkMainnet/LimitOrderSwap/Setup.t.sol b/test/forkMainnet/LimitOrderSwap/Setup.t.sol index 8ec59032..116f2a1e 100644 --- a/test/forkMainnet/LimitOrderSwap/Setup.t.sol +++ b/test/forkMainnet/LimitOrderSwap/Setup.t.sol @@ -62,7 +62,7 @@ contract LimitOrderSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelp allowanceTarget = new AllowanceTarget(allowanceTargetOwner, trusted); limitOrderSwap = new LimitOrderSwap(limitOrderOwner, UNISWAP_PERMIT2_ADDRESS, address(allowanceTarget), IWETH(WETH_ADDRESS), feeCollector); - mockLimitOrderTaker = new MockLimitOrderTaker(walletOwner, UNISWAP_V2_ADDRESS); + mockLimitOrderTaker = new MockLimitOrderTaker(walletOwner, UNISWAP_SWAP_ROUTER_02_ADDRESS); deal(maker, 100 ether); setTokenBalanceAndApprove(maker, UNISWAP_PERMIT2_ADDRESS, tokens, 100000); @@ -76,7 +76,7 @@ contract LimitOrderSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelp tokenList[0] = DAI_ADDRESS; tokenList[1] = USDT_ADDRESS; vm.startPrank(walletOwner); - mockLimitOrderTaker.setAllowance(tokenList, UNISWAP_V2_ADDRESS); + mockLimitOrderTaker.setAllowance(tokenList, UNISWAP_SWAP_ROUTER_02_ADDRESS); vm.stopPrank(); defaultOrder = LimitOrder({ diff --git a/test/forkMainnet/SmartOrderStrategy/AMMs.t.sol b/test/forkMainnet/SmartOrderStrategy/AMMs.t.sol index 56a7a793..db956d0d 100644 --- a/test/forkMainnet/SmartOrderStrategy/AMMs.t.sol +++ b/test/forkMainnet/SmartOrderStrategy/AMMs.t.sol @@ -5,11 +5,12 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { SmartOrderStrategyTest } from "./Setup.t.sol"; -import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol"; import { ICurveFiV2 } from "contracts/interfaces/ICurveFiV2.sol"; import { ISmartOrderStrategy } from "contracts/interfaces/ISmartOrderStrategy.sol"; +import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol"; import { Constant } from "contracts/libraries/Constant.sol"; import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol"; +import { UniswapV2Library } from "test/utils/UniswapV2Library.sol"; contract AMMsTest is SmartOrderStrategyTest { using SafeERC20 for IERC20; @@ -17,16 +18,15 @@ contract AMMsTest is SmartOrderStrategyTest { function testUniswapV2WithoutAmountReplace() public { bytes memory uniswapData = abi.encodeWithSelector( - IUniswapRouterV2.swapExactTokensForTokens.selector, + IUniswapSwapRouter02.swapExactTokensForTokens.selector, defaultInputAmount, 0, // minOutputAmount defaultUniV2Path, - address(smartOrderStrategy), - defaultExpiry + address(smartOrderStrategy) ); ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation[](1); operations[0] = ISmartOrderStrategy.Operation({ - dest: UNISWAP_V2_ADDRESS, + dest: UNISWAP_SWAP_ROUTER_02_ADDRESS, inputToken: defaultInputToken, inputRatio: 0, // zero ratio indicate no replacement dataOffset: 0, @@ -36,8 +36,7 @@ contract AMMsTest is SmartOrderStrategyTest { bytes memory data = abi.encode(operations); // get the exact quote from uniswap - IUniswapRouterV2 router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = router.getAmountsOut(defaultInputAmount, defaultUniV2Path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, defaultUniV2Path); uint256 expectedOut = amounts[amounts.length - 1]; vm.startPrank(genericSwap, genericSwap); @@ -53,16 +52,15 @@ contract AMMsTest is SmartOrderStrategyTest { function testUniswapV2WithAmountReplace() public { bytes memory uniswapData = abi.encodeWithSelector( - IUniswapRouterV2.swapExactTokensForTokens.selector, + IUniswapSwapRouter02.swapExactTokensForTokens.selector, defaultInputAmount, 0, defaultUniV2Path, - address(smartOrderStrategy), - defaultExpiry + address(smartOrderStrategy) ); ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation[](1); operations[0] = ISmartOrderStrategy.Operation({ - dest: UNISWAP_V2_ADDRESS, + dest: UNISWAP_SWAP_ROUTER_02_ADDRESS, inputToken: defaultInputToken, inputRatio: defaultInputRatio, dataOffset: uint128(4 + 32), // add 32 bytes of length prefix @@ -73,8 +71,7 @@ contract AMMsTest is SmartOrderStrategyTest { // get the exact quote from uniswap uint256 inputAmountAfterRatio = (defaultInputAmount * defaultInputRatio) / Constant.BPS_MAX; - IUniswapRouterV2 router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = router.getAmountsOut(inputAmountAfterRatio, defaultUniV2Path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(inputAmountAfterRatio, defaultUniV2Path); uint256 expectedOut = amounts[amounts.length - 1]; vm.startPrank(genericSwap, genericSwap); @@ -90,16 +87,15 @@ contract AMMsTest is SmartOrderStrategyTest { function testUniswapV2WithMaxAmountReplace() public { bytes memory uniswapData = abi.encodeWithSelector( - IUniswapRouterV2.swapExactTokensForTokens.selector, + IUniswapSwapRouter02.swapExactTokensForTokens.selector, defaultInputAmount, 0, defaultUniV2Path, - address(smartOrderStrategy), - defaultExpiry + address(smartOrderStrategy) ); ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation[](1); operations[0] = ISmartOrderStrategy.Operation({ - dest: UNISWAP_V2_ADDRESS, + dest: UNISWAP_SWAP_ROUTER_02_ADDRESS, inputToken: defaultInputToken, inputRatio: Constant.BPS_MAX, // BPS_MAX indicate the input amount will be replaced by the actual balance dataOffset: uint128(4 + 32), // add 32 bytes of length prefix @@ -112,8 +108,7 @@ contract AMMsTest is SmartOrderStrategyTest { uint256 actualInputAmount = 5678; // get the exact quote from uniswap - IUniswapRouterV2 router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = router.getAmountsOut(actualInputAmount, defaultUniV2Path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(actualInputAmount, defaultUniV2Path); uint256 expectedOut = amounts[amounts.length - 1]; vm.startPrank(genericSwap, genericSwap); @@ -130,16 +125,15 @@ contract AMMsTest is SmartOrderStrategyTest { function testUniswapV2WithWETHUnwrap() public { bytes memory uniswapData = abi.encodeWithSelector( - IUniswapRouterV2.swapExactTokensForTokens.selector, + IUniswapSwapRouter02.swapExactTokensForTokens.selector, defaultInputAmount, 0, // minOutputAmount defaultUniV2Path, - address(smartOrderStrategy), - defaultExpiry + address(smartOrderStrategy) ); ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation[](2); operations[0] = ISmartOrderStrategy.Operation({ - dest: UNISWAP_V2_ADDRESS, + dest: UNISWAP_SWAP_ROUTER_02_ADDRESS, inputToken: defaultInputToken, inputRatio: 0, // zero ratio indicate no replacement dataOffset: 0, @@ -149,8 +143,7 @@ contract AMMsTest is SmartOrderStrategyTest { bytes memory data = abi.encode(operations); // get the exact quote from uniswap - IUniswapRouterV2 router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = router.getAmountsOut(defaultInputAmount, defaultUniV2Path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, defaultUniV2Path); uint256 expectedOut = amounts[amounts.length - 1]; // set output token as ETH @@ -172,17 +165,15 @@ contract AMMsTest is SmartOrderStrategyTest { // Curve : WETH -> USDT // get the exact quote from uniswap - IUniswapRouterV2 router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = router.getAmountsOut(defaultInputAmount, defaultUniV2Path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, defaultUniV2Path); uint256 uniOut = amounts[amounts.length - 1]; bytes memory uniswapData = abi.encodeWithSelector( - IUniswapRouterV2.swapExactTokensForTokens.selector, + IUniswapSwapRouter02.swapExactTokensForTokens.selector, defaultInputAmount, 0, // minOutputAmount defaultUniV2Path, - address(smartOrderStrategy), - defaultExpiry + address(smartOrderStrategy) ); // exhange function selector : 0x5b41b908 @@ -192,7 +183,7 @@ contract AMMsTest is SmartOrderStrategyTest { ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation[](2); operations[0] = ISmartOrderStrategy.Operation({ - dest: UNISWAP_V2_ADDRESS, + dest: UNISWAP_SWAP_ROUTER_02_ADDRESS, inputToken: USDC_ADDRESS, inputRatio: 0, // zero ratio indicate no replacement dataOffset: 0, diff --git a/test/forkMainnet/SmartOrderStrategy/Setup.t.sol b/test/forkMainnet/SmartOrderStrategy/Setup.t.sol index ccdcbe69..2f55b813 100644 --- a/test/forkMainnet/SmartOrderStrategy/Setup.t.sol +++ b/test/forkMainnet/SmartOrderStrategy/Setup.t.sol @@ -17,7 +17,7 @@ contract SmartOrderStrategyTest is Test, Tokens, BalanceUtil { bytes defaultOpsData; address[] defaultUniV2Path = [USDC_ADDRESS, WETH_ADDRESS]; address[] tokenList = [USDT_ADDRESS, USDC_ADDRESS, WETH_ADDRESS, WBTC_ADDRESS]; - address[] ammList = [UNISWAP_V2_ADDRESS, SUSHISWAP_ADDRESS, CURVE_TRICRYPTO2_POOL_ADDRESS]; + address[] ammList = [UNISWAP_SWAP_ROUTER_02_ADDRESS, SUSHISWAP_ADDRESS, CURVE_TRICRYPTO2_POOL_ADDRESS]; SmartOrderStrategy smartOrderStrategy; diff --git a/test/forkMainnet/UniAgent/SwapRouter02.t.sol b/test/forkMainnet/UniAgent/SwapRouter02.t.sol index 764dbd4f..9c2369c1 100644 --- a/test/forkMainnet/UniAgent/SwapRouter02.t.sol +++ b/test/forkMainnet/UniAgent/SwapRouter02.t.sol @@ -1,18 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.17; -import { ISwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol"; -import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol"; +import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol"; import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol"; import { IUniAgent } from "contracts/interfaces/IUniAgent.sol"; import { UniswapV3 } from "contracts/libraries/UniswapV3.sol"; import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol"; +import { UniswapV2Library } from "test/utils/UniswapV2Library.sol"; import { UniAgentTest } from "test/forkMainnet/UniAgent/Setup.t.sol"; contract SwapRouter02Test is UniAgentTest { using BalanceSnapshot for Snapshot; - IUniswapRouterV2 v2Router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); IUniswapV3Quoter v3Quoter = IUniswapV3Quoter(UNISWAP_V3_QUOTER_ADDRESS); uint256 defaultOutputAmount; uint24 defaultFee = 3000; @@ -27,10 +26,10 @@ contract SwapRouter02Test is UniAgentTest { Snapshot memory userInputToken = BalanceSnapshot.take({ owner: user, token: defaultInputToken }); Snapshot memory recvOutputToken = BalanceSnapshot.take({ owner: recipient, token: defaultOutputToken }); - uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, defaultPath); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, defaultPath); uint256 outputAmount = amounts[amounts.length - 1]; uint256 minOutputAmount = (defaultOutputAmount * 95) / 100; // default 5% slippage tolerance - bytes memory payload = abi.encodeCall(ISwapRouter02.swapExactTokensForTokens, (defaultInputAmount, minOutputAmount, defaultPath, recipient)); + bytes memory payload = abi.encodeCall(IUniswapSwapRouter02.swapExactTokensForTokens, (defaultInputAmount, minOutputAmount, defaultPath, recipient)); vm.prank(user); uniAgent.swap(IUniAgent.RouterType.SwapRouter02, defaultInputToken, defaultInputAmount, payload, defaultUserPermit); @@ -49,9 +48,9 @@ contract SwapRouter02Test is UniAgentTest { defaultOutputAmount = v3Quoter.quoteExactInput(encodedPath, defaultInputAmount); uint256 minOutputAmount = (defaultOutputAmount * 95) / 100; // default 5% slippage tolerance bytes memory payload = abi.encodeCall( - ISwapRouter02.exactInputSingle, + IUniswapSwapRouter02.exactInputSingle, ( - ISwapRouter02.ExactInputSingleParams({ + IUniswapSwapRouter02.ExactInputSingleParams({ tokenIn: defaultInputToken, tokenOut: defaultOutputToken, fee: defaultFee, diff --git a/test/forkMainnet/UniAgent/Universal.t.sol b/test/forkMainnet/UniAgent/Universal.t.sol index 7d2a91d7..53c8be1e 100644 --- a/test/forkMainnet/UniAgent/Universal.t.sol +++ b/test/forkMainnet/UniAgent/Universal.t.sol @@ -1,36 +1,24 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.17; -import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol"; import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol"; import { IUniversalRouter } from "contracts/interfaces/IUniswapUniversalRouter.sol"; import { IUniAgent } from "contracts/interfaces/IUniAgent.sol"; import { UniswapV3 } from "contracts/libraries/UniswapV3.sol"; import { UniswapCommands } from "test/utils/UniswapCommands.sol"; +import { UniswapV2Library } from "test/utils/UniswapV2Library.sol"; import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol"; import { UniAgentTest } from "test/forkMainnet/UniAgent/Setup.t.sol"; contract UniversalTest is UniAgentTest { using BalanceSnapshot for Snapshot; - IUniswapRouterV2 v2Router; IUniswapV3Quoter v3Quoter; - uint256 defaultOutputAmount; - bytes defaultRouterPayload; function setUp() public override { super.setUp(); - v2Router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); v3Quoter = IUniswapV3Quoter(UNISWAP_V3_QUOTER_ADDRESS); - uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, defaultPath); - defaultOutputAmount = amounts[amounts.length - 1]; - uint256 minOutputAmount = (defaultOutputAmount * 95) / 100; // default 5% slippage tolerance - - bytes memory cmds = abi.encodePacked(bytes1(uint8(UniswapCommands.V2_SWAP_EXACT_IN))); - bytes[] memory inputs = new bytes[](1); - inputs[0] = abi.encode(recipient, defaultInputAmount, minOutputAmount, defaultPath, false); - defaultRouterPayload = abi.encodeCall(IUniversalRouter.execute, (cmds, inputs, defaultExpiry)); } function testURV2SwapExactIn() public { @@ -38,12 +26,21 @@ contract UniversalTest is UniAgentTest { Snapshot memory userInputToken = BalanceSnapshot.take({ owner: user, token: defaultInputToken }); Snapshot memory recvOutputToken = BalanceSnapshot.take({ owner: recipient, token: defaultOutputToken }); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, defaultPath); + uint256 outputAmount = amounts[amounts.length - 1]; + uint256 minOutputAmount = (outputAmount * 95) / 100; // default 5% slippage tolerance + + bytes memory cmds = abi.encodePacked(bytes1(uint8(UniswapCommands.V2_SWAP_EXACT_IN))); + bytes[] memory inputs = new bytes[](1); + inputs[0] = abi.encode(recipient, defaultInputAmount, minOutputAmount, defaultPath, false); + bytes memory payload = abi.encodeCall(IUniversalRouter.execute, (cmds, inputs, defaultExpiry)); + vm.prank(user); - uniAgent.swap(IUniAgent.RouterType.UniversalRouter, defaultInputToken, defaultInputAmount, defaultRouterPayload, defaultUserPermit); + uniAgent.swap(IUniAgent.RouterType.UniversalRouter, defaultInputToken, defaultInputAmount, payload, defaultUserPermit); userInputToken.assertChange(-int256(defaultInputAmount)); // recipient should receive exact amount of quote from Uniswap - recvOutputToken.assertChange(int256(defaultOutputAmount)); + recvOutputToken.assertChange(int256(outputAmount)); } function testURV3SwapExactIn() public { @@ -72,8 +69,13 @@ contract UniversalTest is UniAgentTest { function testURHandleRouterError() public { vm.warp(defaultExpiry + 1); + bytes memory cmds = abi.encodePacked(bytes1(uint8(UniswapCommands.V2_SWAP_EXACT_IN))); + bytes[] memory inputs = new bytes[](1); + inputs[0] = abi.encode(recipient, defaultInputAmount, 0, defaultPath, false); + bytes memory payload = abi.encodeCall(IUniversalRouter.execute, (cmds, inputs, defaultExpiry)); + vm.expectRevert(IUniversalRouter.TransactionDeadlinePassed.selector); vm.prank(user); - uniAgent.swap(IUniAgent.RouterType.UniversalRouter, defaultInputToken, defaultInputAmount, defaultRouterPayload, defaultUserPermit); + uniAgent.swap(IUniAgent.RouterType.UniversalRouter, defaultInputToken, defaultInputAmount, payload, defaultUserPermit); } } diff --git a/test/forkMainnet/UniAgent/V2.t.sol b/test/forkMainnet/UniAgent/V2.t.sol index ae997ff0..a56eddc0 100644 --- a/test/forkMainnet/UniAgent/V2.t.sol +++ b/test/forkMainnet/UniAgent/V2.t.sol @@ -1,29 +1,28 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.17; -import { IUniswapRouterV2 } from "contracts//interfaces/IUniswapRouterV2.sol"; import { IUniAgent } from "contracts/interfaces/IUniAgent.sol"; +import { IUniswapV2Router } from "contracts/interfaces/IUniswapV2Router.sol"; import { Constant } from "contracts/libraries/Constant.sol"; import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol"; +import { UniswapV2Library } from "test/utils/UniswapV2Library.sol"; import { UniAgentTest } from "test/forkMainnet/UniAgent/Setup.t.sol"; contract V2Test is UniAgentTest { using BalanceSnapshot for Snapshot; - IUniswapRouterV2 v2Router; uint256 defaultOutputAmount; bytes defaultRouterPayload; function setUp() public override { super.setUp(); - v2Router = IUniswapRouterV2(UNISWAP_V2_ADDRESS); - uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, defaultPath); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, defaultPath); defaultOutputAmount = amounts[amounts.length - 1]; uint256 minOutputAmount = (defaultOutputAmount * 95) / 100; // default 5% slippage tolerance defaultRouterPayload = abi.encodeCall( - IUniswapRouterV2.swapExactTokensForTokens, + IUniswapV2Router.swapExactTokensForTokens, (defaultInputAmount, minOutputAmount, defaultPath, recipient, defaultExpiry) ); } @@ -52,10 +51,10 @@ contract V2Test is UniAgentTest { Snapshot memory userInputToken = BalanceSnapshot.take({ owner: user, token: inputToken }); Snapshot memory recvOutputToken = BalanceSnapshot.take({ owner: recipient, token: path[1] }); - uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, path); uint256 outputAmount = amounts[amounts.length - 1]; - bytes memory payload = abi.encodeCall(IUniswapRouterV2.swapExactETHForTokens, (outputAmount, path, recipient, defaultExpiry)); + bytes memory payload = abi.encodeCall(IUniswapV2Router.swapExactETHForTokens, (outputAmount, path, recipient, defaultExpiry)); vm.prank(user); uniAgent.swap{ value: defaultInputAmount }(IUniAgent.RouterType.V2Router, inputToken, defaultInputAmount, payload, defaultUserPermit); @@ -76,10 +75,10 @@ contract V2Test is UniAgentTest { Snapshot memory userInputToken = BalanceSnapshot.take({ owner: user, token: path[0] }); Snapshot memory recvOutputToken = BalanceSnapshot.take({ owner: recipient, token: outputToken }); - uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, path); uint256 outputAmount = amounts[amounts.length - 1]; - bytes memory payload = abi.encodeCall(IUniswapRouterV2.swapExactTokensForETH, (defaultInputAmount, outputAmount, path, recipient, defaultExpiry)); + bytes memory payload = abi.encodeCall(IUniswapV2Router.swapExactTokensForETH, (defaultInputAmount, outputAmount, path, recipient, defaultExpiry)); vm.prank(user); uniAgent.swap(IUniAgent.RouterType.V2Router, path[0], defaultInputAmount, payload, defaultUserPermit); @@ -99,10 +98,10 @@ contract V2Test is UniAgentTest { path[0] = inputToken; path[1] = defaultOutputToken; - uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, path); uint256 outputAmount = amounts[amounts.length - 1]; - bytes memory payload = abi.encodeCall(IUniswapRouterV2.swapExactTokensForTokens, (defaultInputAmount, outputAmount, path, recipient, defaultExpiry)); + bytes memory payload = abi.encodeCall(IUniswapV2Router.swapExactTokensForTokens, (defaultInputAmount, outputAmount, path, recipient, defaultExpiry)); bytes memory userPermit = getTokenlonPermit2Data(user, userPrivateKey, inputToken, address(uniAgent)); vm.prank(user); @@ -130,10 +129,10 @@ contract V2Test is UniAgentTest { path[0] = inputToken; path[1] = defaultOutputToken; - uint256[] memory amounts = v2Router.getAmountsOut(defaultInputAmount, path); + uint256[] memory amounts = UniswapV2Library.getAmountsOut(defaultInputAmount, path); uint256 outputAmount = amounts[amounts.length - 1]; - bytes memory payload = abi.encodeCall(IUniswapRouterV2.swapExactTokensForTokens, (defaultInputAmount, outputAmount, path, recipient, defaultExpiry)); + bytes memory payload = abi.encodeCall(IUniswapV2Router.swapExactTokensForTokens, (defaultInputAmount, outputAmount, path, recipient, defaultExpiry)); bytes memory userPermit = getTokenlonPermit2Data(user, userPrivateKey, inputToken, address(uniAgent)); // should still succeed even re-approve the token diff --git a/test/mocks/MockLimitOrderTaker.sol b/test/mocks/MockLimitOrderTaker.sol index d49e5ecb..4cf2487f 100644 --- a/test/mocks/MockLimitOrderTaker.sol +++ b/test/mocks/MockLimitOrderTaker.sol @@ -6,30 +6,29 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s import { Ownable } from "contracts/abstracts/Ownable.sol"; import { IStrategy } from "contracts/interfaces/IStrategy.sol"; -import { IUniswapRouterV2 } from "contracts/interfaces/IUniswapRouterV2.sol"; +import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol"; import { MockERC1271Wallet } from "./MockERC1271Wallet.sol"; contract MockLimitOrderTaker is IStrategy, MockERC1271Wallet { using SafeERC20 for IERC20; - IUniswapRouterV2 public immutable uniswapV2Router; + IUniswapSwapRouter02 public immutable uniswapRouter02; - constructor(address _operator, address _uniswapV2Router) MockERC1271Wallet(_operator) { - uniswapV2Router = IUniswapRouterV2(_uniswapV2Router); + constructor(address _operator, address _uniswapRouter02) MockERC1271Wallet(_operator) { + uniswapRouter02 = IUniswapSwapRouter02(_uniswapRouter02); } function executeStrategy(address inputToken, address outputToken, uint256 inputAmount, bytes calldata data) external payable override { (address routerAddr, bytes memory makerSpecificData) = abi.decode(data, (address, bytes)); - require(routerAddr == address(uniswapV2Router), "non supported protocol"); + require(routerAddr == address(uniswapRouter02), "non supported protocol"); - (uint256 deadline, address[] memory path) = abi.decode(makerSpecificData, (uint256, address[])); + address[] memory path = abi.decode(makerSpecificData, (address[])); _validateAMMPath(inputToken, outputToken, path); - _tradeUniswapV2TokenToToken(inputAmount, deadline, path); + _tradeUniswapV2TokenToToken(inputAmount, path); } - function _tradeUniswapV2TokenToToken(uint256 _inputAmount, uint256 _deadline, address[] memory _path) internal returns (uint256) { - uint256[] memory amounts = uniswapV2Router.swapExactTokensForTokens(_inputAmount, 0, _path, address(this), _deadline); - return amounts[amounts.length - 1]; + function _tradeUniswapV2TokenToToken(uint256 _inputAmount, address[] memory _path) internal returns (uint256) { + return uniswapRouter02.swapExactTokensForTokens(_inputAmount, 0, _path, address(this)); } function _validateAMMPath(address _inputToken, address _outputToken, address[] memory _path) internal pure { diff --git a/test/utils/Addresses.sol b/test/utils/Addresses.sol index 9cff5279..0583940c 100644 --- a/test/utils/Addresses.sol +++ b/test/utils/Addresses.sol @@ -17,9 +17,9 @@ contract Addresses is Test { address CURVE_TRICRYPTO2_POOL_ADDRESS = abi.decode(vm.parseJson(file, "$.CURVE_TRICRYPTO2_POOL_ADDRESS"), (address)); address SUSHISWAP_ADDRESS = abi.decode(vm.parseJson(file, "$.SUSHISWAP_ADDRESS"), (address)); - address UNISWAP_V2_ADDRESS = abi.decode(vm.parseJson(file, "$.UNISWAP_V2_ADDRESS"), (address)); address UNISWAP_V3_QUOTER_ADDRESS = abi.decode(vm.parseJson(file, "$.UNISWAP_V3_QUOTER_ADDRESS"), (address)); address UNISWAP_PERMIT2_ADDRESS = abi.decode(vm.parseJson(file, "$.UNISWAP_PERMIT2_ADDRESS"), (address)); + address UNISWAP_SWAP_ROUTER_02_ADDRESS = abi.decode(vm.parseJson(file, "$.UNISWAP_SWAP_ROUTER_02_ADDRESS"), (address)); address UNISWAP_UNIVERSAL_ROUTER_ADDRESS = abi.decode(vm.parseJson(file, "$.UNISWAP_UNIVERSAL_ROUTER_ADDRESS"), (address)); function getChainId() internal view returns (uint256 chainId) { diff --git a/test/utils/UniswapV2Library.sol b/test/utils/UniswapV2Library.sol new file mode 100644 index 00000000..5739ead0 --- /dev/null +++ b/test/utils/UniswapV2Library.sol @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.17; + +interface IUniswapV2Pair { + event Approval(address indexed owner, address indexed spender, uint256 value); + event Transfer(address indexed from, address indexed to, uint256 value); + + function name() external pure returns (string memory); + + function symbol() external pure returns (string memory); + + function decimals() external pure returns (uint8); + + function totalSupply() external view returns (uint256); + + function balanceOf(address owner) external view returns (uint256); + + function allowance(address owner, address spender) external view returns (uint256); + + function approve(address spender, uint256 value) external returns (bool); + + function transfer(address to, uint256 value) external returns (bool); + + function transferFrom(address from, address to, uint256 value) external returns (bool); + + function DOMAIN_SEPARATOR() external view returns (bytes32); + + function PERMIT_TYPEHASH() external pure returns (bytes32); + + function nonces(address owner) external view returns (uint256); + + function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; + + event Mint(address indexed sender, uint256 amount0, uint256 amount1); + event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to); + event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to); + event Sync(uint112 reserve0, uint112 reserve1); + + function MINIMUM_LIQUIDITY() external pure returns (uint256); + + function factory() external view returns (address); + + function token0() external view returns (address); + + function token1() external view returns (address); + + function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); + + function price0CumulativeLast() external view returns (uint256); + + function price1CumulativeLast() external view returns (uint256); + + function kLast() external view returns (uint256); + + function mint(address to) external returns (uint256 liquidity); + + function burn(address to) external returns (uint256 amount0, uint256 amount1); + + function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external; + + function skim(address to) external; + + function sync() external; + + function initialize(address, address) external; +} + +library UniswapV2Library { + address constant factory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f; + + // returns sorted token addresses, used to handle return values from pairs sorted in this order + function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { + require(tokenA != tokenB, "UniswapV2Library: IDENTICAL_ADDRESSES"); + (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); + require(token0 != address(0), "UniswapV2Library: ZERO_ADDRESS"); + } + + // calculates the CREATE2 address for a pair without making any external calls + function pairFor(address tokenA, address tokenB) internal pure returns (address pair) { + (address token0, address token1) = sortTokens(tokenA, tokenB); + pair = address( + uint160( + uint256( + keccak256( + abi.encodePacked( + hex"ff", + factory, + keccak256(abi.encodePacked(token0, token1)), + hex"96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f" // init code hash + ) + ) + ) + ) + ); + } + + // fetches and sorts the reserves for a pair + function getReserves(address tokenA, address tokenB) internal view returns (uint256 reserveA, uint256 reserveB) { + (address token0, ) = sortTokens(tokenA, tokenB); + (uint256 reserve0, uint256 reserve1, ) = IUniswapV2Pair(pairFor(tokenA, tokenB)).getReserves(); + (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); + } + + // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset + function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut) internal pure returns (uint256 amountOut) { + require(amountIn > 0, "UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT"); + require(reserveIn > 0 && reserveOut > 0, "UniswapV2Library: INSUFFICIENT_LIQUIDITY"); + uint256 amountInWithFee = amountIn * 997; + uint256 numerator = amountInWithFee * reserveOut; + uint256 denominator = (reserveIn * 1000) + amountInWithFee; + amountOut = numerator / denominator; + } + + // performs chained getAmountOut calculations on any number of pairs + function getAmountsOut(uint256 amountIn, address[] memory path) internal view returns (uint256[] memory amounts) { + require(path.length >= 2, "UniswapV2Library: INVALID_PATH"); + amounts = new uint256[](path.length); + amounts[0] = amountIn; + for (uint256 i; i < path.length - 1; i++) { + (uint256 reserveIn, uint256 reserveOut) = getReserves(path[i], path[i + 1]); + amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); + } + } +} diff --git a/test/utils/config/arbitrumMainnet.json b/test/utils/config/arbitrumMainnet.json index c4dca60f..179c3409 100644 --- a/test/utils/config/arbitrumMainnet.json +++ b/test/utils/config/arbitrumMainnet.json @@ -10,8 +10,8 @@ "CURVE_TRICRYPTO2_POOL_ADDRESS": "0x0000000000000000000000000000000000000000", "SUSHISWAP_ADDRESS": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", - "UNISWAP_V2_ADDRESS": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", "UNISWAP_V3_QUOTER_ADDRESS": "0x0000000000000000000000000000000000000000", "UNISWAP_PERMIT2_ADDRESS": "0x000000000022d473030f116ddee9f6b43ac78ba3", + "UNISWAP_SWAP_ROUTER_02_ADDRESS": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "UNISWAP_UNIVERSAL_ROUTER_ADDRESS": "0x4648a43B2C14Da09FdF82B161150d3F634f40491" } diff --git a/test/utils/config/goerli.json b/test/utils/config/goerli.json index 1b55c1ee..30f49ed3 100644 --- a/test/utils/config/goerli.json +++ b/test/utils/config/goerli.json @@ -10,8 +10,8 @@ "CURVE_TRICRYPTO2_POOL_ADDRESS": "0x0000000000000000000000000000000000000000", "SUSHISWAP_ADDRESS": "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", - "UNISWAP_V2_ADDRESS": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", "UNISWAP_V3_QUOTER_ADDRESS": "0x0000000000000000000000000000000000000000", "UNISWAP_PERMIT2_ADDRESS": "0x000000000022d473030f116ddee9f6b43ac78ba3", + "UNISWAP_SWAP_ROUTER_02_ADDRESS": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "UNISWAP_UNIVERSAL_ROUTER_ADDRESS": "0x4648a43B2C14Da09FdF82B161150d3F634f40491" } diff --git a/test/utils/config/local.json b/test/utils/config/local.json index 13b5f884..dd01cfb0 100644 --- a/test/utils/config/local.json +++ b/test/utils/config/local.json @@ -10,8 +10,8 @@ "CURVE_TRICRYPTO2_POOL_ADDRESS": "0x000000000000000000000000000000000000000", "SUSHISWAP_ADDRESS": "0x000000000000000000000000000000000000000", - "UNISWAP_V2_ADDRESS": "0x000000000000000000000000000000000000000", "UNISWAP_V3_QUOTER_ADDRESS": "0x000000000000000000000000000000000000000", "UNISWAP_PERMIT2_ADDRESS": "0x000000000000000000000000000000000000000", + "UNISWAP_SWAP_ROUTER_02_ADDRESS": "0x000000000000000000000000000000000000000", "UNISWAP_UNIVERSAL_ROUTER_ADDRESS": "0x000000000000000000000000000000000000000" } diff --git a/test/utils/config/mainnet.json b/test/utils/config/mainnet.json index c91686df..6755532a 100644 --- a/test/utils/config/mainnet.json +++ b/test/utils/config/mainnet.json @@ -10,8 +10,8 @@ "CURVE_TRICRYPTO2_POOL_ADDRESS": "0x80466c64868E1ab14a1Ddf27A676C3fcBE638Fe5", "SUSHISWAP_ADDRESS": "0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F", - "UNISWAP_V2_ADDRESS": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", "UNISWAP_V3_QUOTER_ADDRESS": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", "UNISWAP_PERMIT2_ADDRESS": "0x000000000022d473030f116ddee9f6b43ac78ba3", + "UNISWAP_SWAP_ROUTER_02_ADDRESS": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", "UNISWAP_UNIVERSAL_ROUTER_ADDRESS": "0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B" } diff --git a/test/utils/config/polygon.json b/test/utils/config/polygon.json new file mode 100644 index 00000000..4bb9a1c9 --- /dev/null +++ b/test/utils/config/polygon.json @@ -0,0 +1,17 @@ +{ + "WETH_ADDRESS": "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "USDT_ADDRESS": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "USDC_ADDRESS": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174", + "CRV_ADDRESS": "0x172370d5Cd63279eFa6d502DAB29171933a610AF", + "TUSD_ADDRESS": "0x2e1AD108fF1D8C782fcBbB89AAd783aC49586756", + "DAI_ADDRESS": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", + "LON_ADDRESS": "0x6f7C932e7684666C9fd1d44527765433e01fF61d", + "WBTC_ADDRESS": "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6", + + "CURVE_TRICRYPTO2_POOL_ADDRESS": "0x000000000000000000000000000000000000000", + "SUSHISWAP_ADDRESS": "0x000000000000000000000000000000000000000", + "UNISWAP_V3_QUOTER_ADDRESS": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6", + "UNISWAP_PERMIT2_ADDRESS": "0x000000000022d473030f116ddee9f6b43ac78ba3", + "UNISWAP_SWAP_ROUTER_02_ADDRESS": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", + "UNISWAP_UNIVERSAL_ROUTER_ADDRESS": "0x3fC91A3afd70395Cd496C647d5a6CC9D4B2b7FAD" +}