From 18efe0305b763b1ea5037536cd54734b58778fd2 Mon Sep 17 00:00:00 2001 From: royvardhan Date: Mon, 24 Feb 2025 19:48:25 +0530 Subject: [PATCH] fix: usv4 integration tests and remove selector from swap/strategy encoder --- .../test/executors/UniswapV4Executor.t.sol | 12 ++--- .../evm/strategy_encoder/strategy_encoders.rs | 49 ++++++------------- .../evm/swap_encoder/swap_encoders.rs | 40 +++------------ src/encoding/evm/tycho_encoder.rs | 10 ++-- src/encoding/strategy_encoder.rs | 5 +- src/encoding/swap_encoder.rs | 3 -- 6 files changed, 30 insertions(+), 89 deletions(-) diff --git a/foundry/test/executors/UniswapV4Executor.t.sol b/foundry/test/executors/UniswapV4Executor.t.sol index 86d78fa..97c5546 100644 --- a/foundry/test/executors/UniswapV4Executor.t.sol +++ b/foundry/test/executors/UniswapV4Executor.t.sol @@ -41,7 +41,7 @@ contract UniswapV4ExecutorTest is Test, Constants { new UniswapV4ExecutorExposed(IPoolManager(poolManager)); } - function testDecodeParamsV4() public view { + function testDecodeParams() public view { bool zeroForOne = true; uint24 pool1Fee = 500; int24 tickSpacing1 = 60; @@ -86,7 +86,7 @@ contract UniswapV4ExecutorTest is Test, Constants { assertEq(decodedPools[1].tickSpacing, tickSpacing2); } - function testSingleSwapV4() public { + function testSingleSwap() public { uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); @@ -118,8 +118,7 @@ contract UniswapV4ExecutorTest is Test, Constants { // USDE -> USDT // Generated by the Tycho swap encoder - test_encode_uniswap_v4_simple_swap bytes memory protocolData = - hex"4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec701f62849f9a0b5bf2913b396098f7c7019b51a820a91dd7346dac17f958d2ee523a2206206994597c13d831ec7000064000001"; - + hex"4c9edd5852cd905f086c759e8383e09bff1e68b3dac17f958d2ee523a2206206994597c13d831ec701f62849f9a0b5bf2913b396098f7c7019b51a820adac17f958d2ee523a2206206994597c13d831ec7000064000001"; uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); uint256 usdeBalanceBeforePool = USDE.balanceOf(poolManager); @@ -135,7 +134,7 @@ contract UniswapV4ExecutorTest is Test, Constants { assertTrue(USDT.balanceOf(address(uniswapV4Exposed)) == amountOut); } - function testMultipleSwapV4() public { + function testMultipleSwap() public { // USDE -> USDT -> WBTC uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); @@ -174,8 +173,9 @@ contract UniswapV4ExecutorTest is Test, Constants { function testMultipleSwapIntegration() public { // USDE -> USDT -> WBTC // Generated by the Tycho swap encoder - test_encode_uniswap_v4_sequential_swap + bytes memory protocolData = - hex"4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c59901f62849f9a0b5bf2913b396098f7c7019b51a820a91dd7346dac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c"; + hex"4c9edd5852cd905f086c759e8383e09bff1e68b32260fac5e5542a773aa44fbcfedf7c193bc2c59901f62849f9a0b5bf2913b396098f7c7019b51a820adac17f958d2ee523a2206206994597c13d831ec70000640000012260fac5e5542a773aa44fbcfedf7c193bc2c599000bb800003c"; uint256 amountIn = 100 ether; deal(USDE_ADDR, address(uniswapV4Exposed), amountIn); diff --git a/src/encoding/evm/strategy_encoder/strategy_encoders.rs b/src/encoding/evm/strategy_encoder/strategy_encoders.rs index dd2989d..364648c 100644 --- a/src/encoding/evm/strategy_encoder/strategy_encoders.rs +++ b/src/encoding/evm/strategy_encoder/strategy_encoders.rs @@ -30,7 +30,6 @@ pub trait EVMStrategyEncoder: StrategyEncoder { token_out: U8, split: U24, executor_address: Bytes, - executor_selector: FixedBytes<4>, protocol_data: Vec, ) -> Vec { let mut encoded = Vec::new(); @@ -38,17 +37,10 @@ pub trait EVMStrategyEncoder: StrategyEncoder { encoded.push(token_out.to_be_bytes_vec()[0]); encoded.extend_from_slice(&split.to_be_bytes_vec()); encoded.extend(executor_address.to_vec()); - encoded.extend(executor_selector); encoded.extend(protocol_data); encoded } - /// Encodes a selector string into its 4-byte representation. - fn encode_executor_selector(&self, selector: &str) -> FixedBytes<4> { - let hash = keccak256(selector.as_bytes()); - FixedBytes::<4>::from([hash[0], hash[1], hash[2], hash[3]]) - } - /// Uses prefix-length encoding to efficient encode action data. /// /// Prefix-length encoding is a data encoding method where the beginning of a data segment @@ -114,10 +106,7 @@ impl SplitSwapStrategyEncoder { impl EVMStrategyEncoder for SplitSwapStrategyEncoder {} impl StrategyEncoder for SplitSwapStrategyEncoder { - fn encode_strategy( - &self, - solution: Solution, - ) -> Result<(Vec, Bytes, Option), EncodingError> { + fn encode_strategy(&self, solution: Solution) -> Result<(Vec, Bytes), EncodingError> { self.split_swap_validator .validate_split_percentages(&solution.swaps)?; self.split_swap_validator @@ -209,7 +198,6 @@ impl StrategyEncoder for SplitSwapStrategyEncoder { Bytes::from_str(swap_encoder.executor_address()).map_err(|_| { EncodingError::FatalError("Invalid executor address".to_string()) })?, - self.encode_executor_selector(swap_encoder.swap_selector()), grouped_protocol_data, ); swaps.push(swap_data); @@ -253,7 +241,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder { }; let contract_interaction = encode_input(&self.selector, method_calldata); - Ok((contract_interaction, solution.router_address, None)) + Ok((contract_interaction, solution.router_address)) } fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box> { @@ -283,10 +271,7 @@ impl ExecutorStrategyEncoder { } impl EVMStrategyEncoder for ExecutorStrategyEncoder {} impl StrategyEncoder for ExecutorStrategyEncoder { - fn encode_strategy( - &self, - solution: Solution, - ) -> Result<(Vec, Bytes, Option), EncodingError> { + fn encode_strategy(&self, solution: Solution) -> Result<(Vec, Bytes), EncodingError> { let grouped_swaps = group_swaps(solution.clone().swaps); let number_of_groups = grouped_swaps.len(); if number_of_groups > 1 { @@ -328,11 +313,7 @@ impl StrategyEncoder for ExecutorStrategyEncoder { let executor_address = Bytes::from_str(swap_encoder.executor_address()) .map_err(|_| EncodingError::FatalError("Invalid executor address".to_string()))?; - Ok(( - grouped_protocol_data, - executor_address, - Some(swap_encoder.swap_selector().to_string()), - )) + Ok((grouped_protocol_data, executor_address)) } fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box> { @@ -413,7 +394,7 @@ mod tests { native_action: None, }; - let (protocol_data, executor_address, selector) = encoder + let (protocol_data, executor_address) = encoder .encode_strategy(solution) .unwrap(); let hex_protocol_data = encode(&protocol_data); @@ -434,7 +415,6 @@ mod tests { "00", )) ); - assert_eq!(selector, Some("swap(uint256,bytes)".to_string())); } #[test] @@ -539,7 +519,7 @@ mod tests { ..Default::default() }; - let (protocol_data, executor_address, selector) = encoder + let (protocol_data, executor_address) = encoder .encode_strategy(solution) .unwrap(); let hex_protocol_data = encode(&protocol_data); @@ -574,7 +554,6 @@ mod tests { "0001f4" )) ); - assert_eq!(selector, Some("swap(uint256,bytes)".to_string())); } #[rstest] @@ -646,7 +625,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); let expected_min_amount_encoded = hex::encode(U256::abi_encode(&expected_min_amount)); @@ -748,7 +727,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); @@ -797,7 +776,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); @@ -886,7 +865,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); @@ -968,7 +947,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); @@ -1079,7 +1058,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); let expected_min_amount_encoded = hex::encode(U256::abi_encode(&expected_min_amount)); @@ -1171,7 +1150,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); let hex_calldata = encode(&calldata); @@ -1235,7 +1214,7 @@ mod tests { ..Default::default() }; - let (calldata, _, _) = encoder + let (calldata, _) = encoder .encode_strategy(solution) .unwrap(); diff --git a/src/encoding/evm/swap_encoder/swap_encoders.rs b/src/encoding/evm/swap_encoder/swap_encoders.rs index a0becd7..71121d1 100644 --- a/src/encoding/evm/swap_encoder/swap_encoders.rs +++ b/src/encoding/evm/swap_encoder/swap_encoders.rs @@ -24,7 +24,6 @@ use crate::encoding::{ #[derive(Clone)] pub struct UniswapV2SwapEncoder { executor_address: String, - swap_selector: String, } impl UniswapV2SwapEncoder { @@ -35,7 +34,7 @@ impl UniswapV2SwapEncoder { impl SwapEncoder for UniswapV2SwapEncoder { fn new(executor_address: String) -> Self { - Self { executor_address, swap_selector: "swap(uint256,bytes)".to_string() } + Self { executor_address } } fn encode_swap( @@ -66,10 +65,6 @@ impl SwapEncoder for UniswapV2SwapEncoder { &self.executor_address } - fn swap_selector(&self) -> &str { - &self.swap_selector - } - fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -83,7 +78,6 @@ impl SwapEncoder for UniswapV2SwapEncoder { #[derive(Clone)] pub struct UniswapV3SwapEncoder { executor_address: String, - swap_selector: String, } impl UniswapV3SwapEncoder { @@ -94,7 +88,7 @@ impl UniswapV3SwapEncoder { impl SwapEncoder for UniswapV3SwapEncoder { fn new(executor_address: String) -> Self { - Self { executor_address, swap_selector: "swap(uint256,bytes)".to_string() } + Self { executor_address } } fn encode_swap( @@ -128,9 +122,6 @@ impl SwapEncoder for UniswapV3SwapEncoder { fn executor_address(&self) -> &str { &self.executor_address } - fn swap_selector(&self) -> &str { - &self.swap_selector - } fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -145,8 +136,6 @@ impl SwapEncoder for UniswapV3SwapEncoder { #[derive(Clone)] pub struct UniswapV4SwapEncoder { executor_address: String, - swap_selector: String, - callback_selector: String, } impl UniswapV4SwapEncoder { @@ -157,11 +146,7 @@ impl UniswapV4SwapEncoder { impl SwapEncoder for UniswapV4SwapEncoder { fn new(executor_address: String) -> Self { - Self { - executor_address, - swap_selector: "swap(uint256,bytes)".to_string(), - callback_selector: "unlockCallback(bytes)".to_string(), - } + Self { executor_address } } fn encode_swap( @@ -206,7 +191,6 @@ impl SwapEncoder for UniswapV4SwapEncoder { group_token_out_address, zero_to_one, callback_executor, - encode_function_selector(&self.callback_selector), pool_params, ); @@ -217,10 +201,6 @@ impl SwapEncoder for UniswapV4SwapEncoder { &self.executor_address } - fn swap_selector(&self) -> &str { - &self.swap_selector - } - fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -230,11 +210,10 @@ impl SwapEncoder for UniswapV4SwapEncoder { /// /// # Fields /// * `executor_address` - The address of the executor contract that will perform the swap. -/// * `swap_selector` - The selector of the swap function in the executor contract. +/// * `vault_address` - The address of the vault contract that will perform the swap. #[derive(Clone)] pub struct BalancerV2SwapEncoder { executor_address: String, - swap_selector: String, vault_address: String, } @@ -242,7 +221,6 @@ impl SwapEncoder for BalancerV2SwapEncoder { fn new(executor_address: String) -> Self { Self { executor_address, - swap_selector: "swap(uint256,bytes)".to_string(), vault_address: "0xba12222222228d8ba445958a75a0704d566bf2c8".to_string(), } } @@ -277,9 +255,6 @@ impl SwapEncoder for BalancerV2SwapEncoder { fn executor_address(&self) -> &str { &self.executor_address } - fn swap_selector(&self) -> &str { - &self.swap_selector - } fn clone_box(&self) -> Box { Box::new(self.clone()) } @@ -418,7 +393,6 @@ mod tests { .encode_swap(swap, encoding_context) .unwrap(); let hex_swap = encode(&encoded_swap); - println!("{}", hex_swap); assert_eq!( hex_swap, @@ -478,6 +452,7 @@ mod tests { .encode_swap(swap, encoding_context) .unwrap(); let hex_swap = encode(&encoded_swap); + println!("{}", hex_swap); assert_eq!( hex_swap, @@ -490,8 +465,6 @@ mod tests { "01", // executor address "f62849f9a0b5bf2913b396098f7c7019b51a820a", - // callback selector for "unlockCallback(bytes)" - "91dd7346", // pool params: // - intermediary token "dac17f958d2ee523a2206206994597c13d831ec7", @@ -637,6 +610,7 @@ mod tests { let combined_hex = format!("{}{}", encode(&initial_encoded_swap), encode(&second_encoded_swap)); + println!("{}", combined_hex); assert_eq!( combined_hex, @@ -649,8 +623,6 @@ mod tests { "01", // executor address "f62849f9a0b5bf2913b396098f7c7019b51a820a", - // callback selector for "unlockCallback(bytes)" - "91dd7346", // pool params: // - intermediary token USDT "dac17f958d2ee523a2206206994597c13d831ec7", diff --git a/src/encoding/evm/tycho_encoder.rs b/src/encoding/evm/tycho_encoder.rs index cfd4375..0690674 100644 --- a/src/encoding/evm/tycho_encoder.rs +++ b/src/encoding/evm/tycho_encoder.rs @@ -105,7 +105,7 @@ impl TychoEncoder for EVMTychoEncoder { for solution in solutions.iter() { self.validate_solution(solution)?; - let (contract_interaction, target_address, selector) = self + let (contract_interaction, target_address) = self .strategy_encoder .encode_strategy(solution.clone())?; @@ -118,7 +118,7 @@ impl TychoEncoder for EVMTychoEncoder { value, data: contract_interaction, to: target_address, - selector, + selector: None, }); } Ok(transactions) @@ -152,16 +152,12 @@ mod tests { struct MockStrategy; impl StrategyEncoder for MockStrategy { - fn encode_strategy( - &self, - _solution: Solution, - ) -> Result<(Vec, Bytes, Option), EncodingError> { + fn encode_strategy(&self, _solution: Solution) -> Result<(Vec, Bytes), EncodingError> { Ok(( Bytes::from_str("0x1234") .unwrap() .to_vec(), Bytes::from_str("0xabcd").unwrap(), - None, )) } diff --git a/src/encoding/strategy_encoder.rs b/src/encoding/strategy_encoder.rs index cf049c2..b0e42fb 100644 --- a/src/encoding/strategy_encoder.rs +++ b/src/encoding/strategy_encoder.rs @@ -17,10 +17,7 @@ pub trait StrategyEncoder { /// - The encoded data as bytes /// - The address of the contract to call (router or executor) /// - Optionally, the function selector to use when calling the contract - fn encode_strategy( - &self, - solution: Solution, - ) -> Result<(Vec, Bytes, Option), EncodingError>; + fn encode_strategy(&self, solution: Solution) -> Result<(Vec, Bytes), EncodingError>; /// Retrieves the swap encoder for a specific protocol system. /// diff --git a/src/encoding/swap_encoder.rs b/src/encoding/swap_encoder.rs index d00b136..56fc724 100644 --- a/src/encoding/swap_encoder.rs +++ b/src/encoding/swap_encoder.rs @@ -32,9 +32,6 @@ pub trait SwapEncoder: Sync + Send { /// Returns the address of the protocol-specific executor contract. fn executor_address(&self) -> &str; - /// Returns the function selector used to execute the swap on the protocol. - fn swap_selector(&self) -> &str; - /// Creates a cloned instance of the swap encoder. /// /// This allows the encoder to be cloned when it is being used as a `Box`.