feat: Support new transfer logic in all executors
TODO: - Fix failing tests - Remove permit2 from initialization of contracts
This commit is contained in:
@@ -26,7 +26,8 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
|
||||
USDE_ADDR,
|
||||
USDT_ADDR,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL,
|
||||
true, // permit2 transferFrom to protocol
|
||||
false, // transfer to protocol
|
||||
ALICE,
|
||||
pools
|
||||
);
|
||||
@@ -44,6 +45,8 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
false,
|
||||
address(0),
|
||||
swap
|
||||
);
|
||||
|
||||
@@ -74,7 +77,8 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
|
||||
USDE_ADDR,
|
||||
WBTC_ADDR,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL,
|
||||
true, // permit2 transferFrom to protocol
|
||||
false, // transfer to protocol
|
||||
ALICE,
|
||||
pools
|
||||
);
|
||||
@@ -83,7 +87,16 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
|
||||
encodeSingleSwap(address(usv4Executor), protocolData);
|
||||
|
||||
tychoRouter.singleSwap(
|
||||
amountIn, USDE_ADDR, WBTC_ADDR, 118280, false, false, ALICE, swap
|
||||
amountIn,
|
||||
USDE_ADDR,
|
||||
WBTC_ADDR,
|
||||
118280,
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
false,
|
||||
address(0),
|
||||
swap
|
||||
);
|
||||
|
||||
assertEq(IERC20(WBTC_ADDR).balanceOf(ALICE), 118281);
|
||||
@@ -262,7 +275,8 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
DAI_WETH_USV3,
|
||||
zeroForOne,
|
||||
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
|
||||
true, // permit2 transferFrom to protocol
|
||||
false // transfer to protocol
|
||||
);
|
||||
bytes memory swap =
|
||||
encodeSingleSwap(address(usv3Executor), protocolData);
|
||||
@@ -277,6 +291,8 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
false,
|
||||
address(0),
|
||||
swap
|
||||
);
|
||||
|
||||
|
||||
@@ -8,25 +8,21 @@ import "./executors/UniswapV4Utils.sol";
|
||||
import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol";
|
||||
|
||||
contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
function _getSequentialSwaps(bool permit2)
|
||||
internal
|
||||
view
|
||||
returns (bytes[] memory)
|
||||
{
|
||||
function _getSequentialSwaps() internal view returns (bytes[] memory) {
|
||||
// Trade 1 WETH for USDC through DAI with 2 swaps on Uniswap V2
|
||||
// 1 WETH -> DAI -> USDC
|
||||
// (univ2) (univ2)
|
||||
|
||||
TokenTransfer.TransferType transferType = permit2
|
||||
? TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
|
||||
: TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL;
|
||||
|
||||
bytes[] memory swaps = new bytes[](2);
|
||||
// WETH -> DAI
|
||||
swaps[0] = encodeSequentialSwap(
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false, transferType
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
DAI_USDC_POOL, // receiver (direct to next pool)
|
||||
false,
|
||||
false // transfer to protocol from router
|
||||
)
|
||||
);
|
||||
|
||||
@@ -38,7 +34,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
DAI_USDC_POOL,
|
||||
ALICE,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false // transfer to protocol from router
|
||||
)
|
||||
);
|
||||
return swaps;
|
||||
@@ -55,7 +51,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
bytes memory signature
|
||||
) = handlePermit2Approval(WETH_ADDR, tychoRouterAddr, amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSequentialSwaps(true);
|
||||
bytes[] memory swaps = _getSequentialSwaps();
|
||||
tychoRouter.sequentialSwapPermit2(
|
||||
amountIn,
|
||||
WETH_ADDR,
|
||||
@@ -66,6 +62,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
|
||||
@@ -82,7 +80,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(tychoRouterAddr, amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSequentialSwaps(false);
|
||||
bytes[] memory swaps = _getSequentialSwaps();
|
||||
tychoRouter.sequentialSwap(
|
||||
amountIn,
|
||||
WETH_ADDR,
|
||||
@@ -91,6 +89,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
|
||||
@@ -107,7 +107,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(tychoRouterAddr, amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSequentialSwaps(false);
|
||||
bytes[] memory swaps = _getSequentialSwaps();
|
||||
vm.expectRevert(TychoRouter__UndefinedMinAmountOut.selector);
|
||||
tychoRouter.sequentialSwap(
|
||||
amountIn,
|
||||
@@ -117,6 +117,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
}
|
||||
@@ -129,7 +131,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(tychoRouterAddr, amountIn - 1);
|
||||
|
||||
bytes[] memory swaps = _getSequentialSwaps(false);
|
||||
bytes[] memory swaps = _getSequentialSwaps();
|
||||
vm.expectRevert();
|
||||
tychoRouter.sequentialSwap(
|
||||
amountIn,
|
||||
@@ -139,6 +141,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
}
|
||||
@@ -154,7 +158,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
bytes memory signature
|
||||
) = handlePermit2Approval(WETH_ADDR, tychoRouterAddr, amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSequentialSwaps(true);
|
||||
bytes[] memory swaps = _getSequentialSwaps();
|
||||
|
||||
uint256 minAmountOut = 3000 * 1e18;
|
||||
|
||||
@@ -175,6 +179,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
vm.stopPrank();
|
||||
@@ -202,24 +208,14 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
swaps[0] = encodeSequentialSwap(
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
tychoRouterAddr,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false, true
|
||||
)
|
||||
);
|
||||
|
||||
// DAI -> USDC
|
||||
swaps[1] = encodeSequentialSwap(
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
DAI_ADDR,
|
||||
DAI_USDC_POOL,
|
||||
ALICE,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
)
|
||||
encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, ALICE, true, true)
|
||||
);
|
||||
|
||||
uint256 amountOut = tychoRouter.sequentialSwapPermit2{value: amountIn}(
|
||||
@@ -232,6 +228,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
emptyPermitSingle,
|
||||
"",
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
uint256 expectedAmount = 2005810530;
|
||||
@@ -262,11 +260,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
swaps[0] = encodeSequentialSwap(
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
USDC_ADDR,
|
||||
DAI_USDC_POOL,
|
||||
tychoRouterAddr,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
|
||||
USDC_ADDR, DAI_USDC_POOL, tychoRouterAddr, false, false
|
||||
)
|
||||
);
|
||||
|
||||
@@ -274,11 +268,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
swaps[1] = encodeSequentialSwap(
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
DAI_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
tychoRouterAddr,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true, true
|
||||
)
|
||||
);
|
||||
|
||||
@@ -292,6 +282,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true,
|
||||
DAI_USDC_POOL,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
|
||||
@@ -315,7 +307,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
tychoRouterAddr,
|
||||
USDC_WETH_USV3,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap(
|
||||
@@ -324,7 +317,8 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
|
||||
tychoRouterAddr,
|
||||
USDC_WETH_USV3_2,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false, // permit2 transferFrom to protocol
|
||||
true // transfer to protocol
|
||||
);
|
||||
|
||||
bytes[] memory swaps = new bytes[](2);
|
||||
|
||||
@@ -26,7 +26,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
|
||||
false // funds already in WETH_DAI_POOL, no transfer necessary
|
||||
);
|
||||
|
||||
bytes memory swap =
|
||||
@@ -42,6 +42,8 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true, // transferFrom to WETH_DAI_POOL
|
||||
WETH_DAI_POOL, // receiver of input tokens
|
||||
swap
|
||||
);
|
||||
|
||||
@@ -67,7 +69,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
|
||||
false // funds already in WETH_DAI_POOL, no transfer necessary
|
||||
);
|
||||
|
||||
bytes memory swap =
|
||||
@@ -82,6 +84,8 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
swap
|
||||
);
|
||||
|
||||
@@ -103,20 +107,24 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(address(tychoRouterAddr), amountIn);
|
||||
|
||||
bytes memory protocolData = encodeUniswapV2Swap(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
|
||||
);
|
||||
bytes memory protocolData =
|
||||
encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false, false);
|
||||
|
||||
bytes memory swap =
|
||||
encodeSingleSwap(address(usv2Executor), protocolData);
|
||||
|
||||
vm.expectRevert(TychoRouter__UndefinedMinAmountOut.selector);
|
||||
tychoRouter.singleSwap(
|
||||
amountIn, WETH_ADDR, DAI_ADDR, 0, false, false, ALICE, swap
|
||||
amountIn,
|
||||
WETH_ADDR,
|
||||
DAI_ADDR,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
swap
|
||||
);
|
||||
}
|
||||
|
||||
@@ -134,7 +142,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
|
||||
false // funds already in WETH_DAI_POOL, no transfer necessary
|
||||
);
|
||||
|
||||
bytes memory swap =
|
||||
@@ -150,6 +158,8 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
swap
|
||||
);
|
||||
}
|
||||
@@ -169,7 +179,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
|
||||
false // funds already in WETH_DAI_POOL, no transfer necessary
|
||||
);
|
||||
|
||||
bytes memory swap =
|
||||
@@ -192,6 +202,8 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
false,
|
||||
ALICE,
|
||||
true,
|
||||
WETH_DAI_POOL,
|
||||
swap
|
||||
);
|
||||
}
|
||||
@@ -213,13 +225,8 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
sigDeadline: 0
|
||||
});
|
||||
|
||||
bytes memory protocolData = encodeUniswapV2Swap(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
);
|
||||
bytes memory protocolData =
|
||||
encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false, true);
|
||||
|
||||
bytes memory swap =
|
||||
encodeSingleSwap(address(usv2Executor), protocolData);
|
||||
@@ -234,6 +241,8 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
emptyPermitSingle,
|
||||
"",
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
swap
|
||||
);
|
||||
uint256 expectedAmount = 2018817438608734439722;
|
||||
@@ -257,11 +266,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
) = handlePermit2Approval(DAI_ADDR, tychoRouterAddr, amountIn);
|
||||
|
||||
bytes memory protocolData = encodeUniswapV2Swap(
|
||||
DAI_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
tychoRouterAddr,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
|
||||
DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true, false
|
||||
);
|
||||
|
||||
bytes memory swap =
|
||||
@@ -277,6 +282,8 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true, // transferFrom to WETH_DAI_POOL
|
||||
WETH_DAI_POOL, // receiver of input tokens
|
||||
swap
|
||||
);
|
||||
|
||||
|
||||
@@ -8,11 +8,7 @@ import "./executors/UniswapV4Utils.sol";
|
||||
import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol";
|
||||
|
||||
contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
function _getSplitSwaps(bool permit2)
|
||||
private
|
||||
view
|
||||
returns (bytes[] memory)
|
||||
{
|
||||
function _getSplitSwaps() private view returns (bytes[] memory) {
|
||||
// Trade 1 WETH for USDC through DAI and WBTC with 4 swaps on Uniswap V2
|
||||
// -> DAI ->
|
||||
// 1 WETH USDC
|
||||
@@ -20,10 +16,6 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
// (univ2) (univ2)
|
||||
bytes[] memory swaps = new bytes[](4);
|
||||
|
||||
TokenTransfer.TransferType inTransferType = permit2
|
||||
? TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
|
||||
: TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL;
|
||||
|
||||
// WETH -> WBTC (60%)
|
||||
swaps[0] = encodeSplitSwap(
|
||||
uint8(0),
|
||||
@@ -31,11 +23,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
(0xffffff * 60) / 100, // 60%
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
WETH_ADDR,
|
||||
WETH_WBTC_POOL,
|
||||
tychoRouterAddr,
|
||||
false,
|
||||
inTransferType
|
||||
WETH_ADDR, WETH_WBTC_POOL, tychoRouterAddr, false, true
|
||||
)
|
||||
);
|
||||
// WBTC -> USDC
|
||||
@@ -44,13 +32,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
uint8(2),
|
||||
uint24(0),
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
WBTC_ADDR,
|
||||
USDC_WBTC_POOL,
|
||||
ALICE,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
)
|
||||
encodeUniswapV2Swap(WBTC_ADDR, USDC_WBTC_POOL, ALICE, true, true)
|
||||
);
|
||||
// WETH -> DAI
|
||||
swaps[2] = encodeSplitSwap(
|
||||
@@ -59,7 +41,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
uint24(0),
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false, inTransferType
|
||||
WETH_ADDR, WETH_DAI_POOL, tychoRouterAddr, false, true
|
||||
)
|
||||
);
|
||||
|
||||
@@ -69,13 +51,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
uint8(2),
|
||||
uint24(0),
|
||||
address(usv2Executor),
|
||||
encodeUniswapV2Swap(
|
||||
DAI_ADDR,
|
||||
DAI_USDC_POOL,
|
||||
ALICE,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
)
|
||||
encodeUniswapV2Swap(DAI_ADDR, DAI_USDC_POOL, ALICE, true, true)
|
||||
);
|
||||
|
||||
return swaps;
|
||||
@@ -85,10 +61,9 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
// Trade 1 WETH for USDC through DAI and WBTC - see _getSplitSwaps for more info
|
||||
|
||||
uint256 amountIn = 1 ether;
|
||||
deal(WETH_ADDR, ALICE, amountIn);
|
||||
deal(WETH_ADDR, address(tychoRouterAddr), amountIn);
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(address(tychoRouterAddr), amountIn);
|
||||
bytes[] memory swaps = _getSplitSwaps(false);
|
||||
bytes[] memory swaps = _getSplitSwaps();
|
||||
tychoRouter.exposedSplitSwap(amountIn, 4, pleEncode(swaps));
|
||||
vm.stopPrank();
|
||||
|
||||
@@ -109,7 +84,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
bytes memory signature
|
||||
) = handlePermit2Approval(WETH_ADDR, tychoRouterAddr, amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSplitSwaps(true);
|
||||
bytes[] memory swaps = _getSplitSwaps();
|
||||
|
||||
tychoRouter.splitSwapPermit2(
|
||||
amountIn,
|
||||
@@ -122,6 +97,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
|
||||
@@ -138,7 +115,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(tychoRouterAddr, amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSplitSwaps(false);
|
||||
bytes[] memory swaps = _getSplitSwaps();
|
||||
|
||||
tychoRouter.splitSwap(
|
||||
amountIn,
|
||||
@@ -149,6 +126,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
4,
|
||||
ALICE,
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
|
||||
@@ -165,7 +144,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
vm.startPrank(ALICE);
|
||||
IERC20(WETH_ADDR).approve(address(tychoRouterAddr), amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSplitSwaps(false);
|
||||
bytes[] memory swaps = _getSplitSwaps();
|
||||
|
||||
vm.expectRevert(TychoRouter__UndefinedMinAmountOut.selector);
|
||||
tychoRouter.splitSwap(
|
||||
@@ -177,6 +156,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
4,
|
||||
ALICE,
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
vm.stopPrank();
|
||||
@@ -190,7 +171,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
vm.startPrank(ALICE);
|
||||
// Approve less than the amountIn
|
||||
IERC20(WETH_ADDR).approve(address(tychoRouterAddr), amountIn - 1);
|
||||
bytes[] memory swaps = _getSplitSwaps(false);
|
||||
bytes[] memory swaps = _getSplitSwaps();
|
||||
|
||||
vm.expectRevert();
|
||||
tychoRouter.splitSwap(
|
||||
@@ -202,6 +183,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
false,
|
||||
2,
|
||||
ALICE,
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
|
||||
@@ -219,7 +202,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
bytes memory signature
|
||||
) = handlePermit2Approval(WETH_ADDR, tychoRouterAddr, amountIn);
|
||||
|
||||
bytes[] memory swaps = _getSplitSwaps(true);
|
||||
bytes[] memory swaps = _getSplitSwaps();
|
||||
|
||||
uint256 minAmountOut = 3000 * 1e18;
|
||||
|
||||
@@ -241,6 +224,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
vm.stopPrank();
|
||||
@@ -265,13 +250,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
spender: address(0),
|
||||
sigDeadline: 0
|
||||
});
|
||||
bytes memory protocolData = encodeUniswapV2Swap(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
);
|
||||
bytes memory protocolData =
|
||||
encodeUniswapV2Swap(WETH_ADDR, WETH_DAI_POOL, ALICE, false, true);
|
||||
|
||||
bytes memory swap = encodeSplitSwap(
|
||||
uint8(0), uint8(1), uint24(0), address(usv2Executor), protocolData
|
||||
@@ -290,6 +270,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
emptyPermitSingle,
|
||||
"",
|
||||
false,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
uint256 expectedAmount = 2018817438608734439722;
|
||||
@@ -315,11 +297,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
) = handlePermit2Approval(DAI_ADDR, tychoRouterAddr, amountIn);
|
||||
|
||||
bytes memory protocolData = encodeUniswapV2Swap(
|
||||
DAI_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
tychoRouterAddr,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
|
||||
DAI_ADDR, WETH_DAI_POOL, tychoRouterAddr, true, true
|
||||
);
|
||||
|
||||
bytes memory swap = encodeSplitSwap(
|
||||
@@ -339,6 +317,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
ALICE,
|
||||
permitSingle,
|
||||
signature,
|
||||
true,
|
||||
tychoRouterAddr,
|
||||
pleEncode(swaps)
|
||||
);
|
||||
|
||||
@@ -365,10 +345,10 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
// │ │
|
||||
// └─ (USV3, 40% split) ──> WETH ─┘
|
||||
uint256 amountIn = 100 * 10 ** 6;
|
||||
deal(USDC_ADDR, ALICE, amountIn);
|
||||
|
||||
// Assume funds have already been transferred to tychoRouter
|
||||
deal(USDC_ADDR, tychoRouterAddr, amountIn);
|
||||
vm.startPrank(ALICE);
|
||||
// Approve the TychoRouter to spend USDC
|
||||
IERC20(USDC_ADDR).approve(tychoRouterAddr, amountIn);
|
||||
|
||||
bytes memory usdcWethV3Pool1ZeroOneData = encodeUniswapV3Swap(
|
||||
USDC_ADDR,
|
||||
@@ -376,7 +356,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
tychoRouterAddr,
|
||||
USDC_WETH_USV3,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
|
||||
false, // transferFrom swapper required
|
||||
true // transfer from tycho router to protocol
|
||||
);
|
||||
|
||||
bytes memory usdcWethV3Pool2ZeroOneData = encodeUniswapV3Swap(
|
||||
@@ -385,7 +366,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
tychoRouterAddr,
|
||||
USDC_WETH_USV3_2,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
|
||||
false, // transferFrom swapper required
|
||||
true // transfer from tycho router to protocol
|
||||
);
|
||||
|
||||
bytes memory wethUsdcV2OneZeroData = encodeUniswapV2Swap(
|
||||
@@ -393,7 +375,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
USDC_WETH_USV2,
|
||||
tychoRouterAddr,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
true // transfer from tycho router to protocol
|
||||
);
|
||||
|
||||
bytes[] memory swaps = new bytes[](3);
|
||||
@@ -443,7 +425,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
USDC_WETH_USV2,
|
||||
tychoRouterAddr,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
true // transfer required
|
||||
);
|
||||
|
||||
bytes memory usdcWethV3Pool1OneZeroData = encodeUniswapV3Swap(
|
||||
@@ -452,7 +434,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
tychoRouterAddr,
|
||||
USDC_WETH_USV3,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false, // transferFrom required
|
||||
true // transfer required
|
||||
);
|
||||
|
||||
bytes memory usdcWethV3Pool2OneZeroData = encodeUniswapV3Swap(
|
||||
@@ -461,7 +444,8 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
tychoRouterAddr,
|
||||
USDC_WETH_USV3_2,
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false, // transferFrom required
|
||||
true // transfer required
|
||||
);
|
||||
|
||||
bytes[] memory swaps = new bytes[](3);
|
||||
@@ -500,11 +484,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
||||
deal(BASE_USDC, tychoRouterAddr, amountIn);
|
||||
|
||||
bytes memory protocolData = encodeUniswapV2Swap(
|
||||
BASE_USDC,
|
||||
USDC_MAG7_POOL,
|
||||
tychoRouterAddr,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
|
||||
BASE_USDC, USDC_MAG7_POOL, tychoRouterAddr, true, true
|
||||
);
|
||||
|
||||
bytes memory swap = encodeSplitSwap(
|
||||
|
||||
@@ -185,10 +185,11 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
address target,
|
||||
address receiver,
|
||||
bool zero2one,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferNeeded
|
||||
) internal pure returns (bytes memory) {
|
||||
return
|
||||
abi.encodePacked(tokenIn, target, receiver, zero2one, transferType);
|
||||
return abi.encodePacked(
|
||||
tokenIn, target, receiver, zero2one, transferNeeded
|
||||
);
|
||||
}
|
||||
|
||||
function encodeUniswapV3Swap(
|
||||
@@ -197,7 +198,8 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
address receiver,
|
||||
address target,
|
||||
bool zero2one,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferFromNeeded,
|
||||
bool transferNeeded
|
||||
) internal view returns (bytes memory) {
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(target);
|
||||
return abi.encodePacked(
|
||||
@@ -207,7 +209,8 @@ contract TychoRouterTestSetup is Constants, Permit2TestHelper, TestUtils {
|
||||
receiver,
|
||||
target,
|
||||
zero2one,
|
||||
transferType
|
||||
transferFromNeeded,
|
||||
transferNeeded
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ contract BalancerV2ExecutorExposed is BalancerV2Executor {
|
||||
bytes32 poolId,
|
||||
address receiver,
|
||||
bool needsApproval,
|
||||
TransferType transferType
|
||||
bool transferNeeded
|
||||
)
|
||||
{
|
||||
return _decodeData(data);
|
||||
@@ -41,12 +41,7 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
|
||||
|
||||
function testDecodeParams() public view {
|
||||
bytes memory params = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
BAL_ADDR,
|
||||
WETH_BAL_POOL_ID,
|
||||
address(2),
|
||||
true,
|
||||
TokenTransfer.TransferType.NONE
|
||||
WETH_ADDR, BAL_ADDR, WETH_BAL_POOL_ID, address(2), true, false
|
||||
);
|
||||
|
||||
(
|
||||
@@ -55,7 +50,7 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
|
||||
bytes32 poolId,
|
||||
address receiver,
|
||||
bool needsApproval,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferNeeded
|
||||
) = balancerV2Exposed.decodeParams(params);
|
||||
|
||||
assertEq(address(tokenIn), WETH_ADDR);
|
||||
@@ -63,7 +58,6 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
|
||||
assertEq(poolId, WETH_BAL_POOL_ID);
|
||||
assertEq(receiver, address(2));
|
||||
assertEq(needsApproval, true);
|
||||
assertEq(uint8(transferType), uint8(TokenTransfer.TransferType.NONE));
|
||||
}
|
||||
|
||||
function testDecodeParamsInvalidDataLength() public {
|
||||
@@ -77,12 +71,7 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
|
||||
function testSwap() public {
|
||||
uint256 amountIn = 10 ** 18;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
BAL_ADDR,
|
||||
WETH_BAL_POOL_ID,
|
||||
BOB,
|
||||
true,
|
||||
TokenTransfer.TransferType.NONE
|
||||
WETH_ADDR, BAL_ADDR, WETH_BAL_POOL_ID, BOB, true, false
|
||||
);
|
||||
|
||||
deal(WETH_ADDR, address(balancerV2Exposed), amountIn);
|
||||
@@ -104,7 +93,7 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
|
||||
bytes32 poolId,
|
||||
address receiver,
|
||||
bool needsApproval,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferNeeded
|
||||
) = balancerV2Exposed.decodeParams(protocolData);
|
||||
|
||||
assertEq(address(tokenIn), WETH_ADDR);
|
||||
@@ -112,7 +101,6 @@ contract BalancerV2ExecutorTest is Constants, TestUtils {
|
||||
assertEq(poolId, WETH_BAL_POOL_ID);
|
||||
assertEq(receiver, BOB);
|
||||
assertEq(needsApproval, true);
|
||||
assertEq(uint8(transferType), uint8(TokenTransfer.TransferType.NONE));
|
||||
}
|
||||
|
||||
function testSwapIntegration() public {
|
||||
|
||||
@@ -37,7 +37,7 @@ contract CurveExecutorExposed is CurveExecutor {
|
||||
int128 i,
|
||||
int128 j,
|
||||
bool tokenApprovalNeeded,
|
||||
TokenTransfer.TransferType transferType,
|
||||
bool transferNeeded,
|
||||
address receiver
|
||||
)
|
||||
{
|
||||
@@ -68,7 +68,7 @@ contract CurveExecutorTest is Test, Constants {
|
||||
uint8(2),
|
||||
uint8(0),
|
||||
true,
|
||||
TokenTransfer.TransferType.NONE,
|
||||
false,
|
||||
ALICE
|
||||
);
|
||||
|
||||
@@ -80,7 +80,7 @@ contract CurveExecutorTest is Test, Constants {
|
||||
int128 i,
|
||||
int128 j,
|
||||
bool tokenApprovalNeeded,
|
||||
TokenTransfer.TransferType transferType,
|
||||
bool transferNeeded,
|
||||
address receiver
|
||||
) = curveExecutorExposed.decodeData(data);
|
||||
|
||||
@@ -91,7 +91,6 @@ contract CurveExecutorTest is Test, Constants {
|
||||
assertEq(i, 2);
|
||||
assertEq(j, 0);
|
||||
assertEq(tokenApprovalNeeded, true);
|
||||
assertEq(uint8(transferType), uint8(TokenTransfer.TransferType.NONE));
|
||||
assertEq(receiver, ALICE);
|
||||
}
|
||||
|
||||
@@ -295,7 +294,7 @@ contract CurveExecutorTest is Test, Constants {
|
||||
uint8(uint256(uint128(i))),
|
||||
uint8(uint256(uint128(j))),
|
||||
true,
|
||||
TokenTransfer.TransferType.NONE,
|
||||
false,
|
||||
receiver
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ pragma solidity ^0.8.26;
|
||||
|
||||
import "../TestUtils.sol";
|
||||
import {Constants} from "../Constants.sol";
|
||||
import {EkuboExecutor, TokenTransfer} from "@src/executors/EkuboExecutor.sol";
|
||||
import {EkuboExecutor} from "@src/executors/EkuboExecutor.sol";
|
||||
import {ICore} from "@ekubo/interfaces/ICore.sol";
|
||||
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import {NATIVE_TOKEN_ADDRESS} from "@ekubo/math/constants.sol";
|
||||
@@ -45,7 +45,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
uint256 usdcBalanceBeforeExecutor = USDC.balanceOf(address(executor));
|
||||
|
||||
bytes memory data = abi.encodePacked(
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL), // transferType (transfer from executor to core)
|
||||
true, // transferNeeded (transfer from executor to core)
|
||||
address(executor), // receiver
|
||||
NATIVE_TOKEN_ADDRESS, // tokenIn
|
||||
USDC_ADDR, // tokenOut
|
||||
@@ -82,7 +82,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
uint256 ethBalanceBeforeExecutor = address(executor).balance;
|
||||
|
||||
bytes memory data = abi.encodePacked(
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL), // transferType (transfer from executor to core)
|
||||
true, // transferNeeded (transfer from executor to core)
|
||||
address(executor), // receiver
|
||||
USDC_ADDR, // tokenIn
|
||||
NATIVE_TOKEN_ADDRESS, // tokenOut
|
||||
@@ -140,7 +140,7 @@ contract EkuboExecutorTest is Constants, TestUtils {
|
||||
// Same test case as in swap_encoder::tests::ekubo::test_encode_swap_multi
|
||||
function testMultiHopSwap() public {
|
||||
bytes memory data = abi.encodePacked(
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL), // transferType
|
||||
true, // transferNeeded (transfer from executor to core)
|
||||
address(executor), // receiver
|
||||
NATIVE_TOKEN_ADDRESS, // tokenIn
|
||||
USDC_ADDR, // tokenOut of 1st swap
|
||||
|
||||
@@ -17,7 +17,7 @@ contract MaverickV2ExecutorExposed is MaverickV2Executor {
|
||||
IERC20 tokenIn,
|
||||
address target,
|
||||
address receiver,
|
||||
TransferType transferType
|
||||
bool transferNeeded
|
||||
)
|
||||
{
|
||||
return _decodeData(data);
|
||||
@@ -39,27 +39,16 @@ contract MaverickV2ExecutorTest is TestUtils, Constants {
|
||||
}
|
||||
|
||||
function testDecodeParams() public view {
|
||||
bytes memory params = abi.encodePacked(
|
||||
GHO_ADDR,
|
||||
GHO_USDC_POOL,
|
||||
address(2),
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
);
|
||||
bytes memory params =
|
||||
abi.encodePacked(GHO_ADDR, GHO_USDC_POOL, address(2), true);
|
||||
|
||||
(
|
||||
IERC20 tokenIn,
|
||||
address target,
|
||||
address receiver,
|
||||
TokenTransfer.TransferType transferType
|
||||
) = maverickV2Exposed.decodeParams(params);
|
||||
(IERC20 tokenIn, address target, address receiver, bool transferNeeded)
|
||||
= maverickV2Exposed.decodeParams(params);
|
||||
|
||||
assertEq(address(tokenIn), GHO_ADDR);
|
||||
assertEq(target, GHO_USDC_POOL);
|
||||
assertEq(receiver, address(2));
|
||||
assertEq(
|
||||
uint8(transferType),
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
|
||||
);
|
||||
assertEq(transferNeeded, true);
|
||||
}
|
||||
|
||||
function testDecodeParamsInvalidDataLength() public {
|
||||
@@ -72,12 +61,8 @@ contract MaverickV2ExecutorTest is TestUtils, Constants {
|
||||
|
||||
function testSwap() public {
|
||||
uint256 amountIn = 10e18;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
GHO_ADDR,
|
||||
GHO_USDC_POOL,
|
||||
BOB,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
);
|
||||
bytes memory protocolData =
|
||||
abi.encodePacked(GHO_ADDR, GHO_USDC_POOL, BOB, true);
|
||||
|
||||
deal(GHO_ADDR, address(maverickV2Exposed), amountIn);
|
||||
uint256 balanceBefore = USDC.balanceOf(BOB);
|
||||
@@ -94,20 +79,13 @@ contract MaverickV2ExecutorTest is TestUtils, Constants {
|
||||
bytes memory protocolData =
|
||||
loadCallDataFromFile("test_encode_maverick_v2");
|
||||
|
||||
(
|
||||
IERC20 tokenIn,
|
||||
address pool,
|
||||
address receiver,
|
||||
TokenTransfer.TransferType transferType
|
||||
) = maverickV2Exposed.decodeParams(protocolData);
|
||||
(IERC20 tokenIn, address pool, address receiver, bool transferNeeded) =
|
||||
maverickV2Exposed.decodeParams(protocolData);
|
||||
|
||||
assertEq(address(tokenIn), GHO_ADDR);
|
||||
assertEq(pool, GHO_USDC_POOL);
|
||||
assertEq(receiver, BOB);
|
||||
assertEq(
|
||||
uint8(transferType),
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
|
||||
);
|
||||
assertEq(transferNeeded, true);
|
||||
}
|
||||
|
||||
function testSwapIntegration() public {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
pragma solidity ^0.8.26;
|
||||
|
||||
import "@src/executors/UniswapV2Executor.sol";
|
||||
import "@src/executors/TokenTransfer.sol";
|
||||
import {Test} from "../../lib/forge-std/src/Test.sol";
|
||||
import {Constants} from "../Constants.sol";
|
||||
import {Permit2TestHelper} from "../Permit2TestHelper.sol";
|
||||
@@ -23,7 +22,7 @@ contract UniswapV2ExecutorExposed is UniswapV2Executor {
|
||||
address target,
|
||||
address receiver,
|
||||
bool zeroForOne,
|
||||
TransferType transferType
|
||||
bool transferNeeded
|
||||
)
|
||||
{
|
||||
return _decodeData(data);
|
||||
@@ -60,7 +59,6 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
UniswapV2ExecutorExposed pancakeswapV2Exposed;
|
||||
IERC20 WETH = IERC20(WETH_ADDR);
|
||||
IERC20 DAI = IERC20(DAI_ADDR);
|
||||
IAllowanceTransfer permit2;
|
||||
|
||||
function setUp() public {
|
||||
uint256 forkBlock = 17323404;
|
||||
@@ -80,34 +78,25 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
PERMIT2_ADDRESS,
|
||||
25
|
||||
);
|
||||
permit2 = IAllowanceTransfer(PERMIT2_ADDRESS);
|
||||
}
|
||||
|
||||
function testDecodeParams() public view {
|
||||
bytes memory params = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
address(2),
|
||||
address(3),
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
);
|
||||
bytes memory params =
|
||||
abi.encodePacked(WETH_ADDR, address(2), address(3), false, true);
|
||||
|
||||
(
|
||||
IERC20 tokenIn,
|
||||
address target,
|
||||
address receiver,
|
||||
bool zeroForOne,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferNeeded
|
||||
) = uniswapV2Exposed.decodeParams(params);
|
||||
|
||||
assertEq(address(tokenIn), WETH_ADDR);
|
||||
assertEq(target, address(2));
|
||||
assertEq(receiver, address(3));
|
||||
assertEq(zeroForOne, false);
|
||||
assertEq(
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL),
|
||||
uint8(transferType)
|
||||
);
|
||||
assertEq(transferNeeded, true);
|
||||
}
|
||||
|
||||
function testDecodeParamsInvalidDataLength() public {
|
||||
@@ -158,13 +147,8 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
uint256 amountIn = 10 ** 18;
|
||||
uint256 amountOut = 1847751195973566072891;
|
||||
bool zeroForOne = false;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
BOB,
|
||||
zeroForOne,
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
|
||||
);
|
||||
bytes memory protocolData =
|
||||
abi.encodePacked(WETH_ADDR, WETH_DAI_POOL, BOB, zeroForOne, true);
|
||||
|
||||
deal(WETH_ADDR, address(uniswapV2Exposed), amountIn);
|
||||
uniswapV2Exposed.swap(amountIn, protocolData);
|
||||
@@ -173,70 +157,12 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
assertGe(finalBalance, amountOut);
|
||||
}
|
||||
|
||||
function testSwapWithTransferFrom() public {
|
||||
uint256 amountIn = 10 ** 18;
|
||||
uint256 amountOut = 1847751195973566072891;
|
||||
bool zeroForOne = false;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
BOB,
|
||||
zeroForOne,
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL)
|
||||
);
|
||||
|
||||
deal(WETH_ADDR, address(this), amountIn);
|
||||
IERC20(WETH_ADDR).approve(address(uniswapV2Exposed), amountIn);
|
||||
|
||||
uniswapV2Exposed.swap(amountIn, protocolData);
|
||||
|
||||
uint256 finalBalance = DAI.balanceOf(BOB);
|
||||
assertGe(finalBalance, amountOut);
|
||||
}
|
||||
|
||||
function testSwapWithPermit2TransferFrom() public {
|
||||
uint256 amountIn = 10 ** 18;
|
||||
uint256 amountOut = 1847751195973566072891;
|
||||
bool zeroForOne = false;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
ALICE,
|
||||
zeroForOne,
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL)
|
||||
);
|
||||
|
||||
deal(WETH_ADDR, ALICE, amountIn);
|
||||
vm.startPrank(ALICE);
|
||||
(
|
||||
IAllowanceTransfer.PermitSingle memory permitSingle,
|
||||
bytes memory signature
|
||||
) = handlePermit2Approval(
|
||||
WETH_ADDR, address(uniswapV2Exposed), amountIn
|
||||
);
|
||||
|
||||
// Assume the permit2.approve method will be called from the TychoRouter
|
||||
// Replicate this scenario in this test.
|
||||
permit2.permit(ALICE, permitSingle, signature);
|
||||
|
||||
uniswapV2Exposed.swap(amountIn, protocolData);
|
||||
vm.stopPrank();
|
||||
|
||||
uint256 finalBalance = DAI.balanceOf(ALICE);
|
||||
assertGe(finalBalance, amountOut);
|
||||
}
|
||||
|
||||
function testSwapNoTransfer() public {
|
||||
uint256 amountIn = 10 ** 18;
|
||||
uint256 amountOut = 1847751195973566072891;
|
||||
bool zeroForOne = false;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
WETH_DAI_POOL,
|
||||
BOB,
|
||||
zeroForOne,
|
||||
uint8(TokenTransfer.TransferType.NONE)
|
||||
);
|
||||
bytes memory protocolData =
|
||||
abi.encodePacked(WETH_ADDR, WETH_DAI_POOL, BOB, zeroForOne, false);
|
||||
|
||||
deal(WETH_ADDR, address(this), amountIn);
|
||||
IERC20(WETH_ADDR).transfer(address(WETH_DAI_POOL), amountIn);
|
||||
@@ -255,20 +181,19 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
address target,
|
||||
address receiver,
|
||||
bool zeroForOne,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferNeeded
|
||||
) = uniswapV2Exposed.decodeParams(protocolData);
|
||||
|
||||
assertEq(address(tokenIn), WETH_ADDR);
|
||||
assertEq(target, 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640);
|
||||
assertEq(receiver, 0x0000000000000000000000000000000000000001);
|
||||
assertEq(zeroForOne, false);
|
||||
// TRANSFER = 0
|
||||
assertEq(0, uint8(transferType));
|
||||
assertEq(transferNeeded, false);
|
||||
}
|
||||
|
||||
function testSwapIntegration() public {
|
||||
bytes memory protocolData =
|
||||
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb111d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0000";
|
||||
hex"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb111d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0001";
|
||||
uint256 amountIn = 10 ** 18;
|
||||
uint256 amountOut = 1847751195973566072891;
|
||||
deal(WETH_ADDR, address(uniswapV2Exposed), amountIn);
|
||||
@@ -282,13 +207,8 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
uint256 amountIn = 10 ** 18;
|
||||
bool zeroForOne = false;
|
||||
address fakePool = address(new FakeUniswapV2Pool(WETH_ADDR, DAI_ADDR));
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
WETH_ADDR,
|
||||
fakePool,
|
||||
BOB,
|
||||
zeroForOne,
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
|
||||
);
|
||||
bytes memory protocolData =
|
||||
abi.encodePacked(WETH_ADDR, fakePool, BOB, zeroForOne, true);
|
||||
|
||||
deal(WETH_ADDR, address(uniswapV2Exposed), amountIn);
|
||||
vm.expectRevert(UniswapV2Executor__InvalidTarget.selector);
|
||||
@@ -302,13 +222,8 @@ contract UniswapV2ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
vm.rollFork(26857267);
|
||||
uint256 amountIn = 10 * 10 ** 6;
|
||||
bool zeroForOne = true;
|
||||
bytes memory protocolData = abi.encodePacked(
|
||||
BASE_USDC,
|
||||
USDC_MAG7_POOL,
|
||||
BOB,
|
||||
zeroForOne,
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
|
||||
);
|
||||
bytes memory protocolData =
|
||||
abi.encodePacked(BASE_USDC, USDC_MAG7_POOL, BOB, zeroForOne, true);
|
||||
|
||||
deal(BASE_USDC, address(uniswapV2Exposed), amountIn);
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ contract UniswapV3ExecutorExposed is UniswapV3Executor {
|
||||
address receiver,
|
||||
address target,
|
||||
bool zeroForOne,
|
||||
TransferType transferType
|
||||
bool transferFromNeeded,
|
||||
bool transferNeeded
|
||||
)
|
||||
{
|
||||
return _decodeData(data);
|
||||
@@ -71,7 +72,8 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
address(2),
|
||||
address(3),
|
||||
false,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
(
|
||||
@@ -81,7 +83,8 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
address receiver,
|
||||
address target,
|
||||
bool zeroForOne,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferFromNeeded,
|
||||
bool transferNeeded
|
||||
) = uniswapV3Exposed.decodeData(data);
|
||||
|
||||
assertEq(tokenIn, WETH_ADDR);
|
||||
@@ -90,10 +93,8 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
assertEq(receiver, address(2));
|
||||
assertEq(target, address(3));
|
||||
assertEq(zeroForOne, false);
|
||||
assertEq(
|
||||
uint8(transferType),
|
||||
uint8(TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL)
|
||||
);
|
||||
assertEq(transferFromNeeded, false);
|
||||
assertEq(transferNeeded, true);
|
||||
}
|
||||
|
||||
function testSwapIntegration() public {
|
||||
@@ -109,7 +110,8 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
address(this),
|
||||
DAI_WETH_USV3,
|
||||
zeroForOne,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
uint256 amountOut = uniswapV3Exposed.swap(amountIn, data);
|
||||
@@ -184,7 +186,8 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
address(this),
|
||||
fakePool,
|
||||
zeroForOne,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
|
||||
false,
|
||||
true
|
||||
);
|
||||
|
||||
vm.expectRevert(UniswapV3Executor__InvalidTarget.selector);
|
||||
@@ -197,7 +200,8 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
address receiver,
|
||||
address target,
|
||||
bool zero2one,
|
||||
TokenTransfer.TransferType transferType
|
||||
bool transferFromNeeded,
|
||||
bool transferNeeded
|
||||
) internal view returns (bytes memory) {
|
||||
IUniswapV3Pool pool = IUniswapV3Pool(target);
|
||||
return abi.encodePacked(
|
||||
@@ -207,7 +211,8 @@ contract UniswapV3ExecutorTest is Test, Constants, Permit2TestHelper {
|
||||
receiver,
|
||||
target,
|
||||
zero2one,
|
||||
transferType
|
||||
transferFromNeeded,
|
||||
transferNeeded
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ pragma solidity ^0.8.26;
|
||||
import "../../src/executors/UniswapV4Executor.sol";
|
||||
import "../TestUtils.sol";
|
||||
import "./UniswapV4Utils.sol";
|
||||
import "@src/executors/TokenTransfer.sol";
|
||||
import "@src/executors/UniswapV4Executor.sol";
|
||||
import {Constants} from "../Constants.sol";
|
||||
import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol";
|
||||
@@ -22,7 +21,8 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor {
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
bool zeroForOne,
|
||||
TokenTransfer.TransferType transferType,
|
||||
bool transferFromNeeded,
|
||||
bool transferNeeded,
|
||||
address receiver,
|
||||
UniswapV4Pool[] memory pools
|
||||
)
|
||||
@@ -53,8 +53,8 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
|
||||
int24 tickSpacing1 = 60;
|
||||
uint24 pool2Fee = 1000;
|
||||
int24 tickSpacing2 = -10;
|
||||
TokenTransfer.TransferType transferType =
|
||||
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL;
|
||||
bool transferFromNeeded = false;
|
||||
bool transferNeeded = true;
|
||||
|
||||
UniswapV4Executor.UniswapV4Pool[] memory pools =
|
||||
new UniswapV4Executor.UniswapV4Pool[](2);
|
||||
@@ -70,14 +70,21 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
|
||||
});
|
||||
|
||||
bytes memory data = UniswapV4Utils.encodeExactInput(
|
||||
USDE_ADDR, USDT_ADDR, zeroForOne, transferType, ALICE, pools
|
||||
USDE_ADDR,
|
||||
USDT_ADDR,
|
||||
zeroForOne,
|
||||
transferFromNeeded,
|
||||
transferNeeded,
|
||||
ALICE,
|
||||
pools
|
||||
);
|
||||
|
||||
(
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
bool zeroForOneDecoded,
|
||||
TokenTransfer.TransferType transferTypeDecoded,
|
||||
bool transferFromNeededDecoded,
|
||||
bool transferNeededDecoded,
|
||||
address receiver,
|
||||
UniswapV4Executor.UniswapV4Pool[] memory decodedPools
|
||||
) = uniswapV4Exposed.decodeData(data);
|
||||
@@ -85,7 +92,8 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
|
||||
assertEq(tokenIn, USDE_ADDR);
|
||||
assertEq(tokenOut, USDT_ADDR);
|
||||
assertEq(zeroForOneDecoded, zeroForOne);
|
||||
assertEq(uint8(transferTypeDecoded), uint8(transferType));
|
||||
assertEq(transferFromNeededDecoded, transferFromNeeded);
|
||||
assertEq(transferNeededDecoded, transferNeeded);
|
||||
assertEq(receiver, ALICE);
|
||||
assertEq(decodedPools.length, 2);
|
||||
assertEq(decodedPools[0].intermediaryToken, USDT_ADDR);
|
||||
@@ -112,12 +120,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
|
||||
});
|
||||
|
||||
bytes memory data = UniswapV4Utils.encodeExactInput(
|
||||
USDE_ADDR,
|
||||
USDT_ADDR,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL,
|
||||
ALICE,
|
||||
pools
|
||||
USDE_ADDR, USDT_ADDR, true, false, true, ALICE, pools
|
||||
);
|
||||
|
||||
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);
|
||||
@@ -169,12 +172,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils {
|
||||
});
|
||||
|
||||
bytes memory data = UniswapV4Utils.encodeExactInput(
|
||||
USDE_ADDR,
|
||||
WBTC_ADDR,
|
||||
true,
|
||||
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL,
|
||||
ALICE,
|
||||
pools
|
||||
USDE_ADDR, WBTC_ADDR, true, false, true, ALICE, pools
|
||||
);
|
||||
|
||||
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);
|
||||
|
||||
@@ -8,7 +8,8 @@ library UniswapV4Utils {
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
bool zeroForOne,
|
||||
UniswapV4Executor.TransferType transferType,
|
||||
bool transferFromNeeded,
|
||||
bool transferNeeded,
|
||||
address receiver,
|
||||
UniswapV4Executor.UniswapV4Pool[] memory pools
|
||||
) public pure returns (bytes memory) {
|
||||
@@ -24,7 +25,12 @@ library UniswapV4Utils {
|
||||
}
|
||||
|
||||
return abi.encodePacked(
|
||||
tokenIn, tokenOut, zeroForOne, transferType, receiver, encodedPools
|
||||
tokenIn,
|
||||
tokenOut,
|
||||
zeroForOne,
|
||||
transferNeeded,
|
||||
receiver,
|
||||
encodedPools
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user