docs: More docs and improvements of existing docs

- Tried not to leave a single public function undocumented, though did not double-document public function with obvious names
- Remove all mentions of the strategy selector in favour of the strategy registry (to avoid confusion)
This commit is contained in:
TAMARA LIPOWSKI
2025-02-05 16:35:43 -05:00
parent 44e8e0bb96
commit 07457b5f76
10 changed files with 43 additions and 14 deletions

View File

@@ -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<Arc<RootProvider<BoxTransport>>, EncodingError> {
dotenv().ok();
let eth_rpc_url = env::var("ETH_RPC_URL")

View File

@@ -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<u8>>) -> Vec<u8> {
let mut encoded_action_data: Vec<u8> = 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,

View File

@@ -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,

View File

@@ -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<String, Box<dyn SwapEncoder>>,
}
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<Self, EncodingError> {
let config_str = fs::read_to_string(executors_file_path)?;
let config: HashMap<Chain, HashMap<String, String>> = serde_json::from_str(&config_str)?;

View File

@@ -24,10 +24,10 @@ pub struct EVMTychoEncoder<S: StrategyEncoderRegistry> {
}
impl<S: StrategyEncoderRegistry> EVMTychoEncoder<S> {
pub fn new(strategy_selector: S, router_address: String) -> Result<Self, EncodingError> {
pub fn new(strategy_registry: S, router_address: String) -> Result<Self, EncodingError> {
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<MockStrategyRegistry> {
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()

View File

@@ -16,11 +16,13 @@ pub fn bytes_to_address(address: &Bytes) -> Result<Address, EncodingError> {
}
}
/// 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<u8>) -> Vec<u8> {
let mut hasher = Keccak256::new();
hasher.update(selector.as_bytes());

View File

@@ -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<f64>,
/// Expected amount of the bought token (exact in) or sold token (exact out).
pub expected_amount: Option<BigUint>,
@@ -27,9 +27,9 @@ pub struct Solution {
pub check_amount: Option<BigUint>,
/// List of swaps to fulfill the solution.
pub swaps: Vec<Swap>,
// If not set, then the Tycho Router will be used
/// If not set, then the Tycho Router will be used
pub router_address: Option<Bytes>,
// If set, the corresponding native action will be executed.
/// If set, the corresponding native action will be executed.
pub native_action: Option<NativeAction>,
/// 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<u8>,
}
/// 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,

View File

@@ -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,

View File

@@ -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<Vec<u8>, 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.

View File

@@ -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<S: StrategyEncoderRegistry> {
fn encode_router_calldata(
&self,