# H2O: weak randomness in mint enables flash-loan drain

H2O token's mint used predictable block data as randomness; attacker brute-forced favorable blocks, flash-loaned BUSD, and drained value via repeated skim.

- Payout: Real-world hack
- Severity: high
- Program: H2O
- Credited: DeFiHackLabs
- Disclosed: 2025-03-14
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2025-03/H2O_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20250314-h2o
- Tags: domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm technique:race-window vuln:accounting-error vuln:flash-loan vuln:oracle-manipulation

**Target:** H2O token contract on BSC
**Root cause:** The H2O token's mint/randomness check derived its random value from block.timestamp, pair address, and blockhash(block.number-1), which an attacker can predict and grind by choosing favorable blocks.
**Steps:**
1. Identify H2O token at `0xe9c4D4f095C7943a9ef5EC01AfD1385D011855A1` on BSC and its PancakeSwap V2 pair.
2. Compute randomness as `keccak256(abi.encodePacked(block.timestamp, H2O.pair(), blockhash(block.number-1))) % 2`; grind timestamps until desired outcome.
3. Flash-loan 100000 BUSD from PancakeV3Pool `0x4f31Fa980a675570939B737Ebdde0471a4Be40Eb`.
4. Swap borrowed BUSD for H2O via PancakeSwap Router V2.
5. Loop 50 times: transfer H2O balance to the pair and call `skim(address(this))` to extract value.
6. Swap accumulated H2O back to BUSD and repay flash loan plus fee.
**How found:** Researcher likely noticed the mint function used block variables for randomness and realized it could be brute-forced by selecting favorable blocks/timestamps.
**Exploitation:** Attacker flash-loaned 100k BUSD, bought H2O, then repeatedly transferred H2O to the pair and called skim to extract BUSD, exploiting the weak random mint to profit. Multiple attempts were needed because the random check had to pass; failed attempts reverted.
**Insight:** When a contract uses block.timestamp and blockhash for randomness, an attacker can grind transactions across blocks to satisfy the condition; look for modulo operations on block data in mint/reward logic.
