Euler V1's `EToken.donateToReserves(uint subAccountId, uint amount)` — added in EIP-14 — let a user burn their own eTokens and credit the reserve, but it did NOT invoke `checkLiquidity` on the caller. The attacker flash-loaned 30M DAI from Aave, deposited into Euler to mint eDAI, recursively borrowed via `mint` to inflate dDAI (creating a 10x leverage position), then called `donateToReserves` to burn a large slice of their eDAI without proportionally reducing dDAI. This left the position with debt > collateral instantly — a state normally unreachable because the standard `withdraw`/`transfer` paths call `checkLiquidity`. A second attacker-controlled account then invoked `liquidate()`, which under Euler's percent-discount liquidation curve granted the liquidator an outsized portion of the violator's collateral (the bigger the gap, the bigger the discount). Repeated across pools (DAI, WBTC, stETH, USDC) for ~$197M.
Reproducible Foundry test fork from SunWeb3Sec/DeFiHackLabs. Clone the repo, run forge test against the file path above, and replay the exploit against a mainnet fork at the historical block. Use for reproduction only — not for live targets.
Classification: Protocol Logic. Technique: Flashloan Donate Function Logic Exploit. Target type: DeFi Protocol. Affected chains: Ethereum. Implementation language: Solidity. Funds returned: $240,000,000.
- chain
- ethereum
- protocol
- Euler V1
- bug_class
- flashloan
- date_occurred
- 2023-03-13
- loss_usd
- $197,000,000
- classification
- Protocol Logic
- technique
- Flashloan Donate Function Logic Exploit
- target_type
- DeFi Protocol
- language
- Solidity
- source_id
- dl:1183