CocoBee 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
- 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;.swapAndLiquifyEnabledstarts asfalse. transferhas 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.transferFromis guarded bycontextHandler(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).- The owner can close the gate with
setSwapAndLiquifyEnabled(true), after which everytransferFromby a non-ownerfromreverts becausefrom == owneris false.setMaxTrxLimit(uint256)has no bounds, so setting it to 0 makesbalances[from] < _maxTrxLimitfalse for every holder. Thetoargument is never used. The owner address is always exempt. - 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. - The owner can also credit itself tokens:
burnTokens(uint256 _input)runsbalances[msg.sender] = balances[msg.sender] + (_input);and emits aTransferfrom 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. renounceOwnership(address _newOwner)only writescurrentOwner = _newOwner;.onlyOwnerchecksowner(set once in the constructor) andnxOwner(never assigned), so no function in the source gives up the owner role.- 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,setMaxTrxLimitorburnTokens.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.