On March 13th, 2023, the lending project, Euler Finance, on the Ethereum blockchain was attacked, and the attacker profited approximately 200 million US dollars. The SlowMist Security Team intervened and analyzed the situation promptly, and shared the results as follows:
Euler Finance is a non-custodial and permissionless lending protocol on Ethereum, allowing users to earn interest or hedge market volatility with their cryptocurrency assets.
When users deposit collateral on Euler Finance, they receive corresponding EToken as proof, and subsequent redemption of collateral and lending are both carried out through EToken. The design of EToken allows users to borrow more assets and increase their debt by minting EToken and directly using new EToken as collateral, that is, self-borrowing with layered leverage.
Euler’s soft liquidation mechanism allows liquidators to flexibly help debtors repay their debts, rather than being limited to fixed coefficients.
The following are the related addresses involved in this attack:
Attacker’s EOA Address 1: 0x5f259d0b76665c337c6104145894f4d1d2758b8c
Attacker’s EOA Address 2: 0xb2698c2d99ad2c302a95a8db26b08d17a77cedd4
There were two critical reasons behind the attack:
Firstly, failure to check whether the user was in a state of liquidation after donating funds to the reserve address resulted in the direct triggering of the soft liquidation mechanism.
Secondly, the debtor’s health factor drops below 1 when the soft liquidation logic is triggered due to high leverage. This allows the liquidator’s profit to entirely cover their debt, as the value of the collateral obtained after liquidation is greater than the value of the debt. Thus, the liquidator can successfully extract the obtained funds without the need for any additional collateral, passing their health check (checkLiquidity) with ease.
This section analyzes the attack transaction with hash 0xc310a0af, with other attack techniques remaining consistent:
- The attacker borrowed 30,000,000 DAI through a flash loan from Aave and created two sub-attack contracts (0x583c21 and 0xA0b3ee) in preparation for subsequent attacks.
2. The attacker deposited 20,000,000 DAI into Euler Finance through the deposit function and obtained 19,568,124.3 eDAI as collateral tokens.
3. Called the mint function (self-borrow) to borrow 195,681,243 eDAI and 200,000,000 debt tokens (dDAI).
4. Immediately after, the attacker called the repay function to repay the remaining 10,000,000 DAI. This was done to reduce the debt and increase the value of the collateral in preparation for another round of borrowing.
5. The attacker then called the mint function again (self-borrow) for a second round of borrowing, borrowing 195,681,243 eDAI and 200,000,000 dDAI. At this point, the account held approximately 410,930,612 eDAI and 390,000,000 dDAI.
6. The attacker then called the donateToReserves function to donate 100,000,000 eDAI to the reserve address. At this point, the account had 310,930,612 eDAI and 390,000,000 dDAI, placing the account in a liquidation state. However, the donateToReserves function did not check the account’s health factor.
7. Called the liquidation function using another sub-attack contract 0xA0b3ee to liquidate the account 0x583c21, which was in a liquidation state in the previous step.
During the liquidation process, the attacker transferred the debt of 259,319,058 dDAI from account 0x583c21 to 0xA0b3ee and obtained 310,930,612 eDAI from the account.
It is apparent that the liquidator only assumes a small amount of debt but can obtain the vast majority of the collateral. This is because of Euler Finance’s soft liquidation mechanism: when the liquidator begins the liquidation process, a discount is calculated based on the debtor’s health factor. As a result of this mechanism, the lower the health factor, the greater the discount and the more collateral that can be transferred. Ultimately, the liquidator only needs to cover their own debt to complete this attack.
Since the amount of collateral obtained by account 0xA0b3ee after liquidation was greater than the amount of debt, the account was able to pass the liquidation check successfully.
8. Finally, the attacker called the withdraw function to withdraw the funds obtained from the previous liquidation and repay the profit obtained from the flash loan.
MistTrack On-chain Analysis
At the time of writing, 100 ETH has been transferred by the attacker to Tornado Cash.
The remaining funds are held in the attacker’s address.
Here are the details: (Note: Prices are as of 10:00 UTC on March 14, 2023)
It is worth noting that there were a total of 6 attack transactions in this attack, with the first attack transaction initiated by the attacker’s EOA address 1, and all other attack transactions initiated by the attacker’s EOA address 2.
Here is the timeline for the 6 attack transactions:
On March 13, 2023, at 11:38:11 UTC, the attacker’s EOA address 1 withdrew 8,877,507.34 DAI to the attacker’s EOA address 2.
On March 13, 2023, at 12:08:35 UTC, the attacker’s EOA address 1 initiated an on-chain message transaction, claiming to be an MEV bot that outpaced the first attack transaction initiated by the attacker’s EOA address 2, and attempted to outpace other attack transactions but failed. Unfortunately, the attack contract created by the bot could only withdraw to the profit address of the attacker’s EOA address 2.
According to the on-chain analysis team at MistTrack, the source of the fees used by the attacker’s EOA address 1 was traced back to a hacker address that had previously carried out a flash loan attack on the EPMAX project on the Binance Smart Chain, stealing a total of 346,399.28 USDT.
After the attack, the EPMAX hacker address crossed to the ETH chain via cBridge and transferred the profits to Tornado Cash. The platform tools used by the EPMAX hacker include Multichain, FixedFloat, cBridge, 1inch, and KyberSwap.
The fees used by the attacker’s EOA address 2 were also traced back to Tornado Cash.
Upon careful analysis, it becomes apparent that there is no issue with examining the “donate” operation in isolation without verifying the donating user’s liquidity. When a user is in a state of liquidation after donating, it is inevitable that arbitrage bots will perform necessary liquidation procedures. Moreover, focusing solely on the characteristics of soft liquidation can serve to alleviate both excessive and insufficient liquidation scenarios. In cases of normal liquidation, the liquidator is required to provide collateral to avoid failing the liquidity check after completing the liquidation process.
However, when the “donate” operation is combined with soft liquidation, a different reaction occurs. Attackers can use leverage (self-borrowing) and the donation feature to lower their health factor to below 1, which directly leads to liquidators being able to cover their debts with profits after completing the liquidation.
The primary reason for this attack is the absence of liquidity checks in critical functions that involve user funds, which, when combined with a liquidation mechanism that dynamically updates discounts, creates lucrative arbitrage opportunities for attackers to siphon off a large amount of collateral without the need for collateral or debt repayment. As a result, the SlowMist Security Team recommends that lending protocols incorporate necessary health checks in functions that involve user funds, while also considering the security risks that can arise from combining different modules. This will allow for the design of secure economic and viable models that effectively mitigate such attacks in the future.