What is a governance attack?
A governance attack aims to implement malicious proposals to steal funds from projects that use a smart contract governance system called a DAO (Decentralized Autonomous Organization). DAOs allow users to vote with governance tokens on proposals that change the project's code. Proposals are only implemented if they receive enough votes.
Acquiring governance power
An attacker must obtain sufficient voting power to propose and vote on a nefariously crafted proposal. There are a few common methods an attacker may use to gain enough voting power.
- Use flash loans offered by lending protocols to borrow stable coins to buy governance tokens.
- Exploit any flaws in functions related to the distribution of governance tokens in the protocol.
- Exploit or manipulate any connected price oracles to drastically reduce the price of governance tokens.
- Use a Sybil-like strategy to slowly obtain governance tokens across multiple accounts to avoid detection.
Executing an attack
Attacks vary based on the architecture of the project and the method used to acquire governance tokens. However, attackers generally do the following:
- Write the malicious proposal(s). The proposed code changes may be as small as altering a fee percentage or other global parameters. Other times, the proposal may be as extreme as a completely new implementation smart contract for the project's proxy contract. For non-upgradable projects, the proposal may be a new contract that is added to the project's whitelist.
- Propose the proposal(s). Some projects may require users to hold a portion of governance tokens in order to submit proposals.
- Vote to affirm the implementation of the proposal(s), assuming the attacker has acquired enough governance tokens. If governance tokens were acquired through a flash loan, they must be sold to pay back the loan in the same block the vote passed.
- Implement the malicious proposal. This execution changes the state of the project to benefit the attacker, allowing them to steal funds.
Real world example
In 2022, Beanstalk suffered an infamous governance attack, where an attacker exploited the DAO to steal $181M.
Their emergencyCommit()
function required a supermajority of governance power to quickly vote and execute proposals. There was a 1-day delay between proposal submission and voting. Unfortunately, it had zero delay between the voting and implementation stage.
This allowed the attacker to create multiple flash loans and obtain a supermajority of governance power. The power was used to call emeregencyCommit()
for the attacker’s proposals, immediately voting on and implementing them in the same block. The execution drained the project, allowing the attacker to profit and pay back the flash loans.
In part, the attack was successful due to the misdirection and obfuscation techniques used to calm suspicions of the Beanstalk team.
The first proposal BIP18 (Beanstalk Improvement Proposal #18) was the Trojan horse. It appeared empty until deployment because the malicious code used to steal funds was placed inside the constructor of the proposal's implementation contract.
The second proposal BIP19 was the distraction used to avert attention away from BIP18. The implementation was named initBip18
to create the illusion that it was a part of the initialization process, despite having no connection.
Additionally, BIP19's verified code included logic to donate $250,000 to Ukraine’s donation address, which offered a stamp of legitimacy that any on-chain observer could view. During the attack, a small portion of the stolen funds from BIP18 were actually used to perform the donation.
More technical breakdowns of the attack can be found by Cyfrin and Immunefi.
Preventing governance attacks
- Ensure there is always a non-zero delay between the voting and implementation stages for a proposal. This disallows attackers from leveraging flash loans to obtain sufficient voting power to immediately execute malicious proposals.
- Implement a time lock on governance token transfers so they cannot be used to immediately vote. This also stops flash loans.
- Allow users to delegate voting power to prominent DAO members to increase voter turnout, increasing the amount of governance tokens an attacker needs to pass a proposal.
- Implement a veto mechanism that allows trusted actors to pause or reject proposals after voting. This reduces decentralization but can act as the final line of defense against malicious proposals.
- Ensure price oracles relating to governance tokens cannot be manipulated.
- Ensure governance token distribution mechanisms cannot be exploited so attackers cannot infinitely mint or earn tokens.
- Reduce governance token liquidity so it becomes more difficult to quickly obtain tokens in bulk.
- Ensure proposals are audited by reputable security firms or internal teams before they are put up to vote.
- Limit the power of governance actions where possible, so if an attack does occur, damage is minimized.