CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

avatar
CertiK
11 months ago
This article is approximately 1782 words,and reading the entire article takes about 3 minutes
Hackers exploited an integer division problem to hollow out the fund lending pool on Hope.money.

At 19:48:59 on October 18, 2023, Beijing time, Hope.money’s lending pool was attacked based on the implementation of flash loans.

Hope.money has built the HopeLend lending platform, HopeSwap decentralized exchange, stable currency $HOPE, and governance token $LT to provide users with full-stack decentralized financial services.

The protocol involved in this attack is HopeLend, a decentralized lending platform where users can provide liquidity to the protocol or earn income from over-collateralized loans.

The whole story

In the code implementation of HopeLend, there is an exploitable vulnerability in the lending pool. When destroying deposit certificates, an erroneous integer division problem occurred, causing the decimal point part to be truncated, resulting in the destruction of a smaller number of certificates than expected. Obtained and expected Consistent value token.

The attacker exploited this flaw to empty the various lending pools where funds existed on Hope.money.

Among them, the hEthWbtc lending pool was deployed 73 days ago, but there was no funds in it. Therefore, the hacker injected a large amount of funds into the lending pool to dramatically increase the discount rate, thereby quickly emptying out all other loans within a block transaction. Pool funds.

What’s even more dramatic is that the hacker who exploited the vulnerability did not obtain the funds to exploit the vulnerability. His attack transaction was discovered by the front-runner. The front-runner imitated his attack behavior and successfully stole all the attack proceeds (527 ETH), and finally 50 % of the attack proceeds (263 ETH) were used by front-runners to bribe the miners who packaged the blocks (payload).

The initial hacker who discovered the vulnerability created an attack contract in block 18377039 and called the attack contract in block 18377042. At this time, the front-runner monitored the transactions in the memory pool and simulated the attack contract as a front-runner. The input to the running contract was exploited in the same block 18377042, and the initial hackers transaction in block 18377042 failed to execute because it was sequenced behind the front-runner.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

Where the funds go

An hour after the front-runner received his profit, he moved the funds to: 0x9a9122Ef3C4B33cAe7902EDFCD5F5a486792Bc3A

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

At 13:30:23 on October 20, the suspected official team contacted the address, allowing the front-runner to leave 26 ETH (10% profit) as a reward, and received a reply from the front-runner.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

The final funds were transferred to GnosisSafe’s multi-signature vault after an hour of communication.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

Below we show the actual vulnerability and the details of how hackers exploited it.

pre-information

*HopeLend’s lending protocol implementation is forked from Aave, so the core business logic related to vulnerabilities is referenced from Aave’s white paper.

0x00 Deposits and Loans

Aave is a pure DeFi. The lending business is implemented through a liquidity pool. When users deposit liquidity in Aave, they expect to receive the income from lending.

The loan proceeds will not be fully distributed to users. A small portion of the interest income will be included in the risk reserve. This proportion is small, and most of the loan proceeds will be distributed to users who provide liquidity.

When lending deposits in Aave, Aave uses discounting to convert the number of deposits at different points in time into the number of deposits at the initial time point of the liquidity pool. Therefore, the sum of principal and interest corresponding to the underlying assets for each number of shares can be directly It is calculated using amount (share) * index (discount rate), which greatly facilitates calculation and understanding.

It can be understood as a process similar to purchasing a fund. The initial net value of the fund is 1. The user invests 100 yuan to obtain 100 shares. Assume that after a period of time, the net value becomes 1.03. At this time, the user invests 100 yuan again and obtains 100 shares. is 97 and the total share of users is 197.

This is actually discounting the asset according to the index (net value). The reason why this is done is because the users actual sum of principal and interest is multiplied by the current index using balance. When depositing for the second time, the correct principal and interest sum of the user should be 100 * 1.03 + 100 = 203. If discount processing is not performed, the principal and interest sum after the user deposits 100 for the second time becomes (100+ 100) * 1.03 = 206, which is wrong. If discounting is carried out, the sum of principal and interest becomes (100 + 100 / 1.03) * 1.03 = 103 + 100 = 203, and the result of 203 is correct.

Attack process

0x25126......403907(hETHWBTC pool)

0x5a63e......844e74 (attack contract-cash out)

attacker:

1. Lend initial flash loan funds and pledge them

The attacker first borrowed 2,300 WBTC from Aave Flash Loan and pledged 2,000 WBTC to HopeLend. The funds will be transferred to HopeLends hEthWbtc contract (0x251...907) and the corresponding 2,000 hETHWBTC will be obtained.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

2. Use the empty loan pool to manipulate the initial discount rate (liquidityIndex)

Borrow 2,000 WBTC via flash loan from HopeLend.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

The current value is 1 hETHWBTC = 1 WBTC.

The normal operation of depositing and withdrawing ETHWBTC in exchange for WBTC will not affect the exchange ratio (the exchange ratio will only be affected when interest is earned, and 1 hETHWBTC will get more WBTC).

At this point, the hacker begins to manipulate the discount rate through a series of complex operations:

• The hacker directly transferred the 2,000 WBTC obtained to HopeLend’s hEthWbtc contract (0x 251…907) through direct transfer. This step is not a loan repayment.

• The hacker then withdrew most of the WBTC (1999.999...) pledged in step 1, so the previous step required transferring WBTC back to replenish the assets in the pool.

• In the end, the hacker only retains the smallest unit (1 e-8) of hEthWbtc. This cannot be fully mentioned here because a little bit needs to be left. When calculating the discount rate (liquidityIndex), new ones will be added based on the existing ones. Yes, if cleared, the discount rate (liquidityIndex) will become 0, and the proportion in the pool cannot be unbalanced.

