Nintendo Protocol Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

The Nintendo Protocol token (Nintendo) gates every transfer through a burnTokenCheck modifier. An ordinary holder can send tokens only to the hard-coded _unirouter address or to _owner; any other recipient reverts with "ERC20: transfer amount exceeds balance", although the holder's balance is not actually below the amount. The owner decides who is exempt through a whitelist, a blacklist and a _safeOwner address.

De.Fi's REKT database lists the token as an Exit Scam/Honeypot. The verified source shows these powers; it does not show which addresses the owner exempted or blocked.

How it happened

  1. Both transfer and transferFrom call _approveCheck(sender, recipient, amount), which carries the burnTokenCheck(sender,recipient,amount) modifier.
  2. The modifier lets a transfer pass unchecked when sender == _owner || sender == _safeOwner || recipient == _owner, or when _whiteAddress[sender] == true. While _owner == _safeOwner, a transfer sent by the owner also runs _safeOwner = recipient, so _safeOwner becomes the recipient of that first owner transfer. The code does not show which address that was.
  3. Every other sender is checked with require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"). Such a sender is never _safeOwner at that point (that case passed in step 2), so the transfer succeeds only if the recipient is the _unirouter address hard-coded in the contract. A transfer to a liquidity pair or any other address reverts, and the revert leaves the holder's balance unchanged.
  4. The owner can change who falls on which side: increaseAllowance(address[]) whitelists and un-blacklists addresses, addApprove(address[]) blacklists and un-whitelists them, decreaseAllowance(address) sets _safeOwner, and multiTransfer sends tokens and whitelists the first approvecount receivers while approving _unirouter for the maximum amount on their behalf. A blacklisted sender faces the same require as an unlisted one.
  5. A small exception exists once _sellAmount is set, which happens when the owner sends tokens to itself (if (sender == _owner && sender == recipient){_sellAmount = amount;}). An unlisted holder sending less than _sellAmount is not reverted, but if the recipient is _safeOwner the holder is added to _blackAddress in the same call, so later transfers face the restriction again.
  6. _mint is public and checks only msg.sender == _owner; it credits _balances[_owner] whatever account is passed, so the owner can increase supply. No function in the contract changes _owner after the constructor.

Protocol details

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

Build your security review skills

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