Skip to content

Commit 710951e

Browse files
Merge pull request #301 from consenlabs/v6-update-strategy-tests
V6 update strategy tests
2 parents d894011 + 1a215df commit 710951e

18 files changed

+113
-69
lines changed

test/forkMainnet/GenericSwap.t.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ import { SigHelper } from "test/utils/SigHelper.sol";
88
import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol";
99
import { computeContractAddress } from "test/utils/Addresses.sol";
1010
import { Permit2Helper } from "test/utils/Permit2Helper.sol";
11+
import { UniswapV3 } from "test/utils/UniswapV3.sol";
12+
import { IUniswapV3Quoter } from "test/utils/IUniswapV3Quoter.sol";
13+
import { IUniswapSwapRouter02 } from "test/utils/IUniswapSwapRouter02.sol";
1114
import { MockStrategy } from "test/mocks/MockStrategy.sol";
1215
import { GenericSwap } from "contracts/GenericSwap.sol";
1316
import { AllowanceTarget } from "contracts/AllowanceTarget.sol";
1417
import { TokenCollector } from "contracts/abstracts/TokenCollector.sol";
1518
import { SmartOrderStrategy } from "contracts/SmartOrderStrategy.sol";
1619
import { Constant } from "contracts/libraries/Constant.sol";
17-
import { UniswapV3 } from "contracts/libraries/UniswapV3.sol";
1820
import { GenericSwapData, getGSDataHash } from "contracts/libraries/GenericSwapData.sol";
1921
import { IGenericSwap } from "contracts/interfaces/IGenericSwap.sol";
2022
import { ISmartOrderStrategy } from "contracts/interfaces/ISmartOrderStrategy.sol";
21-
import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol";
22-
import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol";
2323

