RCums Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

RCums (ROCKET CUMS, BNB Chain, contract 0xf4326430…130677) contains an owner-controlled tracing switch that is off by default. While it is on, the first transferFrom from a non-zero sender stores its recipient in nxOwner, and from then on every transfer or transferFrom to that address reverts. If the stored address is the trading pair, sells fail while buys from the pair still work, and no function can change nxOwner afterwards, although the owner can switch the check off and on with setTracing.

De.Fi's REKT database lists the token as an Exit Scam/Honeypot dated 2021-06-15 and says the owner could disable the transfer function, which restricted users in selling their tokens; the listing gives no loss amount.

How it happened

  1. The constructor mints the whole supply to the deployer (_totalSupply = 10000000000000000000000;, 9 decimals). The tracing flag starts as bool tracing = false;, so at first nothing is blocked.
  2. setTracing(bool _tracing) onlyOwner lets the owner switch the check on or off at any time.
  3. With tracing on, the contextHandler modifier on transferFrom runs if(from != address(0) && nxOwner == address(0)) nxOwner = to; else require(to != nxOwner, "Order ContextHandler");. The first transferFrom after the switch is on passes and stores its recipient in nxOwner; the sender need not be the owner. If that call is the router moving tokens into the pair, the pair is stored.
  4. From then on transferFrom reverts when to == nxOwner, and transfer carries require(to != nxOwner, "Handling Request"); through the requestHandler modifier. Neither check exempts the owner. A sale through the router is a transferFrom from the holder to the pair, so it reverts. A buy is a transfer from the pair to the buyer and passes.
  5. nxOwner is assigned only in that one line and only while it is zero, so the stored address cannot be cleared or replaced. The owner can still call setTracing(false) to let transfers to it through and setTracing(true) to block them again.
  6. Other owner-related code: onlyOwner accepts msg.sender == owner || msg.sender == nxOwner, so the stored address also passes owner-only checks. emitTransfer(uint256 _input) onlyOwner runs balances[msg.sender] = balances[msg.sender] + (_input); without changing _totalSupply, which adds to the caller's balance. renounceOwnership(address _newOwner) is public with no access check and only writes currentOwner, which nothing else reads; it does not change owner.

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract ROCKET CUMS

Build your security review skills

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