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,
/// List of swaps to fulfill the order.
pub swaps: Vec<Swap>,
/// 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<Bytes>,
// 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 {

View File

@@ -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<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::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<dyn StrategyEncoder> {
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 {})

View File

@@ -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
})