name: "governance-attack-vectors" description: "Protocol Type Trigger governance (detected when Governor, Timelock, voting, proposal, quorum, delegate patterns found) - Inject Into Breadth agents, depth-external, depth-edge-case"
Injectable Skill: Governance Attack Vectors
Protocol Type Trigger:
governance(detected when Governor, Timelock, voting, proposal, quorum, delegate patterns found) Inject Into: Breadth agents, depth-external, depth-edge-case Language: EVM only (Solana has structural mitigations via token locking; Move governance is less standardized) Finding prefix:[GOV-N]
Orchestrator Decomposition Guide
When decomposing this skill into depth agent investigation questions, map sections to domains:
- Section 1: depth-external (flash loan voting, external token interactions)
- Section 2: depth-state-trace (proposal lifecycle state, execution integrity)
- Section 3: depth-edge-case (quorum boundaries, threshold edge cases)
- Section 4: depth-state-trace (delegation state, vote counting)
When This Skill Activates
Recon detects governance patterns: Governor, TimelockController, propose, castVote, execute, queue, quorum, getVotes, delegate, votingPower, or DAO framework imports.
1. Flash Loan Voting Analysis
1a. Vote Power Source
Identify how voting power is determined:
- Snapshot-based (block number checkpoint) or live balance?
- If snapshot: when is the snapshot taken? (proposal creation, vote start, or fixed intervals)
- If live balance: can voting power be acquired via flash loan within the voting transaction?
1b. Snapshot Manipulation Window
If snapshot-based:
- Is there a delay between proposal creation and snapshot? (proposal → delay → snapshot → voting)
- Can an attacker acquire tokens BEFORE snapshot and return them AFTER? (multi-block attack)
- Is the snapshot block predictable? Can attacker front-run to accumulate tokens in the snapshot block?
1c. Delegation Flash Attack
For delegation-based voting:
- Can delegation be changed within the same block as voting?
- Pattern: flash borrow tokens → delegate to self → vote → undelegate → return tokens (single tx if no snapshot or snapshot is current block)
- Is
delegate()subject to the same snapshot asgetVotes()?
Tag: [TRACE:vote_power_source={snapshot/live} → snapshot_block={when} → flash_window={YES/NO}]
2. Proposal Lifecycle Security
2a. Proposal Creation
- What is the minimum threshold to create a proposal? (token balance, delegation threshold)
- Can proposal threshold be met via flash loan? (same flash analysis as voting)
- Is there a limit on active proposals? (unbounded proposals → storage/gas griefing)
- Can an attacker spam proposals to dilute voter attention or exhaust gas budgets?
2b. Proposal Content Validation
For each proposal that includes executable calldata:
- Is the target contract restricted? (whitelist vs arbitrary address)
- Is the function selector restricted? (whitelist vs arbitrary calldata)
- Can a proposal encode calls to the governance contract itself? (self-referential governance: change quorum, change timelock, change voting period)
- Can a proposal encode calls to the token contract? (mint tokens, change supply, modify balances)
2c. Execution Integrity
For the execution path (typically via timelock):
- Is there a mandatory delay between queue and execution?
- Can the delay be bypassed? (emergency execute, guardian role, zero-delay configuration)
- Can a queued proposal be re-executed? (replay of governance action)
- Is execution atomic? If one action in a batch fails, do all revert?
2d. Cancellation and Veto
- Who can cancel a proposal? (proposer, guardian, anyone with threshold)
- Can a proposal be cancelled AFTER it passes but BEFORE execution?
- Can the cancellation mechanism be used to grief legitimate proposals?
- If a guardian/veto role exists: is it time-limited or permanent?
Tag: [TRACE:propose → calldata={target,selector} → restricted={YES/NO} → self_referential={YES/NO}]
3. Quorum and Threshold Analysis
3a. Quorum Computation
- Is quorum a fixed number or percentage of total supply?
- If percentage of supply: does supply change affect quorum? (token mint/burn changes the quorum threshold mid-vote)
- Can an attacker manipulate the quorum denominator? (inflate supply to lower effective quorum percentage)
3b. Threshold Edge Cases
- At exactly quorum (not quorum+1): does the proposal pass or fail? (
>=vs>) - At zero participation: what happens? (proposal fails, or defaults to pass?)
- Can abstain votes count toward quorum without counting for/against? (governance-specific - some implementations count abstain for quorum but not for approval)
3c. Voting Period Boundaries
- What happens if a vote is cast at the exact block where voting ends? (boundary precision)
- Can the voting period be changed while proposals are active? (retroactive period change)
- Is there a minimum voting period enforced? Can governance set period to 1 block?
Tag: [BOUNDARY:quorum_threshold={exact} → votes_for={quorum} → passes={YES/NO}]
4. Delegation and Vote Counting
4a. Delegation Chain Integrity
- Can delegation form cycles? (A delegates to B, B delegates to A)
- Is there a maximum delegation depth? (A → B → C → ... → unbounded gas)
- When delegation changes: are checkpoints updated correctly? (old delegate loses power, new delegate gains)
- Can self-delegation be used to double-count? (delegate to self + vote directly)
4b. Vote Weight Consistency
- Is vote weight at proposal snapshot equal to token balance at that block?
- Can token transfers AFTER snapshot but BEFORE vote change the outcome? (transfer tokens to a second account, vote with both)
- For staking/locking governance: are locked tokens counted correctly? (tokens locked in one contract, voting from another)
4c. Vote Tallying
- Are for/against/abstain tallied correctly in all code paths?
- Can a voter change their vote? If yes: is the old vote correctly subtracted?
- Can a voter vote multiple times? (nonce/bitmap check)
Tag: [TRACE:delegate(from={A}, to={B}) → checkpoint_update={block} → power_transfer={correct/incorrect}]
Key Questions (must answer all)
- Is voting power snapshot-based or live-balance? If snapshot: when is it taken relative to proposal creation?
- Can proposal calldata target the governance or token contract itself?
- Can quorum be manipulated by changing total supply during an active vote?
- Is there a mandatory, non-bypassable delay between proposal approval and execution?
- Can an attacker accumulate voting power via flash loan within the snapshot or voting window?
Common False Positives
- Block-delayed snapshot: Snapshot taken at proposal creation with multi-block voting delay → flash loan in voting tx cannot affect historical snapshot
- Timelock-enforced delay: All execution goes through timelock with non-zero minimum delay → immediate exploitation prevented
- Fixed quorum: Quorum is absolute number (not percentage of supply) → supply changes don't affect threshold
- Token transfer restrictions during voting: Tokens locked when delegated/voting → cannot transfer and re-vote
- Guardian with sunset: Veto power has an expiration → temporary centralization that decays
Step Execution Checklist (MANDATORY)
| Section | Required | Completed? | Notes |
|---|---|---|---|
| 1. Flash Loan Voting | YES | Power source, snapshot window, delegation flash | |
| 2. Proposal Lifecycle | YES | Creation, content validation, execution, cancellation | |
| 3. Quorum and Thresholds | YES | Computation, edge cases, period boundaries | |
| 4. Delegation and Vote Counting | IF delegation supported | Chain integrity, weight consistency, tallying |