CommEX Rug Pull

Reported loss $134K
Rugpull

What happened

CMX was a BNB Chain token named after the CommEX exchange, deployed on 30 September 2023 by 0x67F09504…57b888; CertiK called it a fake CommEx token promoted in Russian-speaking Telegram groups. Its transfer and transferFrom never revert when a transfer is refused: they return true and move nothing. A sale into the pair or router passes only if the wallet has bought at least as much CMX as it has sold, and two owner-set limits, _theNumber and _theRemainder, allow it. The owner can stop every sale with one call to setNumber(0) or setRemainder, while buys and whitelisted wallets are never checked. The master address also has an unlimited allowance over the pair's CMX and a syncPair function, so it can take tokens out of the pool and reset its reserves without trading.

On 6 October 2023 CertiK reported the deployer removed about $154K from the LP. De.Fi's REKT database puts the loss at 635.86 WBNB, 134,077 USD, and lists the liquidity removal transaction 0x56a8cc91…4dcbe2. According to De.Fi's listing, the funds went to another address and were split across several wallets: part stayed in the deployer wallet as BSC-USD, and part went to a Bybit deposit through what the listing calls the scammer's address, in transaction 0x51c7f193…f265fe. The listing also names two further addresses, 0x041b8ED1…9F1bA4 and 0xc6ae76C4…EE98d5. It also says the creator pulled liquidity five times before and used it to buy back CMX, holding the price up.

How it happened

  1. The constructor mints all 100,000,000 CMX to the owner, makes the owner master, whitelists it in _marketersAndDevs, and sets _allowances[address(_pair)][master] = ~uint256(0).
  2. transfer and transferFrom only call _transfer when _canTransfer returns true. Otherwise they still return true, so a refused transfer moves nothing and does not revert.
  3. In _canTransfer, whitelisted wallets and anything sent from the router or pair (buys) pass. A transfer to the router or pair (a sale) passes only if bought >= sold + amount && _theNumber >= soldETH + amountETH && sender.balance >= _theRemainder. The first condition is the wallet's own buy/sell tally; _theNumber and _theRemainder are set by the owner. Wallet-to-wallet transfers between non-whitelisted holders always return false.
  4. _theNumber starts at the maximum and _theRemainder at zero, so sales work at first. The owner can call setNumber(0) to block any sale worth more than zero BNB, or setRemainder to demand more BNB in the seller's wallet than any holder has. The deployer is still owner.
  5. master, which the owner sets with setMaster, can transferFrom CMX out of the pair with its unlimited allowance and call syncPair() to make the pair accept the new reserves.
  6. On 6 October 2023 the deployer removed about $154K of liquidity, according to CertiK. De.Fi's listing adds that it had pulled liquidity five times before and used the funds to buy back CMX, holding the price up. No source opened here shows setNumber, setRemainder or the pair allowance being used.

Protocol details

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

Build your security review skills

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