feat: add cyclicSwapAmountOut tracker in _swap, add split cylic tests

This commit is contained in:
royvardhan
2025-03-06 22:00:25 +05:30
parent 66c00df4f1
commit 4d67df4096
3 changed files with 75 additions and 36 deletions

View File

@@ -329,6 +329,7 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
uint256[] memory remainingAmounts = new uint256[](nTokens);
uint256[] memory amounts = new uint256[](nTokens);
uint256 cyclicSwapAmountOut = 0;
amounts[0] = amountIn;
remainingAmounts[0] = amountIn;
@@ -345,13 +346,15 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
currentAmountOut = _callExecutor(
swapData.executor(), currentAmountIn, swapData.protocolData()
);
amounts[tokenOutIndex] = tokenOutIndex == 0
? currentAmountOut
: amounts[tokenOutIndex] + currentAmountOut;
if (tokenOutIndex == 0) {
cyclicSwapAmountOut += currentAmountOut;
} else {
amounts[tokenOutIndex] += currentAmountOut;
}
remainingAmounts[tokenOutIndex] += currentAmountOut;
remainingAmounts[tokenInIndex] -= currentAmountIn;
}
return amounts[tokenOutIndex];
return tokenOutIndex == 0 ? cyclicSwapAmountOut : amounts[tokenOutIndex];
}
/**

View File

@@ -45,6 +45,7 @@ contract Constants is Test, BaseConstants {
address DAI_USDC_POOL = 0xAE461cA67B15dc8dc81CE7615e0320dA1A9aB8D5;
address WETH_WBTC_POOL = 0xBb2b8038a1640196FbE3e38816F3e67Cba72D940;
address USDC_WBTC_POOL = 0x004375Dff511095CC5A197A54140a24eFEF3A416;
address USDC_WETH_USV2 = 0xB4e16d0168e52d35CaCD2c6185b44281Ec28C9Dc;
// Uniswap v3
address USV3_FACTORY_ETHEREUM = 0x1F98431c8aD98523631AE4a59f267346ea31F984;

View File

@@ -1195,26 +1195,26 @@ contract TychoRouterTest is TychoRouterTestSetup {
function testCyclicSequentialSwap() public {
// This test has start and end tokens that are the same
// The flow is:
// USDC -> WETH -> USDC -> WETH -> USDC using two pools, and four swaps
// USDC -> WETH -> USDC using two pools
uint256 amountIn = 100 * 10 ** 6;
deal(USDC_ADDR, tychoRouterAddr, amountIn);
bytes memory usdcWethPoolOneZeroForOneData = encodeUniswapV3Swap(
bytes memory usdcWethV3Pool1ZeroOneData = encodeUniswapV3Swap(
USDC_ADDR, WETH_ADDR, tychoRouterAddr, USDC_WETH_USV3, true
);
bytes memory usdcWethPoolTwoOneForZeroData = encodeUniswapV3Swap(
bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap(
WETH_ADDR, USDC_ADDR, tychoRouterAddr, USDC_WETH_USV3_2, false
);
bytes[] memory swaps = new bytes[](4);
bytes[] memory swaps = new bytes[](2);
// USDC -> WETH
swaps[0] = encodeSwap(
uint8(0),
uint8(1),
uint24(0),
address(usv3Executor),
usdcWethPoolOneZeroForOneData
usdcWethV3Pool1ZeroOneData
);
// WETH -> USDC
swaps[1] = encodeSwap(
@@ -1222,30 +1222,14 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(0),
uint24(0),
address(usv3Executor),
usdcWethPoolTwoOneForZeroData
);
// USDC -> WETH
swaps[2] = encodeSwap(
uint8(0),
uint8(1),
uint24(0),
address(usv3Executor),
usdcWethPoolOneZeroForOneData
);
// WETH -> USDC
swaps[3] = encodeSwap(
uint8(1),
uint8(0),
uint24(0),
address(usv3Executor),
usdcWethPoolTwoOneForZeroData
usdcWethV3Pool2OneZeroData
);
tychoRouter.exposedSwap(amountIn, 2, pleEncode(swaps));
assertEq(IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), 99778590);
assertEq(IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), 99889294);
}
function testCyclicSplitSwap() public {
function testSplitInputCyclicSwap() public {
// This test has start and end tokens that are the same
// The flow is:
// ┌─── WETH (Pool 1) ───┐
@@ -1259,18 +1243,18 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint256 amountIn = 100 * 10 ** 6;
deal(USDC_ADDR, tychoRouterAddr, amountIn);
bytes memory usdcWethPoolOneZeroForOneData = encodeUniswapV3Swap(
bytes memory usdcWethV3Pool1ZeroOneData = encodeUniswapV3Swap(
USDC_ADDR, WETH_ADDR, tychoRouterAddr, USDC_WETH_USV3, true
);
bytes memory usdcWethPoolOneOneForZeroData = encodeUniswapV3Swap(
bytes memory usdcWethV3Pool1OneZeroData = encodeUniswapV3Swap(
WETH_ADDR, USDC_ADDR, tychoRouterAddr, USDC_WETH_USV3, false
);
bytes memory usdcWethPoolTwoZeroForOneData = encodeUniswapV3Swap(
bytes memory usdcWethV3Pool2ZeroOneData = encodeUniswapV3Swap(
USDC_ADDR, WETH_ADDR, tychoRouterAddr, USDC_WETH_USV3_2, true
);
bytes memory usdcWethPoolTwoOneForZeroData = encodeUniswapV3Swap(
bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap(
WETH_ADDR, USDC_ADDR, tychoRouterAddr, USDC_WETH_USV3_2, false
);
@@ -1281,7 +1265,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(1),
(0xffffff * 60) / 100, // 60%
address(usv3Executor),
usdcWethPoolOneZeroForOneData
usdcWethV3Pool1ZeroOneData
);
// WETH -> USDC
swaps[1] = encodeSwap(
@@ -1289,7 +1273,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(0),
uint24(0),
address(usv3Executor),
usdcWethPoolTwoOneForZeroData
usdcWethV3Pool2OneZeroData
);
// USDC -> WETH
@@ -1298,7 +1282,7 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(1),
uint24(0),
address(usv3Executor),
usdcWethPoolTwoZeroForOneData
usdcWethV3Pool2ZeroOneData
);
// WETH -> USDC
@@ -1307,12 +1291,63 @@ contract TychoRouterTest is TychoRouterTestSetup {
uint8(0),
uint24(0),
address(usv3Executor),
usdcWethPoolOneOneForZeroData
usdcWethV3Pool1OneZeroData
);
tychoRouter.exposedSwap(amountIn, 2, pleEncode(swaps));
assertEq(IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), 99345512);
}
function testSplitOutputCyclicSwap() public {
// This test has start and end tokens that are the same
// The flow is:
// ┌─── WETH (Pool 2, 60% split) ───┐
// │ │
// USDC ----─┤ ├─> USDC
// │ │
// └─── WETH (Pool 2, the rest) ───┘
//
uint256 amountIn = 100 * 10 ** 6;
deal(USDC_ADDR, tychoRouterAddr, amountIn);
bytes memory usdcWethV2Data = encodeUniswapV2Swap(
USDC_ADDR, USDC_WETH_USV2, tychoRouterAddr, true
);
bytes memory usdcWethV3Pool1OneZeroData = encodeUniswapV3Swap(
WETH_ADDR, USDC_ADDR, tychoRouterAddr, USDC_WETH_USV3, false
);
bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap(
WETH_ADDR, USDC_ADDR, tychoRouterAddr, USDC_WETH_USV3_2, false
);
bytes[] memory swaps = new bytes[](3);
// USDC -> WETH
swaps[0] = encodeSwap(
uint8(0), uint8(1), uint24(0), address(usv2Executor), usdcWethV2Data
);
// WETH -> USDC
swaps[1] = encodeSwap(
uint8(1),
uint8(0),
(0xffffff * 60) / 100,
address(usv3Executor),
usdcWethV3Pool1OneZeroData
);
// WETH -> USDC
swaps[2] = encodeSwap(
uint8(1),
uint8(0),
uint24(0),
address(usv3Executor),
usdcWethV3Pool2OneZeroData
);
tychoRouter.exposedSwap(amountIn, 2, pleEncode(swaps));
assertEq(IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), 99525908);
}
// Base Network Tests
// Make sure to set the RPC_URL to base network
function testSwapSingleBase() public {