• The wBTC exchanged for destroying most of the hEthWbtc in the previous step, plus the remaining wBTC from the previous flash loan, will be returned to the flash loan lent to the HopeLend pool, with a total payment of 2001.8 WBTC (including interest of 1.8 wBTC).

• The above process destroys most of the hEthWbtc, leaving only 1 minimum unit (1 e-8) of hEthWbtc in the hacker account. This reduces the total amount of hETHWBTC, but there are 2001.8 wBTC in the lending pool. This means The discount rate (liquidityIndex) at that time reached an astonishing 126,000,000. This involves knowledge that the interest of deposit users basically comes from the growth of liquidity in the pool. The lending pool will dynamically adjust the borrowing and deposit interest rates based on the deposit rate and usage rate.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

Here, when the pool receives additional liquidity from flash loan interest (1.8 WBTC), seventy percent (126, 000, 000) is included in the liquidityIndex (liquidityIndex), which is used to calculate deposits per unit (hEthWbt) discounted value.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

Since the pool was empty before the hacker operation, the totalLiquidity after repayment is only 1, the amount is 126000000, and the initial liquidityIndex is 1, the result is 126000001.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

3. Continue to enlarge the discount rate

The hacker continued to borrow 2,000 WBTC through flash loans from HopeLend and returned an additional 1.8 WBTC each time, allowing the LiquidityIndex to accumulate 126, 000, 000 each time.

The hacker repeated the process 60 times, and finally the liquidityIndex reached 7,560,000,001, and the discounted value of 1 minimum unit of hEthWBTC held by the attacker could reach 75.6 WBTC (approximately $2.14 million).

This also allows hackers to control hEthWBTC and distort its value.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

4. Empty the lending pool of other existing funds and generate income

The attacker then used 1 minimum unit of hEthWBTC as collateral to lend a large amount of assets from HopeLends other five token pools.

include:

  • 175.4 - WETH

  • 145, 522.220985 - USDT

  • 123, 406.134999 - USDC

  • 844, 282.284002229528476039 - HOPE

  • 220, 617.821736563540747967 - stHOPE

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

These tokens were converted into WBTC and WETH through Uniswap as proceeds. After deducting various fees, the hacker’s final profit was approximately 263 WETH (263.9 WETH excluding the bribe payload).

Why hackers can borrow large amounts of money from other pools:

When borrowing money or withdrawing deposits, the lending contract will check the users mortgage asset status to ensure that the loan does not exceed the mortgage.

Since the discount rate has been manipulated by hackers before and the discount rate will be factored into the mortgage value calculation with the normalizedIncome multiplier, the mortgage value of one unit of hEthWBTC in its hands is as high as 75.6 WBTC.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

Every time he borrowed money from other pools, the hacker easily passed the collateral asset verification.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

At this time, the attacker invested a total of 2000+ 1.8* 60 WBTC in HopeLend to manipulate liquidityIndex, leaving only 1 unit of hEtthWBTC.

5. Exploit key vulnerability points (integer division errors) to cash out

In order to withdraw the previously invested wBTC, the attacker deployed another attack contract: 0x 5 a 63 e......844 e 74 and called the withdrawAllBtc() method in it

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

The vulnerability process is as follows:

① First deposit 151.20000002 wBTC. According to the current liquidityIndex (1 minimum unit hEthWBTC= 75.6 wBTC), the attacker obtains 2 minimum units of hEthWBTC.

② Withdraw 113.4 wBTC, back-calculate its corresponding hEthWBTC share, and perform a burn operation on hEthWBTC.

③ 113.4 wBTC requires the destruction of 1.9999999998 minimum units of hEthWBTC. However, due to the accuracy of the div function, only one minimum unit of hEthWBTC is destroyed, thus becoming an exploitable vulnerability. Hackers can still retain 1 minimum unit of hEthWBTC.

critical vulnerability

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

The burn method of hEthWBTC calls the high-precision division rayDiv.

CertiK: Analysis of lending attacks on decentralized lending platform HopeLend

Here:

a= 11340000000 (WBTC planned to be withdrawn)

b=7560000001000000000000000009655610336 (discount rate)

Although (a* 1e27+b/2)/b = 1.9999999998, soliditys own div method truncates and returns 1, which is equivalent to 11340000000 / 7560000001. The decimal places are truncated after division.

0x5a63 (attack contract - cash out) continues to deposit 75.60000001 WBTC and obtains exactly 1 more minimum unit of hEthWBTC, thus continuing to hold 2 minimum units of hEthWBTC.

In this cycle of withdrawing 113.40000000 wBTC and depositing 75.60000001 wBTC, the attacker can obtain 37.8 wBTC out of thin air each time.

After 58 cycles, the attacker withdrew all the wBTC invested earlier and successfully returned Aave’s flash loan.

in conclusion

Since the hEthWBTC lending pool has not been initialized, the attacker can easily manipulate the liquidityIndex and increase it to the maximum. After the withdrawal rate is greatly amplified as a divisor, due to the truncation error of integer division, it is easier to withdraw the previous investment in one block. .

In a well-functioning lending pool, it is not easy for a small increase in loan interest to greatly increase the discount rate because there is already liquidity in the pool.

Original article, author:CertiK。Reprint/Content Collaboration/For Reporting, Please Contact report@odaily.email;Illegal reprinting must be punished by law.

ODAILY reminds readers to establish correct monetary and investment concepts, rationally view blockchain, and effectively improve risk awareness; We can actively report and report any illegal or criminal clues discovered to relevant departments.

Recommended Reading
Editor’s Picks