C.R.E.A.M. Finance Post Mortem: Flash Loan Exploit Oct 27
Dear C.R.E.A.M. community, partners & friends, we would first like to thank everyone for their support and to everyone who has helped us in handling this exploit to date, especially our friends at Yearn. As communicated earlier, we have patched the vulnerability and only our Ethereum v1 markets were impacted. All other C.R.E.A.M. Finance v1 markets and the Iron Bank are safe.
Our community and users will always remain our top priority. We are working with authorities to trace the attacker and have created a plan to restore funds lost. We will disclose the details of this repayment plan as soon as everything is finalized.
This attack was a mix of economic and oracle exploits. The attacker flash borrowed DAI from MakerDAO to create a large amount of yUSD tokens, while simultaneously exploiting the price oracle calculation for yUSD price through the manipulation of the multi-asset liquidity pool (containing yDAI, yUSDC,yUSDT and yTUSD) on which the price oracle relied. This all took place in a single transaction.
Having increased the increased yUSD price per share, the attacker’s yUSD position was artificially increased, creating sufficient borrow limit to remove the vast majority of the liquidity from C.R.E.A.M. Ethereum v1 markets.
How did it happen?
Let’s start with yUSD and yCrv.
- yUSD: Yearn vault token. The underlying is yCrv. User deposits yCrv for yUSD
- yCrv: Curve Y Pool LP token. It is also called Curve.fi yDAI/yUSDC/yUSDT/yTUSD, which means this is a liquidity pool for all these y tokens.
There were two addresses A and B involved in the attack, and here are the steps taken:
- Address A flash borrowed $500M DAI and deposited into Curve and Yearn Vault for yUSD, and supplied the yUSD to get crYUSD
- Address B flash borrowed $2B ETH and added as collateral
- Address B borrowed yUSD and supplied yUSD recursively, and then transferred all crYUSD to Address A. The collateralized ETH position allowed the transfer to occur. Address A at this point had $1.5B crYUSD as collateral and $500M yUSD in the address
- Address A converted yUSD to yCrv via the withdraw function, leaving $8M yUSD in yCrv
- yCrv.balanceOf(yUSD) ~= 8m
- yUSD.totalSupply() ~= 8m
→ pricePerShare ~= 1
5. Address A transferred $8M yCrv to yUSD contract, leading to an increase in the pricePerShare:
- yCrv.balanceOf(yUSD) ~= 16m
- yUSD.totalSupply() ~= 8m
→ yUSD.pricePerShare() ~= 2
6. Thus, collateral value in Address A doubled and became $3B
7. Address A borrowed $2B ETH from C.R.E.A.M. Ethereum v1 to pay back the debt from Address B in step 2, and also unwrap yUSD to pay back DAI flash loan in step 1
8. Address A borrowed all the liquidity from C.R.E.A.M. Ethereum v1 markets with the rest of the collateralized ~$1B crYUSD
We have suspended all interactions with our Ethereum v1 markets. crTokens on C.R.E.A.M. Ethereum v1 markets are locked and cannot be transferred.
Our friends at Yearn Finance successfully salvaged $9.42 million the attacker “donated” to the yUSD vault to manipulate the pricePerShare as part of the attack and will soon return funds to the C.R.E.A.M. Multisig.
The key vulnerability lies in the price calculation of a wrappable token. We have stopped all supply/borrow of wrappable tokens, including all PancakeSwap LP tokens.
Impact & Repayment
The attacker removed ~$130m USD worth of tokens from C.R.E.A.M. Ethereum v1 markets. We are working to repay lost funds, starting with a partial payment. Details of this repayment plan will be announced in the coming days.
We encourage the attacker to reach out and begin a dialogue for the return of our users’ funds. They are impacting everyday users of DeFi and we would like them to do the right thing. We will honor a bug bounty of 10% upon return of funds.