Understanding Harvest Finance Flash Loan Attack For Autists

JSeam
5 min readOct 26, 2020
-24mil USDT+USDC, OUCH!

Hello fellow autists who have left money in harvest.finance and didn’t withdraw. In the midst of FUD and retard autists, I’ll provide a voice of reason and explain how this dark autist managed to pull off this Flash Loan attack. It wasn’t a hack on the contract but rather an economic exploit. So don’t be a retard FUDster. This dark autist has put his galaxy brain to bad use — had 200 iq, now it’s -200 iq.

Overview and Breakdown

The attack was done through manipulating the curve y vaults and used the mispricing in USDC and USDT to drain the fUSDC and fUSDT pools on Harvest Finance. The steps are pretty elaborate.

Here’s how the attack was done. Two key wallets and one contract were involved in this economic attack:

  1. 0xf224ab004461540778a914ea397c589b677e27bb (Mastermind address who creates and calls the attacker contract to orchestrate the economic attack)
  2. 0x3811765a53c3188c24d412daec3f60faad5f119b (Accomplice address who exits with RenBTC)
  3. 0xc6028a9fa486f52efd2b95b949ac630d287ce0af (Attacker contract with the steps to execute the attack)

Setup

To setup this attack clean ETH must be obtained to obfuscate the trail of the attacker. ~10 ETH from tornado cash is first sent to the Mastermind address.

Tx: 0x4b7b9e387a79289720a0226f695913d1d11dbdc681b7218a432136cc089363c4

The Mastermind address then sends 1 ETH to the Accomplice address who then does the necessary approvals on USDC, USDT, WBTC, and RenBTC so that it can eventually convert the funds to RenBTC and exit obfuscating trails once more.

Tx:
0x87a7a3e0ef64692c964fafa110a04077597cb1410ac126851f68f5e5441ea169

Later the Mastermind address creates the attacker contract and launches the attack shortly after.

Tx:
0x117f502fb08f575c8e1dc11d80094d177e2cdcf09b12a8bc121e49fd32f9c6d1

Interaction with the Attacker Contract

Now that the setup is complete. The Mastermind address now interacts with the attacker contract. Decompiled contract with some annotations I made in a hurry are found here.

The main reasons that made this economic attack feasible was the high arbTolerance was set at 3 in the Strategy Contract 0x1c47343ea7135c2ba3b2d24202ad960adafaa81c and that the Strategy Contract refers to the yCRV vault for prices. So to do the economic attack it is necessary to manipulate the yCRV stablecoin prices and running deposit and withdraw on functions on the fUSDC 0x9b3be0cc5dd26fd0254088d03d8206792715588b and fUSDT 0x1c47343ea7135c2ba3b2d24202ad960adafaa81c vault contract

The specific of the attack are as follows. I’ll outline the key steps in the transactions.

Step 1) Init the Contract and

Initialize the contract with the init() function. The init() function is probably meant for misc setup needed to run the contract.
Tx: 0x6fa5d1dbaa60a24b1593020c82f1fc414befb835f1755ba7830761d07de12f03

Step 2) Use Uniswap Flashswap Magic

Do a flashswap (more on flashswaps) on uniswap to get enough tokens to pull this off. You just need to return back the tokens with the 0.3% pool fees at the end of the transaction. Be sure to check the reserves on Uniswap so there’s enough liquidity to pull this off using the getReserves() method. Be sure to also check the vault contract if there’s enough investedUnderlyingBalance() to see how much money you’ll need to put to pull off this.

Once you call the token transfer on uniswap you have your magic internet money for your hanky panky dandy doodles economic exploit on Harvest.

Step 3) Manipulate yCRV prices while depositing and withdrawing out of either Harvest’s USDC pool or USDT pools

With your new temporary magic internet money in USDT and USDC you can start draining the pools. Essentially, you want to swap about the yUSDT and yUSDC pools on yCRV to mess with Harvest. OUCH!

This is the flow for milking USDC out of the fUSDC pool. The steps for milking USDT out of the fUSDT pool is the opposite.

  1. Deposit the flashswap USDT into the yCRV vault to get yUSDT.
  2. With the yUSDT you can now swap it for yUSDC to get USDC. So you now have your original USDC and the swapped USDC.
  3. Now the price of yUSDT and yUSDC isn’t going to be the same. Since you bought yUSDC, yUSDC price would go up.
  4. Now deposit your initial USDC into Harvest for fUSDC.
  5. Once thats done you can use you can use your swapped USDC convert it back to yUSDC swap it to get yUSDT. With the yUSDT withdraw your USDT from the yCRV vault.
  6. Now because you bought yUSDT, the price of yUSDC will go down.
  7. With the price of yUSDC down you can withdraw from the pool and earn a tiny lil but painful difference of around 0.6% from the Harvest pool.
  8. Repeat this a couple of times in the transaction
  9. Now you gotta settle the accounting problem with uniswap. Send them back the money + 0.3% LP fees!!!
  10. Now with the difference make sure you get some ETH back because this transaction just cost you crazy gas fees of 5–10+ ETH. Not that it’ll matter because you’ll get to pocket 24 mil dollars from this whole thing. Keep the USDC and USDT for pocketing.

Set of Txs:
https://etherscan.io/txs?a=0xf224ab004461540778a914ea397c589b677e27bb

Exit To renBTC

Wow you got rich with from fucking over a bunch of farmers. Time to escape with the hard earned loot. Send the USDC and USDT earned to your Accomplice address who has set up the escape route.

TX:
0x53fae6f1d6b8a76a666a0bf7f9c724e6006465e544f89f1515b939d8911e8c58

All you need to do is gradually swap USDC -> WETH -> WBTC -> renBTC or whatever leads to renBTC and exit off the darknodes in renBTC to obfuscate your trails. Now you have a $100k bounty on you :D

Be Nice!

Send some money back to the vaults you exploited because although you’re a dark autist you’re ~10% nice. So you give some lube as consolation to the people you fucked over.

Tx:
0x25119cd54a4562aa427d9770af383512f9cb5e8e4d17232ad96b69dc293a3510

Get Access to Degen Only Access (DOA) @ atomic.blue

Lmao I guess you’re now a huge cunt so you have access to some elitist asshole club on the internet.

Tx:
0x71a52869b68508f6db4fa12089b1e7415deb5bf13b54cce0730684b93b548955

A Possible Mitigation

A possible mitigation measure would be to introduce Chainlink oracles in the calculation of stable coin prices to make it much harder to manipulate the prices on Curve. Instead of having one source of price feeds, there should be multiple prices to cross-reference from. However, a problem with this approach is that there will be a very loose connection with the real share price and another arbitrage and flashloan attack could occur. This might not be a good solution

Instead of an arbitrage tolerance threshold of 3%, it should be reduced much more to a fair degree. I suppose 0.3% or less would make the attack harder economically since you’ll need to pay off whatever fees + insane gas fees.

The reason why such an attack was possible and couldn’t have been easily spotted is due to the large surface vector for the entire system. Because Harvest interacts with so many other contracts there are emergent side effects that are hard to predict or audit.

Instead of contract audits, the entire DeFi scene and smart contract should consider formal verification methods to verify the correctness of a smart contract mathematically. This is tedious, but probably less painful than randomly losing money because you don’t understand all the states the smart contract system would end up in. Bugs are costly.

--

--