Move token Rug Pull

Reported loss $87K
Rugpull

What happened

Move (MOVE, BSC contract 0xED062451…00e037) is a tax-token template (liquidity, marketing and team fees swapped into a USD token) with owner switches that can stop or divert trading. The owner can set the sell tax with no cap, make buys deliver tokens to the owner address for a block window the owner chooses, blacklist any address including the pair, and set the maximum transaction size to zero. The owner is exempt from fees and limits, and the auto-liquidity LP tokens are sent to the owner address. The on-chain owner is still 0xf0135add…46b357 (read 2026-09-30), so ownership was not renounced.

CertiK's alert of 2023-04-16 reports that the deployer removed LP in 4 transactions totalling about $87k. De.Fi's REKT database lists the incident as an exit scam/rug pull of about $87k on BSC, with the deployer selling off the token and a drop of about 90% from the initial price.

from De.Fi's listing: address named as responsible 0xf0135add…46b357; liquidity removal transaction 0xee70a89b…4076be.

How it happened

  1. The constructor sends the whole supply to the owner and exempts the owner from fees and limits: _balances[owner] = _totalSupply;, isExcludedFromFee[owner] = true;, isTxLimitExempt[owner] = true;. It also sets receiveAddress = owner;, and addLiquidityUSDT sends the LP tokens it creates to receiveAddress.
  2. Sell tax has no ceiling: function setSelTaxes(uint256 newLiquidityTax, uint256 newMarketingTax, uint256 newTeamTax) external onlyOwner(). On a sell, _transfer debits the holder the full amount, takeFee computes feeAmount = amount.mul(_totalTaxIfSelling.sub(_sellDestroyFee)).div(100); and sends it to the token contract, and the pair is credited amount.sub(feeAmount.add(destAmount).add(airdropAmount)). At 100% the pair receives nothing; above 100% the sub reverts and the sell fails.
  3. Buys can be redirected: if(sender == uniswapPair && block.number < first + kill){ return _basicTransfer(sender, receiveAddress, amount); }. kill starts at 0 but setKing(uint256 newValue) public onlyOwner sets it without a bound, and while the window is open every token leaving the pair goes to the owner address instead of the buyer.
  4. Blacklist: require(!_isBlacklisted[sender] && !_isBlacklisted[recipient] runs on every transfer, and multipleBotlistAddress (onlyOwner) can flag any address. A flagged holder cannot sell; a flagged pair address stops all buys and sells.
  5. Size limit: require(amount <= _maxTxAmount applies unless one side is tx-limit exempt, and setMaxTxAmount(uint256 maxTxAmount) external onlyOwner() has no bounds. With a limit of 0, every non-exempt transfer reverts, because _transfer also requires amount > 0.
  6. What was reported: CertiK says the deployer removed LP in 4 transactions totalling about $87k, and De.Fi's listing says the token was sold and fell about 90%. Removing LP does not need any of the switches above. No opened transaction shows the owner calling any of them, so the list describes what the code allows.

Protocol details

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

Build your security review skills

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