# BribesFactory::createBribeFlywheel can be completely blocked from creating any Flywheel by a malicious actor

Sending 1 wei of reward token to address(0) makes setFlywheelRewards attempt transferFrom from zero address, reverting all createBribeFlywheel calls.

- Payout: Contest reward
- Severity: medium
- Program: Maia DAO Ecosystem
- Credited: ABA
- Disclosed: 2023-09-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-05-maia-findings/issues/362
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AM-29
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** BribesFactory / FlywheelCore reward token transfer
**Root cause:** FlywheelCore::setFlywheelRewards reads balanceOf(address(0)) and, if >0, calls safeTransferFrom from the zero address, which reverts since address(0) never approved. Constructor initializes flywheelRewards to address(0) before resetting it.
**Steps:**
1. Deploy/mint a Solmate-based reward token (allows transfers to address(0)).
2. Call `bribeToken.transfer(address(0), 1)` to seed a nonzero balance at the zero address.
3. Call `factory.createBribeFlywheel(address(bribeToken))`.
4. Constructor sets flywheelRewards=address(0); setFlywheelRewards reads balanceOf(0)=1>0 and calls safeTransferFrom(address(0), newRewards, 1), reverting with arithmetic underflow.
**How found:** Code reading of createBribeFlywheel: noticed flywheelRewards initialized to address(0) then reset via setFlywheelRewards, which transfers any existing balance from the old rewards address without checking for zero address; realized Solmate ERC20 permits transfers to address(0).
**Exploitation:** Attacker burns 1 wei of the bribe/reward token to address(0); every subsequent createBribeFlywheel for that token reverts, permanently blocking flywheel creation (griefing DoS).
**Insight:** When a contract temporarily holds a sentinel address (address(0)) as a state value and later migrates balances from it, any token that permits burns to zero can be used to force a transferFrom from the zero address and brick the flow; check balanceOf(address(0)) assumptions in migration logic.
