Agent 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

Stars 215
Forks 33

Install this agent skill to your Project

npx add-skill https://github.com/PlamenTSV/plamen/tree/main/agents/skills/injectable/governance-attack-vectors

SKILL.md

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 as getVotes()?

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)

  1. Is voting power snapshot-based or live-balance? If snapshot: when is it taken relative to proposal creation?
  2. Can proposal calldata target the governance or token contract itself?
  3. Can quorum be manipulated by changing total supply during an active vote?
  4. Is there a mandatory, non-bypassable delay between proposal approval and execution?
  5. 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

Expand your agent's capabilities with these related and highly-rated skills.

Didn't find tool you were looking for?

Be as detailed as possible for better results