2424
contract GenericSwapTest is Test, Tokens, BalanceUtil, Permit2Helper, SigHelper {
2525
using BalanceSnapshot for Snapshot;

test/forkMainnet/SmartOrderStrategy/AMMs.t.sol

Lines changed: 82 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,34 @@ import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
55
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
66

77
import { SmartOrderStrategyTest } from "./Setup.t.sol";
8-
import { ICurveFiV2 } from "contracts/interfaces/ICurveFiV2.sol";
8+
import { ICurveFiV2 } from "test/utils/ICurveFiV2.sol";
99
import { ISmartOrderStrategy } from "contracts/interfaces/ISmartOrderStrategy.sol";
10-
import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol";
10+
import { IUniswapSwapRouter02 } from "test/utils/IUniswapSwapRouter02.sol";
1111
import { Constant } from "contracts/libraries/Constant.sol";
1212
import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol";
1313
import { UniswapV2Library } from "test/utils/UniswapV2Library.sol";
14+
import { UniswapV3 } from "test/utils/UniswapV3.sol";
1415

1516
contract 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

test/forkMainnet/SmartOrderStrategy/Setup.t.sol

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import { Test } from "forge-std/Test.sol";
55
import { SmartOrderStrategy } from "contracts/SmartOrderStrategy.sol";
66
import { Tokens } from "test/utils/Tokens.sol";
77
import { BalanceUtil } from "test/utils/BalanceUtil.sol";
8+
import { IUniswapV3Quoter } from "test/utils/IUniswapV3Quoter.sol";
9+
import { UniswapV3 } from "test/utils/UniswapV3.sol";
810

911
contract SmartOrderStrategyTest is Test, Tokens, BalanceUtil {
1012
address strategyOwner = makeAddr("strategyOwner");
@@ -15,11 +17,16 @@ contract SmartOrderStrategyTest is Test, Tokens, BalanceUtil {
1517
uint128 defaultInputRatio = 5000;
1618
uint256 defaultExpiry = block.timestamp + 100;
1719
bytes defaultOpsData;
18-
address[] defaultUniV2Path = [USDC_ADDRESS, WETH_ADDRESS];
20+
bytes encodedUniv3Path;
21+
address[] defaultUniV2Path = [defaultInputToken, defaultOutputToken];
1922
address[] tokenList = [USDT_ADDRESS, USDC_ADDRESS, WETH_ADDRESS, WBTC_ADDRESS];
20-
address[] ammList = [UNISWAP_SWAP_ROUTER_02_ADDRESS, SUSHISWAP_ADDRESS, CURVE_TRICRYPTO2_POOL_ADDRESS];
23+
address[] ammList = [UNISWAP_SWAP_ROUTER_02_ADDRESS, CURVE_TRICRYPTO2_POOL_ADDRESS];
24+
25+
uint24 defaultFee = 3000;
26+
uint24[] v3Fees = [defaultFee];
2127

2228
SmartOrderStrategy smartOrderStrategy;
29+
IUniswapV3Quoter v3Quoter;
2330

2431
function setUp() public virtual {
2532
// Deploy and setup SmartOrderStrategy
@@ -36,6 +43,9 @@ contract SmartOrderStrategyTest is Test, Tokens, BalanceUtil {
3643
SmartOrderStrategy.Operation[] memory operations = new SmartOrderStrategy.Operation[](1);
3744
defaultOpsData = abi.encode(operations);
3845

46+
v3Quoter = IUniswapV3Quoter(UNISWAP_V3_QUOTER_ADDRESS);
47+
encodedUniv3Path = UniswapV3.encodePath(defaultUniV2Path, v3Fees);
48+
3949
vm.label(UNISWAP_UNIVERSAL_ROUTER_ADDRESS, "UniswapUniversalRouter");
4050
}
4151
}

test/forkMainnet/UniAgent/SwapRouter02.t.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity 0.8.17;
33

4-
import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol";
5-
import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol";
4+
import { IUniswapSwapRouter02 } from "test/utils/IUniswapSwapRouter02.sol";
5+
import { IUniswapV3Quoter } from "test/utils/IUniswapV3Quoter.sol";
66
import { IUniAgent } from "contracts/interfaces/IUniAgent.sol";
7-
import { UniswapV3 } from "contracts/libraries/UniswapV3.sol";
7+
import { UniswapV3 } from "test/utils/UniswapV3.sol";
88
import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol";
99
import { UniswapV2Library } from "test/utils/UniswapV2Library.sol";
1010
import { UniAgentTest } from "test/forkMainnet/UniAgent/Setup.t.sol";

test/forkMainnet/UniAgent/Universal.t.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity 0.8.17;
33

4-
import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol";
5-
import { IUniversalRouter } from "contracts/interfaces/IUniswapUniversalRouter.sol";
4+
import { IUniswapV3Quoter } from "test/utils/IUniswapV3Quoter.sol";
5+
import { IUniversalRouter } from "test/utils/IUniswapUniversalRouter.sol";
66
import { IUniAgent } from "contracts/interfaces/IUniAgent.sol";
7-
import { UniswapV3 } from "contracts/libraries/UniswapV3.sol";
7+
import { UniswapV3 } from "test/utils/UniswapV3.sol";
88
import { UniswapCommands } from "test/utils/UniswapCommands.sol";
99
import { UniswapV2Library } from "test/utils/UniswapV2Library.sol";
1010
import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol";

test/forkMainnet/UniAgent/V2.t.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
pragma solidity 0.8.17;
33

44
import { IUniAgent } from "contracts/interfaces/IUniAgent.sol";
5-
import { IUniswapV2Router } from "contracts/interfaces/IUniswapV2Router.sol";
5+
import { IUniswapV2Router } from "test/utils/IUniswapV2Router.sol";
66
import { Constant } from "contracts/libraries/Constant.sol";
77
import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol";
88
import { UniswapV2Library } from "test/utils/UniswapV2Library.sol";

test/forkMainnet/UniAgent/V3.t.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity 0.8.17;
33

4-
import { IUniswapV3Quoter } from "contracts/interfaces/IUniswapV3Quoter.sol";
5-
import { IUniswapV3SwapRouter } from "contracts/interfaces/IUniswapV3SwapRouter.sol";
4+
import { IUniswapV3Quoter } from "test/utils/IUniswapV3Quoter.sol";
5+
import { IUniswapV3SwapRouter } from "test/utils/IUniswapV3SwapRouter.sol";
66
import { IUniAgent } from "contracts/interfaces/IUniAgent.sol";
7-
import { UniswapV3 } from "contracts/libraries/UniswapV3.sol";
7+
import { UniswapV3 } from "test/utils/UniswapV3.sol";
88
import { BalanceSnapshot, Snapshot } from "test/utils/BalanceSnapshot.sol";
99
import { UniAgentTest } from "test/forkMainnet/UniAgent/Setup.t.sol";
1010

test/mocks/MockLimitOrderTaker.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.s
66

77
import { Ownable } from "contracts/abstracts/Ownable.sol";
88
import { IStrategy } from "contracts/interfaces/IStrategy.sol";
9-
import { IUniswapSwapRouter02 } from "contracts/interfaces/IUniswapSwapRouter02.sol";
9+
import { IUniswapSwapRouter02 } from "test/utils/IUniswapSwapRouter02.sol";
1010
import { MockERC1271Wallet } from "./MockERC1271Wallet.sol";
1111

1212
contract MockLimitOrderTaker is IStrategy, MockERC1271Wallet {

test/utils/Addresses.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ function readAddresses(Vm vm) view returns (string memory data) {
3838
string memory fileName;
3939
if (chainId == 1) {
4040
fileName = "test/utils/config/mainnet.json";
41+
} else if (chainId == 137) {
42+
fileName = "test/utils/config/polygon.json";
4143
} else if (chainId == 5) {
4244
fileName = "test/utils/config/goerli.json";
4345
} else if (chainId == 42161) {
File renamed without changes.

0 commit comments

Comments
 (0)