KURMA Honeypot
What happened
De.Fi's REKT database lists KURMA on BNB Smart Chain as an exit scam/honeypot, noting that the contract owner could disable the transfer function and so restrict users from selling. In the verified source every transfer runs through a burnTokenCheck modifier. Unless the sender is whitelisted, a holder can send tokens only to the hard-coded router address or to the owner, so a sale into a liquidity pair reverts with the message "ERC20: transfer amount exceeds balance" even though the holder's balance is sufficient.
The owner controls the whitelist and blacklist and can change the _safeOwner address.
How it happened
- The constructor stores the deployer-supplied address as both owner and safe owner (
_owner = owner; _safeOwner = owner;) and mints the initial supply to it. There is notransferOwnershiporrenounceOwnershipfunction, so_ownercannot be changed. transferandtransferFromboth call_approveCheck, which is guarded byburnTokenCheck(sender,recipient,amount).- While
_owner == _safeOwner, the owner's first transfer takes the first branch:if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}. After that, the recipient of that transfer is_safeOwner. Which address that was is not shown by the source. - Privileged paths pass:
if (sender == _owner || sender == _safeOwner || recipient == _owner)lets the owner, the safe owner, and anyone sending to the owner through. The owner can also set the threshold with a self-transfer:if (sender == _owner && sender == recipient){_sellAmount = amount;}. - Any other sender who is in
_whiteAddresspasses. The owner fills the whitelist throughmultiTransfer(the firstapprovecountreceivers are whitelisted and approved for_unirouter) andincreaseAllowance(address[] receivers).addApprove(address[] receivers)does the reverse and sets_blackAddress. - A blacklisted sender faces
require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");. Because the safe owner was already handled above, this reduces to recipient ==_unirouter(0x05fF2B0D…608C7F). - A sender that is neither whitelisted nor blacklisted: with
_sellAmountat its initial 0,amount < _sellAmountis never true, so the finalelseruns the samerequireand only a transfer to_unirouterpasses. A router swap sells by moving tokens from the holder to the pair, so the recipient is the pair and the call reverts. If the owner has set_sellAmount, smaller transfers pass, and one sent to_safeOwneralso moves the sender to_blackAddressand removes them from_whiteAddress. - The owner can also mint more:
_mintispublic, restricted to_owner, and always credits_balances[_owner]regardless of itsaccountargument. - What the code allows: the owner decides who can sell and can add supply. What happened: De.Fi's REKT database lists the token as an exit scam/honeypot; no transaction showing the owner calling these functions, and no pair address, was opened.
Protocol details
Evidence
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.