DeFi Security

Governance Attacks: When DAOs Get Hijacked by Flash Loans and Voter Apathy

Kennedy OwiroJanuary 31, 20269 min read

Decentralized governance is supposed to give power to the community. In practice, it's given power to whoever can accumulate the most tokens in a single transaction. Beanstalk Farms lost $182M to a flash loan governance attack — the attacker borrowed enough tokens to pass a malicious proposal, drained the protocol, and repaid the loan, all in one transaction. They're not alone.

How Governance Attacks Work

Most DAO governance systems use token-weighted voting: more tokens = more votes. This creates several attack vectors.

Flash Loan Governance

function attack() external {
    // 1. Flash loan governance tokens
    aave.flashLoan(address(this), BEAN, 1_000_000e18, "");
}

function executeOperation(...) external returns (bool) {
    // 2. Create and vote on malicious proposal
    dao.propose(maliciousProposal);
    dao.vote(proposalId, 1_000_000e18);

    // 3. If quorum met + no timelock, execute immediately
    dao.execute(proposalId);
    // Proposal drains treasury to attacker

    // 4. Repay flash loan
    IERC20(BEAN).approve(address(aave), amount + fee);
    return true;
}

Governance Attack Variants

1. Flash Loan Voting

Borrow tokens → vote → repay. Only works if voting uses current balance rather than historical snapshots.

2. Proposal Spam

Create many proposals to confuse voters and sneak through a malicious one during voter fatigue.

3. Social Engineering

Disguise a malicious proposal as a routine parameter change through confusing naming or complex execution logic.

4. Vote Buying

Off-chain markets for governance votes (dark DAOs) that undermine the integrity of on-chain voting.

ProtocolYearLossAttack Vector
Beanstalk2022$182MFlash loan governance
Build Finance DAO2022$470KHostile takeover via token accumulation
Tornado Cash2023GovernanceMalicious proposal with hidden logic
Audius2022$6MGovernance contract vulnerability

Building Secure Governance

// Snapshot-based voting: immune to flash loans
function propose(bytes memory proposal) external {
    require(
        token.getPastVotes(msg.sender, block.number - 1) >= proposalThreshold,
        "Need tokens BEFORE proposing"
    );
    // Snapshot is taken at proposal creation block
}

// Timelock: gives users time to exit
function execute(uint256 proposalId) external {
    require(
        block.timestamp >= proposals[proposalId].eta,
        "Timelock not expired"  // 48-hour minimum delay
    );
}
  • ✅ Use snapshot-based voting (OpenZeppelin Governor) — tokens must be held before proposal
  • ✅ Implement timelocks (24-72 hours) on all governance actions
  • ✅ Set realistic quorum (10-20% of circulating supply)
  • ✅ Add voting delay (proposal → voting starts takes 1+ day)
  • ✅ Multi-step proposals for critical changes (propose → review → execute)

How Vultbase Detects Governance Issues

  1. Pattern DB — 16 governance attack patterns including flash loan voting and proposal manipulation
  2. Challenge-Based Testing — Simulates flash loan governance scenarios
  3. Access Control Analysis — Verifies timelock and threshold configurations

Your governance is your protocol's constitution. Audit it before someone rewrites it with a flash loan.

governanceDAOflash loan votingDeFi governancesmart contract securitytoken voting
Share

Written by

Kennedy Owiro

Founder & CTO, Vultbase

14+ years building security and QA systems at scale. Background in fintech security and Web3 smart contract testing. Built Vultbase's Intelligence Engine with 1,200+ exploit patterns from $40B+ in historical DeFi losses.

Protect your protocol before launch.

Submit your smart contracts for automated security analysis powered by 1,200+ real exploit patterns.

Start Your Audit →