HolyMoon Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

HolyMoon's contract keeps an address in the variable nxOwner and, for everyone except the owner account, rejects transfers that send tokens to it. The first transferFrom call stores its recipient there automatically; a liquidity addition through a router is such a call, so the pool address can end up stored. A holder's sell then reverts before their balance is debited, so the tokens stay in the wallet but cannot be sold, while the _owner account is exempt.

De.Fi's REKT database lists HolyMoon (HMOON) as an exit scam/honeypot on BNB Smart Chain dated 2021-05-23 and states that the owner could disable the transfer function, restricting users from selling.

How it happened

  1. The constructor mints _totalSupply = 500 * 10**6 * 10**9; (9 decimals) to the deployer, who is both _owner and _leaveowner.
  2. Every transfer runs the BeforeTransfer modifier. Its first branch is if(from != address(0) && nxOwner == address(0) && fromTransfer) nxOwner = to;: the first transferFrom call (fromTransfer is true only from transferFrom) stores its recipient in nxOwner. A router liquidity addition is such a call, so nxOwner can end up holding the pool address. The code alone does not show which address it holds on-chain.
  3. Every later call takes the other branch: else require((to != nxOwner || from == _owner), "Order TransferFromMiddleware");. A transfer to nxOwner passes only when from == _owner. A router sell calls transferFrom(holder, pool, amount), so from is the holder, the require fails, and the call reverts before _balances[sender] = _balances[sender].sub(...) runs. The holder keeps the tokens but cannot sell them. The _owner account can still send to nxOwner. Buys, paid out from the pool to the buyer, pass.
  4. The block can be changed by an owner account: function transferOwnership(address newOwner) public onlyOwner { nxOwner = newOwner; } only overwrites nxOwner and does not move ownership. Pointing it at an unused address lifts the block; setting it to the zero address lets the next transferFrom capture a new recipient. onlyOwner also accepts _leaveowner, and renounceOwnership only zeroes _owner, so the _leaveowner account keeps these powers.
  5. What happened: De.Fi's REKT database lists the token as a honeypot. No transaction showing the block applied to holders, a transferOwnership call, or a liquidity removal was opened for this record.

Protocol details

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

Build your security review skills

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