Skip to content
OpenSmartRoute
Skillv1.0.0

contracts-governance-attack

DAO governance attack — flash-loan-backed vote manipulation, delegation hijack, quorum dilution, proposal-spam DoS, time-lock bypass via emergency multisig, snapshot vs. on-chain vote desync, Compound

by dnzengou(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from dnzengou/evo-decepticon (packages/decepticon/decepticon/skills/standard/contracts/governance-attack/SKILL.md). Install upstream with npx skills add dnzengou/evo-decepticon --skill governance-attack. Copyright stays with the author.

DAO Governance Attack

Attack classes

1. Flash-loan-backed vote

DAOs that grant voting power = current token balance (not snapshot of past balance) are vulnerable:

// Attack: borrow governance token, vote, return loan, all in one tx
function attack() external {
    // 1. Flash-borrow gov tokens
    IFlashLoan(aave).flashLoan(address(this), govToken, 1_000_000e18, "");
}
function executeOperation(...) external {
    // 2. Vote on the malicious proposal
    governor.castVote(proposalId, 1);   // 1 = for
    // 3. Repay loan + premium (automatic by flash-loan callback)
}

This is what happened to Beanstalk (April 2022, $182M loss) — attacker flash-borrowed Beanstalk gov tokens, voted to drain the treasury, repaid the loan. Same block.

Defense check: Does getVotes(address, blockNumber) reference a past snapshot? If yes (Compound's GovernorBravo pattern, OZ Governor with ERC20Votes + getPastVotes), flash-loan vote doesn't work.

2. Delegation hijack

ERC20Votes lets users delegate. If a contract holds gov tokens and delegates to itself, controlling that contract = controlling the votes.

// If the target DAO has a contract holding tokens that delegates to itself,
// and that contract is upgradeable/has an admin function:
upgradeableContract.upgradeAndCall(newImpl, abi.encodeWithSelector(redelegate.selector, attacker));
// Now attacker controls those votes.

3. Quorum dilution attack

If quorum = % of total supply (not % of currently-active voters), an attacker can mint or stake extra tokens to push quorum out of reach:

// Some DAOs base quorum on totalSupply()
// Attacker mints a bunch of tokens to themselves (via legit minting if they're holder)
// Quorum requirement now too high for real voters to meet → all proposals fail

4. Proposal spam DoS

GovernorBravo has a proposalThreshold. If low, attacker spams proposals to:

  • Burn proposers' gas
  • Confuse the UI
  • Push real proposals out of the active window

5. Time-lock bypass via emergency multisig

Most DAOs have a "Security Council" or "Emergency Multisig" that can execute without time-lock for emergencies. If signers can be socially engineered, phished, or are compromised: instant treasury drain.

Check: timelock.executor() — if it's a multisig and you can compromise N-of-M signers, the time-lock is illusory.

6. Snapshot vs. on-chain desync

Off-chain Snapshot.org votes use signed messages. If the DAO trusts Snapshot results and executes via a relayer:

  • Forge votes by sniping pending signed messages
  • Bribe voters off-chain (cheaper than on-chain)
  • Replay signed messages on a fork

7. Proposal-script slippage

GovernorBravo proposals execute calldata. If the proposal description and the actual calldata don't match, voters approve one thing while approving another:

// Description: "Allocate 1000 USDC to grants"
// Actual calldata: transfer(attacker, 1_000_000e6)
// Voters who don't decode calldata get rugged.

Recon

# Identify the governance contract
cast call --rpc-url $RPC $TIMELOCK "getMinDelay()(uint256)"
cast call --rpc-url $RPC $GOVERNOR "votingPeriod()(uint256)"
cast call --rpc-url $RPC $GOVERNOR "proposalThreshold()(uint256)"
cast call --rpc-url $RPC $GOVERNOR "quorum(uint256)(uint256)" $BLOCK

# Compound/Aave/Uniswap-style: Get GovernorBravo state
forge inspect GovernorBravoDelegate storage-layout

# List active proposals
cast logs --rpc-url $RPC --address $GOVERNOR \
  --from-block latest:-1000 \
  "ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)"

Defender's checklist (the audit you're trying to defeat)

Defense Bypass
getVotes uses past-block snapshot Can't flash-loan-vote — find delegation-hijack instead
Two-step time-lock (queue + execute) Can't bypass without compromised emergency multisig
proposalThreshold > 0 Can't spam — but might still be cheap
Off-chain vote (Snapshot) → on-chain by N-of-M multisig Replace at the multisig layer

Tooling

# Tally, Boardroom — DAO dashboards (find target governance contracts)
# Forge / Foundry — simulate the attack on a fork
forge test --fork-url $RPC --match-test test_governance_drain
# Tenderly — live transaction simulation against fork

References

  • "Beanstalk Governance Attack" post-mortems (Beanstalk Farms, April 2022)
  • Compound GovernorBravo audit reports (OpenZeppelin)
  • "Slippage in Governance Proposals" — Trail of Bits research
  • Devcon Bogota talks on governance security

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/dnzengou-evo-decepticon-governance-attack/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

dnzengou-evo-decepticon-governance-attack.ocm.jsonjson
{
  "ocm": "1",
  "id": "dnzengou-evo-decepticon-governance-attack",
  "kind": "skill",
  "name": "contracts-governance-attack",
  "description": "DAO governance attack — flash-loan-backed vote manipulation, delegation hijack, quorum dilution, proposal-spam DoS, time-lock bypass via emergency multisig, snapshot vs. on-chain vote desync, Compound/Aave/Uniswap-style GovernorBravo abuse.",
  "publisher": "dnzengou",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "finance"
    ],
    "tags": [
      "skill-md",
      "defi",
      "dao",
      "governance",
      "flash-loan",
      "github"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "DAO governance attack — flash-loan-backed vote manipulation, delegation hijack, quorum dilution, proposal-spam DoS, time-lock bypass via emergency multisig, snapshot vs. on-chain vote desync, Compound/Aave/Uniswap-style GovernorBravo abuse."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "github",
      "repository": "https://github.com/dnzengou/evo-decepticon",
      "path": "packages/decepticon/decepticon/skills/standard/contracts/governance-attack/SKILL.md",
      "ref": "c7cb6b8eae3d30d60d96b6c4971aa6c26db4c4a0",
      "url": "https://github.com/dnzengou/evo-decepticon/blob/c7cb6b8eae3d30d60d96b6c4971aa6c26db4c4a0/packages/decepticon/decepticon/skills/standard/contracts/governance-attack/SKILL.md",
      "key": "dnzengou/evo-decepticon/packages/decepticon/decepticon/skills/standard/contracts/governance-attack/SKILL.md"
    },
    "allowed_tools": [
      "Bash",
      "Read",
      "Write"
    ]
  },
  "instructions": "# DAO Governance Attack\n\n## Attack classes\n\n### 1. Flash-loan-backed vote\nDAOs that grant voting power = current token balance (not snapshot of past balance) are vulnerable:\n\n```solidity\n// Attack: borrow governance token, vote, return loan, all in one tx\nfunction attack() external {\n    // 1. Flash-borrow gov tokens\n    IFlashLoan(aave).flashLoan(address(this), govToken, 1_000_000e18, \"\");\n}\nfunction executeOperation(...) external {\n    // 2. Vote on the malicious proposal\n    governor.castVote(proposalId, 1);   // 1 = for\n    // 3. Repay loan + premium (automatic by flash-loan callback)\n}\n``",
  "cost": {
    "context_tokens": 1149
  }
}

Fetch it by URL: GET /api/v1/registry/dnzengou-evo-decepticon-governance-attack/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.