TIGER Rug Pull

Reported loss $784K
Rugpull

What happened

TIGER is a 21,000,000-supply BEP20 token on BNB Smart Chain with a PancakeSwap TIGER/USDT pool. In the code, buys and sells by ordinary wallets are rejected until a swapTime fixed in the constructor, and after that they pay a fixed 10% fee split between node, fomo, NFT and pool reward wallets; the contract has no function to change those fees or swapTime. What it does allow is a fee-exempt, gate-exempt class of wallets: the owner and the wallet that receives the other 410,000 tokens at deployment are marked as isDelivers, so their transfers skip the fee logic and the swapTime check, and the owner can add any address to that list.

On 2022-09-23 CertiK Alert reported a price drop of more than 96% for the contract. De.Fi's REKT database lists the event as an exit scam / rug pull in which an address (0x2b7f41d9…471b5a) sold aggressively on PancakeSwap, with about 784,106 USD in profit moved on to another address. The existing text also records that 410,000 TIGER were minted at token creation to an additional address (initial holder 0x2c690f9d…49f22f), which transferred tokens to the selling address in transaction 0xdcb323b3…0d84fd; the liquidity pool is 0x6f516846…51c700. These addresses, the sale and the profit figure come from the De.Fi listing; the explorer pages could not be opened to confirm them.

How it happened

  1. The constructor mints the supply to two wallets: _mint(owner(), toPool); with toPool = 2059 * 1e4 * 1e18 (20,590,000 TIGER) and _mint(_receiveToken, total.sub(toPool)); with total = 2100 * 1e4 * 1e18, which is 410,000 TIGER for the _receiveToken wallet. The deployer chooses that wallet in the constructor arguments.
  2. The same constructor exempts both wallets: isDelivers[_receiveToken] = true; and isDelivers[owner()] = true;. In _transfer, if(isDelivers[sender] || isDelivers[recipient] || inSwapAndLiquify){ _basicTransfer(sender, recipient, amount); return; } skips the fee path and the require(block.timestamp >= swapTime, 'Can\'t swap!') check that guards every buy and sell by other wallets. The owner can extend the exempt list with function setDelivers(address[] memory addrs, bool flag) public onlyOwner().
  3. Every other wallet cannot buy or sell until the swapTime set in the constructor (swapTime = _swapTime;, with no later setter). After that, _sellTransfer takes nodeFeeSell, nftFee, fomo100Fee and poolFee (3% + 2% + 3% + 2%) from the amount before the pool receives it. These values are plain state variables with no active setter, so the 10% is fixed.
  4. A wallet in isDelivers can therefore swap its whole balance into the TIGER/USDT pair without the 10% fee and without waiting for swapTime. What happened, per De.Fi's listing and CertiK Alert: on 2022-09-23 an address sold aggressively on PancakeSwap, the price fell by more than 96%, and roughly 784,106 USD was listed as profit. Which wallet's tokens were sold, and by whom, is not shown by the code alone.

Protocol details

Classification Token
Protocol Type Exit Scam/Rugpull
Affected asset / contract TIGER

Build your security review skills

Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.