fix: add slippage clamping and improve WSOL wrap logic

Changes to src/utils/calc/common.rs:
- Add MAX_SLIPPAGE_BASIS_POINTS constant (9999 = 99.99%)
- Clamp basis_points in calculate_with_slippage_buy to prevent amount doubling

Changes to src/instruction/pumpswap.rs:
- Fix WSOL wrap amount calculation for exact vs non-exact input modes
- Use input_amount for exact mode, sol_amount for non-exact mode

🤖 Generated with [Qoder][https://qoder.com]
This commit is contained in:
0xfnzero
2026-04-06 16:53:36 +08:00
parent c8f9f9f6aa
commit 35bfa93516
2 changed files with 25 additions and 2 deletions
+11 -1
View File
@@ -139,8 +139,18 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
let mut instructions = Vec::with_capacity(6);
if create_wsol_ata {
// Determine wrap amount based on instruction type:
// - buy_exact_quote_in: program spends exactly input_amount, wrap input_amount
// - buy: program may spend up to max_quote, wrap max_quote
let wrap_amount = if quote_is_wsol_or_usdc
&& params.use_exact_sol_amount.unwrap_or(true)
{
params.input_amount.unwrap_or(0)
} else {
sol_amount
};
instructions
.extend(crate::trading::common::handle_wsol(&params.payer.pubkey(), sol_amount));
.extend(crate::trading::common::handle_wsol(&params.payer.pubkey(), wrap_amount));
}
if params.create_output_mint_ata {
+14 -1
View File
@@ -28,6 +28,10 @@ pub const fn ceil_div(a: u128, b: u128) -> u128 {
(a + b - 1) / b
}
/// Maximum slippage in basis points (99.99% = 9999 bps)
/// This prevents the wrap amount from doubling when slippage is 100%
pub const MAX_SLIPPAGE_BASIS_POINTS: u64 = 9999;
/// Calculate buy amount with slippage protection
/// Add slippage percentage to the amount to ensure successful purchase
///
@@ -40,9 +44,18 @@ pub const fn ceil_div(a: u128, b: u128) -> u128 {
/// * basis_points = 10 -> 0.1% slippage
/// * basis_points = 100 -> 1% slippage
/// * basis_points = 500 -> 5% slippage
///
/// # Note
/// Basis points are clamped to MAX_SLIPPAGE_BASIS_POINTS (9999 = 99.99%)
/// to prevent the amount from doubling when basis_points = 10000.
#[inline(always)]
pub const fn calculate_with_slippage_buy(amount: u64, basis_points: u64) -> u64 {
amount + (amount * basis_points / 10000)
let bps = if basis_points > MAX_SLIPPAGE_BASIS_POINTS {
MAX_SLIPPAGE_BASIS_POINTS
} else {
basis_points
};
amount + (amount * bps / 10000)
}
/// Calculate sell amount with slippage protection