Beanstalk Hack Analysis & POC
Beanstalk protocol got hacked for around $74M through exploiting the governance mechanism & stealing all the BEANS & Curve LP tokens stored in the Beanstalk protocol. It is a bit complex hack, let’s break it down step by step.
Proposal creation transaction on BeanGovernance
Â
Imperative Functions of the Protocol
Before diving into the hack let’s analyze how the governance system worked for the protocol & why the proposal was important.
- The idea of a proposal is to modify the beanstalk protocol in any way that attracts or affects the interest of the community.
- A proposal for governance can be created by anyone who has deposited beans into the protocol. Anyone who hasn’t deposited beans will not be able to create the proposal.
- The proposal in this scenario is a smart contract that will be executed if enough votes pass for it. An example of this can be to whitelist other pools for governance voting, etc.
- If anything goes wrong, there is also an emergencyCommit function that bypasses all of the individual votes & executes the proposal. It can be called after a waiting period of one day.Â
Â
The Intent
The attacker created 2 Proposals.
The malicious contract requested the following tokens to be sent over to the exploit contract address.
- BEAN3CRV-f, A BEAN-CRV metapool on curve.
- BEANLUSD-f, A BEAN-LUSD metapool on curve.
- UNI-V2 ETH/BEAN, A liquidity pool for ETH-BEAN.
- BEAN token.
Â
Undertakings of the Exploit
- The attacker starts by taking a flashloan of $1 Billion from AAVE v2 containing the following assets.
- 350,000,000 DAI
- 500,000,000 USDCÂ
- 150,000,000 USDT
- The attacker takes yet another Flashloan from Uniswap v2 for 32,100,950 BEAN & Sushiswap for 11,643,065 LUSD.
- Then the attacker deposits DAI, USDC & USDT to Curves 3Pool (DAI/USDC/USDT) to get 979,691,328 3Crv tokens.
- Exchange 15,000,000 CRV tokens to 15,251,318 LUSD on BEANLUSD-f pool.
- Add single asset liquidity 964,691,328 CRV to get 795,425,740 BEAN3CRV-f.
- The attacker deposits 32,100,950 BEAN & 26,894,383 LUSD to get 58,924,887 BEANLUSD-f
- The user then deposits BEANLUSD-f & BEAN3CRV-f to the beanstalk contract to get enough voting power.
- The attacker calls Diamond.vote(18) At this point user has control over 66% of the voting power.
- The proposal gets executed by calling the Diamond.emergencyCommit(18) function on beanstalk protocol which sends the following tokens back to the exploit contract.
- 36,084,584 BEAN
- 0.540716100968756904 UNI-V2 ETH/BEAN.
- 874,663,982 BEAN3CRV-f.
- 60,562,844 BEANLUSD-f.
- 100 BEAN minted to the exploit contract.
- Removes 874,663,982 CRV single liquidity to get 1,007,734,729 CRV tokens.
- Removes 60,562,844 BEANLUSD-f single liquidity to get 28,149,504 LUSD.  Â
- Returns flashloan of 11,678,100 LUSD to Sushiswap.
- Returns flashloan of 32,197,543 BEAN to Uniswap V2.
- Exchanges 16,471,404 LUSD to get 16,184,690 CRV on LUSDCRV-f.
- Removes liquidity from 511,959,710 3CRV Pool to get 522,487,380 USDC, 358,371,797 DAI, 156,732,232 USDT.
- Returns flashloan on aave for 350,315,000 DAI, 500,450,000 USDC & 150,135,000 USDT.
- Removes liquidity on 0.540716100968756904 Uniswap V2 to get 10,883 Eth & 32,511,085 BEAN.
- Donated 250,000 USDC to Ukraine Donation Wallet.Â
- Swap 15,443,059 DAI to 15,441,256 USDC on Uniswap V3.
- Swap 37,228,637 USDC for 11,822 Eth on Uniswap V3.
- Swap 6,597,232 USDT for 2,124 Eth on Uniswap V3.
- Â Leaving the attacker with over 24k Eth ~ $72M in profit.
Â
The Exit Strategy
The hacker used tornado cash & split the ~24k Eth into chunks of 1, 10 & 100 Eth to disappear in thin air. One thing to note is that this hack was a result of a bad governance design and not an economic design.
Â
HACK YOURSELF!
Here is the Github repo that has POC for the hack.
Read More:
Cream Finance Hack: What Motivates Hackers to Return Stolen Funds?