BurgerSwap Flash Loan Attack | Analysis

BurgerSwap Flash loan attack analysis

On 27th May 2021, BurgerSwap experienced a flash loan attack, resulting in a loss of $7.2M of user’s funds. BurgerSwap is a DEX on the Binance Smart Chain(BSC). It was forked from the Uniswap protocol. So it works on the same basic AMM model that Uniswap and other such DEXs use.

Background

Here is the summary of what the attackers stole:

  • 4.4k WBNB ($1.6M)
  • 22k BUSD ($22k)
  • 2.5 ETH ($6.8k)
  • 1.43M USDT ($1.4M)
  • 432k BURGER ($3.2M)
  • 142k xBURGER ($1M)
  • 95k ROCKS
The attacker moved out all the tokens from his account

The attacker was able to exploit a flaw in the BurgerSwap contract where it was missing x*y ≥ k check, which was present in the initial UniswapV2Pair contract from which BurgerSwap was forked. The attacker could do re-entrancy and transfer any amounts from the pool before the reserves were updated. The attacker did 14 such transactions which resulted in a $7.2M loss for the protocol.

Details

BurgerSwap swapping function had a missing require statement which could let anyone remove any amounts from a pool on the protocol. Let’s have a look at the difference between the UniswapV2 Pair code and BurgerSwap DemaxPair code:

BurgerSwap Pair Swap Function code
BurgerSwap Pair Swap Function code
BurgerSwap Pair Swap Function code
UniswapV2Pair swap function code

The swap() function checks for the x*y ≥ k condition which verifies if the correct amount of tokens were received to do the swap. The code marked in the red box is what BurgerSwap is missing from its swap()function. Anyone could call this function to swap 100 token A to 100 token B, and could send only 1 token A and receive back 100 token B. This allows anybody to remove any amount of tokens from the pool without checking the x*y ≥k. There seems to be no explanation for why this check was removed by the developers of BurgerSwap.

Another difference was an extra modifier onlyPlatform for the swap() function that allowed only the Router to call the swap function.

onlyPlatform modifier was added to the swap() function

For the attack, the hackers created a pair with some newly created X tokens and BURGER. Then the Router was called to do a swap, sending in incorrect amounts of tokens. After the X token → BURGER swap, the attacker re-entered and did another swap BURGER → WBNB. Because the attacker re-entered before the updation of reserves after the first swap, the previous values of reserves were used for the next swap from BURGER → WBNB.

Lets take the example of WBNB pool for the details of the attack :

Tx Hash: 0xac8a739c1f668b13d065d56a03c37a686e0aa1c9339e79fcbc5a2d0a6311e333

(1) Flash swapped 6000 WBNB from PanckakeSwap.

(2) Swapped 6000 WBNB ↔ 92000 BURGER.

BurgerSwap attack info
BurgerSwap attack info

(3) Created a new token (which we will call X). Created a new pair with some X tokens and BURGER.

(4) Added 100 X tokens and 45000 BURGER to the pool.

(5) Swapped 100 X tokens ↔ 4400 WBNB.

(6) Swapped another 45000 BURGER ↔ 4400 WBNB because of re-entrancy.

BurgerSwap attack swapped tokens
BurgerSwap attack swapped tokens

(7) Swapped 493 WBNB ↔ 108800 BURGER

(8) Replayed the flash swap.

There were 14 such transactions and in total the attacker stole around 7.2M USD in different tokens. Most of which was sold and sent to Ethereum.

BurgerSwap has come up with a plan to compensate all the users who were affected by this attack. They will be airdropping cBURGER tokens to the user’s who held BURGER LPs at the time of the attack. Users will have to stake in the cBURGER pool. This pool will be funded by the BURGERs allocated to the team and the income of the protocol.

Reach out to QuillAudits