SSSwap

First Flight #41
Beginner FriendlyRust
100 EXP
View results
Submission Details
Severity: high
Valid

Missing Slippage Protection in Liquidity Provision

Root + Impact

Description

The provide_liquidity function lacks a mechanism for users to specify minimum acceptable LP tokens, exposing them to potential MEV attacks and unexpected losses when pool conditions change between transaction submission and execution.

Mechanism: When a user adds liquidity to the pool, they provide an amount of token A, and the system calculates the required amount of token B based on the current pool ratio. However, there is no parameter for the user to specify a minimum amount of LP tokens they expect to receive.

Root Cause: The function signature lacks a parameter for minimum output protection:

pub fn provide_liquidity(context: Context<ModifyLiquidity>,
amount_a: u64
) -> Result<()> {
let amount_b = calculate_token_b_provision_with_a_given(
&mut context.accounts.vault_a,
&mut context.accounts.vault_b,
amount_a
)?;
// ...
}

Attack Vector: Malicious validators or searchers could execute a sandwich attack by:

  1. Detecting a user's liquidity provision transaction

  2. Adding their own liquidity before the user's transaction to alter the pool ratio unfavorably

  3. Removing their liquidity after the user's transaction executes

Risk

Likelihood:

Likelihood Assessment:

Attack Complexity: Low - Common MEV extraction pattern on blockchain networks
Prerequisites: Transaction visibility in mempool or validator access

Impact:

Impact Assessment:

Integrity: Medium - User operations execute correctly but with potentially unfair economic outcomes
Financial: Medium - Users may receive fewer LP tokens than expected without protection

Proof of Concept

N/A

Recommended Mitigation

Add a minimum LP tokens parameter to the function:

pub fn provide_liquidity(
context: Context<ModifyLiquidity>,
amount_a: u64,
min_lp_tokens: u64
) -> Result<()> {
let amount_b = calculate_token_b_provision_with_a_given(
&mut context.accounts.vault_a,
&mut context.accounts.vault_b,
amount_a
)?;
// Calculate expected LP tokens
let lp_to_mint: u64 = liquidity_calculation(amount_a, amount_b)?;
// Add slippage protection
require!(
lp_to_mint >= min_lp_tokens,
AmmError::SlippageExceeded
);
// Continue with existing logic...
}

Create a new error type in your error module:

#[error_code]
pub enum AmmError {
// ...existing errors
SlippageExceeded,
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 5 days ago
Submission Judgement Published
Validated
Assigned finding tags:

Liquidity Provision Lacks Slippage Protection

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.