Skip to content

Latest commit

 

History

History
69 lines (40 loc) · 5.63 KB

2021-06-29.md

File metadata and controls

69 lines (40 loc) · 5.63 KB

Vulnerability disclosure 2021-06-29

Summary

  • An attack vector in the GenLevComp strategy type was disclosed through Yearn's security process.
  • Yearn's yvDAI vault had two potentially affected GenLevComp strategies attached.
  • In the event of a successful exploit, an attacker would have been able to liquidate an affected strategy's entire debt position on Compound and potentially capture liquidation fees.
  • No funds have been lost. The vulnerable strategies were successfully wound down, and are in process of being fixed.
  • Yearn's security team has decided to award the disclosing security researcher, xyzaudits, with the maximum bounty reward of $200,000.

Background

A security researcher, xyzaudits, contacts Yearn's security team through its vulnerability disclosure process about a possible exploit that can lead to significant loss of user funds.

Shortly thereafter, a secure line of communication is established and the details of the vulnerability are disclosed. The issue is related to GenLevComp, a strategy type that is in use in two strategies in the yvDAI 0.3.0 vault. A war room is created, with the priority to remove funds from the possibly affected contracts followed by verifying the exploit and creating a fix.

Details of vulnerability

DAI GenLevComp[1], a.k.a StrategyGenericLevCompFarm, is a leveraged strategy that borrows and lends DAI repeatedly on Compound in order to farm Comp tokens. To get into this highly leveraged position it uses dYdX for flash loans.

To receive the flashloan, dYdX sends DAI to GenLevComp and then calls the function callFunction. After the logic is complete, dYdX needs to receive back more DAI than was sent otherwise the transaction reverts.

GenLevComp lends out the amount borrowed to Compound and borrows the repayAmount (calculated as amount+2) which it then returns to dYdX. The logic flow is that amount and repayAmount are passed to dYdX. dYdX send the DAI equivalent of amount to the contract and executes callFunction with input of amount and repayAmount. After callFunction dYdX pulls the repayAmount and verifies it has more funds than it started with.

If GenLevComp does not receive the expected amount from the loan, or if callFunction is called by anyone other than dYdX's SOLO contract, or if dYdX does not receive its funds back, the transaction reverts. It was believed that the combination of these three safety features made the function safe.

The security researcher was able to effectively initiate a flashLoan of 0 amount and inject their own value to repayAmount. Because of this there was no loan, so dYdX did not expect any repayment and therefore did not revert. dYdX SOLO contract still called the callFunction. And the function received the correct amount: zero. Bypassing the three safety checks.

Then a loan of the injected repayAmount was taken out from Compound. By calculating an exact number the exploiter would be able to force the strategy to borrow right up until it was 1 block away from liquidation. On the next block, liquidators would be able to liquidate the strategy and claim liquidation fees. By repeating this process again and again an exploiter would be able to completely liquidate the contract.

Details of fix

Two fixes were implemented[2]:

  1. A check was added to callFunction to make sure that only itself could initiate the dYdX call. Thereby stopping a third party from being able to intiate the flash loan.
  2. The calculation for repayAmount was moved from function doDyDxFlashLoan to function callFunction. Thereby removing the opportunity to inject a false number.

Timeline of events

June 29, 2021, 19:20 (UTC): Initial contact by xyzaudits.

20:15: Secure disclosure of vulnerability.

20:30: A war room is convened and the decision is made to remove all funds from the strategy before attempting to verify the exploit.

21:02: All funds are removed from DAI GenLevComp and returned to the yvDAI vault. Three more strategies which share the same code are identified, one of which is believed to be at risk: DAI IB GenLevComp[3]

21:09: All funds are removed from DAI IB GenLevComp and returned to the yvDAI vault.

21:53: As a precaution, all funds from the remaining two strategies are also removed and returned to yvUSDC.[4]

22:07: The exploit is verified.

22:25: Gro Protocol, who use a fork of the vulnerable contract and are deemed to potentially be at risk, are notified.

22:54: A fix is commited and ready for testing.

Third party disclosure

As per Yearn's security process document, the project does not currently have any established bilateral disclosure agreements.[5] However, in this case, due to the critical nature of the vulnerability, a disclosure was made to "Gro Protocol" prior to this publication.

References

  1. DAI GenLevComp: 0x55ec3771376b6E1E4cA88D0eEa5e42A448f51C7F
  2. https://github.com/Grandthrax/YearnV2-Generic-Lev-Comp-Farm/commit/a726df840ee7e51a6c84bf5115137560e9b9a3d3
  3. DAI IB GenLevComp: 0x77b7CD137Dd9d94e7056f78308D7F65D2Ce68910
  4. USDC GenLevComp: 0x339dc96a37Dba86008126B3391Db77af93cC0Bd9 USDC IB GenLevComp:0xE68A8565B4F837BDa10e2e917BFAaa562e1cD143
  5. https://github.com/yearn/yearn-security/blob/master/SECURITY.md#bilateral-responsible-disclosure-agreements