From a98e8d21ccd2eafeb42805acb6ce157b60374a0c Mon Sep 17 00:00:00 2001 From: Diana Carvalho Date: Mon, 22 Sep 2025 10:16:45 +0100 Subject: [PATCH 1/3] feat: Update tycho common to point to hooks feature branch Took 34 minutes Took 1 minute --- Cargo.toml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8adb195..a4b88fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,12 +11,12 @@ license = "MIT" categories = ["finance", "cryptography::cryptocurrencies"] readme = "README.md" exclude = [ - "foundry/*", - "foundry", - "tests/*", - "tests/common", - ".github/*", - ".gitmodules", + "foundry/*", + "foundry", + "tests/*", + "tests/common", + ".github/*", + ".gitmodules", ] [[bin]] From c51c6f52a5c1a7e47caab3bfa721f7c373a8229e Mon Sep 17 00:00:00 2001 From: Diana Carvalho Date: Mon, 22 Sep 2025 12:53:11 +0100 Subject: [PATCH 2/3] feat: Add historical_trade option to encoding Adding it is necessary because sometimes we use the encoding crate for historical trades for testing. This is relevant for protocols that need token approvals like Balancer v2 and Curve. For this case, we prefer to set the approval flag to always be true than checking if it's necessary using and RPC. This RPC check would be wrong because it always uses the latest block Took 30 minutes --- src/encoding/evm/encoder_builders.rs | 12 ++++++ src/encoding/evm/encoding_utils.rs | 5 ++- .../evm/strategy_encoder/strategy_encoders.rs | 23 +++++++++++ .../evm/swap_encoder/swap_encoders.rs | 39 +++++++++++++------ src/encoding/evm/tycho_encoders.rs | 6 +++ src/encoding/models.rs | 3 ++ 6 files changed, 75 insertions(+), 13 deletions(-) diff --git a/src/encoding/evm/encoder_builders.rs b/src/encoding/evm/encoder_builders.rs index b6b6497..90f641b 100644 --- a/src/encoding/evm/encoder_builders.rs +++ b/src/encoding/evm/encoder_builders.rs @@ -23,6 +23,7 @@ pub struct TychoRouterEncoderBuilder { executors_file_path: Option, router_address: Option, swapper_pk: Option, + historical_trade: bool, } impl Default for TychoRouterEncoderBuilder { @@ -39,6 +40,7 @@ impl TychoRouterEncoderBuilder { router_address: None, swapper_pk: None, user_transfer_type: None, + historical_trade: false, } } pub fn chain(mut self, chain: Chain) -> Self { @@ -65,6 +67,15 @@ impl TychoRouterEncoderBuilder { self } + /// Sets the `historical_trade` manually to true. + /// If set to true, it means that the encoded trade will be used in an historical block (as a + /// test) and not in the current one. This is relevant for checking token approvals in some + /// protocols (like Balancer v2). + pub fn historical_trade(mut self) -> Self { + self.historical_trade = true; + self + } + /// Sets the `swapper_pk` for the encoder. This is used to sign permit2 objects. This is only /// needed if you intend to get the full calldata for the transfer. We do not recommend /// using this option, you should sign and create the function calldata entirely on your @@ -115,6 +126,7 @@ impl TychoRouterEncoderBuilder { tycho_router_address, user_transfer_type, signer, + self.historical_trade, )?)) } else { Err(EncodingError::FatalError( diff --git a/src/encoding/evm/encoding_utils.rs b/src/encoding/evm/encoding_utils.rs index 1e31f2c..5b636c2 100644 --- a/src/encoding/evm/encoding_utils.rs +++ b/src/encoding/evm/encoding_utils.rs @@ -58,11 +58,12 @@ use crate::encoding::{ /// funds. /// /// # Parameters +/// - `chain_id`: Chain ID /// - `encoded_solution`: The solution already encoded by Tycho. /// - `solution`: The high-level solution including tokens, amounts, and receiver info. -/// - `token_in_already_in_router`: Whether the input token is already present in the router. -/// - `router_address`: The address of the Tycho Router contract. +/// - `user_transfer_type`: The desired transfer method. /// - `native_address`: The address used to represent the native token +/// - `signer`: Optional signer for permit2 /// /// # Returns /// A `Result` that either contains the full transaction data (to, diff --git a/src/encoding/evm/strategy_encoder/strategy_encoders.rs b/src/encoding/evm/strategy_encoder/strategy_encoders.rs index fa47be8..e0c1255 100644 --- a/src/encoding/evm/strategy_encoder/strategy_encoders.rs +++ b/src/encoding/evm/strategy_encoder/strategy_encoders.rs @@ -26,12 +26,15 @@ use crate::encoding::{ /// * `function_signature`: String, the signature for the swap function in the router contract /// * `router_address`: Address of the router to be used to execute swaps /// * `transfer_optimization`: TransferOptimization, responsible for optimizing the token transfers +/// * `historical_trade`: Whether the swap is to be done in the current block or in an historical +/// one. This is relevant for checking token approvals in some protocols (like Balancer v2). #[derive(Clone)] pub struct SingleSwapStrategyEncoder { swap_encoder_registry: SwapEncoderRegistry, function_signature: String, router_address: Bytes, transfer_optimization: TransferOptimization, + historical_trade: bool, } impl SingleSwapStrategyEncoder { @@ -40,6 +43,7 @@ impl SingleSwapStrategyEncoder { swap_encoder_registry: SwapEncoderRegistry, user_transfer_type: UserTransferType, router_address: Bytes, + historical_trade: bool, ) -> Result { let function_signature = if user_transfer_type == UserTransferType::TransferFromPermit2 { "singleSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)" @@ -57,6 +61,7 @@ impl SingleSwapStrategyEncoder { user_transfer_type, router_address, ), + historical_trade, }) } @@ -119,6 +124,7 @@ impl StrategyEncoder for SingleSwapStrategyEncoder { group_token_in: grouped_swap.token_in.clone(), group_token_out: grouped_swap.token_out.clone(), transfer_type: transfer, + historical_trade: self.historical_trade, }; let mut grouped_protocol_data: Vec> = vec![]; @@ -171,6 +177,8 @@ impl StrategyEncoder for SingleSwapStrategyEncoder { /// * `sequential_swap_validator`: SequentialSwapValidator, responsible for checking validity of /// sequential swap solutions /// * `transfer_optimization`: TransferOptimization, responsible for optimizing the token transfers +/// * `historical_trade`: Whether the swap is to be done in the current block or in an historical +/// one. This is relevant for checking token approvals in some protocols (like Balancer v2). #[derive(Clone)] pub struct SequentialSwapStrategyEncoder { swap_encoder_registry: SwapEncoderRegistry, @@ -180,6 +188,7 @@ pub struct SequentialSwapStrategyEncoder { wrapped_address: Bytes, sequential_swap_validator: SequentialSwapValidator, transfer_optimization: TransferOptimization, + historical_trade: bool, } impl SequentialSwapStrategyEncoder { @@ -188,6 +197,7 @@ impl SequentialSwapStrategyEncoder { swap_encoder_registry: SwapEncoderRegistry, user_transfer_type: UserTransferType, router_address: Bytes, + historical_trade: bool, ) -> Result { let function_signature = if user_transfer_type == UserTransferType::TransferFromPermit2 { "sequentialSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)" @@ -210,6 +220,7 @@ impl SequentialSwapStrategyEncoder { user_transfer_type, router_address, ), + historical_trade, }) } @@ -279,6 +290,7 @@ impl StrategyEncoder for SequentialSwapStrategyEncoder { group_token_in: grouped_swap.token_in.clone(), group_token_out: grouped_swap.token_out.clone(), transfer_type: transfer, + historical_trade: self.historical_trade, }; let mut grouped_protocol_data: Vec> = vec![]; @@ -336,6 +348,8 @@ impl StrategyEncoder for SequentialSwapStrategyEncoder { /// solutions /// * `router_address`: Address of the router to be used to execute swaps /// * `transfer_optimization`: TransferOptimization, responsible for optimizing the token transfers +/// * `historical_trade`: Whether the swap is to be done in the current block or in an historical +/// one. This is relevant for checking token approvals in some protocols (like Balancer v2). #[derive(Clone)] pub struct SplitSwapStrategyEncoder { swap_encoder_registry: SwapEncoderRegistry, @@ -345,6 +359,7 @@ pub struct SplitSwapStrategyEncoder { split_swap_validator: SplitSwapValidator, router_address: Bytes, transfer_optimization: TransferOptimization, + historical_trade: bool, } impl SplitSwapStrategyEncoder { @@ -353,6 +368,7 @@ impl SplitSwapStrategyEncoder { swap_encoder_registry: SwapEncoderRegistry, user_transfer_type: UserTransferType, router_address: Bytes, + historical_trade: bool, ) -> Result { let function_signature = if user_transfer_type == UserTransferType::TransferFromPermit2 { "splitSwapPermit2(uint256,address,address,uint256,bool,bool,uint256,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)" @@ -374,6 +390,7 @@ impl SplitSwapStrategyEncoder { user_transfer_type, router_address, ), + historical_trade, }) } @@ -479,6 +496,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder { group_token_in: grouped_swap.token_in.clone(), group_token_out: grouped_swap.token_out.clone(), transfer_type: transfer, + historical_trade: self.historical_trade, }; let mut grouped_protocol_data: Vec> = vec![]; @@ -591,6 +609,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFromPermit2, router_address(), + false, ) .unwrap(); let solution = Solution { @@ -651,6 +670,7 @@ mod tests { swap_encoder_registry, UserTransferType::None, router_address(), + false, ) .unwrap(); let solution = Solution { @@ -732,6 +752,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFrom, router_address(), + false, ) .unwrap(); let solution = Solution { @@ -867,6 +888,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFromPermit2, Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"), + false, ) .unwrap(); @@ -1015,6 +1037,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFrom, Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"), + false, ) .unwrap(); diff --git a/src/encoding/evm/swap_encoder/swap_encoders.rs b/src/encoding/evm/swap_encoder/swap_encoders.rs index 134a5d6..eb8375b 100644 --- a/src/encoding/evm/swap_encoder/swap_encoders.rs +++ b/src/encoding/evm/swap_encoder/swap_encoders.rs @@ -280,19 +280,20 @@ impl SwapEncoder for BalancerV2SwapEncoder { ) -> Result, EncodingError> { let token_approvals_manager = ProtocolApprovalsManager::new()?; let token = bytes_to_address(&swap.token_in)?; - let approval_needed: bool; + let mut approval_needed: bool = true; if let Some(router_address) = &encoding_context.router_address { - let tycho_router_address = bytes_to_address(router_address)?; - approval_needed = token_approvals_manager.approval_needed( - token, - tycho_router_address, - Address::from_str(&self.vault_address) - .map_err(|_| EncodingError::FatalError("Invalid vault address".to_string()))?, - )?; - } else { - approval_needed = true; - } + if !encoding_context.historical_trade { + let tycho_router_address = bytes_to_address(router_address)?; + approval_needed = token_approvals_manager.approval_needed( + token, + tycho_router_address, + Address::from_str(&self.vault_address).map_err(|_| { + EncodingError::FatalError("Invalid vault address".to_string()) + })?, + )?; + } + }; let component_id = AlloyBytes::from_str(&swap.component.id) .map_err(|_| EncodingError::FatalError("Invalid component ID".to_string()))?; @@ -1026,6 +1027,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = UniswapV2SwapEncoder::new( String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"), @@ -1081,6 +1083,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = UniswapV3SwapEncoder::new( String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"), @@ -1138,6 +1141,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::None, + historical_trade: true, }; let encoder = BalancerV2SwapEncoder::new( String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"), @@ -1207,6 +1211,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = UniswapV4SwapEncoder::new( String::from("0xF62849F9A0B5Bf2913b396098F7c7019b51A820a"), @@ -1275,6 +1280,7 @@ mod tests { // Token out is the same as the group token out group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = UniswapV4SwapEncoder::new( @@ -1318,6 +1324,7 @@ mod tests { group_token_in: usde_address.clone(), group_token_out: wbtc_address.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; // Setup - First sequence: USDE -> USDT @@ -1448,6 +1455,7 @@ mod tests { exact_out: false, router_address: Some(Bytes::default()), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = EkuboSwapEncoder::new(String::default(), Chain::Ethereum, None).unwrap(); @@ -1490,6 +1498,7 @@ mod tests { exact_out: false, router_address: Some(Bytes::default()), transfer_type: TransferType::Transfer, + historical_trade: false, }; let first_swap = SwapBuilder::new( @@ -1687,6 +1696,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::None, + historical_trade: false, }; let encoder = CurveSwapEncoder::new( String::from("0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f"), @@ -1753,6 +1763,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::None, + historical_trade: false, }; let encoder = CurveSwapEncoder::new( String::from("0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f"), @@ -1820,6 +1831,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::None, + historical_trade: false, }; let encoder = CurveSwapEncoder::new( String::from("0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f"), @@ -1888,6 +1900,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = BalancerV3SwapEncoder::new( String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"), @@ -1940,6 +1953,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = MaverickV2SwapEncoder::new( String::from("0x543778987b293C7E8Cf0722BB2e935ba6f4068D4"), @@ -2033,6 +2047,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = BebopSwapEncoder::new( @@ -2107,6 +2122,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = HashflowSwapEncoder::new( @@ -2200,6 +2216,7 @@ mod tests { group_token_in: token_in.clone(), group_token_out: token_out.clone(), transfer_type: TransferType::Transfer, + historical_trade: false, }; let encoder = HashflowSwapEncoder::new( diff --git a/src/encoding/evm/tycho_encoders.rs b/src/encoding/evm/tycho_encoders.rs index 2710d71..79632db 100644 --- a/src/encoding/evm/tycho_encoders.rs +++ b/src/encoding/evm/tycho_encoders.rs @@ -54,6 +54,7 @@ impl TychoRouterEncoder { router_address: Bytes, user_transfer_type: UserTransferType, signer: Option, + historical_trade: bool, ) -> Result { let permit2 = if user_transfer_type == UserTransferType::TransferFromPermit2 { Some(Permit2::new()?) @@ -66,18 +67,21 @@ impl TychoRouterEncoder { swap_encoder_registry.clone(), user_transfer_type.clone(), router_address.clone(), + historical_trade.clone(), )?, sequential_swap_strategy: SequentialSwapStrategyEncoder::new( chain, swap_encoder_registry.clone(), user_transfer_type.clone(), router_address.clone(), + historical_trade.clone(), )?, split_swap_strategy: SplitSwapStrategyEncoder::new( chain, swap_encoder_registry, user_transfer_type.clone(), router_address.clone(), + historical_trade, )?, router_address, permit2, @@ -331,6 +335,7 @@ impl TychoExecutorEncoder { group_token_in: grouped_swap.token_in.clone(), group_token_out: grouped_swap.token_out.clone(), transfer_type: transfer, + historical_trade: false, }; let mut grouped_protocol_data: Vec> = vec![]; let mut initial_protocol_data: Vec = vec![]; @@ -498,6 +503,7 @@ mod tests { router_address(), user_transfer_type, None, + false, ) .unwrap() } diff --git a/src/encoding/models.rs b/src/encoding/models.rs index 48b224c..b7886ba 100644 --- a/src/encoding/models.rs +++ b/src/encoding/models.rs @@ -273,6 +273,8 @@ impl PartialEq for PermitDetails { /// * `group_token_in`: Token to be used as the input for the group swap. /// * `group_token_out`: Token to be used as the output for the group swap. /// * `transfer`: Type of transfer to be performed. See `TransferType` for more details. +/// * `historical_trade`: Whether the swap is to be done in the current block or in an historical +/// one. This is relevant for checking token approvals in some protocols (like Balancer v2). #[derive(Clone, Debug)] pub struct EncodingContext { pub receiver: Bytes, @@ -281,6 +283,7 @@ pub struct EncodingContext { pub group_token_in: Bytes, pub group_token_out: Bytes, pub transfer_type: TransferType, + pub historical_trade: bool, } /// Represents the type of transfer to be performed into the pool. From e78a362894955a8b0e676bbcb189195d00815aad Mon Sep 17 00:00:00 2001 From: Diana Carvalho Date: Tue, 23 Sep 2025 09:32:46 +0100 Subject: [PATCH 3/3] feat: Pass the file contents instead of the file path for executors This is better because passing paths around might be really complex when running the code in another environments that is not local Took 30 minutes --- src/bin/tycho-encode.rs | 13 ++++++++-- src/encoding/evm/encoder_builders.rs | 26 +++++++++---------- .../evm/strategy_encoder/strategy_encoders.rs | 7 ++--- .../evm/swap_encoder/swap_encoder_registry.rs | 12 +++------ src/encoding/evm/tycho_encoders.rs | 14 +++++----- tests/common/mod.rs | 5 ++-- 6 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/bin/tycho-encode.rs b/src/bin/tycho-encode.rs index 161f7ae..d0252dc 100644 --- a/src/bin/tycho-encode.rs +++ b/src/bin/tycho-encode.rs @@ -1,9 +1,13 @@ -use std::io::{self, Read}; +use std::{ + fs, + io::{self, Read}, +}; use alloy::sol_types::SolValue; use clap::{Parser, Subcommand}; use tycho_common::{hex_bytes::Bytes, models::Chain}; use tycho_execution::encoding::{ + errors::EncodingError, evm::{ approvals::permit2::PermitSingle, encoder_builders::{TychoExecutorEncoderBuilder, TychoRouterEncoderBuilder}, @@ -83,7 +87,12 @@ fn main() -> Result<(), Box> { Commands::TychoRouter => { let mut builder = TychoRouterEncoderBuilder::new().chain(chain); if let Some(config_path) = cli.executors_file_path { - builder = builder.executors_file_path(config_path); + let executors_addresses = fs::read_to_string(&config_path).map_err(|e| { + EncodingError::FatalError(format!( + "Error reading executors file from {config_path:?}: {e}", + )) + })?; + builder = builder.executors_addresses(executors_addresses); } if let Some(router_address) = cli.router_address { builder = builder.router_address(router_address); diff --git a/src/encoding/evm/encoder_builders.rs b/src/encoding/evm/encoder_builders.rs index 90f641b..703f083 100644 --- a/src/encoding/evm/encoder_builders.rs +++ b/src/encoding/evm/encoder_builders.rs @@ -20,7 +20,7 @@ use crate::encoding::{ pub struct TychoRouterEncoderBuilder { chain: Option, user_transfer_type: Option, - executors_file_path: Option, + executors_addresses: Option, router_address: Option, swapper_pk: Option, historical_trade: bool, @@ -36,7 +36,7 @@ impl TychoRouterEncoderBuilder { pub fn new() -> Self { TychoRouterEncoderBuilder { chain: None, - executors_file_path: None, + executors_addresses: None, router_address: None, swapper_pk: None, user_transfer_type: None, @@ -53,10 +53,10 @@ impl TychoRouterEncoderBuilder { self } - /// Sets the `executors_file_path` manually. - /// If it's not set, the default path will be used (config/executor_addresses.json) - pub fn executors_file_path(mut self, executors_file_path: String) -> Self { - self.executors_file_path = Some(executors_file_path); + /// Sets the `executors_addresses` manually. + /// If it's not set, the default value will be used (contents of config/executor_addresses.json) + pub fn executors_addresses(mut self, executors_addresses: String) -> Self { + self.executors_addresses = Some(executors_addresses); self } @@ -107,7 +107,7 @@ impl TychoRouterEncoderBuilder { } let swap_encoder_registry = - SwapEncoderRegistry::new(self.executors_file_path.clone(), chain)?; + SwapEncoderRegistry::new(self.executors_addresses.clone(), chain)?; let signer = if let Some(pk) = self.swapper_pk { let pk = B256::from_str(&pk).map_err(|_| { @@ -140,7 +140,7 @@ impl TychoRouterEncoderBuilder { /// Builder pattern for constructing a `TychoExecutorEncoder` with customizable options. pub struct TychoExecutorEncoderBuilder { chain: Option, - executors_file_path: Option, + executors_addresses: Option, } impl Default for TychoExecutorEncoderBuilder { @@ -151,17 +151,17 @@ impl Default for TychoExecutorEncoderBuilder { impl TychoExecutorEncoderBuilder { pub fn new() -> Self { - TychoExecutorEncoderBuilder { chain: None, executors_file_path: None } + TychoExecutorEncoderBuilder { chain: None, executors_addresses: None } } pub fn chain(mut self, chain: Chain) -> Self { self.chain = Some(chain); self } - /// Sets the `executors_file_path` manually. + /// Sets the `executors_addresses` manually. /// If it's not set, the default path will be used (config/executor_addresses.json) - pub fn executors_file_path(mut self, executors_file_path: String) -> Self { - self.executors_file_path = Some(executors_file_path); + pub fn executors_addresses(mut self, executors_addresses: String) -> Self { + self.executors_addresses = Some(executors_addresses); self } @@ -170,7 +170,7 @@ impl TychoExecutorEncoderBuilder { pub fn build(self) -> Result, EncodingError> { if let Some(chain) = self.chain { let swap_encoder_registry = - SwapEncoderRegistry::new(self.executors_file_path.clone(), chain)?; + SwapEncoderRegistry::new(self.executors_addresses.clone(), chain)?; Ok(Box::new(TychoExecutorEncoder::new(swap_encoder_registry)?)) } else { Err(EncodingError::FatalError( diff --git a/src/encoding/evm/strategy_encoder/strategy_encoders.rs b/src/encoding/evm/strategy_encoder/strategy_encoders.rs index e0c1255..44f5503 100644 --- a/src/encoding/evm/strategy_encoder/strategy_encoders.rs +++ b/src/encoding/evm/strategy_encoder/strategy_encoders.rs @@ -553,7 +553,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder { #[cfg(test)] mod tests { - use std::{collections::HashMap, str::FromStr}; + use std::{collections::HashMap, fs, str::FromStr}; use alloy::{hex::encode, primitives::hex}; use num_bigint::{BigInt, BigUint}; @@ -573,9 +573,10 @@ mod tests { } fn get_swap_encoder_registry() -> SwapEncoderRegistry { + let executors_addresses = + fs::read_to_string("config/test_executor_addresses.json").unwrap(); let eth_chain = eth_chain(); - SwapEncoderRegistry::new(Some("config/test_executor_addresses.json".to_string()), eth_chain) - .unwrap() + SwapEncoderRegistry::new(Some(executors_addresses), eth_chain).unwrap() } fn router_address() -> Bytes { diff --git a/src/encoding/evm/swap_encoder/swap_encoder_registry.rs b/src/encoding/evm/swap_encoder/swap_encoder_registry.rs index 221ea76..a9955a3 100644 --- a/src/encoding/evm/swap_encoder/swap_encoder_registry.rs +++ b/src/encoding/evm/swap_encoder/swap_encoder_registry.rs @@ -1,4 +1,4 @@ -use std::{collections::HashMap, fs}; +use std::collections::HashMap; use tycho_common::models::Chain; @@ -21,13 +21,9 @@ pub struct SwapEncoderRegistry { impl SwapEncoderRegistry { /// Populates the registry with the `SwapEncoders` for the given blockchain by parsing the /// executors' addresses in the file at the given path. - pub fn new(executors_file_path: Option, chain: Chain) -> Result { - let config_str = if let Some(ref path) = executors_file_path { - fs::read_to_string(path).map_err(|e| { - EncodingError::FatalError(format!( - "Error reading executors file from {executors_file_path:?}: {e}", - )) - })? + pub fn new(executors_addresses: Option, chain: Chain) -> Result { + let config_str = if let Some(addresses) = executors_addresses { + addresses } else { DEFAULT_EXECUTORS_JSON.to_string() }; diff --git a/src/encoding/evm/tycho_encoders.rs b/src/encoding/evm/tycho_encoders.rs index 79632db..e6cae0d 100644 --- a/src/encoding/evm/tycho_encoders.rs +++ b/src/encoding/evm/tycho_encoders.rs @@ -67,14 +67,14 @@ impl TychoRouterEncoder { swap_encoder_registry.clone(), user_transfer_type.clone(), router_address.clone(), - historical_trade.clone(), + historical_trade, )?, sequential_swap_strategy: SequentialSwapStrategyEncoder::new( chain, swap_encoder_registry.clone(), user_transfer_type.clone(), router_address.clone(), - historical_trade.clone(), + historical_trade, )?, split_swap_strategy: SplitSwapStrategyEncoder::new( chain, @@ -405,7 +405,7 @@ impl TychoEncoder for TychoExecutorEncoder { #[cfg(test)] mod tests { - use std::{collections::HashMap, str::FromStr}; + use std::{collections::HashMap, fs, str::FromStr}; use num_bigint::{BigInt, BigUint}; use tycho_common::models::{protocol::ProtocolComponent, Chain}; @@ -489,11 +489,9 @@ mod tests { } fn get_swap_encoder_registry() -> SwapEncoderRegistry { - SwapEncoderRegistry::new( - Some("config/test_executor_addresses.json".to_string()), - eth_chain(), - ) - .unwrap() + let executors_addresses = + fs::read_to_string("config/test_executor_addresses.json").unwrap(); + SwapEncoderRegistry::new(Some(executors_addresses), eth_chain()).unwrap() } fn get_tycho_router_encoder(user_transfer_type: UserTransferType) -> TychoRouterEncoder { diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 0949b7e..a6be289 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] pub mod encoding; -use std::str::FromStr; +use std::{fs, str::FromStr}; use alloy::{ primitives::{B256, U256}, @@ -71,10 +71,11 @@ pub fn get_signer() -> PrivateKeySigner { } pub fn get_tycho_router_encoder(user_transfer_type: UserTransferType) -> Box { + let executors_addresses = fs::read_to_string("config/test_executor_addresses.json").unwrap(); TychoRouterEncoderBuilder::new() .chain(Chain::Ethereum) .user_transfer_type(user_transfer_type) - .executors_file_path("config/test_executor_addresses.json".to_string()) + .executors_addresses(executors_addresses) .router_address(router_address()) .build() .expect("Failed to build encoder")