# Undercounted liquidity leads to increased volumePerLiquidityInBlock and incorrect adaptive fee

Algebra/QuickSwap computes volumePerLiquidity from only final-range liquidity after a swap, undercounting engaged liquidity and skewing the adaptive fee.

- Payout: Contest reward
- Severity: medium
- Program: QuickSwap
- Credited: Jeiwan
- Disclosed: 2023-12-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-09-quickswap-findings/issues/136
- Library page: https://bugbountylibrary.com/r/c4%3A2022-09-quickswap%3AM-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:fee-bypass

**Target:** AlgebraPool.sol swap volume-per-liquidity accounting
**Root cause:** calculateVolumePerLiquidity is called after the swap loop using currentLiquidity of only the final price range, ignoring initial and intermediary range liquidity engaged during the swap.
**Steps:**
1. Read AlgebraPool.sol swap loop: currentLiquidity updated at L856 as price crosses ranges.
2. Note calculateVolumePerLiquidity called at L880 after loop, using only final currentLiquidity.
3. Compare to movePriceTowardsTarget (PriceMovementMath.sol L150) called inside loop at L789/L795 with per-range liquidity for fees.
4. Observe large swap across narrow positions traverses many ranges; volumePerLiquidity denominator undercounts, overstating volume/liquidity ratio.
5. Result: adaptive fee lowered when liquidity concentrated near current price.
**How found:** Compared the tech paper's definition of L_t (initial+intermediary+final range liquidity) against code placement of calculateVolumePerLiquidity outside the swap loop, and contrasted with fee computation inside the loop.
**Insight:** When a metric is defined over liquidity engaged in a swap, verify it is accumulated inside the price-traversal loop like fees, not sampled once after the loop from final state.
