Editor's Note
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/Aave/Uniswap-style GovernorBravo abuse.
Install
npx skills add https://github.com/PurpleAILAB/Decepticon --skill contracts-governance-attackDAO 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
Related agent Skills
View allconvex-agents
waynesutton/convexskills
ai-agent-builder
claude-office-skills/skills
performing-ssl-tls-security-assessment
xalgord/xalgorix
random-number
rivet-dev/sandbox-agent
guardian-cli
zakirkun/guardian-cli
domain-identification-grouping
tech-leads-club/agent-skills