SumerMoney Hack Analysis

lunaray
3 min readApr 15, 2024

Introduction

We have observed an attack event on the Base chain, transaction at https://basescan.org/tx/0x619c44af9fedb8f5feea2dcae1da94b6d7e5e0e7f4f4a99352b6c4f5e43a4661. The attacker profited a total of 310,570 USDC and 10 cbETH from this attack, amounting to approximately $350,000.

The victim project is SumerMoney, a lending protocol based on Compound fork, where users can profit by providing liquidity. SumerMoney supports various underlying assets including ETH, USDC, USDbc, DAI, wstETH, cbETH, suUSD, and suETH. Each underlying asset corresponds to a lending pool. Users interact with the respective lending pool to perform operations.

Attack Detail

Initially, the attacker utilized a flashloan from Balancer through attack contract 1, borrowing 645,000 USDC and 150 ETH.

Subsequently, attack contract 1 created another attack contract (attack contract 2) and transferred the borrowed 64,5000 USDC from Balancer to the new attack contract 2, along with 1 wei.

Next, in the attack function of attack contract 2, the attacker exchanged 645,000 USDC for 643,630 sdrUSDC through mint. Then, the attacker borrowed 150.358797170664290045 ETH from the sdrETH pool via borrow and repaid the 150.358797170664290046 ETH to the sdrETH pool through repayBorrowBehalf. The implementation of repayBorrowBehalf is as follows:

It can be observed that the contract returns the excess amount to the user. Since the sdrETH pool received 150.358797170664290046 ETH but only lent 150.358797170664290045 ETH, it returns 0.000000000000000001 ETH to attack contract 2. Upon receiving the ETH transfer, attack contract 2 triggers the fallback function, which in turn calls attack contract 1 to perform borrow and redeemUnderlying once again.

It is noticed that the attacker redeems 150 ETH with only 74.99998941541294 sdrETH (supposed to be 150 sdrETH).

Let’s examine how the contract calculates the exchange rate between sdrToken and underlying token.

/*
* We get the current exchange rate and calculate the amount to be redeemed:
* redeemTokens = redeemAmountIn / exchangeRate
* redeemAmount = redeemAmountIn
*/

From the above formula, we understand that the underlying token amountexchanged is the corresponding sdr token amountdivided by exchangeRate. Similarly, the calculation of exchangeRate is as follows:

/*
* Otherwise:
* exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply
*/

Where totalCash is calculated by the following function:

The vulnerability becomes apparent. Operations such as mint, borrow, redeem, repay should all be atomic. However, repayBorrowBehalf exhibits a reentrancy vulnerability. By constructing a specific amount (borrowsAmount + 1 wei), the attacker causes the sdrETH pool to resend the surplus 1 wei to the attacker's contract, triggering the fallback function of attack contract 2. In the fallback function (at the time of ETH transfer, exchangeRate has doubled, increasing the value of sdrToken in the attacker's possession), the attacker performs a reentrant attack by calling lending functions, borrowing other assets. Finally, the loans of SumerMoney and Balancer are repaid, completing the attack.

--

--

lunaray

Lunaray takes a leading position in smart contract auditing and consulting service for blockchain security.