Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

MBC Token

Step-by-step

  1. Request a flash loan
  2. Swap all MBC for BUSD (after this, the price of MBC will be inflated in the pool)
  3. Now call swapAndLiquifyStepV1, which will add a certain amount of MBC and BUSD to the pool
  4. Exchange the MBC you gained in (2) for the BUSD now in the pool. The pool belives MBC to be very valuable so gives you a lot of BUSD.
  5. Repay flash loan.
  6. Keep the rest.

Detailed Description

Understanding this attack needs a small prior on Uniswap router contracts and their methods.

Routers are contracts that facilitate the interaction with Uniswap pools. An important function in a router is addLiquidity:

function addLiquidity(
  address tokenA,
  address tokenB,
  uint amountADesired,
  uint amountBDesired,
  uint amountAMin,
  uint amountBMin,
  address to,
  uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);

This will try to add liquidity to the pool where trades of tokenA/tokenB happen. amountADesired/amountBDesired is the ideal amount of A and B to add, while amountAMin/amountBMin works as slippage protection.

With that in mind, we can check the MBC Token swapAndLiquifyStepv1() function:

    function swapAndLiquifyStepv1() public {
        uint256 ethBalance = ETH.balanceOf(address(this));
        uint256 tokenBalance = balanceOf(address(this));
        addLiquidityUsdt(tokenBalance, ethBalance);
    }

    function addLiquidityUsdt(uint256 tokenAmount, uint256 usdtAmount) private {
        uniswapV2Router.addLiquidity(
            address(_baseToken),
			address(this),
            usdtAmount,
            tokenAmount,
            0,
            0,
            _tokenOwner,
            block.timestamp
        );
    }

In this contract, the _baseToken is the address 0x55d398326f99059fF775485246999027B3197955, BUSD Stablecoin. ETH refers to the same _baseToken.

Something important here to stress is that the MBC Token has a balance of their own (ie: the contract has its own tokens, balanceOf(address(this)) != 0) because it charges a fee to users on every transaction.

Now, inmediatly after calling swapAndLiquifyStepv1, the contract will go to the BUSD/MBC liquidity pool and add all of its balances of both BUSD and MBC to it.

A small sidenote here, but: why does this contract have this function anyway? It does not seem to do much. The answer appears to be some controversial tokenomics. We haven't been able to pinpoint who invented it, but Safemoon, now facing lawsuits, seems to swear by it.

Anyway, moving on the attack. How does the attacker take advantage of this? They inflate the price of the token in the pool and foce the contract to buy it all up.

In the same transaction, they:

  1. Request a flash loan
  2. Swap all MBC for BUSD (after this, the price of MBC will be inflated in the pool)
  3. Now call swapAndLiquifyStepV1, which will add a certain amount of MBC and BUSD to the pool
  4. Exchange the MBC you gained in (2) for the BUSD now in the pool. The pool belives MBC to be very valuable so gives you a lot of BUSD.
  5. Repay flash loan.
  6. Keep the rest.

Possible mitigations

  • swapAndLiquifyStepv1 should be made private

Diagrams and graphs

Overview

overview

Sources and references