# FloorDAO staking: rebase accounting flaw drains ~40 ETH

FloorDAO staking rebase accounting flaw let attacker flash-borrow FLOOR, repeatedly stake/unstake to inflate gFloor, and drain ~40 ETH.

- Payout: Real-world hack
- Severity: high
- Program: FloorDAO
- Analysis by: DeFiHackLabs
- Disclosed: 2023-09-05
- Write-up quality: 7/10
- Original: https://github.com/SunWeb3Sec/DeFiHackLabs/blob/main/src/test/2023-09/FloorDAO_exp.sol
- Library page: https://bugbountylibrary.com/r/dhl%3A20230905-floordao
- Tags: area:web3 domain:web3 impact:funds-loss kind:incident platform:defihacklabs sev:high tech:evm tech:solidity vuln:accounting-error vuln:business-logic vuln:flash-loan

**Target:** FloorStaking contract (stake/unstake rebasing logic) on Ethereum mainnet
**Root cause:** Rebasing stake/unstake accounting let an attacker repeatedly cycle stake(rebasing=false) then unstake(rebasing=false) while circulatingSupply checks were bypassed, inflating gFloor balance beyond fair share.
**Steps:**
1. Flash-borrow nearly all FLOOR from the Uniswap V3 FLOOR pool via `floorUniPool.flash(...)`
2. Loop up to 17 times while `balanceAttacker + balanceStaking > circulatingSupply`: `floor.approve(staking, balanceAttacker)` then `staking.stake(address(this), balanceAttacker, false, true)`
3. Read resulting `gFloor.balanceOf(address(this))` and call `staking.unstake(address(this), gFloorBalance, true, false)` to convert back to FLOOR
4. Repay flash loan `flashAmount + fee1` to the pool
5. Swap remaining inflated FLOOR profit for WETH via `floorUniPool.swap(...)`
**Exploitation:** Attacker flash-borrowed the pool's FLOOR, cycled stake/unstake with rebasing disabled to accumulate gFloor, repaid the flash loan, and swapped the surplus FLOOR for ~40 ETH.
**Insight:** When a staking contract exposes both rebasing and non-rebasing stake/unstake paths, check whether mixing them lets share accounting diverge from circulatingSupply; flash-borrowing the entire pool balance amplifies any per-cycle rounding or rebase drift.

