Source: SharkTeam
On June 10, 2024, UwU Lend was attacked, resulting in a loss of approximately $19.3 million for the project team.
I. Attack Transaction Analysis
Attacker: 0x841dDf093f5188989fA1524e7B893de64B421f47
The attacker initiated three attack transactions:
Attack Transaction 1:
0x242a0fb4fde9de0dc2fd42e8db743cbc197ffa2bf6a036ba0bba303df296408b
Attack Transaction 2:
0xb3f067618ce54bc26a960b660cfc28f9ea0315e2e9a1a855ede1508eb4017376
Attack Transaction 3:
0xca1bbf3b320662c89232006f1ec6624b56242850f07e0f1dadbe4f69ba0d6ac3
Taking Attack Transaction 1 as an example, the analysis is as follows:
Attack Contract: 0x21c58d8f816578b1193aef4683e8c64405a4312e
Target Contract: UwU Lend Treasury Contract, including:
uSUSDE: 0xf1293141fc6ab23b2a0143acc196e3429e0b67a6
uDAI: 0xb95bd0793bcc5524af358ffaae3e38c3903c7626
uUSDT: 0x24959f75d7bda1884f1ec9861f644821ce233c7d
The attack process was as follows:
1. Flash loaned various tokens from different platforms, including WETH, WBTC, sUSD, USD, DAI, FRAX, USDC, and GHO. The receiving address for the tokens was 0x4fea76b66db8b548842349dc01c85278da.
The tokens and quantities flash loaned were as follows:
Flash loaned 159,053.16 WETH and 14,800 WBTC from Aave V3
Flash loaned 40,000 WETH from Aave V2
Flash loaned 91,075.70 WETH and 4,979.79 WBTC from Spark
Flash loaned 301,738,880.01 sUSD, 236,934,023.17 USD, and 100,786,052.15 DAI from Morpho
Flash loaned 60,000,000 FRAX and 15,000,000 USDC from Uniswap V3: FRAX-USDC
Flash loaned 4,627,557.47 GHO and 38,413.34 WETH from Balancer
Flash loaned 500,000,000 DAI from Maker
Totaling approximately 328,542.2 WETH, 19,779.79 WBTC, 600,786,052.15 DAI, 301,738,880.01 sUSD, 236,934,023.17 USD, 4,627,557.47 GHO, 60,000,000 FRAX, and 15,000,000 USDC.
2. Moved the flash loaned tokens to the contract 0xf19d66e82ffe8e203b30df9e81359f8a201517ad (referred to as 0xf19d) to prepare for the attack.
3. Controlled the price of sUSD by exchanging tokens, reducing its price.
(1) USDe to crvUSD.exchange
Exchanged 8,676,504.84 USD for 8,730,453.49 crvUSD, increasing the quantity of USD in USDe-crvUSD, lowering the price, and reducing the quantity of crvUSD.
(2) USDe to DAI.exchange
Exchanged 46,452,158.05 USD for 14,389,460.59 DAI, increasing the quantity of USD in USDe-DAI, lowering the price, and reducing the quantity of DAI.
(3) FRAX to USDe.exchange
Exchanged 14,477,791.69 USD for 46,309,490.86 FRAX, increasing the quantity of USD in USDe-FRAX, lowering the price, and reducing the quantity of FRAX.
(4) GHO to USDe.exchange
Exchanged 4,925,427.20 USD for 4,825,479.07 GHO, increasing the quantity of USD in USDe-GHO, lowering the price, and reducing the quantity of GHO.
(5) USDe to USDC.exchange
Exchanged 14,886,912.83 USD for 14,711,447.94 USDC, increasing the quantity of USD in USDe-USDC, lowering the price, and reducing the quantity of USDC.
Following these exchanges, the price of USD in the five pools decreased, ultimately causing a significant drop in the price of sUSD.
4. Continuously created lending positions by depositing other assets (WETH, WBTC, and DAI) into the LendingPool contract and borrowing sUSD. Due to the sharp drop in the price of sUSD, the borrowed quantity of sUSD was much higher than before the price drop.
5. Similar to Step 3, reversed the process to increase the price of sUSD.
Due to the increased price of sUSD, the value of the lending position in Step 4 exceeded the collateral value, meeting the liquidation criteria.
6. Liquidated the lending positions in batches, earning liquidation rewards in uWETH.
7. Repaid the loans, withdrew the target assets WETH, WBTC, DAI, and sUSD.
8. Deposited sUSD back into the LendingPool, allowing for borrowing more assets, including DAI and USDT, as the price of sUSD was higher.
9. Exchanged tokens to repay the flash loans, ultimately profiting 1,946.89 ETH.
II. Vulnerability Analysis
Through the analysis above, it was found that the entire attack process involved numerous flash loans and manipulating the price of sUSD multiple times. When collateralizing sUSD, it affected the quantity of borrowed assets; when borrowing sUSD, it affected the borrowing rate, thereby influencing the liquidation factor (health factor).
The attacker exploited this by lowering the price of sUSD through flash loans, collateralizing other assets, borrowing a large amount of sUSD, then raising the price of sUSD, liquidating the collateralized assets for profit, collateralizing the remaining sUSD to borrow other assets, and finally repaying the flash loans to complete the attack.
As seen in Step 3, the attacker manipulated the price of sUSD by controlling the prices of USDe/rvUSD, USDe/DAI, FRAX/sUSD, GHO/sUSD, and USDe/USDC in these five pools. Price reading functions were as follows:
sUSD price calculated from 11 prices, with the first 10 retrieved from CurveFinance and the last one from UniswapV3.
The prices retrieved from CurveFinance depended on USDe/rvUSD, USDe/DAI, FRAX/sUSD, GHO/sUSD, and USDe/USDC in these five pools, which were manipulated by the attacker during the attack transactions.
The returned prices were calculated by uwuOracle reading the price, price_oracle(0), and get_p(0) from the CurveFinance pool contract.
1. The price was provided by Chainlink and could not be manipulated.
2. Pool parameters were manipulated by the attacker to control the return value of get_p(0), thus manipulating the price.
III. Security Recommendations
To prevent such attacks in the future, the following precautions should be taken during development:
1. Use off-chain price oracles to prevent price manipulation vulnerabilities.
2. Prior to project deployment, undergo smart contract audits by third-party professional auditing companies.