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]] 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 b6b6497..703f083 100644 --- a/src/encoding/evm/encoder_builders.rs +++ b/src/encoding/evm/encoder_builders.rs @@ -20,9 +20,10 @@ 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, } impl Default for TychoRouterEncoderBuilder { @@ -35,10 +36,11 @@ 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, + historical_trade: false, } } pub fn chain(mut self, chain: Chain) -> Self { @@ -51,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 } @@ -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 @@ -96,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(|_| { @@ -115,6 +126,7 @@ impl TychoRouterEncoderBuilder { tycho_router_address, user_transfer_type, signer, + self.historical_trade, )?)) } else { Err(EncodingError::FatalError( @@ -128,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 { @@ -139,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 } @@ -158,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/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..44f5503 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![]; @@ -535,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}; @@ -555,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 { @@ -591,6 +610,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFromPermit2, router_address(), + false, ) .unwrap(); let solution = Solution { @@ -651,6 +671,7 @@ mod tests { swap_encoder_registry, UserTransferType::None, router_address(), + false, ) .unwrap(); let solution = Solution { @@ -732,6 +753,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFrom, router_address(), + false, ) .unwrap(); let solution = Solution { @@ -867,6 +889,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFromPermit2, Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"), + false, ) .unwrap(); @@ -1015,6 +1038,7 @@ mod tests { swap_encoder_registry, UserTransferType::TransferFrom, Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"), + false, ) .unwrap(); 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/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..e6cae0d 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, )?, sequential_swap_strategy: SequentialSwapStrategyEncoder::new( chain, swap_encoder_registry.clone(), user_transfer_type.clone(), router_address.clone(), + historical_trade, )?, 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![]; @@ -400,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}; @@ -484,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 { @@ -498,6 +501,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. 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")