Beanstalk Governance Attack: When Flash Loans Meet Democracy
On April 17, 2022, Beanstalk Farms lost $182 million in a single transaction. There was no bug in the code. The contracts executed precisely as designed. An attacker borrowed over $1 billion in flash loans, deposited them into the protocol, acquired 79% of the governance voting power, passed a malicious proposal, drained the treasury, and repaid the loans—all atomically, within one block.
The vulnerability was not in the smart contracts. It was in the governance model.
How Beanstalk Governance Worked
Beanstalk was a decentralized stablecoin protocol. Users deposited assets into the “Silo” and received Stalk tokens representing both yield entitlements and governance voting power. Stalk holders could submit and vote on Beanstalk Improvement Proposals (BIPs).
The critical design choice: voting power was determined by the voter’s current Stalk balance at the time of casting a vote. There was no minimum holding period, no snapshot mechanism, no lock-up requirement. Capital deposited seconds ago counted equally with capital staked for months.
The protocol also included an emergency execution path: if a proposal accumulated 67% of all Stalk in favor, it could execute immediately rather than waiting for the standard multi-day voting window.
These two properties—snapshot-free voting and same-block emergency execution—combined to create the attack surface.
The Preparation
The attacker submitted two proposals days in advance, a necessary step because Beanstalk required a waiting period before a proposal could receive votes. Both proposals appeared legitimate at a glance. BIP-18 claimed to update some protocol parameters. BIP-19 contained a small BEAN donation to a Ukraine aid wallet, providing cover.
Both contained the same payload: code that would transfer all Silo assets to the attacker’s address if executed.
The Transaction
On April 17, the attacker executed a single Ethereum transaction:
Step 1: Flash loans. Borrow approximately $350 million DAI, $500 million USDC, and $150 million USDT from Aave.
Step 2: Acquire Stalk. Route the borrowed capital through Curve liquidity pools and deposit the resulting LP tokens into the Beanstalk Silo. The protocol credited the attacker with enough Stalk to represent roughly 79% of total governance power.
Step 3: Emergency commit. Call emergencyCommit(18) with that borrowed Stalk. The contract checked whether the proposal had exceeded 67% support. It had. The proposal executed immediately.
Step 4: Drain. The malicious proposal code transferred all Silo assets—approximately $182 million in BEAN, BEAN3CRV LP tokens, and BEANLUSD LP tokens—to the attacker’s address.
Step 5: Repay. Repay the flash loans plus fees. Net profit: approximately $80 million. The remainder reflected the spread between assets stolen and loans repaid.
The entire sequence took one block.
The Design Flaw
The emergencyCommit function checked one thing: whether current votes exceeded the threshold.
function emergencyCommit(uint256 proposalId) external {
Proposal storage p = proposals[proposalId];
require(
p.votesFor >= (totalStalk * 67) / 100,
"Insufficient votes"
);
executeProposal(proposalId);
}
The threshold was designed to be hard to reach—a supermajority representing two-thirds of all outstanding Stalk. Before flash loans existed at scale, reaching that threshold required genuine community coordination. An attacker would need to acquire that much real, long-term capital.
Flash loans changed the economics entirely. Any amount of capital can be borrowed for a single transaction at negligible cost. The question is not whether 67% can be accumulated—it always can, given enough borrowed capital—but whether the time constraints prevent conversion of that temporary capital into governance power and immediate execution.
Beanstalk had no such time constraints.
The Diamond Pattern’s Role
Beanstalk was built using EIP-2535 Diamonds—a pattern that routes calls to different “facet” contracts based on function selector. The governance facet controlled the diamond, and the diamond controlled the protocol. This meant governance approval was not just a parameter change: it was arbitrary code execution with full protocol permissions.
When the malicious BIP-18 executed, it called transferFrom directly on the Silo’s stored assets. There was no intermediate safety check, no multi-signature requirement for fund movements above some threshold. Governance approval was sufficient authorization for any operation, including draining the entire treasury.
What Would Have Prevented This
Three independent changes would each have been sufficient to prevent the attack:
Time-weighted or locked voting. Require that Stalk be held for a minimum period—say, 7 days—before it counts toward governance. Flash-borrowed capital cannot be held across blocks, let alone days. This single change would have made the attack impossible regardless of the flash loan amount.
Snapshot-based voting. Count voting power as of a block number recorded when the proposal was submitted, not as of when the vote is cast. Capital deposited after proposal submission carries no weight. Again, flash loans that exist only during the voting transaction provide no governance advantage.
Execution delay. Even if a proposal reaches the emergency threshold, require a delay—24 hours, 48 hours, any nonzero amount—between threshold attainment and actual execution. During that window, the community can observe the anomaly and respond. Flash loans cannot bridge this delay.
Any of these would have stopped this specific attack. All three together would have made this class of attack economically impossible for the foreseeable future.
Aftermath
The BEAN stablecoin lost its peg immediately, falling from $1.00 to around $0.14. The Beanstalk team publicly identified themselves to demonstrate they were not the attackers, then began negotiating with the attacker through on-chain messages.
The attacker routed the $80 million profit through Tornado Cash within hours of the attack. Nothing was recovered.
Beanstalk eventually relaunched with revised governance rules. The core protocol logic—the credit-based stablecoin mechanism—was not the problem. The governance layer around it was.
The Broader Pattern
Beanstalk was not an isolated case of flawed governance design. Many DeFi protocols in 2021 and 2022 used current-balance voting, reasoning that large capital stakes represented genuine commitment to the protocol. The assumption held when acquiring that capital meant long-term lock-up. It broke when flash loans made temporary access to arbitrary capital essentially free.
The question to ask of any governance system is: “What could an attacker accomplish if they had 100% of voting power for a single block?” If the answer is “drain all funds,” the governance system needs additional constraints regardless of how hard that 100% threshold seems to reach.