@@ -5,25 +5,34 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
55import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol " ;
66
77import { SmartOrderStrategyTest } from "./Setup.t.sol " ;
8- import { ICurveFiV2 } from "contracts/interfaces /ICurveFiV2.sol " ;
8+ import { ICurveFiV2 } from "test/utils /ICurveFiV2.sol " ;
99import { ISmartOrderStrategy } from "contracts/interfaces/ISmartOrderStrategy.sol " ;
10- import { IUniswapSwapRouter02 } from "contracts/interfaces /IUniswapSwapRouter02.sol " ;
10+ import { IUniswapSwapRouter02 } from "test/utils /IUniswapSwapRouter02.sol " ;
1111import { Constant } from "contracts/libraries/Constant.sol " ;
1212import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol " ;
1313import { UniswapV2Library } from "test/utils/UniswapV2Library.sol " ;
14+ import { UniswapV3 } from "test/utils/UniswapV3.sol " ;
1415
1516contract AMMsTest is SmartOrderStrategyTest {
1617 using SafeERC20 for IERC20 ;
1718 using BalanceSnapshot for Snapshot;
1819
19- function testUniswapV2WithoutAmountReplace () public {
20- bytes memory uniswapData = abi.encodeWithSelector (
21- IUniswapSwapRouter02.swapExactTokensForTokens.selector ,
22- defaultInputAmount,
23- 0 , // minOutputAmount
24- defaultUniV2Path,
25- address (smartOrderStrategy)
20+ function testUniswapV3WithoutAmountReplace () public {
21+ bytes memory uniswapData = abi.encodeCall (
22+ IUniswapSwapRouter02.exactInputSingle,
23+ (
24+ IUniswapSwapRouter02.ExactInputSingleParams ({
25+ tokenIn: defaultInputToken,
26+ tokenOut: defaultOutputToken,
27+ fee: defaultFee,
28+ recipient: address (smartOrderStrategy),
29+ amountIn: defaultInputAmount,
30+ amountOutMinimum: 0 ,
31+ sqrtPriceLimitX96: 0
32+ })
33+ )
2634 );
35+
2736 ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation [](1 );
2837 operations[0 ] = ISmartOrderStrategy.Operation ({
2938 dest: UNISWAP_SWAP_ROUTER_02_ADDRESS,
@@ -36,8 +45,7 @@ contract AMMsTest is SmartOrderStrategyTest {
3645 bytes memory data = abi.encode (operations);
3746
3847 // get the exact quote from uniswap
39- uint256 [] memory amounts = UniswapV2Library.getAmountsOut (defaultInputAmount, defaultUniV2Path);
40- uint256 expectedOut = amounts[amounts.length - 1 ];
48+ uint256 expectedOut = v3Quoter.quoteExactInput (encodedUniv3Path, defaultInputAmount);
4149
4250 vm.startPrank (genericSwap, genericSwap);
4351 IERC20 (defaultInputToken).safeTransfer (address (smartOrderStrategy), defaultInputAmount);
@@ -50,29 +58,35 @@ contract AMMsTest is SmartOrderStrategyTest {
5058 gsOutputToken.assertChange (int256 (expectedOut));
5159 }
5260
53- function testUniswapV2WithAmountReplace () public {
54- bytes memory uniswapData = abi.encodeWithSelector (
55- IUniswapSwapRouter02.swapExactTokensForTokens.selector ,
56- defaultInputAmount,
57- 0 ,
58- defaultUniV2Path,
59- address (smartOrderStrategy)
61+ function testUniswapV3WithAmountReplace () public {
62+ bytes memory uniswapData = abi.encodeCall (
63+ IUniswapSwapRouter02.exactInputSingle,
64+ (
65+ IUniswapSwapRouter02.ExactInputSingleParams ({
66+ tokenIn: defaultInputToken,
67+ tokenOut: defaultOutputToken,
68+ fee: defaultFee,
69+ recipient: address (smartOrderStrategy),
70+ amountIn: defaultInputAmount,
71+ amountOutMinimum: 0 ,
72+ sqrtPriceLimitX96: 0
73+ })
74+ )
6075 );
6176 ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation [](1 );
6277 operations[0 ] = ISmartOrderStrategy.Operation ({
6378 dest: UNISWAP_SWAP_ROUTER_02_ADDRESS,
6479 inputToken: defaultInputToken,
6580 inputRatio: defaultInputRatio,
66- dataOffset: uint128 (4 + 32 ), // add 32 bytes of length prefix
81+ dataOffset: uint128 (4 + 32 + 128 ), // add 32 bytes of length prefix
6782 value: 0 ,
6883 data: uniswapData
6984 });
7085 bytes memory data = abi.encode (operations);
7186
7287 // get the exact quote from uniswap
7388 uint256 inputAmountAfterRatio = (defaultInputAmount * defaultInputRatio) / Constant.BPS_MAX;
74- uint256 [] memory amounts = UniswapV2Library.getAmountsOut (inputAmountAfterRatio, defaultUniV2Path);
75- uint256 expectedOut = amounts[amounts.length - 1 ];
89+ uint256 expectedOut = v3Quoter.quoteExactInput (encodedUniv3Path, inputAmountAfterRatio);
7690
7791 vm.startPrank (genericSwap, genericSwap);
7892 IERC20 (defaultInputToken).safeTransfer (address (smartOrderStrategy), defaultInputAmount);
@@ -85,20 +99,27 @@ contract AMMsTest is SmartOrderStrategyTest {
8599 gsOutputToken.assertChange (int256 (expectedOut));
86100 }
87101
88- function testUniswapV2WithMaxAmountReplace () public {
89- bytes memory uniswapData = abi.encodeWithSelector (
90- IUniswapSwapRouter02.swapExactTokensForTokens.selector ,
91- defaultInputAmount,
92- 0 ,
93- defaultUniV2Path,
94- address (smartOrderStrategy)
102+ function testUniswapV3WithMaxAmountReplace () public {
103+ bytes memory uniswapData = abi.encodeCall (
104+ IUniswapSwapRouter02.exactInputSingle,
105+ (
106+ IUniswapSwapRouter02.ExactInputSingleParams ({
107+ tokenIn: defaultInputToken,
108+ tokenOut: defaultOutputToken,
109+ fee: defaultFee,
110+ recipient: address (smartOrderStrategy),
111+ amountIn: defaultInputAmount,
112+ amountOutMinimum: 0 ,
113+ sqrtPriceLimitX96: 0
114+ })
115+ )
95116 );
96117 ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation [](1 );
97118 operations[0 ] = ISmartOrderStrategy.Operation ({
98119 dest: UNISWAP_SWAP_ROUTER_02_ADDRESS,
99120 inputToken: defaultInputToken,
100121 inputRatio: Constant.BPS_MAX, // BPS_MAX indicate the input amount will be replaced by the actual balance
101- dataOffset: uint128 (4 + 32 ), // add 32 bytes of length prefix
122+ dataOffset: uint128 (4 + 32 + 128 ), // add 32 bytes of length prefix
102123 value: 0 ,
103124 data: uniswapData
104125 });
@@ -108,8 +129,7 @@ contract AMMsTest is SmartOrderStrategyTest {
108129 uint256 actualInputAmount = 5678 ;
109130
110131 // get the exact quote from uniswap
111- uint256 [] memory amounts = UniswapV2Library.getAmountsOut (actualInputAmount, defaultUniV2Path);
112- uint256 expectedOut = amounts[amounts.length - 1 ];
132+ uint256 expectedOut = v3Quoter.quoteExactInput (encodedUniv3Path, actualInputAmount);
113133
114134 vm.startPrank (genericSwap, genericSwap);
115135 IERC20 (defaultInputToken).safeTransfer (address (smartOrderStrategy), actualInputAmount);
@@ -124,14 +144,21 @@ contract AMMsTest is SmartOrderStrategyTest {
124144 }
125145
126146 function testUniswapV2WithWETHUnwrap () public {
127- bytes memory uniswapData = abi.encodeWithSelector (
128- IUniswapSwapRouter02.swapExactTokensForTokens.selector ,
129- defaultInputAmount,
130- 0 , // minOutputAmount
131- defaultUniV2Path,
132- address (smartOrderStrategy)
147+ bytes memory uniswapData = abi.encodeCall (
148+ IUniswapSwapRouter02.exactInputSingle,
149+ (
150+ IUniswapSwapRouter02.ExactInputSingleParams ({
151+ tokenIn: defaultInputToken,
152+ tokenOut: defaultOutputToken,
153+ fee: defaultFee,
154+ recipient: address (smartOrderStrategy),
155+ amountIn: defaultInputAmount,
156+ amountOutMinimum: 0 ,
157+ sqrtPriceLimitX96: 0
158+ })
159+ )
133160 );
134- ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation [](2 );
161+ ISmartOrderStrategy.Operation[] memory operations = new ISmartOrderStrategy.Operation [](1 );
135162 operations[0 ] = ISmartOrderStrategy.Operation ({
136163 dest: UNISWAP_SWAP_ROUTER_02_ADDRESS,
137164 inputToken: defaultInputToken,
@@ -143,8 +170,7 @@ contract AMMsTest is SmartOrderStrategyTest {
143170 bytes memory data = abi.encode (operations);
144171
145172 // get the exact quote from uniswap
146- uint256 [] memory amounts = UniswapV2Library.getAmountsOut (defaultInputAmount, defaultUniV2Path);
147- uint256 expectedOut = amounts[amounts.length - 1 ];
173+ uint256 expectedOut = v3Quoter.quoteExactInput (encodedUniv3Path, defaultInputAmount);
148174
149175 // set output token as ETH
150176 address outputToken = Constant.ETH_ADDRESS;
@@ -160,20 +186,26 @@ contract AMMsTest is SmartOrderStrategyTest {
160186 }
161187
162188 function testMultipleAMMs () public {
163- // (USDC -> USDT) via UniswapV2 + Curve
189+ // (USDC -> USDT) via UniswapV3 + Curve
164190 // UniswapV2 : USDC -> WETH
165191 // Curve : WETH -> USDT
166192
167193 // get the exact quote from uniswap
168- uint256 [] memory amounts = UniswapV2Library.getAmountsOut (defaultInputAmount, defaultUniV2Path);
169- uint256 uniOut = amounts[amounts.length - 1 ];
170-
171- bytes memory uniswapData = abi.encodeWithSelector (
172- IUniswapSwapRouter02.swapExactTokensForTokens.selector ,
173- defaultInputAmount,
174- 0 , // minOutputAmount
175- defaultUniV2Path,
176- address (smartOrderStrategy)
194+ uint256 uniOut = v3Quoter.quoteExactInput (encodedUniv3Path, defaultInputAmount);
195+
196+ bytes memory uniswapData = abi.encodeCall (
197+ IUniswapSwapRouter02.exactInputSingle,
198+ (
199+ IUniswapSwapRouter02.ExactInputSingleParams ({
200+ tokenIn: defaultInputToken,
201+ tokenOut: defaultOutputToken,
202+ fee: defaultFee,
203+ recipient: address (smartOrderStrategy),
204+ amountIn: defaultInputAmount,
205+ amountOutMinimum: 0 ,
206+ sqrtPriceLimitX96: 0
207+ })
208+ )
177209 );
178210
179211 // exhange function selector : 0x5b41b908
0 commit comments