# Imbalanced deposit skews pool reserves

Single-side or imbalanced deposits that shift reserves without charging the swap or skew fee

_Area: DeFi accounting and math bugs. Seen in 3 disclosed reports; latest 2025-03-31. Updated 2026-10-29._

## How it works
An AMM assumes deposits arrive in a ratio consistent with its pricing curve, and that any imbalance is either impossible or paid for. When a deposit path mints shares or sets targets from a ratio (e.g. D1/D0, or min(base, quote*I)) while reserves keep the full deposited amounts, the pool's actual reserves no longer match its target price. The imbalance is free: the depositor paid no swap fee for moving the pool off-balance, so the next trader absorbs the mispricing.

## Where it shows up
- Liquidity-add code that mints LP from a ratio only, with no per-asset ideal-vs-actual balance difference and no dynamic skew fee [E2](https://bugbountylibrary.com/r/c4%3A2024-11-mantra-dex%3AH-08.md).
- Pool bootstrap that consumes all locked amounts of two nominally equal-price tokens without requiring equal amounts [E1](https://bugbountylibrary.com/r/c4%3A2024-03-abracadabra-money%3AH-03.md).
- Target-setting that takes a minimum of two sides while reserves stay at full value, leaving one reserve above target [E1](https://bugbountylibrary.com/r/c4%3A2024-03-abracadabra-money%3AH-03.md).
- Rebalance math using a constant-sum midpoint on a constant-product or tick-based pool [E3](https://bugbountylibrary.com/r/c4%3A2024-12-lambowin%3AM-02.md).
- Raw `balanceOf` used as a price or reserve proxy on UniV3, including out-of-range tick liquidity [E3](https://bugbountylibrary.com/r/c4%3A2024-12-lambowin%3AM-02.md).

## How to review
The invariant: after any deposit, the pool's reserve ratio must equal the ratio implied by its pricing curve, or the depositor must pay a fee proportional to the deviation. Check that liquidity-add computes each asset's ideal balance, compares to actual, and charges a skew penalty (Curve's `_dynamic_fee * difference`) [E2](https://bugbountylibrary.com/r/c4%3A2024-11-mantra-dex%3AH-08.md). For bootstrap, confirm targets and reserves are set consistently — if targets use `min(base, quote*I)`, reserves must be trimmed to match, not left full [E1](https://bugbountylibrary.com/r/c4%3A2024-03-abracadabra-money%3AH-03.md). For rebalance logic, derive the target from `sqrtPrice`/tick, never from raw balances [E3](https://bugbountylibrary.com/r/c4%3A2024-12-lambowin%3AM-02.md).

## Variants seen
- Stableswap fork dropping Curve's skew fee, minting on D1/D0 alone [E2](https://bugbountylibrary.com/r/c4%3A2024-11-mantra-dex%3AH-08.md).
- Bootstrap creating a MagicLP pool where quote target < reserve due to unequal locked amounts [E1](https://bugbountylibrary.com/r/c4%3A2024-03-abracadabra-money%3AH-03.md).
- Constant-sum midpoint rebalance on a constant-product UniV3 pool, reading inactive-tick balances [E3](https://bugbountylibrary.com/r/c4%3A2024-12-lambowin%3AM-02.md).

## Impact and severity
E1 let an attacker drain ~158 MIM by selling the excess token then the other. E2 let a user skew the pool for ~0.16% cost, causing slippage losses for others. E3 produced wrong peg rebalances. Severity rises when the skew is cheap relative to the profit from trading against the mispriced pool, and when other LPs' shares are diluted without compensation.

## Why fixes fail
Ratio-only minting silently drops the imbalance fee even when the D check passes [E2](https://bugbountylibrary.com/r/c4%3A2024-11-mantra-dex%3AH-08.md); trimming targets without trimming reserves leaves the invariant broken [E1](https://bugbountylibrary.com/r/c4%3A2024-03-abracadabra-money%3AH-03.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2024-03-abracadabra-money%3AH-03.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-11-mantra-dex%3AH-08.md
- E3: https://bugbountylibrary.com/r/c4%3A2024-12-lambowin%3AM-02.md
