Merge pull request #163 from propeller-heads/router/dc/ENG-4315-optimize-out-transfer

feat: Support out transfer straight to the receiver
This commit is contained in:
dianacarvalho1
2025-04-16 17:39:21 +01:00
committed by Diana Carvalho
14 changed files with 313 additions and 235 deletions

View File

@@ -58,6 +58,9 @@ import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
error TychoRouter__AddressZero();
error TychoRouter__EmptySwaps();
error TychoRouter__NegativeSlippage(uint256 amount, uint256 minAmount);
error TychoRouter__AmountOutNotFullyReceived(
uint256 amountIn, uint256 amountConsumed
);
error TychoRouter__MessageValueMismatch(uint256 value, uint256 amount);
error TychoRouter__InvalidDataLength();
error TychoRouter__UndefinedMinAmountOut();
@@ -420,6 +423,8 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
_wrapETH(amountIn);
tokenIn = address(_weth);
}
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
amountOut = _splitSwap(amountIn, nTokens, swaps);
if (amountOut < minAmountOut) {
@@ -428,11 +433,17 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
if (unwrapEth) {
_unwrapETH(amountOut);
}
if (tokenOut == address(0)) {
Address.sendValue(payable(receiver), amountOut);
} else {
IERC20(tokenOut).safeTransfer(receiver, amountOut);
}
if (tokenIn != tokenOut) {
uint256 currentBalanceTokenOut = _balanceOf(tokenOut, receiver);
uint256 userAmount = currentBalanceTokenOut - initialBalanceTokenOut;
if (userAmount != amountOut) {
revert TychoRouter__AmountOutNotFullyReceived(
userAmount, amountOut
);
}
}
}
@@ -470,6 +481,7 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
(address executor, bytes calldata protocolData) =
swap_.decodeSingleSwap();
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
amountOut = _callExecutor(executor, amountIn, protocolData);
if (amountOut < minAmountOut) {
@@ -478,11 +490,17 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
if (unwrapEth) {
_unwrapETH(amountOut);
}
if (tokenOut == address(0)) {
Address.sendValue(payable(receiver), amountOut);
} else {
IERC20(tokenOut).safeTransfer(receiver, amountOut);
}
if (tokenIn != tokenOut) {
uint256 currentBalanceTokenOut = _balanceOf(tokenOut, receiver);
uint256 userAmount = currentBalanceTokenOut - initialBalanceTokenOut;
if (userAmount != amountOut) {
revert TychoRouter__AmountOutNotFullyReceived(
userAmount, amountOut
);
}
}
}
@@ -517,7 +535,9 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
tokenIn = address(_weth);
}
uint256 initialBalanceTokenOut = _balanceOf(tokenOut, receiver);
amountOut = _sequentialSwap(amountIn, swaps);
uint256 currentBalanceTokenIn = _balanceOf(tokenIn, address(this));
if (amountOut < minAmountOut) {
revert TychoRouter__NegativeSlippage(amountOut, minAmountOut);
@@ -525,11 +545,17 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
if (unwrapEth) {
_unwrapETH(amountOut);
}
if (tokenOut == address(0)) {
Address.sendValue(payable(receiver), amountOut);
} else {
IERC20(tokenOut).safeTransfer(receiver, amountOut);
}
if (tokenIn != tokenOut) {
uint256 currentBalanceTokenOut = _balanceOf(tokenOut, receiver);
uint256 userAmount = currentBalanceTokenOut - initialBalanceTokenOut;
if (userAmount != amountOut) {
revert TychoRouter__AmountOutNotFullyReceived(
userAmount, amountOut
);
}
}
}
@@ -764,4 +790,13 @@ contract TychoRouter is AccessControl, Dispatcher, Pausable, ReentrancyGuard {
_handleCallback(data);
return "";
}
function _balanceOf(address token, address owner)
internal
view
returns (uint256)
{
return
token == address(0) ? owner.balance : IERC20(token).balanceOf(owner);
}
}

View File

