Cheese Bank Incident: Root Cause Analysis




The Hack Walk-through

  • Step 1: Take a flashloan of 21k ETH from dYdX
Step 1: dYdX Flashloan of 21k ETH
  • Step 2: Swap 50 ETH to 107k CHEESE at UniswapV2
Step 2: Swap 50 ETH to 107k CHEESE at UniswapV2
  • Step 3: Add 107k CHEESE and corresponding 78 ETH into the liquidity pool at UniswapV2 and gets UNI_V2 LP tokens back.
Step 3: addLiquidity(107k CHEESE, 78 ETH) at UniswapV2
  • Step 4: Mint sUSD_V2 tokens with all LP tokens got from Step 3. This allows the exploit contract to use those LP tokens as collaterals for borrowing crypto assets from Cheese Bank.
Step 4: Mint sUSD_V2 Tokens with UNI_V2 LP Tokens
  • Step 5: Raise the CHEESE price at UniswapV2 by swapping 20k ETH to 288k CHEESE, which makes the UNI_V2 LP tokens more valuable as collaterals in 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) allows the bad actor to drain all the USDC, USDT, and DAI withheld by Cheese Bank by legit borrow() calls.
Step 5: Raise CHEESE Price by Swapping 20k ETH to 288k CHEESE at UniswapV2
  • Step 6: Refresh the price feeds of Cheese Bank. The hacker intentionally invokes the CheesePriceOracle::refresh() function to refresh the price of UNI_V2-CHEESE-ETH LP token which is derived from the amount of WETH in the liquidity pool and the ETH price derived from 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 UNI_V2-CHEESE-ETH LP token is computed by totalValue / totalSupply of LP tokens. It means if a bad actor could somehow increase the amount of WETH in a pool (e.g., addLiquidity() with flashloan ether), the price of the LP token would be increased.
Step 6: Refresh the price Cheese Bank
  • Step 7: Drain the USDC, USDT, DAI withheld by Cheese Bank by borrow() calls.
Step 7: Borrow 2m USDC from Cheese Bank
  • Step 8: Swap 288k CHEESE back to 19.98k ETH at UniswapV2. Now, the bad actor harvests $3.3m equivalent USDC, USDT, and DAI. She needs to pay the 21k ETH flashloan back to dYdX with the assets in her pocket. The first choice is the really valuable 288k CHEESE which fills in \~20k ETH.
  • Step 9: Swap 58k USDC to 132 ETH at UniswapV2. Since there’re some ether consumed in previous steps (e.g., fees paid to Uniswap), the bad actor needs to buy some more ether with USDC.
  • Step 10: Collect the hacked assets into 0x02b7.
Step 10: Collect the Hacked Assets
  • Step 11: Return 21k ETH flashloan to dYdX
Step 11: Return the 21k ETH Flashloan to dYdX


About Us




A Blockchain Security Company (

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Beosin Has Completed Security Audit Service of SeasonSwap With No Issues Identified

How to Stake FIO via Anchor Wallet

Can we be anymore simpler?!

DNA DEX Beta Testing Trading &Bug Hunting Competitions Have Now Concluded

How Does Night Owl Security Camera Work?

Night Owl Wireless Security System Reviews

{UPDATE} Little Musician Hack Free Resources Generator

Patch Tuesday Dashboard

DENA Buyback #4 Executed

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


A Blockchain Security Company (

More from Medium

How DeHive Ensures Top-Notch Security in Current Market Conditions

How DeHive Ensures Top-Notch Security in Current Market Conditions

5 methods for setting up a Private Blockchain Network

[ANALYSIS]: Where can I earn the best yields for Polygon (MATIC) tokens?

Application Release 2.4 | Optimizing mobile-friendly user experience