On August 4, 2021, according to news from the SlowMist Zone, the Sorbetto Fragola product of Popsicle Finance , a cross-chain profitability platform, was attacked by hackers. The SlowMist security team immediately intervened in the analysis and shared the results as follows.
In this attack, the attacker completed the attack on Sorbetto Fragola by creating 3 attack contracts. The following are the specific addresses involved in this attack:
Strawberry Sorbet ：
Through the official introduction, we can know that the Sorbetto Fragola product being attacked is mainly used to help users manage Uniswap V3 positions, so as to prevent users from exceeding the selected price range in Uniswap V3 market making positions. Users can deposit two tokens that provide liquidity in Sorbetto Fragola. Sorbetto Fragola will give users Popsicle LP (PLP) voucher. Users can use this voucher to get rewards and get back the mortgaged liquid funds. At the same time, this voucher It can also be transferred to other users at will.
Attack the core
The core of this attack is that Sorbetto Fragola uses the number of PLP credentials held by the user to participate in the calculation of the rewards that the user can obtain, but the PLP credentials can be transferred to other users at will, but no reward is given during the process of transferring the credentials. Settlement transfer and other operations. As a result, as long as you hold a PLP certificate, you can get rewards immediately. In the end, the same PLP certificate can bring benefits to multiple holders at the same time node. Next, we conduct a detailed analysis of the entire attack details.
The attack first created attack contracts C1, C2, and C3 through the H1 address, and then the attacker called the attack contract C1 through the H2 address to start a specific attack. The transaction is:
By analyzing this transaction, we can find that it first borrowed 30,000,000 USDT, 13,000 WETH, 1,400 WBTC, 30,000,000 USDC, 3,000,000 DAI, and 200,000 UNI from AAVE using lightning loan, which will be provided in Sorbetto Fragola for the follow-up Liquidity obtains PLP voucher to prepare.
Then the attacker calls the deposit function of the Sorbetto Fragola contract to deposit two tokens corresponding to the liquidity (here, the WETH and USDT tokens deposited by the attacker for the first time are taken as examples), and they will first pass checkDeviation and updateVault modifiers to check separately Prices and update rewards. The price check is mainly for whether the price fluctuates and is manipulated, etc., and it will not be expanded here. The reward update is closely related to this attack. We cut into the analysis:
You can see that it has called the _updateFeesReward function to perform a specific update operation. Let’s follow up this function:
From the above figure, we can easily find that it first obtains the amount of liquidity held by the contract within the range of tickLower and tickUpper through the positionLiquidity function. Then use the _earnFees function to collect and provide liquidity rewards from Uniswap V3 Pool. Then the _tokenPerShare function is used to calculate the liquidity reward that each PLP voucher can get. Finally, the _fee0Earned and _fee1Earned functions are used to calculate how many rewards the user can obtain for the number of PLP certificates held by the user, and use the user.token0Rewards and user.token1Rewards variables to record, as shown in the following figure:
However, since the attacker has just recharged at this time and has not yet obtained the PLP certificate, the user.token0Rewards and user.token1Rewards variables will naturally record 0.
Seeing this, you may have realized the problem. Since the rewards recorded by the user.token0Rewards and user.token1Rewards variables are calculated based on the PLP credentials held by the user, and the PLP credentials can be transferred, then whether you only need to hold the PLP The voucher triggers this variable to record the reward and we can get the reward. The answer is naturally yes. We continue to look at the deposit function:
After the reward is updated, the liquidityForAmounts function is used to calculate the liquidity of the funds provided by the user in the target price range, and then the Uniswap V3 Pool mint function is called to inject the liquidity. Then use _calcShare to calculate the number of PLP vouchers that Sorbetto Fragola needs to cast to the user.
After the attacker obtains the PLP certificate, as we thought, the PLP certificate is transferred to other addresses, and the collectFees function of the Sorbetto Fragola contract is called to record the reward.
From the transfer record on the PLP certificate chain in the above figure, we can see that after the attacking contract C1 obtains the PLP certificate, it is transferred to the attacking contract C2, and then the collectFees function is called. Then the attacking contract C2 transferred the PLP credentials to the attacking contract C3 and called collectFees again. Finally, the attacking contract C3 transfers the PLP credentials back to the attacking contract C1. We cut into the collectFees function for analysis:
From the above figure, we can easily see that this function also has an updateVault modifier. After the above analysis, we can know that the updateVault modifier is used to reward updates. Therefore, the collectFees function is called to trigger the updateVault modification when the attack contract C2 holds PLP credentials. The device will calculate the rewards that should be distributed according to the number of PLP vouchers it holds, and record them into the token0Rewards and token1Rewards variables of the user. It should be noted that the tokenPerSharePaid variable cached for such PLP voucher holders is 0 at this time, which directly causes users to obtain PLP voucher holding rewards.
We can also see from the changes in the state on the chain:
Then attack the contract C2 to obtain the reward record by following the same method.
Finally, the PLP voucher is transferred back to the attack contract C1, and the Sorbetto Fragola contract’s withdraw function is called to burn the PLP voucher to retrieve the previously deposited WETH and USDT liquidity. And the attack contracts C2 and C3 respectively call the collectFees function to pass in the number of rewards to be received to receive the rewards. In this way, the attacker not only gets back the deposited liquidity in the same block, but also gets multiple additional liquidity rewards.
Then the attacker began to use other tokens to reward the concocted method, as shown in the following figure:
1. The attacker creates multiple attack contracts and borrows a large amount of tokens from AAVE using flash loans;
2. The attacker uses borrowed tokens to deposit in the Sorbetto Fragola contract to obtain PLP certificates;
3. The attacker uses the reward settlement defect of the Sorbetto Fragola contract to transfer the obtained PLP credentials between the attack contracts he created and calls the collectFees function of the Sorbetto Fragola contract to record the reward for each attack contract;
4. The attacker burns the PLP certificate to retrieve the liquid funds deposited in the Sorbetto Fragola contract, and calls the collectFees function of the Sorbetto Fragola contract through each attack contract to obtain the recorded reward;
5. Continuously circulate the above operations to attack each liquid capital pool to obtain rewards;
6. Return the flash loan to make a profit and leave.
MistTrack analysis process
According to the analysis and statistics of the SlowMist AML team, this attack lost approximately 4.98M USDT, 2.56K WETH, 96 WBTC, 5.39M USDC, 159.93K DAI, 10.49K UNI, close to US$21 million.
Capital flow analysis
The analysis of the MistTrack anti-money laundering tracking system of SlowMist AML found that the attacker’s H1 address first obtained initial funds from Tornado.Cash and then deployed three attack contracts:
After the attack was profitable, the tokens obtained were converted into ETH through Uniswap V3 and transferred to Tornado.Cash again:
At present, the balance of the attacker’s account is only 0.08 ETH, and the remaining funds have been transferred through Tornado.Cash.
The core of this vulnerability is that the same PLP certificate can bring benefits to multiple holders at the same time node due to the defect in the reward update record. In response to such vulnerabilities, the SlowMist security team recommends that the reward settlement issue should be handled before voucher transfer, and the user’s reward cache before and after the transfer should be recorded to avoid such problems again.
Posted by:CoinYuppie，Reprinted with attribution to:https://coinyuppie.com/empty-glove-white-wolf-popsicle-is-hacked-analysis/
Coinyuppie is an open information publishing platform, all information provided is not related to the views and positions of coinyuppie, and does not constitute any investment and financial advice. Users are expected to carefully screen and prevent risks.