Sonne Finance Attack Analysis: How can $100 leverage $6.5 million? The essence of this attack is that when the market (soToken) was created, the attacker performed the first mortgage casting operation and minted very few soTokens with a small amount of underlying tokens, resulting in the "totalSupply" value of soToken being too small. The attacker then exploited the vulnerability of Solidity contract precision loss, and then sent the underlying token directly to the soToken contract (soToken will not be minted, which means that "totalSupply" remains unchanged and "totalCash" becomes larger) instead of staking + casting. method to deposit the underlying token. Such an operation makes the "totalCash" variable in the contract become larger, but "totalSupply" remains unchanged, causing exchangeRate to become larger. In the end, when the attacker redeems the underlying token, the soToken that needs to be destroyed is less than the soToken minted during the mortgage. The attacker uses the earned soToken to lend the underlying token WETH and USDC to other soTokens (such as soWETH, soUSDC), and finally obtains Profits were as high as US$20 million.
On May 15, 2024, Sonne Finance was attacked on the Optimism chain, resulting in losses of up to $20 million. After the attack, user @tonyke_bot on
(https://twitter.com/tonyke_bot/status/1790547461611860182)
##After the Sonne Finance project team discovered the attack, it quickly suspended Optimism All markets and indicate that the markets on Base are safe. (https://twitter.com/SonneFinance/status/1790535383005966554) Attack BriefSonne Finance is on Optimism A fork of Compound V2’s decentralized lending protocol for individuals, institutions, and protocols to access financial services. The Sonne Finance protocol aggregates users' token assets to form a lending liquidity pool, providing users with a bank-like lending business. Like Compound, protocol participants can mortgage their tokens into Sonne Finance’s lending liquidity pool and obtain the certificate soToken (same as cToken). SoToken is an interest-bearing asset certificate, which will generate a certain amount of income as the block progresses, and will also receive SONE token incentives. Participants can also borrow other tokens from the Sonne lending asset pool with the soToken in their hands. For example, participants can mortgage a certain amount of USDC to obtain soUSDC certificates, and then lend out WETH for further circulation. Mortgage lending in the Sonne Finance protocol can be a many-to-many asset relationship. During the mortgage lending process, the protocol will automatically calculate the health factor (Health Factor) of the participant's address. When the health factor is lower than 1, the mortgage of the address Products will support liquidation, and liquidators can also receive certain liquidation rewards. The relationship between the number of underlying tokens deposited by users and the minted soTokens is mainly related to a variable called exchangeRate. This variable can be roughly used to indicate how much underlying token each soToken is worth. The calculation formula of exchangeRate is as follows: In the above formula, totalCash refers to the number of underlying tokens held by soToken, and totalBorrows refers to the underlying tokens lent out in a certain market. The amount of totalReserves refers to the total reserve amount (which includes the interest paid by the borrower), and totalSupply refers to the number of soToken minted. When redeeming, the user can specify the number of underlying tokens to be redeemed, redeemAmount, to calculate the number of soTokens that need to be destroyed, redeemTokens. The calculation method is roughly "redeemTokens = redeemAmount / exchangeRat", pay attention here The loss of accuracy is not dealt with.The essence of this attack is that when the market (soToken) was created, the attacker performed the first mortgage casting operation and minted very few soTokens with a small amount of underlying tokens, resulting in the "totalSupply" value of soToken being too high. Small. The attacker then exploited the vulnerability of Solidity contract precision loss, and then sent the underlying token directly to the soToken contract (soToken will not be minted, which means that "totalSupply" remains unchanged and "totalCash" becomes larger) instead of staking + casting. method to deposit the underlying token. Such an operation makes the "totalCash" variable in the contract become larger, but "totalSupply" remains unchanged, causing exchangeRate to become larger. In the end, when the attacker redeems the underlying token, the soToken that needs to be destroyed is less than the soToken minted during the mortgage. The attacker uses the earned soToken to lend the underlying token WETH and USDC to other soTokens (such as soWETH, soUSDC), and finally obtains Profits were as high as US$20 million.
Attack preparation transactions:
https://optimistic.etherscan.io/tx/0x45c0ccfd3ca1b4a937feebcb0f5a166c409c9e403070808835d41da40732db96
Profit from the attack Transaction:
https://optimistic.etherscan.io/tx/0x9312ae377d7ebdf3c7c3a86f80514878deb5df51aad38b6191d55db53e42b7f0
Attack EOA related address:
0x5d0d99e9886581ff8f cb01f35804317f5ed80bbb
0xae4a7cde7c99fb98b0d5fa414aa40f0300531f43
Attacker (contract) related address:
0xa78aefd483ce3919c0ad55c8a2e5c97cbac1caf8
0x02fa2625825917e9b1f8346a465de1bbc150c5b9
underlying token (VELO Token V2):
0 x9560e827af36c94d2ac33a39bce1fe78631088db
Vulnerability contract (soVELO, similar to Compound’s cToken):
0xe3b81318b1b6776f0877c3770afddff97b9f5fe5
X @tonyke_bot user rescue transaction:
https://optimistic.etherscan.io/ tx/0x816f9e289d8b9dee9a94086c200c0470c6456603c967f82ab559a5931fd181c2
The Sonne Finance project party recently passed a proposal to add the VELO market to Sonne Finance (https:// twitter.com/SonneFinance/status/1786871066075206044) and arranged five transactions through the multisig wallet that were executed two days later (https://optimistic.etherscan.io/tx/0x18ebeb958b50579ce76528ed812025949dfcff8c2673eb0c8bc78b12ba6377b 7), these five transactions are used to create VELO market (soVELO contract), and set some key configurations of the market, such as setting the interest rate model, setting the price oracle, setting the mortgage factor, etc. After the VELO market is created, users can deposit VELO tokens to mint soVELO tokens, which can in turn be used to borrow other soTokens.
The attack preparation stage is mainly for the attacker to create a VELO market (soVELO contract) based on the information in the Sonne Finance project proposal after the two-day lock-in period of the proposal has expired, and set the key configuration, and mint soVELO tokens by mortgaging VELO tokens into the soVELO contract. At the same time, the VELO tokens held by the attacker are sent directly to the soVELO contract to increase the exchangeRate and prepare for subsequent attacks to profit.
The specific steps are as follows:
After the two-day locking time ends, the attacker first packages the operations of the first four transactions arranged in the proposal into one transaction. (Transaction 0x45c0cc), used to create the VELO market (soVELO contract) and set up key configurations. When VELO market is initialized, exchangeRate is set to "200,000,000,000,000,000,000,000,000".
The attacker calls the "mint" function of the soVELO contract to deposit VELO tokens and mint soVELO tokens. The attacker specifies "mintAmount" as "400,000,001" (the VELO token's quantity). As can be seen from the function "exchangeRateStoredInternal", since the "_totalSuppl" of soVELO token is 0 at this time, exchangeRate is the value set in step 1. According to the formula "mintTokens = actualMintAmount / exchangeRate", the calculated number of soVELO tokens that should be minted at this time is 2. In short, in this step, the attacker deposits VELO tokens with a value of "400,000,001" into the soVELO contract, and the attacker obtains soVELO tokens with a value of 2.
soVELO.mint:
The attacker sent VELO tokens directly to the soVELO contract. The value of VELO tokens is "2,552,964,259,704,265,837,526". At this time, the VELO tokens held by the soVELO contract increase. However, since there are no new soVELO tokens minted, the totalSupply remains unchanged, which means that it is calculated according to the exchangeRate calculation formula. The exchangeRate output will become larger.
The attacker transferred the soVELO tokens held multiple times, eventually to another attack EOA 0xae4a.
The attack profit stage is mainly when the attacker executes the fifth transaction of the proposal and lends VELO tokens directly to the soVELO contract through flash loans to Increase the exchangeRate further. Then the attacker uses the soVELO token with a value of 2 in his hand to borrow underlying tokens such as WETH and USDC from other soToken (such as soWETH, soUSDC, etc.) contracts, and these parts become the attacker's profit. Then the attacker went to redeem his underlying token in the soVELO contract. Due to the increase in exchangeRate and the loss of accuracy in calculating the soVELO tokens that need to be destroyed for redemption, the attacker ultimately only used the soVELO token with a value of 1. Almost all the previously deposited VELO tokens were redeemed, which can be understood as the attacker using the extra soVELO tokens with a value of 1 to earn underlying tokens such as WETH and USDC by borrowing from other soTokens. The attacker used the same technique to repeat the attack many times and ultimately made huge profits.
The specific steps are as follows:
The attacker executes the fifth transaction in the proposal and sets the lending factor specified in the proposal.
The attacker flash loaned VELO tokens with a value of "35,469,150,965,253,049,864,450,449" from the VolatileV2 AMM - USDC/VELO pool, which triggered the attacker's hook function. In the hook function, the attacker continues to perform the attack operation.
The attacker sends the VELO tokens he holds to the soVELO contract to further increase the exchangeRate. Currently, there are a total of VELO tokens with a value of "35,471,703,929,512,754,530,287,976" in the soVELO contract (the sum of VELO tokens transferred in by the attacker three times).
The attacker creates a new contract 0xa16388a6210545b27f669d5189648c1722300b8b. In the constructor, he transfers the 2 soVELO tokens he holds to the newly created contract 0xa163 (hereinafter referred to as the attacker 0xa163).
The attacker 0xa163 used the soVELO tokens he held to borrow WETH with a value of "265,842,857,910,985,546,929" from soWETH.
Attacker 0xa163 calls soVELO's "redeemUnderlying" function, specifying the value of redeemed VELO tokens as "35,471,603,929,512,754,530,287,976" (almost all attackers have previously transferred or mortgaged into the soVELO contract number of VELO tokens), at this time it is necessary to calculate the number of soVELO tokens that need to be destroyed for redemption according to the formula "redeemTokens = redeemAmountIn / exchangeRate".
It can be seen from the "exchangeRateStoredInternal" function that since _totalSupply is 2 instead of 0 at this time, the value of exchangeRate needs to be calculated, which is calculated through the formula "exchangeRate = (totalCash + totalBorrows - totalReserves) / totalSupply", The current exchangeRate is "17,735,851,964,756,377,265,143,988,000,000,000,000,000,000", which is much larger than the initial exchangeRate set "200,000,000,000,000,000,000,000,00".
The value of "redeemTokens" calculated based on the new exchangeRate is "1.99". Due to the downward rounding characteristics of Solidity, the value of "redeemTokens" is ultimately 1. This means that the attacker 0xa163 used soVELO tokens with a value of 1 to redeem almost all the VELO tokens previously deposited. At the same time, the attacker 0xa163 also earned WETH with a value of "265,842,857,910,985,546,929" borrowed from soWETH.
soVELO.redeemUnderlying:
##soVELO.exchangeRateStoredInternal:The attacker transferred the funds shortly after grabbing the illegal gains. Most of the funds were transferred to the following 4 addresses, and some were to change addresses to continue. Some attacks are for money laundering:
0x4ab93fc50b82d4dc457db85888dfdae28d29b98d
The attacker transferred 198 WETH to this address, and then the address used the same attack Using this method, illegal gains were obtained from the following transactions:
After the attack, the address transferred the above illegal gains to 0x5d0d99e9886581ff8fcb01f35804317f5ed80bbb.
0x5d0d99e9886581ff8fcb01f35804317f5ed80bbb
The attacker transferred 724277 USDC and 2353 VELO to this address, and exchanged USDC for Ether. Then part of the funds were immediately transferred to the Stargate cross-chain bridge, and most of the illegal funds remained in this address:
The above is the detailed content of How can $100 leverage $6.5 million? Sonne Finance attack analysis. For more information, please follow other related articles on the PHP Chinese website!