From 90ac0a4c985c04745c00a2d072d3d02d3baff318 Mon Sep 17 00:00:00 2001 From: pedrobergamini <41773103+pedrobergamini@users.noreply.github.com> Date: Tue, 17 Jun 2025 23:27:03 -0300 Subject: [PATCH] test: fix all aggregate order tests and a few executor bugs --- foundry/src/executors/BebopExecutor.sol | 22 +- .../test/TychoRouterProtocolIntegration.t.sol | 69 ++- foundry/test/assets/calldata.txt | 26 +- foundry/test/executors/BebopExecutor.t.sol | 567 +++++++++++++++--- .../evm/swap_encoder/swap_encoders.rs | 6 +- 5 files changed, 561 insertions(+), 129 deletions(-) diff --git a/foundry/src/executors/BebopExecutor.sol b/foundry/src/executors/BebopExecutor.sol index 067163f..0295d5b 100644 --- a/foundry/src/executors/BebopExecutor.sol +++ b/foundry/src/executors/BebopExecutor.sol @@ -193,8 +193,10 @@ contract BebopExecutor is IExecutor, IExecutorErrors, RestrictTransferFrom { givenAmount, order.taker_amount, filledTakerAmount ); - // Transfer tokens to executor - _transfer(address(this), transferType, tokenIn, givenAmount); + if (tokenIn != address(0)) { + // Transfer tokens to executor + _transfer(address(this), transferType, tokenIn, givenAmount); + } // Approve Bebop settlement to spend tokens if needed if (approvalNeeded) { @@ -248,20 +250,24 @@ contract BebopExecutor is IExecutor, IExecutorErrors, RestrictTransferFrom { revert BebopExecutor__InvalidInput(); } - // For aggregate orders, calculate total taker amount across all makers - uint256 totalTakerAmount = 0; + // For aggregate orders, calculate total taker amount across all amounts of the 2D array + uint256 totalTakerAmount; for (uint256 i = 0; i < order.taker_amounts.length; i++) { - totalTakerAmount += order.taker_amounts[i][0]; + for (uint256 j = 0; j < order.taker_amounts[i].length; j++) { + totalTakerAmount += order.taker_amounts[i][j]; + } } uint256 actualFilledTakerAmount = _getActualFilledTakerAmount( givenAmount, totalTakerAmount, filledTakerAmount ); - // Transfer single input token - _transfer(address(this), transferType, tokenIn, givenAmount); + if (tokenIn != address(0)) { + // Transfer tokens to executor + _transfer(address(this), transferType, tokenIn, givenAmount); + } - // Approve if needed + // Approve Bebop settlement to spend tokens if needed if (approvalNeeded) { // slither-disable-next-line unused-return IERC20(tokenIn).forceApprove(bebopSettlement, type(uint256).max); diff --git a/foundry/test/TychoRouterProtocolIntegration.t.sol b/foundry/test/TychoRouterProtocolIntegration.t.sol index 6657a8a..9a0f74e 100644 --- a/foundry/test/TychoRouterProtocolIntegration.t.sol +++ b/foundry/test/TychoRouterProtocolIntegration.t.sol @@ -299,14 +299,13 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup { // The calldata swaps 200 USDC for ONDO // The receiver in the order is 0xc5564C13A157E6240659fb81882A28091add8670 address orderReceiver = 0xc5564C13A157E6240659fb81882A28091add8670; + address maker = 0xCe79b081c0c924cb67848723ed3057234d10FC6b; 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); + deal(ONDO_ADDR, maker, expAmountOut); + vm.prank(maker); IERC20(ONDO_ADDR).approve(BEBOP_SETTLEMENT, expAmountOut); vm.startPrank(ALICE); @@ -322,47 +321,51 @@ contract TychoRouterTestProtocolIntegration is TychoRouterTestSetup { uint256 finalBalance = IERC20(ONDO_ADDR).balanceOf(orderReceiver); assertTrue(success, "Call Failed"); assertGe(finalBalance, expAmountOut); - assertEq(IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), 0); + assertEq( + IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), + 0, + "USDC left in router" + ); 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 + // Based on real transaction: https://etherscan.io/tx/0xec88410136c287280da87d0a37c1cb745f320406ca3ae55c678dec11996c1b1c + address orderTaker = 0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6; // This is both taker and receiver in the order + uint256 ethAmount = 9850000000000000; // 0.00985 WETH + uint256 expAmountOut = 17969561; // 17.969561 USDC expected output - // // Fund the two makers from the calldata with WETH - // address maker1 = 0x1111111111111111111111111111111111111111; - // address maker2 = 0x2222222222222222222222222222222222222222; + // Fund the two makers from the real transaction with USDC + address maker1 = 0x67336Cec42645F55059EfF241Cb02eA5cC52fF86; + address maker2 = 0xBF19CbF0256f19f39A016a86Ff3551ecC6f2aAFE; - // // Maker 1 provides 0.24 WETH, Maker 2 provides 0.16 WETH - // deal(WETH_ADDR, maker1, 240000000000000000); - // deal(WETH_ADDR, maker2, 160000000000000000); + deal(USDC_ADDR, maker1, 10607211); // Maker 1 provides 10.607211 USDC + deal(USDC_ADDR, maker2, 7362350); // Maker 2 provides 7.362350 USDC - // // 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); + // Makers approve settlement contract + vm.prank(maker1); + IERC20(USDC_ADDR).approve(BEBOP_SETTLEMENT, type(uint256).max); + vm.prank(maker2); + IERC20(USDC_ADDR).approve(BEBOP_SETTLEMENT, type(uint256).max); - // vm.startPrank(ALICE); - // IERC20(USDC_ADDR).approve(tychoRouterAddr, type(uint256).max); + // Fund ALICE with ETH as it will send the transaction + vm.deal(ALICE, ethAmount); + vm.startPrank(ALICE); - // bytes memory callData = loadCallDataFromFile( - // "test_single_encoding_strategy_bebop_aggregate" - // ); + // Load calldata from file + bytes memory callData = loadCallDataFromFile( + "test_single_encoding_strategy_bebop_aggregate" + ); - // (bool success,) = tychoRouterAddr.call(callData); + // Execute the swap + (bool success,) = tychoRouterAddr.call{value: ethAmount}(callData); + uint256 finalBalance = IERC20(USDC_ADDR).balanceOf(orderTaker); - // uint256 finalBalance = IERC20(WETH_ADDR).balanceOf(ALICE); + assertTrue(success, "Call Failed"); + assertGe(finalBalance, expAmountOut); + assertEq(address(tychoRouterAddr).balance, 0, "ETH left in router"); - // assertTrue(success, "Call Failed"); - // assertGe(finalBalance, expAmountOut); - // assertEq(IERC20(USDC_ADDR).balanceOf(tychoRouterAddr), 0); - - // vm.stopPrank(); - - vm.skip(true); + vm.stopPrank(); } } diff --git a/foundry/test/assets/calldata.txt b/foundry/test/assets/calldata.txt index deb187a..2c5cb1b 100644 --- a/foundry/test/assets/calldata.txt +++ b/foundry/test/assets/calldata.txt @@ -8,7 +8,7 @@ test_single_encoding_strategy_ekubo:5c4b639c000000000000000000000000000000000000 test_single_encoding_strategy_maverick:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000040d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000051a4ad4f68d0b91cfd19687c881e50f3a00242828c40d16fc0246ad3160ccc09b8d0d3a2cd28ae6c2f14cf6d2fe3e1b326114b07d22a6f6bb59e346c67cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_single_encoding_strategy_curve_st_eth:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ae7ab96520de3a18e5e111b5eaab095312d7fe84000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff211eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeae7ab96520de3a18e5e111b5eaab095312d7fe84dc24316b9ae028f1497c275eb9192a3ea0f670220100010002cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000 test_single_encoding_strategy_bebop:5c4b639c000000000000000000000000000000000000000000000000000000000bebc200000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be300000000000000000000000000000000000000000000000cdbfbba0faafaf02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5564c13a157e6240659fb81882a28091add86700000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000002e7d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab82f62fe7c39859fa577269be300000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000068470140000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b000000000000000000000000000000000000000000000000000637256e698be1000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000cdbfbba0faafaf020000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000000000000000000000000000000000000000000072c75365fbad713c3dbdcac257c435540000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000 -test_encode_bebop_aggregate:6b175474e89094c44da98b954eedeac495271d0f2260fac5e5542a773aa44fbcfedf7c193bc2c599000100000000000000000000000000000000000000000000000000000000000f424000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000499602d20000000000000000000000001111111111111111111111111111111111111111000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c0000000000000000000000000444444444444444444444444444444444444444400000000000000000000000000000000000000000000000000000000000005a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000002222222222222222222222222222222222222222000000000000000000000000333333333333333333333333333333333333333300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000003039000000000000000000000000000000000000000000000000000000000000303a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000010000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c59900000000000000000000000000000000000000000000000000000000000000010000000000000000000000002260fac5e5542a773aa44fbcfedf7c193bc2c599000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000006f05b59d3b20000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000001312d0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000001312d00000000000000000000000000000000000000000000000000000000000000004000400040000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111010000000000000000000000000000000000000000000000000000000000000001 +test_encode_bebop_aggregate:0000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480101000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000681773350000000000000000000000007078b12ca5b294d95e9ac16d90b7d38238d8f4e6000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000007078b12ca5b294d95e9ac16d90b7d38238d8f4e600000000000000000000000000000000000000000000000000000000000005a0d3bb6e37a886dc243affa93ce81c8a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000bf19cbf0256f19f39a016a86ff3551ecc6f2aafe0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000001969b98b07c0000000000000000000000000000000000000000000000000000000000ebe7000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000014a614797ce1520000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000e58715d8cbeae00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000a1da6b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000070572e00000000000000000000000000000000000000000000000000000000000000040004000400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041d5abb425f9bac1f44d48705f41a8ab9cae207517be8553d2c03b06a88995f2f351ab8ce7627a87048178d539dd64fd2380245531a0c8e43fdc614652b1f32fc71c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f38c698e48a3eac48f184bc324fef0b135ee13705ab38cc0bbf5a792f21002f051e445b9e7d57cf24c35e17629ea35b3263591c4abf8ca87ffa44b41301b89c41b0000000000000000000000000000000000000000000000000000000000000000 test_single_encoding_strategy_curve:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000055c08ca52497e2f1534b59e2917bf524d4765257000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000691d1499e622d69689cdf9004d05ec547d650ff21155c08ca52497e2f1534b59e2917bf524d4765257c02aaa39b223fe8d0a0e5c4f27ead9083c756cc277146b0a1d08b6844376df6d9da99ba7f1b19e710201000100cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000 test_encode_balancer_v2:c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2ba100000625a3754423978a60c9317c58a424e3d5c6ee304399dbdb9c8ef030ab642b10820db8f560002000000000000000000141d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e0102 test_uniswap_v3_balancer_v3:e21dd0d3000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000004a220e6096b25eadb88358cb44068a324825467500000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d200692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed0000006503a6a84cd762d9707a21605b548aaab891562aab2260fac5e5542a773aa44fbcfedf7c193bc2c5994a220e6096b25eadb88358cb44068a3248254675571bea0e99e139cd0b6b7d9352ca872dfe0d72dd01cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000 @@ -16,23 +16,23 @@ test_encode_bebop_single:a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab test_uniswap_v3_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000bf00692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb8004375dff511095cc5a197a54140a24efef3a416cbcdf9626bc03e24f779434178a73a0b4bad62ed000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010200 test_uniswap_v3_uniswap_v3:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000692e234dae75c793f67a35089c9d99245e1c58470b2260fac5e5542a773aa44fbcfedf7c193bc2c599a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc299ac8ca7087fa4a2a1fb6357269965a2014abc35010100000000000000000000 test_sequential_swap_strategy_encoder_no_permit2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 -test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068798d5400000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075c00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000415d97acdc43165dccb6633b604b05c7c1b84e35c7918304d600a518d1aac0b46c429655eb4960e809b8ab053db1a03613950f6d6786b9aae26a97adcc9f8d3d361c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000 +test_single_encoding_strategy_usv4_eth_in:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000007e0a55d4322a6e93c2379c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068799b4a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155200000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041dd4fb2e7c21126741cfc34bb7c92e21b59fb1f2b017d1afecb4896fa216906843f590ce68bc13e6725c711bec2b95b654e76838b3fbf1671d099bb6fe089758e1b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820a00000000000000000000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc26982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000 test_single_swap_strategy_encoder_no_permit2:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 test_single_swap_strategy_encoder_no_transfer_in:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000058e7926ee858a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 -test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000068798d5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075d00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041537be9de00dab420618fca4aee3a489d7258ea247064829b27da9a70924fbce07b7470bcfd978546c4494e72b574532678aa9edc1629563df0623caf780b65a71c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000000000000000 -test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068798d5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075d00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000411d2dbb2c057ef34080ff4d2cba4a80f7fc602e190a45b1a1e57440161a44550b739f3c6db782b2ce2925b61fb2785fb336daba0c7c8bd174e2860aa766e6f00f1b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000 +test_single_encoding_strategy_usv4_grouped_swap:30ace1b1000000000000000000000000000000000000000000000000000000003b9aca00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006982508145454ce325ddbe47a25d4ec3d23119330000000000000000000000000000000000000000005064ff624d54346285543f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000003b9aca000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000411ae5d9a57df58c0c86a9a25915bc9854e7d1d19c386edf27cac416486fe873646b0b0ec32dfdf9b36f82a60e8cc2c6ef40ca7506b9a0d099e796b63fadeee99e1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000086f62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486982508145454ce325ddbe47a25d4ec3d23119330000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c6982508145454ce325ddbe47a25d4ec3d23119330061a80001f40000000000000000000000000000000000000000000000000000 +test_sequential_strategy_cyclic_swap:51bcc7b60000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ec8f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004197b18d90cb62432aa84f949fa9764d17ed7319d9a7ef6c8c14b5a6c0477bb4e8147b5507020884fb29b817769c607427c66915c28c38c55d4af2e9f1da87ca831b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640010000692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000000000 test_uniswap_v3_curve:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed000000691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae460301000102cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000 test_uniswapv3_bebop:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d996e0293020b100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000021900692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000001acd6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb486b175474e89094c44da98b954eedeac495271d0f01000000016000000000000000000000000000000000000000000000000000000000684514c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bbbbbbb520d69a9775e85b458c58c648259fad5f0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000000000000007881786100000000000000000000000000000000000000000000006d996e0293020b1000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004aabbccdd0100000000000000 -test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e000000000000000000000000000000000000000000000000000000000068798d5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075d00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041e16b0019843223bbace4fb5ed3de58d9e99584335b50145f1f5e68d283efb2cf467eddafc6bd70fd3b1fb0a6e9e7bf72ac0211ff1dedbcdc22ced15b006d3ea21c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000 +test_single_encoding_strategy_usv4_eth_out:30ace1b100000000000000000000000000000000000000000000000000000000b2d05e00000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f81490b4f29aade00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000b2d05e000000000000000000000000000000000000000000000000000000000068799b4a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155200000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041b52428e79412b9ce2c6cb85b8d8e9cd52e390abdefdd671100bc6e2d96a2296d03ec2cb4d57e836f94e71c64a303009639429b0ecea710f3832ec3a131dacdeb1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c0000000000000000000000000000000000000000 test_balancer_v2_uniswap_v2:e21dd0d30000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000c80072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e004375dff511095cc5a197a54140a24efef3a416010000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 -test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068798d5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075d00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041f9fdfba8499edecf60e3c7f8d06ac099f7081fe43eee2f003d4724762d846c1f43078ef56234e2eaff9683b79f9cfc852e340e8114713ef1aafd67bc2aa90fe91c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 -test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068798d5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075d00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041f9fdfba8499edecf60e3c7f8d06ac099f7081fe43eee2f003d4724762d846c1f43078ef56234e2eaff9683b79f9cfc852e340e8114713ef1aafd67bc2aa90fe91c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 -test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000000000000000000000000000000000000068798d5500000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075d00000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041aac9ec0debeb27e6434207314848ec6bd795da216ed1c6b53cd0acc930ffa15d09a342e7bda96f05a6741b2f9d576b29da29cd0a81920458b305708c16e4ed101c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000 -test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068798d5600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075e00000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004181feb23715b56cecae5c7d9f86afb499c2315bbdf198152c09074c88371957dd62dbdc69214ff6b4c43383307c4aa9cb90dd4e9297095ccbbd131f1585c59bba1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000 -test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068798d5600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075e00000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004181feb23715b56cecae5c7d9f86afb499c2315bbdf198152c09074c88371957dd62dbdc69214ff6b4c43383307c4aa9cb90dd4e9297095ccbbd131f1585c59bba1c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000 -test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068798d5600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075e00000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000260000000000000000000000000000000000000000000000000000000000000004181869de54d663dfbc86d19d5f92c20a20bb1c749f1f37f9d2c08f7f790cdffd73843edfb88af0ae07de136583d4a990c61be19fdcf7d72268c99560c78946fcc1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 -test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068798d5600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075e000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041457ce537de8033c9601cb54e069c44f75a4c0b049a81ae909bc2e171a57212a8236d88ff1ff4dd9f405b210e75394f66fe6962770525bac81c1956a9ba16ed021c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000 -test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000068798d5600000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852075e00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000410f4ea8fcc933abfe9cdcfc877e77e9b6b8ad386f9dace343c06f1a787d45ff966e4a07c45be8f4420e89ccc90ad78ea7fe8112eab578672600446ee8da467a921b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000 +test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041abaaaa196b16253db868167a8bb3915652059c7e3ec65ebfd1d5338b8992bcb57b42348b7f1786b224a43b5437537a7ff7d1df4aac24e49c43bafe4ecc5b9c661b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 +test_sequential_swap_strategy_encoder:51bcc7b60000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041abaaaa196b16253db868167a8bb3915652059c7e3ec65ebfd1d5338b8992bcb57b42348b7f1786b224a43b5437537a7ff7d1df4aac24e49c43bafe4ecc5b9c661b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a800525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d940004375dff511095cc5a197a54140a24efef3a416000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20102000000000000000000000000000000000000000000000000 +test_single_swap_strategy_encoder_unwrap:30ace1b10000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f0000000000000000000000000000000000000000000000a2a15d09519be000000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000414a8ef9869b9c216b67c4c5eb2d8e6959989228e8da504225e6d78809456a566145e22054fa70cce74cd6e1abe5934215be64c9ba6e8781ae10e68c95af4c4e831b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000000000000000000000000000000 +test_split_input_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005ef619b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004197b18d90cb62432aa84f949fa9764d17ed7319d9a7ef6c8c14b5a6c0477bb4e8147b5507020884fb29b817769c607427c66915c28c38c55d4af2e9f1da87ca831b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139006e00019999992e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f56400100006e00010000002e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000bb83ede3eca2a72b3aecc820e955b36f38437d013958ad599c3a0ff1de082011efddc58f1908eb6e6d80100005701000000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2b4e16d0168e52d35cacd2c6185b44281ec28c9dccd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000100000000000000 +test_split_output_cyclic_swap:7c5538460000000000000000000000000000000000000000000000000000000005f5e100000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005e703f4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000005f5e1000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000004197b18d90cb62432aa84f949fa9764d17ed7319d9a7ef6c8c14b5a6c0477bb4e8147b5507020884fb29b817769c607427c66915c28c38c55d4af2e9f1da87ca831b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000139005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48b4e16d0168e52d35cacd2c6185b44281ec28c9dc3ede3eca2a72b3aecc820e955b36f38437d013950100006e01009999992e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f4cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc288e6a0c2ddd26feeb64f039a2c41296fcb3f56400001006e01000000002e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000bb8cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc28ad599c3a0ff1de082011efddc58f1908eb6e6d8000100000000000000 +test_single_swap_strategy_encoder_wrap:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000000059fb7d3830e6fc064b00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000414cb24f925286d0a25272c873bb64f0d3ddfbab81625784bb0ab9718da57e1c07649f79a8af38b1855b44b62c292aa0552dcfd4612bece0c2da3399c841d2e00d1c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200010000000000000000000000000000 +test_split_swap_strategy_encoder:7c5538460000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000018f61ec000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068521553000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000041abaaaa196b16253db868167a8bb3915652059c7e3ec65ebfd1d5338b8992bcb57b42348b7f1786b224a43b5437537a7ff7d1df4aac24e49c43bafe4ecc5b9c661b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000164005700028000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d013950000005700010000005615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2bb2b8038a1640196fbe3e38816f3e67cba72d9403ede3eca2a72b3aecc820e955b36f38437d013950000005702030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fae461ca67b15dc8dc81ce7615e0320da1a9ab8d5cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20101005701030000005615deb798bb3e4dfa0139dfa1b3d433cc23b72f2260fac5e5542a773aa44fbcfedf7c193bc2c599004375dff511095cc5a197a54140a24efef3a416cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2010100000000000000000000000000000000000000000000000000000000 +test_multi_protocol:51bcc7b600000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a2958f36da71a9200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000005150ae84a8cdf000000000000000000000000000000000000000000000000000000000000068799b4b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d01395000000000000000000000000000000000000000000000000000000006852155300000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000002600000000000000000000000000000000000000000000000000000000000000041c94a7b6e6e81fce3938e1905eed1a55e8ad1a72242bc10d9cb41cd8f4f73365c5d9102a6507fb8316b89dae6f8819c8d7ae789724970a8ca9ce827268d7bcef91b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021400525615deb798bb3e4dfa0139dfa1b3d433cc23b72f6b175474e89094c44da98b954eedeac495271d0fa478c2975ab1ea89e8196811f51a7b7ade33eb113ede3eca2a72b3aecc820e955b36f38437d0139501000072c7183455a4c133ae270771860664b6b7ec320bb1c02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599a6f548df93de924d73be7d25dc02554c6bd66db500020000000000000000000e3ede3eca2a72b3aecc820e955b36f38437d01395010200691d1499e622d69689cdf9004d05ec547d650ff2112260fac5e5542a773aa44fbcfedf7c193bc2c599dac17f958d2ee523a2206206994597c13d831ec7d51a44d3fae010294c616388b506acda1bfaae4603010001023ede3eca2a72b3aecc820e955b36f38437d013950071a0cb889707d426a7a386870a03bc70d1b0697598013ede3eca2a72b3aecc820e955b36f38437d01395dac17f958d2ee523a2206206994597c13d831ec7a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001a36e2eb1c43200000032006cf62849f9a0b5bf2913b396098f7c7019b51a820aa0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000001cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000bb800003c000000000000000000000000 test_uniswap_v3_bebop:e21dd0d3000000000000000000000000000000000000000000000000015fb7f9b8c38000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be300000000000000000000000000000000000000000000000cdbfbba0faafaf02000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c5564c13a157e6240659fb81882a28091add867000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000035400692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480001f43ede3eca2a72b3aecc820e955b36f38437d0139588e6a0c2ddd26feeb64f039a2c41296fcb3f5640000002e7d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbffa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48faba6f8e4a5e8ab82f62fe7c39859fa577269be301000000000000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000068470140000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b000000000000000000000000000000000000000000000000000637256e698be1000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000faba6f8e4a5e8ab82f62fe7c39859fa577269be3000000000000000000000000000000000000000000000000000000000bebc20000000000000000000000000000000000000000000000000cdbfbba0faafaf020000000000000000000000000c5564c13a157e6240659fb81882a28091add8670000000000000000000000000000000000000000000000000000000000000000072c75365fbad713c3dbdcac257c435540000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041eb5419631614978da217532a40f02a8f2ece37d8cfb94aaa602baabbdefb56b474f4c2048a0f56502caff4ea7411d99eed6027cd67dc1088aaf4181dcb0df7051c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000 test_single_encoding_strategy_bebop_aggregate:5c4b639c0000000000000000000000000000000000000000000000000022fe85d709a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000001123199000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007078b12ca5b294d95e9ac16d90b7d38238d8f4e6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000867d6bbde9174b1cdaa358d2cf4d57d1a9f7178fbff0000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480201000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000681773350000000000000000000000007078b12ca5b294d95e9ac16d90b7d38238d8f4e6000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c00000000000000000000000000000000000000000000000000000000000000220000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000003e000000000000000000000000000000000000000000000000000000000000004c00000000000000000000000007078b12ca5b294d95e9ac16d90b7d38238d8f4e600000000000000000000000000000000000000000000000000000000000005a0d3bb6e37a886dc243affa93ce81c8a4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000067336cec42645f55059eff241cb02ea5cc52ff86000000000000000000000000bf19cbf0256f19f39a016a86ff3551ecc6f2aafe0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000001969b98b07c0000000000000000000000000000000000000000000000000000000000ebe7000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000014a614797ce1520000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000e58715d8cbeae00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000a1da6b0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000070572e00000000000000000000000000000000000000000000000000000000000000040004000400000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041d5abb425f9bac1f44d48705f41a8ab9cae207517be8553d2c03b06a88995f2f351ab8ce7627a87048178d539dd64fd2380245531a0c8e43fdc614652b1f32fc71c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041f38c698e48a3eac48f184bc324fef0b135ee13705ab38cc0bbf5a792f21002f051e445b9e7d57cf24c35e17629ea35b3263591c4abf8ca87ffa44b41301b89c41b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 test_ekubo_encode_swap_multi:01ca4f73fe97d0b987a0d12b39bbd562c779bab6f60000000000000000000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4851d02a5948496a67827242eabc5725531342527c000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000001a36e2eb1c43200000032 diff --git a/foundry/test/executors/BebopExecutor.t.sol b/foundry/test/executors/BebopExecutor.t.sol index 5b9ff5f..35209a1 100644 --- a/foundry/test/executors/BebopExecutor.t.sol +++ b/foundry/test/executors/BebopExecutor.t.sol @@ -48,7 +48,7 @@ contract BebopExecutorHarness is BebopExecutor, Test { uint256 filledTakerAmount, bytes memory quoteData, bytes memory makerSignaturesData, - bool approvalNeeded + bool // approvalNeeded - unused in test harness ) { return _decodeData(data); @@ -85,8 +85,27 @@ contract BebopExecutorHarness is BebopExecutor, Test { givenAmount, order.taker_amount, filledTakerAmount ); - // Transfer tokens to executor - _transfer(address(this), transferType, tokenIn, givenAmount); + if (tokenIn != address(0)) { + // Transfer tokens to executor + _transfer(address(this), transferType, tokenIn, givenAmount); + } + + // NOTE: NOT NEEDED FOR TESTING + // // Approve Bebop settlement to spend tokens if needed + // if (approvalNeeded) { + // // slither-disable-next-line unused-return + // IERC20(tokenIn).forceApprove(bebopSettlement, type(uint256).max); + // } + + // NOTE: SETUP FOR TESTING + + // Record balances before swap to calculate amountOut + uint256 balanceBefore = tokenOut == address(0) + ? order.receiver.balance + : IERC20(tokenOut).balanceOf(order.receiver); + + // Execute the swap with ETH value if needed + uint256 ethValue = tokenIn == address(0) ? actualFilledTakerAmount : 0; // For testing: transfer tokens from executor to taker address // This simulates the taker having the tokens with approval @@ -101,16 +120,12 @@ contract BebopExecutorHarness is BebopExecutor, Test { vm.startPrank(order.taker_address); IERC20(tokenIn).forceApprove(bebopSettlement, type(uint256).max); vm.stopPrank(); + } else { + vm.stopPrank(); + // For native ETH, send it to the taker address + payable(order.taker_address).transfer(actualFilledTakerAmount); } - // Record balances before swap to calculate amountOut - uint256 balanceBefore = tokenOut == address(0) - ? order.receiver.balance - : IERC20(tokenOut).balanceOf(order.receiver); - - // Execute the swap with ETH value if needed - uint256 ethValue = tokenIn == address(0) ? actualFilledTakerAmount : 0; - // IMPORTANT: Prank as the taker address to pass the settlement validation vm.stopPrank(); vm.startPrank(order.taker_address); @@ -129,6 +144,8 @@ contract BebopExecutorHarness is BebopExecutor, Test { vm.warp(currentTimestamp); vm.stopPrank(); + // NOTE: END SETUP FOR TESTING + // Calculate actual amount received uint256 balanceAfter = tokenOut == address(0) ? order.receiver.balance @@ -146,80 +163,100 @@ contract BebopExecutorHarness is BebopExecutor, Test { uint256 filledTakerAmount, bytes memory quoteData, bytes memory makerSignaturesData, - bool approvalNeeded + bool // approvalNeeded - unused in test harness ) internal virtual override returns (uint256 amountOut) { - // // Decode the Aggregate order - // IBebopSettlement.Aggregate memory order = - // abi.decode(quoteData, (IBebopSettlement.Aggregate)); + // Decode the Aggregate order + IBebopSettlement.Aggregate memory order = + abi.decode(quoteData, (IBebopSettlement.Aggregate)); - // // Decode the MakerSignature array (can contain multiple signatures for Aggregate orders) - // IBebopSettlement.MakerSignature[] memory signatures = - // abi.decode(makerSignaturesData, (IBebopSettlement.MakerSignature[])); + // Decode the MakerSignature array (can contain multiple signatures for Aggregate orders) + IBebopSettlement.MakerSignature[] memory signatures = + abi.decode(makerSignaturesData, (IBebopSettlement.MakerSignature[])); - // // Aggregate orders should have at least one signature - // if (signatures.length == 0) { - // revert BebopExecutor__InvalidInput(); - // } + // Aggregate orders should have at least one signature + if (signatures.length == 0) { + revert BebopExecutor__InvalidInput(); + } - // // For aggregate orders, calculate total taker amount across all makers - // uint256 totalTakerAmount = 0; - // for (uint256 i = 0; i < order.taker_amounts.length; i++) { - // totalTakerAmount += order.taker_amounts[i][0]; - // } - // uint256 actualFilledTakerAmount = _getActualFilledTakerAmount( - // givenAmount, totalTakerAmount, filledTakerAmount - // ); + // For aggregate orders, calculate total taker amount across all amounts of the 2D array + uint256 totalTakerAmount; + for (uint256 i = 0; i < order.taker_amounts.length; i++) { + for (uint256 j = 0; j < order.taker_amounts[i].length; j++) { + totalTakerAmount += order.taker_amounts[i][j]; + } + } - // // Transfer tokens to executor - // _transfer(address(this), transferType, tokenIn, givenAmount); + uint256 actualFilledTakerAmount = _getActualFilledTakerAmount( + givenAmount, totalTakerAmount, filledTakerAmount + ); - // // For testing: transfer tokens from executor to taker address - // // This simulates the taker having the tokens with approval - // if (tokenIn != address(0)) { - // IERC20(tokenIn).safeTransfer( - // order.taker_address, actualFilledTakerAmount - // ); + if (tokenIn != address(0)) { + // Transfer tokens to executor + _transfer(address(this), transferType, tokenIn, givenAmount); + } - // // Approve settlement from taker's perspective - // // Stop any existing prank first - // vm.stopPrank(); - // vm.startPrank(order.taker_address); + // NOTE: NOT NEEDED FOR TESTING + // // Approve Bebop settlement to spend tokens if needed + // if (approvalNeeded) { + // // slither-disable-next-line unused-return // IERC20(tokenIn).forceApprove(bebopSettlement, type(uint256).max); - // vm.stopPrank(); // } - // // Record balances before swap to calculate amountOut - // uint256 balanceBefore = tokenOut == address(0) - // ? order.receiver.balance - // : IERC20(tokenOut).balanceOf(order.receiver); + // NOTE: SETUP FOR TESTING - // // Execute the swap with ETH value if needed - // uint256 ethValue = tokenIn == address(0) ? actualFilledTakerAmount : 0; + // Record balances before swap to calculate amountOut + uint256 balanceBefore = tokenOut == address(0) + ? order.receiver.balance + : IERC20(tokenOut).balanceOf(order.receiver); - // // IMPORTANT: Prank as the taker address to pass the settlement validation - // vm.stopPrank(); - // vm.startPrank(order.taker_address); + // Execute the swap with ETH value if needed + uint256 ethValue = tokenIn == address(0) ? actualFilledTakerAmount : 0; - // // Set block timestamp to ensure order is valid regardless of fork block - // uint256 currentTimestamp = block.timestamp; - // vm.warp(order.expiry - 1); // Set timestamp to just before expiry + // For testing: transfer tokens from executor to taker address + // This simulates the taker having the tokens with approval + if (tokenIn != address(0)) { + IERC20(tokenIn).safeTransfer( + order.taker_address, actualFilledTakerAmount + ); - // // Execute the swap - tokens are now in taker's wallet with approval - // // slither-disable-next-line arbitrary-send-eth - // IBebopSettlement(bebopSettlement).swapAggregate{value: ethValue}( - // order, signatures, actualFilledTakerAmount - // ); + // Approve settlement from taker's perspective + // Stop any existing prank first + vm.stopPrank(); + vm.startPrank(order.taker_address); + IERC20(tokenIn).forceApprove(bebopSettlement, type(uint256).max); + vm.stopPrank(); + } else { + vm.stopPrank(); + // For native ETH, send it to the taker address + payable(order.taker_address).transfer(actualFilledTakerAmount); + } - // // Restore original timestamp - // vm.warp(currentTimestamp); - // vm.stopPrank(); + // IMPORTANT: Prank as the taker address to pass the settlement validation + vm.stopPrank(); + vm.startPrank(order.taker_address); - // // Calculate actual amount received - // uint256 balanceAfter = tokenOut == address(0) - // ? order.receiver.balance - // : IERC20(tokenOut).balanceOf(order.receiver); + // Set block timestamp to ensure order is valid regardless of fork block + uint256 currentTimestamp = block.timestamp; + vm.warp(order.expiry - 1); // Set timestamp to just before expiry - // amountOut = balanceAfter - balanceBefore; + // Use swapAggregate - tokens are now in taker's wallet with approval + // slither-disable-next-line arbitrary-send-eth + IBebopSettlement(bebopSettlement).swapAggregate{value: ethValue}( + order, signatures, actualFilledTakerAmount + ); + + // Restore original timestamp + vm.warp(currentTimestamp); + vm.stopPrank(); + + // NOTE: END SETUP FOR TESTING + + // Calculate actual amount received + uint256 balanceAfter = tokenOut == address(0) + ? order.receiver.balance + : IERC20(tokenOut).balanceOf(order.receiver); + + amountOut = balanceAfter - balanceBefore; } } @@ -262,9 +299,6 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils { // Fork will be created in individual tests to allow different fork blocks } - // Allow test contract to receive ETH - receive() external payable {} - function testDecodeParams() public { // Fork to ensure consistent setup vm.createSelectFork(vm.rpcUrl("mainnet"), 22667985); @@ -542,7 +576,286 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils { // Aggregate Order Tests function testAggregateOrder() public { - vm.skip(true); + // Fork at a suitable block for aggregate order testing + vm.createSelectFork(vm.rpcUrl("mainnet"), 21370890); + + // Deploy Bebop executor harness that uses vm.prank + bebopExecutor = + new BebopExecutorHarness(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); + + // Store the initial ETH balance (dust from forked state) + uint256 initialExecutorBalance = address(bebopExecutor).balance; + + // Create test data from real mainnet transaction + // https://etherscan.io/tx/0xec88410136c287280da87d0a37c1cb745f320406ca3ae55c678dec11996c1b1c + address originalTakerAddress = + 0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6; + + // Create the 2D arrays for tokens and amounts + address[][] memory takerTokens = new address[][](2); + takerTokens[0] = new address[](1); + takerTokens[0][0] = WETH_ADDR; // WETH for first maker + takerTokens[1] = new address[](1); + takerTokens[1][0] = WETH_ADDR; // WETH for second maker + + address[][] memory makerTokens = new address[][](2); + makerTokens[0] = new address[](1); + makerTokens[0][0] = USDC_ADDR; // USDC from first maker + makerTokens[1] = new address[](1); + makerTokens[1][0] = USDC_ADDR; // USDC from second maker + + uint256[][] memory takerAmounts = new uint256[][](2); + takerAmounts[0] = new uint256[](1); + takerAmounts[0][0] = 5812106401997138; // First maker takes ~0.0058 ETH + takerAmounts[1] = new uint256[](1); + takerAmounts[1][0] = 4037893598002862; // Second maker takes ~0.0040 ETH + + uint256[][] memory makerAmounts = new uint256[][](2); + makerAmounts[0] = new uint256[](1); + makerAmounts[0][0] = 10607211; // First maker gives ~10.6 USDC + makerAmounts[1] = new uint256[](1); + makerAmounts[1][0] = 7362350; // Second maker gives ~7.36 USDC + + // Create makers array + address[] memory makerAddresses = new address[](2); + makerAddresses[0] = 0x67336Cec42645F55059EfF241Cb02eA5cC52fF86; + makerAddresses[1] = 0xBF19CbF0256f19f39A016a86Ff3551ecC6f2aAFE; + + // Create maker nonces array + uint256[] memory makerNonces = new uint256[](2); + makerNonces[0] = 1746367197308; + makerNonces[1] = 15460096; + + // Create the aggregate order + IBebopSettlement.Aggregate memory order = IBebopSettlement.Aggregate({ + expiry: 1746367285, + taker_address: originalTakerAddress, + maker_addresses: makerAddresses, + maker_nonces: makerNonces, + taker_tokens: takerTokens, + maker_tokens: makerTokens, + taker_amounts: takerAmounts, + maker_amounts: makerAmounts, + receiver: originalTakerAddress, + commands: hex"00040004", + flags: 95769172144825922628485191511070792431742484643425438763224908097896054784000 + }); + + // Total amounts + uint256 totalTakerAmount = takerAmounts[0][0] + takerAmounts[1][0]; // 0.00985 ETH total + uint256 totalMakerAmount = makerAmounts[0][0] + makerAmounts[1][0]; // 17.969561 USDC total + + // Fund makers with USDC and approve settlement + deal(USDC_ADDR, makerAddresses[0], makerAmounts[0][0]); + deal(USDC_ADDR, makerAddresses[1], makerAmounts[1][0]); + + vm.prank(makerAddresses[0]); + USDC.approve(BEBOP_SETTLEMENT, makerAmounts[0][0]); + + vm.prank(makerAddresses[1]); + USDC.approve(BEBOP_SETTLEMENT, makerAmounts[1][0]); + + // ETH will be sent directly with the swap call + // Fund the test contract with ETH to send with the swap + vm.deal(address(this), totalTakerAmount); + + // Record initial balances + uint256 usdcBefore = USDC.balanceOf(originalTakerAddress); + + // Create maker signatures + IBebopSettlement.MakerSignature[] memory signatures = + new IBebopSettlement.MakerSignature[](2); + signatures[0] = IBebopSettlement.MakerSignature({ + signatureBytes: hex"d5abb425f9bac1f44d48705f41a8ab9cae207517be8553d2c03b06a88995f2f351ab8ce7627a87048178d539dd64fd2380245531a0c8e43fdc614652b1f32fc71c", + flags: 0 // ETH_SIGN + }); + signatures[1] = IBebopSettlement.MakerSignature({ + signatureBytes: hex"f38c698e48a3eac48f184bc324fef0b135ee13705ab38cc0bbf5a792f21002f051e445b9e7d57cf24c35e17629ea35b3263591c4abf8ca87ffa44b41301b89c41b", + flags: 0 // ETH_SIGN + }); + + // Encode order and signatures + bytes memory quoteData = abi.encode(order); + bytes memory makerSignaturesData = abi.encode(signatures); + + // Create packed params for executor with native ETH as input + bytes memory params = abi.encodePacked( + address(0), // tokenIn: native ETH + USDC_ADDR, // tokenOut + uint8(RestrictTransferFrom.TransferType.Transfer), + uint8(BebopExecutor.OrderType.Aggregate), + uint256(0), // filledTakerAmount: 0 for full fill + uint32(quoteData.length), + quoteData, + uint32(makerSignaturesData.length), + makerSignaturesData, + uint8(0) // approvalNeeded: false for native ETH + ); + + // Execute the aggregate swap with ETH value + uint256 amountOut = bebopExecutor.swap{value: totalTakerAmount}( + totalTakerAmount, params + ); + + // Verify results + assertEq(amountOut, totalMakerAmount, "Incorrect amount out"); + assertEq( + USDC.balanceOf(originalTakerAddress) - usdcBefore, + totalMakerAmount, + "USDC balance mismatch" + ); + assertEq( + USDC.balanceOf(address(bebopExecutor)), 0, "USDC left in executor" + ); + assertEq( + address(bebopExecutor).balance, + initialExecutorBalance, + "ETH left in executor should match initial dust amount" + ); + } + + function testAggregateOrder_PartialFill() public { + // Fork at a suitable block for aggregate order testing + vm.createSelectFork(vm.rpcUrl("mainnet"), 21370890); + + // Deploy Bebop executor harness that uses vm.prank + bebopExecutor = + new BebopExecutorHarness(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); + + // Store the initial ETH balance (dust from forked state) + uint256 initialExecutorBalance = address(bebopExecutor).balance; + + // Same aggregate order as before, but with partial fill + address originalTakerAddress = + 0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6; + + // Create the 2D arrays for tokens and amounts + address[][] memory takerTokens = new address[][](2); + takerTokens[0] = new address[](1); + takerTokens[0][0] = WETH_ADDR; + takerTokens[1] = new address[](1); + takerTokens[1][0] = WETH_ADDR; + + 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 takerAmounts = new uint256[][](2); + takerAmounts[0] = new uint256[](1); + takerAmounts[0][0] = 5812106401997138; + takerAmounts[1] = new uint256[](1); + takerAmounts[1][0] = 4037893598002862; + + uint256[][] memory makerAmounts = new uint256[][](2); + makerAmounts[0] = new uint256[](1); + makerAmounts[0][0] = 10607211; + makerAmounts[1] = new uint256[](1); + makerAmounts[1][0] = 7362350; + + // Create makers array + address[] memory makerAddresses = new address[](2); + makerAddresses[0] = 0x67336Cec42645F55059EfF241Cb02eA5cC52fF86; + makerAddresses[1] = 0xBF19CbF0256f19f39A016a86Ff3551ecC6f2aAFE; + + // Create maker nonces array + uint256[] memory makerNonces = new uint256[](2); + makerNonces[0] = 1746367197308; + makerNonces[1] = 15460096; + + // Create the aggregate order + IBebopSettlement.Aggregate memory order = IBebopSettlement.Aggregate({ + expiry: 1746367285, + taker_address: originalTakerAddress, + maker_addresses: makerAddresses, + maker_nonces: makerNonces, + taker_tokens: takerTokens, + maker_tokens: makerTokens, + taker_amounts: takerAmounts, + maker_amounts: makerAmounts, + receiver: originalTakerAddress, + commands: hex"00040004", + flags: 95769172144825922628485191511070792431742484643425438763224908097896054784000 + }); + + // Total amounts + uint256 totalTakerAmount = takerAmounts[0][0] + takerAmounts[1][0]; + uint256 totalMakerAmount = makerAmounts[0][0] + makerAmounts[1][0]; + + // We'll do a 50% partial fill + uint256 partialFillAmount = totalTakerAmount / 2; + uint256 expectedPartialOutput = totalMakerAmount / 2; + + // Fund makers with FULL amounts (they need enough for any partial fill) + deal(USDC_ADDR, makerAddresses[0], makerAmounts[0][0]); + deal(USDC_ADDR, makerAddresses[1], makerAmounts[1][0]); + + vm.prank(makerAddresses[0]); + USDC.approve(BEBOP_SETTLEMENT, makerAmounts[0][0]); + + vm.prank(makerAddresses[1]); + USDC.approve(BEBOP_SETTLEMENT, makerAmounts[1][0]); + + // ETH will be sent directly with the swap call + // Fund the test contract with ETH to send with the swap + vm.deal(address(this), partialFillAmount); + + // Record initial balances + uint256 usdcBefore = USDC.balanceOf(originalTakerAddress); + + // Create maker signatures + IBebopSettlement.MakerSignature[] memory signatures = + new IBebopSettlement.MakerSignature[](2); + signatures[0] = IBebopSettlement.MakerSignature({ + signatureBytes: hex"d5abb425f9bac1f44d48705f41a8ab9cae207517be8553d2c03b06a88995f2f351ab8ce7627a87048178d539dd64fd2380245531a0c8e43fdc614652b1f32fc71c", + flags: 0 + }); + signatures[1] = IBebopSettlement.MakerSignature({ + signatureBytes: hex"f38c698e48a3eac48f184bc324fef0b135ee13705ab38cc0bbf5a792f21002f051e445b9e7d57cf24c35e17629ea35b3263591c4abf8ca87ffa44b41301b89c41b", + flags: 0 + }); + + // Encode order and signatures + bytes memory quoteData = abi.encode(order); + bytes memory makerSignaturesData = abi.encode(signatures); + + // Create packed params for executor with partial fill amount + bytes memory params = abi.encodePacked( + address(0), // tokenIn: native ETH + USDC_ADDR, + uint8(RestrictTransferFrom.TransferType.Transfer), + uint8(BebopExecutor.OrderType.Aggregate), + partialFillAmount, // Specify partial fill amount + uint32(quoteData.length), + quoteData, + uint32(makerSignaturesData.length), + makerSignaturesData, + uint8(0) // approvalNeeded: false for native ETH + ); + + // Execute the partial aggregate swap with ETH value + uint256 amountOut = bebopExecutor.swap{value: partialFillAmount}( + partialFillAmount, params + ); + + // Verify results - should be proportional to the partial fill + assertEq( + amountOut, expectedPartialOutput, "Incorrect partial amount out" + ); + assertEq( + USDC.balanceOf(originalTakerAddress) - usdcBefore, + expectedPartialOutput, + "USDC balance mismatch for partial fill" + ); + assertEq( + USDC.balanceOf(address(bebopExecutor)), 0, "USDC left in executor" + ); + assertEq( + address(bebopExecutor).balance, + initialExecutorBalance, + "ETH left in executor should match initial dust amount" + ); } function testInvalidDataLength() public { @@ -599,4 +912,114 @@ contract BebopExecutorTest is Constants, Permit2TestHelper, TestUtils { vm.expectRevert(BebopExecutor.BebopExecutor__InvalidDataLength.selector); bebopExecutor.decodeParams(tooShortParams); } + + // Integration tests + function testSwapSingleIntegration() public { + // Fork at the right block first + vm.createSelectFork(vm.rpcUrl("mainnet"), 22667985); + + // Deploy Bebop executor harness + bebopExecutor = + new BebopExecutorHarness(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); + + // Load encoded data from test_encode_bebop_single (USDC → ONDO swap) + bytes memory protocolData = + loadCallDataFromFile("test_encode_bebop_single"); + + // Deal 200 USDC to the executor + uint256 amountIn = 200000000; // 200 USDC + deal(USDC_ADDR, address(bebopExecutor), amountIn); + + // Fund the maker with ONDO and approve settlement + address maker = 0xCe79b081c0c924cb67848723ed3057234d10FC6b; + uint256 expectedAmountOut = 237212396774431060000; // 237.21 ONDO + deal(ONDO_ADDR, maker, expectedAmountOut); + vm.prank(maker); + ONDO.approve(BEBOP_SETTLEMENT, expectedAmountOut); + + // Record receiver's initial ONDO balance + address receiver = 0xc5564C13A157E6240659fb81882A28091add8670; + uint256 ondoBefore = ONDO.balanceOf(receiver); + + // Execute the swap + uint256 amountOut = bebopExecutor.swap(amountIn, protocolData); + + // Verify results + assertEq(amountOut, expectedAmountOut, "Incorrect amount out"); + assertEq( + ONDO.balanceOf(receiver) - ondoBefore, + 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 testSwapAggregateIntegration() public { + // Fork at a suitable block for aggregate order testing + vm.createSelectFork(vm.rpcUrl("mainnet"), 21370890); + + // Deploy Bebop executor harness + bebopExecutor = + new BebopExecutorHarness(BEBOP_SETTLEMENT, PERMIT2_ADDRESS); + + // Store the initial ETH balance (dust from forked state) + uint256 initialExecutorBalance = address(bebopExecutor).balance; + + // Based on real transaction: https://etherscan.io/tx/0xec88410136c287280da87d0a37c1cb745f320406ca3ae55c678dec11996c1b1c + address orderTaker = 0x7078B12Ca5B294d95e9aC16D90B7D38238d8F4E6; // This is both taker and receiver in the order + uint256 ethAmount = 9850000000000000; // 0.00985 WETH + uint256 expAmountOut = 17969561; // 17.969561 USDC expected output + + // Fund the two makers from the real transaction with USDC + address maker1 = 0x67336Cec42645F55059EfF241Cb02eA5cC52fF86; + address maker2 = 0xBF19CbF0256f19f39A016a86Ff3551ecC6f2aAFE; + + deal(USDC_ADDR, maker1, 10607211); // Maker 1 provides 10.607211 USDC + deal(USDC_ADDR, maker2, 7362350); // Maker 2 provides 7.362350 USDC + + // Makers approve settlement contract + vm.prank(maker1); + IERC20(USDC_ADDR).approve(BEBOP_SETTLEMENT, type(uint256).max); + vm.prank(maker2); + IERC20(USDC_ADDR).approve(BEBOP_SETTLEMENT, type(uint256).max); + + // Fund ALICE with ETH as it will send the transaction + vm.deal(ALICE, ethAmount); + vm.startPrank(ALICE); + + // Load encoded data from test_encode_bebop_aggregate (ETH → USDC multi-maker swap) + bytes memory protocolData = + loadCallDataFromFile("test_encode_bebop_aggregate"); + + // Record initial USDC balance + uint256 usdcBefore = IERC20(USDC_ADDR).balanceOf(orderTaker); + + // Execute the swap with native ETH + uint256 amountOut = + bebopExecutor.swap{value: ethAmount}(ethAmount, protocolData); + + // Verify results + assertEq(amountOut, expAmountOut, "Incorrect amount out"); + assertEq( + IERC20(USDC_ADDR).balanceOf(orderTaker) - usdcBefore, + expAmountOut, + "USDC balance mismatch" + ); + assertEq( + IERC20(USDC_ADDR).balanceOf(address(bebopExecutor)), + 0, + "USDC left in executor" + ); + assertEq( + address(bebopExecutor).balance, + initialExecutorBalance, + "ETH left in executor should match initial dust amount" + ); + vm.stopPrank(); + } } diff --git a/src/encoding/evm/swap_encoder/swap_encoders.rs b/src/encoding/evm/swap_encoder/swap_encoders.rs index 0c801f6..cdc0be2 100644 --- a/src/encoding/evm/swap_encoder/swap_encoders.rs +++ b/src/encoding/evm/swap_encoder/swap_encoders.rs @@ -2298,7 +2298,7 @@ mod tests { ..Default::default() }; - let token_in = Bytes::from("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"); // WETH + let token_in = Bytes::from(Address::ZERO.as_slice()); // Native ETH let token_out = Bytes::from("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"); // USDC let swap = Swap { component: bebop_component, @@ -2374,7 +2374,7 @@ mod tests { let expected_hex = format!( "{}{}{}{}{}{}{}{}{}{}", // token in - "c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "0000000000000000000000000000000000000000", // token out "a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // transfer type Transfer @@ -2392,7 +2392,7 @@ mod tests { // abi-encoded maker signatures &encode(&encoded_maker_sigs), // approval needed - "01" + "00" ); assert_eq!(hex_swap, expected_hex);