The AMM contract does not validate whether token_mint_a
and token_mint_b
share the same number of decimals during pool initialization. Furthermore, key arithmetic operations that determine liquidity provisions and LP token minting assume both tokens use identical decimal scales. This design flaw allows users to create liquidity pools with mismatched token decimals, leading to incorrect ratio calculations, imbalanced reserves, and potential value extraction via arbitrage.
In the initialize_pool
function of liquidity_operations.rs
, no check is performed to ensure that token_mint_a.decimals
matches token_mint_b.decimals
. Consequently, the internal accounting logic, which operates directly on raw u64
token amounts, assumes 1 unit of token A is equivalent to 1 unit of token B—an assumption that fails if the tokens have different decimal precision.
This mismatch propagates to two critical functions:
calculate_token_b_provision_with_a_given
: This function computes how many units of token B must be added given an amount of token A, using the formula (reserve_b * amount_a) / reserve_a
without any normalization to a common decimal scale.
calculate_lp_amount
: It calculates the LP tokens to mint as sqrt(amount_a * amount_b)
directly on raw u64
inputs, again ignoring the potential difference in token scales.
Token A: 6 decimals
Token B: 9 decimals
Initial reserves: 1 A = 1_000_000, 1 B = 1_000_000_000
User deposits 0.5 A (500_000 raw), contract computes 0.5 B (500_000_000 raw)
Despite appearing balanced, subsequent swaps drastically skew reserves due to the magnitude difference in decimals. This enables an attacker to extract liquidity by exploiting the inaccurate internal representation of value.
The absence of decimal normalization leads to misaligned liquidity ratios, breaking the invariant x * y = k
that AMMs rely on. This results in:
Arbitrage opportunities due to distorted exchange rates
Value extraction at the expense of unsuspecting liquidity providers
Long-term pool imbalance and potential user fund losses
This issue was identified through manual code review.
Enforce decimal equality during pool initialization:
Normalize all token values to a common internal scale (e.g., 18 decimals) before any arithmetic operations:
This ensures proportionality is preserved regardless of token mint configuration.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.