From 5d33a8ebcad5801ae44ce9208fa3727e715ee242 Mon Sep 17 00:00:00 2001 From: pedrobergamini <41773103+pedrobergamini@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:34:05 -0300 Subject: [PATCH] test: refactor Bebop tests for simplified order types --- .../test/TychoRouterProtocolIntegration.t.sol | 55 +- foundry/test/TychoRouterSequentialSwap.t.sol | 12 +- foundry/test/assets/calldata.txt | 40 +- foundry/test/executors/BebopExecutor.t.sol | 1127 +++++++---------- 4 files changed, 515 insertions(+), 719 deletions(-) diff --git a/foundry/test/TychoRouterProtocolIntegration.t.sol b/foundry/test/TychoRouterProtocolIntegration.t.sol index 79d5b50..e6aa17e 100644 --- a/foundry/test/TychoRouterProtocolIntegration.t.sol +++ b/foundry/test/TychoRouterProtocolIntegration.t.sol @@ -295,8 +295,18 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup { } function testSingleBebopIntegration() public { - deal(USDC_ADDR, ALICE, 1000 * 10 ** 6); - uint256 expAmountOut = 400000000000000000; // 0.4 WETH + // The calldata swaps 200 USDC for ONDO + // The receiver in the order is 0xc5564C13A157E6240659fb81882A28091add8670 + address orderReceiver = 0xc5564C13A157E6240659fb81882A28091add8670; + deal(USDC_ADDR, ALICE, 200 * 10 ** 6); // 200 USDC + uint256 expAmountOut = 237212396774431060000; // Expected ONDO amount from calldata + + // Fund the maker with ONDO and approve settlement + deal( + ONDO_ADDR, 0xCe79b081c0c924cb67848723ed3057234d10FC6b, expAmountOut + ); + vm.prank(0xCe79b081c0c924cb67848723ed3057234d10FC6b); + IERC20(ONDO_ADDR).approve(BEBOP_SETTLEMENT, expAmountOut); vm.startPrank(ALICE); IERC20(USDC_ADDR).approve(tychoRouterAddr, type(uint256).max); @@ -304,7 +314,8 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup { loadCallDataFromFile("test_single_encoding_strategy_bebop"); (bool success,) = tychoRouterAddr.call(callData); - uint256 finalBalance = IERC20(WETH_ADDR).balanceOf(ALICE); + // Check the receiver's balance (not ALICE, since the order specifies a different receiver) + uint256 finalBalance = IERC20(ONDO_ADDR).balanceOf(orderReceiver); assertTrue(success, "Call Failed"); assertGe(finalBalance, expAmountOut); assertEq(IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), 0); @@ -312,35 +323,25 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup { vm.stopPrank(); } - function testBebopMultiIntegration() public { - // Setup: Alice has WETH, wants USDC and WBTC - deal(WETH_ADDR, ALICE, 1e18); // 1 WETH - uint256 expUSDCOut = 3000e6; // 3000 USDC - uint256 expWBTCOut = 0.1e8; // 0.1 WBTC - - vm.startPrank(ALICE); - IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); - - bytes memory callData = - loadCallDataFromFile("test_single_encoding_strategy_bebop_multi"); - (bool success,) = tychoRouterAddr.call(callData); - - uint256 finalUSDCBalance = IERC20(USDC_ADDR).balanceOf(ALICE); - uint256 finalWBTCBalance = IERC20(WBTC_ADDR).balanceOf(ALICE); - - assertTrue(success, "Call Failed"); - assertGe(finalUSDCBalance, expUSDCOut); - assertGe(finalWBTCBalance, expWBTCOut); - assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0); - - vm.stopPrank(); - } - function testBebopAggregateIntegration() public { // Setup: Alice has USDC, wants WETH (through multiple makers) deal(USDC_ADDR, ALICE, 1000 * 10 ** 6); uint256 expAmountOut = 400000000000000000; // 0.4 WETH + // Fund the two makers from the calldata with WETH + address maker1 = 0x1111111111111111111111111111111111111111; + address maker2 = 0x2222222222222222222222222222222222222222; + + // Maker 1 provides 0.24 WETH, Maker 2 provides 0.16 WETH + deal(WETH_ADDR, maker1, 240000000000000000); + deal(WETH_ADDR, maker2, 160000000000000000); + + // Makers approve settlement contract + vm.prank(maker1); + IERC20(WETH_ADDR).approve(BEBOP_SETTLEMENT, type(uint256).max); + vm.prank(maker2); + IERC20(WETH_ADDR).approve(BEBOP_SETTLEMENT, type(uint256).max); + vm.startPrank(ALICE); IERC20(USDC_ADDR).approve(tychoRouterAddr, type(uint256).max); diff --git a/foundry/test/TychoRouterSequentialSwap.t.sol b/foundry/test/TychoRouterSequentialSwap.t.sol index 0ab7ca3..f3e5bc0 100644 --- a/foundry/test/TychoRouterSequentialSwap.t.sol +++ b/foundry/test/TychoRouterSequentialSwap.t.sol @@ -502,9 +502,19 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup { deal(WETH_ADDR, ALICE, 1 ether); uint256 balanceBefore = IERC20(DAI_ADDR).balanceOf(ALICE); + // Set up the Bebop maker with the address from our updated rust test + address bebopMaker = address(0x1234567890123456789012345678901234567890); + uint256 expectedDaiAmount = 2021750881000000000000; // ~2021.75 DAI + + // Fund the maker with DAI and approve settlement contract + deal(DAI_ADDR, bebopMaker, expectedDaiAmount); + vm.prank(bebopMaker); + IERC20(DAI_ADDR).approve(BEBOP_SETTLEMENT, expectedDaiAmount); + // Approve router vm.startPrank(ALICE); IERC20(WETH_ADDR).approve(tychoRouterAddr, type(uint256).max); + bytes memory callData = loadCallDataFromFile("test_uniswap_v3_bebop"); (bool success,) = tychoRouterAddr.call(callData); @@ -514,7 +524,7 @@ contract TychoRouterSequentialSwapTest is TychoRouterTestSetup { assertTrue(success, "Call Failed"); // Expecting ~2021.75 DAI from 1 WETH through USDC - assertEq(balanceAfter - balanceBefore, 2021750881000000000000); + assertEq(balanceAfter - balanceBefore, expectedDaiAmount); assertEq(IERC20(WETH_ADDR).balanceOf(tychoRouterAddr), 0); } } diff --git a/foundry/test/assets/calldata.txt b/foundry/test/assets/calldata.txt index 84b4fc8..2e84b99 100644 --- a/foundry/test/assets/calldata.txt +++ b/foundry/test/assets/calldata.txt @@ -1,5 +1,4 @@ test_encode_balancer_v3:7bc3485026ac48b6cf9baf0a377477fff5703af8c71ea051a5f82c67adcf634c36ffe6334793d24c85b2b559bc2d21104c4defdd6efca8a20343361d011d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e -test_ekubo_encode_swap_multi:01ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032 test_encode_maverick_v2:40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c671d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e01 test_encode_uniswap_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb111d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0001 test_encode_uniswap_v4_sequential_swap:4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c5990101cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c @@ -8,33 +7,32 @@ test_single_encoding_strategy_balancer_v3:5c4b639c000000000000000000000000000000 test_single_encoding_strategy_ekubo:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000071a0cb889707d426a7a386870a03bc70d1b069759802cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000000000000000000000000000000000 test_single_encoding_strategy_maverick:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000051a4ad4f68d0b91cfd19687c881e50f3a00242828c40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c67cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_single_encoding_strategy_curve_st_eth:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f670220100010002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000 -test_single_encoding_strategy_bebop:5c4b639c000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001ac15cf58144ef33af1e14b5208015d11f9143e27b9a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000016000000000000000000000000000000000000000000000000000000000684533a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bbbbbbb520d69a9775e85b458c58c648259fad5f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000058d15e176280000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000004aabbccdd010000000000000000000000000000000000000000 -test_encode_bebop_aggregate:6b175474e89094c44da98b954eedeac495271d0f2260fac5e5542a773aa44fbcfedf7c193bc2c599000200000004deadbeef01000000820000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110101 +test_single_encoding_strategy_bebop:5c4b639c000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be300000000000000000000000000000000000000000000000cdbfbba0faafaf02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5564c13a157e6240659fb81882a28091add86700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000002e7d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab82f62fe7c39859fa577269be300000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000068470140000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b000000000000000000000000000000000000000000000000000637256e698be1000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000cdbfbba0faafaf020000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000000000000000000000000000000000000000000072c75365fbad713c3dbdcac257c435540000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000 +test_encode_bebop_aggregate:6b175474e89094c44da98b954eedeac495271d0f2260fac5e5542a773aa44fbcfedf7c193bc2c599000100000000000000000000000000000000000000000000000000000000000f424000000420000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000499602d200000000000000000000000011111111111111111111111111111111111111110000000000000000000000000000000000000000000000000000000000003039000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000032000000000000000000000000044444444444444444444444444444444444444440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000002222222222222222222222222222222222222222000000000000000000000000333333333333333333333333333333333333333300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000000000000000000000000000000000000000000010000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000001312d0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000001312d000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111010000000000000000000000000000000000000000000000000000000000000001 test_single_encoding_strategy_curve:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000 test_encode_balancer_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0102 test_uniswap_v3_balancer_v3:e21dd0d3000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000004a220e6096b25eadb88358cb44068a324825467500000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d200692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed0000006503a6a84cd762d9707a21605b548aaab891562aab2260fac5e5542a773aa44fbcfedf7c193bc2c5994a220e6096b25eadb88358cb44068a3248254675571bea0e99e139cd0b6b7d9352ca872dfe0d72dd01cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000 -test_encode_bebop_single:a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20100000000081234567890abcdef0100000004aabbccdd01 +test_encode_bebop_single:a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab82f62fe7c39859fa577269be301000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000068470140000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b000000000000000000000000000000000000000000000000000637256e698be1000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000cdbfbba0faafaf020000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000000000000000000000000000000000000000000072c75365fbad713c3dbdcac257c435540000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c0000000000000000000000000000000000000000000000000000000000000001 test_uniswap_v3_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000bf00692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb8004375dff511095cc5a197a54140a24efef3a416cbcdf9626bc03e24f779434178a73a0b4bad62ed000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010200 -test_encode_bebop_multi:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48010100000008abcdef123456789001000000041122334401 test_uniswap_v3_uniswap_v3:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010100000000000000000000 test_sequential_swap_strategy_encoder_no_permit2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 -test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000410fbec8a838b0ab0c6991177f140a2991d948b7767a9d22a97244b3d66c34ead61276ab50c058fd3447524570b05e6da03c3d80de587564d1e1285233014711f41c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000 +test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000417826d4ec42b22fbdab7a27bfdb656ac395e4c8a90a529ee86884319b76a1f3c525f92cb81aa9b73cf0e38b5f69474733351e5a078cd0a1e8e5bd419513ca45c81b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000 test_single_swap_strategy_encoder_no_permit2:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_single_swap_strategy_encoder_no_transfer_in:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 -test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca0000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000412f305a90cbb803be11c16e914fe7437d295571d3a0f55934bef53165b1c35dc00d74604d69e6f8879e2ff523695b653cca5c03cd4dfbbea20eb7f4374b6ed0b41b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000000000000000 -test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041f914e61f7e62b74595863e1cf87275c14a4b829c88f1c830c65ec5db96e6bcc628888bf3830aedd3a3607fd3a3604db7bac74e865e488c1b8db8ce478b2954181b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000 +test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041c4dab863da3a72158ccfe93390fdbee4d0fbdc36438ada143e1e95ea5d9d81b14044165723a89831c76cdd680126022e076f59578d976d22691c49e93c101aa61c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000000000000000 +test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004188567e0683f83ad6160498aeee94275427b8f86a04d52197f8a9f54efa1e0ae01b7a2b6fb848bada7240221748f50aa9c7f14bcd87d088db3e0e34b08db6d6f21c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000 test_uniswap_v3_curve:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000 -test_uniswapv3_bebop:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d996e0293020b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000021900692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000001ac15cf58144ef33af1e14b5208015d11f9143e27b9a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486b175474e89094c44da98b954eedeac495271d0f01000000016000000000000000000000000000000000000000000000000000000000684514c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bbbbbbb520d69a9775e85b458c58c648259fad5f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000000007881786100000000000000000000000000000000000000000000006d996e0293020b1000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004aabbccdd0100000000000000 -test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041e2357a59a087b94258281e06120a8257a091ade7da057d0432e9e2ea61f8921c23fba14edcef2b70a7f54ee7673855012c87c5a762b279ba65a6a89b6f68ec3d1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000 +test_uniswapv3_bebop:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d996e0293020b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000021900692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000001acd6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486b175474e89094c44da98b954eedeac495271d0f01000000016000000000000000000000000000000000000000000000000000000000684514c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bbbbbbb520d69a9775e85b458c58c648259fad5f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000000007881786100000000000000000000000000000000000000000000006d996e0293020b1000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004aabbccdd0100000000000000 +test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000419baf5e50cb396a410ce7edce9447866f65f365a00c6995cb9c248437b7dcdc1a204b36b9eb0f701119f46d7cd84bf07248b8ae4cc16c565ea78517845e13f3311c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000 test_balancer_v2_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 -test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041b5a60bac6ae68348169f52e209e33cbf603973ec0e7d3416e46cc740d5f7cdc3541bf87fc9a248661ec152924afd6745d3c10d25d075609996018e35bd183a1f1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 -test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041b5a60bac6ae68348169f52e209e33cbf603973ec0e7d3416e46cc740d5f7cdc3541bf87fc9a248661ec152924afd6745d3c10d25d075609996018e35bd183a1f1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 -test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be0000000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000417c47aa1630bc28112f920d23f9c116de2151bf90c7dbf1fcc37f53f854c1fc3626c1c37d1641652523a0d675889df3ef5fbb0b1179d9b5d669b318cc3694bd0b1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000 -test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c79000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041f914e61f7e62b74595863e1cf87275c14a4b829c88f1c830c65ec5db96e6bcc628888bf3830aedd3a3607fd3a3604db7bac74e865e488c1b8db8ce478b2954181b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000 -test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e10000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c79000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041f914e61f7e62b74595863e1cf87275c14a4b829c88f1c830c65ec5db96e6bcc628888bf3830aedd3a3607fd3a3604db7bac74e865e488c1b8db8ce478b2954181b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000 -test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000410fbec8a838b0ab0c6991177f140a2991d948b7767a9d22a97244b3d66c34ead61276ab50c058fd3447524570b05e6da03c3d80de587564d1e1285233014711f41c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 -test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c79000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041b5a60bac6ae68348169f52e209e33cbf603973ec0e7d3416e46cc740d5f7cdc3541bf87fc9a248661ec152924afd6745d3c10d25d075609996018e35bd183a1f1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000 -test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf0000000000000000000000000000000000000000000000000000000000000686cb27100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068452c7900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000418f4c66f828c985b1181fba44e00b0741a785f10c115d5d94bed32cb0288b102f45b1134882ebb7258ee2977fc722c5f836200b9ef1d693cc11394200f9d11cfa1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000 -test_uniswap_v3_bebop:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d996e0293020b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000021900692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000001ac15cf58144ef33af1e14b5208015d11f9143e27b9a0b86991c6218b36c1d19d4a2e9eb0ce3606eb486b175474e89094c44da98b954eedeac495271d0f01000000016000000000000000000000000000000000000000000000000000000000684533a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bbbbbbb520d69a9775e85b458c58c648259fad5f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000000007881786100000000000000000000000000000000000000000000006d996e0293020b1000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000004aabbccdd0100000000000000 -test_single_encoding_strategy_bebop_aggregate:5c4b639c000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000004ea15cf58144ef33af1e14b5208015d11f9143e27b9a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000200000420000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000684533a700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000320000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000111111111111111111111111111111111111111100000000000000000000000022222222222222222222222222222222222222220000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000354a6ba7a180000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002386f26fc10000001000000821b47a665f9a5e14b5208015d11f9143e27b93dc5a0d8c892ec5326eda1e5df3c42a987d0b2ea5b8be8f0e5c326bd4ec0321b10c6e9b4e5f8a0b8d5e6f7c8a9b01b2c58b665f9a5e14b5208015d11f9143e27b93dc5a0d8c892ec5326eda1e5df3c53b987d0b2ea5b8be8f0e5c326bd4ec0321b10c6e9b4e5f8a0b8d5e6f7c8a9b01c0100000000000000000000000000000000000000000000 -test_single_encoding_strategy_bebop_multi:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000030c15cf58144ef33af1e14b5208015d11f9143e27b9c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001000002c0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000684533a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bbbbbbb520d69a9775e85b458c58c648259fad5f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000b2d05e000000000000000000000000000000000000000000000000000000000000989680010000000411223344010000000000000000000000000000000000000000 +test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041eb0bd61a366bdfff63e6bdd87c2f3f8b8d563571bd1b22cce08e9169c7b69cb73dd90979971cb07f127c306927058800c7dca4c2514981983521a98112cc508e1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 +test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041eb0bd61a366bdfff63e6bdd87c2f3f8b8d563571bd1b22cce08e9169c7b69cb73dd90979971cb07f127c306927058800c7dca4c2514981983521a98112cc508e1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 +test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be00000000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041349e34819c860de0bbb3dcbac7ae5d75ac69a0236d804b75a1912d34369018ca2f80c6fc03cf6979d4f3c2c7cf546126ba31659e962323f5fea327c7842298071b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000 +test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004188567e0683f83ad6160498aeee94275427b8f86a04d52197f8a9f54efa1e0ae01b7a2b6fb848bada7240221748f50aa9c7f14bcd87d088db3e0e34b08db6d6f21c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000 +test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004188567e0683f83ad6160498aeee94275427b8f86a04d52197f8a9f54efa1e0ae01b7a2b6fb848bada7240221748f50aa9c7f14bcd87d088db3e0e34b08db6d6f21c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000 +test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000417826d4ec42b22fbdab7a27bfdb656ac395e4c8a90a529ee86884319b76a1f3c525f92cb81aa9b73cf0e38b5f69474733351e5a078cd0a1e8e5bd419513ca45c81b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 +test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a9000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041eb0bd61a366bdfff63e6bdd87c2f3f8b8d563571bd1b22cce08e9169c7b69cb73dd90979971cb07f127c306927058800c7dca4c2514981983521a98112cc508e1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000 +test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf00000000000000000000000000000000000000000000000000000000000006877c8a100000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d0139500000000000000000000000000000000000000000000000000000000685042a900000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000416e6f00bad5e0d337f2b56b37a7e86c3683f8d3770f4dfe2a327136913a8ccb5961b88ca4b79782954c499c2692963a2235ee7d606f6d3d7a4a439709928ac10a1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000 +test_uniswap_v3_bebop:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d996e0293020b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000031400692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000002a7d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486b175474e89094c44da98b954eedeac495271d0f01000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000068506fc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012345678901234567890123456789012345678900000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000000007881786100000000000000000000000000000000000000000000006d996e0293020b1000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004aabbccdd0000000000000000000000000000000000000000000000000000000001000000000000000000000000 +test_single_encoding_strategy_bebop_aggregate:5c4b639c000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000058d15e17628000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000687d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000100000000000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000068506fc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000320000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000111111111111111111111111111111111111111100000000000000000000000022222222222222222222222222222222222222220000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000354a6ba7a180000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000002386f26fc1000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000411b47a665f9a5e14b5208015d11f9143e27b93dc5a0d8c892ec5326eda1e5df3c42a987d0b2ea5b8be8f0e5c326bd4ec0321b10c6e9b4e5f8a0b8d5e6f7c8a9b01b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000412c58b665f9a5e14b5208015d11f9143e27b93dc5a0d8c892ec5326eda1e5df3c53b987d0b2ea5b8be8f0e5c326bd4ec0321b10c6e9b4e5f8a0b8d5e6f7c8a9b01c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000 +test_ekubo_encode_swap_multi:01ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032 diff --git a/foundry/test/executors/BebopExecutor.t.sol b/foundry/test/executors/BebopExecutor.t.sol index e87a4ae..c11d797 100644 --- a/foundry/test/executors/BebopExecutor.t.sol +++ b/foundry/test/executors/BebopExecutor.t.sol @@ -10,6 +10,7 @@ import {StdCheats} from "forge-std/StdCheats.sol"; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; +import {BebopSettlementMock} from "../mock/BebopSettlementMock.sol"; contract MockToken is ERC20 { uint8 private _decimals; @@ -42,9 +43,9 @@ contract BebopExecutorExposed is BebopExecutor { address tokenOut, RestrictTransferFrom.TransferType transferType, BebopExecutor.OrderType orderType, + uint256 filledTakerAmount, bytes memory quoteData, - uint8 signatureType, - bytes memory signature, + bytes memory makerSignaturesData, bool approvalNeeded ) { @@ -52,309 +53,79 @@ contract BebopExecutorExposed is BebopExecutor { } } -/// @notice Mock Bebop settlement contract for testing -contract MockBebopSettlement is Test, Constants { - function swapSingle( - IBebopSettlement.Single calldata order, - IBebopSettlement.MakerSignature calldata, /* makerSignature */ - uint256 filledTakerAmount - ) external payable returns (uint256 filledMakerAmount) { - // Basic validation - require(order.expiry >= block.timestamp, "Order expired"); - require(filledTakerAmount <= order.taker_amount, "Exceeds order amount"); - - // Mock implementation handles input tokens - if (order.taker_token == address(0)) { - // For ETH input, validate msg.value - require(msg.value >= filledTakerAmount, "Insufficient ETH sent"); - } else { - // For ERC20 input, transfer from sender - IERC20(order.taker_token).transferFrom( - msg.sender, address(this), filledTakerAmount - ); - } - - // Calculate proportional maker amount - filledMakerAmount = - (filledTakerAmount * order.maker_amount) / order.taker_amount; - - address recipient = order.receiver; - - if (order.maker_token == address(0)) { - // For ETH output, send ETH directly - vm.deal(recipient, recipient.balance + filledMakerAmount); - } else { - // For ERC20 output, mint tokens to recipient - uint256 recipientBalanceBefore = - IERC20(order.maker_token).balanceOf(recipient); - - deal( - order.maker_token, - recipient, - recipientBalanceBefore + filledMakerAmount - ); - } - - return filledMakerAmount; - } - - function swapSingleFromContract( - IBebopSettlement.Single calldata order, - IBebopSettlement.MakerSignature calldata, /* makerSignature */ - uint256 filledTakerAmount - ) external payable returns (uint256 filledMakerAmount) { - // Basic validation - require(order.expiry >= block.timestamp, "Order expired"); - require(filledTakerAmount <= order.taker_amount, "Exceeds order amount"); - - // For swapSingleFromContract, tokens should already be in this contract - if (order.taker_token == address(0)) { - // For ETH input, validate contract balance - require( - address(this).balance >= filledTakerAmount, - "Insufficient ETH in contract" - ); - } else { - // For ERC20 input, validate contract balance - require( - IERC20(order.taker_token).balanceOf(address(this)) - >= filledTakerAmount, - "Insufficient tokens in contract" - ); - } - - // Calculate proportional maker amount - filledMakerAmount = - (filledTakerAmount * order.maker_amount) / order.taker_amount; - - address recipient = order.receiver; - - if (order.maker_token == address(0)) { - // For ETH output, send ETH directly - vm.deal(recipient, recipient.balance + filledMakerAmount); - } else { - // For ERC20 output, mint tokens to recipient - uint256 recipientBalanceBefore = - IERC20(order.maker_token).balanceOf(recipient); - - deal( - order.maker_token, - recipient, - recipientBalanceBefore + filledMakerAmount - ); - } - - return filledMakerAmount; - } - - function swapMulti( - IBebopSettlement.Multi calldata order, - IBebopSettlement.MakerSignature calldata, /* makerSignature */ - uint256[] calldata filledTakerAmounts - ) external payable returns (uint256[] memory filledMakerAmounts) { - // Basic validation - require(order.expiry >= block.timestamp, "Order expired"); - require( - order.taker_tokens.length == filledTakerAmounts.length, - "Array length mismatch" - ); - - filledMakerAmounts = new uint256[](order.maker_tokens.length); - - // Handle each token input - uint256 totalEthRequired = 0; - for (uint256 i = 0; i < order.taker_tokens.length; i++) { - if (filledTakerAmounts[i] == 0) continue; - - require( - filledTakerAmounts[i] <= order.taker_amounts[i], - "Exceeds order amount" - ); - - if (order.taker_tokens[i] == address(0)) { - // For ETH input, accumulate required ETH - totalEthRequired += filledTakerAmounts[i]; - } else { - // For ERC20 input, transfer from sender - IERC20(order.taker_tokens[i]).transferFrom( - msg.sender, address(this), filledTakerAmounts[i] - ); - } - } - - // Validate ETH sent - require(msg.value >= totalEthRequired, "Insufficient ETH sent"); - - // Calculate and distribute maker amounts - for (uint256 i = 0; i < order.maker_tokens.length; i++) { - // For single-input, multi-output orders, use the first taker amount - uint256 takerIndex = i < order.taker_tokens.length ? i : 0; - if ( - takerIndex < filledTakerAmounts.length - && filledTakerAmounts[takerIndex] > 0 - ) { - // Calculate proportional maker amount based on the filled ratio - filledMakerAmounts[i] = ( - filledTakerAmounts[takerIndex] * order.maker_amounts[i] - ) / order.taker_amounts[takerIndex]; - - if (order.maker_tokens[i] == address(0)) { - // For ETH output - vm.deal( - order.receiver, - order.receiver.balance + filledMakerAmounts[i] - ); - } else { - // For ERC20 output - deal( - order.maker_tokens[i], - order.receiver, - IERC20(order.maker_tokens[i]).balanceOf(order.receiver) - + filledMakerAmounts[i] - ); - } - } - } - - return filledMakerAmounts; - } - - function swapAggregate( - IBebopSettlement.Aggregate calldata order, - IBebopSettlement.MakerSignature[] calldata, /* makerSignatures */ - uint256[] calldata filledTakerAmounts - ) external payable returns (uint256[][] memory filledMakerAmounts) { - // Basic validation - require(order.expiry >= block.timestamp, "Order expired"); - require( - order.taker_tokens.length == filledTakerAmounts.length, - "Array length mismatch" - ); - require( - order.maker_addresses.length == order.maker_tokens.length, - "Maker array mismatch" - ); - - filledMakerAmounts = new uint256[][](order.maker_addresses.length); - - // Handle taker tokens - uint256 totalEthRequired = 0; - for (uint256 i = 0; i < order.taker_tokens.length; i++) { - if (filledTakerAmounts[i] == 0) continue; - - require( - filledTakerAmounts[i] <= order.taker_amounts[i], - "Exceeds order amount" - ); - - if (order.taker_tokens[i] == address(0)) { - totalEthRequired += filledTakerAmounts[i]; - } else { - IERC20(order.taker_tokens[i]).transferFrom( - msg.sender, address(this), filledTakerAmounts[i] - ); - } - } - - require(msg.value >= totalEthRequired, "Insufficient ETH sent"); - - // Find the first filled taker amount - uint256 filledTakerIndex = 0; - uint256 filledAmount = 0; - for (uint256 i = 0; i < filledTakerAmounts.length; i++) { - if (filledTakerAmounts[i] > 0) { - filledTakerIndex = i; - filledAmount = filledTakerAmounts[i]; - break; - } - } - - require(filledAmount > 0, "No taker amount filled"); - - // Distribute to makers proportionally - for (uint256 i = 0; i < order.maker_addresses.length; i++) { - filledMakerAmounts[i] = new uint256[](order.maker_tokens[i].length); - - for (uint256 j = 0; j < order.maker_tokens[i].length; j++) { - // Calculate proportional maker amount - filledMakerAmounts[i][j] = ( - filledAmount * order.maker_amounts[i][j] - ) / order.taker_amounts[filledTakerIndex]; - - if (order.maker_tokens[i][j] == address(0)) { - vm.deal( - order.receiver, - order.receiver.balance + filledMakerAmounts[i][j] - ); - } else { - deal( - order.maker_tokens[i][j], - order.receiver, - IERC20(order.maker_tokens[i][j]).balanceOf( - order.receiver - ) + filledMakerAmounts[i][j] - ); - } - } - } - - return filledMakerAmounts; - } -} - contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils { using SafeERC20 for IERC20; BebopExecutorExposed bebopExecutor; - MockBebopSettlement mockBebopSettlement; - MockToken WETH; - MockToken USDC; + IERC20 WETH = IERC20(WETH_ADDR); + IERC20 USDC = IERC20(USDC_ADDR); + IERC20 DAI = IERC20(DAI_ADDR); + IERC20 WBTC = IERC20(WBTC_ADDR); + IERC20 ONDO = IERC20(ONDO_ADDR); + IERC20 USDT = IERC20(USDT_ADDR); + + // Test data structures for mainnet fork tests + struct SingleOrderTestData { + uint256 forkBlock; + IBebopSettlement.Single order; + bytes signature; + uint256 amountIn; + uint256 filledTakerAmount; // 0 means fill entire order + uint256 expectedAmountOut; + address sender; + address receiver; + } + + struct AggregateOrderTestData { + uint256 forkBlock; + IBebopSettlement.Aggregate order; + bytes[] signatures; // Multiple signatures for multiple makers + uint256[] amountsIn; + uint256[] filledTakerAmounts; // 0 in array means fill entire amount for that token + uint256[] expectedAmountsOut; + address sender; + address receiver; + } function setUp() public { - // Deploy mock tokens - WETH = new MockToken("Wrapped Ether", "WETH", 18); - USDC = new MockToken("USD Coin", "USDC", 6); - - // Deploy at expected addresses - vm.etch(WETH_ADDR, address(WETH).code); - vm.etch(USDC_ADDR, address(USDC).code); - - // Update references - WETH = MockToken(WETH_ADDR); - USDC = MockToken(USDC_ADDR); - - // Deploy mock contracts - mockBebopSettlement = new MockBebopSettlement(); - - // Deploy Bebop executor - bebopExecutor = new BebopExecutorExposed( - address(mockBebopSettlement), PERMIT2_ADDRESS - ); - - // Fund test accounts - WETH.mint(address(this), 100e18); - USDC.mint(address(this), 100_000e6); // Mint USDC to test contract - USDC.mint(address(mockBebopSettlement), 100_000e6); + // Fork will be created in individual tests to allow different fork blocks } // Allow test contract to receive ETH receive() external payable {} - function testDecodeParams() public view { + function testDecodeParams() public { + // Fork to ensure consistent setup + vm.createSelectFork(vm.rpcUrl("mainnet"), 22667985); + + // Deploy Bebop executor with real settlement contract + bebopExecutor = + new BebopExecutorExposed(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); bytes memory quoteData = hex"1234567890abcdef"; bytes memory signature = hex"aabbccdd"; + // Create ABI-encoded MakerSignature array + IBebopSettlement.MakerSignature[] memory signatures = + new IBebopSettlement.MakerSignature[](1); + signatures[0] = IBebopSettlement.MakerSignature({ + signatureBytes: signature, + flags: uint256(1) // EIP712 signature type + }); + bytes memory makerSignaturesData = abi.encode(signatures); + + uint256 filledTakerAmount = 1e18; // 1 WETH + bytes memory params = abi.encodePacked( WETH_ADDR, USDC_ADDR, uint8(RestrictTransferFrom.TransferType.Transfer), uint8(0), // OrderType.Single + filledTakerAmount, uint32(quoteData.length), quoteData, - uint8(1), // signatureType: EIP712 - uint32(signature.length), - signature, + uint32(makerSignaturesData.length), + makerSignaturesData, uint8(1) // approvalNeeded: true ); @@ -363,9 +134,9 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils { address tokenOut, RestrictTransferFrom.TransferType transferType, BebopExecutor.OrderType orderType, + uint256 decodedFilledTakerAmount, bytes memory decodedQuoteData, - uint8 decodedSignatureType, - bytes memory decodedSignature, + bytes memory decodedMakerSignaturesData, bool decodedApprovalNeeded ) = bebopExecutor.decodeParams(params); @@ -376,216 +147,444 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils { uint8(RestrictTransferFrom.TransferType.Transfer) ); assertEq(uint8(orderType), uint8(BebopExecutor.OrderType.Single)); + assertEq(decodedFilledTakerAmount, filledTakerAmount); assertEq(keccak256(decodedQuoteData), keccak256(quoteData)); - assertEq(decodedSignatureType, 1); // EIP712 signature type - assertEq(keccak256(decodedSignature), keccak256(signature)); + assertEq( + keccak256(decodedMakerSignaturesData), + keccak256(makerSignaturesData) + ); assertTrue(decodedApprovalNeeded); // Approval needed should be true + + // Also verify we can decode the signatures back + IBebopSettlement.MakerSignature[] memory decodedSignatures = abi.decode( + decodedMakerSignaturesData, (IBebopSettlement.MakerSignature[]) + ); + assertEq(decodedSignatures.length, 1); + assertEq( + keccak256(decodedSignatures[0].signatureBytes), keccak256(signature) + ); + assertEq(decodedSignatures[0].flags, 1); // EIP712 } - function testRFQSwap() public { - uint256 amountIn = 1e18; // 1 WETH - uint256 expectedAmountOut = 3000e6; // 3000 USDC + // Single Order Tests + function testSingleOrder() public { + // Fork at the right block first + vm.createSelectFork(vm.rpcUrl("mainnet"), 22667985); - // Create a valid Bebop order - IBebopSettlement.Single memory order = IBebopSettlement.Single({ - expiry: block.timestamp + 3600, - taker_address: address(0), // Any taker - maker_address: address(mockBebopSettlement), - maker_nonce: 1, - taker_token: WETH_ADDR, - maker_token: USDC_ADDR, - taker_amount: amountIn, - maker_amount: expectedAmountOut, - receiver: address(bebopExecutor), // Output should go to executor - packed_commands: 0, - flags: 0 + // Deploy our mock Bebop settlement and use vm.etch to replace the real one + BebopSettlementMock mockSettlement = new BebopSettlementMock(); + bytes memory mockCode = address(mockSettlement).code; + vm.etch(BEBOP_SETTLEMENT, mockCode); + + // Deploy Bebop executor with the (now mocked) settlement contract + bebopExecutor = + new BebopExecutorExposed(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); + + // Create test data from real mainnet transaction + // https://etherscan.io/tx/0x6279bc970273b6e526e86d9b69133c2ca1277e697ba25375f5e6fc4df50c0c94 + address originalTakerAddress = + 0xc5564C13A157E6240659fb81882A28091add8670; + + // Now we can use the original order data since our mock skips taker validation + SingleOrderTestData memory testData = SingleOrderTestData({ + forkBlock: 22667985, + order: IBebopSettlement.Single({ + expiry: 1749483840, + taker_address: originalTakerAddress, // Original taker address from the real order + maker_address: 0xCe79b081c0c924cb67848723ed3057234d10FC6b, + maker_nonce: 1749483765992417, + taker_token: USDC_ADDR, + maker_token: ONDO_ADDR, + taker_amount: 200000000, + maker_amount: 237212396774431060000, + receiver: originalTakerAddress, + packed_commands: 0, + flags: 51915842898789398998206002334703507894664330885127600393944965515693155942400 + }), + signature: hex"eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c", + amountIn: 200000000, + filledTakerAmount: 0, + expectedAmountOut: 237212396774431060000, + sender: originalTakerAddress, + receiver: originalTakerAddress }); - // Encode order as quote data - bytes memory quoteData = abi.encode(order); - bytes memory signature = hex"aabbccdd"; // Mock signature + // Setup: fund the original taker and have them approve the test contract (acting as router) + deal(USDC_ADDR, originalTakerAddress, testData.amountIn); + + // Also fund the maker with ONDO tokens and have them approve the settlement + deal( + ONDO_ADDR, testData.order.maker_address, testData.order.maker_amount + ); + vm.prank(testData.order.maker_address); + ONDO.approve(BEBOP_SETTLEMENT, testData.order.maker_amount); + + // Original taker approves the test contract (router) to spend their USDC + vm.prank(originalTakerAddress); + USDC.approve(address(this), testData.amountIn); + + // Test contract (router) pulls tokens from original taker and sends to executor + USDC.transferFrom( + originalTakerAddress, address(bebopExecutor), testData.amountIn + ); + + // Record initial balances + uint256 ondoBefore = ONDO.balanceOf(originalTakerAddress); + + // Execute the swap (executor already has the tokens) + bytes memory quoteData = abi.encode(testData.order); + IBebopSettlement.MakerSignature[] memory signatures = + new IBebopSettlement.MakerSignature[](1); + signatures[0] = IBebopSettlement.MakerSignature({ + signatureBytes: testData.signature, + flags: uint256(0) // ETH_SIGN + }); + bytes memory makerSignaturesData = abi.encode(signatures); bytes memory params = abi.encodePacked( - WETH_ADDR, USDC_ADDR, + ONDO_ADDR, uint8(RestrictTransferFrom.TransferType.Transfer), - uint8(0), // OrderType.Single + uint8(BebopExecutor.OrderType.Single), + testData.filledTakerAmount, uint32(quoteData.length), quoteData, - uint8(1), // signatureType: EIP712 - uint32(signature.length), - signature, + uint32(makerSignaturesData.length), + makerSignaturesData, uint8(1) // approvalNeeded: true ); - // Transfer WETH to executor first - WETH.transfer(address(bebopExecutor), amountIn); + uint256 amountOut = bebopExecutor.swap(testData.amountIn, params); + + // Verify results + assertEq(amountOut, testData.expectedAmountOut, "Incorrect amount out"); + assertEq( + ONDO.balanceOf(originalTakerAddress) - ondoBefore, + testData.expectedAmountOut, + "ONDO balance mismatch" + ); + assertEq( + USDC.balanceOf(address(bebopExecutor)), 0, "USDC left in executor" + ); + assertEq( + ONDO.balanceOf(address(bebopExecutor)), 0, "ONDO left in executor" + ); + } + + function testSingleOrder_PartialFill() public { + // Fork at the right block first + vm.createSelectFork(vm.rpcUrl("mainnet"), 22667985); + + // Deploy our mock Bebop settlement and use vm.etch to replace the real one + BebopSettlementMock mockSettlement = new BebopSettlementMock(); + bytes memory mockCode = address(mockSettlement).code; + vm.etch(BEBOP_SETTLEMENT, mockCode); + + // Deploy Bebop executor with the (now mocked) settlement contract + bebopExecutor = + new BebopExecutorExposed(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); + + // Test partial fill - only fill half of the order + address originalTakerAddress = + 0xc5564C13A157E6240659fb81882A28091add8670; + + // Using the same order but only filling half + SingleOrderTestData memory testData = SingleOrderTestData({ + forkBlock: 22667985, + order: IBebopSettlement.Single({ + expiry: 1749483840, + taker_address: originalTakerAddress, + maker_address: 0xCe79b081c0c924cb67848723ed3057234d10FC6b, + maker_nonce: 1749483765992417, + taker_token: USDC_ADDR, + maker_token: ONDO_ADDR, + taker_amount: 200000000, // 200 USDC total order + maker_amount: 237212396774431060000, // Total ONDO for full order + receiver: originalTakerAddress, + packed_commands: 0, + flags: 51915842898789398998206002334703507894664330885127600393944965515693155942400 + }), + signature: hex"eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c", + amountIn: 100000000, // Only provide 100 USDC (half) + filledTakerAmount: 100000000, // Explicitly fill only 100 USDC + expectedAmountOut: 118606198387215530000, // Expected proportional ONDO output (half of 237.21) + sender: originalTakerAddress, + receiver: originalTakerAddress + }); + + // Setup: fund the original taker with partial amount + deal(USDC_ADDR, originalTakerAddress, testData.amountIn); + + // Fund the maker with FULL amount (they need enough for any partial fill) + deal( + ONDO_ADDR, testData.order.maker_address, testData.order.maker_amount + ); + vm.prank(testData.order.maker_address); + ONDO.approve(BEBOP_SETTLEMENT, testData.order.maker_amount); + + // Original taker approves the test contract (router) to spend their USDC + vm.prank(originalTakerAddress); + USDC.approve(address(this), testData.amountIn); + + // Test contract (router) pulls tokens from original taker and sends to executor + USDC.transferFrom( + originalTakerAddress, address(bebopExecutor), testData.amountIn + ); + + // Record initial balances + uint256 ondoBefore = ONDO.balanceOf(originalTakerAddress); + + // Execute the partial swap (executor already has the tokens) + bytes memory quoteData = abi.encode(testData.order); + IBebopSettlement.MakerSignature[] memory signatures = + new IBebopSettlement.MakerSignature[](1); + signatures[0] = IBebopSettlement.MakerSignature({ + signatureBytes: testData.signature, + flags: uint256(0) // ETH_SIGN + }); + bytes memory makerSignaturesData = abi.encode(signatures); + + bytes memory params = abi.encodePacked( + USDC_ADDR, + ONDO_ADDR, + uint8(RestrictTransferFrom.TransferType.Transfer), + uint8(BebopExecutor.OrderType.Single), + testData.filledTakerAmount, // Partial fill amount + uint32(quoteData.length), + quoteData, + uint32(makerSignaturesData.length), + makerSignaturesData, + uint8(1) // approvalNeeded: true + ); + + uint256 amountOut = bebopExecutor.swap(testData.amountIn, params); + + // Verify partial fill results + assertEq( + amountOut, + testData.expectedAmountOut, + "Incorrect partial amount out" + ); + assertEq( + ONDO.balanceOf(originalTakerAddress) - ondoBefore, + testData.expectedAmountOut, + "ONDO balance mismatch" + ); + + // Verify no tokens left in executor + assertEq( + USDC.balanceOf(address(bebopExecutor)), 0, "USDC left in executor" + ); + assertEq( + ONDO.balanceOf(address(bebopExecutor)), 0, "ONDO left in executor" + ); + } + + // Aggregate Order Helper Functions + function _setupAggregateOrder(AggregateOrderTestData memory testData) + internal + { + // Fund the sender with all input tokens + for (uint256 i = 0; i < testData.order.taker_tokens.length; i++) { + deal( + testData.order.taker_tokens[i], + testData.sender, + testData.amountsIn[i] + ); + + // Approve executor + vm.prank(testData.sender); + IERC20(testData.order.taker_tokens[i]).approve( + address(bebopExecutor), testData.amountsIn[i] + ); + } + } + + // Aggregate Order Tests + function testAggregateOrder_MultipleMakers() public { + // Fork at block 21732669 (around the time of the etherscan tx) + vm.createSelectFork(vm.rpcUrl("mainnet"), 21732669); + + // Deploy our mock Bebop settlement and use vm.etch to replace the real one + BebopSettlementMock mockSettlement = new BebopSettlementMock(); + bytes memory mockCode = address(mockSettlement).code; + vm.etch(BEBOP_SETTLEMENT, mockCode); + + // Deploy Bebop executor with the (now mocked) settlement contract + bebopExecutor = + new BebopExecutorExposed(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); + + // Based on etherscan tx data + address originalTakerAddress = + 0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6; + address maker1 = 0x67336Cec42645F55059EfF241Cb02eA5cC52fF86; + address maker2 = 0xBF19CbF0256f19f39A016a86Ff3551ecC6f2aAFE; + + // Build aggregate order: WETH -> USDC from two makers + address[] memory maker_addresses = new address[](2); + maker_addresses[0] = maker1; + maker_addresses[1] = maker2; + + // Single input token (WETH) - aggregate orders have single taker token + address[] memory taker_tokens = new address[](1); + taker_tokens[0] = WETH_ADDR; + + uint256[] memory taker_amounts = new uint256[](1); + taker_amounts[0] = 9850000000000000; // Total WETH amount (sum of both makers) + + // Output tokens from each maker + address[][] memory maker_tokens = new address[][](2); + maker_tokens[0] = new address[](1); + maker_tokens[0][0] = USDC_ADDR; + maker_tokens[1] = new address[](1); + maker_tokens[1][0] = USDC_ADDR; + + uint256[][] memory maker_amounts = new uint256[][](2); + maker_amounts[0] = new uint256[](1); + maker_amounts[0][0] = 10607211; // ~10.6 USDC from maker1 + maker_amounts[1] = new uint256[](1); + maker_amounts[1][0] = 7362350; // ~7.36 USDC from maker2 + + AggregateOrderTestData memory testData = AggregateOrderTestData({ + forkBlock: 21732669, + order: IBebopSettlement.Aggregate({ + expiry: 1746367285, + taker_address: originalTakerAddress, + taker_nonce: 0, // Aggregate orders use taker_nonce + taker_tokens: taker_tokens, + taker_amounts: taker_amounts, + maker_addresses: maker_addresses, + maker_tokens: maker_tokens, + maker_amounts: maker_amounts, + receiver: originalTakerAddress, + packed_commands: 0x00040004, + flags: 95769172144825922628485191511070792431742484643425438763224908097896054784000 + }), + signatures: new bytes[](2), + amountsIn: new uint256[](1), + filledTakerAmounts: new uint256[](1), + expectedAmountsOut: new uint256[](1), + sender: originalTakerAddress, + receiver: originalTakerAddress + }); + + // Signatures from the etherscan tx + testData.signatures[0] = + hex"d5abb425f9bac1f44d48705f41a8ab9cae207517be8553d2c03b06a88995f2f351ab8ce7627a87048178d539dd64fd2380245531a0c8e43fdc614652b1f32fc71c"; + testData.signatures[1] = + hex"f38c698e48a3eac48f184bc324fef0b135ee13705ab38cc0bbf5a792f21002f051e445b9e7d57cf24c35e17629ea35b3263591c4abf8ca87ffa44b41301b89c41b"; + + // Total amounts + uint256 totalWethIn = taker_amounts[0]; + uint256 totalUsdcOut = maker_amounts[0][0] + maker_amounts[1][0]; + + testData.amountsIn[0] = totalWethIn; + testData.filledTakerAmounts[0] = 0; // Full fill + testData.expectedAmountsOut[0] = totalUsdcOut; + + // Fund the original taker with WETH + deal(WETH_ADDR, originalTakerAddress, totalWethIn); + + // Fund makers with USDC and have them approve the settlement + deal(USDC_ADDR, maker1, maker_amounts[0][0]); + deal(USDC_ADDR, maker2, maker_amounts[1][0]); + + vm.prank(maker1); + USDC.approve(BEBOP_SETTLEMENT, type(uint256).max); + vm.prank(maker2); + USDC.approve(BEBOP_SETTLEMENT, type(uint256).max); + + // Original taker approves the test contract (router) to spend their tokens + vm.prank(originalTakerAddress); + WETH.approve(address(this), totalWethIn); + + // Test contract (router) pulls tokens from original taker and sends to executor + WETH.transferFrom( + originalTakerAddress, address(bebopExecutor), totalWethIn + ); + + // Record initial balances + uint256 usdcBefore = USDC.balanceOf(originalTakerAddress); + + // Execute the aggregate swap + bytes memory quoteData = abi.encode(testData.order); + IBebopSettlement.MakerSignature[] memory signatures = + new IBebopSettlement.MakerSignature[](2); + signatures[0] = IBebopSettlement.MakerSignature({ + signatureBytes: testData.signatures[0], + flags: uint256(0) // ECDSA from etherscan data + }); + signatures[1] = IBebopSettlement.MakerSignature({ + signatureBytes: testData.signatures[1], + flags: uint256(0) // ECDSA + }); + bytes memory makerSignaturesData = abi.encode(signatures); + + // Encode params for the aggregate order + bytes memory params = abi.encodePacked( + WETH_ADDR, // token_in + USDC_ADDR, // token_out + uint8(RestrictTransferFrom.TransferType.Transfer), + uint8(BebopExecutor.OrderType.Aggregate), + uint256(0), // filledTakerAmount: 0 for full fill + uint32(quoteData.length), + quoteData, + uint32(makerSignaturesData.length), + makerSignaturesData, + uint8(1) // approvalNeeded: true + ); // Execute swap - uint256 executorBalanceBefore = USDC.balanceOf(address(bebopExecutor)); - uint256 amountOut = bebopExecutor.swap(amountIn, params); - uint256 executorBalanceAfter = USDC.balanceOf(address(bebopExecutor)); + uint256 amountOut = bebopExecutor.swap(totalWethIn, params); - // Check that tokens ended up in the executor for the router to collect - assertEq(amountOut, expectedAmountOut); - assertEq(executorBalanceAfter - executorBalanceBefore, amountOut); - } - - function testETHInput() public { - uint256 amountIn = 1e18; // 1 ETH - uint256 expectedAmountOut = 3000e6; // 3000 USDC - - // Create a valid Bebop order with ETH input - IBebopSettlement.Single memory order = IBebopSettlement.Single({ - expiry: block.timestamp + 3600, - taker_address: address(0), // Any taker - maker_address: address(mockBebopSettlement), - maker_nonce: 1, - taker_token: address(0), // ETH input - maker_token: USDC_ADDR, - taker_amount: amountIn, - maker_amount: expectedAmountOut, - receiver: address(bebopExecutor), // Output should go to executor - packed_commands: 0, - flags: 0 - }); - - // Encode order as quote data - bytes memory quoteData = abi.encode(order); - bytes memory signature = hex"aabbccdd"; // Mock signature - - bytes memory params = abi.encodePacked( - address(0), // ETH input - USDC_ADDR, - uint8(RestrictTransferFrom.TransferType.None), // ETH comes via msg.value - uint8(0), // OrderType.Single - uint32(quoteData.length), - quoteData, - uint8(1), // signatureType: EIP712 - uint32(signature.length), - signature, - uint8(0) // approvalNeeded: false for ETH + // Verify results + assertEq(amountOut, totalUsdcOut, "Incorrect amount out"); + assertEq( + USDC.balanceOf(originalTakerAddress) - usdcBefore, + totalUsdcOut, + "USDC balance mismatch" ); - // Fund test contract with ETH - vm.deal(address(this), 10e18); - - uint256 executorBalanceBefore = USDC.balanceOf(address(bebopExecutor)); - uint256 amountOut = - bebopExecutor.swap{value: amountIn}(amountIn, params); - uint256 executorBalanceAfter = USDC.balanceOf(address(bebopExecutor)); - - // Check that tokens ended up in the executor for the router to collect - assertEq(amountOut, expectedAmountOut); - assertEq(executorBalanceAfter - executorBalanceBefore, amountOut); - } - - function testETHOutput() public { - uint256 amountIn = 1000e6; // 1000 USDC - uint256 expectedAmountOut = 1e18; // 1 ETH - - // Create a valid Bebop order with ETH output - IBebopSettlement.Single memory order = IBebopSettlement.Single({ - expiry: block.timestamp + 3600, - taker_address: address(0), // Any taker - maker_address: address(mockBebopSettlement), - maker_nonce: 1, - taker_token: USDC_ADDR, - maker_token: address(0), // ETH output - taker_amount: amountIn, - maker_amount: expectedAmountOut, - receiver: address(bebopExecutor), // Output should go to executor - packed_commands: 0, - flags: 0 - }); - - // Encode order as quote data - bytes memory quoteData = abi.encode(order); - bytes memory signature = hex"aabbccdd"; // Mock signature - - bytes memory params = abi.encodePacked( - USDC_ADDR, - address(0), // ETH output - uint8(RestrictTransferFrom.TransferType.Transfer), - uint8(0), // OrderType.Single - uint32(quoteData.length), - quoteData, - uint8(1), // signatureType: EIP712 - uint32(signature.length), - signature, - uint8(1) // approvalNeeded: true for USDC + // Verify no tokens left in executor + assertEq( + WETH.balanceOf(address(bebopExecutor)), 0, "WETH left in executor" ); - - // Transfer USDC to executor first - USDC.transfer(address(bebopExecutor), amountIn); - - uint256 executorEthBalanceBefore = address(bebopExecutor).balance; - uint256 amountOut = bebopExecutor.swap(amountIn, params); - uint256 executorEthBalanceAfter = address(bebopExecutor).balance; - - // Make sure the ETH ended up in the executor for the router to collect - assertEq(amountOut, expectedAmountOut); - assertEq(executorEthBalanceAfter - executorEthBalanceBefore, amountOut); - } - - function testExpiredQuote() public { - uint256 amountIn = 1e18; - uint256 expectedAmountOut = 3000e6; - - // Create an order with expired timestamp - IBebopSettlement.Single memory order = IBebopSettlement.Single({ - expiry: block.timestamp - 1, // Already expired - taker_address: address(0), - maker_address: address(mockBebopSettlement), - maker_nonce: 1, - taker_token: WETH_ADDR, - maker_token: USDC_ADDR, - taker_amount: amountIn, - maker_amount: expectedAmountOut, - receiver: address(bebopExecutor), // Output should go to executor - packed_commands: 0, - flags: 0 - }); - - bytes memory quoteData = abi.encode(order); - bytes memory signature = hex"aabbccdd"; - - bytes memory params = abi.encodePacked( - WETH_ADDR, - USDC_ADDR, - uint8(RestrictTransferFrom.TransferType.Transfer), - uint8(0), // OrderType.Single - uint32(quoteData.length), - quoteData, - uint8(1), // signatureType: EIP712 - uint32(signature.length), - signature, - uint8(1) // approvalNeeded: true + assertEq( + USDC.balanceOf(address(bebopExecutor)), 0, "USDC left in executor" ); - - // Transfer WETH to executor - WETH.transfer(address(bebopExecutor), amountIn); - - // Should revert due to expired order - vm.expectRevert("Order expired"); - bebopExecutor.swap(amountIn, params); } function testInvalidDataLength() public { + // Fork to ensure consistent setup + vm.createSelectFork(vm.rpcUrl("mainnet"), 22667985); + + // Deploy Bebop executor with real settlement contract + bebopExecutor = + new BebopExecutorExposed(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); bytes memory quoteData = hex"1234567890abcdef"; bytes memory signature = hex"aabbccdd"; + // Create ABI-encoded MakerSignature array + IBebopSettlement.MakerSignature[] memory signatures = + new IBebopSettlement.MakerSignature[](1); + signatures[0] = IBebopSettlement.MakerSignature({ + signatureBytes: signature, + flags: uint256(1) // EIP712 signature type + }); + bytes memory makerSignaturesData = abi.encode(signatures); + // Create params with correct length first + uint256 filledTakerAmount = 1e18; bytes memory validParams = abi.encodePacked( WETH_ADDR, USDC_ADDR, uint8(RestrictTransferFrom.TransferType.Transfer), uint8(0), // OrderType.Single + filledTakerAmount, uint32(quoteData.length), quoteData, - uint8(1), // signatureType: EIP712 - uint32(signature.length), - signature, + uint32(makerSignaturesData.length), + makerSignaturesData, uint8(1) // approvalNeeded: true ); @@ -609,216 +608,4 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils { vm.expectRevert(BebopExecutor.BebopExecutor__InvalidDataLength.selector); bebopExecutor.decodeParams(tooShortParams); } - - function testMultiRFQSwap() public { - uint256 amountIn = 1e18; // 1 WETH - uint256 expectedAmountOut = 3000e6; // 3000 USDC - - // Create arrays for Multi order - address[] memory takerTokens = new address[](2); - takerTokens[0] = WETH_ADDR; - takerTokens[1] = DAI_ADDR; // Not used in this test - - address[] memory makerTokens = new address[](2); - makerTokens[0] = USDC_ADDR; - makerTokens[1] = WBTC_ADDR; // Not used in this test - - uint256[] memory takerAmounts = new uint256[](2); - takerAmounts[0] = amountIn; - takerAmounts[1] = 0; - - uint256[] memory makerAmounts = new uint256[](2); - makerAmounts[0] = expectedAmountOut; - makerAmounts[1] = 0; - - // Create a valid Bebop Multi order - IBebopSettlement.Multi memory order = IBebopSettlement.Multi({ - expiry: block.timestamp + 3600, - taker_address: address(0), - maker_address: address(mockBebopSettlement), - maker_nonce: 1, - taker_tokens: takerTokens, - maker_tokens: makerTokens, - taker_amounts: takerAmounts, - maker_amounts: makerAmounts, - receiver: address(bebopExecutor), - packed_commands: 0, - flags: 0 - }); - - // Encode order as quote data - bytes memory quoteData = abi.encode(order); - bytes memory signature = hex"aabbccdd"; - - bytes memory params = abi.encodePacked( - WETH_ADDR, - USDC_ADDR, - uint8(RestrictTransferFrom.TransferType.Transfer), - uint8(1), // OrderType.Multi - uint32(quoteData.length), - quoteData, - uint8(1), // signatureType: EIP712 - uint32(signature.length), - signature, - uint8(1) // approvalNeeded: true - ); - - // Transfer WETH to executor first - WETH.transfer(address(bebopExecutor), amountIn); - - // Execute swap - uint256 executorBalanceBefore = USDC.balanceOf(address(bebopExecutor)); - uint256 amountOut = bebopExecutor.swap(amountIn, params); - uint256 executorBalanceAfter = USDC.balanceOf(address(bebopExecutor)); - - // Check results - assertGt(amountOut, 0); - assertEq(amountOut, expectedAmountOut); - assertEq(executorBalanceAfter - executorBalanceBefore, amountOut); - } - - function testInvalidSignatureType() public { - uint256 amountIn = 1e18; - uint256 expectedAmountOut = 3000e6; - - // Create a valid order but with invalid signature type - IBebopSettlement.Single memory order = IBebopSettlement.Single({ - expiry: block.timestamp + 3600, - taker_address: address(0), - maker_address: address(mockBebopSettlement), - maker_nonce: 1, - taker_token: WETH_ADDR, - maker_token: USDC_ADDR, - taker_amount: amountIn, - maker_amount: expectedAmountOut, - receiver: address(bebopExecutor), - packed_commands: 0, - flags: 0 - }); - - bytes memory quoteData = abi.encode(order); - bytes memory signature = hex"aabbccdd"; - - // Test with signatureType 0 (invalid) - bytes memory params = abi.encodePacked( - WETH_ADDR, - USDC_ADDR, - uint8(RestrictTransferFrom.TransferType.Transfer), - uint8(0), // OrderType.Single - uint32(quoteData.length), - quoteData, - uint8(0), // signatureType: 0 (invalid!) - uint32(signature.length), - signature, - uint8(1) // approvalNeeded: true - ); - - // Transfer WETH to executor - WETH.transfer(address(bebopExecutor), amountIn); - - // Should revert with invalid signature type when executing - vm.expectRevert( - BebopExecutor.BebopExecutor__InvalidSignatureType.selector - ); - bebopExecutor.swap(amountIn, params); - - // Test with signatureType 4 (invalid) - params = abi.encodePacked( - WETH_ADDR, - USDC_ADDR, - uint8(RestrictTransferFrom.TransferType.Transfer), - uint8(0), // OrderType.Single - uint32(quoteData.length), - quoteData, - uint8(4), // signatureType: 4 (invalid!) - uint32(signature.length), - signature, - uint8(1) // approvalNeeded: true - ); - - // Should also revert - vm.expectRevert( - BebopExecutor.BebopExecutor__InvalidSignatureType.selector - ); - bebopExecutor.swap(amountIn, params); - } - - function testAggregateRFQSwap() public { - uint256 amountIn = 1e18; // 1 WETH - uint256 expectedAmountOut = 3000e6; // 3000 USDC total from 2 makers - - // Create arrays for Aggregate order - address[] memory takerTokens = new address[](1); - takerTokens[0] = WETH_ADDR; - - uint256[] memory takerAmounts = new uint256[](1); - takerAmounts[0] = amountIn; - - address[] memory makerAddresses = new address[](2); - makerAddresses[0] = address(mockBebopSettlement); - makerAddresses[1] = makeAddr("maker2"); - - address[][] memory makerTokens = new address[][](2); - makerTokens[0] = new address[](1); - makerTokens[0][0] = USDC_ADDR; - makerTokens[1] = new address[](1); - makerTokens[1][0] = USDC_ADDR; - - uint256[][] memory makerAmounts = new uint256[][](2); - makerAmounts[0] = new uint256[](1); - makerAmounts[0][0] = 1500e6; // First maker provides 1500 USDC - makerAmounts[1] = new uint256[](1); - makerAmounts[1][0] = 1500e6; // Second maker provides 1500 USDC - - // Create a valid Bebop Aggregate order - IBebopSettlement.Aggregate memory order = IBebopSettlement.Aggregate({ - expiry: block.timestamp + 3600, - taker_address: address(0), - taker_nonce: 1, - taker_tokens: takerTokens, - taker_amounts: takerAmounts, - maker_addresses: makerAddresses, - maker_tokens: makerTokens, - maker_amounts: makerAmounts, - receiver: address(bebopExecutor), - packed_commands: 0, - flags: 0 - }); - - // Encode order as quote data - bytes memory quoteData = abi.encode(order); - - // Encode multiple signatures (2 makers) - for EIP712, use concatenated 65-byte signatures - bytes memory sig1 = - hex"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"; - bytes memory sig2 = - hex"1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111101"; - bytes memory signatures = abi.encodePacked(sig1, sig2); - - bytes memory params = abi.encodePacked( - WETH_ADDR, - USDC_ADDR, - uint8(RestrictTransferFrom.TransferType.Transfer), - uint8(2), // OrderType.Aggregate - uint32(quoteData.length), - quoteData, - uint8(1), // signatureType: EIP712 - uint32(signatures.length), - signatures, - uint8(1) // approvalNeeded: true - ); - - // Transfer WETH to executor first - WETH.transfer(address(bebopExecutor), amountIn); - - // Execute swap - uint256 executorBalanceBefore = USDC.balanceOf(address(bebopExecutor)); - uint256 amountOut = bebopExecutor.swap(amountIn, params); - uint256 executorBalanceAfter = USDC.balanceOf(address(bebopExecutor)); - - // Check results - assertGt(amountOut, 0); - assertEq(amountOut, expectedAmountOut); - assertEq(executorBalanceAfter - executorBalanceBefore, amountOut); - } }