Cheese Bank Hack
Incident Overview
Addresses, related to the flash loan attack:
The attacker - 0x882d72aa…6cd9aa
Smart contract with the malicious logic - 0x9e025943…0b93c3
Transaction behind the attack:
https://etherscan.io/tx/0x600a869a…02f1cc
The attacker:
- took a flash loan of 21k ETH from dYdX
- swapped 50 ETH to 107k CHEESE at UniswapV2
- added 107k CHEESE and corresponding 78 ETH into the liquidity pool at UniswapV2 and got UNI_V2 LP tokens back
- minted sUSD_V2 tokens with all LP tokens got from Step 3. This allowed the exploit contract to use those LP tokens as collateral for borrowing crypto assets from Cheese Bank
- raised the CHEESE price at UniswapV2 by swapping 20k ETH to 288k CHEESE, making the UNI_V2 LP tokens more valuable as collaterals Cheese Bank. This is the crucial step in this incident since the Cheese Bank uses the amount of WETH in a liquidity pool to estimate the price of the corresponding LP token. The manipulated UNI_V2-CHEESE-ETH pool (with 20k+ WETH) allowed the attacker to drain all the USDC, USDT, and DAI withheld by Cheese Bank by legit borrow() calls
- refreshed the price feeds of Cheese Bank. The attacker intentionally invoked the CheesePriceOracle::refresh() function to refresh the price of the UNI_V2-CHEESE-ETH LP token which is derived from the amount of WETH in the liquidity pool and the ETH price derived from the UNI_V2-USDT-ETH pool. Specifically, the CheesePriceOracle::fetchLPAnhorPrice() function gets the wEthBalance of UNI_V2-CHEESE-ETH contract. With the passed in ethPrice, the totalValue is derived by wEthBalance x 2 x ethPrice. Therefore, the unit price of the UNI_V2-CHEESE-ETH LP token is computed by totalValue / totalSupply of LP tokens. It means if the attacker could somehow increase the amount of WETH in a pool (e.g., addLiquidity() with flash loan ether), the price of the LP token would be increased
- drained the USDC, USDT, DAI withheld by Cheese Bank by borrow() calls. Besides the 2M USDC, 1.23M USDT and 87k DAI are borrowed from Cheese Bank. The exact balance of USDC/USDT/DAI is borrowed by the exploit contract
- swapped 288k CHEESE back to 19.98k ETH at UniswapV2
- swapped 58k USDC to 132 ETH at UniswapV2
- collected assets into https://etherscan.io/address/02b7165d0916e373f0235056a7e6fccdb82d2255
- repaid 21k ETH flashloan to dYdX.
Incident Report
Protocol Information
Market Context at Time of Hack
What the Attacker Needed to Succeed
Understanding the prerequisites for this type of attack helps auditors identify protocols that are most at risk and helps developers build better defenses.
What Auditors Should Check
If you're auditing a protocol with similar architecture to Cheese Bank, these are the critical security checks that could have prevented this incident (November 2020).
- Verify all logic paths related to Flash Loan Attack are guarded by proper access controls and input validation - see the Flash Loans Attacks attack class for patterns
- Review privileged functions (owner, admin, governance) for potential abuse vectors - centralization risks should be documented and bounded with timelocks or multi-sigs
Master these auditing techniques with hands-on labs and real exploit scenarios in the Smart Contract Hacking course.
Free TrialRelated Attack Classes
The technique used in this hack maps to these vulnerability classes in our security curriculum:
Sources & References
Learn to Prevent the Next Cheese Bank
The Cheese Bank hack is one of many attacks that skilled auditors are trained to detect before deployment. Master real exploit patterns and defense techniques with hands-on Web3 security training.