An exploit against Yearn’s v1 yDAI vault has led to 11m DAI of vault deposits being lost.
Acting in roughly 11 minutes, Yearn’s security team and multi-sig wallet signers were able to stop the exploit while it was underway, saving 24m DAI out of the vault’s total 35m DAI deposits.
By creating exchange rate imbalances in Curve’s 3pool, an exploiter was able to cause Yearn’s yDAI vault to deposit and withdraw funds from 3pool at unfavorable rates across a series of transactions.
The exploiter profited from the loss by holding a good portion of the Curve 3pool during the attack, and withdrawing to a combination of USDT, DAI, and ETH. It is estimated to have resulted in a 2.7m DAI profit.
Peckshield has released an analysis. This is an exploit that took advantage of a contract that relies on the business logic of an external contract.
In order to understand how the exploit works it’s helpful to first understand how Curve pools work. Curve pools are optimized for the exchange of like kind assets such as stablecoins and bases it’s bonding curve on the assumption that over the long term these assets have a one to one exchange rate.
In order to incentivize having a balance of assets in the pool it implements deposit and withdrawal bonuses/penalties. When there is a disproportionately small amount of a given token in the pool a deposit bonus is given, conversely a penalty is applied when a token has a larger share of the pool. The reverse is applied for withdrawals where a penalty is applied for withdrawing scarce tokens and a bonus is applied for abundant tokens.
The yDAI vault makes deposits and withdrawals into the Curve 3pool as part of it’s core strategy. In the block prior to the first transaction (11792210) the 3pool liquidity balances were:
Upon initiating the transaction the exploit contract, through a series a flash loans and swaps acquired 38,219,752 DAI and133,000,000 USDC which they swapped through 3pool for 167,159,608 USDT bringing the new pool balances to:
At this point the pool is heavily skewed which creates high slippage for DAI and USDC depositors and high rewards for USDT depositors and DAI and USDC withdrawers.
The exploiting contract then deposits 105,469,871 DAI into the yDAI vault. Upon triggering earn on the yDAI vault, the yDAI vault deposited 104,436,479 DAI in to 3pool which now made the skew significantly more extreme. With such an extreme skew the tails of the rewards curve are now utilized which are convex compared to when the pool is more balanced.
At this point the exploiting contract deposits back into the 3pool the USDT for 169,468,555 3pool shares and redeems it’s yDAI shares, which triggers a DAI withdrawal from 3pool where the exploiting contract receives 104,700,650 in DAI which is 769,221 less DAI than it deposited. The exploiting contract then redeems 168,604,719 3pool shares for it’s original deposit of 167,159,608 USDT and profit of 863,836 3pool shares. Considering the shares tend towards $1 in value over time the net profit on this turn for the exploiting contract was ~$94,000.
The contract call then loops through the above process a few more times then repaying the flash loans before hitting the gas limit and sending the final profits of 316,814 3crv and 11,833 USDT to the contract caller. As the limiting factor in the loops is the gas limit the attacker than initiated several more calls to the exploiting contract bringing the final amount of funds received by the exploiting sender to 506,314 3crv, 1,747,728 USDT and 513,356 DAI.
This attack shows the importance of understanding how dependent contracts function. It seems the Yearn team did have such an understanding as they implemented a withdrawal fee of 0.5% in the yDAI vault which would have rendered this attack unprofitable in most scenarios but they recently disabled the fee to encourage migration to new vaults. The vault also had slippage protection in place of 1% but at large enough sums and with enough rotations through a strategy it proved to be to too wide to deter such an attack. Another interesting point is that anyone could call the earn function which triggers a deployment of the vault funds and the attacker took advantage of that. In V2 vaults they utilize a network of keepers which are whitelisted agents that monitor the chain and trigger actions as needed. Finally it seems important to consider window of opportunity attacks, loosing parameters to facilitate temporary onchain events can create attack vectors that don’t exist under normal circumstances.
It looks like Quantstamp had successfully identified some of the vectors through which this exploit was executed in their audit. This is a good example of how audits should have more attention paid to them by the crypto community to avoid preventable exploits.
Great flag @Larry_Bates. Would be interesting to consider to what extent this type of vulnerability was already or could have been previously noted by auditors. Further, is there a consensus on whether this was a true exploit or is this something that is in contention?
@Vishesh There is no contention, this was indeed an exploit. Same old formula: cause an imbalance somewhere, profit elsewhere. As @Barry noted, the safety guards in place were off at the time the exploit happened.
@Jomari Thanks for your post and welcome to SCRF. It all boils down to the audit type based on what a client asks for. Audit companies traditionally focus on code audits only, which generally (unless obvious) do not cover economic attack threat models. If one wants an economic type audit, they have to go to specialized providers. One cannot and should not expect a one-size-fits-all audit type. Would you agree?
There may be a lack of clarity in the space about what specific assurances an audit generally provides. Possibly due to the lack of an accepted definition of what an ‘audit’ actually is?
I wonder also whether it’s reasonable for a single organization to provide sufficient coverage of sound economics, game theory, code security, etc, etc, as well as being able to provide a clear understanding about how a specific tool or protocol will interact with the wider ecosystem. Feels like a big lift to me.
This also raises the extremely thorny question about whether the issue at hand is an exploit or clever discovery of alpha.
Or whether the ‘exploit’ resides in the dapp in question or in another one that was combined with it in an unexpected manner. Or whether each one in isolation is fine, but combined with X others, can become a problem.
@Jomari do you know of any good examples of audits that explore potential economic failures? Particularly when the behaviour of the primitive in question is examined as a piece in the wider crypto economy?
The original paper that called for a moratorium on the DAO had a mix of economic and code vulnerabilities and is probably one of the best examples of both being highlighted in one piece of research. That is a great observation that an organization fit to execute one type of audit is most likely not fit to execute both to the same level of quality as if they only focused on one type. This is likely why regulations like Sarbanes-Oxley don’t explicitly require “code audits” even though it is a financial audit analyzing the safety of financial systems.