feat: Support encoding only the pool swap

Create StraightToPoolStrategyEncoder
This commit is contained in:
Diana Carvalho
2025-01-14 12:56:37 +00:00
parent 4991883fc8
commit 3e609c75ae
4 changed files with 42 additions and 10 deletions

View File

@@ -32,8 +32,9 @@ pub struct Order {
pub receiver: Bytes, pub receiver: Bytes,
/// List of swaps to fulfill the order. /// List of swaps to fulfill the order.
pub swaps: Vec<Swap>, pub swaps: Vec<Swap>,
/// Whether to include router calldata (true) or just swap data (false). /// If set to true, the order will be encoded to be sent directly to the SwapExecutor and skip the router.
add_router_calldata: bool, /// 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 // if not set, then the Propeller Router will be used
pub router_address: Option<Bytes>, pub router_address: Option<Bytes>,
// if set, it will be applied to check_amount // if set, it will be applied to check_amount
@@ -63,7 +64,7 @@ pub struct Swap {
pub struct EncodingContext { pub struct EncodingContext {
pub receiver: Bytes, pub receiver: Bytes,
pub exact_out: bool, pub exact_out: bool,
pub router_address: Bytes, pub address_for_approvals: Bytes,
} }
pub enum ActionType { pub enum ActionType {

View File

@@ -6,7 +6,7 @@ use crate::encoding::models::{
ActionType, EncodingContext, NativeAction, Order, PROPELLER_ROUTER_ADDRESS, ActionType, EncodingContext, NativeAction, Order, PROPELLER_ROUTER_ADDRESS,
}; };
use crate::encoding::swap_encoder::{get_swap_encoder, get_swap_executor_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 { pub trait StrategyEncoder {
fn encode_strategy( fn encode_strategy(
@@ -76,7 +76,7 @@ impl StrategyEncoder for SequentialExactInStrategyEncoder {
let encoding_context = EncodingContext { let encoding_context = EncodingContext {
receiver, receiver,
exact_out: order.exact_out, exact_out: order.exact_out,
router_address, address_for_approvals: router_address,
}; };
let protocol_data = swap_encoder.encode_swap(swap.clone(), encoding_context)?; 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); let swap_data = self.encode_protocol_header(protocol_data, protocol_system, 0, 0, 0);
@@ -123,3 +123,33 @@ impl StrategyEncoder for SlipSwapStrategyEncoder {
todo!() 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<Vec<u8>, 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)
}
}

View File

@@ -1,7 +1,7 @@
use crate::encoding::models::Order; use crate::encoding::models::Order;
use crate::encoding::strategy_encoder::{ use crate::encoding::strategy_encoder::{
SequentialExactInStrategyEncoder, SingleSwapStrategyEncoder, SlipSwapStrategyEncoder, SequentialExactInStrategyEncoder, SingleSwapStrategyEncoder, SlipSwapStrategyEncoder,
StrategyEncoder, StraightToPoolStrategyEncoder, StrategyEncoder,
}; };
pub trait StrategySelector { pub trait StrategySelector {
@@ -12,7 +12,9 @@ pub struct DefaultStrategySelector;
impl StrategySelector for DefaultStrategySelector { impl StrategySelector for DefaultStrategySelector {
fn select_strategy(&self, order: &Order) -> Box<dyn StrategyEncoder> { fn select_strategy(&self, order: &Order) -> Box<dyn StrategyEncoder> {
if order.swaps.len() == 1 { if order.straight_to_pool {
Box::new(StraightToPoolStrategyEncoder {})
} else if order.swaps.len() == 1 {
Box::new(SingleSwapStrategyEncoder {}) Box::new(SingleSwapStrategyEncoder {})
} else if order.swaps.iter().all(|s| s.split == 0.0) { } else if order.swaps.iter().all(|s| s.split == 0.0) {
Box::new(SequentialExactInStrategyEncoder {}) Box::new(SequentialExactInStrategyEncoder {})

View File

@@ -1,9 +1,8 @@
use crate::encoding::approvals::approvals_manager::TokenApprovalsManager; use crate::encoding::approvals::approvals_manager::TokenApprovalsManager;
use crate::encoding::approvals::interface::Approval; use crate::encoding::approvals::interface::Approval;
use crate::encoding::approvals::interface::ApprovalsManager;
use crate::encoding::models::{EncodingContext, Swap}; use crate::encoding::models::{EncodingContext, Swap};
use crate::encoding::utils::bytes_to_address; use crate::encoding::utils::bytes_to_address;
use alloy_primitives::{Address, U256}; use alloy_primitives::Address;
use alloy_sol_types::SolValue; use alloy_sol_types::SolValue;
use anyhow::Error; use anyhow::Error;
use num_bigint::BigUint; use num_bigint::BigUint;
@@ -47,7 +46,7 @@ impl SwapEncoder for BalancerV2SwapEncoder {
token_approvals_manager token_approvals_manager
.approval_needed(Approval { .approval_needed(Approval {
spender: self.vault_address.clone(), spender: self.vault_address.clone(),
owner: encoding_context.router_address, owner: encoding_context.address_for_approvals,
token: swap.token_in.clone(), token: swap.token_in.clone(),
amount: (BigUint::one() << 256) - BigUint::one(), // max U256 amount: (BigUint::one() << 256) - BigUint::one(), // max U256
}) })