# AMM pool can be drained using a flashloan and calling stabilize

StabilizerNode.stabilize reads AMM pool spot price for trade sizing, letting a flashloan-skewed pool drain rewardToken as LP rewards.

- Payout: Audit contest
- Severity: medium
- Program: Malt Finance
- Found by: stonesandtrees
- Disclosed: 2022-02-14
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-11-malt-findings/issues/372
- Library page: https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AM-25
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:flash-loan vuln:oracle-manipulation

**Target:** StabilizerNode / UniswapHandler AMM stabilization logic
**Root cause:** The stabilization trigger uses a short TWAP, but the trade size is computed from the AMM pool's spot reserves in UniswapHandler._calculateTradeSize, which is flashloan-manipulable.
**Steps:**
1. Wait until TWAP rises above the stabilization threshold
2. Flashloan to remove all but a tiny amount of Malt from the AMM pool
3. Call `stabilize`; TWAP check passes and `_distributeSupply` calls `_calculateTradeSize` in UniswapHandler
4. Calculation concludes almost all rewardToken must be removed to restore peg
5. Malt mints Malt to buy out rewardToken from the pool
6. Protocol distributes received rewardToken as rewards; 0.3% to attacker, rest to LP rewards/swing trader/treasury
**How found:** Code review noting the mismatch between the TWAP-based trigger check and the spot-reserve-based trade size calculation in UniswapHandler, which is manipulable within a single transaction.
**Exploitation:** Attacker flashloans to skew pool reserves, triggers stabilize so the protocol mints Malt and swaps out rewardToken, capturing 0.3% directly while destroying the pool and misallocating LP rewards.
**Insight:** When a protocol mixes a manipulation-resistant oracle (TWAP) for one decision with raw spot reserves for the actual trade sizing, the spot read is the exploitable seam; check every downstream calculation that consumes pool state, not just the trigger.
