diff --git a/src/encoding/evm/approvals/protocol_approvals_manager.rs b/src/encoding/evm/approvals/protocol_approvals_manager.rs index ff4e1ce..9af2355 100644 --- a/src/encoding/evm/approvals/protocol_approvals_manager.rs +++ b/src/encoding/evm/approvals/protocol_approvals_manager.rs @@ -25,7 +25,7 @@ impl ProtocolApprovalsManager { Ok(Self { client, runtime }) } - /// Checks the current allowance for the given token, owner, and spender, and returns True + /// Checks the current allowance for the given token, owner, and spender, and returns true /// if the current allowance is zero. pub fn approval_needed( &self, @@ -60,6 +60,7 @@ impl ProtocolApprovalsManager { } } +/// Gets the client used for interacting with the EVM-compatible network. pub async fn get_client() -> Result>, EncodingError> { dotenv().ok(); let eth_rpc_url = env::var("ETH_RPC_URL") diff --git a/src/encoding/evm/strategy_encoder/strategy_encoders.rs b/src/encoding/evm/strategy_encoder/strategy_encoders.rs index 5aae7b1..9d2adb0 100644 --- a/src/encoding/evm/strategy_encoder/strategy_encoders.rs +++ b/src/encoding/evm/strategy_encoder/strategy_encoders.rs @@ -18,7 +18,10 @@ use crate::encoding::{ swap_encoder::SwapEncoder, }; +/// Encodes a solution using a specific strategy for execution on the EVM-compatible network. pub trait EVMStrategyEncoder: StrategyEncoder { + /// Encodes information necessary for performing a single swap against a given executor for + /// a protocol. fn encode_swap_header( &self, token_in: U8, @@ -37,11 +40,17 @@ pub trait EVMStrategyEncoder: StrategyEncoder { 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 + /// (the "prefix") contains information about the length of the following data. fn ple_encode(&self, action_data_array: Vec>) -> Vec { let mut encoded_action_data: Vec = Vec::new(); @@ -57,7 +66,6 @@ pub trait EVMStrategyEncoder: StrategyEncoder { /// Represents the encoder for a swap strategy which supports single, sequential and split swaps. /// /// # Fields -/// /// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders /// * `permit2`: Permit2, the object containing necessary information for managing permit2 /// operations @@ -78,7 +86,9 @@ impl SplitSwapStrategyEncoder { Ok(Self { permit2: Permit2::new(signer_pk, chain)?, selector, swap_encoder_registry }) } } + impl EVMStrategyEncoder for SplitSwapStrategyEncoder {} + impl StrategyEncoder for SplitSwapStrategyEncoder { fn encode_strategy( &self, @@ -224,7 +234,6 @@ impl StrategyEncoder for SplitSwapStrategyEncoder { /// the router. Only one solution with one swap is supported. /// /// # Fields -/// /// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders pub struct ExecutorStrategyEncoder { swap_encoder_registry: SwapEncoderRegistry, diff --git a/src/encoding/evm/swap_encoder/builder.rs b/src/encoding/evm/swap_encoder/builder.rs index d0b8eeb..4d99206 100644 --- a/src/encoding/evm/swap_encoder/builder.rs +++ b/src/encoding/evm/swap_encoder/builder.rs @@ -4,6 +4,7 @@ use crate::encoding::{ swap_encoder::SwapEncoder, }; +/// Builds a `SwapEncoder` for the given protocol system and executor address. pub struct SwapEncoderBuilder { protocol_system: String, executor_address: String, diff --git a/src/encoding/evm/swap_encoder/swap_encoder_registry.rs b/src/encoding/evm/swap_encoder/swap_encoder_registry.rs index 639dfc0..9ae7a43 100644 --- a/src/encoding/evm/swap_encoder/swap_encoder_registry.rs +++ b/src/encoding/evm/swap_encoder/swap_encoder_registry.rs @@ -7,12 +7,16 @@ use crate::encoding::{ swap_encoder::SwapEncoder, }; +/// Registry containing all supported `SwapEncoders`. #[derive(Clone)] pub struct SwapEncoderRegistry { + /// A hashmap containing the protocol system as a key and the `SwapEncoder` as a value. encoders: HashMap>, } impl SwapEncoderRegistry { + /// Populates the registry with the `SwapEncoders` for the given blockchain by parsing the + /// executors in the file at the given path. pub fn new(executors_file_path: &str, blockchain: Chain) -> Result { let config_str = fs::read_to_string(executors_file_path)?; let config: HashMap> = serde_json::from_str(&config_str)?; diff --git a/src/encoding/evm/tycho_encoder.rs b/src/encoding/evm/tycho_encoder.rs index 71908bc..10bb4a9 100644 --- a/src/encoding/evm/tycho_encoder.rs +++ b/src/encoding/evm/tycho_encoder.rs @@ -24,10 +24,10 @@ pub struct EVMTychoEncoder { } impl EVMTychoEncoder { - pub fn new(strategy_selector: S, router_address: String) -> Result { + pub fn new(strategy_registry: S, router_address: String) -> Result { let router_address = Bytes::from_str(&router_address) .map_err(|_| EncodingError::FatalError("Invalid router address".to_string()))?; - Ok(EVMTychoEncoder { strategy_registry: strategy_selector, router_address }) + Ok(EVMTychoEncoder { strategy_registry, router_address }) } } @@ -165,9 +165,9 @@ mod tests { } fn get_mocked_tycho_encoder() -> EVMTychoEncoder { - let strategy_selector = MockStrategyRegistry::new(Chain::Ethereum, "", None).unwrap(); + let strategy_registry = MockStrategyRegistry::new(Chain::Ethereum, "", None).unwrap(); EVMTychoEncoder::new( - strategy_selector, + strategy_registry, "0x1234567890abcdef1234567890abcdef12345678".to_string(), ) .unwrap() diff --git a/src/encoding/evm/utils.rs b/src/encoding/evm/utils.rs index 05a13e0..5d3a70a 100644 --- a/src/encoding/evm/utils.rs +++ b/src/encoding/evm/utils.rs @@ -16,11 +16,13 @@ pub fn bytes_to_address(address: &Bytes) -> Result { } } +/// Converts a general `BigUint` to an EVM-specific `U256` value. pub fn biguint_to_u256(value: &BigUint) -> U256 { let bytes = value.to_bytes_be(); U256::from_be_slice(&bytes) } +/// Encodes the input data for a function call to the given function selector. pub fn encode_input(selector: &str, mut encoded_args: Vec) -> Vec { let mut hasher = Keccak256::new(); hasher.update(selector.as_bytes()); diff --git a/src/encoding/models.rs b/src/encoding/models.rs index 06b1dc1..5cd5707 100644 --- a/src/encoding/models.rs +++ b/src/encoding/models.rs @@ -18,7 +18,7 @@ pub struct Solution { /// False if the solution is an exact input solution. Currently only exact input solutions are /// supported. pub exact_out: bool, - // If set, it will be applied to expected_amount + /// If set, it will be applied to expected_amount pub slippage: Option, /// Expected amount of the bought token (exact in) or sold token (exact out). pub expected_amount: Option, @@ -27,9 +27,9 @@ pub struct Solution { pub check_amount: Option, /// List of swaps to fulfill the solution. pub swaps: Vec, - // If not set, then the Tycho Router will be used + /// If not set, then the Tycho Router will be used pub router_address: Option, - // If set, the corresponding native action will be executed. + /// If set, the corresponding native action will be executed. pub native_action: Option, /// If set to true, the solution will be encoded to be sent directly to the Executor and /// skip the router. The user is responsible for managing necessary approvals and token @@ -69,15 +69,18 @@ pub struct Swap { /// * `data`: Encoded calldata for the transaction. #[derive(Clone, Debug)] pub struct Transaction { - // Address of the contract to call with the calldata pub to: Bytes, - // Native token value to be sent with the transaction. pub value: BigUint, - // Encoded calldata for the transaction. pub data: Vec, } /// Represents necessary attributes for encoding an order. +/// +/// # Fields +/// +/// * `receiver`: Address of the receiver of the out token after the swaps are completed. +/// * `exact_out`: true if the solution is a buy order, false if it is a sell order. +/// * `router_address`: Address of the router contract to be used for the swaps. pub struct EncodingContext { pub receiver: Bytes, pub exact_out: bool, diff --git a/src/encoding/strategy_encoder.rs b/src/encoding/strategy_encoder.rs index d9c79f9..c68246e 100644 --- a/src/encoding/strategy_encoder.rs +++ b/src/encoding/strategy_encoder.rs @@ -2,6 +2,7 @@ use tycho_core::{models::Chain, Bytes}; use crate::encoding::{errors::EncodingError, models::Solution, swap_encoder::SwapEncoder}; +/// Encodes a solution using a specific strategy. pub trait StrategyEncoder { fn encode_strategy( &self, diff --git a/src/encoding/swap_encoder.rs b/src/encoding/swap_encoder.rs index 356086e..a0a9d0f 100644 --- a/src/encoding/swap_encoder.rs +++ b/src/encoding/swap_encoder.rs @@ -3,17 +3,23 @@ use crate::encoding::{ models::{EncodingContext, Swap}, }; -/// This trait must be implemented in order to encode a swap for a specific protocol. +/// This trait must be implemented in order to encode a single swap for a specific protocol. pub trait SwapEncoder: Sync + Send { fn new(executor_address: String) -> Self where Self: Sized; + + /// Encodes a swap and its relevant context information into call data for a specific protocol. fn encode_swap( &self, swap: Swap, encoding_context: EncodingContext, ) -> Result, EncodingError>; + + /// The address of the executor that will be used to swap through a specific protocol. fn executor_address(&self) -> &str; + + /// The selector of the executor function that will be called in order to perform a swap. fn executor_selector(&self) -> &str; /// Clones the swap encoder as a trait object. diff --git a/src/encoding/tycho_encoder.rs b/src/encoding/tycho_encoder.rs index 8ee054e..3be2277 100644 --- a/src/encoding/tycho_encoder.rs +++ b/src/encoding/tycho_encoder.rs @@ -4,6 +4,8 @@ use crate::encoding::{ strategy_encoder::StrategyEncoderRegistry, }; +/// An encoder must implement this trait in order to encode a solution into a Transaction for +/// execution using a Tycho router or related contracts. pub trait TychoEncoder { fn encode_router_calldata( &self,