# UniswapV3Initializer.calculateLpTail() Miscalculates lpTailLiquidity Due to Incorrect Tick Usage

Doppler's calculateLpTail uses MIN/MAX_SQRT_PRICE instead of aligned-tick sqrt prices, minting an incorrect lpTail position and unbalancing bond vs sold amounts at initialization.

- Payout: Contest reward
- Severity: medium
- Program: Doppler
- Credited: KupiaSec
- Disclosed: 2025-02-18
- Write-up quality: 6/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_doppler.pdf#3.2.6
- Library page: https://bugbountylibrary.com/r/cantina%3Adoppler%3A3.2.6
- Tags: domain:web3 impact:integrity kind:contest platform:cantina sev:medium tech:evm tech:solidity technique:source-review vuln:accounting-error

**Target:** UniswapV3Initializer.calculateLpTail() in Doppler Solidity contracts
**Root cause:** Liquidity is computed against MIN_SQRT_PRICE/MAX_SQRT_PRICE (for unaligned MIN_TICK/MAX_TICK) while the position is actually minted at ticks aligned to tickSpacing, so liquidity and tick range disagree.
**Steps:**
1. Note calculateLpTail computes lpTailLiquidity via LiquidityAmounts.getLiquidityForAmounts(sqrtPriceAtTail, MIN_SQRT_PRICE, MAX_SQRT_PRICE, ...)
2. Observe posTickLower/posTickUpper are alignTickToTickSpacing(MIN_TICK/MAX_TICK, tickSpacing), not MIN_TICK/MAX_TICK
3. When MIN_TICK/MAX_TICK are not multiples of tickSpacing, aligned ticks differ from MIN/MAX
4. Mint lpTail with mismatched liquidity vs range, producing imbalance between bondingAssetsRemaining and reserves
**How found:** Code reading of calculateLpTail: noticed liquidity computed with MIN/MAX_SQRT_PRICE while the minted position uses tickSpacing-aligned ticks, a mismatch that only manifests when MIN_TICK/MAX_TICK aren't multiples of tickSpacing.
**Insight:** When a function computes liquidity from sqrt prices but mints at ticks, verify the sqrt prices correspond to the exact aligned ticks used for minting—tickSpacing alignment silently shifts the range endpoints.
