From 4ba59192fcfe60d6d4f95b9540a2a7d4da202952 Mon Sep 17 00:00:00 2001 From: TAMARA LIPOWSKI Date: Fri, 11 Jul 2025 17:05:45 -0400 Subject: [PATCH] feat: add testExecuteIntegration - Needed to change the integration test setup to use two USV3 pools instead of one V3 and V2, since the V2 pool was taking too much fees for the order to be fulfilled. - Also needed to change the fork block to make this test work, which meant also needing to update the data for the existing testExecute. --- foundry/test/Constants.sol | 1 + foundry/test/assets/calldata.txt | 2 +- foundry/test/uniswap_x/UniswapXFiller.t.sol | 68 +++++++++++---------- tests/uniswap_x_integration_tests.rs | 12 +++- 4 files changed, 47 insertions(+), 36 deletions(-) diff --git a/foundry/test/Constants.sol b/foundry/test/Constants.sol index cb81d58..c2ca63d 100644 --- a/foundry/test/Constants.sol +++ b/foundry/test/Constants.sol @@ -77,6 +77,7 @@ contract Constants is Test, BaseConstants { // Uniswap v3 address DAI_WETH_USV3 = 0xC2e9F25Be6257c210d7Adf0D4Cd6E3E881ba25f8; + address DAI_USDT_USV3 = 0x48DA0965ab2d2cbf1C17C09cFB5Cbe67Ad5B1406; address USDC_WETH_USV3 = 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640; // 0.05% fee address USDC_WETH_USV3_2 = 0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8; // 0.3% fee diff --git a/foundry/test/assets/calldata.txt b/foundry/test/assets/calldata.txt index 1bb2e40..730de23 100644 --- a/foundry/test/assets/calldata.txt +++ b/foundry/test/assets/calldata.txt @@ -33,4 +33,4 @@ test_encode_balancer_v3:7bc3485026ac48b6cf9baf0a377477fff5703af8c71ea051a5f82c67 test_single_encoding_strategy_balancer_v3:5c4b639c0000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000097ffedb80d4b2ca6105a07a4d90eb739c45a66600000000000000000000000030881baa943777f92dc934d53d3bfdf33382cab300000000000000000000000000000000000000000000000000000000000003e800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000006503a6a84cd762d9707a21605b548aaab891562aab097ffedb80d4b2ca6105a07a4d90eb739c45a66630881baa943777f92dc934d53d3bfdf33382cab3f028ac624074d6793c36dc8a06ecec0f5a39a71800cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000000000000000000000000000000000 test_uniswap_v3_balancer_v3:e21dd0d3000000000000000000000000000000000000000000000000002386f26fc10000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000004a220e6096b25eadb88358cb44068a324825467500000000000000000000000000000000000000000000000000000000018f61ec00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d200692e234dae75c793f67a35089c9d99245e1c58470bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc22260fac5e5542a773aa44fbcfedf7c193bc2c599000bb83ede3eca2a72b3aecc820e955b36f38437d01395cbcdf9626bc03e24f779434178a73a0b4bad62ed0000006503a6a84cd762d9707a21605b548aaab891562aab2260fac5e5542a773aa44fbcfedf7c193bc2c5994a220e6096b25eadb88358cb44068a3248254675571bea0e99e139cd0b6b7d9352ca872dfe0d72dd01cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc20000000000000000000000000000 test_single_swap_strategy_encoder:30ace1b10000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006d70b85442ed96492800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000006880f27700000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ede3eca2a72b3aecc820e955b36f38437d013950000000000000000000000000000000000000000000000000000000068596c7f00000000000000000000000000000000000000000000000000000000000001e0000000000000000000000000000000000000000000000000000000000000026000000000000000000000000000000000000000000000000000000000000000411d60a13b5e993ef8088cb2cb7e16281f47fbc329bd0ec2a48165e7898542a7ed12fe7ffdec713b6d94e99ddf0a384674617b6190b8534491d525ecb090c8e4881c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2a478c2975ab1ea89e8196811f51a7b7ade33eb11cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc200000000000000000000000000000000 -test_sequential_swap_usx:0101e21dd0d300000000000000000000000000000000000000000000006c6b935b8bbd4000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000769cfd80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d9da78b6a5bedca287aa5d49613ba36b90c15c40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000bf00692e234dae75c793f67a35089c9d99245e1c58470b6b175474e89094c44da98b954eedeac495271d0fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000643041cbd36888becc7bbcbc0045e3b1f144466f5f5777d92f208679db4b9778590fa3cab3ac9e2168010000525615deb798bb3e4dfa0139dfa1b3d433cc23b72fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb483041cbd36888becc7bbcbc0045e3b1f144466f5f6d9da78b6a5bedca287aa5d49613ba36b90c15c4010200 +test_sequential_swap_usx:0101e21dd0d300000000000000000000000000000000000000000000006c6b935b8bbd4000000000000000000000000000006b175474e89094c44da98b954eedeac495271d0f000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000769cfd80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006d9da78b6a5bedca287aa5d49613ba36b90c15c40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d600692e234dae75c793f67a35089c9d99245e1c58470b6b175474e89094c44da98b954eedeac495271d0fa0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000643ede3eca2a72b3aecc820e955b36f38437d013955777d92f208679db4b9778590fa3cab3ac9e2168010000692e234dae75c793f67a35089c9d99245e1c58470ba0b86991c6218b36c1d19d4a2e9eb0ce3606eb48dac17f958d2ee523a2206206994597c13d831ec70000646d9da78b6a5bedca287aa5d49613ba36b90c15c43416cf6c708da44db2624d63ea0aaef7113527c6010100000000000000000000 diff --git a/foundry/test/uniswap_x/UniswapXFiller.t.sol b/foundry/test/uniswap_x/UniswapXFiller.t.sol index b473277..6522c84 100644 --- a/foundry/test/uniswap_x/UniswapXFiller.t.sol +++ b/foundry/test/uniswap_x/UniswapXFiller.t.sol @@ -6,7 +6,7 @@ import "@src/uniswap_x/UniswapXFiller.sol"; import "../TychoRouterTestSetup.sol"; contract UniswapXFillerTest is Test, TychoRouterTestSetup { - address EXECUTOR = makeAddr("executor"); + address EXECUTOR = address(0xCe79b081c0c924cb67848723ed3057234d10FC6b); address REACTOR = address(0x00000011F84B9aa48e5f8aA8B9897600006289Be); UniswapXFiller filler; @@ -18,7 +18,7 @@ contract UniswapXFillerTest is Test, TychoRouterTestSetup { ); function getForkBlock() public pure override returns (uint256) { - return 22788691; + return 22880493; } function fillerSetup() public { @@ -116,46 +116,49 @@ contract UniswapXFillerTest is Test, TychoRouterTestSetup { assertGe(IERC20(DAI_ADDR).balanceOf(BOB), amountOut); } - function testCallbackIntegration() public { + function testExecuteIntegration() public { fillerSetup(); - deal(DAI_ADDR, address(filler), 2000 ether); - uint256 amountOut = 1994835180; - ResolvedOrder[] memory orders = new ResolvedOrder[](1); - OutputToken[] memory outputs = new OutputToken[](1); + // Set to time with no more exclusivity penalty for not being exclusive filler + vm.warp(1752050415); - outputs[0] = - OutputToken({token: address(USDT_ADDR), amount: 0, recipient: BOB}); - // Irrelevant fields for this test - we only need token output - // info for the sake of testing. - orders[0] = ResolvedOrder({ - info: OrderInfo({ - reactor: address(0), - swapper: address(0), - nonce: 0, - deadline: 0, - additionalValidationContract: address(0), - additionalValidationData: "" - }), - input: InputToken({token: address(DAI_ADDR), amount: 0, maxAmount: 0}), - outputs: outputs, - sig: "", - hash: "" + deal( + DAI_ADDR, + address(0xD213e6F6dCB2DBaC03FA28b893F6dA1BD822e852), + 2000 ether + ); + + uint256 amountIn = 2000000000000000000000; + + vm.startPrank(address(0xD213e6F6dCB2DBaC03FA28b893F6dA1BD822e852)); + // Approve Permit2 + IERC20(DAI_ADDR).approve( + address(0x000000000022D473030F116dDEE9F6B43aC78BA3), amountIn + ); + vm.stopPrank(); + + // Tx 0x005d7b150017ba1b59d2f99395ccae7bda9b739938ade4e509817e32760aaf9d + // Calldata generated using rust test `test_sequential_swap_usx` + + SignedOrder memory order = SignedOrder({ + order: hex"000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001000000000000000000000000004449cd34d1eb1fedcf02a1be3834ffde8e6a61800000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000006c6b935b8bbd40000000000000000000000000000000000000000000000000006c6b935b8bbd40000000000000000000000000000000000000000000000000000000000000000001e00000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000011f84b9aa48e5f8aa8b9897600006289be000000000000000000000000d213e6f6dcb2dbac03fa28b893f6da1bd822e8520468320351debb1ddbfb032a239d699e3d54e3ce2b6e1037cd836a784c80b60100000000000000000000000000000000000000000000000000000000686e2bf9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec70000000000000000000000000000000000000000000000000000000076f9f4870000000000000000000000000000000000000000000000000000000076566300000000000000000000000000d213e6f6dcb2dbac03fa28b893f6da1bd822e85200000000000000000000000000000000000000000000000000000000686e2aee00000000000000000000000000000000000000000000000000000000686e2b2a000000000000000000000000ce79b081c0c924cb67848723ed3057234d10fc6b0000000000000000000000000000000000000000000000000000000000000064000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000007727b5f40000000000000000000000000000000000000000000000000000000000000041a2d261cd4c8930428260f18b55e3036024bac68d58cb2ee6161e6395b0984b827104158713d44ddc4e14d852b48d93d95a4e60b8d5be1ef431c1e82d2f76a4111b00000000000000000000000000000000000000000000000000000000000000", + sig: hex"f4cc5734820e4ee08519045c83a25b75687756053b3d6c0fda2141380dfa6ef17b40f64d9279f237e96982c6ba53a202e01a4358fd66e027c9bdf200d5626f441c" }); + bytes memory callbackData = loadCallDataFromFile("test_sequential_swap_usx"); - vm.startPrank(REACTOR); - filler.reactorCallback(orders, callbackData); + vm.startPrank(EXECUTOR); + filler.execute(order, callbackData); vm.stopPrank(); - - // Check that the funds are in the filler at the end of the function call - uint256 finalBalance = IERC20(USDT_ADDR).balanceOf(address(filler)); - assertGe(finalBalance, amountOut); } function testExecute() public { fillerSetup(); + + // Overwrite block so signature doesn't expire. + vm.rollFork(22788691); + // tx: 0x5b602b7d0a37e241bd032a907b9ddf314e9f2fc2104fd91cb55bdb3d8dfe4e9c // 0.2 WBTC -> USDC SignedOrder memory order = SignedOrder({ @@ -200,11 +203,12 @@ contract UniswapXFillerTest is Test, TychoRouterTestSetup { vm.stopPrank(); // This is a hack because the tx we are trying to replicate returns a looooot more USDC than what the uni v2 pool does at this point - // 5113180081 is the difference and 54068100 is the fee - deal(USDC_ADDR, address(filler), 5113180081 + 54068100); + // 21613301393 is the difference and 54068100 is the fee + deal(USDC_ADDR, address(filler), 21613301393 + 54068100); vm.startPrank(EXECUTOR); filler.execute(order, callbackData); + console.logUint(IERC20(USDC_ADDR).balanceOf(address(filler))); vm.stopPrank(); } diff --git a/tests/uniswap_x_integration_tests.rs b/tests/uniswap_x_integration_tests.rs index 80c955a..5200578 100644 --- a/tests/uniswap_x_integration_tests.rs +++ b/tests/uniswap_x_integration_tests.rs @@ -23,7 +23,7 @@ fn test_sequential_swap_usx() { // Replicates real uniswap X order settled in tx: // 0x005d7b150017ba1b59d2f99395ccae7bda9b739938ade4e509817e32760aaf9d // Performs a sequential - // swap from DAI to USDT though USDC using USV3 and USV2 pools + // swap from DAI to USDT though USDC using USV3 pools // // DAI ───(USV3)──> USDC ───(USV2)──> USDT // Creates all the calldata needed for the uniswap X callbackData @@ -54,8 +54,14 @@ fn test_sequential_swap_usx() { }; let swap_usdc_usdt = Swap { component: ProtocolComponent { - id: "0x3041CbD36888bECc7bbCBc0045E3B1f144466f5f".to_string(), - protocol_system: "uniswap_v2".to_string(), + id: "0x3416cF6C708Da44DB2624D63ea0AAef7113527C6".to_string(), + protocol_system: "uniswap_v3".to_string(), + static_attributes: { + let mut attrs = HashMap::new(); + attrs + .insert("fee".to_string(), Bytes::from(BigInt::from(100).to_signed_bytes_be())); + attrs + }, ..Default::default() }, token_in: usdc.clone(),