Back to all stories
Reports
Incident Analysis
Zunami Protocol Incident Analysis
8/16/2023
Zunami Protocol Incident Analysis

Introduction

On 13 August, 2023 Zunami Protocol suffered an exploit via flash loan attack, resulting in a loss of 1,178 ETH (approximately $2.16 million). During this attack, the exploiter manipulated the price of StakeDAO on Sushiswap using a flash loan to tamper the balance of UZD, Zunami’s stable token. The attacker then transferred all the stolen funds through Tornado Cash.

Overview

On 13 August, the Zunami Protocol was exploited by externally owned address 0x5f4C2 in a flash loan attack that manipulated the price of SDT and inflated the UZD balance of the attacker. The attacker initially withdrew 10 ETH from Tornado Cash which was used to create the attack contract.

The attacker used the flash loan to manipulate Zunami’s pools and inflate the price of UZD. The attacker then called cacheAssetPrice() which increased the attacker’s UZD balance from 4.8 million UZD to 16.9 million UZD, a little over three times the amount. A user’s token balance is calculated via the following formula:

Balance[address] * assetPriceCached()/DEFAULT_DECIMALS_FACTOR

The attacker executed the flash loan exploit twice, gaining a total of 1178 ETH after repaying flash loans totaling approximately $32.4 million.

Attack Flow

This attack flow is based on the following transaction: https://etherscan.io/tx/0x0788ba222970c7c68a738b0e08fb197e669e61f9b226ceec4cab9b85abe8cceb

  1. The attacker flash loaned 7,000,000 USDT from UniSwapV3 as well as 7,000,000 USDC and 10,011 WETH (~$18.4 million) from Balancer.

  2. The attacker used the flash loaned funds to conduct the following swaps:

a. 5,750,000 USDC swapped for 5,746,896 crvFRAX on Curve which was later swapped for 4,082,036 UZD in pool 1.

b. 1,250,000 USDC swapped for 1,250,333 crvUSD on Curve which was later swapped for 791,280 UZD in pool 2.

c. 11 WETH swapped for 55,981 SDT in pool 3 and then transferred the SDT to the strategy.

  1. The attacker then swapped:

a. 10,000 WETH for 58,042 SDT in affected pair 1 (SushiSwap: SDT) and;

b. 7,000,000 USDT to 2,154 WETH in affected pair 2 (SushiSwap: USDT) to increase the price of SDT-USDT.

  1. The attacker called cacheAssetPrice() in the UZD contract (0xb40b) and updated the price of UZD which increased the attacker’s UZD balance from 4.8m UZD to 16.9m UZD due to the way in which it is calculated.

  2. The attacker swapped the 58,042 SDT and 2,154 WETH, from step 3, back to 9,999.93 WETH and 6,976,034 USDT respectively.

  3. The attacker swapped:

a. 14,158,424 UZD for 7,281,124 crvFRAX in pool 1 and;

b. 2,744,533 UZD for 1,891,351 crvUSD in pool 2.

  1. After conducting final swaps for WETH and repaying the loans the attacker was left with 1,152 WETH, approximately $2.12 million.

Protocol Vulnerability

The exploit is the result of price manipulation. The attacker was able to inflate their UZD balance 3x by taking advantage of the way in which UDZ is calculated. A user's UZD balance is calculated using the following formula:

Balance[address] * assetPriceCached()/DEFAULT_DECIMALS_FACTOR

  • Balance[address] UDZ balance of the user
  • assetPriceCached() detailed below
  • The DEFAULT_DECIMALS_FACTOR is a constant. 26cf2235-0d5e-48ec-8091-e249a1d7337d

The assetPriceCached() function returns the value of variable _assetPriceCached which was updated by attacker using function cacheAssetPrice() in step 4 of the attack flow above.

Screenshot 2023-08-16 at 8.45.06 PM

The totalHoldings() function under assetPrice() is in contract 0x2ffcc661011bec72e1a9524e12060983e74d14ce and is responsible for calculating total holdings across all of Zunami pools.

Screenshot 2023-08-16 at 8.46.19 PM The vulnerable pool in this exploit is 0x984.

462d7fb1-490e-4526-9a7c-4bfc4620302f

The formula for calculating total holdings in this strategy is:

_lpBalance * lpPrice + sdt * sdtPrice + config.crv * crvPrice

-sdt is calculated by the following: Screenshot 2023-08-16 at 8.50.25 PM

The price was manipulated by the attacker in step 4 of the attack flow. After the price is manipulated, the attacker called cacheAssetPrice() to significantly inflate the balance of their UZD. This increased their UZD balance from an initial 4,873,316 UZD to approximately 16,902,957 UDZ after the manipulation.

Flash Loan Attack Statistics

This incident ranks as the 10th largest flash loan attack detected by CertiK in 2023. Despite this, there have been four flash loan attacks in August with total losses of $3.8 million. The Zunami exploit constitutes the majority of the losses this month, making August the month with the lowest volume of flash loan attacks in 2023 so far.

Screenshot 2023-08-16 at 8.53.58 PM

In 2023, flash loans have gained popularity among attackers to maximize returns. August is projected to fall well below the average of 18 incidents per month in 2023, with only 4 recorded at the midpoint. Despite the low number of incidents, the average amount lost per incident in August is $972,000, marking the third highest average this year.

Screenshot 2023-08-16 at 8.54.58 PM

Conclusion

Despite August being set to see the lowest volume of flash loan attacks, the Zunami Protocol incident represents the 10th largest flash loan incident that CertiK detected so far in 2023. The volume of flash loan attacks has massively decreased in August with the month being set to see the lowest number of attacks in a single month this year. This is similar to August in 2022 that only saw six flash loans and an overall loss of $378,269. Despite the low number of flash loans detected in August, CertiK detected a significantly higher number of flash loans this year compared to 2022. The volume of flash loan attacks in 2023 demonstrates the need for robust security measures and third party audits. Check CertiK Skynet - Web3 Security, Due Diligence and Insights to help you understand the security risks behind projects you wish to engage with.