SSSwap

First Flight #41
Beginner FriendlyRust
100 EXP
View results
Submission Details
Impact: medium
Likelihood: high
Invalid

Pool Duplication Risk Due to Unsorted Token Addresses

Root + Impact

Description

At programs/amm/src/instructions/liquidity_operations.rs#209

The current implementation does not sort token_a and token_b before deriving the pool PDA.

This allows users to create two separate pools for the same token pair (e.g., USDC/SOL and SOL/USDC), leading to fragmented liquidity and potential user confusion.

// --- Calculate and Mint Initial LP Tokens --- //
// Call the calculation function (assuming it returns Result<u64>)
let lp_amount_to_mint: u64 = liquidity_calculation(amount_token_a, amount_token_b)?;
// Create the bump slice variable first
let bump_seed = [context.bumps.liquidity_pool]; // Store the bump in a separate variable
let token_a_key = context.accounts.token_mint_a.key();
let token_b_key = context.accounts.token_mint_b.key();
// Define PDA signer seeds using the variable
let signer_seeds: &[&[&[u8]]] = &[&[
b"pool",
token_a_key.as_ref(),
token_b_key.as_ref(),
&bump_seed, // Use the reference to the variable
]];

Risk

Likelihood:

It's not trivial that a user can creates for example USDCSOL and SOLUSDC liquidity pairs.

Impact:

  • Fragmented liquidity across duplicated pools

  • Inconsistent pricing and slippage behavior across mirrored pools

  • Potential arbitrage abuse


Proof of Concept

Simply creates SOLUSDC and USDCSOL within the system.


Recommended Mitigation

This ensures the same token pair always maps to a single, deterministic pool address.

+ let (token_a, token_b) = if token_a.key() < token_b.key() {
+ (token_a, token_b)
+ } else {
+ (token_b, token_a)
+ };
let lp_amount_to_mint: u64 = liquidity_calculation(amount_token_a, amount_token_b)?;
Updates

Lead Judging Commences

0xtimefliez Lead Judge 5 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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