# Hack Analysis: Uranium Finance, April 2021

Uranium Finance's forked Uniswap V2 pair used a 10000 fee scale but kept 1000 in the K invariant check, letting attackers drain 26 pools for ~$50m.

- Payout: Real-world hack
- Severity: critical
- Program: Uranium Finance AMM
- Credited: Immunefi
- Disclosed: 2022-09-16
- Write-up quality: 8/10
- Original: https://immunefi.com/blog/bug-fix-reviews/hack-analysis-uranium-finance-april-2021/
- Library page: https://bugbountylibrary.com/r/blog%3Aimmunefi-com-blog-bug-fix-reviews-hack-analysis-uranium-finance-april-2021
- Tags: domain:web3 impact:funds-loss kind:incident platform:immunefi sev:critical tech:evm tech:solidity technique:incomplete-fix technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Uniswap V2-fork AMM pair contracts on BNB Chain
**Root cause:** The pair's swap() scaled balances by 10000 for the fee but compared the product against reserves scaled by 1000**2, so the K check was trivially satisfied and allowed outsized withdrawals.
**Steps:**
1. Fork BNB Chain at block 6920000 (pre-exploit) with an archive node.
2. Deploy attack contract; fund with BNB and wrap to WBNB via deposit().
3. Query Uranium factory getPair(WBNB, BUSD) to get pair address.
4. Transfer 1 ether WBNB to the pair, then call pair.swap() requesting 99% of the pair's BUSD balance.
5. Transfer 1 ether BUSD back to the pair, then call pair.swap() requesting 99% of the pair's WBNB balance.
6. Repeat across all 26 pairs to drain total liquidity.
**How found:** Compared Uranium's forked pair contract against canonical Uniswap V2, spotting the magic constant 10000 in the fee scaling but 1000**2 in the K requirement — a scaling mismatch that guarantees the invariant passes.
**Exploitation:** Attacker sends a tiny amount of token0 to the pair to inflate balance0Adjusted, then calls swap() asking for ~99% of token1; the broken K check passes because the reserve side is scaled by 1000**2 while balances use 10000. Repeating in reverse drains both tokens from each pair, netting ~$50m across 26 pairs.
**Escalation:** Single-pair drain generalized to all 26 Uranium pairs, amplifying loss to over $50m.
**Insight:** When auditing a Uniswap V2 fork, diff the pair's swap() constants: any change to the fee multiplier (1000) must be mirrored in the K check's 1000**2 term, or the invariant becomes vacuous.
