feat: Create a EVMEncoderBuilder
- It has two three methods to be created: - new: where the user can pass any custom StrategyEncoder - tycho_router: where the default SplitSwapStrategyEncoder with Tycho Router will be used - direct_execution: where the user can encode only the execution data and integrate this into their workflow. - This replaces StrategyEncoderRegistry - EVMTychoEncoder holds directly the StrategyEncoder and not the registry (per one init of the EVMTychoEncoder there is only one possible StrategyEncoder) - Update quickstart - Update bin (add subcommands to bin to create a different instance of EVMEncoderBuilder) --- don't change below this line --- ENG-4246 Took 33 minutes Took 38 seconds Took 38 seconds
This commit is contained in:
48
README.md
48
README.md
@@ -24,30 +24,46 @@ cargo build --release
|
||||
cargo install --path .
|
||||
```
|
||||
|
||||
After installation, the `tycho-encode` command will be available to use from any directory in your terminal. The command
|
||||
accepts the following options:
|
||||
After installation, the `tycho-encode` command will be available to use from any directory in your terminal.
|
||||
|
||||
### Commands
|
||||
|
||||
The command lets you choose the encoding strategy to be used. The available strategies are:
|
||||
|
||||
#### Tycho Router
|
||||
|
||||
`tycho-router`: Encodes a transaction using the Tycho Router encoding strategy. Requires a private key for signing
|
||||
Permit2.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
echo '<solution_payload>' | tycho-encode tycho-router -p 0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234
|
||||
```
|
||||
|
||||
#### Direct execution
|
||||
|
||||
`direct-execution`: Encodes a transaction using the direct execution encoding strategy. Does not require a private key.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
echo '<solution_payload>' | tycho-encode direct-execution
|
||||
```
|
||||
|
||||
### Encoding Transactions
|
||||
|
||||
The commands accept the following options:
|
||||
|
||||
- `-c`: Path to the executor addresses configuration file (defaults to `src/encoding/config/executor_addresses.json`)
|
||||
- `-p`: Private key for signing approvals (required when direct_execution is false)
|
||||
|
||||
### Encoding Transactions
|
||||
|
||||
To encode a transaction, you can pipe a JSON payload to the binary:
|
||||
|
||||
```bash
|
||||
# Using default config path
|
||||
echo '<solution_payload>' | tycho-encode
|
||||
|
||||
# Using custom config path
|
||||
echo '<solution_payload>' | tycho-encode -c /path/to/your/config.json
|
||||
```
|
||||
|
||||
#### Example
|
||||
|
||||
Here's a complete example that encodes a swap from WETH to DAI using Uniswap V2:
|
||||
Here's a complete example that encodes a swap from WETH to DAI using Uniswap V2 and the Tycho Router strategy:
|
||||
|
||||
```bash
|
||||
echo '{"sender":"0x1234567890123456789012345678901234567890","receiver":"0x1234567890123456789012345678901234567890","given_token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","given_amount":"1000000000000000000","checked_token":"0x6B175474E89094C44Da98b954EedeAC495271d0F","exact_out":false,"slippage":0.01,"expected_amount":"1000000000000000000","checked_amount":"990000000000000000","router_address":"0xaa820C29648D5EA543d712cC928377Bd7206a0E7","swaps":[{"component":{"id":"0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640","protocol_system":"uniswap_v2","protocol_type_name":"UniswapV2Pool","chain":"ethereum","tokens":["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"],"contract_ids":["0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"],"static_attributes":{"factory":"0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f"},"change":"Update","creation_tx":"0x0000000000000000000000000000000000000000000000000000000000000000","created_at":"2024-02-28T12:00:00"},"token_in":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","token_out":"0x6B175474E89094C44Da98b954EedeAC495271d0F","split":1.0}],"direct_execution":true}' | tycho-encode
|
||||
echo '{"sender":"0x1234567890123456789012345678901234567890","receiver":"0x1234567890123456789012345678901234567890","given_token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","given_amount":"1000000000000000000","checked_token":"0x6B175474E89094C44Da98b954EedeAC495271d0F","exact_out":false,"slippage":0.01,"expected_amount":"1000000000000000000","checked_amount":"990000000000000000","router_address":"0xaa820C29648D5EA543d712cC928377Bd7206a0E7","swaps":[{"component":{"id":"0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640","protocol_system":"uniswap_v2","protocol_type_name":"UniswapV2Pool","chain":"ethereum","tokens":["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"],"contract_ids":["0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D"],"static_attributes":{"factory":"0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f"},"change":"Update","creation_tx":"0x0000000000000000000000000000000000000000000000000000000000000000","created_at":"2024-02-28T12:00:00"},"token_in":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","token_out":"0x6B175474E89094C44Da98b954EedeAC495271d0F","split":0.0}],"direct_execution":true}' | tycho-encode tycho-router -p 0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234
|
||||
```
|
||||
|
||||
#### JSON Payload Structure: Solution struct
|
||||
|
||||
@@ -6,12 +6,8 @@ use tycho_core::{
|
||||
Bytes,
|
||||
};
|
||||
use tycho_execution::encoding::{
|
||||
evm::{
|
||||
strategy_encoder::strategy_encoder_registry::EVMStrategyEncoderRegistry,
|
||||
tycho_encoder::EVMTychoEncoder,
|
||||
},
|
||||
evm::encoder_builder::EVMEncoderBuilder,
|
||||
models::{Solution, Swap},
|
||||
strategy_encoder::StrategyEncoderRegistry,
|
||||
tycho_encoder::TychoEncoder,
|
||||
};
|
||||
|
||||
@@ -20,16 +16,15 @@ fn main() {
|
||||
let router_address = Bytes::from_str("0x1234567890abcdef1234567890abcdef12345678")
|
||||
.expect("Failed to create router address");
|
||||
let signer_pk =
|
||||
Some("0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234".to_string());
|
||||
"0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234".to_string();
|
||||
let user_address = Bytes::from_str("0xcd09f75E2BF2A4d11F3AB23f1389FcC1621c0cc2")
|
||||
.expect("Failed to create user address");
|
||||
|
||||
// Initialize the encoder
|
||||
let strategy_encoder_registry =
|
||||
EVMStrategyEncoderRegistry::new(TychoCoreChain::Ethereum, None, signer_pk.clone())
|
||||
.expect("Failed to create strategy encoder registry");
|
||||
let encoder = EVMTychoEncoder::new(strategy_encoder_registry, TychoCoreChain::Ethereum)
|
||||
.expect("Failed to create encoder");
|
||||
let encoder = EVMEncoderBuilder::tycho_router(TychoCoreChain::Ethereum, signer_pk, None)
|
||||
.expect("Failed to create encoder builder")
|
||||
.build()
|
||||
.expect("Failed to build encoder");
|
||||
|
||||
// ------------------- Encode a simple swap -------------------
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
pub use clap::Parser;
|
||||
use clap::Subcommand;
|
||||
|
||||
#[derive(Parser)]
|
||||
/// Encode swap transactions for the Tycho router
|
||||
@@ -33,12 +34,24 @@ pub use clap::Parser;
|
||||
/// "direct_execution": false
|
||||
/// }
|
||||
/// ```
|
||||
#[command(author, version, about, long_about = None)]
|
||||
pub struct Cli {
|
||||
/// Private key for signing approvals (required when direct_execution is false)
|
||||
#[arg(short)]
|
||||
pub private_key: Option<String>,
|
||||
|
||||
/// Path to the executor addresses configuration file
|
||||
#[arg(short)]
|
||||
pub config_path: Option<String>,
|
||||
#[command(subcommand)]
|
||||
pub command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum Commands {
|
||||
/// Use the Tycho router encoding strategy
|
||||
TychoRouter {
|
||||
#[arg(short, long)]
|
||||
config_path: Option<String>,
|
||||
#[arg(short, long)]
|
||||
private_key: String,
|
||||
},
|
||||
/// Use the direct execution encoding strategy
|
||||
DirectExecution {
|
||||
#[arg(short, long)]
|
||||
config_path: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -3,21 +3,16 @@ use std::io::{self, Read};
|
||||
use clap::Parser;
|
||||
use serde_json::Value;
|
||||
use tycho_core::dto::Chain;
|
||||
use tycho_execution::encoding::{
|
||||
evm::{
|
||||
strategy_encoder::strategy_encoder_registry::EVMStrategyEncoderRegistry,
|
||||
tycho_encoder::EVMTychoEncoder,
|
||||
},
|
||||
models::Solution,
|
||||
strategy_encoder::StrategyEncoderRegistry,
|
||||
tycho_encoder::TychoEncoder,
|
||||
};
|
||||
use tycho_execution::encoding::{models::Solution, tycho_encoder::TychoEncoder};
|
||||
|
||||
mod lib {
|
||||
pub mod cli;
|
||||
}
|
||||
|
||||
use lib::cli::Cli;
|
||||
use tycho_execution::encoding::{errors::EncodingError, evm::encoder_builder::EVMEncoderBuilder};
|
||||
|
||||
use crate::lib::cli::Commands;
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let cli = Cli::parse();
|
||||
@@ -33,8 +28,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
}
|
||||
|
||||
// Encode the solution
|
||||
let encoded = encode_swaps(&buffer, cli.config_path, cli.private_key)?;
|
||||
|
||||
let encoded = match cli.command {
|
||||
Commands::TychoRouter { config_path, private_key } => {
|
||||
encode_swaps(&buffer, config_path, Some(private_key), true)?
|
||||
}
|
||||
Commands::DirectExecution { config_path } => {
|
||||
encode_swaps(&buffer, config_path, None, false)?
|
||||
}
|
||||
};
|
||||
// Output the encoded result as JSON to stdout
|
||||
println!(
|
||||
"{}",
|
||||
@@ -49,12 +50,20 @@ fn encode_swaps(
|
||||
input: &str,
|
||||
config_path: Option<String>,
|
||||
private_key: Option<String>,
|
||||
) -> Result<Value, Box<dyn std::error::Error>> {
|
||||
use_tycho_router: bool,
|
||||
) -> Result<Value, EncodingError> {
|
||||
let solution: Solution = serde_json::from_str(input)?;
|
||||
let chain = Chain::Ethereum;
|
||||
|
||||
let strategy_selector = EVMStrategyEncoderRegistry::new(chain, config_path, private_key)?;
|
||||
let encoder = EVMTychoEncoder::new(strategy_selector, chain)?;
|
||||
let encoder = if use_tycho_router {
|
||||
let private_key = private_key.ok_or(EncodingError::FatalError(
|
||||
"Private key is required for tycho_router".to_string(),
|
||||
))?;
|
||||
EVMEncoderBuilder::tycho_router(chain, private_key, config_path)?.build()?
|
||||
} else {
|
||||
EVMEncoderBuilder::direct_execution(chain, config_path)?.build()?
|
||||
};
|
||||
|
||||
let transactions = encoder.encode_router_calldata(vec![solution])?;
|
||||
|
||||
Ok(serde_json::json!({
|
||||
|
||||
44
src/encoding/evm/encoder_builder.rs
Normal file
44
src/encoding/evm/encoder_builder.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
use tycho_core::dto::Chain;
|
||||
|
||||
use crate::encoding::{
|
||||
errors::EncodingError,
|
||||
evm::{
|
||||
strategy_encoders::{ExecutorStrategyEncoder, SplitSwapStrategyEncoder},
|
||||
swap_encoder::swap_encoder_registry::SwapEncoderRegistry,
|
||||
tycho_encoder::EVMTychoEncoder,
|
||||
},
|
||||
strategy_encoder::StrategyEncoder,
|
||||
};
|
||||
|
||||
pub struct EVMEncoderBuilder {
|
||||
strategy: Box<dyn StrategyEncoder>,
|
||||
chain: Chain,
|
||||
}
|
||||
|
||||
impl EVMEncoderBuilder {
|
||||
pub fn new(chain: Chain, strategy: Box<dyn StrategyEncoder>) -> Self {
|
||||
EVMEncoderBuilder { chain, strategy }
|
||||
}
|
||||
pub fn tycho_router(
|
||||
chain: Chain,
|
||||
signer_pk: String,
|
||||
executors_file_path: Option<String>,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let swap_encoder_registry = SwapEncoderRegistry::new(executors_file_path, chain)?;
|
||||
let strategy =
|
||||
Box::new(SplitSwapStrategyEncoder::new(signer_pk, chain, swap_encoder_registry)?);
|
||||
Ok(EVMEncoderBuilder { chain, strategy })
|
||||
}
|
||||
pub fn direct_execution(
|
||||
chain: Chain,
|
||||
executors_file_path: Option<String>,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let swap_encoder_registry = SwapEncoderRegistry::new(executors_file_path, chain)?;
|
||||
let strategy = Box::new(ExecutorStrategyEncoder::new(swap_encoder_registry));
|
||||
Ok(EVMEncoderBuilder { chain, strategy })
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<EVMTychoEncoder, EncodingError> {
|
||||
EVMTychoEncoder::new(self.chain, self.strategy)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod approvals;
|
||||
mod constants;
|
||||
pub mod strategy_encoder;
|
||||
pub mod encoder_builder;
|
||||
pub mod strategy_encoders;
|
||||
mod swap_encoder;
|
||||
pub mod tycho_encoder;
|
||||
pub mod utils;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
mod group_swaps;
|
||||
pub mod strategy_encoder_registry;
|
||||
mod strategy_encoders;
|
||||
mod strategy_validators;
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::encoding::{
|
||||
errors::EncodingError,
|
||||
evm::{
|
||||
strategy_encoder::strategy_encoders::{ExecutorStrategyEncoder, SplitSwapStrategyEncoder},
|
||||
swap_encoder::swap_encoder_registry::SwapEncoderRegistry,
|
||||
},
|
||||
models::{Chain, Solution},
|
||||
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 {
|
||||
strategies: HashMap<String, Box<dyn StrategyEncoder>>,
|
||||
}
|
||||
|
||||
impl StrategyEncoderRegistry for EVMStrategyEncoderRegistry {
|
||||
fn new(
|
||||
chain: tycho_core::dto::Chain,
|
||||
executors_file_path: Option<String>,
|
||||
signer_pk: Option<String>,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let chain = Chain::from(chain);
|
||||
let swap_encoder_registry = SwapEncoderRegistry::new(executors_file_path, chain.clone())?;
|
||||
|
||||
let mut strategies: HashMap<String, Box<dyn StrategyEncoder>> = HashMap::new();
|
||||
strategies.insert(
|
||||
"executor".to_string(),
|
||||
Box::new(ExecutorStrategyEncoder::new(swap_encoder_registry.clone())),
|
||||
);
|
||||
if let Some(signer) = signer_pk {
|
||||
strategies.insert(
|
||||
"split_swap".to_string(),
|
||||
Box::new(
|
||||
SplitSwapStrategyEncoder::new(signer, chain, swap_encoder_registry).unwrap(),
|
||||
),
|
||||
);
|
||||
}
|
||||
Ok(Self { strategies })
|
||||
}
|
||||
fn get_encoder(&self, solution: &Solution) -> Result<&Box<dyn StrategyEncoder>, EncodingError> {
|
||||
if solution.direct_execution {
|
||||
self.strategies
|
||||
.get("executor")
|
||||
.ok_or(EncodingError::FatalError("Executor strategy not found".to_string()))
|
||||
} else {
|
||||
self.strategies
|
||||
.get("split_swap")
|
||||
.ok_or(EncodingError::FatalError("Split swap strategy not found. Please pass the signer private key to the StrategySelector constructor".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for EVMStrategyEncoderRegistry {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
strategies: self
|
||||
.strategies
|
||||
.iter()
|
||||
.map(|(k, v)| (k.clone(), v.clone_box()))
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,9 +89,10 @@ pub struct SplitSwapStrategyEncoder {
|
||||
impl SplitSwapStrategyEncoder {
|
||||
pub fn new(
|
||||
signer_pk: String,
|
||||
chain: Chain,
|
||||
blockchain: tycho_core::dto::Chain,
|
||||
swap_encoder_registry: SwapEncoderRegistry,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let chain = Chain::from(blockchain);
|
||||
let selector = "swap(uint256,address,address,uint256,bool,bool,uint256,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string();
|
||||
Ok(Self {
|
||||
permit2: Permit2::new(signer_pk, chain.clone())?,
|
||||
@@ -337,8 +338,8 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::encoding::models::Swap;
|
||||
|
||||
fn eth_chain() -> Chain {
|
||||
TychoCoreChain::Ethereum.into()
|
||||
fn eth_chain() -> TychoCoreChain {
|
||||
TychoCoreChain::Ethereum
|
||||
}
|
||||
|
||||
fn eth() -> Bytes {
|
||||
@@ -19,8 +19,9 @@ impl SwapEncoderRegistry {
|
||||
/// executors' addresses in the file at the given path.
|
||||
pub fn new(
|
||||
executors_file_path: Option<String>,
|
||||
blockchain: Chain,
|
||||
blockchain: tycho_core::dto::Chain,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let chain = Chain::from(blockchain);
|
||||
let config_str = if let Some(ref path) = executors_file_path {
|
||||
fs::read_to_string(path).map_err(|e| {
|
||||
EncodingError::FatalError(format!(
|
||||
@@ -34,8 +35,8 @@ impl SwapEncoderRegistry {
|
||||
let config: HashMap<String, HashMap<String, String>> = serde_json::from_str(&config_str)?;
|
||||
let mut encoders = HashMap::new();
|
||||
let executors = config
|
||||
.get(&blockchain.name)
|
||||
.ok_or(EncodingError::FatalError("No executors found for blockchain".to_string()))?;
|
||||
.get(&chain.name)
|
||||
.ok_or(EncodingError::FatalError("No executors found for chain".to_string()))?;
|
||||
for (protocol, executor_address) in executors {
|
||||
let builder = SwapEncoderBuilder::new(protocol, executor_address);
|
||||
let encoder = builder.build()?;
|
||||
|
||||
@@ -4,26 +4,27 @@ use tycho_core::Bytes;
|
||||
use crate::encoding::{
|
||||
errors::EncodingError,
|
||||
models::{Chain, NativeAction, Solution, Transaction},
|
||||
strategy_encoder::StrategyEncoderRegistry,
|
||||
strategy_encoder::StrategyEncoder,
|
||||
tycho_encoder::TychoEncoder,
|
||||
};
|
||||
|
||||
/// Represents an encoder for a swap 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.
|
||||
/// * `strategy_encoder`: Strategy encoder to follow for encoding the solution
|
||||
/// * `native_address`: Address of the chain's native token
|
||||
/// * `wrapped_address`: Address of the chain's wrapped native token
|
||||
#[derive(Clone)]
|
||||
pub struct EVMTychoEncoder<S: StrategyEncoderRegistry> {
|
||||
strategy_registry: S,
|
||||
pub struct EVMTychoEncoder {
|
||||
strategy_encoder: Box<dyn StrategyEncoder>,
|
||||
native_address: Bytes,
|
||||
wrapped_address: Bytes,
|
||||
}
|
||||
|
||||
impl<S: StrategyEncoderRegistry> EVMTychoEncoder<S> {
|
||||
pub fn new(strategy_registry: S, chain: tycho_core::dto::Chain) -> Result<Self, EncodingError> {
|
||||
impl EVMTychoEncoder {
|
||||
pub fn new(
|
||||
chain: tycho_core::dto::Chain,
|
||||
strategy_encoder: Box<dyn StrategyEncoder>,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let chain: Chain = Chain::from(chain);
|
||||
if chain.name != *"ethereum" {
|
||||
return Err(EncodingError::InvalidInput(
|
||||
@@ -31,14 +32,14 @@ impl<S: StrategyEncoderRegistry> EVMTychoEncoder<S> {
|
||||
));
|
||||
}
|
||||
Ok(EVMTychoEncoder {
|
||||
strategy_registry,
|
||||
strategy_encoder,
|
||||
native_address: chain.native_token()?,
|
||||
wrapped_address: chain.wrapped_token()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: StrategyEncoderRegistry> EVMTychoEncoder<S> {
|
||||
impl EVMTychoEncoder {
|
||||
/// Raises an `EncodingError` if the solution is not considered valid.
|
||||
///
|
||||
/// A solution is considered valid if all the following conditions are met:
|
||||
@@ -92,7 +93,7 @@ impl<S: StrategyEncoderRegistry> EVMTychoEncoder<S> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: StrategyEncoderRegistry> TychoEncoder<S> for EVMTychoEncoder<S> {
|
||||
impl TychoEncoder for EVMTychoEncoder {
|
||||
fn encode_router_calldata(
|
||||
&self,
|
||||
solutions: Vec<Solution>,
|
||||
@@ -101,11 +102,9 @@ impl<S: StrategyEncoderRegistry> TychoEncoder<S> for EVMTychoEncoder<S> {
|
||||
for solution in solutions.iter() {
|
||||
self.validate_solution(solution)?;
|
||||
|
||||
let strategy = self
|
||||
.strategy_registry
|
||||
.get_encoder(solution)?;
|
||||
let (contract_interaction, target_address, selector) =
|
||||
strategy.encode_strategy(solution.clone())?;
|
||||
let (contract_interaction, target_address, selector) = self
|
||||
.strategy_encoder
|
||||
.encode_strategy(solution.clone())?;
|
||||
|
||||
let value = match solution.native_action.as_ref() {
|
||||
Some(NativeAction::Wrap) => solution.given_amount.clone(),
|
||||
@@ -134,10 +133,6 @@ mod tests {
|
||||
models::Swap, strategy_encoder::StrategyEncoder, swap_encoder::SwapEncoder,
|
||||
};
|
||||
|
||||
struct MockStrategyRegistry {
|
||||
strategy: Box<dyn StrategyEncoder>,
|
||||
}
|
||||
|
||||
fn dai() -> Bytes {
|
||||
Bytes::from_str("0x6b175474e89094c44da98b954eedeac495271d0f").unwrap()
|
||||
}
|
||||
@@ -150,23 +145,6 @@ mod tests {
|
||||
Bytes::from_str("0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2").unwrap()
|
||||
}
|
||||
|
||||
impl StrategyEncoderRegistry for MockStrategyRegistry {
|
||||
fn new(
|
||||
_chain: tycho_core::dto::Chain,
|
||||
_executors_file_path: Option<String>,
|
||||
_signer_pk: Option<String>,
|
||||
) -> Result<MockStrategyRegistry, EncodingError> {
|
||||
Ok(Self { strategy: Box::new(MockStrategy) })
|
||||
}
|
||||
|
||||
fn get_encoder(
|
||||
&self,
|
||||
_solution: &Solution,
|
||||
) -> Result<&Box<dyn StrategyEncoder>, EncodingError> {
|
||||
Ok(&self.strategy)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct MockStrategy;
|
||||
|
||||
@@ -192,10 +170,9 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mocked_tycho_encoder() -> EVMTychoEncoder<MockStrategyRegistry> {
|
||||
let strategy_registry =
|
||||
MockStrategyRegistry::new(TychoCoreChain::Ethereum, None, None).unwrap();
|
||||
EVMTychoEncoder::new(strategy_registry, TychoCoreChain::Ethereum).unwrap()
|
||||
fn get_mocked_tycho_encoder() -> EVMTychoEncoder {
|
||||
let strategy_encoder = Box::new(MockStrategy {});
|
||||
EVMTychoEncoder::new(TychoCoreChain::Ethereum, strategy_encoder).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
mod errors;
|
||||
pub mod errors;
|
||||
#[cfg(feature = "evm")]
|
||||
pub mod evm;
|
||||
pub mod models;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use tycho_core::{dto::Chain, Bytes};
|
||||
use tycho_core::Bytes;
|
||||
|
||||
use crate::encoding::{errors::EncodingError, models::Solution, swap_encoder::SwapEncoder};
|
||||
|
||||
@@ -13,19 +13,3 @@ pub trait StrategyEncoder {
|
||||
fn get_swap_encoder(&self, protocol_system: &str) -> Option<&Box<dyn SwapEncoder>>;
|
||||
fn clone_box(&self) -> Box<dyn StrategyEncoder>;
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
fn new(
|
||||
chain: Chain,
|
||||
executors_file_path: Option<String>,
|
||||
signer_pk: Option<String>,
|
||||
) -> Result<Self, EncodingError>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Returns the strategy encoder that should be used to encode the given solution.
|
||||
#[allow(clippy::borrowed_box)]
|
||||
fn get_encoder(&self, solution: &Solution) -> Result<&Box<dyn StrategyEncoder>, EncodingError>;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::encoding::{
|
||||
errors::EncodingError,
|
||||
models::{Solution, Transaction},
|
||||
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> {
|
||||
pub trait TychoEncoder {
|
||||
fn encode_router_calldata(
|
||||
&self,
|
||||
solutions: Vec<Solution>,
|
||||
|
||||
Reference in New Issue
Block a user