Nagasaki Shiba Honeypot
What happened
De.Fi's REKT database lists Nagasaki Shiba (NIBBA, Ethereum contract 0x2f1b026a…7b230e) as an exit scam/honeypot, noting that the contract owner could disable the transfer function, which restricted users in selling their tokens. In the verified source, every transfer runs through a burnTokenCheck modifier. While _sellAmount is still 0, and unless the sender is _owner, _safeOwner, a whitelisted address, or the recipient is _owner, a transfer reverts when its recipient is not the hard-coded _unirouter address, and a sell to a liquidity pool has a different recipient.
The owner-only functions increaseAllowance, addApprove and decreaseAllowance change the whitelist, the blacklist and _safeOwner, so the owner can decide who may sell. De.Fi gives no loss figure, and the code alone does not show who was able to sell.
How it happened
- The constructor sets
_owner = owner;and_safeOwner = owner;, then calls_mint(owner, initialSupply*(10**18));followed by_mint(0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B, initialSupply*(10**18));._mintrequiresmsg.sender == _owner, so for the deployment to succeed_ownermust be the deployer 0xc9634Bfa…86F825. _mintalways credits_balances[_owner] = _balances[_owner].add(amount);and only the emittedTransferevent namesaccount. Both constructor mints therefore land in the owner's balance, while the secondTransferevent names 0xAb5801a7…9aeC9B, so an event-based holder view andbalanceOfcan disagree.transferandtransferFromboth call_approveCheck(sender, recipient, amount), which carries the modifierburnTokenCheck(sender,recipient,amount). IntransferFrom,senderis the holder whose tokens move, not the router.- Branch 1:
if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}. While_safeOwnerstill equals_owner, the first transfer from the owner passes and re-points_safeOwnerto that transfer's recipient. Branch 2:if (sender == _owner || sender == _safeOwner || recipient == _owner)always passes; inside it,if (sender == _owner && sender == recipient){_sellAmount = amount;}lets an owner self-transfer set_sellAmountonce_safeOwnerdiffers from_owner. - Branch 3: if
_whiteAddress[sender] == truethe transfer passes. Branch 4: if_blackAddress[sender] == true, the linerequire((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");applies.sender == _safeOwnerwas already handled in branch 2, so in practice only a transfer to_unirouterpasses. - Branch 5, every other sender:
if (amount < _sellAmount)the transfer passes, and ifrecipient == _safeOwnerthe sender is moved to the blacklist (_blackAddress[sender] = true; _whiteAddress[sender] = false;). Otherwise the samerequireas branch 4 runs._sellAmountstarts at 0 (uint256 private _sellAmount = 0;), soamount < _sellAmountis false for every amount until the owner sets it. - A holder who is not whitelisted and sells through a router sends tokens to a pool address, not to
_unirouter, so therequirereverts with the messageERC20: transfer amount exceeds balance, even though the balance is not touched at that point. Buys are transfers from the pool, so they pass only if the pool is_safeOwner(for example when the first owner transfer went to the pool), is whitelisted, oramount < _sellAmount. - The owner controls the lists:
increaseAllowance(address[] memory receivers)whitelists and un-blacklists,addApprove(address[] memory receivers)blacklists and un-whitelists, anddecreaseAllowance(address safeOwner)sets_safeOwner.multiTransfersends tokens and whitelists the firstapprovecountreceivers. No function reassigns_owner, and_mintstays public but owner-only.
Protocol details
Evidence
- report @Token_Sniffer incident report twitter.com
- address Etherscan verified source for 0x2f1b026ac7b170a09253fcdc9cebd046b57b230e etherscan.io
- analysis Sourcify match for 0x2f1b026ac7b170a09253fcdc9cebd046b57b230e repo.sourcify.dev
- analysis De.Fi REKT database listing for NIBBA (Exit Scam/Honeypot) de.fi
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.