diff --git a/Cargo.lock b/Cargo.lock index 370911a..91af9cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3039,7 +3039,7 @@ dependencies = [ [[package]] name = "tycho-execution" -version = "1.0.0" +version = "0.1.0" dependencies = [ "alloy", "alloy-primitives", diff --git a/src/encoding/approvals/approvals_manager.rs b/src/encoding/approvals/approvals_manager.rs index 620a678..fde5442 100644 --- a/src/encoding/approvals/approvals_manager.rs +++ b/src/encoding/approvals/approvals_manager.rs @@ -1,33 +1,32 @@ use std::{env, sync::Arc}; use alloy::{ - providers::{Provider, ProviderBuilder, RootProvider}, + providers::{ProviderBuilder, RootProvider}, transports::BoxTransport, }; use alloy_primitives::Address; use dotenv::dotenv; +#[allow(dead_code)] pub struct ProtocolApprovalsManager { client: Arc>, } impl ProtocolApprovalsManager { pub fn new() -> Self { - Self { - client: get_client(), - } + Self { client: get_client() } } pub async fn approval_needed( &self, - token: Address, - spender_address: Address, - router_address: Address, + _token: Address, + _spender_address: Address, + _router_address: Address, ) -> bool { todo!() // should be something like // let allowance = self // .client - // .call(token, "allowance(address,address)(uint256)", (router_address, spender_address)) - // .await; + // .call(token, "allowance(address,address)(uint256)", (router_address, + // spender_address)) .await; // // allowance == U256::ZERO // If allowance is 0, approval is needed } diff --git a/src/encoding/approvals/interface.rs b/src/encoding/approvals/interface.rs index 405ef11..45ca74e 100644 --- a/src/encoding/approvals/interface.rs +++ b/src/encoding/approvals/interface.rs @@ -1,6 +1,7 @@ use num_bigint::BigUint; use tycho_core::Bytes; +#[allow(dead_code)] pub struct Approval { pub spender: Bytes, pub owner: Bytes, @@ -9,5 +10,6 @@ pub struct Approval { } pub trait UserApprovalsManager { + #[allow(dead_code)] fn encode_approvals(&self, approvals: Vec) -> Vec; } diff --git a/src/encoding/approvals/permit2.rs b/src/encoding/approvals/permit2.rs index 66bbdb9..e89adbd 100644 --- a/src/encoding/approvals/permit2.rs +++ b/src/encoding/approvals/permit2.rs @@ -1,12 +1,16 @@ -use crate::encoding::approvals::interface::{Approval, UserApprovalsManager}; -use alloy_primitives::U256; use std::str::FromStr; + +use alloy_primitives::U256; use tycho_core::Bytes; +use crate::encoding::approvals::interface::{Approval, UserApprovalsManager}; + +#[allow(dead_code)] pub struct Permit2 { pub address: Bytes, } +#[allow(dead_code)] impl Permit2 { pub fn new() -> Self { Self { @@ -16,9 +20,9 @@ impl Permit2 { } fn get_allowance_data( &self, - user: Bytes, - router_address: Bytes, - token: Bytes, + _user: Bytes, + _router_address: Bytes, + _token: Bytes, ) -> (U256, u64, U256) { // get allowance data (if it exists) and the nonce // returns permitAmount, expiration, nonce @@ -26,12 +30,12 @@ impl Permit2 { } } impl UserApprovalsManager for Permit2 { - fn encode_approvals(&self, approvals: Vec) -> Vec { + fn encode_approvals(&self, _approvals: Vec) -> Vec { // calls get_allowance_data to get nonce // checks if we are not permitted already - // puts data into a permitSingle struct if there is only 1 PermitDetails, if there are several, use PermitBatch - // adds the nonce and the expiration (uniswap recommends 30 days for expiration) - // signs data + // puts data into a permitSingle struct if there is only 1 PermitDetails, if there are + // several, use PermitBatch adds the nonce and the expiration (uniswap recommends + // 30 days for expiration) signs data // returns encoded data todo!() } diff --git a/src/encoding/models.rs b/src/encoding/models.rs index 94cbff9..89ad2e1 100644 --- a/src/encoding/models.rs +++ b/src/encoding/models.rs @@ -1,7 +1,7 @@ +use std::{env, str::FromStr}; + use lazy_static::lazy_static; use num_bigint::BigUint; -use std::env; -use std::str::FromStr; use tycho_core::{dto::ProtocolComponent, Bytes}; lazy_static! { @@ -12,6 +12,7 @@ lazy_static! { } #[derive(Clone)] +#[allow(dead_code)] pub struct Solution { /// True if the solution is an exact output solution. pub exact_out: bool, @@ -32,8 +33,9 @@ pub struct Solution { pub receiver: Bytes, /// List of swaps to fulfill the solution. pub swaps: Vec, - /// If set to true, the solution will be encoded to be sent directly to the SwapExecutor and skip the router. - /// The user is responsible for managing necessary approvals and token transfers. + /// If set to true, the solution will be encoded to be sent directly to the SwapExecutor and + /// skip the router. The user is responsible for managing necessary approvals and token + /// transfers. pub straight_to_pool: bool, // if not set, then the Propeller Router will be used pub router_address: Option, @@ -44,6 +46,7 @@ pub struct Solution { } #[derive(Clone, PartialEq)] +#[allow(dead_code)] pub enum NativeAction { Wrap, Unwrap, @@ -61,6 +64,7 @@ pub struct Swap { pub split: f64, } +#[allow(dead_code)] pub struct Transaction { pub data: Vec, // ETH value to be sent with the transaction. diff --git a/src/encoding/router_encoder.rs b/src/encoding/router_encoder.rs index a57a7da..1f44bf9 100644 --- a/src/encoding/router_encoder.rs +++ b/src/encoding/router_encoder.rs @@ -1,44 +1,46 @@ -use crate::encoding::approvals::interface::{Approval, UserApprovalsManager}; -use crate::encoding::models::{NativeAction, Solution, Transaction, PROPELLER_ROUTER_ADDRESS}; -use crate::encoding::strategy_selector::StrategySelector; -use crate::encoding::utils::{encode_input, ple_encode}; use alloy_sol_types::SolValue; use anyhow::Error; use num_bigint::BigUint; +use crate::encoding::{ + approvals::interface::{Approval, UserApprovalsManager}, + models::{NativeAction, Solution, Transaction, PROPELLER_ROUTER_ADDRESS}, + strategy_selector::StrategySelector, + utils::{encode_input, ple_encode}, +}; + +#[allow(dead_code)] struct RouterEncoder { strategy_selector: S, approvals_manager: A, } +#[allow(dead_code)] impl RouterEncoder { pub fn new(strategy_selector: S, approvals_manager: A) -> Self { - RouterEncoder { - strategy_selector, - approvals_manager, - } + RouterEncoder { strategy_selector, approvals_manager } } pub fn encode_router_calldata(&self, solutions: Vec) -> Result { - let approvals_calldata = self.handle_approvals(&solutions)?; // TODO: where should we append this? + let _approvals_calldata = self.handle_approvals(&solutions)?; // TODO: where should we append this? let mut calldata_list: Vec> = Vec::new(); let encode_for_batch_execute = solutions.len() > 1; let mut value = BigUint::ZERO; for solution in solutions.iter() { - let exact_out = solution.exact_out.clone(); - let straight_to_pool = solution.straight_to_pool.clone(); + let exact_out = solution.exact_out; + let straight_to_pool = solution.straight_to_pool; - let strategy = self.strategy_selector.select_strategy(&solution); + let strategy = self + .strategy_selector + .select_strategy(solution); let method_calldata = strategy.encode_strategy((*solution).clone())?; let contract_interaction = if encode_for_batch_execute { let args = (strategy.action_type(exact_out) as u16, method_calldata); args.abi_encode() + } else if straight_to_pool { + method_calldata } else { - if straight_to_pool { - method_calldata - } else { - encode_input(strategy.selector(exact_out), method_calldata) - } + encode_input(strategy.selector(exact_out), method_calldata) }; calldata_list.push(contract_interaction); @@ -56,7 +58,7 @@ impl RouterEncoder { Ok(Transaction { data, value }) } - fn handle_approvals(&self, solutions: &Vec) -> Result, Error> { + fn handle_approvals(&self, solutions: &[Solution]) -> Result, Error> { let mut approvals = Vec::new(); for solution in solutions.iter() { approvals.push(Approval { @@ -69,6 +71,8 @@ impl RouterEncoder { owner: solution.sender.clone(), }); } - Ok(self.approvals_manager.encode_approvals(approvals)) + Ok(self + .approvals_manager + .encode_approvals(approvals)) } } diff --git a/src/encoding/strategy_encoder.rs b/src/encoding/strategy_encoder.rs index c2eb5f8..63d3ef4 100644 --- a/src/encoding/strategy_encoder.rs +++ b/src/encoding/strategy_encoder.rs @@ -1,16 +1,18 @@ +use std::cmp::min; + use alloy_primitives::Address; use alloy_sol_types::SolValue; use anyhow::Error; use num_bigint::BigUint; use num_traits::Zero; -use std::cmp::min; -use crate::encoding::models::{ - ActionType, EncodingContext, NativeAction, Solution, PROPELLER_ROUTER_ADDRESS, +use crate::encoding::{ + models::{ActionType, EncodingContext, NativeAction, Solution, PROPELLER_ROUTER_ADDRESS}, + swap_encoder::SWAP_ENCODER_REGISTRY, + utils::{biguint_to_u256, ple_encode}, }; -use crate::encoding::swap_encoder::SWAP_ENCODER_REGISTRY; -use crate::encoding::utils::{biguint_to_u256, ple_encode}; +#[allow(dead_code)] pub trait StrategyEncoder { fn encode_strategy(&self, to_encode: Solution) -> Result, Error>; @@ -34,7 +36,7 @@ pub trait StrategyEncoder { pub struct SingleSwapStrategyEncoder {} impl StrategyEncoder for SingleSwapStrategyEncoder { - fn encode_strategy(&self, solution: Solution) -> Result, Error> { + fn encode_strategy(&self, _solution: Solution) -> Result, Error> { todo!() } @@ -86,11 +88,7 @@ impl StrategyEncoder for SequentialStrategyEncoder { } else { PROPELLER_ROUTER_ADDRESS.clone() }; - let receiver = if is_last { - solution.receiver.clone() - } else { - router_address.clone() - }; + let receiver = if is_last { solution.receiver.clone() } else { router_address.clone() }; let encoding_context = EncodingContext { receiver, @@ -116,7 +114,7 @@ impl StrategyEncoder for SequentialStrategyEncoder { wrap, unwrap, biguint_to_u256(&solution.given_amount), - if check_amount.is_zero() { false } else { true }, // if check_amount is zero, then we don't need to check + !check_amount.is_zero(), /* if check_amount is zero, then we don't need to check */ biguint_to_u256(&check_amount), encoded_swaps, ) @@ -144,7 +142,7 @@ impl StrategyEncoder for SequentialStrategyEncoder { pub struct SplitSwapStrategyEncoder {} impl StrategyEncoder for SplitSwapStrategyEncoder { - fn encode_strategy(&self, solution: Solution) -> Result, Error> { + fn encode_strategy(&self, _solution: Solution) -> Result, Error> { todo!() } fn action_type(&self, _exact_out: bool) -> ActionType { diff --git a/src/encoding/strategy_selector.rs b/src/encoding/strategy_selector.rs index d48e5d2..4a50139 100644 --- a/src/encoding/strategy_selector.rs +++ b/src/encoding/strategy_selector.rs @@ -1,10 +1,13 @@ -use crate::encoding::models::Solution; -use crate::encoding::strategy_encoder::{ - SequentialStrategyEncoder, SingleSwapStrategyEncoder, SplitSwapStrategyEncoder, - StraightToPoolStrategyEncoder, StrategyEncoder, +use crate::encoding::{ + models::Solution, + strategy_encoder::{ + SequentialStrategyEncoder, SingleSwapStrategyEncoder, SplitSwapStrategyEncoder, + StraightToPoolStrategyEncoder, StrategyEncoder, + }, }; pub trait StrategySelector { + #[allow(dead_code)] fn select_strategy(&self, solution: &Solution) -> Box; } @@ -16,7 +19,11 @@ impl StrategySelector for DefaultStrategySelector { Box::new(StraightToPoolStrategyEncoder {}) } else if solution.swaps.len() == 1 { Box::new(SingleSwapStrategyEncoder {}) - } else if solution.swaps.iter().all(|s| s.split == 0.0) { + } else if solution + .swaps + .iter() + .all(|s| s.split == 0.0) + { Box::new(SequentialStrategyEncoder {}) } else { Box::new(SplitSwapStrategyEncoder {}) diff --git a/src/encoding/swap_encoder/builder.rs b/src/encoding/swap_encoder/builder.rs index ce4acb1..492962d 100644 --- a/src/encoding/swap_encoder/builder.rs +++ b/src/encoding/swap_encoder/builder.rs @@ -1,8 +1,10 @@ -use crate::encoding::swap_encoder::swap_encoder::{ +use std::str::FromStr; + +use alloy_primitives::Address; + +use crate::encoding::swap_encoder::swap_struct_encoder::{ BalancerV2SwapEncoder, SwapEncoder, UniswapV2SwapEncoder, }; -use alloy_primitives::Address; -use std::str::FromStr; pub struct SwapEncoderBuilder { protocol_system: String, @@ -14,7 +16,7 @@ impl SwapEncoderBuilder { SwapEncoderBuilder { protocol_system: protocol_system.to_string(), executor_address: Address::from_str(executor_address) - .expect(&format!("Invalid address: {}", executor_address)), + .unwrap_or_else(|_| panic!("Invalid address: {}", executor_address)), } } diff --git a/src/encoding/swap_encoder/mod.rs b/src/encoding/swap_encoder/mod.rs index 85f6b2f..90cee48 100644 --- a/src/encoding/swap_encoder/mod.rs +++ b/src/encoding/swap_encoder/mod.rs @@ -1,10 +1,12 @@ -use crate::encoding::swap_encoder::registry::{Config, SwapEncoderRegistry}; -use lazy_static::lazy_static; use std::sync::RwLock; +use lazy_static::lazy_static; + +use crate::encoding::swap_encoder::registry::{Config, SwapEncoderRegistry}; + mod builder; mod registry; -mod swap_encoder; +mod swap_struct_encoder; lazy_static! { pub static ref SWAP_ENCODER_REGISTRY: RwLock = { diff --git a/src/encoding/swap_encoder/registry.rs b/src/encoding/swap_encoder/registry.rs index 8320b64..efcfdda 100644 --- a/src/encoding/swap_encoder/registry.rs +++ b/src/encoding/swap_encoder/registry.rs @@ -1,8 +1,10 @@ -use crate::encoding::swap_encoder::builder::SwapEncoderBuilder; -use crate::encoding::swap_encoder::swap_encoder::SwapEncoder; +use std::{collections::HashMap, fs}; + use serde::Deserialize; -use std::collections::HashMap; -use std::fs; + +use crate::encoding::swap_encoder::{ + builder::SwapEncoderBuilder, swap_struct_encoder::SwapEncoder, +}; pub struct SwapEncoderRegistry { encoders: HashMap>, @@ -14,16 +16,16 @@ impl SwapEncoderRegistry { for (protocol, executor_address) in config.executors { let builder = SwapEncoderBuilder::new(&protocol, &executor_address); - let encoder = builder.build().expect(&format!( - "Failed to build swap encoder for protocol: {}", - protocol - )); + let encoder = builder.build().unwrap_or_else(|_| { + panic!("Failed to build swap encoder for protocol: {}", protocol) + }); encoders.insert(protocol, encoder); } Self { encoders } } + #[allow(clippy::borrowed_box)] pub fn get_encoder(&self, protocol_system: &str) -> Option<&Box> { self.encoders.get(protocol_system) } diff --git a/src/encoding/swap_encoder/swap_encoder.rs b/src/encoding/swap_encoder/swap_struct_encoder.rs similarity index 86% rename from src/encoding/swap_encoder/swap_encoder.rs rename to src/encoding/swap_encoder/swap_struct_encoder.rs index 4fb0132..467b98d 100644 --- a/src/encoding/swap_encoder/swap_encoder.rs +++ b/src/encoding/swap_encoder/swap_struct_encoder.rs @@ -1,10 +1,14 @@ -use crate::encoding::approvals::approvals_manager::ProtocolApprovalsManager; -use crate::encoding::models::{EncodingContext, Swap}; -use crate::encoding::utils::bytes_to_address; +use std::str::FromStr; + use alloy_primitives::Address; use alloy_sol_types::SolValue; use anyhow::Error; -use std::str::FromStr; + +use crate::encoding::{ + approvals::approvals_manager::ProtocolApprovalsManager, + models::{EncodingContext, Swap}, + utils::bytes_to_address, +}; pub trait SwapEncoder: Sync + Send { fn new(executor_address: Address) -> Self @@ -23,7 +27,11 @@ impl SwapEncoder for UniswapV2SwapEncoder { fn new(executor_address: Address) -> Self { Self { executor_address } } - fn encode_swap(&self, swap: Swap, encoding_context: EncodingContext) -> Result, Error> { + fn encode_swap( + &self, + _swap: Swap, + _encoding_context: EncodingContext, + ) -> Result, Error> { todo!() } @@ -55,7 +63,7 @@ impl SwapEncoder for BalancerV2SwapEncoder { let router_address = bytes_to_address(&encoding_context.address_for_approvals)?; let approval_needed = runtime.block_on(async { token_approvals_manager - .approval_needed(token, self.vault_address.clone(), router_address) + .approval_needed(token, self.vault_address, router_address) .await }); // should we return gas estimation here too?? if there is an approval needed, gas will be diff --git a/src/encoding/utils.rs b/src/encoding/utils.rs index a2c9683..d510fa7 100644 --- a/src/encoding/utils.rs +++ b/src/encoding/utils.rs @@ -12,10 +12,7 @@ pub fn bytes_to_address(address: &Bytes) -> Result { if address.len() == 20 { Ok(Address::from_slice(address)) } else { - Err(anyhow::format_err!( - "Invalid ERC20 token address: {:?}", - address - )) + Err(anyhow::format_err!("Invalid ERC20 token address: {:?}", address)) } } pub fn biguint_to_u256(value: &BigUint) -> U256 { @@ -34,6 +31,7 @@ pub fn ple_encode(action_data_array: Vec>) -> Vec { encoded_action_data } +#[allow(dead_code)] pub fn encode_input(selector: &str, mut encoded_args: Vec) -> Vec { let mut hasher = Keccak256::new(); hasher.update(selector.as_bytes()); @@ -42,9 +40,9 @@ pub fn encode_input(selector: &str, mut encoded_args: Vec) -> 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] + if encoded_args.len() > 32 && + encoded_args[..32] == + [0u8; 31] .into_iter() .chain([32].to_vec()) .collect::>() diff --git a/src/lib.rs b/src/lib.rs index b8120c4..35ed87a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1 +1 @@ -mod encoding; \ No newline at end of file +mod encoding;