# Governance finalization blocked by revert

Reverting or spam entries in ballot, proposal, or cancel paths that halt finalization or force linear defense cost

_Area: Smart contract access control and control flow. Seen in 3 disclosed reports; latest 2024-11-20. Updated 2026-10-24._

## How it works
Governance assumes every step between a decision and its recorded outcome completes. That breaks when a step can revert or be repeated at attacker cost: an external call inside finalization reverts and aborts the state write that marks the ballot finalized [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md), or an attacker floods the queue with entries that each need individual cancellation [E3](https://bugbountylibrary.com/r/c4%3A2024-10-kleidi%3AM-01.md). The invariant that fails is that finalization must be reachable regardless of what any single participant or callee does.

## Where it shows up
- Finalization code that calls an external contract before writing the finalized flag, with no try/catch [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md)
- A caller-chosen callee address in an approval/execution branch [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md)
- Per-item cancel/execute loops where cost scales with attacker-created items and no O(1) invalidation exists [E3](https://bugbountylibrary.com/r/c4%3A2024-10-kleidi%3AM-01.md)
- Privileged setters guarded only by a role, not by self-call, letting the role rewrite its own constraints [E1](https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AH-01.md)
- Proposer slots or nonces that stay occupied when finalization aborts [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md)

## How to review
Trace the finalization path end to end. The property: marking finalized (and freeing the proposer slot) must succeed even if the external call reverts — either the call is wrapped and its failure recorded, or the state write happens first. For queues, check whether one cheap action (epoch/nonce bump, pause) invalidates all pending items at O(1) cost; if cancellation is per-item, a compromised or hostile proposer forces linear defender spend [E3](https://bugbountylibrary.com/r/c4%3A2024-10-kleidi%3AM-01.md). For admin setters, require msg.sender == address(this) on any function that changes the governor, delay, or role itself, so changes only flow through the queued timelock path [E1](https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AH-01.md).

## Variants seen
- External call revert aborts ballot finalization, locking the proposer's active slot [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md)
- Spam of uniquely-salted proposals forces per-item cancel gas, draining the guardian [E3](https://bugbountylibrary.com/r/c4%3A2024-10-kleidi%3AM-01.md)
- Governor role can reassign itself and zero the delay, bypassing the timelock entirely [E1](https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AH-01.md)

## Impact and severity
Medium to high: a single reverting callee permanently blocks a proposal and its slot [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md); spam turns defense into a gas drain [E3](https://bugbountylibrary.com/r/c4%3A2024-10-kleidi%3AM-01.md); self-rewriting admin roles defeat the timelock's whole purpose, enabling instant privileged minting [E1](https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AH-01.md). Severity rises when the blocked path is the only route to finalize, or when the attacker pays little per item while the defender pays per item.

## Why fixes fail
Guarding setters with a role instead of self-call leaves the guarded party able to rewrite its own limits [E1](https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AH-01.md); adding try/catch without freeing the slot still strands the proposer [E2](https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md); per-item cancellation without an epoch/nonce bump leaves the linear cost intact [E3](https://bugbountylibrary.com/r/c4%3A2024-10-kleidi%3AM-01.md).

## Evidence
- E1: https://bugbountylibrary.com/r/c4%3A2021-11-malt%3AH-01.md
- E2: https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-02.md
- E3: https://bugbountylibrary.com/r/c4%3A2024-10-kleidi%3AM-01.md
