From f82ae3b92a82b27981f7178ec5d3c4cc7ec1329a Mon Sep 17 00:00:00 2001 From: Diana Carvalho Date: Thu, 9 Oct 2025 10:26:28 +0200 Subject: [PATCH 1/3] feat: Support Euler low balance single swaps (univ4) Took 1 hour 34 minutes Took 4 minutes --- foundry/src/executors/UniswapV4Executor.sol | 9 +-- foundry/test/Constants.sol | 4 + foundry/test/protocols/UniswapV4.t.sol | 84 +++++++++++++++++---- 3 files changed, 77 insertions(+), 20 deletions(-) diff --git a/foundry/src/executors/UniswapV4Executor.sol b/foundry/src/executors/UniswapV4Executor.sol index 8f245f6..3cdee4f 100644 --- a/foundry/src/executors/UniswapV4Executor.sol +++ b/foundry/src/executors/UniswapV4Executor.sol @@ -275,17 +275,12 @@ contract UniswapV4Executor is address receiver, bytes calldata hookData ) external returns (uint128) { + Currency currencyIn = zeroForOne ? poolKey.currency0 : poolKey.currency1; + _settle(currencyIn, amountIn, transferType); uint128 amountOut = _swap( poolKey, zeroForOne, -int256(uint256(amountIn)), hookData ).toUint128(); - Currency currencyIn = zeroForOne ? poolKey.currency0 : poolKey.currency1; - uint256 amount = _getFullDebt(currencyIn); - if (amount > amountIn) { - revert UniswapV4Executor__V4TooMuchRequested(amountIn, amount); - } - _settle(currencyIn, amount, transferType); - Currency currencyOut = zeroForOne ? poolKey.currency1 : poolKey.currency0; _take(currencyOut, receiver, _mapTakeAmount(amountOut, currencyOut)); diff --git a/foundry/test/Constants.sol b/foundry/test/Constants.sol index f078f36..0053124 100644 --- a/foundry/test/Constants.sol +++ b/foundry/test/Constants.sol @@ -56,6 +56,7 @@ contract Constants is Test, BaseConstants { address BSGG_ADDR = address(0xdA16Cf041E2780618c49Dbae5d734B89a6Bac9b3); address GHO_ADDR = address(0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f); address ONDO_ADDR = address(0xfAbA6f8e4a5E8Ab82F62fe7C39859FA577269BE3); + address RLUSD_ADDR = address(0x8292Bb45bf1Ee4d140127049757C2E0fF06317eD); // Maverick v2 address MAVERICK_V2_FACTORY = 0x0A7e848Aca42d879EF06507Fca0E7b33A0a63c1e; @@ -146,6 +147,9 @@ contract Constants is Test, BaseConstants { // Curve meta registry address CURVE_META_REGISTRY = 0xF98B45FA17DE75FB1aD0e7aFD971b0ca00e379fC; + // Uniswap v4 pool manager + address POOL_MANAGER = 0x000000000004444c5dc75cB358380D2e3dE08A90; + /** * @dev Deploys a dummy contract with non-empty bytecode */ diff --git a/foundry/test/protocols/UniswapV4.t.sol b/foundry/test/protocols/UniswapV4.t.sol index 656fd65..0706ae9 100644 --- a/foundry/test/protocols/UniswapV4.t.sol +++ b/foundry/test/protocols/UniswapV4.t.sol @@ -11,8 +11,8 @@ import {SafeCallback} from "@uniswap/v4-periphery/src/base/SafeCallback.sol"; import {Test} from "../../lib/forge-std/src/Test.sol"; contract UniswapV4ExecutorExposed is UniswapV4Executor { - constructor(IPoolManager _poolManager, address _permit2) - UniswapV4Executor(_poolManager, _permit2) + constructor(IPoolManager _POOL_MANAGER, address _permit2) + UniswapV4Executor(_POOL_MANAGER, _permit2) {} function decodeData(bytes calldata data) @@ -41,13 +41,11 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { IERC20 USDT = IERC20(USDT_ADDR); IERC20 USDC = IERC20(USDC_ADDR); - address poolManager = 0x000000000004444c5dc75cB358380D2e3dE08A90; - function setUp() public { uint256 forkBlock = 22689128; vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock); uniswapV4Exposed = new UniswapV4ExecutorExposed( - IPoolManager(poolManager), PERMIT2_ADDRESS + IPoolManager(POOL_MANAGER), PERMIT2_ADDRESS ); } @@ -114,7 +112,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { function testSingleSwap() public { uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); - uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); + uint256 usdeBalanceBeforePool = USDE.balanceOf(POOL_MANAGER); uint256 usdeBalanceBeforeSwapExecutor = USDE.balanceOf(address(uniswapV4Exposed)); @@ -138,7 +136,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { ); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); - assertEq(USDE.balanceOf(poolManager), usdeBalanceBeforePool + amountIn); + assertEq(USDE.balanceOf(POOL_MANAGER), usdeBalanceBeforePool + amountIn); assertEq( USDE.balanceOf(address(uniswapV4Exposed)), usdeBalanceBeforeSwapExecutor - amountIn @@ -152,12 +150,12 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { loadCallDataFromFile("test_encode_uniswap_v4_simple_swap"); uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); - uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); + uint256 usdeBalanceBeforePool = USDE.balanceOf(POOL_MANAGER); uint256 usdeBalanceBeforeSwapExecutor = USDE.balanceOf(address(uniswapV4Exposed)); uint256 amountOut = uniswapV4Exposed.swap(amountIn, protocolData); - assertEq(USDE.balanceOf(poolManager), usdeBalanceBeforePool + amountIn); + assertEq(USDE.balanceOf(POOL_MANAGER), usdeBalanceBeforePool + amountIn); assertEq( USDE.balanceOf(ALICE), usdeBalanceBeforeSwapExecutor - amountIn ); @@ -168,7 +166,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { // USDE -> USDT -> WBTC uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); - uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); + uint256 usdeBalanceBeforePool = USDE.balanceOf(POOL_MANAGER); uint256 usdeBalanceBeforeSwapExecutor = USDE.balanceOf(address(uniswapV4Exposed)); @@ -197,7 +195,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { ); uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); - assertEq(USDE.balanceOf(poolManager), usdeBalanceBeforePool + amountIn); + assertEq(USDE.balanceOf(POOL_MANAGER), usdeBalanceBeforePool + amountIn); assertEq( USDE.balanceOf(address(uniswapV4Exposed)), usdeBalanceBeforeSwapExecutor - amountIn @@ -212,12 +210,12 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); - uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); + uint256 usdeBalanceBeforePool = USDE.balanceOf(POOL_MANAGER); uint256 usdeBalanceBeforeSwapExecutor = USDE.balanceOf(address(uniswapV4Exposed)); uint256 amountOut = uniswapV4Exposed.swap(amountIn, protocolData); - assertEq(USDE.balanceOf(poolManager), usdeBalanceBeforePool + amountIn); + assertEq(USDE.balanceOf(POOL_MANAGER), usdeBalanceBeforePool + amountIn); assertEq( USDE.balanceOf(address(uniswapV4Exposed)), usdeBalanceBeforeSwapExecutor - amountIn @@ -267,6 +265,66 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { } } +contract UniswapV4ExecutorTestForEuler is Constants, TestUtils { + /* These tests are necessary because Euler works a little differently from general UniswapV4 logic. + In the previous version of the UniswapV4Executor we are only sending the user's tokens into the Pool Manager + after we call swap on it. This is ok because the Pool Manager tracks the debts and accepts everything as long + as the tokens are transfers inside of the unlock callback. However, Euler expects the funds to already be + in the Pool Manager when beforeSwap is called. This is not a problem for tokens that the Pool Manager has a + lot of, but for tokens with low balances this makes the tx fail. We need to transfer the tokens into + the Pool Manager before we call swap on it. + The only risk here is that we are assuming that the amount_in will never change. In the previous version, we + were confirming this amount with the currencyDelta of the Pool Manager. Now we pray. + */ + using SafeERC20 for IERC20; + + UniswapV4ExecutorExposed uniswapV4Exposed; + IERC20 USDT = IERC20(USDT_ADDR); + IERC20 RLUSD = IERC20(RLUSD_ADDR); + + function setUp() public { + uint256 forkBlock = 23535338; + vm.createSelectFork(vm.rpcUrl("mainnet"), forkBlock); + uniswapV4Exposed = new UniswapV4ExecutorExposed( + IPoolManager(POOL_MANAGER), PERMIT2_ADDRESS + ); + } + + function testSingleSwapEulerLowBalance() public { + uint256 amountIn = 134187695711754971245517404; + deal(RLUSD_ADDR, address(uniswapV4Exposed), amountIn); + address eulerProxy = 0xe1Ce9AF672f8854845E5474400B6ddC7AE458a10; + uint256 rlusdEulerBalanceBefore = RLUSD.balanceOf(eulerProxy); + uint256 rlusdBalanceBeforeSwapExecutor = + RLUSD.balanceOf(address(uniswapV4Exposed)); + + UniswapV4Executor.UniswapV4Pool[] memory pools = + new UniswapV4Executor.UniswapV4Pool[](1); + pools[0] = UniswapV4Executor.UniswapV4Pool({ + intermediaryToken: USDT_ADDR, + fee: uint24(50), + tickSpacing: int24(1) + }); + + bytes memory data = UniswapV4Utils.encodeExactInput( + RLUSD_ADDR, + USDT_ADDR, + true, + RestrictTransferFrom.TransferType.Transfer, + ALICE, + address(0xF87ACF8428F2f9403AAA0256A7272d6549ECa8A8), + bytes(""), + pools + ); + + uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); + assertEq( + RLUSD.balanceOf(eulerProxy), rlusdEulerBalanceBefore + amountIn + ); + assertTrue(USDT.balanceOf(ALICE) == amountOut); + } +} + contract TychoRouterForBalancerV3Test is TychoRouterTestSetup { function testSingleSwapUSV4CallbackPermit2() public { vm.startPrank(ALICE); From d13b4d8586b8371ffd16100695aee80665000cd9 Mon Sep 17 00:00:00 2001 From: Diana Carvalho Date: Thu, 9 Oct 2025 11:16:26 +0200 Subject: [PATCH 2/3] fix: Hook and hook data are per pool! not per swap This was a big bug that was blocking a grouped swap in uniswap v4 with hooks Updated execution and encoding to match te fix Took 49 minutes --- foundry/src/executors/UniswapV4Executor.sol | 79 +++++++++++++------ foundry/test/assets/calldata.txt | 32 ++++---- foundry/test/protocols/UniswapV4.t.sol | 63 +++++++-------- foundry/test/protocols/UniswapV4Utils.sol | 16 ++-- .../evm/swap_encoder/swap_encoders.rs | 64 +++++++++------ src/encoding/evm/tycho_encoders.rs | 14 +++- tests/protocol_integration_tests.rs | 11 ++- 7 files changed, 168 insertions(+), 111 deletions(-) diff --git a/foundry/src/executors/UniswapV4Executor.sol b/foundry/src/executors/UniswapV4Executor.sol index 3cdee4f..ce17196 100644 --- a/foundry/src/executors/UniswapV4Executor.sol +++ b/foundry/src/executors/UniswapV4Executor.sol @@ -59,6 +59,8 @@ contract UniswapV4Executor is address intermediaryToken; uint24 fee; int24 tickSpacing; + address hook; + bytes hookData; } constructor(IPoolManager _poolManager, address _permit2) @@ -89,8 +91,6 @@ contract UniswapV4Executor is bool zeroForOne, TransferType transferType, address receiver, - address hook, - bytes memory hookData, UniswapV4Executor.UniswapV4Pool[] memory pools ) = _decodeData(data); bytes memory swapData; @@ -100,7 +100,7 @@ contract UniswapV4Executor is currency1: Currency.wrap(zeroForOne ? tokenOut : tokenIn), fee: pools[0].fee, tickSpacing: pools[0].tickSpacing, - hooks: IHooks(hook) + hooks: IHooks(pools[0].hook) }); swapData = abi.encodeWithSelector( this.swapExactInputSingle.selector, @@ -109,7 +109,7 @@ contract UniswapV4Executor is amountIn, transferType, receiver, - hookData + pools[0].hookData ); } else { PathKey[] memory path = new PathKey[](pools.length); @@ -118,8 +118,8 @@ contract UniswapV4Executor is intermediateCurrency: Currency.wrap(pools[i].intermediaryToken), fee: pools[i].fee, tickSpacing: pools[i].tickSpacing, - hooks: IHooks(hook), - hookData: hookData + hooks: IHooks(pools[i].hook), + hookData: pools[i].hookData }); } @@ -149,8 +149,6 @@ contract UniswapV4Executor is bool zeroForOne, TransferType transferType, address receiver, - address hook, - bytes memory hookData, UniswapV4Pool[] memory pools ) { @@ -163,42 +161,71 @@ contract UniswapV4Executor is zeroForOne = data[40] != 0; transferType = TransferType(uint8(data[41])); receiver = address(bytes20(data[42:62])); - hook = address(bytes20(data[62:82])); - bytes calldata remaining = data[82:]; + bytes calldata remaining = data[62:]; + + // Decode first pool with hook data + if (remaining.length < 48) { + // 20 + 3 + 3 + 20 + 2 = 48 minimum + revert UniswapV4Executor__InvalidDataLength(); + } + address firstToken = address(bytes20(remaining[0:20])); uint24 firstFee = uint24(bytes3(remaining[20:23])); int24 firstTickSpacing = int24(uint24(bytes3(remaining[23:26]))); - UniswapV4Pool memory firstPool = - UniswapV4Pool(firstToken, firstFee, firstTickSpacing); + address firstHook = address(bytes20(remaining[26:46])); + uint16 firstHookDataLength = uint16(bytes2(remaining[46:48])); + + uint256 firstPoolTotalLength = 48 + firstHookDataLength; + if (remaining.length < firstPoolTotalLength) { + revert UniswapV4Executor__InvalidDataLength(); + } + + bytes memory firstHookData = remaining[48:48 + firstHookDataLength]; // Remaining after first pool are ple encoded - bytes[] memory encodedPools = - LibPrefixLengthEncodedByteArray.toArray(remaining[26:]); + bytes[] memory encodedPools = LibPrefixLengthEncodedByteArray.toArray( + remaining[firstPoolTotalLength:] + ); pools = new UniswapV4Pool[](1 + encodedPools.length); - pools[0] = firstPool; - - uint256 encodedPoolsLength = 26; - uint256 plePoolsTotalLength; + pools[0] = UniswapV4Pool( + firstToken, firstFee, firstTickSpacing, firstHook, firstHookData + ); + // Decode subsequent pools for (uint256 i = 0; i < encodedPools.length; i++) { - bytes memory poolsData = encodedPools[i]; + bytes memory poolData = encodedPools[i]; + address intermediaryToken; uint24 fee; int24 tickSpacing; + address hook; + uint16 hookDataLength; // slither-disable-next-line assembly assembly { - intermediaryToken := mload(add(poolsData, add(0, 20))) - fee := shr(232, mload(add(poolsData, add(0, 52)))) - tickSpacing := shr(232, mload(add(poolsData, add(0, 55)))) + let dataPtr := add(poolData, 0x20) + intermediaryToken := shr(96, mload(dataPtr)) + fee := and(shr(232, mload(add(dataPtr, 20))), 0xffffff) + tickSpacing := and(shr(208, mload(add(dataPtr, 20))), 0xffffff) + hook := shr(96, mload(add(dataPtr, 26))) + hookDataLength := and(shr(240, mload(add(dataPtr, 46))), 0xffff) } - pools[i + 1] = UniswapV4Pool(intermediaryToken, fee, tickSpacing); - plePoolsTotalLength += 2 + encodedPoolsLength; // 2 bytes prefix + data - } - hookData = remaining[26 + plePoolsTotalLength:]; + if (poolData.length < 48 + hookDataLength) { + revert UniswapV4Executor__InvalidDataLength(); + } + + bytes memory hookData = new bytes(hookDataLength); + for (uint256 j = 0; j < hookDataLength; j++) { + hookData[j] = poolData[48 + j]; + } + + pools[i + 1] = UniswapV4Pool( + intermediaryToken, fee, tickSpacing, hook, hookData + ); + } } /** diff --git a/foundry/test/assets/calldata.txt b/foundry/test/assets/calldata.txt index 2d18bc3..53814ef 100644 --- a/foundry/test/assets/calldata.txt +++ b/foundry/test/assets/calldata.txt @@ -3,40 +3,40 @@ test_single_encoding_strategy_ekubo:5c4b639c000000000000000000000000000000000000 test_uniswap_v3_uniswap_v3:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010100000000000000000000 test_balancer_v2_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 test_sequential_swap_strategy_encoder_no_permit2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 -test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000690c64a200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4deaa00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041f647d5b34e89b6a97afb8880fe9d6a814dca3d2d4e28559d3c4a95209b0a77237e856d8303775681662344f6dee5c669a4495c8caee979312f9f2e3460d1da051c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800003c001a6982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000 -test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000690c670900000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4e11100000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041990c5c3a2b47a6a93e19ed7b4d80c2c46c260fd9e814c0d752b57884c5b8037a25b3b66412a1288b8c4abc7a38bb9147422a8322dcc8fb1fe28394b3a4d792db1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800003c -test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690c618500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8d00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004176425407bdc375ba702de9eb3f58406fd84cf11ae8885c85fd2856a158b4f5551af0968035b666fc98f6385e0c3648948e1ea697bfa1b482b0e499029331afc21c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 +test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000690f090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830800000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000413ff4a94daefbf49fdbb8365edb64ffafab52f5956d05d2d7fd8ca98d758022e66819727a763ce0082e04dcf578d48c716c89cfbdc3a9bbb091e2142983c840941b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000000000306982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000000000000000000000000000000000000000000000000000000000000000 +test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000690f090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830800000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041423151502b4b094bdb826ae8812816cc10a4feb0f42c1bb27ec2fe207bfa5763545fbd27dc088fc4803474e546e2d052cae205755eab4a0acbe550d439463e891c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690f090100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830900000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004178d16caffcd0a2f2e9be59eb09f823e80783766a64b5fbaf807e60069c14f6e73ecd21c5d9609ced8e9c2a9c97bca55f855b181b826a3abf8dba47449d44ff091b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 test_single_swap_strategy_encoder_no_permit2:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_single_swap_strategy_encoder_no_transfer_in:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 -test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690c618400000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8c00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041392f23271f720a74fefe973884fe5c2957bc9fe0c2618858150bfdf6a7063a341c716c580a76ce02a74a07ecf46c0c5378edf16917acc4888960c85fe18b0fb11c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080f62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330061a80001f4 -test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000690c618500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8d00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000411f7857a9cfde5489563219e61f71377735a58a32f0728ddd74f2b71e7b758b84670dea155b2c8a49737afd32f5d54debc766d314368453d2893fe2fd30cc654a1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000 +test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690f090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830800000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041746aae798b7622f0ca13268b11ab27fdcf0cf25a6d8978245140df94dbe87ae20f223bf34c6d4590af4de87dbe7ba6527997d3dbee049a8ada634b258fa2f7b91c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082f62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000690f090100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000412e6c8abb344d17d190c8b200325cf75cb530b799ee05f1c0f6852267fbf0c55f7f965ffc1bdc77ef8ce31c5967d0864db62604c4d73e42250f51f9374aa5b6251c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000 test_single_encoding_strategy_curve_st_eth:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f670220100010002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000 test_single -test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000064000001001a2260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c +test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000010000000000000000000000000000000000000000000000302260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c00000000000000000000000000000000000000000000 6d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006869398600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006841b38e00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041752ca399237fc5086ef89d5f6dabecfb4b43c0753ecfb7020a6a86045db423fd3be9565f79b511fe93f55f76f61b1ac8d786b04051110ca6cbe10bbf69901b871c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_single_encoding_strategy_curve:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000 -test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be0000000000000000000000000000000000000000000000000000000000000690c618500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8d00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041d850a41d303b8f3b986037309f03d354916d3626079e71262d46a331ac0c0bd02a1d37fb24f8c16470733ea331ba92d5d280654df1a1a690a7cf1ca129177b5c1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000 -test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690c618500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8d00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004164b437b923b8c5c9c8c23615665f6cc9e9d78e727933983bc00a27cc6f5402247cc65b837a344aa5969a8d1d1ba94468cea0964c204e849684d428d5ed3d7d7e1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 -test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000690c618600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8e0000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000412789f69867940869a21a45b54866a03699f58efc8de7bb501f83e11871660fda682dcd54577dfb06e4680b9ec072aa494dcdd379208cad750f222f8e0def00dc1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000 -test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000690c618600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8e0000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000000412789f69867940869a21a45b54866a03699f58efc8de7bb501f83e11871660fda682dcd54577dfb06e4680b9ec072aa494dcdd379208cad750f222f8e0def00dc1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000 -test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690c618600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8e000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041e7c7f461b2cdde06f27be36481b7053786063a8518e4d3389f79e36ec9d97f0168e4c80606daa0de04ee6ef93b43b893b79b5c52c0f2b4e81c0b5ae15d288bd01c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000 +test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be0000000000000000000000000000000000000000000000000000000000000690f090100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000418b2fe3debafebd25629834d68bbad24353d43f264dc41d167f45d55e517ea52c20caf3a48d880084a0a91864cab498cd4a5bec85cfdd2c4876a8460833d95c5c1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000 +test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690f090100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041968ae60683fbbd07f3e74ec161797ce5c86e2bc3f95267efc303dfd2637c1f1e4b773a5ceb439bf55c24fd839688a4e6da45e7b14bb0558390907c262c4f9efe1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 +test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000690f090200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830a000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041863289c930c3659128f786cf07248a8012e7e1797a19aa5582c7847fd0af127838c48108b480c69c30f7f5a7db106478ca37de285ec843b2c842d40edf8df0c71b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000 +test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000690f090200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830a000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041863289c930c3659128f786cf07248a8012e7e1797a19aa5582c7847fd0af127838c48108b480c69c30f7f5a7db106478ca37de285ec843b2c842d40edf8df0c71b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000 +test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690f090200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830a000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041a3d697791c6f3d3223723b6c607e71edd837d835c5708c3cf0587af85f8d02d51582be268c2e9236c46f41473b66c5bd45c69aee839c56e03cf2786010effd8b1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000 test_uniswap_v3_curve:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000 -test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf0000000000000000000000000000000000000000000000000000000000000690c618300000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8b00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041c102acdbcd521340ef5598bff05e7e7af02527bb3ddeb00463fb2228f94747f514b158749ca67ebb8cff3b2a65d6da4ab73d9aee46125c52fdc9f1a18a53ba081b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022800525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c432000000320080f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000bb800003c000000000000000000000000000000000000000000000000 +test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf0000000000000000000000000000000000000000000000000000000000000690f090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830800000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000413a3b95dd4c1944a591871536bdd122ff018094da0f1698692a3c381fdcc00a6b13e86dfe7e5ceaa474a8cec68a52aaa02804e0ab8855bb6b4e0e3f3f68ae52a01b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022a00525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c432000000320082f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 test_encode_balancer_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0102 test_ekubo_encode_swap_multi:01ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032 -test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000064000001001a2260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c -test_encode_uniswap_v4_simple_swap:4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7000064000001 +test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000010000000000000000000000000000000000000000000000302260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c00000000000000000000000000000000000000000000 +test_encode_uniswap_v4_simple_swap:4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec70101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec700006400000100000000000000000000000000000000000000000000 test_single_encoding_strategy_maverick:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000051a4ad4f68d0b91cfd19687c881e50f3a00242828c40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c67cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_encode_maverick_v2:40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c671d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e01 test_encode_uniswap_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb111d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0001 test_encode_balancer_v3:7bc3485026ac48b6cf9baf0a377477fff5703af8c71ea051a5f82c67adcf634c36ffe6334793d24c85b2b559bc2d21104c4defdd6efca8a20343361d011d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e test_single_encoding_strategy_balancer_v3:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000097ffedb80d4b2ca6105a07a4d90eb739c45a66600000000000000000000000030881baa943777f92dc934d53d3bfdf33382cab300000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000006503a6a84cd762d9707a21605b548aaab891562aab097ffedb80d4b2ca6105a07a4d90eb739c45a66630881baa943777f92dc934d53d3bfdf33382cab3f028ac624074d6793c36dc8a06ecec0f5a39a71800cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000 test_uniswap_v3_balancer_v3:e21dd0d3000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000004a220e6096b25eadb88358cb44068a324825467500000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d200692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed0000006503a6a84cd762d9707a21605b548aaab891562aab2260fac5e5542a773aa44fbcfedf7c193bc2c5994a220e6096b25eadb88358cb44068a3248254675571bea0e99e139cd0b6b7d9352ca872dfe0d72dd01cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000 -test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690c618500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8d00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004176425407bdc375ba702de9eb3f58406fd84cf11ae8885c85fd2856a158b4f5551af0968035b666fc98f6385e0c3648948e1ea697bfa1b482b0e499029331afc21c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 +test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000690f090200000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830a00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041a3d697791c6f3d3223723b6c607e71edd837d835c5708c3cf0587af85f8d02d51582be268c2e9236c46f41473b66c5bd45c69aee839c56e03cf2786010effd8b1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_uniswap_v3_bebop:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000000000000000000000000000198473000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000034400692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000002d7d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb482260fac5e5542a773aa44fbcfedf7c193bc2c599020c0000000000000000000000000000000000000000000000000000000000198473011d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e4dcebcba00000000000000000000000000000000000000000000000000000000689dcb3c0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000bee3211ab312a8d065c4fef0247448e17a8da0000000000000000000000000000000000000000000000000002901f2d62bc91b77000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000007881786100000000000000000000000000000000000000000000000000000000001984730000000000000000000000001d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0000000000000000000000000000000000000000000000000000000000000000a02bc8495ad1c76c31d466ce719f80400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000041f3a03b07f390cd707402912278414c46190ca8ca362dd218b9a58956178cb6ee0e5755db7abe02fe15d498d092d4c6865a5eb18486b3e45e27d50d34b87bf1e21c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 test_single_encoding_strategy_bebop_aggregate:5c4b639c00000000000000000000000000000000000000000000000000000004a817c800000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000003f5b138698d22b5cfda00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a1000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000897d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab82f62fe7c39859fa577269be300020000000000000000000000000000000000000000000003f5b138698d22b5cfda01d2068e04cf586f76eece7ba5beb779d7bb1474a1a2f7489300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000689b78880000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000005a060a5c2aaaaa2fe2cda34423cac76a84c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000051c72848c68a965f66fa7a88855f9f7784502a7f000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000002901f2d62bb356ca0000000000000000000000000000000000000000000000002901f2d62bb356cb0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000001000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be30000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000044f83c726000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000589400da00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000003aa5f96046644f6e37a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000004b51a26526ddbeec60000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000417ab4332f2b091d87d56d04eee35dd49452782c782de71608c0425c5ae41f1d7e147173851c870d76720ce07d45cd8622352716b1c7965819ee2bf8c573c499ae1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410c8da2637aa929e11caff9afdfc4c489320c6dba77cc934d88ba8956e365fd1d48983087c6e474bbb828181cdfdd17317c4c9c3ee4bc98e3769d0c05cc7a285e1c00000000000000000000000000000000000000000000000000000000000000000000000000000000 test_single_encoding_strategy_bebop:5c4b639c000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be300000000000000000000000000000000000000000000000a8aea46aa4ec5c0f500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a10000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000002d7d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab82f62fe7c39859fa577269be3000c00000000000000000000000000000000000000000000000a8aea46aa4ec5c0f501d2068e04cf586f76eece7ba5beb779d7bb1474a14dcebcba00000000000000000000000000000000000000000000000000000000689b548f0000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000000000000000000000000000279ead5d9685f25b000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000a8aea46aa4ec5c0f5000000000000000000000000d2068e04cf586f76eece7ba5beb779d7bb1474a100000000000000000000000000000000000000000000000000000000000000005230bcb979c81cebf94a3b5c08bcfa300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414ce40058ff07f11d9224c2c8d1e58369e4a90173856202d8d2a17da48058ad683dedb742eda0d4c0cf04cf1c09138898dd7fd06f97268ea7f74ef9b42d29bf4c1b00000000000000000000000000000000000000000000000000000000000000000000000000000000 -test_sequential_swap_strategy_encoder_unwrap:51bcc7b600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000690c618500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e4db8d00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041925993edd03b83a6ee0aa2e7d70bbe3c5db69f9b2e98e8baab7d9885362934a43eb12dd8f4ddec098f1e912e79f346ed686577a689386aad1204f8f8ef5d90e31b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48004375dff511095cc5a197a54140a24efef3a416bb2b8038a1640196fbe3e38816f3e67cba72d940000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950102000000000000000000000000000000000000000000000000 +test_sequential_swap_strategy_encoder_unwrap:51bcc7b600000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000690f090100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068e7830900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041292fdeef4199f5cbca3f5246fdbf321cc8b7e93fc10101305a874784613a3c0765738f19032a4f0aceeec5ffc8f4fe4dcd5782a9e1272cf5f742e36b281195e11c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48004375dff511095cc5a197a54140a24efef3a416bb2b8038a1640196fbe3e38816f3e67cba72d940000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950102000000000000000000000000000000000000000000000000 test_sequential_swap_usx:0101e21dd0d300000000000000000000000000000000000000000000006c6b935b8bbd4000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000769cfd80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d9da78b6a5bedca287aa5d49613ba36b90c15c40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470b6b175474e89094c44da98b954eedeac495271d0fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000643ede3eca2a72b3aecc820e955b36f38437d013955777d92f208679db4b9778590fa3cab3ac9e2168010000692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48dac17f958d2ee523a2206206994597c13d831ec70000646d9da78b6a5bedca287aa5d49613ba36b90c15c43416cf6c708da44db2624d63ea0aaef7113527c6010100000000000000000000 test_uniswap_v3_hashflow:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000000038aebf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001c800692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400000015b15cf58144ef33af1e14b5208015d11f9143e27b90201478eca1b93865dca0b9f325935eb123c8a4af011bee3211ab312a8d065c4fef0247448e17a8da000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb482260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000000000000000000000000100c84f11000000000000000000000000000000000000000000000000000000000038aebf0000000000000000000000000000000000000000000000000000000068a47cd800000000000000000000000000000000000000000000000000000198c286fecb125000064000640000001747eb8c38ffffffffffffff0029642016edb36d00006ddb3b21fe8509e274ddf46c55209cdbf30360944abbca6569ed6b26740d052f419964dcb5a3bdb98b4ed1fb3642a2760b8312118599a962251f7a8f73fe4fbe1c000000000000000000000000000000000000000000000000 test_single_encoding_strategy_hashflow:5c4b639c0000000000000000000000000000000000000000000000000000000100c84f11000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000000038aebf00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000015b15cf58144ef33af1e14b5208015d11f9143e27b90001478eca1b93865dca0b9f325935eb123c8a4af011bee3211ab312a8d065c4fef0247448e17a8da000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb482260fac5e5542a773aa44fbcfedf7c193bc2c5990000000000000000000000000000000000000000000000000000000100c84f11000000000000000000000000000000000000000000000000000000000038aebf0000000000000000000000000000000000000000000000000000000068a47cd800000000000000000000000000000000000000000000000000000198c286fecb125000064000640000001747eb8c38ffffffffffffff0029642016edb36d00006ddb3b21fe8509e274ddf46c55209cdbf30360944abbca6569ed6b26740d052f419964dcb5a3bdb98b4ed1fb3642a2760b8312118599a962251f7a8f73fe4fbe1c0000000000 diff --git a/foundry/test/protocols/UniswapV4.t.sol b/foundry/test/protocols/UniswapV4.t.sol index 0706ae9..2cd63a7 100644 --- a/foundry/test/protocols/UniswapV4.t.sol +++ b/foundry/test/protocols/UniswapV4.t.sol @@ -24,8 +24,6 @@ contract UniswapV4ExecutorExposed is UniswapV4Executor { bool zeroForOne, RestrictTransferFrom.TransferType transferType, address receiver, - address hook, - bytes memory hookData, UniswapV4Pool[] memory pools ) { @@ -61,12 +59,16 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { pools[0] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: USDT_ADDR, fee: pool1Fee, - tickSpacing: tickSpacing1 + tickSpacing: tickSpacing1, + hook: address(0), + hookData: bytes("") }); pools[1] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: USDE_ADDR, fee: pool2Fee, - tickSpacing: tickSpacing2 + tickSpacing: tickSpacing2, + hook: address(0), + hookData: bytes("0x12345") }); bytes memory data = UniswapV4Utils.encodeExactInput( @@ -75,8 +77,6 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { zeroForOne, RestrictTransferFrom.TransferType.Transfer, ALICE, - address(0), - bytes(""), pools ); @@ -86,8 +86,6 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { bool zeroForOneDecoded, RestrictTransferFrom.TransferType transferType, address receiver, - address hook, - bytes memory hookData, UniswapV4Executor.UniswapV4Pool[] memory decodedPools ) = uniswapV4Exposed.decodeData(data); @@ -99,7 +97,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { uint8(RestrictTransferFrom.TransferType.Transfer) ); assertEq(receiver, ALICE); - assertEq(hook, address(0)); + assertEq(decodedPools[0].hook, address(0)); assertEq(decodedPools.length, 2); assertEq(decodedPools[0].intermediaryToken, USDT_ADDR); assertEq(decodedPools[0].fee, pool1Fee); @@ -107,6 +105,7 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { assertEq(decodedPools[1].intermediaryToken, USDE_ADDR); assertEq(decodedPools[1].fee, pool2Fee); assertEq(decodedPools[1].tickSpacing, tickSpacing2); + assertEq(decodedPools[1].hookData, bytes("0x12345")); } function testSingleSwap() public { @@ -121,7 +120,9 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { pools[0] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: USDT_ADDR, fee: uint24(100), - tickSpacing: int24(1) + tickSpacing: int24(1), + hook: address(0), + hookData: bytes("") }); bytes memory data = UniswapV4Utils.encodeExactInput( @@ -130,8 +131,6 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { true, RestrictTransferFrom.TransferType.Transfer, ALICE, - address(0), - bytes(""), pools ); @@ -175,12 +174,16 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { pools[0] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: USDT_ADDR, fee: uint24(100), - tickSpacing: int24(1) + tickSpacing: int24(1), + hook: address(0), + hookData: bytes("") }); pools[1] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: WBTC_ADDR, fee: uint24(3000), - tickSpacing: int24(60) + tickSpacing: int24(60), + hook: address(0), + hookData: bytes("") }); bytes memory data = UniswapV4Utils.encodeExactInput( @@ -189,8 +192,6 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { true, RestrictTransferFrom.TransferType.Transfer, ALICE, - address(0), - bytes(""), pools ); @@ -237,7 +238,9 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { pools[0] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: WETH_ADDR, fee: uint24(500), - tickSpacing: int24(1) + tickSpacing: int24(1), + hook: hook, + hookData: bytes("") }); bytes memory data = UniswapV4Utils.encodeExactInput( @@ -246,8 +249,6 @@ contract UniswapV4ExecutorTest is Constants, TestUtils { true, RestrictTransferFrom.TransferType.Transfer, ALICE, - hook, - bytes(""), pools ); @@ -295,15 +296,15 @@ contract UniswapV4ExecutorTestForEuler is Constants, TestUtils { deal(RLUSD_ADDR, address(uniswapV4Exposed), amountIn); address eulerProxy = 0xe1Ce9AF672f8854845E5474400B6ddC7AE458a10; uint256 rlusdEulerBalanceBefore = RLUSD.balanceOf(eulerProxy); - uint256 rlusdBalanceBeforeSwapExecutor = - RLUSD.balanceOf(address(uniswapV4Exposed)); UniswapV4Executor.UniswapV4Pool[] memory pools = new UniswapV4Executor.UniswapV4Pool[](1); pools[0] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: USDT_ADDR, fee: uint24(50), - tickSpacing: int24(1) + tickSpacing: int24(1), + hook: address(0xF87ACF8428F2f9403AAA0256A7272d6549ECa8A8), + hookData: bytes("") }); bytes memory data = UniswapV4Utils.encodeExactInput( @@ -312,8 +313,6 @@ contract UniswapV4ExecutorTestForEuler is Constants, TestUtils { true, RestrictTransferFrom.TransferType.Transfer, ALICE, - address(0xF87ACF8428F2f9403AAA0256A7272d6549ECa8A8), - bytes(""), pools ); @@ -340,7 +339,9 @@ contract TychoRouterForBalancerV3Test is TychoRouterTestSetup { pools[0] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: USDT_ADDR, fee: uint24(100), - tickSpacing: int24(1) + tickSpacing: int24(1), + hook: address(0), + hookData: bytes("") }); bytes memory protocolData = UniswapV4Utils.encodeExactInput( @@ -349,8 +350,6 @@ contract TychoRouterForBalancerV3Test is TychoRouterTestSetup { true, RestrictTransferFrom.TransferType.TransferFrom, ALICE, - address(0), - bytes(""), pools ); @@ -385,12 +384,16 @@ contract TychoRouterForBalancerV3Test is TychoRouterTestSetup { pools[0] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: USDT_ADDR, fee: uint24(100), - tickSpacing: int24(1) + tickSpacing: int24(1), + hook: address(0), + hookData: bytes("") }); pools[1] = UniswapV4Executor.UniswapV4Pool({ intermediaryToken: WBTC_ADDR, fee: uint24(3000), - tickSpacing: int24(60) + tickSpacing: int24(60), + hook: address(0), + hookData: bytes("") }); bytes memory protocolData = UniswapV4Utils.encodeExactInput( @@ -399,8 +402,6 @@ contract TychoRouterForBalancerV3Test is TychoRouterTestSetup { true, RestrictTransferFrom.TransferType.TransferFrom, ALICE, - address(0), - bytes(""), pools ); diff --git a/foundry/test/protocols/UniswapV4Utils.sol b/foundry/test/protocols/UniswapV4Utils.sol index 9051f12..f90b0ce 100644 --- a/foundry/test/protocols/UniswapV4Utils.sol +++ b/foundry/test/protocols/UniswapV4Utils.sol @@ -10,8 +10,6 @@ library UniswapV4Utils { bool zeroForOne, RestrictTransferFrom.TransferType transferType, address receiver, - address hook, - bytes memory hookData, UniswapV4Executor.UniswapV4Pool[] memory pools ) public pure returns (bytes memory) { require(pools.length > 0, "Must have at least one pool"); @@ -19,7 +17,10 @@ library UniswapV4Utils { bytes memory firstPool = abi.encodePacked( pools[0].intermediaryToken, bytes3(pools[0].fee), - pools[0].tickSpacing + pools[0].tickSpacing, + pools[0].hook, + bytes2(uint16(pools[0].hookData.length)), + pools[0].hookData ); bytes[] memory encodedExtraPools = new bytes[](pools.length - 1); @@ -27,7 +28,10 @@ library UniswapV4Utils { encodedExtraPools[i - 1] = abi.encodePacked( pools[i].intermediaryToken, bytes3(pools[i].fee), - pools[i].tickSpacing + pools[i].tickSpacing, + pools[i].hook, + bytes2(uint16(pools[i].hookData.length)), + pools[i].hookData ); } @@ -37,10 +41,8 @@ library UniswapV4Utils { zeroForOne, transferType, receiver, - hook, firstPool, - pleEncode(encodedExtraPools), - hookData + pleEncode(encodedExtraPools) ); } diff --git a/src/encoding/evm/swap_encoder/swap_encoders.rs b/src/encoding/evm/swap_encoder/swap_encoders.rs index 6e768d3..66750fe 100644 --- a/src/encoding/evm/swap_encoder/swap_encoders.rs +++ b/src/encoding/evm/swap_encoder/swap_encoders.rs @@ -189,23 +189,24 @@ impl SwapEncoder for UniswapV4SwapEncoder { Ok(hook) => Address::from_slice(&hook), Err(_) => Address::ZERO, }; - let mut hook_data = AlloyBytes::new(); - if encoding_context.group_token_out == swap.token_out { - // Add hook data if it's only the last swap - hook_data = AlloyBytes::from( - swap.user_data - .clone() - .unwrap_or_default() - .to_vec(), - ); - } + + let hook_data = swap + .user_data + .clone() + .unwrap_or_default() + .to_vec(); + + let hook_data_length = (hook_data.len() as u16).to_be_bytes(); + // Early check if this is not the first swap if encoding_context.group_token_in != swap.token_in { return Ok(( bytes_to_address(&swap.token_out)?, pool_fee_u24, pool_tick_spacing_u24, - hook_data, + hook_address, + hook_data_length, + AlloyBytes::from(hook_data), ) .abi_encode_packed()); } @@ -218,8 +219,15 @@ impl SwapEncoder for UniswapV4SwapEncoder { let zero_to_one = Self::get_zero_to_one(token_in_address, token_out_address); - let pool_params = - (token_out_address, pool_fee_u24, pool_tick_spacing_u24).abi_encode_packed(); + let pool_params = ( + token_out_address, + pool_fee_u24, + pool_tick_spacing_u24, + hook_address, + hook_data_length, + AlloyBytes::from(hook_data), + ) + .abi_encode_packed(); let args = ( group_token_in_address, @@ -227,9 +235,7 @@ impl SwapEncoder for UniswapV4SwapEncoder { zero_to_one, (encoding_context.transfer_type as u8).to_be_bytes(), bytes_to_address(&encoding_context.receiver)?, - hook_address, pool_params, - hook_data, ); Ok(args.abi_encode_packed()) @@ -1249,15 +1255,17 @@ mod tests { "01", // receiver "cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", - // hook address (not set, so zero) - "0000000000000000000000000000000000000000", // pool params: // - intermediary token "dac17f958d2ee523a2206206994597c13d831ec7", // - fee "000064", // - tick spacing - "000001" + "000001", + // hook address (not set, so zero) + "0000000000000000000000000000000000000000", + // hook data length (0) + "0000" )) ); write_calldata_to_file("test_encode_uniswap_v4_simple_swap", hex_swap.as_str()); @@ -1315,7 +1323,11 @@ mod tests { // - fee (3 bytes) "000bb8", // - tick spacing (3 bytes) - "00003c" + "00003c", + // hook address (not set, so zero) + "0000000000000000000000000000000000000000", + // hook data length (0) + "0000" )) ); } @@ -1414,8 +1426,6 @@ mod tests { "01", // receiver "cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", - // hook address (not set, so zero) - "0000000000000000000000000000000000000000", // pool params: // - intermediary token USDT "dac17f958d2ee523a2206206994597c13d831ec7", @@ -1423,15 +1433,23 @@ mod tests { "000064", // - tick spacing "000001", + // hook address (not set, so zero) + "0000000000000000000000000000000000000000", + // hook data length (0) + "0000", // Second swap // ple encoding - "001a", + "0030", // - intermediary token WBTC "2260fac5e5542a773aa44fbcfedf7c193bc2c599", // - fee "000bb8", // - tick spacing - "00003c" + "00003c", + // hook address (not set, so zero) + "0000000000000000000000000000000000000000", + // hook data length (0) + "0000" )) ); write_calldata_to_file("test_encode_uniswap_v4_sequential_swap", combined_hex.as_str()); diff --git a/src/encoding/evm/tycho_encoders.rs b/src/encoding/evm/tycho_encoders.rs index 3e88a36..f8ba760 100644 --- a/src/encoding/evm/tycho_encoders.rs +++ b/src/encoding/evm/tycho_encoders.rs @@ -1247,22 +1247,28 @@ mod tests { "01", // receiver "cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", - // hook address (not set, so zero) - "0000000000000000000000000000000000000000", // first pool intermediary token (ETH) "0000000000000000000000000000000000000000", // fee "000bb8", // tick spacing "00003c", + // hook address (not set, so zero) + "0000000000000000000000000000000000000000", + // hook data length (0) + "0000", // ple encoding - "001a", + "0030", // second pool intermediary token (PEPE) "6982508145454ce325ddbe47a25d4ec3d2311933", // fee "0061a8", // tick spacing - "0001f4" + "0001f4", + // hook address (not set, so zero) + "0000000000000000000000000000000000000000", + // hook data length (0) + "0000", )) ); } diff --git a/tests/protocol_integration_tests.rs b/tests/protocol_integration_tests.rs index 83cf430..c0896ec 100644 --- a/tests/protocol_integration_tests.rs +++ b/tests/protocol_integration_tests.rs @@ -357,7 +357,7 @@ fn test_single_encoding_strategy_usv4_grouped_swap() { let expected_swaps = String::from(concat!( // length of ple encoded swaps without padding - "000000000000000000000000000000000000000000000000000000000000009c", + "00000000000000000000000000000000000000000000000000000000000000b4", // Swap data header "f62849f9a0b5bf2913b396098f7c7019b51a820a", // executor address // Protocol data @@ -366,18 +366,21 @@ fn test_single_encoding_strategy_usv4_grouped_swap() { "00", // zero2one "00", // transfer type TransferFrom "cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver - "0000000000000000000000000000000000000000", // hook address // First pool params "0000000000000000000000000000000000000000", // intermediary token (ETH) "000bb8", // fee "00003c", // tick spacing + "0000000000000000000000000000000000000000", // hook address + "0000", // hook data length // ple encoding - "001a", + "0030", // Second pool params "6982508145454ce325ddbe47a25d4ec3d2311933", // intermediary token (PEPE) "0061a8", // fee "0001f4", // tick spacing - "00000000" // padding + "0000000000000000000000000000000000000000", // hook address + "0000", // hook data length + "000000000000000000000000" // padding )); let hex_calldata = encode(&calldata); From b83f7c41f6eef289d2aa7a3e953124d184bdd785 Mon Sep 17 00:00:00 2001 From: Diana Carvalho Date: Thu, 9 Oct 2025 11:34:26 +0200 Subject: [PATCH 3/3] fix: Support Euler in swapExactInput Do the token transfers before calling swap on the pool manager Took 13 minutes Took 10 seconds --- foundry/src/executors/UniswapV4Executor.sol | 22 +----- foundry/test/protocols/UniswapV4.t.sol | 77 +++++++++++++++++++++ 2 files changed, 78 insertions(+), 21 deletions(-) diff --git a/foundry/src/executors/UniswapV4Executor.sol b/foundry/src/executors/UniswapV4Executor.sol index ce17196..c05d2f8 100644 --- a/foundry/src/executors/UniswapV4Executor.sol +++ b/foundry/src/executors/UniswapV4Executor.sol @@ -332,6 +332,7 @@ contract UniswapV4Executor is uint128 amountOut = 0; Currency swapCurrencyIn = currencyIn; uint256 swapAmountIn = amountIn; + _settle(currencyIn, amountIn, transferType); unchecked { uint256 pathLength = path.length; PathKey calldata pathKey; @@ -353,12 +354,6 @@ contract UniswapV4Executor is } } - uint256 amount = _getFullDebt(currencyIn); - if (amount > amountIn) { - revert UniswapV4Executor__V4TooMuchRequested(amountIn, amount); - } - _settle(currencyIn, amount, transferType); - _take( swapCurrencyIn, // at the end of the loop this is actually currency out receiver, @@ -409,21 +404,6 @@ contract UniswapV4Executor is amount = uint256(_amount); } - /// @notice Obtain the full amount owed by this contract (negative delta) - /// @param currency Currency to get the delta for - /// @return amount The amount owed by this contract as a uint256 - function _getFullDebt(Currency currency) - internal - view - returns (uint256 amount) - { - int256 _amount = poolManager.currencyDelta(address(this), currency); - // If the amount is positive, it should be taken not settled. - if (_amount > 0) revert UniswapV4Executor__DeltaNotNegative(currency); - // Casting is safe due to limits on the total supply of a pool - amount = uint256(-_amount); - } - /** * @notice Pays and settles a currency to the pool manager. * @dev The implementing contract must ensure that the `payer` is a secure address. diff --git a/foundry/test/protocols/UniswapV4.t.sol b/foundry/test/protocols/UniswapV4.t.sol index 2cd63a7..f0b7a4a 100644 --- a/foundry/test/protocols/UniswapV4.t.sol +++ b/foundry/test/protocols/UniswapV4.t.sol @@ -282,6 +282,7 @@ contract UniswapV4ExecutorTestForEuler is Constants, TestUtils { UniswapV4ExecutorExposed uniswapV4Exposed; IERC20 USDT = IERC20(USDT_ADDR); IERC20 RLUSD = IERC20(RLUSD_ADDR); + IERC20 WBTC = IERC20(WBTC_ADDR); function setUp() public { uint256 forkBlock = 23535338; @@ -322,6 +323,82 @@ contract UniswapV4ExecutorTestForEuler is Constants, TestUtils { ); assertTrue(USDT.balanceOf(ALICE) == amountOut); } + + function testMultipleSwapEulerLowBalance() public { + // RLUSD -(euler)-> USDT -> WBTC + uint256 amountIn = 134187695711754971245517404; + deal(RLUSD_ADDR, address(uniswapV4Exposed), amountIn); + address eulerProxy = 0xe1Ce9AF672f8854845E5474400B6ddC7AE458a10; + uint256 rlusdEulerBalanceBefore = RLUSD.balanceOf(eulerProxy); + + UniswapV4Executor.UniswapV4Pool[] memory pools = + new UniswapV4Executor.UniswapV4Pool[](2); + pools[0] = UniswapV4Executor.UniswapV4Pool({ + intermediaryToken: USDT_ADDR, + fee: uint24(50), + tickSpacing: int24(1), + hook: address(0xF87ACF8428F2f9403AAA0256A7272d6549ECa8A8), + hookData: bytes("") + }); + pools[1] = UniswapV4Executor.UniswapV4Pool({ + intermediaryToken: WBTC_ADDR, + fee: uint24(3000), + tickSpacing: int24(60), + hook: address(0), + hookData: bytes("") + }); + + bytes memory data = UniswapV4Utils.encodeExactInput( + RLUSD_ADDR, + WBTC_ADDR, + true, + RestrictTransferFrom.TransferType.Transfer, + ALICE, + pools + ); + + uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); + assertEq( + RLUSD.balanceOf(eulerProxy), rlusdEulerBalanceBefore + amountIn + ); + assertTrue(WBTC.balanceOf(ALICE) == amountOut); + } + + function testMultipleSwapLastSwapEuler() public { + // USDC -> RLUSD -(euler)- > USDT + // Sanity check to see if a grouped swap with Euler in the last hop works + uint256 amountIn = 134187695711754971245517404; + deal(USDC_ADDR, address(uniswapV4Exposed), amountIn); + + UniswapV4Executor.UniswapV4Pool[] memory pools = + new UniswapV4Executor.UniswapV4Pool[](2); + pools[0] = UniswapV4Executor.UniswapV4Pool({ + intermediaryToken: RLUSD_ADDR, + fee: uint24(500), + tickSpacing: int24(10), + hook: address(0), + hookData: bytes("") + }); + pools[1] = UniswapV4Executor.UniswapV4Pool({ + intermediaryToken: USDT_ADDR, + fee: uint24(50), + tickSpacing: int24(1), + hook: address(0xF87ACF8428F2f9403AAA0256A7272d6549ECa8A8), + hookData: bytes("") + }); + + bytes memory data = UniswapV4Utils.encodeExactInput( + USDC_ADDR, + USDT_ADDR, + false, + RestrictTransferFrom.TransferType.Transfer, + ALICE, + pools + ); + + uint256 amountOut = uniswapV4Exposed.swap(amountIn, data); + assertTrue(USDT.balanceOf(ALICE) == amountOut); + } } contract TychoRouterForBalancerV3Test is TychoRouterTestSetup {