Skip to content

Latest commit

 

History

History
79 lines (50 loc) · 4.4 KB

2020-10-30.md

File metadata and controls

79 lines (50 loc) · 4.4 KB

Vulnerability disclosure 2020-10-30

Summary

  • A potential vulnerability was mitigated ~1.5 hours after being reported by a security researcher Wen-Ding Li through Yearn's security vulnerability disclosure process on October 29 2020.
  • Through a flash loan vulnerability, funds of the TUSD vault could have been put at risk. It was not exploited.
  • The TUSD vault was configured to stop deploying funds to use its strategy while the problem was investigated and fixed.
  • Funds are safe. No action is required by users.

Background

Security researcher Wen-Ding Li contacts Yearn's security team following the steps outlined in Yearn's security process document.

Having established contact, Wen-Ding discloses that he has an initial proof of concept of a flash loan attack that can be mounted on the TUSD vault, resulting in an 18% loss to users, with the attacker being able to walk away with 650k TUSD.

As a mitigation against the attack, Wen-Ding recommends that the TUSD vault immediately is prevented from sending funds to the affected strategy, by calling setMin(0) on the TUSD vault.

He points out that other vaults using the Curve strategy would potentially be vulnerable to the same attack, such as the DAI vault and the GUSD vault, but that these vaults already have min set to zero and are therefore not vulnerable.

After the initial review of the details and confirming the vulnerability, a private group is put together to further investigate and resolve the problem.

Details of vulnerability

Two factors on Yearn's side made the TUSD vault vulnerable to the attack:

  1. The deposit() function of the TUSD strategy does not check for slippage before it calls add_liquidity().
  2. Anyone is able to call the earn() function in v1 Yearn vaults.

Combined, this meant that an attacker could crunch the DAI supply in the Curve's y pool, and profit from the imbalance caused as outlined below.

Step-by-step flash loan attack

  1. Borrow a large amount of TUSD using a flash loan.
  2. Swap 15.5M TUSD to DAI via curve.fi/y pool, leaving the pool with almost no DAI liquidity.
  3. Deposit 5.5M TUSD into yTUSD vault.
  4. Call earn() function on TUSD vault, forcing it to deposit into the strategy, which adds TUSD liquidity into the Curve pool, with strategy suffering huge slippage.
  5. Swap DAI back for TUSD. More TUSD will be returned due to the increased imbalance in the pool.
  6. Withdraw from the vault, forcing the vault to remove liquidty and suffer more losses.

Exploit

curve.exchange_underlying(3, 0, 15.5e24, 0)
yvtusd.deposit(5.5e24)
yvtusd.earn()
curve.exchange_underlying(0, 3, dai.balanceOf(hacker), 0)
yvtusd.withdrawAll()

Details of fix

The optimal fix would be to make Vault's earn() function permissioned. Unfortunately the Controller used in v1 doesn't allow upgrading a Vault without redeploying the whole system.

An acceptable workaround would be to intercept the call when it hits Strategy.

Vault.earn()Controller.earn()Strategy.deposit()

Timeline of events

Oct 30, 2020, 15:56 (UTC): Wen-Ding Li makes initial contact attempt with Yearn's security team in line with the established policy.

19:30: Disclosure of vulnerability.

19:47: Initial sense check of the Security team confirms vulnerability seems valid.

20:17: Transaction for Multi-sig is prepared for calling setMin(0)

21:07: setMin(0) transaction broadcasted successfully, Yearn's TUSD vault is no longer vulnerable.

Oct 31, 2020: Disclosure

Third party disclosure

As per Yearn's security process document, the project does not currently have any established bilateral disclosure agreements. In line with our security policy, no disclosure has therefore been made to third parties prior to to this publication.

Links