- Remove src/common/address_lookup.rs and tip_cache.rs to simplify common modules - Move protocol-specific utility functions from trading/ to instruction/utils/ - Refactor utility functions for PumpFun, PumpSwap, Raydium AMM V4, and Raydium CPMM - Consolidate constant definitions by inlining seeds and accounts modules into respective utility files - Update all import paths to ensure code consistency - Optimize trading parameter construction and executor logic - Improve address lookup cache and nonce management mechanisms
151 lines
5.1 KiB
Rust
151 lines
5.1 KiB
Rust
use crate::instruction::utils::raydium_amm_v4::accounts::{
|
|
SWAP_FEE_DENOMINATOR, SWAP_FEE_NUMERATOR, TRADE_FEE_DENOMINATOR, TRADE_FEE_NUMERATOR,
|
|
};
|
|
|
|
/// Computes trading fee using ceiling division.
|
|
///
|
|
/// # Arguments
|
|
/// * `amount` - The amount to calculate fee for
|
|
/// * `fee_rate` - The fee rate to apply
|
|
///
|
|
/// # Returns
|
|
/// The calculated trading fee
|
|
fn compute_trading_fee(amount: u64, fee_rate: u64, fee_denominator: u64) -> u64 {
|
|
let numerator = (amount as u128) * (fee_rate as u128);
|
|
((numerator + fee_denominator as u128 - 1) / fee_denominator as u128) as u64
|
|
}
|
|
|
|
/// Computes protocol or fund fee using floor division.
|
|
///
|
|
/// # Arguments
|
|
/// * `amount` - The amount to calculate fee for
|
|
/// * `fee_rate` - The fee rate to apply
|
|
///
|
|
/// # Returns
|
|
/// The calculated protocol or fund fee
|
|
fn compute_protocol_fund_fee(amount: u64, fee_rate: u64, fee_denominator: u64) -> u64 {
|
|
let numerator = (amount as u128) * (fee_rate as u128);
|
|
(numerator / fee_denominator as u128) as u64
|
|
}
|
|
|
|
/// Parameters for computing swap amounts and fees.
|
|
#[derive(Debug, Clone)]
|
|
pub struct ComputeSwapParams {
|
|
/// Whether the entire input amount is traded
|
|
pub all_trade: bool,
|
|
/// The input amount for the swap
|
|
pub amount_in: u64,
|
|
/// The expected output amount from the swap
|
|
pub amount_out: u64,
|
|
/// The minimum acceptable output amount (considering slippage_basis_points)
|
|
pub min_amount_out: u64,
|
|
/// The trading fee amount
|
|
pub fee: u64,
|
|
}
|
|
|
|
/// Result of a swap calculation containing all relevant amounts and fees.
|
|
#[derive(Debug, Clone)]
|
|
pub struct SwapResult {
|
|
/// The new amount in the input vault after the swap
|
|
pub new_input_vault_amount: u64,
|
|
/// The new amount in the output vault after the swap
|
|
pub new_output_vault_amount: u64,
|
|
/// The actual input amount used in the swap
|
|
pub input_amount: u64,
|
|
/// The actual output amount received from the swap
|
|
pub output_amount: u64,
|
|
/// The trading fee charged
|
|
pub trade_fee: u64,
|
|
/// The swap fee charged
|
|
pub swap_fee: u64,
|
|
}
|
|
|
|
/// Performs a swap calculation based on input amount.
|
|
///
|
|
/// Calculates the output amount and all associated fees when swapping a specific input amount.
|
|
///
|
|
/// # Arguments
|
|
/// * `input_amount` - The amount of input tokens to swap
|
|
/// * `input_vault_amount` - Current amount in the input token vault
|
|
/// * `output_vault_amount` - Current amount in the output token vault
|
|
/// * `trade_fee_rate` - The trading fee rate
|
|
/// * `swap_fee_rate` - The swap fee rate
|
|
///
|
|
/// # Returns
|
|
/// A `SwapResult` containing all swap calculations and fees
|
|
fn swap_base_input(
|
|
input_amount: u64,
|
|
input_vault_amount: u64,
|
|
output_vault_amount: u64,
|
|
trade_fee_rate: u64,
|
|
swap_fee_rate: u64,
|
|
) -> SwapResult {
|
|
let trade_fee = compute_trading_fee(input_amount, trade_fee_rate, TRADE_FEE_DENOMINATOR);
|
|
|
|
let input_amount_less_fees = input_amount.saturating_sub(trade_fee);
|
|
|
|
let swap_fee = compute_protocol_fund_fee(trade_fee, swap_fee_rate, SWAP_FEE_DENOMINATOR);
|
|
|
|
let output_amount_swapped = ((output_vault_amount as u128)
|
|
.saturating_mul(input_amount_less_fees as u128)
|
|
/ (input_vault_amount as u128).saturating_add(input_amount_less_fees as u128))
|
|
as u64;
|
|
|
|
let output_amount = output_amount_swapped.saturating_sub(swap_fee);
|
|
|
|
SwapResult {
|
|
new_input_vault_amount: input_vault_amount.saturating_add(input_amount_less_fees),
|
|
new_output_vault_amount: output_vault_amount.saturating_sub(output_amount_swapped),
|
|
input_amount,
|
|
output_amount,
|
|
trade_fee,
|
|
swap_fee,
|
|
}
|
|
}
|
|
|
|
/// Computes swap parameters including amounts, fees, and slippage protection.
|
|
///
|
|
/// This function calculates the expected output amount, minimum output amount (with slippage),
|
|
/// and trading fees for a given input amount in a Raydium AMM V4 pool.
|
|
///
|
|
/// # Arguments
|
|
/// * `base_reserve` - The current reserve amount of the base token in the pool
|
|
/// * `quote_reserve` - The current reserve amount of the quote token in the pool
|
|
/// * `is_base_in` - Whether the input token is the base token (true) or quote token (false)
|
|
/// * `amount_in` - The amount of input tokens to swap
|
|
/// * `slippage_basis_points` - The acceptable slippage in basis points (e.g., 100 for 1%)
|
|
///
|
|
/// # Returns
|
|
/// A `ComputeSwapParams` struct containing all computed swap parameters
|
|
pub fn compute_swap_amount(
|
|
base_reserve: u64,
|
|
quote_reserve: u64,
|
|
is_base_in: bool,
|
|
amount_in: u64,
|
|
slippage_basis_points: u64,
|
|
) -> ComputeSwapParams {
|
|
let (input_reserve, output_reserve) =
|
|
if is_base_in { (base_reserve, quote_reserve) } else { (quote_reserve, base_reserve) };
|
|
|
|
let swap_result = swap_base_input(
|
|
amount_in,
|
|
input_reserve,
|
|
output_reserve,
|
|
TRADE_FEE_NUMERATOR,
|
|
SWAP_FEE_NUMERATOR,
|
|
);
|
|
|
|
let min_amount_out = ((swap_result.output_amount as f64)
|
|
* (1.0 - (slippage_basis_points as f64) / 10000.0)) as u64;
|
|
|
|
let all_trade = swap_result.input_amount == amount_in;
|
|
|
|
ComputeSwapParams {
|
|
all_trade,
|
|
amount_in,
|
|
amount_out: swap_result.output_amount,
|
|
min_amount_out,
|
|
fee: swap_result.trade_fee,
|
|
}
|
|
}
|