docs: (WIP) In-code docs for encoders
- TODO double check all this, look for missing docs
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# Tycho Execution
|
# Tycho Execution
|
||||||
|
|
||||||
TODO: add banner
|

|
||||||
|
|
||||||
Tycho Execution makes it easy to trade on different DEXs by handling the complex encoding for you. Instead of creating
|
Tycho Execution makes it easy to trade on different DEXs by handling the complex encoding for you. Instead of creating
|
||||||
custom code for each DEX, you get a simple, ready-to-use tool that generates the necessary data to execute trades. It’s
|
custom code for each DEX, you get a simple, ready-to-use tool that generates the necessary data to execute trades. It’s
|
||||||
|
|||||||
BIN
banner.png
Normal file
BIN
banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 897 KiB |
@@ -12,6 +12,7 @@ use tokio::runtime::Runtime;
|
|||||||
|
|
||||||
use crate::encoding::{errors::EncodingError, evm::utils::encode_input};
|
use crate::encoding::{errors::EncodingError, evm::utils::encode_input};
|
||||||
|
|
||||||
|
/// A manager for checking if an approval is needed for interacting with a certain spender.
|
||||||
pub struct ProtocolApprovalsManager {
|
pub struct ProtocolApprovalsManager {
|
||||||
client: Arc<RootProvider<BoxTransport>>,
|
client: Arc<RootProvider<BoxTransport>>,
|
||||||
runtime: Runtime,
|
runtime: Runtime,
|
||||||
@@ -23,6 +24,9 @@ impl ProtocolApprovalsManager {
|
|||||||
let client = runtime.block_on(get_client())?;
|
let client = runtime.block_on(get_client())?;
|
||||||
Ok(Self { client, runtime })
|
Ok(Self { client, runtime })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks the current allowance for the given token, owner, and spender, and returns True
|
||||||
|
/// if the current allowance is zero.
|
||||||
pub fn approval_needed(
|
pub fn approval_needed(
|
||||||
&self,
|
&self,
|
||||||
token: Address,
|
token: Address,
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ use crate::encoding::{
|
|||||||
strategy_encoder::{StrategyEncoder, StrategyEncoderRegistry},
|
strategy_encoder::{StrategyEncoder, StrategyEncoderRegistry},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Contains all supported strategies to encode a solution.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `strategies` - A hashmap containing the name of the strategy as a key and the strategy
|
||||||
|
/// encoder as a value.
|
||||||
pub struct EVMStrategyEncoderRegistry {
|
pub struct EVMStrategyEncoderRegistry {
|
||||||
strategies: HashMap<String, Box<dyn StrategyEncoder>>,
|
strategies: HashMap<String, Box<dyn StrategyEncoder>>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,13 @@ 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
|
||||||
|
/// * `selector`: String, the selector for the swap function in the router contract
|
||||||
pub struct SplitSwapStrategyEncoder {
|
pub struct SplitSwapStrategyEncoder {
|
||||||
swap_encoder_registry: SwapEncoderRegistry,
|
swap_encoder_registry: SwapEncoderRegistry,
|
||||||
permit2: Permit2,
|
permit2: Permit2,
|
||||||
@@ -213,7 +220,11 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This strategy encoder is used for solutions that are sent directly to the pool.
|
/// This strategy encoder is used for solutions that are sent directly to the pool.
|
||||||
/// Only 1 solution with 1 swap is supported.
|
/// Only one solution with one swap is supported.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
///
|
||||||
|
/// * `swap_encoder_registry`: SwapEncoderRegistry, containing all possible swap encoders
|
||||||
pub struct ExecutorStrategyEncoder {
|
pub struct ExecutorStrategyEncoder {
|
||||||
swap_encoder_registry: SwapEncoderRegistry,
|
swap_encoder_registry: SwapEncoderRegistry,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ use crate::encoding::{
|
|||||||
swap_encoder::SwapEncoder,
|
swap_encoder::SwapEncoder,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Encodes a swap on a Uniswap V2 pool through the given executor address.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
||||||
|
/// * `executor_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,
|
||||||
@@ -66,6 +72,11 @@ impl SwapEncoder for UniswapV2SwapEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Encodes a swap on a Uniswap V3 pool through the given executor address.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
||||||
|
/// * `executor_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,6 +151,11 @@ impl SwapEncoder for UniswapV3SwapEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Encodes a swap on a Balancer pool through the given executor address.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `executor_address` - The address of the executor contract that will perform the swap.
|
||||||
|
/// * `executor_selector` - The selector of the swap function in the executor contract.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BalancerV2SwapEncoder {
|
pub struct BalancerV2SwapEncoder {
|
||||||
executor_address: String,
|
executor_address: String,
|
||||||
|
|||||||
@@ -11,8 +11,15 @@ use crate::encoding::{
|
|||||||
tycho_encoder::TychoEncoder,
|
tycho_encoder::TychoEncoder,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Represents an encoder for a swap through the given router address using any strategy supported
|
||||||
|
/// by the strategy registry.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `strategy_registry`: S, the strategy registry to use to select the best strategy to encode a
|
||||||
|
/// solution, based on its supported strategies and the solution attributes.
|
||||||
|
/// * `router_address`: Bytes, the address of the router to use to execute the swaps.
|
||||||
pub struct EVMTychoEncoder<S: StrategyEncoderRegistry> {
|
pub struct EVMTychoEncoder<S: StrategyEncoderRegistry> {
|
||||||
strategy_selector: S,
|
strategy_registry: S,
|
||||||
router_address: Bytes,
|
router_address: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,7 +27,7 @@ impl<S: StrategyEncoderRegistry> EVMTychoEncoder<S> {
|
|||||||
pub fn new(strategy_selector: S, router_address: String) -> Result<Self, EncodingError> {
|
pub fn new(strategy_selector: S, router_address: String) -> Result<Self, EncodingError> {
|
||||||
let router_address = Bytes::from_str(&router_address)
|
let router_address = Bytes::from_str(&router_address)
|
||||||
.map_err(|_| EncodingError::FatalError("Invalid router address".to_string()))?;
|
.map_err(|_| EncodingError::FatalError("Invalid router address".to_string()))?;
|
||||||
Ok(EVMTychoEncoder { strategy_selector, router_address })
|
Ok(EVMTychoEncoder { strategy_registry: strategy_selector, router_address })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +89,7 @@ impl<S: StrategyEncoderRegistry> TychoEncoder<S> for EVMTychoEncoder<S> {
|
|||||||
.unwrap_or(self.router_address.clone());
|
.unwrap_or(self.router_address.clone());
|
||||||
|
|
||||||
let strategy = self
|
let strategy = self
|
||||||
.strategy_selector
|
.strategy_registry
|
||||||
.get_encoder(solution)?;
|
.get_encoder(solution)?;
|
||||||
let (contract_interaction, target_address) =
|
let (contract_interaction, target_address) =
|
||||||
strategy.encode_strategy(solution.clone(), router_address)?;
|
strategy.encode_strategy(solution.clone(), router_address)?;
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use num_bigint::BigUint;
|
use num_bigint::BigUint;
|
||||||
use tycho_core::{dto::ProtocolComponent, Bytes};
|
use tycho_core::{dto::ProtocolComponent, Bytes};
|
||||||
|
|
||||||
|
/// Represents a solution containing details describing an order, and instructions for filling
|
||||||
|
/// the order.
|
||||||
#[derive(Clone, Default, Debug)]
|
#[derive(Clone, Default, Debug)]
|
||||||
pub struct Solution {
|
pub struct Solution {
|
||||||
/// Address of the sender.
|
/// Address of the sender.
|
||||||
@@ -35,12 +37,17 @@ pub struct Solution {
|
|||||||
pub direct_execution: bool,
|
pub direct_execution: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents an action to be performed on the native token either before or after the swap.
|
||||||
|
/// `Wrap` means that the native token will be wrapped before the first swap, and `Unwrap`
|
||||||
|
/// means that the native token will be unwrapped after the last swap, before being sent to the
|
||||||
|
/// receiver.
|
||||||
#[derive(Clone, PartialEq, Debug)]
|
#[derive(Clone, PartialEq, Debug)]
|
||||||
pub enum NativeAction {
|
pub enum NativeAction {
|
||||||
Wrap,
|
Wrap,
|
||||||
Unwrap,
|
Unwrap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents a swap operation to be performed on a pool.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Swap {
|
pub struct Swap {
|
||||||
/// Protocol component from tycho indexer
|
/// Protocol component from tycho indexer
|
||||||
@@ -49,10 +56,16 @@ pub struct Swap {
|
|||||||
pub token_in: Bytes,
|
pub token_in: Bytes,
|
||||||
/// Token being output from the pool.
|
/// Token being output from the pool.
|
||||||
pub token_out: Bytes,
|
pub token_out: Bytes,
|
||||||
/// Percentage of the amount to be swapped in this operation (for example, 0.5 means 50%)
|
/// Decimal of the amount to be swapped in this operation (for example, 0.5 means 50%)
|
||||||
pub split: f64,
|
pub split: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents a transaction to be executed on the Ethereum network.
|
||||||
|
///
|
||||||
|
/// # Fields
|
||||||
|
/// * `to`: Address of the contract to call with the calldata
|
||||||
|
/// * `value`: ETH value to be sent with the transaction.
|
||||||
|
/// * `data`: Encoded calldata for the transaction.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
// Address of the contract to call with the calldata
|
// Address of the contract to call with the calldata
|
||||||
@@ -63,6 +76,8 @@ pub struct Transaction {
|
|||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Represents necessary attributes for encoding an order.
|
||||||
pub struct EncodingContext {
|
pub struct EncodingContext {
|
||||||
pub receiver: Bytes,
|
pub receiver: Bytes,
|
||||||
pub exact_out: bool,
|
pub exact_out: bool,
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ pub trait StrategyEncoder {
|
|||||||
fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box<dyn SwapEncoder>>;
|
fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box<dyn SwapEncoder>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Contains the supported strategies to encode a solution, and chooses the best strategy to encode
|
||||||
|
/// a solution based on the solution's attributes.
|
||||||
pub trait StrategyEncoderRegistry {
|
pub trait StrategyEncoderRegistry {
|
||||||
fn new(
|
fn new(
|
||||||
chain: Chain,
|
chain: Chain,
|
||||||
@@ -21,6 +24,8 @@ pub trait StrategyEncoderRegistry {
|
|||||||
) -> Result<Self, EncodingError>
|
) -> Result<Self, EncodingError>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
|
/// Returns the strategy encoder that should be used to encode the given solution.
|
||||||
#[allow(clippy::borrowed_box)]
|
#[allow(clippy::borrowed_box)]
|
||||||
fn get_encoder(&self, solution: &Solution) -> Result<&Box<dyn StrategyEncoder>, EncodingError>;
|
fn get_encoder(&self, solution: &Solution) -> Result<&Box<dyn StrategyEncoder>, EncodingError>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ use crate::encoding::{
|
|||||||
errors::EncodingError,
|
errors::EncodingError,
|
||||||
models::{EncodingContext, Swap},
|
models::{EncodingContext, Swap},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// This trait must be implemented in order to encode a swap for a specific protocol.
|
||||||
pub trait SwapEncoder: Sync + Send {
|
pub trait SwapEncoder: Sync + Send {
|
||||||
fn new(executor_address: String) -> Self
|
fn new(executor_address: String) -> Self
|
||||||
where
|
where
|
||||||
|
|||||||
Reference in New Issue
Block a user