From 3e609c75aefaff7c4627c39c9d328961b656658c Mon Sep 17 00:00:00 2001 From: Diana Carvalho Date: Tue, 14 Jan 2025 12:56:37 +0000 Subject: [PATCH] feat: Support encoding only the pool swap Create StraightToPoolStrategyEncoder --- src/encoding/models.rs | 7 ++++--- src/encoding/strategy_encoder.rs | 34 +++++++++++++++++++++++++++++-- src/encoding/strategy_selector.rs | 6 ++++-- src/encoding/swap_encoder.rs | 5 ++--- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/encoding/models.rs b/src/encoding/models.rs index d820000..ddfd0e5 100644 --- a/src/encoding/models.rs +++ b/src/encoding/models.rs @@ -32,8 +32,9 @@ pub struct Order { pub receiver: Bytes, /// List of swaps to fulfill the order. pub swaps: Vec, - /// Whether to include router calldata (true) or just swap data (false). - add_router_calldata: bool, + /// If set to true, the order 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, // if set, it will be applied to check_amount @@ -63,7 +64,7 @@ pub struct Swap { pub struct EncodingContext { pub receiver: Bytes, pub exact_out: bool, - pub router_address: Bytes, + pub address_for_approvals: Bytes, } pub enum ActionType { diff --git a/src/encoding/strategy_encoder.rs b/src/encoding/strategy_encoder.rs index c3328d2..ac280fb 100644 --- a/src/encoding/strategy_encoder.rs +++ b/src/encoding/strategy_encoder.rs @@ -6,7 +6,7 @@ use crate::encoding::models::{ ActionType, EncodingContext, NativeAction, Order, PROPELLER_ROUTER_ADDRESS, }; use crate::encoding::swap_encoder::{get_swap_encoder, get_swap_executor_address}; -use crate::encoding::utils::{biguint_to_u256, bytes_to_address, encode_input, ple_encode}; +use crate::encoding::utils::{biguint_to_u256, encode_input, ple_encode}; pub trait StrategyEncoder { fn encode_strategy( @@ -76,7 +76,7 @@ impl StrategyEncoder for SequentialExactInStrategyEncoder { let encoding_context = EncodingContext { receiver, exact_out: order.exact_out, - router_address, + address_for_approvals: router_address, }; let protocol_data = swap_encoder.encode_swap(swap.clone(), encoding_context)?; let swap_data = self.encode_protocol_header(protocol_data, protocol_system, 0, 0, 0); @@ -123,3 +123,33 @@ impl StrategyEncoder for SlipSwapStrategyEncoder { todo!() } } + +/// This strategy encoder is used for orders that are sent directly to the pool. +/// Only 1 order with 1 swap is supported. +pub struct StraightToPoolStrategyEncoder {} + +impl StrategyEncoder for StraightToPoolStrategyEncoder { + fn encode_strategy( + &self, + order: Order, + encode_for_batch_execute: bool, + ) -> Result, Error> { + if order.router_address.is_none() { + return Err(anyhow::anyhow!( + "Router address is required for straight to pool orders" + )); + } + let swap = order.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 encoding_context = EncodingContext { + receiver: order.receiver, + exact_out: order.exact_out, + address_for_approvals: router_address, + }; + let protocol_data = swap_encoder.encode_swap(swap.clone(), encoding_context)?; + Ok(protocol_data) + } +} diff --git a/src/encoding/strategy_selector.rs b/src/encoding/strategy_selector.rs index 6faa47a..602c9d6 100644 --- a/src/encoding/strategy_selector.rs +++ b/src/encoding/strategy_selector.rs @@ -1,7 +1,7 @@ use crate::encoding::models::Order; use crate::encoding::strategy_encoder::{ SequentialExactInStrategyEncoder, SingleSwapStrategyEncoder, SlipSwapStrategyEncoder, - StrategyEncoder, + StraightToPoolStrategyEncoder, StrategyEncoder, }; pub trait StrategySelector { @@ -12,7 +12,9 @@ pub struct DefaultStrategySelector; impl StrategySelector for DefaultStrategySelector { fn select_strategy(&self, order: &Order) -> Box { - if order.swaps.len() == 1 { + if order.straight_to_pool { + Box::new(StraightToPoolStrategyEncoder {}) + } else if order.swaps.len() == 1 { Box::new(SingleSwapStrategyEncoder {}) } else if order.swaps.iter().all(|s| s.split == 0.0) { Box::new(SequentialExactInStrategyEncoder {}) diff --git a/src/encoding/swap_encoder.rs b/src/encoding/swap_encoder.rs index 232d8d7..503d7f7 100644 --- a/src/encoding/swap_encoder.rs +++ b/src/encoding/swap_encoder.rs @@ -1,9 +1,8 @@ use crate::encoding::approvals::approvals_manager::TokenApprovalsManager; use crate::encoding::approvals::interface::Approval; -use crate::encoding::approvals::interface::ApprovalsManager; use crate::encoding::models::{EncodingContext, Swap}; use crate::encoding::utils::bytes_to_address; -use alloy_primitives::{Address, U256}; +use alloy_primitives::Address; use alloy_sol_types::SolValue; use anyhow::Error; use num_bigint::BigUint; @@ -47,7 +46,7 @@ impl SwapEncoder for BalancerV2SwapEncoder { token_approvals_manager .approval_needed(Approval { spender: self.vault_address.clone(), - owner: encoding_context.router_address, + owner: encoding_context.address_for_approvals, token: swap.token_in.clone(), amount: (BigUint::one() << 256) - BigUint::one(), // max U256 })