Sitemap

SlowMist: Analysis of PancakeBunny Attack (Released in 2021)

7 min readMay 9, 2023
Press enter or click to view image in full size
Press enter or click to view image in full size

According to SlowMist Zone News, on July 17, 2021, the Polygon version of the DeFi yield aggregator PancakeBunny was attacked by a flash loan attack. The SlowMist security team intervened in the analysis immediately and shared the results as follows.

It is worth noting that this attack is similar to the flash loan attack suffered by PancakeBunny on the Binance Smart Chain on May 20. The SlowMist Security Team conducted a brief analysis before, which can be viewed in the article “Token Flash Crash, Analysis of PancakeBunny Hack.”

Attack Details Analysis

First, the attacker borrowed a large amount of USDC, USDT, and WETH tokens through a flash loan from AAVE and transferred the borrowed USDC and USDT tokens to SushiSwap to add liquidity and obtain SLP.

Press enter or click to view image in full size

Next, the attacker performed the most critical operation of this attack: he mortgaged a small part of the LP obtained from adding liquidity to the VaultSushiFlipToFlip contract to prepare for obtaining polyBUNNY token rewards. The majority of the LP was mortgaged to MiniChefV2, and the deposit revenue address was designated as the VaultSushiFlipToFlip contract.

Press enter or click to view image in full size

Then, to reduce the attack cost, the attacker used the borrowed 100,000 WETH tokens to exchange for WMATIC tokens on QuickSwap (it will be explained later why this reduces the attack cost).

Press enter or click to view image in full size

Afterward, the attacker called the withdrawAll function of the VaultSushiFlipToFlip contract to obtain the mortgaged SLP and polyBUNNY token rewards. We analyzed this function specifically:

Press enter or click to view image in full size
Press enter or click to view image in full size

At line 162 and 163 of the above code, the attacker’s collateral certificates were converted into the amount of SLP that the user deposited in MiniChefV2 through the VaultSushiFlipToFlip contract, using the balanceOf and principalOf functions, respectively. Theoretically, these two values should not differ significantly, but analysis of the balanceOf function reveals that it calculates the amount by multiplying the percentage of the user’s collateral credentials by the amount of SLP deposited by the VaultSushiFlipToFlip contract in MiniChefV2.

Since the attacker has already deposited a large amount of SLP directly into the MiniChefV2 contract and designated the benefit address to the VaultSushiFlipToFlip contract, the balance function will retrieve a much larger value than expected, while the percentage of the attacker’s credentials remains normal, ultimately resulting in a much larger value assigned to the amount. This directly leads to the performanceFee parameter calculated at line 176 of the above code being an unexpected and enormous value.

This abnormal performanceFee parameter is then passed into the mintForV2 function to participate in the calculation of the polyBUNNY token reward. Let’s analyze this function next:

Press enter or click to view image in full size
Press enter or click to view image in full size

In this section of the code, we can see that the mintFor function is called to handle the specific logic. First, on line 205, the SLP tokens are sent to the Pair contract to prepare for the subsequent removal of liquidity. Since the shouldMarketBuy function’s final price comparison calculation is false, the _zapAssets function is called through an if statement. We will analyze the _zapAssets function.

Press enter or click to view image in full size

In the _zapAssets function, since the asset is SLP, the else if logic is used to call the removeLiquidity function of the SushiSwap Router contract to remove liquidity. Then, through the _tokenToAsset function, the USDC and USDT tokens obtained from removing liquidity are exchanged for polyBUNNY and WETH tokens respectively on QuickSwap and added liquidity again on QuickSwap. Next, we analyzed the _tokenToAsset function:

Press enter or click to view image in full size

Through a simple analysis, we found that it directly calls the zapInToken function of the zapPolygon contract through the if logic, and we won’t elaborate on the analysis of the judgment conditions. We then continued to analyze the zapInToken function:

Press enter or click to view image in full size

Similarly, by analyzing the judgment conditions, we can specify that it will enter the else logic through the code line 133, and then call the _swapTokenForMATIC function to exchange the tokens based on the exchange path “USDC -> WETH -> WMATIC” set through the if logic at code line 221. The exchange path for USDT tokens is the same.

