Yearn Finance Hack
The Story
On February 4, 2021, Yearn Finance, one of the pioneering DeFi yield aggregator protocols, suffered an exploit targeting its v1 yDAI vault. The attacker used a complex flash loan maneuver to manipulate the Curve's 3pool and drain approximately $11 million from the vault.
What made this attack notable was the rapid response from the DeFi community. The attack was noticed almost immediately, with users alerting the team through Discord. Yearn developers responded within minutes, quickly implementing a fix by pausing deposits to the affected vault.
Additionally, the Curve team assisted by temporarily killing the 3pool frontend to prevent further manipulation. Despite the quick reaction, the attacker managed to profit around $2.7 million, while the rest of the stolen amount was lost to slippage and fees in the complex transaction.
Following the incident, Yearn's governance took steps to enhance security measures and compensate affected users for their losses, demonstrating the resilience and collaborative nature of the DeFi ecosystem.
Technical Analysis
The Yearn Finance attack was a sophisticated flash loan exploit that took advantage of interactions between multiple DeFi protocols. Here's how it worked:
- The attacker took out a flash loan of millions of DAI from Aave
- They used this to manipulate the Curve 3pool (DAI, USDC, USDT) by creating an imbalance in the pool
- They exploited this imbalance to trick Yearn's yDAI vault's price calculations
- The vault's share price mechanism was manipulated, allowing the attacker to deposit and withdraw at artificially favorable rates
The key vulnerability was in how the yDAI vault calculated the value of deposits and withdrawals, particularly its reliance on external price feeds:
// Simplified representation of the vulnerable code
function getPricePerFullShare() public view returns (uint) {
// Get total assets in the vault including those deployed in strategies
uint totalAssets = token.balanceOf(address(this)).add(
Controller(controller).strategies(address(token)).totalAssets()
);
// Calculate price per share
if (totalSupply() == 0) {
return 0;
}
// Vulnerability: price per share can be manipulated through Curve pool imbalance
return totalAssets.mul(1e18).div(totalSupply());
}
The attacker's exploit contract contained complex logic that allowed them to:
- Create an imbalance in the Curve 3pool
- Deposit into the yDAI vault at a manipulated price
- Normalize the Curve pool
- Withdraw from the yDAI vault at a different manipulated price
- Profit from the difference and repay the flash loan
Lessons Learned
- DeFi protocols should implement multiple price oracles and circuit breakers
- Flash loan attack vectors should be explicitly considered in security audits
- Economic incentives should be designed to make attacks unprofitable
- Emergency response procedures should be documented and practiced
- Cross-protocol dependencies create complex attack surfaces that need ongoing monitoring