# Utopia: predictable airdrop address enables pair reserve drain

Utopia token's airdrop address was predictable from block.number and lastAirdropAddress, letting attacker skim pair reserves to a computed address and drain ~$119k.

- Payout: Real-world hack
- Severity: high
- Program: Utopia
- Analysis by: DeFiHackLabs
- Disclosed: 2023-07-20
- Write-up quality: 6/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-07/Utopia_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20230720-utopia
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm technique:source-review vuln:accounting-error vuln:business-logic

**Target:** BEP-20 token airdrop logic and PancakeSwap pair
**Root cause:** Airdrop recipient address was derived from a weak seed of lastAirdropAddress, block.number and the pair address, making it predictable; attacker set pair balance to 1 and skimmed reserves to that computed address.
**Steps:**
1. Swap WBNB to Utopia via PancakeSwap router.
2. Transfer 1 Utopia to the pair and compute `seed = (uint160(Utopia.lastAirdropAddress()) | uint160(block.number)) ^ uint160(address(Pair)) ^ uint160(address(Pair))`, then `notRandomAirdropAddr = address(uint160(seed | 1))`.
3. Call `Pair.skim(notRandomAirdropAddr)` to send excess tokens to the computed address, then `Pair.sync()`.
4. Transfer 1 more Utopia to pair, `Pair.sync()`, then swap 32 Utopia for WBNB via `Pair.swap` to extract value.
**How found:** Researcher noticed airdrop address derivation used only block.number and lastAirdropAddress, making it predictable; reproduced via Foundry PoC.
**Exploitation:** Attacker manipulated the pair's token balance to 1, computed the predictable airdrop address, skimmed reserves to it, resynced, and swapped out WBNB for ~$119k profit.
**Insight:** When a contract derives a recipient from block.number and a stored address, check if an attacker can force the pair balance to 1 and skim to that computed address to drain reserves.

