MoonGold Honeypot
What happened
MoonGold blocks sells through a variable named newun that transferFrom fills automatically. The first transferFrom call from a non-zero address while newun is empty stores that call's recipient in newun, and from then on every transfer and transferFrom to that address reverts with "please wait". When the stored address is the liquidity pair, buys (which send tokens out of the pair) still work, but a holder's sell, which sends tokens into the pair, reverts.
De.Fi's REKT database lists MoonGold as an exit scam/honeypot on BNB Smart Chain and states that the contract owner could disable the transfer function, which restricted users in selling their tokens. The code does not show which address newun held on chain or whether liquidity was later withdrawn.
How it happened
- The constructor sets the deployer as
ownerand gives it the whole supply:balances[owner] = _totalSupply;(1,000,000,000,000,000 tokens with 18 decimals).newunstarts as the zero address. transferrefuses any recipient equal tonewun:require(to != newun, "please wait");.transferFromcontains the capture logic:if(from != address(0) && newun == address(0)) newun = to; else require(to != newun, "please wait");. The first call withnewunempty skips therequireand storesto; later calls hit theelsebranch. A router adding liquidity callstransferFromwith the pair as recipient, so the pair address would be stored then; the source does not say that this happened for this token.- Once
newunequals the pair, a buy works because the pair sends tokens to the buyer (tois the buyer), and holder-to-holder transfers work. A sell viatransferor a router'stransferFromhas the pair asto, so it reverts with "please wait". There is no owner exemption, so the owner's own transfers to that address revert as well. - The owner can change the value with
function transfernewun(address _newun) public onlyOwner { newun = _newun; }. Setting it to the zero address re-arms the capture on the nexttransferFrom, and only pointing it at an address that is not used as a recipient lifts the block. clearCNDAO()(onlyOwner) sends the contract's own BNB balance to the owner, which does not touch pool liquidity. The source file header says the token and liquidity are burned before listing and the footer says the tokens are for testing purposes, but the code contains no liquidity burn.- What happened on chain (the
newunvalue, sells that failed, liquidity removed) is not shown by the source; the honeypot label comes from De.Fi's listing and a blog post that explains this same mechanism in other tokens.
Protocol details
Evidence
- report @Token_Sniffer incident report twitter.com
- address BscScan verified source for 0x718b126fba8dd29da752a229a1f4ef045c3e39b0 (MoonGold) bscscan.com
- analysis Sourcify match for MoonGold on chain 56 repo.sourcify.dev
- analysis BSC Liquidity Pool Blocking Scam Analysis (cryptot3ddybear blog) cryptot3ddybear.gitlab.io
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.