Started at 00:47:19 AM +UTC, Nov-17-2020, the Origin protocol was attacked by exploiting its flawed handling of the mint logic in its VaultCore smart contract. The hack results in a loss of approximately $7.7M (11,809 ETH and 2,249,821 DAI) from the affected vault. Here we elaborate the technical details in this blog post.




Summary

This incident was due to a bug in the protocol without (1) validating the transferred-in assets and (2) enforcing reentrancy protection on the mint logic. The exploitation leads to a greatly inflated totalSupply of the rebasing token, i.e., OUSD. The attacker then makes use of the inflation to redeem and drain about $7.7M of assets from the OUSD vault.

Details

The Hack Walk-through

We started the analysis from the transaction behind the hack: 0xe1c7…8401. This hack is initialized from a malicious ERC20-like contract (located at 0x47c3). This malicious contract implements a hook that will be invoked whenever the transferFrom() (function signature: 0x23b872dd) is being called.

With this preparation, the bad actor launches the attack by firstly applying 70K ETH flashloans from dYdX, then swapping 17.5K ETH to 7.85M USDT (on Uniswap) and other 52.5K ETH to 20.99M DAI (also on Uniswap). After the preparation, the malicious actor starts minting OUSD twice. The first minting operation is via mint() with 7.5M USDT while the second minting is via mintMultiple() with 20.5M DAI. However, the mintMultiple() routine does not properly validate the transferred-in assets.


The Reentrancy-Based Exploitation on Origin Protocol

As shown in the figure above, if the prepared malicious ERC20 assets are transferred in, the FakeToken.transferFrom() function is called, invoking the hook function that then re-enters the VaultCore contract again.


VaultCore.rebase()

The re-entered VaultCore.mint() dramatically inflates the totalSupply of OUSD by at least 20.5M (from the mintMultiple()). The above code snippet shows that the rebase() function derives the newTotalSupply by calculating the assets in the vault and strategies. Because of the previously transferred-in 20.5m DAI, the newTotalSupply is greatly increased and the following oUSD.changeSupply() applies it to the OUSD token contract. This inflates OUSD by 20.5M. When the execution returns to VaultCore.mintMultiple(), those 20.5M DAI corresponding OUSD would be normally minted again, which inflates OUSD by another 20.5M.

Due to the rebasing nature of OUSD, every OUSD owner accordingly gets an inflated balance. After that, the bad actor immediately redeems her share of 33.269M OUSD for profit. In total, the actor performs three valid mints: 7.5M USDT (via mint()), 20.5M DAI (via mintMultiple()) and 2K USDT (via reentered mint() due to the reentrancy), leading to 28M + 2K OUSD. However, because of the inflated totalBalance, the actor can walk away with 33.269M OUSD. The detailed attack sequence is as follows:

  1. dYdX flashloan 70K ETH
  2. swap 17.5K ETH to 7.85M USDT on Uniswap
  3. swap 52.5K ETH to 20.99M DAI on Uniswap
  4. OUSD.rebaseOptIn
  5. VaultCore.mint(7.5M USDT) -> 7.5M OUSD
  6. VaultCore.mintMultiple(20.5M DAI, 0 fakeToken) -> 20.5M OUSD (hijacked) * VaultCore.mint(2K USDT) -> 2K OUSD * inflate OUSD totalSupply by 20.5M
  7. swap 300K OUSD to 158.55K USDT on Uniswap
  8. swap 1M OUSD to 520.756K USDT on Uniswap
  9. VaultCore.totalValue() -> 35M
  10. VaultCore.redeem (33.269M OUSD) and gets following assets: * 19.5M DAI * 9.4M USDT * 3.9M USDC
  11. swap 10.45M USDT to 22.898K ETH on Uniswap
  12. swap 3.9M USDC to 8.305K ETH on Uniswap
  13. swap 19.0M DAI to 47.976K ETH on Uniswap
  14. payback dYdX flashloan 70K ETH

Aftermath

Once again, the classic reentrancy attack allows the hacker to walk away with 11,809 ETH + 2,249,821 DAI, which is around $7.7M loss. As a common mitigation mechanism to block such reentrancy attacks, the so-called Checks-Effects-Interactions design pattern always helps. In addition, whitelist the supported asset to avoid control flow hijacking and apply reentrancy guard if necessary.

About Us

PeckShield Inc. is an industry leading blockchain security company with the goal of elevating the security, privacy, and usability of current blockchain ecosystem. For any business or media inquiries (including the need for smart contract auditing), please contact us at telegram, twitter, or email.



Published

17 November 2020

Tags