# Loss Of Flash Governance Tokens If They Are Not Withdrawn Before The Next Request

Behodler's public assertGovernanceApproved overwrites pendingFlashDecision, locking previously deposited governance tokens; anyone can trigger it for any approved sender.

- Payout: Audit contest
- Severity: high
- Program: Behodler
- Found by: kirk-baird
- Disclosed: 2022-03-24
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-01-behodler-findings/issues/156
- Library page: https://bugbountylibrary.com/r/c4%3A2022-01-behodler%3AH-06
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:solidity technique:source-review vuln:access-control vuln:accounting-error

**Target:** FlashGovernanceArbiter.sol governance contract
**Root cause:** pendingFlashDecision[target][sender] is assigned flashGovernanceConfig instead of accumulating, so a second call overwrites the prior deposit's amount and unlockTime, leaving the earlier tokens unaccounted for in the contract.
**Steps:**
1. Sender calls approve() on the ERC20 asset for FlashGovernanceArbiter.
2. Sender calls assertGovernanceApproved(sender, target, emergency) depositing amount; pendingFlashDecision[target][sender] set with unlockTime = now + config.
3. Wait until pendingFlashDecision[target][sender].unlockTime < block.timestamp.
4. Call assertGovernanceApproved(sender, target, emergency) again with same target/sender; line `pendingFlashDecision[target][sender] = flashGovernanceConfig` overwrites prior record.
5. Prior amount is no longer tracked; withdrawGovernanceAsset cannot recover it, tokens locked in contract.
**How found:** Code reading of assertGovernanceApproved noticed the direct struct assignment overwriting prior state rather than accumulating, combined with the function being public.
**Exploitation:** Because assertGovernanceApproved is public, an attacker can call it with an arbitrary sender who has approved the contract, overwriting that sender's pendingFlashDecision and permanently locking their previously deposited governance tokens.
**Escalation:** Public callability lets any attacker grief any approved sender, not just self-inflicted loss.
**Insight:** When a deposit-tracking mapping is assigned wholesale from a config struct, check whether repeated calls overwrite prior balances; also check whether the deposit function is public and callable on behalf of others, turning a self-inflicted bug into griefing.
