GOATMOON Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

De.Fi's REKT database lists GOATMOON on BNB Smart Chain as an Exit Scam/Honeypot, stating that the contract owner could disable the transfer function and so restrict users from selling. The verified source shows the mechanism: every transfer passes through a burnTokenCheck modifier, and a holder who is not whitelisted by the owner can only send tokens to a hard-coded router address or to the owner, not to a liquidity pool. The revert message reads "ERC20: transfer amount exceeds balance" even though the holder's balance is not the cause.

The contract was deployed on 2021-05-15 at 15:36 UTC in transaction 0x96a58552…bc4989. No loss figure is listed.

How it happened

  1. The owner address _owner is set once in the constructor and the source has no function that changes it. transfer and transferFrom both call _approveCheck, which carries the burnTokenCheck modifier.
  2. The first transfer sent by the owner while _owner == _safeOwner passes and runs _safeOwner = recipient. After that, transfers pass when the sender is _owner or _safeOwner, or when the recipient is _owner.
  3. For every other sender, a transfer passes only if the sender is whitelisted (_whiteAddress[sender] == true). Otherwise it must satisfy require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"), where _unirouter is the hard-coded address 0x05fF2B0D…608C7F. A sale through a liquidity pool sends tokens to the pool, which neither exemption covers, so it reverts with a message that blames the balance.
  4. _sellAmount starts at 0, so the amount < _sellAmount escape never applies until the owner sets it by transferring to itself (if (sender == _owner && sender == recipient){_sellAmount = amount;}). Once it is set, a non-listed holder can send amounts below it, and if the recipient is _safeOwner the sender is flagged: _blackAddress[sender] = true; _whiteAddress[sender] = false;. A blacklisted holder can then only send to _unirouter or _owner.
  5. The owner alone controls the lists and the exemption target: increaseAllowance whitelists, addApprove blacklists, decreaseAllowance(address safeOwner) replaces _safeOwner, and multiTransfer can whitelist receivers and set their allowance to _unirouter to the maximum.
  6. The owner can also mint: _mint is public, requires msg.sender == _owner, and adds the amount to _balances[_owner]. The code shows this power; no transaction was opened showing it used.

Protocol details

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

Build your security review skills

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