Merge pull request #208 from propeller-heads/audit/dc/rename-selector-to-function-signature

chore: Rename selector to function signature
This commit is contained in:
dianacarvalho1
2025-05-27 15:26:20 +01:00
committed by GitHub
11 changed files with 79 additions and 79 deletions

View File

@@ -64,10 +64,10 @@ fn main() {
.clone(); .clone();
println!(" ====== Simple swap WETH -> USDC ======"); println!(" ====== Simple swap WETH -> USDC ======");
println!( println!(
"The simple swap encoded solution should be sent to address {:?} and selector {:?} and the \ "The simple swap encoded solution should be sent to address {:?} with function signature {:?} and the \
following encoded data: {:?}", following encoded swaps: {:?}",
encoded_solution.interacting_with, encoded_solution.interacting_with,
encoded_solution.selector, encoded_solution.function_signature,
hex::encode(encoded_solution.swaps) hex::encode(encoded_solution.swaps)
); );
@@ -138,10 +138,10 @@ fn main() {
println!(" ====== Complex split swap WETH -> USDC ======"); println!(" ====== Complex split swap WETH -> USDC ======");
println!( println!(
"The complex swaps encoded solution should be sent to address {:?} and selector {:?} and the \ "The complex swaps encoded solution should be sent to address {:?} with function signature {:?} and the \
following encoded data: {:?}", following encoded swaps: {:?}",
complex_encoded_solution.interacting_with, complex_encoded_solution.interacting_with,
complex_encoded_solution.selector, complex_encoded_solution.function_signature,
hex::encode(complex_encoded_solution.swaps) hex::encode(complex_encoded_solution.swaps)
); );
} }

View File