Press enter or click to view image in full size

Prior to this, the attacker had already borrowed 100,000 WETH tokens and exchanged them for a large amount of WMATIC tokens on QuickSwap through the “WETH -> WMATIC” path. Therefore, the WMATIC tokens obtained through the “USDC/USDT -> WETH -> WMATIC” path were reduced. As a result, when the attacker exchanges the WMATIC tokens for WETH and polyBUNNY tokens through the _swapMATICToFlip function, there will be fewer tokens transferred to the LP that is ultimately sent to BUNNY_POOL, achieving the goal of reducing the attacker’s SLP cost and ultimately reducing some of the attack cost.

Next, let’s look at the mintFor function. After completing the above series of operations, the amount of polyBUNNY tokens to be minted will be calculated through the amountBunnyToMint function. From the figure below, we can see that the contributionInETH parameter involved in the calculation comes from the valueOfAsset function of the priceCalculator contract, but the parameter received by the valueOfAsset function is the previously mentioned _performanceFee, which is an unexpected huge value.

Press enter or click to view image in full size

We can analyze the valueOfAsset function simply as follows:

Since the asset is SLP, the _getPairPrice function is called on line 155 of the above code to obtain the price. By analyzing this function, we can find that the methods used to obtain the price are all trusted oracles, so the attacker cannot manipulate the oracles directly. However, since the amount involved in the calculation, i.e., _performanceFee, is an unexpected huge value, the resulting valueInETH and valueInUSD obtained through multiplication calculation are also unexpected huge values.

Press enter or click to view image in full size
Press enter or click to view image in full size

Subsequently, the obtained unexpected contributionInETH parameter will be passed to the amountBunnyToMint function for coin minting calculation.

Press enter or click to view image in full size

The priceOfETH and priceOfBunny here are obtained from the trusted ChainLink and official price-feeding oracles, respectively. Therefore, after multiplication calculation, the resulting mintBunny coin amount is an unexpected huge value, which results in the attacker receiving a large amount of polyBUNNY token rewards.

Attack Process:

1. The attacker borrowed USDT/USDC/WETH tokens through AAVE flash loan and obtained SLP by adding liquidity on SushiSwap.

2. Most of the SLP tokens were transferred to MiniChefV2 and the beneficiary address was set to the VaultSushiFlipToFlip contract, while a small part was deposited into the VaultSushiFlipToFlip contract.

3. Since most of the attacker’s SLP tokens were set to the beneficiary address of the VaultSushiFlipToFlip contract in MiniChefV2, VaultSushiFlipToFlip obtained the wrong balanceOf, causing the performanceFee to become an unexpected huge value.

4. The final coin minting for polyBUNNY token rewards used this unexpected performanceFee parameter, resulting in the minting of additional polyBUNNY tokens for the attacker.

5. Finally, the attacker sold the polyBUNNY tokens, repaid the flash loan, and walked away with profits.

Summary

The difference between this attack and the first one is that it was not the manipulation of the oracle that caused the error in the coin minting amount, but rather VaultSushiFlipToFlip contract mistakenly obtaining the amount of collateral not deposited by the attacker in MiniChefV2, resulting in abnormal parameters for coin minting. Extra polyBUNNY tokens were ultimately minted.

Reference transaction link:

https://polygonscan.com/tx/0x25e5d9ea359be7fc50358d18c2b6d429d27620

About SlowMist

SlowMist is a blockchain security firm established in January 2018. The firm was started by a team with over ten years of network security experience to become a global force. Our goal is to make the blockchain ecosystem as secure as possible for everyone. We are now a renowned international blockchain security firm that has worked on various well-known projects such as Huobi, OKX, Binance, imToken, Crypto.com, Amber Group, Klaytn, EOS, 1inch, PancakeSwap, TUSD, Alpaca Finance, MultiChain, O3Swap, etc.

Website:
https://www.slowmist.com
Twitter:
https://twitter.com/SlowMist_Team
Github:
https://github.com/slowmist/

--

--

SlowMist
SlowMist

Written by SlowMist

SlowMist is a Blockchain security firm established in 2018, providing services such as security audits, security consultants, red teaming, and more.