CocoBee Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

CocoBee (CCB) is a BNB Smart Chain token (contract 0x9cd2220d…bda7f2) whose transferFrom carries an owner-switchable block. The contextHandler modifier reverts every transferFrom whose from is not the owner when swapAndLiquifyEnabled is true, and otherwise requires the holder's balance to be below _maxTrxLimit; the owner can change both values at any time. Plain transfer has no check, so buys and wallet-to-wallet sends are unaffected, while a sale through a router, which pulls tokens with transferFrom, is what the modifier can stop.

The source header says the LP will be locked and ownership renounced after launch, but the code has no function that changes the owner. De.Fi's REKT database lists the token as an Exit Scam/Honeypot and states that the contract owner could disable the transfer function, which restricted users in selling their tokens.

How it happened

  1. The constructor sets _totalSupply = 100000000 * 10**15; (100 trillion tokens at 9 decimals), _maxTrxLimit = 10000000 * 10**15; (10% of supply) and gives the whole supply to the deployer: balances[owner] = _totalSupply;. swapAndLiquifyEnabled starts as false.
  2. transfer has no restriction: balances[msg.sender] = balances[msg.sender].sub(tokens); balances[to] = balances[to].add(tokens);. Buys, where the pair sends tokens out, and direct wallet-to-wallet sends are not affected.
  3. transferFrom is guarded by contextHandler(from, to): if(from != owner) { if(swapAndLiquifyEnabled){ require(from == owner, "Order ContextHandler"); } else { require(balances[from] < _maxTrxLimit , "Order ContextHandler"); } }. In the default state a holder passes only while their balance is below 10% of supply (the check reads the holder's balance, not the amount sold).
  4. The owner can close the gate with setSwapAndLiquifyEnabled(true), after which every transferFrom by a non-owner from reverts because from == owner is false. setMaxTrxLimit(uint256) has no bounds, so setting it to 0 makes balances[from] < _maxTrxLimit false for every holder. The to argument is never used. The owner address is always exempt.
  5. A sale through a router moves tokens with transferFrom(holder, pair, amount), so once either setting is changed it reverts with "Order ContextHandler" for holders.
  6. The owner can also credit itself tokens: burnTokens(uint256 _input) runs balances[msg.sender] = balances[msg.sender] + (_input); and emits a Transfer from the zero address, without changing _totalSupply; despite the name it adds to the owner's balance. _construct() sends any BNB held by the contract to the owner.
  7. renounceOwnership(address _newOwner) only writes currentOwner = _newOwner;. onlyOwner checks owner (set once in the constructor) and nxOwner (never assigned), so no function in the source gives up the owner role.
  8. What happened is known only from the listing: De.Fi's REKT database classifies the token as an Exit Scam/Honeypot and gives no loss figure. No transaction was opened showing the owner calling setSwapAndLiquifyEnabled, setMaxTrxLimit or burnTokens.

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract CCB

Build your security review skills

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