NeptuneWallet Honeypot
What happened
NeptuneWallet (NEW) is a BEP20 token with an owner-controlled tracing switch. When tracing is true, the first transferFrom call stores its recipient in nxOwner, and from then on transfer and transferFrom revert for that recipient. If that address is a trading pair, sells revert while buys from the pair are unaffected.
The owner can turn tracing off and on, and emitTransfer lets the owner add to its own balance without raising totalSupply. De.Fi's REKT database lists the token as an Exit Scam/Honeypot and says the contract owner could restrict users from selling. An opened Token Sniffer post from 2021-05-05 describes this kind of LP-address block in other tokens and predates this deployment.
How it happened
- The constructor sets
symbol = "NEW", assigns the full 1000000000000000000000 raw supply to the owner and then callstransfer(dead, burnedAmount)for 500000000000000000000 raw units, sending half the supply to 0x00000000…00dEaD. tracingstarts asfalse(bool tracing = false;), so at first the checks do nothing. OnlysetTracing(bool _tracing) onlyOwnerchanges it.- With
tracingon,transferFromrunsif(from != address(0) && nxOwner == address(0)) nxOwner = to; else require(to != nxOwner, "Order ContextHandler");. The firsttransferFromafter that stores its recipient innxOwner. The source does not show which address that was. - From then on
transferFromandtransfer(require(to != nxOwner, "Handling Request")) revert for any call whose recipient isnxOwner, with no exemption for the owner. IfnxOwneris a pair, a sell, which makes the router calltransferFrom(holder, pair, amount), reverts, while a buy, where the pair is the sender, is not blocked. There is no function that changesnxOwner, butsetTracing(false)switches the check off andsetTracing(true)switches it back on. onlyOwneracceptsmsg.sender == owner || msg.sender == nxOwner, so the captured address also satisfies the owner check.emitTransfer(uint256 _input) onlyOwnerrunsbalances[msg.sender] = balances[msg.sender] + (_input);with no overflow check and no change to_totalSupply, so the owner can add to its own balance at will. The source alone does not show whether this was done.renounceOwnership(address _newOwner)has no access check and only writescurrentOwner, which no other code reads, so it does not remove or transfer the owner role.- What happened on-chain (sell attempts, liquidity removal, losses) was not established by the opened sources. De.Fi's REKT database lists the token as a honeypot.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.