diff --git a/src/encoding/evm/mod.rs b/src/encoding/evm/mod.rs index 55557f3..8b2d01f 100644 --- a/src/encoding/evm/mod.rs +++ b/src/encoding/evm/mod.rs @@ -3,4 +3,4 @@ mod constants; pub mod strategy_encoder; mod swap_encoder; pub mod tycho_encoder; -mod utils; +pub mod utils; diff --git a/src/encoding/evm/strategy_encoder/strategy_encoders.rs b/src/encoding/evm/strategy_encoder/strategy_encoders.rs index fa2b211..01959f0 100644 --- a/src/encoding/evm/strategy_encoder/strategy_encoders.rs +++ b/src/encoding/evm/strategy_encoder/strategy_encoders.rs @@ -261,7 +261,10 @@ impl SplitSwapStrategyEncoder { impl EVMStrategyEncoder for SplitSwapStrategyEncoder {} impl StrategyEncoder for SplitSwapStrategyEncoder { - fn encode_strategy(&self, solution: Solution) -> Result<(Vec, Bytes), EncodingError> { + fn encode_strategy( + &self, + solution: Solution, + ) -> Result<(Vec, Bytes, Option), EncodingError> { self.validate_split_percentages(&solution.swaps)?; self.validate_swap_path( &solution.swaps, @@ -395,7 +398,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder { .abi_encode(); let contract_interaction = encode_input(&self.selector, method_calldata); - Ok((contract_interaction, solution.router_address)) + Ok((contract_interaction, solution.router_address, None)) } fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box> { @@ -425,7 +428,10 @@ impl ExecutorStrategyEncoder { } impl EVMStrategyEncoder for ExecutorStrategyEncoder {} impl StrategyEncoder for ExecutorStrategyEncoder { - fn encode_strategy(&self, solution: Solution) -> Result<(Vec, Bytes), EncodingError> { + fn encode_strategy( + &self, + solution: Solution, + ) -> Result<(Vec, Bytes, Option), EncodingError> { let swap = solution .swaps .first() @@ -449,7 +455,15 @@ impl StrategyEncoder for ExecutorStrategyEncoder { let executor_address = Bytes::from_str(swap_encoder.executor_address()) .map_err(|_| EncodingError::FatalError("Invalid executor address".to_string()))?; - Ok((protocol_data, executor_address)) + Ok(( + protocol_data, + executor_address, + Some( + swap_encoder + .executor_selector() + .to_string(), + ), + )) } fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box> { @@ -531,7 +545,7 @@ mod tests { native_action: None, }; - let (protocol_data, executor_address) = encoder + let (protocol_data, executor_address, selector) = encoder .encode_strategy(solution) .unwrap(); let hex_protocol_data = encode(&protocol_data); @@ -552,8 +566,8 @@ mod tests { "00", )) ); + assert_eq!(selector, Some("swap(uint256,bytes)".to_string())); } - #[rstest] #[case::no_check_no_slippage( None, @@ -622,7 +636,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)); @@ -723,7 +737,7 @@ mod tests { ..Default::default() }; - let (calldata, _) = encoder + let (calldata, _, _) = encoder .encode_strategy(solution) .unwrap(); @@ -771,7 +785,7 @@ mod tests { ..Default::default() }; - let (calldata, _) = encoder + let (calldata, _, _) = encoder .encode_strategy(solution) .unwrap(); @@ -859,7 +873,7 @@ mod tests { ..Default::default() }; - let (calldata, _) = encoder + let (calldata, _, _) = encoder .encode_strategy(solution) .unwrap(); diff --git a/src/encoding/evm/tycho_encoder.rs b/src/encoding/evm/tycho_encoder.rs index 6e66755..bc52fca 100644 --- a/src/encoding/evm/tycho_encoder.rs +++ b/src/encoding/evm/tycho_encoder.rs @@ -104,7 +104,7 @@ impl TychoEncoder for EVMTychoEncoder { let strategy = self .strategy_registry .get_encoder(solution)?; - let (contract_interaction, target_address) = + let (contract_interaction, target_address, selector) = strategy.encode_strategy(solution.clone())?; let value = match solution.native_action.as_ref() { @@ -116,6 +116,7 @@ impl TychoEncoder for EVMTychoEncoder { value, data: contract_interaction, to: target_address, + selector, }); } Ok(transactions) @@ -170,12 +171,16 @@ mod tests { struct MockStrategy; impl StrategyEncoder for MockStrategy { - fn encode_strategy(&self, _solution: Solution) -> Result<(Vec, Bytes), EncodingError> { + fn encode_strategy( + &self, + _solution: Solution, + ) -> Result<(Vec, Bytes, Option), EncodingError> { Ok(( Bytes::from_str("0x1234") .unwrap() .to_vec(), Bytes::from_str("0xabcd").unwrap(), + None, )) } diff --git a/src/encoding/models.rs b/src/encoding/models.rs index 4853fcc..f7dd483 100644 --- a/src/encoding/models.rs +++ b/src/encoding/models.rs @@ -95,11 +95,13 @@ impl Swap { /// * `to`: Address of the contract to call with the calldata /// * `value`: Native token value to be sent with the transaction. /// * `data`: Encoded calldata for the transaction. +/// * `selector`: Only relevant for direct executions. The selector of the function to be called. #[derive(Clone, Debug)] pub struct Transaction { pub to: Bytes, pub value: BigUint, pub data: Vec, + pub selector: Option, } /// Represents necessary attributes for encoding an order. diff --git a/src/encoding/strategy_encoder.rs b/src/encoding/strategy_encoder.rs index 744df63..550392d 100644 --- a/src/encoding/strategy_encoder.rs +++ b/src/encoding/strategy_encoder.rs @@ -4,7 +4,10 @@ use crate::encoding::{errors::EncodingError, models::Solution, swap_encoder::Swa /// Encodes a solution using a specific strategy. pub trait StrategyEncoder { - fn encode_strategy(&self, to_encode: Solution) -> Result<(Vec, Bytes), EncodingError>; + fn encode_strategy( + &self, + to_encode: Solution, + ) -> Result<(Vec, Bytes, Option), EncodingError>; #[allow(clippy::borrowed_box)] fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box>;