Copyright © 2023 by Verilog Solutions. All rights reserved.

April 14, 2023

by Verilog Solutions

Background

Untitled

On April 12, 2023, Yearn yUSDT was exploited, resulting in a loss of 11.6 million. attacking transaction

The Yearn yUSDT pool mints yUSDT shares tokens for users when they deposit USDT into the pool. Due to the misconfiguration of the Fulcrum token address in the yUSDT pool, the attacker is able to manipulate the share price and profits of 11.6 million from the attack. The attacker withdraws from the yUSDT pool after inflating the share price and deposits into yUSDT after deflating the share price.

Unlike normal exploits, the attacker is not the only one who benefits from the exploit. AAVE V1 users' USDT loans were repaid by the attacker.

Walkthrough

Step 1 - ****The attacker first deposits USDT into the pool to mint some yUSDT. To inflate the share, the attacker mints some Fulcrum USDC to the yUSDT pool. Because of the share inflation, the attacker is able to withdraw more USDT from the yUSDT pool.

function _calcPoolValueInToken() internal view returns (uint) {
    return _balanceCompoundInToken() // Compound USDT balance
      .add(_balanceFulcrumInToken()) // Fulcrum USDC iToken (iUSDC)
      .add(_balanceDydx()) // Dydx balance
      .add(_balanceAave()) // aUSDT 
      .add(_balance()); // USDT balance
  }

Step 2 - is to deflate the share price

yUSDT pool supplies USDT in the pool to providers like AAVE based on the provider APR. If a new provider has a better APR, users can call rebalance() function to redeem all the tokens from all providers and supply those USDT to the new Provider. If everything’s configured right, the pool value shouldn’t change after rebalance.

Before the attack, AAVE V1 is the only provider with non-zero APR. To manipulate the provider APR and switch the provider, the attacker repays USDT loans for AAVE V1 users and lowers the AAVE APR to zero. Now all the provider has zero APR. So after rebalance(), USDC tokens are redeemed from the Fulcrum USDC pool. Due to the misconfiguration of the Fulcrum USDC, the pool balance becomes zero after rebalance. The share price is one for an empty Pool, which means an attacker can mint yUSDT at a better deal.

function rebalance() public {
    Lender newProvider = recommend();

    if (newProvider != provider) {
      _withdrawAll();
    }

    if (balance() > 0) { // USDT balance
      if (newProvider == Lender.DYDX) {
        supplyDydx(balance());
      } else if (newProvider == Lender.FULCRUM) {
        supplyFulcrum(balance());
      } else if (newProvider == Lender.COMPOUND) {
        supplyCompound(balance());
      } else if (newProvider == Lender.AAVE) {
        supplyAave(balance());
      }
    }

    provider = newProvider;
  }

Step 3 - The attacker now can deposit USDT into the yUSDT pool to mint yUSDT after deflating the share. The attacker later swaps the yUSDT to other tokens in the Curve’s y Swap pool.

After the aforementioned attacks, the majority of the funds are currently located in the following addresses:

  1. 0x5baC20BEef31d0ECCb369A33514831eD8e9cdfE0
  2. 0x16Af29b7eFbf019ef30aae9023A5140c012374A5
  3. 0x6f4A6262d06272c8B2E00Ce75e76d84b9D6F6aB8