@@ -106,7 +106,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let encoded = serde_json::json!({ let encoded = serde_json::json!({
"swaps": format!("0x{}", hex::encode(&encoded_solutions[0].swaps)), "swaps": format!("0x{}", hex::encode(&encoded_solutions[0].swaps)),
"interacting_with": format!("0x{}", hex::encode(&encoded_solutions[0].interacting_with)), "interacting_with": format!("0x{}", hex::encode(&encoded_solutions[0].interacting_with)),
"selector": format!("{}",&encoded_solutions[0].selector), "function_signature": format!("{}",&encoded_solutions[0].function_signature),
"n_tokens": format!("{}", &encoded_solutions[0].n_tokens), "n_tokens": format!("{}", &encoded_solutions[0].n_tokens),
"permit": match encoded_solutions[0].permit.as_ref() { "permit": match encoded_solutions[0].permit.as_ref() {
Some(permit) => { Some(permit) => {

View File

@@ -17,7 +17,10 @@ use tycho_common::Bytes;
use crate::encoding::{ use crate::encoding::{
errors::EncodingError, errors::EncodingError,
evm::utils::{biguint_to_u256, bytes_to_address, encode_input, get_client, get_runtime}, evm::{
encoding_utils::encode_input,
utils::{biguint_to_u256, bytes_to_address, get_client, get_runtime},
},
models, models,
}; };

View File

@@ -14,7 +14,10 @@ use tokio::{
use crate::encoding::{ use crate::encoding::{
errors::EncodingError, errors::EncodingError,
evm::utils::{encode_input, get_client, get_runtime}, evm::{
encoding_utils::encode_input,
utils::{get_client, get_runtime},
},
}; };
/// A manager for checking if an approval is needed for interacting with a certain spender. /// A manager for checking if an approval is needed for interacting with a certain spender.

View File

@@ -4,7 +4,7 @@ use alloy::{
primitives::U256, primitives::U256,
signers::{local::PrivateKeySigner, Signature, SignerSync}, signers::{local::PrivateKeySigner, Signature, SignerSync},
}; };
use alloy_primitives::Address; use alloy_primitives::{Address, Keccak256};
use alloy_sol_types::{eip712_domain, SolStruct, SolValue}; use alloy_sol_types::{eip712_domain, SolStruct, SolValue};
use num_bigint::BigUint; use num_bigint::BigUint;
use tycho_common::Bytes; use tycho_common::Bytes;
@@ -13,7 +13,6 @@ use crate::encoding::{
errors::EncodingError, errors::EncodingError,
evm::{ evm::{
approvals::permit2::PermitSingle, approvals::permit2::PermitSingle,
utils,
utils::{biguint_to_u256, bytes_to_address}, utils::{biguint_to_u256, bytes_to_address},
}, },
models, models,
@@ -34,7 +33,7 @@ use crate::encoding::{
/// - `splitSwapPermit2` /// - `splitSwapPermit2`
/// ///
/// The encoding includes handling of native asset wrapping/unwrapping, permit2 support, /// The encoding includes handling of native asset wrapping/unwrapping, permit2 support,
/// and proper input argument formatting based on the selector string. /// and proper input argument formatting based on the function signature string.
/// ///
/// # ⚠️ Important Responsibility Note /// # ⚠️ Important Responsibility Note
/// ///
@@ -60,7 +59,7 @@ use crate::encoding::{
/// funds. /// funds.
/// ///
/// # Parameters /// # Parameters
/// - `encoded_solution`: The solution already encoded by Tycho, including selector and swap path. /// - `encoded_solution`: The solution already encoded by Tycho.
/// - `solution`: The high-level solution including tokens, amounts, and receiver info. /// - `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. /// - `token_in_already_in_router`: Whether the input token is already present in the router.
/// - `router_address`: The address of the Tycho Router contract. /// - `router_address`: The address of the Tycho Router contract.
@@ -71,8 +70,8 @@ use crate::encoding::{
/// value, data), or an error if the inputs are invalid. /// value, data), or an error if the inputs are invalid.
/// ///
/// # Errors /// # Errors
/// - Returns `EncodingError::FatalError` if the selector is unsupported or required fields (e.g., /// - Returns `EncodingError::FatalError` if the function signature is unsupported or required
/// permit or signature) are missing. /// fields (e.g., permit or signature) are missing.
pub fn encode_tycho_router_call( pub fn encode_tycho_router_call(
chain_id: u64, chain_id: u64,
encoded_solution: EncodedSolution, encoded_solution: EncodedSolution,
@@ -109,7 +108,7 @@ pub fn encode_tycho_router_call(
}; };
let method_calldata = if encoded_solution let method_calldata = if encoded_solution
.selector .function_signature
.contains("singleSwapPermit2") .contains("singleSwapPermit2")
{ {
( (
@@ -128,7 +127,7 @@ pub fn encode_tycho_router_call(
) )
.abi_encode() .abi_encode()
} else if encoded_solution } else if encoded_solution
.selector .function_signature
.contains("singleSwap") .contains("singleSwap")
{ {
( (
@@ -144,7 +143,7 @@ pub fn encode_tycho_router_call(
) )
.abi_encode() .abi_encode()
} else if encoded_solution } else if encoded_solution
.selector .function_signature
.contains("sequentialSwapPermit2") .contains("sequentialSwapPermit2")
{ {
( (
@@ -163,7 +162,7 @@ pub fn encode_tycho_router_call(
) )
.abi_encode() .abi_encode()
} else if encoded_solution } else if encoded_solution
.selector .function_signature
.contains("sequentialSwap") .contains("sequentialSwap")
{ {
( (
@@ -179,7 +178,7 @@ pub fn encode_tycho_router_call(
) )
.abi_encode() .abi_encode()
} else if encoded_solution } else if encoded_solution
.selector .function_signature
.contains("splitSwapPermit2") .contains("splitSwapPermit2")
{ {
( (
@@ -199,7 +198,7 @@ pub fn encode_tycho_router_call(
) )
.abi_encode() .abi_encode()
} else if encoded_solution } else if encoded_solution
.selector .function_signature
.contains("splitSwap") .contains("splitSwap")
{ {
( (
@@ -216,10 +215,10 @@ pub fn encode_tycho_router_call(
) )
.abi_encode() .abi_encode()
} else { } else {
Err(EncodingError::FatalError("Invalid selector for Tycho router".to_string()))? Err(EncodingError::FatalError("Invalid function signature for Tycho router".to_string()))?
}; };
let contract_interaction = utils::encode_input(&encoded_solution.selector, method_calldata); let contract_interaction = encode_input(&encoded_solution.function_signature, method_calldata);
let value = if solution.given_token == native_address { let value = if solution.given_token == native_address {
solution.given_amount.clone() solution.given_amount.clone()
} else { } else {
@@ -257,3 +256,25 @@ pub fn sign_permit(
EncodingError::FatalError(format!("Failed to sign permit2 approval with error: {e}")) EncodingError::FatalError(format!("Failed to sign permit2 approval with error: {e}"))
}) })
} }
/// Encodes the input data for a function call to the given function selector.
pub fn encode_input(selector: &str, mut encoded_args: Vec<u8>) -> Vec<u8> {
let mut hasher = Keccak256::new();
hasher.update(selector.as_bytes());
let selector_bytes = &hasher.finalize()[..4];
let mut call_data = selector_bytes.to_vec();
// Remove extra prefix if present (32 bytes for dynamic data)
// Alloy encoding is including a prefix for dynamic data indicating the offset or length
// but at this point we don't want that
if encoded_args.len() > 32 &&
encoded_args[..32] ==
[0u8; 31]
.into_iter()
.chain([32].to_vec())
.collect::<Vec<u8>>()
{
encoded_args = encoded_args[32..].to_vec();
}
call_data.extend(encoded_args);
call_data
}

View File

@@ -23,13 +23,13 @@ use crate::encoding::{
/// ///
/// # Fields /// # Fields
/// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders /// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders
/// * `selector`: String, the selector for the swap function in the router contract /// * `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 /// * `router_address`: Address of the router to be used to execute swaps
/// * `transfer_optimization`: TransferOptimization, responsible for optimizing the token transfers /// * `transfer_optimization`: TransferOptimization, responsible for optimizing the token transfers
#[derive(Clone)] #[derive(Clone)]
pub struct SingleSwapStrategyEncoder { pub struct SingleSwapStrategyEncoder {
swap_encoder_registry: SwapEncoderRegistry, swap_encoder_registry: SwapEncoderRegistry,
selector: String, function_signature: String,
router_address: Bytes, router_address: Bytes,
transfer_optimization: TransferOptimization, transfer_optimization: TransferOptimization,
} }
@@ -41,14 +41,14 @@ impl SingleSwapStrategyEncoder {
user_transfer_type: UserTransferType, user_transfer_type: UserTransferType,
router_address: Bytes, router_address: Bytes,
) -> Result<Self, EncodingError> { ) -> Result<Self, EncodingError> {
let selector = if user_transfer_type == UserTransferType::TransferFromPermit2 { 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)" "singleSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)"
} else { } else {
"singleSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)" "singleSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)"
}.to_string(); }.to_string();
Ok(Self { Ok(Self {
selector, function_signature,
swap_encoder_registry, swap_encoder_registry,
router_address: router_address.clone(), router_address: router_address.clone(),
transfer_optimization: TransferOptimization::new( transfer_optimization: TransferOptimization::new(
@@ -133,7 +133,7 @@ impl StrategyEncoder for SingleSwapStrategyEncoder {
grouped_protocol_data, grouped_protocol_data,
); );
Ok(EncodedSolution { Ok(EncodedSolution {
selector: self.selector.clone(), function_signature: self.function_signature.clone(),
interacting_with: self.router_address.clone(), interacting_with: self.router_address.clone(),
swaps: swap_data, swaps: swap_data,
permit: None, permit: None,
@@ -155,7 +155,7 @@ impl StrategyEncoder for SingleSwapStrategyEncoder {
/// ///
/// # Fields /// # Fields
/// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders /// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders
/// * `selector`: String, the selector for the swap function in the router contract /// * `function_signature`: String, the signature for the swap function in the router contract
/// * `native_address`: Address of the chain's native token /// * `native_address`: Address of the chain's native token
/// * `wrapped_address`: Address of the chain's wrapped token /// * `wrapped_address`: Address of the chain's wrapped token
/// * `router_address`: Address of the router to be used to execute swaps /// * `router_address`: Address of the router to be used to execute swaps
@@ -165,7 +165,7 @@ impl StrategyEncoder for SingleSwapStrategyEncoder {
#[derive(Clone)] #[derive(Clone)]
pub struct SequentialSwapStrategyEncoder { pub struct SequentialSwapStrategyEncoder {
swap_encoder_registry: SwapEncoderRegistry, swap_encoder_registry: SwapEncoderRegistry,
selector: String, function_signature: String,
router_address: Bytes, router_address: Bytes,
native_address: Bytes, native_address: Bytes,
wrapped_address: Bytes, wrapped_address: Bytes,
@@ -180,14 +180,14 @@ impl SequentialSwapStrategyEncoder {
user_transfer_type: UserTransferType, user_transfer_type: UserTransferType,
router_address: Bytes, router_address: Bytes,
) -> Result<Self, EncodingError> { ) -> Result<Self, EncodingError> {
let selector = if user_transfer_type == UserTransferType::TransferFromPermit2 { 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)" "sequentialSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)"
} else { } else {
"sequentialSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)" "sequentialSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)"
}.to_string(); }.to_string();
Ok(Self { Ok(Self {
selector, function_signature,
swap_encoder_registry, swap_encoder_registry,
router_address: router_address.clone(), router_address: router_address.clone(),
native_address: chain.native_token()?, native_address: chain.native_token()?,
@@ -288,7 +288,7 @@ impl StrategyEncoder for SequentialSwapStrategyEncoder {
let encoded_swaps = ple_encode(swaps); let encoded_swaps = ple_encode(swaps);
Ok(EncodedSolution { Ok(EncodedSolution {
interacting_with: self.router_address.clone(), interacting_with: self.router_address.clone(),
selector: self.selector.clone(), function_signature: self.function_signature.clone(),
swaps: encoded_swaps, swaps: encoded_swaps,
permit: None, permit: None,
n_tokens: 0, n_tokens: 0,
@@ -309,7 +309,7 @@ impl StrategyEncoder for SequentialSwapStrategyEncoder {
/// ///
/// # Fields /// # Fields
/// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders /// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders
/// * `selector`: String, the selector for the swap function in the router contract /// * `function_signature`: String, the signature for the swap function in the router contract
/// * `native_address`: Address of the chain's native token /// * `native_address`: Address of the chain's native token
/// * `wrapped_address`: Address of the chain's wrapped token /// * `wrapped_address`: Address of the chain's wrapped token
/// * `split_swap_validator`: SplitSwapValidator, responsible for checking validity of split swap /// * `split_swap_validator`: SplitSwapValidator, responsible for checking validity of split swap
@@ -319,7 +319,7 @@ impl StrategyEncoder for SequentialSwapStrategyEncoder {
#[derive(Clone)] #[derive(Clone)]
pub struct SplitSwapStrategyEncoder { pub struct SplitSwapStrategyEncoder {
swap_encoder_registry: SwapEncoderRegistry, swap_encoder_registry: SwapEncoderRegistry,
selector: String, function_signature: String,
native_address: Bytes, native_address: Bytes,
wrapped_address: Bytes, wrapped_address: Bytes,
split_swap_validator: SplitSwapValidator, split_swap_validator: SplitSwapValidator,
@@ -334,13 +334,13 @@ impl SplitSwapStrategyEncoder {
user_transfer_type: UserTransferType, user_transfer_type: UserTransferType,
router_address: Bytes, router_address: Bytes,
) -> Result<Self, EncodingError> { ) -> Result<Self, EncodingError> {
let selector = if user_transfer_type == UserTransferType::TransferFromPermit2 { 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)" "splitSwapPermit2(uint256,address,address,uint256,bool,bool,uint256,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)"
} else { } else {
"splitSwap(uint256,address,address,uint256,bool,bool,uint256,address,bool,bytes)" "splitSwap(uint256,address,address,uint256,bool,bool,uint256,address,bool,bytes)"
}.to_string(); }.to_string();
Ok(Self { Ok(Self {
selector, function_signature,
swap_encoder_registry, swap_encoder_registry,
native_address: chain.native_token()?, native_address: chain.native_token()?,
wrapped_address: chain.wrapped_token()?, wrapped_address: chain.wrapped_token()?,
@@ -489,7 +489,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
}; };
Ok(EncodedSolution { Ok(EncodedSolution {
interacting_with: self.router_address.clone(), interacting_with: self.router_address.clone(),
selector: self.selector.clone(), function_signature: self.function_signature.clone(),
swaps: encoded_swaps, swaps: encoded_swaps,
permit: None, permit: None,
n_tokens: tokens_len, n_tokens: tokens_len,
@@ -596,7 +596,7 @@ mod tests {
let hex_calldata = encode(&encoded_solution.swaps); let hex_calldata = encode(&encoded_solution.swaps);
assert_eq!(hex_calldata, expected_swap); assert_eq!(hex_calldata, expected_swap);
assert_eq!(encoded_solution.selector, "singleSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string()); assert_eq!(encoded_solution.function_signature, "singleSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string());
assert_eq!(encoded_solution.interacting_with, router_address()); assert_eq!(encoded_solution.interacting_with, router_address());
} }
@@ -659,7 +659,7 @@ mod tests {
assert_eq!(hex_calldata, expected_input); assert_eq!(hex_calldata, expected_input);
assert_eq!( assert_eq!(
encoded_solution.selector, encoded_solution.function_signature,
"singleSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)" "singleSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)"
.to_string() .to_string()
); );
@@ -747,7 +747,7 @@ mod tests {
assert_eq!(hex_calldata, expected); assert_eq!(hex_calldata, expected);
assert_eq!( assert_eq!(
encoded_solution.selector, encoded_solution.function_signature,
"sequentialSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)" "sequentialSwap(uint256,address,address,uint256,bool,bool,address,bool,bytes)"
.to_string() .to_string()
); );
@@ -902,7 +902,7 @@ mod tests {
.join(""); .join("");
assert_eq!(hex_calldata, expected_swaps); assert_eq!(hex_calldata, expected_swaps);
assert_eq!( assert_eq!(
encoded_solution.selector, encoded_solution.function_signature,
"splitSwapPermit2(uint256,address,address,uint256,bool,bool,uint256,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)" "splitSwapPermit2(uint256,address,address,uint256,bool,bool,uint256,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)"
.to_string() .to_string()
); );
@@ -1050,7 +1050,7 @@ mod tests {
assert_eq!(hex_calldata, expected_swaps); assert_eq!(hex_calldata, expected_swaps);
assert_eq!( assert_eq!(
encoded_solution.selector, encoded_solution.function_signature,
"splitSwap(uint256,address,address,uint256,bool,bool,uint256,address,bool,bytes)" "splitSwap(uint256,address,address,uint256,bool,bool,uint256,address,bool,bytes)"
.to_string() .to_string()
); );

View File

@@ -19,7 +19,6 @@ use crate::encoding::{
/// ///
/// # Fields /// # Fields
/// * `executor_address` - The address of the executor contract that will perform the swap. /// * `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.
#[derive(Clone)] #[derive(Clone)]
pub struct UniswapV2SwapEncoder { pub struct UniswapV2SwapEncoder {
executor_address: String, executor_address: String,
@@ -78,7 +77,6 @@ impl SwapEncoder for UniswapV2SwapEncoder {
/// ///
/// # Fields /// # Fields
/// * `executor_address` - The address of the executor contract that will perform the swap. /// * `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.
#[derive(Clone)] #[derive(Clone)]
pub struct UniswapV3SwapEncoder { pub struct UniswapV3SwapEncoder {
executor_address: String, executor_address: String,
@@ -140,8 +138,6 @@ impl SwapEncoder for UniswapV3SwapEncoder {
/// ///
/// # Fields /// # Fields
/// * `executor_address` - The address of the executor contract that will perform the swap. /// * `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.
/// * `callback_selector` - The selector of the callback function in the executor contract.
#[derive(Clone)] #[derive(Clone)]
pub struct UniswapV4SwapEncoder { pub struct UniswapV4SwapEncoder {
executor_address: String, executor_address: String,

View File

@@ -337,7 +337,7 @@ impl TychoExecutorEncoder {
swaps: grouped_protocol_data, swaps: grouped_protocol_data,
interacting_with: executor_address, interacting_with: executor_address,
permit: None, permit: None,
selector: "".to_string(), function_signature: "".to_string(),
n_tokens: 0, n_tokens: 0,
}) })
} }

View File

@@ -9,7 +9,7 @@ use alloy::{
providers::{ProviderBuilder, RootProvider}, providers::{ProviderBuilder, RootProvider},
transports::BoxTransport, transports::BoxTransport,
}; };
use alloy_primitives::{aliases::U24, Address, Keccak256, U256, U8}; use alloy_primitives::{aliases::U24, Address, U256, U8};
use alloy_sol_types::SolValue; use alloy_sol_types::SolValue;
use num_bigint::BigUint; use num_bigint::BigUint;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@@ -159,25 +159,3 @@ pub fn write_calldata_to_file(test_identifier: &str, hex_calldata: &str) {
writeln!(file, "{line}").expect("Failed to write calldata"); writeln!(file, "{line}").expect("Failed to write calldata");
} }
} }
/// Encodes the input data for a function call to the given function selector.
pub fn encode_input(selector: &str, mut encoded_args: Vec<u8>) -> Vec<u8> {
let mut hasher = Keccak256::new();
hasher.update(selector.as_bytes());
let selector_bytes = &hasher.finalize()[..4];
let mut call_data = selector_bytes.to_vec();
// Remove extra prefix if present (32 bytes for dynamic data)
// Alloy encoding is including a prefix for dynamic data indicating the offset or length
// but at this point we don't want that
if encoded_args.len() > 32 &&
encoded_args[..32] ==
[0u8; 31]
.into_iter()
.chain([32].to_vec())
.collect::<Vec<u8>>()
{
encoded_args = encoded_args[32..].to_vec();
}
call_data.extend(encoded_args);
call_data
}

View File

@@ -105,7 +105,6 @@ impl Swap {
/// * `to`: Address of the contract to call with the calldata /// * `to`: Address of the contract to call with the calldata
/// * `value`: Native token value to be sent with the transaction. /// * `value`: Native token value to be sent with the transaction.
/// * `data`: Encoded calldata for 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)] #[derive(Clone, Debug)]
pub struct Transaction { pub struct Transaction {
pub to: Bytes, pub to: Bytes,
@@ -118,14 +117,14 @@ pub struct Transaction {
/// # Fields /// # Fields
/// * `swaps`: Encoded swaps to be executed. /// * `swaps`: Encoded swaps to be executed.
/// * `interacting_with`: Address of the contract to be called. /// * `interacting_with`: Address of the contract to be called.
/// * `selector`: The selector of the function to be called. /// * `function_signature`: The signature of the function to be called.
/// * `n_tokens`: Number of tokens in the swap. /// * `n_tokens`: Number of tokens in the swap.
/// * `permit`: Optional permit for the swap (if permit2 is enabled). /// * `permit`: Optional permit for the swap (if permit2 is enabled).
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct EncodedSolution { pub struct EncodedSolution {
pub swaps: Vec<u8>, pub swaps: Vec<u8>,
pub interacting_with: Bytes, pub interacting_with: Bytes,
pub selector: String, pub function_signature: String,
pub n_tokens: usize, pub n_tokens: usize,
pub permit: Option<PermitSingle>, pub permit: Option<PermitSingle>,
} }

View File

@@ -26,8 +26,8 @@ use crate::encoding::{
/// outer function call arguments themselves** and verify that they enforce correct and secure /// outer function call arguments themselves** and verify that they enforce correct and secure
/// behavior. /// behavior.
pub trait TychoEncoder { pub trait TychoEncoder {
/// Encodes a list of [`Solution`]s into [`EncodedSolution`]s, which include the selector and /// Encodes a list of [`Solution`]s into [`EncodedSolution`]s, which include the function
/// internal swap call data. /// signature and internal swap call data.
/// ///
/// This method gives users maximum flexibility and control. It **does not** produce full /// This method gives users maximum flexibility and control. It **does not** produce full
/// transaction objects. Users are responsible for: /// transaction objects. Users are responsible for:
@@ -36,7 +36,7 @@ pub trait TychoEncoder {
/// ///
/// # Returns /// # Returns
/// A vector of encoded solutions, each containing: /// A vector of encoded solutions, each containing:
/// - The Tycho method selector /// - The Tycho method function signature
/// - The encoded swap path /// - The encoded swap path
/// - Additional metadata (e.g., permit2 information) /// - Additional metadata (e.g., permit2 information)
/// ///