@@ -4,6 +4,7 @@ pragma solidity ^0.8.26;
import "@interfaces/IExecutor.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./TokenTransfer.sol";
import "@openzeppelin/contracts/utils/Address.sol";
error CurveExecutor__AddressZero();
error CurveExecutor__InvalidDataLength();
@@ -54,7 +55,7 @@ contract CurveExecutor is IExecutor, TokenTransfer {
payable
returns (uint256)
{
if (data.length != 65) revert CurveExecutor__InvalidDataLength();
if (data.length != 85) revert CurveExecutor__InvalidDataLength();
(
address tokenIn,
@@ -64,7 +65,8 @@ contract CurveExecutor is IExecutor, TokenTransfer {
int128 i,
int128 j,
bool tokenApprovalNeeded,
TransferType transferType
TransferType transferType,
address receiver
) = _decodeData(data);
_transfer(
@@ -109,7 +111,16 @@ contract CurveExecutor is IExecutor, TokenTransfer {
}
uint256 balanceAfter = _balanceOf(tokenOut);
return balanceAfter - balanceBefore;
uint256 amountOut = balanceAfter - balanceBefore;
if (receiver != address(this)) {
if (tokenOut == nativeToken) {
Address.sendValue(payable(receiver), amountOut);
} else {
IERC20(tokenOut).safeTransfer(receiver, amountOut);
}
}
return amountOut;
}
function _decodeData(bytes calldata data)
@@ -123,7 +134,8 @@ contract CurveExecutor is IExecutor, TokenTransfer {
int128 i,
int128 j,
bool tokenApprovalNeeded,
TransferType transferType
TransferType transferType,
address receiver
)
{
tokenIn = address(bytes20(data[0:20]));
@@ -134,6 +146,7 @@ contract CurveExecutor is IExecutor, TokenTransfer {
j = int128(uint128(uint8(data[62])));
tokenApprovalNeeded = data[63] != 0;
transferType = TransferType(uint8(data[64]));
receiver = address(bytes20(data[65:85]));
}
receive() external payable {

View File

@@ -46,6 +46,7 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback, TokenTransfer {
address tokenOut,
bool zeroForOne,
TransferType transferType,
address receiver,
UniswapV4Executor.UniswapV4Pool[] memory pools
) = _decodeData(data);
@@ -72,7 +73,7 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback, TokenTransfer {
bytes memory actions = abi.encodePacked(
uint8(Actions.SWAP_EXACT_IN_SINGLE),
uint8(Actions.SETTLE_ALL),
uint8(Actions.TAKE_ALL)
uint8(Actions.TAKE)
);
bytes[] memory params = new bytes[](3);
@@ -87,7 +88,7 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback, TokenTransfer {
})
);
params[1] = abi.encode(tokenIn, amountIn); // currency to settle
params[2] = abi.encode(tokenOut, uint256(0)); // currency to take
params[2] = abi.encode(tokenOut, receiver, uint256(0)); // currency to take. 0 means to take the full amount
swapData = abi.encode(actions, params);
} else {
PathKey[] memory path = new PathKey[](pools.length);
@@ -104,7 +105,7 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback, TokenTransfer {
bytes memory actions = abi.encodePacked(
uint8(Actions.SWAP_EXACT_IN),
uint8(Actions.SETTLE_ALL),
uint8(Actions.TAKE_ALL)
uint8(Actions.TAKE)
);
bytes[] memory params = new bytes[](3);
@@ -119,22 +120,23 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback, TokenTransfer {
})
);
params[1] = abi.encode(currencyIn, amountIn);
params[2] = abi.encode(Currency.wrap(tokenOut), uint256(0));
params[2] =
abi.encode(Currency.wrap(tokenOut), receiver, uint256(0));
swapData = abi.encode(actions, params);
}
uint256 tokenOutBalanceBefore;
tokenOutBalanceBefore = tokenOut == address(0)
? address(this).balance
: IERC20(tokenOut).balanceOf(address(this));
? receiver.balance
: IERC20(tokenOut).balanceOf(receiver);
executeActions(swapData);
uint256 tokenOutBalanceAfter;
tokenOutBalanceAfter = tokenOut == address(0)
? address(this).balance
: IERC20(tokenOut).balanceOf(address(this));
? receiver.balance
: IERC20(tokenOut).balanceOf(receiver);
calculatedAmount = tokenOutBalanceAfter - tokenOutBalanceBefore;
@@ -155,10 +157,11 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback, TokenTransfer {
address tokenOut,
bool zeroForOne,
TransferType transferType,
address receiver,
UniswapV4Pool[] memory pools
)
{
if (data.length < 67) {
if (data.length < 88) {
revert UniswapV4Executor__InvalidDataLength();
}
@@ -166,10 +169,11 @@ contract UniswapV4Executor is IExecutor, V4Router, ICallback, TokenTransfer {
tokenOut = address(bytes20(data[20:40]));
zeroForOne = (data[40] != 0);
transferType = TransferType(uint8(data[41]));
receiver = address(bytes20(data[42:62]));
uint256 poolsLength = (data.length - 42) / 26; // 26 bytes per pool object
uint256 poolsLength = (data.length - 62) / 26; // 26 bytes per pool object
pools = new UniswapV4Pool[](poolsLength);
bytes memory poolsData = data[42:];
bytes memory poolsData = data[62:];
uint256 offset = 0;
for (uint256 i = 0; i < poolsLength; i++) {
address intermediaryToken;

View File

@@ -12,7 +12,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
uint256 balancerBefore = IERC20(DAI_ADDR).balanceOf(ALICE);
// Encoded solution generated using `test_split_swap_strategy_encoder_no_permit2`
(bool success,) = tychoRouterAddr.call(
hex"79b9b93b0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000008f1d5c1cae37400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000059005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395000100000000000000"
hex"79b9b93b0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000008f1d5c1cae37400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000059005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000"
);
vm.stopPrank();
@@ -37,7 +37,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_encoding_strategy_usv4`
(bool success,) = tychoRouterAddr.call(
hex"7c553846000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000006824c2ae00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fd3cb6000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041850e1add80e90f19d7b1ac70721b5dec8a6bdcb57999ea957f831ea57c4ce1a116bec18d2cae2559421ead48186b6985176fee7f8d2e3452c1518dc2635224b41c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007900770001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d231193300040000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000000000"
hex"7c553846000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe9342000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041c96ca498573c3c283e270700101c963405003b631ce90988c3690248b5cab66a70a1cb074afa6acf671300c917b8d6ac0149ae538c95a67a844175bfa9ae7d811b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d008b0001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330004cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000000000000000000000000000000000"
);
vm.stopPrank();
@@ -60,7 +60,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
// Encoded solution generated using `test_split_encoding_strategy_usv4_eth_in`
(bool success,) = tychoRouterAddr.call{value: 1 ether}(
hex"7c5538460000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d2311933000000000000000000000000000000000000000000c87c939ae635f92dc2379c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006824c2cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fd3cd3000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041a97e156e8c7a48a968efe2f057700ce8458ecfbfb53e0319fc9223b2364aba20227d2ee00226b42e2f28aeb002a242576d75152b270d73a8926f595190828f3d1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f005d0001000000f62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d231193301056982508145454ce325ddbe47a25d4ec3d23119330061a80001f400"
hex"7c5538460000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d2311933000000000000000000000000000000000000000000c87c939ae635f92dc2379c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe934200000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004197c8f24177a14b631dd3a9226c08a0a376fcaf7894364b5131db4415890fc2c57a48bb5497d36a57a4aa359fd6781788c697f6a85500d7bee3e7a1597f0900b81b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007300710001000000f62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330105cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000000000000000000000"
);
vm.stopPrank();
@@ -87,7 +87,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
// Encoded solution generated using `test_split_encoding_strategy_usv4_eth_out`
(bool success,) = tychoRouterAddr.call(
hex"7c55384600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000000000000000000000000000000000006824c2da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fd3ce20000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000416b224d97fe1a35f2698380969c22854cf7ed92881ea484df7adb438f8d8e78e66c8617131f6712c5f3b4fa07725725081b2ebe27cd44acd11332a4a72bded96c1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005f005d0001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000040000000000000000000000000000000000000000000bb800003c00"
hex"7c55384600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe9342000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041dbb84c68a4293bcf6303ca45327614667c54226086ddcfa2daa9289c1657da9a57268f4d8ceea3c831d43e5a96b1dc54766bc3fda8845d5c7e266981b9d84c651b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007300710001000000f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000004cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c00000000000000000000000000"
);
vm.stopPrank();
@@ -109,7 +109,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
vm.startPrank(ALICE);
// Encoded solution generated using `test_split_swap_strategy_encoder_wrap`
(bool success,) = tychoRouterAddr.call{value: 1 ether}(
hex"7c5538460000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000903146e5f6c59c064b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006821640400000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9de0c000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041b34e1f3d4e78942b2429b776073a5dfab1420f763de7d7e2a2296ca8abf684f923f7ae7945e824d8a084b9610d33ed49246a36e8e0efbce8ae210b0474f9fe3a1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059005700020000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000"
hex"7c5538460000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000903146e5f6c59c064b000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068261ff900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe9a01000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041eaba97110bc7c3586bf8fa3d3d2c24a3863e84d2e1688689e325e750f860802d745309e3dc818fe029f439c14a52d9a3f48f2873733259c342eb01bdf8ac896b1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059005700020000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000"
);
vm.stopPrank();
@@ -131,7 +131,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
IERC20(DAI_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_swap_strategy_encoder_unwrap`
(bool success,) = tychoRouterAddr.call(
hex"7c5538460000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000000000006821641200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9de1a00000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004181d23336d0cacd47a4d228590a825a1d92a48378cd481ff308b6d235e14b925c584f31e420682879bea58363ca4aa44a3b79557b15a9f73078a4696e00f55f911b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395010200000000000000"
hex"7c5538460000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe93420000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000413c401d4a22c3e0b693b4f9d0807f6107ab6b6d6b716a45978ba175af6e717ae617d4c13b8603db25ee6902b807ee049588ce27030bf3f60833bf26e9561f560c1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000059005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d01395010200000000000000"
);
vm.stopPrank();
@@ -159,7 +159,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
vm.startPrank(ALICE);
// Encoded solution generated using `test_split_encoding_strategy_ekubo`
(bool success,) = address(tychoRouter).call{value: 1 ether}(
hex"79b9b93b0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000078007600010000003d7ebc40af7092e3f1c81f2e996cba5cae2090d705a4ad4f68d0b91cfd19687c881e50f3a00242828c0000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c0000000000000000000000000000000000000000"
hex"79b9b93b0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000078007600010000003d7ebc40af7092e3f1c81f2e996cba5cae2090d705cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c0000000000000000000000000000000000000000"
);
uint256 balancerAfter = IERC20(USDC_ADDR).balanceOf(ALICE);
@@ -181,9 +181,9 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
// Approve permit2
vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_swap_strategy_encoder_complex`
// Encoded solution generated using `test_split_swap_strategy_encoder_complex_route`
(bool success,) = tychoRouterAddr.call(
hex"7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006821643700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9de3f00000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004112f41a590796702b322fa5a9ee1602daef9b22d732e4fd8f122f072b65dda325271f630759db500db8a42bd4f41ddc18ddda63650deaf36228dca702e28eefd31b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950002005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950002005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d53ede3eca2a72b3aecc820e955b36f38437d013950100005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a4163ede3eca2a72b3aecc820e955b36f38437d01395010000000000000000000000000000000000000000000000000000000000"
hex"7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe9342000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041d137d0776bc16ff9c49bfd3e96103ceb6926654f314489cafcf5a64ab7a9c4f2061ed5ffdef67c33c3c5b78036d28d9eb73da156a0e68d8740235be50e88a3481b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950002005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950002005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20100005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010000000000000000000000000000000000000000000000000000000000"
);
vm.stopPrank();
@@ -210,7 +210,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_sequential_swap_strategy_encoder_complex_route`
(bool success,) = tychoRouterAddr.call(
hex"51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006821644a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9de5200000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041530bdcde0c687eacb51a339f30c7b3eff7c078a3bbd4bc852519568dcdf271bb4c6ac05583f32c4a8d1a99be3a2817fe86c15ad2a06c5cf938bde9c22bc80f301c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d01395000200525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a4163ede3eca2a72b3aecc820e955b36f38437d013950100000000000000000000000000000000000000000000000000"
hex"51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe934200000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041d137d0776bc16ff9c49bfd3e96103ceb6926654f314489cafcf5a64ab7a9c4f2061ed5ffdef67c33c3c5b78036d28d9eb73da156a0e68d8740235be50e88a3481b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d01395000200525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20100000000000000000000000000000000000000000000000000"
);
vm.stopPrank();
@@ -234,7 +234,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_sequential_swap_strategy_encoder_no_permit2`
(bool success,) = tychoRouterAddr.call(
hex"e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d01395000100525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a4163ede3eca2a72b3aecc820e955b36f38437d013950100000000000000000000000000000000000000000000000000"
hex"e8a980d70000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d01395000100525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20100000000000000000000000000000000000000000000000000"
);
vm.stopPrank();
@@ -252,9 +252,9 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
// Approve permit2
vm.startPrank(ALICE);
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_cyclic_sequential_swap`
// Encoded solution generated using `test_cyclic_sequential_swap_split_strategy`
(bool success,) = tychoRouterAddr.call(
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f4308e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006821647000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9de780000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000413c8b048dc7b7614106a5aa1fa13e48c02a6a9714dfa07d2c424f68b81a5f828c39ace62f2dd57d7bfad10910ae44f77d68aec5c079fce456028b1bd7f72053151c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400102006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80000"
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f4308e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe934200000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004194fc497ac440b520981d23b4713425da21dc1c801e657d218a917b5c51339a660b9a5fe0a346cb0aacc0d67ebf03f8fa3ec9fade437ef1b08ea837b2442931b61b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400102006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d80000"
);
assertTrue(success, "Call Failed");
@@ -271,7 +271,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_input_cyclic_swap`
(bool success,) = tychoRouterAddr.call(
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006821659d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9dfa5000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041dd84c5cdc51719e377598eccd8eac0aae036e7e0745a7c65b5d44cc817071a7460ccc73934363f33cc7af71dc07545aeff1d92f8c2f0b2973e1fc37e7b2de3551c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400102006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80102005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000"
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe934200000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004194fc497ac440b520981d23b4713425da21dc1c801e657d218a917b5c51339a660b9a5fe0a346cb0aacc0d67ebf03f8fa3ec9fade437ef1b08ea837b2442931b61b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400102006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80102005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000"
);
assertTrue(success, "Call Failed");
@@ -288,7 +288,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
IERC20(USDC_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_split_output_cyclic_swap`
(bool success,) = tychoRouterAddr.call(
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005eea514000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000682165ac00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9dfb400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004107f2b0f9c2e4e308ab43b288d69de30d84b10c8075e4dd9a2cf66594f97a52fb34de2534b89bf1887da74c92fd03464f45baff700dd32e213e3add1a3f351e891b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950102006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400000006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d8000000000000000000"
hex"7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005eea514000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe934200000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004194fc497ac440b520981d23b4713425da21dc1c801e657d218a917b5c51339a660b9a5fe0a346cb0aacc0d67ebf03f8fa3ec9fade437ef1b08ea837b2442931b61b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950102006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400000006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000000000000000000"
);
assertTrue(success, "Call Failed");
@@ -304,7 +304,7 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
IERC20(UWU_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_split_encoding_strategy_curve`
(bool success,) = tychoRouterAddr.call(
hex"79b9b93b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000005c005a00010000001d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e71020100010300000000"
hex"79b9b93b0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000070006e00010000001d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000103cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000"
);
assertTrue(success, "Call Failed");
@@ -312,19 +312,4 @@ contract TychoRouterTestIntegration is TychoRouterTestSetup {
vm.stopPrank();
}
function testSplitCurveIntegrationStETH() public {
deal(ALICE, 1 ether);
vm.startPrank(ALICE);
// Encoded solution generated using `test_split_encoding_strategy_curve_st_eth`
(bool success,) = tychoRouterAddr.call{value: 1 ether}(
hex"79b9b93b0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe840000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000005c005a00010000001d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f67022010001000500000000"
);
assertTrue(success, "Call Failed");
assertEq(IERC20(STETH_ADDR).balanceOf(ALICE), 1000754689941529590);
vm.stopPrank();
}
}

View File

@@ -36,7 +36,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
encodeUniswapV2Swap(
DAI_ADDR,
DAI_USDC_POOL,
tychoRouterAddr,
ALICE,
true,
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
)
@@ -44,22 +44,6 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
return swaps;
}
function testSequentialSwapInternalMethod() public {
// Trade 1 WETH for USDC through DAI - see _getSequentialSwaps for more info
uint256 amountIn = 1 ether;
deal(WETH_ADDR, ALICE, amountIn);
vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(tychoRouterAddr, amountIn);
bytes[] memory swaps = _getSequentialSwaps(false);
tychoRouter.exposedSequentialSwap(amountIn, pleEncode(swaps));
vm.stopPrank();
uint256 usdcBalance = IERC20(USDC_ADDR).balanceOf(tychoRouterAddr);
assertEq(usdcBalance, 2644659787);
assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0);
}
function testSequentialSwapPermit2() public {
// Trade 1 WETH for USDC through DAI - see _getSequentialSwaps for more info
uint256 amountIn = 1 ether;
@@ -232,7 +216,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup {
encodeUniswapV2Swap(
DAI_ADDR,
DAI_USDC_POOL,
tychoRouterAddr,
ALICE,
true,
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
)

View File

@@ -24,7 +24,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV2Swap(
WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
ALICE,
false,
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
);
@@ -65,7 +65,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV2Swap(
WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
ALICE,
false,
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
);
@@ -106,7 +106,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV2Swap(
WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
ALICE,
false,
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
);
@@ -132,7 +132,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV2Swap(
WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
ALICE,
false,
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
);
@@ -167,7 +167,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV2Swap(
WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
ALICE,
false,
TokenTransfer.TransferType.TRANSFER_FROM_TO_PROTOCOL
);
@@ -216,7 +216,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV2Swap(
WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
ALICE,
false,
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
);
@@ -296,7 +296,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max);
// Encoded solution generated using `test_single_swap_strategy_encoder_no_permit2`
(bool success,) = tychoRouterAddr.call(
hex"20144a070000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000008f1d5c1cae3740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139500010000000000000000000000000000"
hex"20144a070000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000008f1d5c1cae3740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000"
);
vm.stopPrank();
@@ -315,7 +315,7 @@ contract TychoRouterSingleSwapTest is TychoRouterTestSetup {
IERC20(WETH_ADDR).approve(PERMIT2_ADDRESS, type(uint256).max);
// Encoded solution generated using `test_single_swap_strategy_encoder`
(bool success,) = tychoRouterAddr.call(
hex"30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000903146e5f6c59c064b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000682169c100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067f9e3c900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000412d3f0fee3fc61987512f024f20b1448eb934f82105a91653dd169179c693aaf95d09ef666ce1d38be70b8156fa6e4ea3e8717204e02fe7ba99a1fc4e5a26e6e11b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139500020000000000000000000000000000"
hex"30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000903146e5f6c59c064b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006826193a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000067fe934200000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041d137d0776bc16ff9c49bfd3e96103ceb6926654f314489cafcf5a64ab7a9c4f2061ed5ffdef67c33c3c5b78036d28d9eb73da156a0e68d8740235be50e88a3481b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200020000000000000000000000000000"
);
vm.stopPrank();

View File

@@ -47,7 +47,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
encodeUniswapV2Swap(
WBTC_ADDR,
USDC_WBTC_POOL,
tychoRouterAddr,
ALICE,
true,
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
)
@@ -72,7 +72,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
encodeUniswapV2Swap(
DAI_ADDR,
DAI_USDC_POOL,
tychoRouterAddr,
ALICE,
true,
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
)
@@ -92,7 +92,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouter.exposedSplitSwap(amountIn, 4, pleEncode(swaps));
vm.stopPrank();
uint256 usdcBalance = IERC20(USDC_ADDR).balanceOf(tychoRouterAddr);
uint256 usdcBalance = IERC20(USDC_ADDR).balanceOf(ALICE);
assertEq(usdcBalance, 2615491639);
assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0);
}
@@ -136,7 +136,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
deal(WETH_ADDR, ALICE, amountIn);
vm.startPrank(ALICE);
IERC20(WETH_ADDR).approve(address(tychoRouterAddr), amountIn);
IERC20(WETH_ADDR).approve(tychoRouterAddr, amountIn);
bytes[] memory swaps = _getSplitSwaps(false);
@@ -154,7 +154,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
uint256 usdcBalance = IERC20(USDC_ADDR).balanceOf(ALICE);
assertEq(usdcBalance, 2615491639);
assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0);
assertEq(IERC20(WETH_ADDR).balanceOf(ALICE), 0);
}
function testSplitSwapUndefinedMinAmount() public {
@@ -268,7 +268,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV2Swap(
WETH_ADDR,
WETH_DAI_POOL,
tychoRouterAddr,
ALICE,
false,
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL
);
@@ -367,7 +367,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
bytes memory protocolData = encodeUniswapV3Swap(
WETH_ADDR,
DAI_ADDR,
tychoRouterAddr,
ALICE,
DAI_WETH_USV3,
zeroForOne,
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL
@@ -428,6 +428,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
USDT_ADDR,
true,
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_ROUTER,
ALICE,
pools
);
@@ -476,7 +477,12 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
});
bytes memory protocolData = UniswapV4Utils.encodeExactInput(
USDE_ADDR, WBTC_ADDR, true, TokenTransfer.TransferType.NONE, pools
USDE_ADDR,
WBTC_ADDR,
true,
TokenTransfer.TransferType.NONE,
ALICE,
pools
);
bytes memory swap = encodeSplitSwap(
@@ -488,7 +494,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
tychoRouter.exposedSplitSwap(amountIn, 2, pleEncode(swaps));
assertEq(IERC20(WBTC_ADDR).balanceOf(tychoRouterAddr), 102718);
assertEq(IERC20(WBTC_ADDR).balanceOf(ALICE), 102718);
}
function testSplitInputCyclicSwapInternalMethod() public {

View File

@@ -37,7 +37,8 @@ contract CurveExecutorExposed is CurveExecutor {
int128 i,
int128 j,
bool tokenApprovalNeeded,
TokenTransfer.TransferType transferType
TokenTransfer.TransferType transferType,
address receiver
)
{
return _decodeData(data);
@@ -67,7 +68,8 @@ contract CurveExecutorTest is Test, Constants {
uint8(2),
uint8(0),
true,
TokenTransfer.TransferType.NONE
TokenTransfer.TransferType.NONE,
ALICE
);
(
@@ -78,7 +80,8 @@ contract CurveExecutorTest is Test, Constants {
int128 i,
int128 j,
bool tokenApprovalNeeded,
TokenTransfer.TransferType transferType
TokenTransfer.TransferType transferType,
address receiver
) = curveExecutorExposed.decodeData(data);
assertEq(tokenIn, WETH_ADDR);
@@ -89,6 +92,7 @@ contract CurveExecutorTest is Test, Constants {
assertEq(j, 0);
assertEq(tokenApprovalNeeded, true);
assertEq(uint8(transferType), uint8(TokenTransfer.TransferType.NONE));
assertEq(receiver, ALICE);
}
function testTriPool() public {
@@ -96,15 +100,12 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether;
deal(DAI_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(DAI_ADDR, USDC_ADDR, TRIPOOL, 1);
bytes memory data = _getData(DAI_ADDR, USDC_ADDR, TRIPOOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 999797);
assertEq(
IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), amountOut);
}
function testStEthPool() public {
@@ -113,14 +114,14 @@ contract CurveExecutorTest is Test, Constants {
deal(address(curveExecutorExposed), amountIn);
bytes memory data =
_getData(ETH_ADDR_FOR_CURVE, STETH_ADDR, STETH_POOL, 1);
_getData(ETH_ADDR_FOR_CURVE, STETH_ADDR, STETH_POOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 1001072414418410897);
assertEq(
IERC20(STETH_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
IERC20(STETH_ADDR).balanceOf(ALICE),
amountOut - 1 // there is something weird in this pool, but won't investigate for now because we don't currently support it in the simulation
);
}
@@ -129,15 +130,13 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether;
deal(WETH_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(WETH_ADDR, WBTC_ADDR, TRICRYPTO2_POOL, 3);
bytes memory data =
_getData(WETH_ADDR, WBTC_ADDR, TRICRYPTO2_POOL, 3, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 2279618);
assertEq(
IERC20(WBTC_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(WBTC_ADDR).balanceOf(ALICE), amountOut);
}
function testSUSDPool() public {
@@ -145,15 +144,12 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 100 * 10 ** 6;
deal(USDC_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(USDC_ADDR, SUSD_ADDR, SUSD_POOL, 1);
bytes memory data = _getData(USDC_ADDR, SUSD_ADDR, SUSD_POOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 100488101605550214590);
assertEq(
IERC20(SUSD_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(SUSD_ADDR).balanceOf(ALICE), amountOut);
}
function testFraxUsdcPool() public {
@@ -161,15 +157,13 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether;
deal(FRAX_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(FRAX_ADDR, USDC_ADDR, FRAX_USDC_POOL, 1);
bytes memory data =
_getData(FRAX_ADDR, USDC_ADDR, FRAX_USDC_POOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 998097);
assertEq(
IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), amountOut);
}
function testUsdeUsdcPool() public {
@@ -177,15 +171,13 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 100 * 10 ** 6;
deal(USDC_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(USDC_ADDR, USDE_ADDR, USDE_USDC_POOL, 1);
bytes memory data =
_getData(USDC_ADDR, USDE_ADDR, USDE_USDC_POOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 100064812138999986170);
assertEq(
IERC20(USDE_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(USDE_ADDR).balanceOf(ALICE), amountOut);
}
function testDolaFraxPyusdPool() public {
@@ -194,32 +186,27 @@ contract CurveExecutorTest is Test, Constants {
deal(DOLA_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data =
_getData(DOLA_ADDR, FRAXPYUSD_POOL, DOLA_FRAXPYUSD_POOL, 1);
_getData(DOLA_ADDR, FRAXPYUSD_POOL, DOLA_FRAXPYUSD_POOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 99688992);
assertEq(
IERC20(FRAXPYUSD_POOL).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(FRAXPYUSD_POOL).balanceOf(ALICE), amountOut);
}
function testCryptoPoolWithETH() public {
// Swapping XYO -> ETH on a CryptoPool, deployed by factory 0xF18056Bbd320E96A48e3Fbf8bC061322531aac99
uint256 amountIn = 1 ether;
uint256 initialBalance = address(curveExecutorExposed).balance; // this address already has some ETH assigned to it
uint256 initialBalance = address(ALICE).balance; // this address already has some ETH assigned to it
deal(XYO_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data =
_getData(XYO_ADDR, ETH_ADDR_FOR_CURVE, ETH_XYO_POOL, 2);
_getData(XYO_ADDR, ETH_ADDR_FOR_CURVE, ETH_XYO_POOL, 2, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 6081816039338);
assertEq(
address(curveExecutorExposed).balance, initialBalance + amountOut
);
assertEq(ALICE.balance, initialBalance + amountOut);
}
function testCryptoPool() public {
@@ -227,15 +214,13 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1000 ether;
deal(BSGG_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(BSGG_ADDR, USDT_ADDR, BSGG_USDT_POOL, 2);
bytes memory data =
_getData(BSGG_ADDR, USDT_ADDR, BSGG_USDT_POOL, 2, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 23429);
assertEq(
IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(USDT_ADDR).balanceOf(ALICE), amountOut);
}
function testTricryptoPool() public {
@@ -243,15 +228,13 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether;
deal(WETH_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(WETH_ADDR, USDC_ADDR, TRICRYPTO_POOL, 2);
bytes memory data =
_getData(WETH_ADDR, USDC_ADDR, TRICRYPTO_POOL, 2, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 1861130974);
assertEq(
IERC20(USDC_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(USDC_ADDR).balanceOf(ALICE), amountOut);
}
function testTwoCryptoPool() public {
@@ -259,15 +242,13 @@ contract CurveExecutorTest is Test, Constants {
uint256 amountIn = 1 ether;
deal(UWU_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data = _getData(UWU_ADDR, WETH_ADDR, UWU_WETH_POOL, 2);
bytes memory data =
_getData(UWU_ADDR, WETH_ADDR, UWU_WETH_POOL, 2, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 2873786684675);
assertEq(
IERC20(WETH_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(WETH_ADDR).balanceOf(ALICE), amountOut);
}
function testStableSwapPool() public {
@@ -276,15 +257,12 @@ contract CurveExecutorTest is Test, Constants {
deal(CRVUSD_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data =
_getData(CRVUSD_ADDR, USDT_ADDR, CRVUSD_USDT_POOL, 1);
_getData(CRVUSD_ADDR, USDT_ADDR, CRVUSD_USDT_POOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 999910);
assertEq(
IERC20(USDT_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(USDT_ADDR).balanceOf(ALICE), amountOut);
}
function testMetaPool() public {
@@ -293,22 +271,20 @@ contract CurveExecutorTest is Test, Constants {
deal(WTAO_ADDR, address(curveExecutorExposed), amountIn);
bytes memory data =
_getData(WTAO_ADDR, WSTTAO_ADDR, WSTTAO_WTAO_POOL, 1);
_getData(WTAO_ADDR, WSTTAO_ADDR, WSTTAO_WTAO_POOL, 1, ALICE);
uint256 amountOut = curveExecutorExposed.swap(amountIn, data);
assertEq(amountOut, 32797923610);
assertEq(
IERC20(WSTTAO_ADDR).balanceOf(address(curveExecutorExposed)),
amountOut
);
assertEq(IERC20(WSTTAO_ADDR).balanceOf(ALICE), amountOut);
}
function _getData(
address tokenIn,
address tokenOut,
address pool,
uint8 poolType
uint8 poolType,
address receiver
) internal view returns (bytes memory data) {
(int128 i, int128 j) = _getIndexes(tokenIn, tokenOut, pool);
data = abi.encodePacked(
@@ -319,7 +295,8 @@ contract CurveExecutorTest is Test, Constants {
uint8(uint256(uint128(i))),
uint8(uint256(uint128(j))),
true,
TokenTransfer.TransferType.NONE
TokenTransfer.TransferType.NONE,
receiver
);
}

View File

@@ -22,6 +22,7 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor {
address tokenOut,
bool zeroForOne,
TokenTransfer.TransferType transferType,
address receiver,
UniswapV4Pool[] memory pools
)
{
@@ -68,7 +69,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
});
bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDT_ADDR, zeroForOne, transferType, pools
USDE_ADDR, USDT_ADDR, zeroForOne, transferType, ALICE, pools
);
(
@@ -76,6 +77,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
address tokenOut,
bool zeroForOneDecoded,
TokenTransfer.TransferType transferTypeDecoded,
address receiver,
UniswapV4Executor.UniswapV4Pool[] memory decodedPools
) = uniswapV4Exposed.decodeData(data);
@@ -83,6 +85,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
assertEq(tokenOut, USDT_ADDR);
assertEq(zeroForOneDecoded, zeroForOne);
assertEq(uint8(transferTypeDecoded), uint8(transferType));
assertEq(receiver, ALICE);
assertEq(decodedPools.length, 2);
assertEq(decodedPools[0].intermediaryToken, USDT_ADDR);
assertEq(decodedPools[0].fee, pool1Fee);
@@ -108,7 +111,12 @@ contract UniswapV4ExecutorTest is Test, Constants {
});
bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, USDT_ADDR, true, TokenTransfer.TransferType.NONE, pools
USDE_ADDR,
USDT_ADDR,
true,
TokenTransfer.TransferType.NONE,
ALICE,
pools
);
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);
@@ -117,14 +125,14 @@ contract UniswapV4ExecutorTest is Test, Constants {
USDE.balanceOf(address(uniswapV4Exposed)),
usdeBalanceBeforeSwapExecutor - amountIn
);
assertTrue(USDT.balanceOf(address(uniswapV4Exposed)) == amountOut);
assertTrue(USDT.balanceOf(ALICE) == amountOut);
}
function testSingleSwapIntegration() public {
// USDE -> USDT
// Generated by the Tycho swap encoder - test_encode_uniswap_v4_simple_swap
bytes memory protocolData =
hex"4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70100dac17f958d2ee523a2206206994597c13d831ec7000064000001";
hex"4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec7000064000001";
uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);
uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager);
@@ -134,10 +142,9 @@ contract UniswapV4ExecutorTest is Test, Constants {
uint256 amountOut = uniswapV4Exposed.swap(amountIn, protocolData);
assertEq(USDE.balanceOf(poolManager), usdeBalanceBeforePool + amountIn);
assertEq(
USDE.balanceOf(address(uniswapV4Exposed)),
usdeBalanceBeforeSwapExecutor - amountIn
USDE.balanceOf(ALICE), usdeBalanceBeforeSwapExecutor - amountIn
);
assertTrue(USDT.balanceOf(address(uniswapV4Exposed)) == amountOut);
assertTrue(USDT.balanceOf(ALICE) == amountOut);
}
function testMultipleSwap() public {
@@ -162,7 +169,12 @@ contract UniswapV4ExecutorTest is Test, Constants {
});
bytes memory data = UniswapV4Utils.encodeExactInput(
USDE_ADDR, WBTC_ADDR, true, TokenTransfer.TransferType.NONE, pools
USDE_ADDR,
WBTC_ADDR,
true,
TokenTransfer.TransferType.NONE,
ALICE,
pools
);
uint256 amountOut = uniswapV4Exposed.swap(amountIn, data);
@@ -171,9 +183,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
USDE.balanceOf(address(uniswapV4Exposed)),
usdeBalanceBeforeSwapExecutor - amountIn
);
assertTrue(
IERC20(WBTC_ADDR).balanceOf(address(uniswapV4Exposed)) == amountOut
);
assertTrue(IERC20(WBTC_ADDR).balanceOf(ALICE) == amountOut);
}
function testMultipleSwapIntegration() public {
@@ -181,7 +191,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
// Generated by the Tycho swap encoder - test_encode_uniswap_v4_sequential_swap
bytes memory protocolData =
hex"4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990100dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c";
hex"4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c";
uint256 amountIn = 100 ether;
deal(USDE_ADDR, address(uniswapV4Exposed), amountIn);
@@ -195,8 +205,6 @@ contract UniswapV4ExecutorTest is Test, Constants {
USDE.balanceOf(address(uniswapV4Exposed)),
usdeBalanceBeforeSwapExecutor - amountIn
);
assertTrue(
IERC20(WBTC_ADDR).balanceOf(address(uniswapV4Exposed)) == amountOut
);
assertTrue(IERC20(WBTC_ADDR).balanceOf(ALICE) == amountOut);
}
}

View File

@@ -9,6 +9,7 @@ library UniswapV4Utils {
address tokenOut,
bool zeroForOne,
UniswapV4Executor.TransferType transferType,
address receiver,
UniswapV4Executor.UniswapV4Pool[] memory pools
) public pure returns (bytes memory) {
bytes memory encodedPools;
@@ -23,7 +24,7 @@ library UniswapV4Utils {
}
return abi.encodePacked(
tokenIn, tokenOut, zeroForOne, transferType, encodedPools
tokenIn, tokenOut, zeroForOne, transferType, receiver, encodedPools
);
}
}

View File

@@ -111,16 +111,19 @@ impl StrategyEncoder for SingleSwapStrategyEncoder {
NativeAction::Unwrap => unwrap = true,
}
}
let protocol = grouped_swap.protocol_system.clone();
let swap_encoder = self
.get_swap_encoder(&grouped_swap.protocol_system)
.get_swap_encoder(&protocol)
.ok_or_else(|| {
EncodingError::InvalidInput(format!(
"Swap encoder not found for protocol: {}",
grouped_swap.protocol_system
protocol
))
})?;
let swap_receiver =
if !unwrap { solution.receiver.clone() } else { self.router_address.clone() };
let mut grouped_protocol_data: Vec<u8> = vec![];
for swap in grouped_swap.swaps.iter() {
let transfer_type = self.get_transfer_type(
@@ -133,7 +136,7 @@ impl StrategyEncoder for SingleSwapStrategyEncoder {
);
let encoding_context = EncodingContext {
receiver: self.router_address.clone(),
receiver: swap_receiver.clone(),
exact_out: solution.exact_out,
router_address: Some(self.router_address.clone()),
group_token_in: grouped_swap.input_token.clone(),
@@ -286,16 +289,25 @@ impl StrategyEncoder for SequentialSwapStrategyEncoder {
}
let mut swaps = vec![];
for grouped_swap in grouped_swaps.iter() {
for (i, grouped_swap) in grouped_swaps.iter().enumerate() {
let protocol = grouped_swap.protocol_system.clone();
let swap_encoder = self
.get_swap_encoder(&grouped_swap.protocol_system)
.get_swap_encoder(&protocol)
.ok_or_else(|| {
EncodingError::InvalidInput(format!(
"Swap encoder not found for protocol: {}",
grouped_swap.protocol_system
protocol
))
})?;
// if it is the last swap and there isn't an unwrap at the end, we can set the receiver
// to the final user
let swap_receiver = if i == grouped_swaps.len() - 1 && !unwrap {
solution.receiver.clone()
} else {
self.router_address.clone()
};
let mut grouped_protocol_data: Vec<u8> = vec![];
for swap in grouped_swap.swaps.iter() {
let transfer_type = self.get_transfer_type(
@@ -308,7 +320,7 @@ impl StrategyEncoder for SequentialSwapStrategyEncoder {
);
let encoding_context = EncodingContext {
receiver: self.router_address.clone(),
receiver: swap_receiver.clone(),
exact_out: solution.exact_out,
router_address: Some(self.router_address.clone()),
group_token_in: grouped_swap.input_token.clone(),
@@ -516,15 +528,22 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
let mut swaps = vec![];
for grouped_swap in grouped_swaps.iter() {
let protocol = grouped_swap.protocol_system.clone();
let swap_encoder = self
.get_swap_encoder(&grouped_swap.protocol_system)
.get_swap_encoder(&protocol)
.ok_or_else(|| {
EncodingError::InvalidInput(format!(
"Swap encoder not found for protocol: {}",
grouped_swap.protocol_system
protocol
))
})?;
let swap_receiver = if !unwrap && grouped_swap.output_token == solution.checked_token {
solution.receiver.clone()
} else {
self.router_address.clone()
};
let mut grouped_protocol_data: Vec<u8> = vec![];
for swap in grouped_swap.swaps.iter() {
let transfer_type = self.get_transfer_type(
@@ -537,7 +556,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
);
let encoding_context = EncodingContext {
receiver: self.router_address.clone(),
receiver: swap_receiver.clone(),
exact_out: solution.exact_out,
router_address: Some(self.router_address.clone()),
group_token_in: grouped_swap.input_token.clone(),
@@ -766,7 +785,7 @@ mod tests {
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"00", // zero2one
"02", // transfer type
"00000000000000", // padding
@@ -869,13 +888,13 @@ mod tests {
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"00", // zero2one
"02", // transfer type
"0000000000000000000000000000", // padding
));
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_single_swap_strategy_encoder: {}", hex_calldata);
assert_eq!(hex_calldata[..456], expected_input);
assert_eq!(hex_calldata[1224..], expected_swap);
@@ -930,7 +949,7 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_single_swap_strategy_encoder_wrap: {}", hex_calldata);
}
#[test]
@@ -982,7 +1001,7 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_split_swap_strategy_encoder_wrap: {}", hex_calldata);
}
#[test]
@@ -1034,7 +1053,7 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_split_swap_strategy_encoder_unwrap: {}", hex_calldata);
}
#[test]
@@ -1126,7 +1145,7 @@ mod tests {
.unwrap();
let _hex_calldata = encode(&calldata);
println!("{}", _hex_calldata);
println!("test_split_swap_strategy_encoder_complex_route: {}", _hex_calldata);
}
#[test]
@@ -1192,14 +1211,11 @@ mod tests {
.unwrap();
let _hex_calldata = encode(&calldata);
println!("{}", _hex_calldata);
println!("test_sequential_swap_strategy_encoder_complex_route: {}", _hex_calldata);
}
#[test]
fn test_sequential_swap_strategy_encoder_no_permit2() {
// Note: This test does not assert anything. It is only used to obtain integration test
// data for our router solidity test.
//
// Performs a split swap from WETH to USDC though WBTC and DAI using USV2 pools
//
// WETH ───(USV2)──> WBTC ───(USV2)──> USDC
@@ -1253,8 +1269,41 @@ mod tests {
.encode_strategy(solution)
.unwrap();
let _hex_calldata = encode(&calldata);
println!("{}", _hex_calldata);
let hex_calldata = encode(&calldata);
println!("test_sequential_swap_strategy_encoder_no_permit2: {}", hex_calldata);
let expected = String::from(concat!(
"e8a980d7", /* function selector */
"0000000000000000000000000000000000000000000000000de0b6b3a7640000", // amount in
"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token ou
"00000000000000000000000000000000000000000000000000000000018f61ec", // min amount out
"0000000000000000000000000000000000000000000000000000000000000000", // wrap
"0000000000000000000000000000000000000000000000000000000000000000", // unwrap
"000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"0000000000000000000000000000000000000000000000000000000000000100", /* length ple
* encode */
"00000000000000000000000000000000000000000000000000000000000000a8",
// swap 1
"0052", // swap length
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"bb2b8038a1640196fbe3e38816f3e67cba72d940", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver (router)
"00", // zero to one
"01", // transfer type
// swap 2
"0052", // swap length
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address
"2260fac5e5542a773aa44fbcfedf7c193bc2c599", // token in
"004375dff511095cc5a197a54140a24efef3a416", // component id
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver (final user)
"01", // zero to one
"00", // transfer type
"000000000000000000000000000000000000000000000000", // padding
));
assert_eq!(hex_calldata, expected);
}
#[test]
@@ -1373,9 +1422,9 @@ mod tests {
let expected_swaps = String::from(concat!(
// length of ple encoded swaps without padding
"0000000000000000000000000000000000000000000000000000000000000079",
"000000000000000000000000000000000000000000000000000000000000008d",
// ple encoded swaps
"0077", // Swap length
"008b", // Swap length
"00", // token in index
"01", // token out index
"000000", // split
@@ -1386,6 +1435,7 @@ mod tests {
"6982508145454ce325ddbe47a25d4ec3d2311933", // group token in
"00", // zero2one
"04", // transfer type (transfer to router)
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
// First pool params
"0000000000000000000000000000000000000000", // intermediary token (ETH)
"000bb8", // fee
@@ -1394,14 +1444,14 @@ mod tests {
"6982508145454ce325ddbe47a25d4ec3d2311933", // intermediary token (PEPE)
"0061a8", // fee
"0001f4", // tick spacing
"00000000000000" // padding
"00000000000000000000000000000000000000" // padding
));
let hex_calldata = encode(&calldata);
assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps);
println!("{}", hex_calldata);
println!("test_split_encoding_strategy_usv4: {}", hex_calldata);
}
#[test]
@@ -1461,7 +1511,7 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_split_encoding_strategy_ekubo: {}", hex_calldata);
}
#[test]
@@ -1529,7 +1579,7 @@ mod tests {
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"00", // zero2one
"01", // transfer type
"0000000000000000000000000000", // padding
@@ -1539,7 +1589,7 @@ mod tests {
let hex_calldata = encode(&calldata);
assert_eq!(hex_calldata, expected_input);
println!("{}", hex_calldata);
println!("test_single_swap_strategy_encoder_no_permit2: {}", hex_calldata);
}
#[test]
@@ -1612,7 +1662,7 @@ mod tests {
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a478c2975ab1ea89e8196811f51a7b7ade33eb11", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"00", // zero2one
"01", // transfer type
"00000000000000", // padding
@@ -1622,7 +1672,7 @@ mod tests {
let hex_calldata = encode(&calldata);
assert_eq!(hex_calldata, expected_input);
println!("{}", hex_calldata);
println!("test_split_swap_strategy_encoder_no_permit2: {}", hex_calldata);
}
#[test]
@@ -1686,7 +1736,7 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_split_encoding_strategy_usv4_eth_in: {}", hex_calldata);
}
#[test]
fn test_split_encoding_strategy_usv4_eth_out() {
@@ -1753,7 +1803,7 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_split_encoding_strategy_usv4_eth_out: {}", hex_calldata);
}
#[test]
@@ -1863,7 +1913,7 @@ mod tests {
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token in
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token out
"0001f4", // pool fee
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
"01", // zero2one
"02", // transfer type
@@ -1874,7 +1924,7 @@ mod tests {
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token out
"000bb8", // pool fee
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
"00", // zero2one
"00", // transfer type
@@ -1883,7 +1933,7 @@ mod tests {
assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps);
println!("{}", hex_calldata);
println!("test_cyclic_sequential_swap_split_strategy: {}", hex_calldata);
}
#[test]
@@ -2017,7 +2067,7 @@ mod tests {
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token in
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token out
"0001f4", // pool fee
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
"01", // zero2one
"02", // transfer type
@@ -2029,7 +2079,7 @@ mod tests {
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token in
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token out
"000bb8", // pool fee
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
"01", // zero2one
"02", // transfer type
@@ -2040,7 +2090,7 @@ mod tests {
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address,
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id,
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"00", // zero2one
"00", // transfer type
"00000000000000" // padding
@@ -2048,7 +2098,7 @@ mod tests {
.join("");
assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps);
println!("{}", hex_calldata);
println!("test_split_input_cyclic_swap: {}", hex_calldata);
}
#[test]
@@ -2178,7 +2228,7 @@ mod tests {
"5615deb798bb3e4dfa0139dfa1b3d433cc23b72f", // executor address
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token in
"b4e16d0168e52d35cacd2c6185b44281ec28c9dc", // component id
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"3ede3eca2a72b3aecc820e955b36f38437d01395", // receiver
"01", // zero2one
"02", // transfer type
"006e", // ple encoded swaps
@@ -2189,7 +2239,7 @@ mod tests {
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token out
"0001f4", // pool fee
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640", // component id
"00", // zero2one
"00", // transfer type
@@ -2201,7 +2251,7 @@ mod tests {
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token out
"000bb8", // pool fee
"3ede3eca2a72b3aecc820e955b36f38437d01395", // router address
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"8ad599c3a0ff1de082011efddc58f1908eb6e6d8", // component id
"00", // zero2one
"00", // transfer type
@@ -2211,7 +2261,7 @@ mod tests {
assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps);
println!("{}", hex_calldata);
println!("test_split_output_cyclic_swap: {}", hex_calldata);
}
#[test]
@@ -2273,7 +2323,7 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_split_encoding_strategy_curve: {}", hex_calldata);
}
#[test]
@@ -2335,6 +2385,6 @@ mod tests {
.unwrap();
let hex_calldata = encode(&calldata);
println!("{}", hex_calldata);
println!("test_split_encoding_strategy_curve_st_eth: {}", hex_calldata);
}
}

View File

@@ -24,12 +24,13 @@ pub trait TransferOptimization {
// In the case of wrapping, check if the swap's token in is the wrapped token to
// determine if it's the first swap. Otherwise, compare to the given token.
let is_first_swap =
(swap.token_in == given_token) || ((swap.token_in == wrapped_token) && wrap);
let is_first_swap = swap.token_in == given_token;
if swap.token_in == native_token {
// Funds are already in router. All protocols currently take care of native transfers.
TransferType::None
} else if (swap.token_in == wrapped_token) && wrap {
TransferType::TransferToProtocol
} else if is_first_swap && send_funds_to_pool {
if permit2 {
// Transfer from swapper to pool using permit2.
@@ -149,7 +150,7 @@ mod tests {
let strategy = MockStrategy {};
let transfer_method =
strategy.get_transfer_type(swap.clone(), eth(), eth(), weth(), false, true);
assert_eq!(transfer_method, TransferType::TransferFromToProtocol);
assert_eq!(transfer_method, TransferType::TransferToProtocol);
}
#[test]

View File

@@ -207,6 +207,7 @@ impl SwapEncoder for UniswapV4SwapEncoder {
group_token_out_address,
zero_to_one,
(encoding_context.transfer_type as u8).to_be_bytes(),
bytes_to_address(&encoding_context.receiver)?,
pool_params,
);
@@ -548,6 +549,7 @@ impl SwapEncoder for CurveSwapEncoder {
j.to_be_bytes::<1>(),
approval_needed,
(encoding_context.transfer_type as u8).to_be_bytes(),
bytes_to_address(&encoding_context.receiver)?,
);
Ok(args.abi_encode_packed())
@@ -765,9 +767,8 @@ mod tests {
split: 0f64,
};
let encoding_context = EncodingContext {
// The receiver address was taken from `address(uniswapV4Exposed)` in the
// UniswapV4Executor.t.sol
receiver: Bytes::from("0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f"),
// The receiver is ALICE to match the solidity tests
receiver: Bytes::from("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2"),
exact_out: false,
// Same as the executor address
router_address: Some(Bytes::from("0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f")),
@@ -786,7 +787,7 @@ mod tests {
.encode_swap(swap, encoding_context)
.unwrap();
let hex_swap = encode(&encoded_swap);
println!("{}", hex_swap);
println!("test_encode_uniswap_v4_simple_swap: {}", hex_swap);
assert_eq!(
hex_swap,
@@ -799,6 +800,8 @@ mod tests {
"01",
// transfer type
"00",
// receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2",
// pool params:
// - intermediary token
"dac17f958d2ee523a2206206994597c13d831ec7",
@@ -877,11 +880,11 @@ mod tests {
let usdt_address = Bytes::from("0xdAC17F958D2ee523a2206206994597C13D831ec7");
let wbtc_address = Bytes::from("0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599");
let router_address = Bytes::from("0x5615deb798bb3e4dfa0139dfa1b3d433cc23b72f");
let receiver_address = router_address.clone();
// The context is the same for both swaps, since the group token in and out are the same
let context = EncodingContext {
receiver: receiver_address.clone(),
// The receiver is ALICE to match the solidity tests
receiver: Bytes::from("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2"),
exact_out: false,
router_address: Some(router_address.clone()),
group_token_in: usde_address.clone(),
@@ -955,7 +958,7 @@ mod tests {
let combined_hex =
format!("{}{}", encode(&initial_encoded_swap), encode(&second_encoded_swap));
println!("{}", combined_hex);
println!("test_encode_uniswap_v4_sequential_swap: {}", combined_hex);
assert_eq!(
combined_hex,
String::from(concat!(
@@ -967,6 +970,8 @@ mod tests {
"01",
// transfer type
"00",
// receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2",
// pool params:
// - intermediary token USDT
"dac17f958d2ee523a2206206994597c13d831ec7",
@@ -982,6 +987,7 @@ mod tests {
"00003c"
))
);
println!("{}", combined_hex)
}
mod ekubo {
@@ -1276,6 +1282,8 @@ mod tests {
"01",
// transfer type
"05",
// receiver,
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e"
))
);
}
@@ -1344,6 +1352,8 @@ mod tests {
"01",
// transfer type
"05",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e"
))
);
}
@@ -1422,6 +1432,8 @@ mod tests {
"01",
// transfer type
"05",
// receiver
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e"
))
);
}

View File

@@ -1050,6 +1050,8 @@ mod tests {
"00",
// transfer type
"00",
// receiver
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2",
// first pool intermediary token (ETH)
"0000000000000000000000000000000000000000",
// fee