Economic Attack on Harvest Finance— Deep Dive
--
We analyze the economic attack that occurred against Harvest Finance in two parts: We analyzes specific attack methods based on transaction and smart contract codes.
What happened?
On October 26, 2020, a Flash Loan-based economic attack occurred at Harvest Finance. This attack allowed the hacker to withdraw and transfer about $24M of USDT, USDC, from the vault of Harvest Finance to the hacker’s wallet. The hacker deployed smart contracts for Flash Loan-based attacks and executed a total of 34 transactions.
Each transaction performed the following functions:
- Deploying a smart contract
- Calling smart contract initialization function
- USDC Vault Attack using Flash Loan (Total 17 Transactions)
- USDT Vault Attack using Flash Loan (Total 13 Transactions)
- Transferring $24M USDC, USDT to the hacker wallet
- Transferring about $2.5M USDC, USDT to Harvest Finance team
What is Flash Loan?
Let’s see what Flash Loan is before explaining the specific attack scenario.
Ordinary loans involve providing mortgages then borrowing money. But in Flash Loan, we can borrow a lot of money without any collateral. And the borrowed money can be used wherever you want if you keep only one condition. The condition is that the repayment shall be made within the same transaction where the loan occurred. If you keep this condition, you can borrow a lot of money without collateral. It may sound strange, but it’s possible in the blockchain world.
For instance, if two decentralized exchanges support the same token and there is a price difference, Flash Loan can be used to generate profit without investment funds because of the arbitrage opportunity.
- Borrow $100,000 via Flash Loan
- Purchase tokens for $10 per unit from decentralized exchange A
- Sell tokens for $11 per unit at decentralized exchange B
- Repay the loan in the same transaction
If all of the above processes are carried out in a single transaction, the loan is valid. Transactions on Ethereum can interact with a variety of smart contracts within the gas limit. That is why it is possible to perform a series of processes in a single transaction.
Uniswap and AAVE support Flash Loan, and the hacker used the flash swap function provided by Uniswap for this attack.
Economic Attack Scenario
To steal funds from USDC, USDT Vault, the hacker called the functions of a pre-written smart contract. Two types of functions were called for the attack, each being used for the USDT and USDC vault attacks. 17 transactions occurred in the USDC vault attack and 13 in the USDT vault attack.
Regardless of the type of vault, the attack method is similar. In this article, we look at an example of a transaction that stole funds from a USDC vault. There is a difference in the amount of USDC, USDT exchanged for each transaction, and the amount of tokens shown in the scenario below is about 0x35f8d2f572fceaac9288e5d462117850ef2694786992a8c3f6d02612277b0877 generated for USDC vault attacks.
The execution trace above occurred within a transaction with specific processes as follows:
- Borrow money using the flash loan in Uniswap
- The hacker borrowed USDT (18,308,555.417594) and USDC (50,000,000) from Uniswap for attacks.
- However, to attack the USDT vault, the hacker does not borrow USDC via the flash loan but use the USDC already in possession. Because the USDC vault attack has already generated USDC revenue, there is no need to borrow USDC from the flash loan while paying fees.
- Smart contract balance
2. Swap USDT to USDC in Curve Y pool — Price of USDC increases
- The hacker swapped USDT (17,222,012.640506) to USDC (17216703.208672) in the Curve Y pool. Through this swap, the hacker manipulated the USDC price of the Curve Y pool to rise.
- Smart contract balance
3. Deposit USDC to the USDC Vault of Harvest Finance
- The hacker deposited USDC (49977468.555526) into the USDC vault and received fUSDC (51456280.788906). At this time, the USDC/fUSDC exchange rate is 0.9712608022.
- Smart contract balance
4. Swap USDC from Curve Y pool to USDT — Price of USDC decreases
- The hacker swapped USDC (17,239,234.653146) to USDT (17,230,747.185604) in the Curve Y pool. This swap normalized the manipulated USDC price of the Curve Y pool.
- Smart contract balance
5. Withdraw USDC from the USDC vault of Harvest Finance
- The hacker withdrew the USDC (50298684.215219) equivalent to fUSDC (51456280.788906) from the USDC vault. The USDC/fUSDC exchange rate (0.97750329888 ) became higher upon this withdrawal than its deposit because the swap under Round 4 brought the USDC price in Curve Y pools back to the pre-manipulation level.
- The Harvest Finance team’s post-mortem misrepresented the withdrawn amount (50,596,877.367825) from “Round 2” as happened in “Round 1”.
- Smart contract balance
6. Repeat Rounds 2 to 5 twice
- Round 2 to 5 resulted in 8,734.545098 USDT, 298,684.215219 USDC profits. The hacker ran Rounds 2 to 5 two times more within the same transaction to increase the profit.
7. Repay the flash loan on Uniswap and buy ETH for the gas fee
- The hacker repaid the flash loan amount, along with the fee, and purchased and transferred 20ETH to the hacker’s wallet from Uniswap for the next attack.
- However, there is no ETH purchase for the gas fee when attacking the USDT vault. It seems that the hacker did not purchase additional ETH because enough gas fees were already secured during the USDC vault attack.
As a result of 3 transactions in total, the balance of smart contracts increased by 26,150.459777 USDT and 894,567.817318 USDC. The profit made with one transaction was about $920K. (The return is a bit smaller after deducting about 0.3% of the Flash Loan fee and gas fee.)
As mentioned earlier, the hacker generated 17 transactions to withdraw funds from the USDC vault, and 13 transactions were used similarly to withdraw from the USDT vault. A total of 30 transactions were generated to withdraw 14,761,898.396474 USDC and 11,718,914.048541 USDT from the vaults. Of these, $24M was transferred to the hacker’s wallet, and the rest was transferred to the Harvest Finance Team.
Smart Contract Code Analysis
Note) The term “Underlying Asset” used in this section means stable coins such as USDC and USDT.
An economic attack using the flash loan could occur due to the fAsset(ex. fUSDC, fUSDT) pricing mechanism, which is received when investors deposit their crypto into the vault for yield farming.
When you deposit USDC, USDT — the underlying asset — to the vault, you receive fAsset. When you withdraw the underlying asset from the vault, you return fAsset.
The exchange rate between fAsset and the underlying asset during deposit/withdrawal refers to the price of the Curve Y pool.
The deposit and withdraw function above shows that the underlyingBalanceWithInvention function determines the exchange rate of fAsset and the underlying asset.
Looking at the underlyingBalanceWithInvention code above, you can see that it is formed as the sum of the underlying asset held in the vault and the underlying asset invested in Strategy. The balance of the underlying asset held in the vault can be easily checked via the balance of the token that the vault address holds. However, it is complicated to calculate the value of the underlying asset invested through Strategy because the asset is converted to yCRV and deposited in the Curve Y pool.
To obtain the value of the underlying asset involved via Strategy, it communicates with multiple contracts as the diagram below. At this point, the number of yCRV tokens is converted to the value of the underlying asset through DepositY.vy in Curve Finance, which corresponds to the address hard-coded in the PriceConverter Contract.
(PriceConverter’s address is 0xfCA4416d9dEF20aC5b8b8b322b6559770eFbF but is not “Verified & Published” in etherscan. Harvest Finance team needs to “Verify & Publish” the contract.)
DepositY’s “calc_withdraw_one_coin” function converts the value of a single yCRV into an underlying asset. Because there was a large quantity of swap using a Flash Loan, the manipulated price is used to convert the yCRV into an underlying asset. The hacker can make profits through arbitrage within a single transaction due to the yCRV price difference between deposit and withdrawal.
Economic Exploit vs. Smart Contract Code Hack
There has been much debate in the De-Fi (Decentralized Finance) community about whether this incident should be seen as a security vulnerability in the smart contract code or an economic attack such as an arbitrage transaction. Some argue that this is not hacking because there are no security vulnerabilities in the code, such as Integer Overflow and Re-entrancy. Others claim that it is a code hack because the hacker withdrew assets via Flash Loan.
There are many ways to gain economic benefits from De-Fi without being a security vulnerability in code. Typically, there is an opportunity for arbitrage in the Automated Market Maker (AMM) via Front-Running. For example, in Uniswap, when transactions that cause high price volatility in pools of low-liquidity enter the Mempool of a blockchain node, you can make a profit by trading before then reselling it immediately after the transaction.
Uniswap allows setting an acceptable slippage to prevent this, but 0.5% of default values on the Uniswap fail to be greatly effective in preventing Front-Running. Even within 0.5% of slippage, many Front-Running bots earn more than $2M a month. Their revenue comes from the loss of traders in Uniswap. Whether you view this front running as an economic attack or as a hack depends on your viewpoint.
No matter what your viewpoint is, we are regretful that the HAECHI AUDIT team had not discovered it in advance and informed of this issue. Also, we apologize to investors who made investments with confidence after seeing our audit reports. However, a typical smart contract security audit is not an economic analysis but an analysis of security vulnerabilities in the smart contract code. We strived to find security vulnerabilities in the code. As a result, we delivered some issues to the Harvest Finance Team. For example, we have reported a code error in which the “defositArbCheck()” function always returned True. The released audit report was written based on the 4f2812d Commit made on September 12, 2020, and we are conducting the second audit of smart contracts additionally released.
Although it is not a security vulnerability in the code, we tried to draw attention from the community by raising the issue of a structure in which the foundation can readily withdraw assets deposited in Harvest Finance. The Harvest Finance Team quickly applied a Timelock contract by accepting our suggestion swiftly. Although this falls outside the scope of a general security audit that examines code vulnerabilities, we decided to disclose it in the report as we considered the information as important for the Harvest Finance Team and the community.
As De-Fi develops, the interaction between various building blocks is becoming more active. And numerous building blocks are constantly evolving via upgradable patterns. In this process, it is important not only to avoid security vulnerabilities in code but also to prevent economic attacks using flash loans and other methods. HAECHI AUDIT recognizes this importance and will work hard to establish better security auditing standards for de-fi protocols. Also, we are going to actively help the Harvest Finance Team to adequately address this incident.
HAECHI AUDIT Official website: https://audit.haechi.io/
HAECHI AUDIT Twitter: https://twitter.com/haechi_audit
About HAECHI AUDIT
It is HAECHI AUDIT’s mission to help clients develop secure smart contracts by providing the most trustworthy security auditing services.
HAECHI AUDIT is a top smart contract security audit firm consists of blockchain professionals. We provide the most secure smart contract security audit and smart contract development services to our global clients.
So far, based on the HAECHI AUDIT’s security audit report, our clients have successfully listed on the global cryptocurrency exchanges such as Huobi, Upbit, OKEX, and others.
Trusted by the industry leaders, we have been incubated by the Samsung Electronics and awarded the Ethereum Foundation Grants and Ethereum Community Fund.
Secure your smart contracts with HAECHI AUDIT.
Contact : audit@haechi.io