diff --git a/src/encoding/models.rs b/src/encoding/models.rs index ddfd0e5..a02bd08 100644 --- a/src/encoding/models.rs +++ b/src/encoding/models.rs @@ -11,12 +11,9 @@ lazy_static! { .expect("Invalid ROUTER_ADDRESS"); } +#[derive(Clone)] pub struct Solution { - pub orders: Vec, -} - -pub struct Order { - /// True if the order is an exact output order. + /// True if the solution is an exact output solution. pub exact_out: bool, /// The token being sold (exact in) or bought (exact out). pub given_token: Bytes, @@ -30,9 +27,9 @@ pub struct Order { pub sender: Bytes, /// Address of the receiver. pub receiver: Bytes, - /// List of swaps to fulfill the order. + /// List of swaps to fulfill the solution. pub swaps: Vec, - /// If set to true, the order will be encoded to be sent directly to the SwapExecutor and skip the router. + /// 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 diff --git a/src/encoding/router_encoder.rs b/src/encoding/router_encoder.rs index 9a8491f..a6d5bf5 100644 --- a/src/encoding/router_encoder.rs +++ b/src/encoding/router_encoder.rs @@ -1,6 +1,5 @@ use crate::encoding::approvals::interface::{Approval, UserApprovalsManager}; use crate::encoding::models::{Solution, PROPELLER_ROUTER_ADDRESS}; -use crate::encoding::strategy_encoder::StrategyEncoder; use crate::encoding::strategy_selector::StrategySelector; use crate::encoding::utils::{encode_input, ple_encode}; use alloy_sol_types::SolValue; @@ -17,16 +16,16 @@ impl RouterEncoder { approvals_manager, } } - pub fn encode_router_calldata(&self, solution: Solution) -> Result, Error> { - let approvals_calldata = self.handle_approvals(&solution)?; // TODO: where should we append this? + pub fn encode_router_calldata(&self, solutions: Vec) -> Result, Error> { + 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 = solution.orders.len() > 1; - for order in solution.orders { - let exact_out = order.exact_out.clone(); - let straight_to_pool = order.straight_to_pool.clone(); + let encode_for_batch_execute = solutions.len() > 1; + for solution in solutions.iter() { + let exact_out = solution.exact_out.clone(); + let straight_to_pool = solution.straight_to_pool.clone(); - let strategy = self.strategy_selector.select_strategy(&order); - let method_calldata = strategy.encode_strategy(order)?; + 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); @@ -48,17 +47,17 @@ impl RouterEncoder { } } - fn handle_approvals(&self, solution: &Solution) -> Result, Error> { + fn handle_approvals(&self, solutions: &Vec) -> Result, Error> { let mut approvals = Vec::new(); - for order in solution.orders.iter() { + for solution in solutions.iter() { approvals.push(Approval { - token: order.given_token.clone(), - spender: order + token: solution.given_token.clone(), + spender: solution .router_address .clone() .unwrap_or(PROPELLER_ROUTER_ADDRESS.clone()), - amount: order.given_amount.clone(), - owner: order.sender.clone(), + amount: solution.given_amount.clone(), + owner: solution.sender.clone(), }); } Ok(self.approvals_manager.encode_approvals(approvals)) diff --git a/src/encoding/strategy_encoder.rs b/src/encoding/strategy_encoder.rs index 610aa37..9a4e6eb 100644 --- a/src/encoding/strategy_encoder.rs +++ b/src/encoding/strategy_encoder.rs @@ -3,13 +3,13 @@ use anyhow::Error; use num_bigint::BigUint; use crate::encoding::models::{ - ActionType, EncodingContext, NativeAction, Order, PROPELLER_ROUTER_ADDRESS, + ActionType, EncodingContext, NativeAction, Solution, PROPELLER_ROUTER_ADDRESS, }; use crate::encoding::swap_encoder::{get_swap_encoder, get_swap_executor_address}; use crate::encoding::utils::{biguint_to_u256, ple_encode}; pub trait StrategyEncoder { - fn encode_strategy(&self, to_encode: Order) -> Result, Error>; + fn encode_strategy(&self, to_encode: Solution) -> Result, Error>; fn action_type(&self, exact_out: bool) -> ActionType; fn selector(&self, exact_out: bool) -> &str; @@ -32,7 +32,7 @@ pub trait StrategyEncoder { pub struct SingleSwapStrategyEncoder {} impl StrategyEncoder for SingleSwapStrategyEncoder { - fn encode_strategy(&self, order: Order) -> Result, Error> { + fn encode_strategy(&self, solution: Solution) -> Result, Error> { todo!() } @@ -56,33 +56,33 @@ impl StrategyEncoder for SingleSwapStrategyEncoder { pub struct SequentialStrategyEncoder {} impl StrategyEncoder for SequentialStrategyEncoder { - fn encode_strategy(&self, order: Order) -> Result, Error> { - let mut check_amount = order.check_amount.clone(); - if order.slippage.is_some() { + fn encode_strategy(&self, solution: Solution) -> Result, Error> { + let mut check_amount = solution.check_amount.clone(); + if solution.slippage.is_some() { let one_hundred = BigUint::from(100u32); - let slippage_percent = BigUint::from((order.slippage.unwrap() * 100.0) as u32); + let slippage_percent = BigUint::from((solution.slippage.unwrap() * 100.0) as u32); let multiplier = &one_hundred - slippage_percent; - check_amount = (&order.check_amount * multiplier) / one_hundred; + check_amount = (&solution.check_amount * multiplier) / one_hundred; } let mut swaps = vec![]; - for (index, swap) in order.swaps.iter().enumerate() { - let is_last = index == order.swaps.len() - 1; + for (index, swap) in solution.swaps.iter().enumerate() { + let is_last = index == solution.swaps.len() - 1; let protocol_system = swap.component.protocol_system.clone(); let swap_encoder = get_swap_encoder(&protocol_system); - let router_address = if order.router_address.is_some() { - order.router_address.clone().unwrap() + let router_address = if solution.router_address.is_some() { + solution.router_address.clone().unwrap() } else { PROPELLER_ROUTER_ADDRESS.clone() }; let receiver = if is_last { - order.receiver.clone() + solution.receiver.clone() } else { router_address.clone() }; let encoding_context = EncodingContext { receiver, - exact_out: order.exact_out, + exact_out: solution.exact_out, address_for_approvals: router_address, }; let protocol_data = swap_encoder.encode_swap(swap.clone(), encoding_context)?; @@ -93,8 +93,8 @@ impl StrategyEncoder for SequentialStrategyEncoder { let encoded_swaps = ple_encode(swaps); let (mut unwrap, mut wrap) = (false, false); - if order.native_action.is_some() { - match order.native_action.unwrap() { + if solution.native_action.is_some() { + match solution.native_action.unwrap() { NativeAction::Wrap => wrap = true, NativeAction::Unwrap => unwrap = true, } @@ -102,7 +102,7 @@ impl StrategyEncoder for SequentialStrategyEncoder { let method_calldata = ( wrap, unwrap, - biguint_to_u256(&order.given_amount), + biguint_to_u256(&solution.given_amount), biguint_to_u256(&check_amount), encoded_swaps, ) @@ -130,7 +130,7 @@ impl StrategyEncoder for SequentialStrategyEncoder { pub struct SlipSwapStrategyEncoder {} impl StrategyEncoder for SlipSwapStrategyEncoder { - fn encode_strategy(&self, order: Order) -> Result, Error> { + fn encode_strategy(&self, solution: Solution) -> Result, Error> { todo!() } fn action_type(&self, _exact_out: bool) -> ActionType { @@ -142,25 +142,25 @@ impl StrategyEncoder for SlipSwapStrategyEncoder { } } -/// This strategy encoder is used for orders that are sent directly to the pool. -/// Only 1 order with 1 swap is supported. +/// This strategy encoder is used for solutions that are sent directly to the pool. +/// Only 1 solution with 1 swap is supported. pub struct StraightToPoolStrategyEncoder {} impl StrategyEncoder for StraightToPoolStrategyEncoder { - fn encode_strategy(&self, order: Order) -> Result, Error> { - if order.router_address.is_none() { + fn encode_strategy(&self, solution: Solution) -> Result, Error> { + if solution.router_address.is_none() { return Err(anyhow::anyhow!( - "Router address is required for straight to pool orders" + "Router address is required for straight to pool solutions" )); } - let swap = order.swaps.first().unwrap(); + let swap = solution.swaps.first().unwrap(); let protocol_system = swap.component.protocol_system.clone(); let swap_encoder = get_swap_encoder(&protocol_system); - let router_address = order.router_address.unwrap(); + let router_address = solution.router_address.unwrap(); let encoding_context = EncodingContext { - receiver: order.receiver, - exact_out: order.exact_out, + receiver: solution.receiver, + exact_out: solution.exact_out, address_for_approvals: router_address, }; let protocol_data = swap_encoder.encode_swap(swap.clone(), encoding_context)?; diff --git a/src/encoding/strategy_selector.rs b/src/encoding/strategy_selector.rs index 4c01a9c..7dcde79 100644 --- a/src/encoding/strategy_selector.rs +++ b/src/encoding/strategy_selector.rs @@ -1,22 +1,22 @@ -use crate::encoding::models::Order; +use crate::encoding::models::Solution; use crate::encoding::strategy_encoder::{ SequentialStrategyEncoder, SingleSwapStrategyEncoder, SlipSwapStrategyEncoder, StraightToPoolStrategyEncoder, StrategyEncoder, }; pub trait StrategySelector { - fn select_strategy(&self, order: &Order) -> Box; + fn select_strategy(&self, solution: &Solution) -> Box; } pub struct DefaultStrategySelector; impl StrategySelector for DefaultStrategySelector { - fn select_strategy(&self, order: &Order) -> Box { - if order.straight_to_pool { + fn select_strategy(&self, solution: &Solution) -> Box { + if solution.straight_to_pool { Box::new(StraightToPoolStrategyEncoder {}) - } else if order.swaps.len() == 1 { + } else if solution.swaps.len() == 1 { Box::new(SingleSwapStrategyEncoder {}) - } else if order.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(SlipSwapStrategyEncoder {})