HappyMoon Honeypot
What happened
HappyMoon is a BEP-20 token on BNB Smart Chain whose transfer and transferFrom functions revert for any transfer whose recipient equals a stored address called newun. transferFrom fills newun with the recipient of the first call made while it is empty, which on a DEX is typically the liquidity pair created when liquidity is added. After that, buys still work but any sell, which sends tokens to the pair, reverts with "please wait".
The owner can also change newun with transfernewun. De.Fi's REKT database lists the token as an Exit Scam/Honeypot and describes it as a contract where the owner could disable the transfer function, which restricted users in selling their tokens.
How it happened
- The constructor mints the whole supply to the deployer, who becomes
owner:_totalSupply = 10000000000000000000000000000000;andbalances[owner] = _totalSupply;(10^31 raw units, 10 trillion tokens at 18 decimals). - The contract keeps a variable
address public newun;that is empty at deployment.transferFromrunsif(from != address(0) && newun == address(0)) newun = to; else require(to != newun, "please wait");, so the firsttransferFrommade whilenewunis empty passes and stores its recipient innewun. On a DEX, the router'stransferFromthat moves tokens into the pair when liquidity is added would be that first call. - From then on both transfer paths check the recipient:
require(to != newun, "please wait");intransferand the sameelse require(to != newun, "please wait");branch intransferFrom. A sell routes the holder's tokens to the pair withtransferFrom, so it reverts. Buys send tokens from the pair to the buyer, whose address differs fromnewun, so they succeed. Any holder or the owner moving tokens to the pair is blocked the same way. - The owner can change the block at any time with
function transfernewun(address _newun) public onlyOwner { newun = _newun; }. Pointingnewunat an unused address lifts the sell block. Setting it to the zero address re-arms capture, so the nexttransferFromstores a new recipient. There is norenounceOwnership;transferOwnershiponly hands the role to another address. - The code also gives the owner
clearCNDAO, which sends any BNB held by the token contract to the owner:_owner.transfer(address(this).balance);. Removing liquidity is not blocked bynewun, because the pair sends tokens out to the remover, and the recipient is then notnewun. - What happened: De.Fi's REKT database lists this token as an Exit Scam/Honeypot dated 2021-09-20 with no loss figure. No opened transaction or holder page in this review shows a specific
transfernewuncall, a failed sell, or a liquidity removal.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.