SafeShib Honeypot

Reported loss Not disclosed
Ethereum
Honeypot

What happened

De.Fi's REKT database lists SafeShib (SAFESHIB) on Ethereum as an Exit Scam/Honeypot and says the contract owner could disable the transfer function, which restricted users in selling their tokens. The code has no single switch for that. Every transfer goes through a burnTokenCheck modifier, and while _sellAmount is still 0 an ordinary holder can only send tokens to the hard-coded _unirouter address or to the owner; whitelisted addresses and the owner are exempt.

The owner alone controls the whitelist, blacklist, _safeOwner and _sellAmount. The code allows this; it does not show which addresses were whitelisted or blacklisted. The comments and constants in the file that mention a six-month liquidity lock are plain text and enforce nothing in this contract.

How it happened

  1. The constructor sets _owner = owner; and _safeOwner = owner;. _unirouter is hard-coded as 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D and _sellAmount starts at 0.
  2. transfer and transferFrom both run _approveCheck, guarded by burnTokenCheck(sender,recipient,amount). The first branch is if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}, so the first time the owner sends tokens anywhere, the recipient becomes _safeOwner. The owner can also reassign it directly with decreaseAllowance(address safeOwner).
  3. After that, the owner, _safeOwner, and any transfer whose recipient is the owner pass unrestricted: if (sender == _owner || sender == _safeOwner || recipient == _owner). Senders marked in _whiteAddress also pass unrestricted. The owner marks them with increaseAllowance(address[]) or multiTransfer, which also gives the first approvecount receivers a maximum allowance to _unirouter.
  4. Any other sender hits require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"); unless amount < _sellAmount. With _sellAmount at 0, an ordinary holder's transfer to an address other than _unirouter or the owner reverts, even when the balance is sufficient. The check reads the recipient argument, which is where the tokens go, not the caller.
  5. The owner can raise _sellAmount by sending tokens to itself once _safeOwner differs from _owner (if (sender == _owner && sender == recipient){_sellAmount = amount;}). Below that amount, an ordinary sender may transfer anywhere, but if the recipient is _safeOwner the sender is added to _blackAddress. addApprove(address[]) blacklists addresses directly and clears their whitelist flag.
  6. _mint is public but requires msg.sender == _owner and always credits _balances[_owner], so the owner can add supply to its own balance.
  7. The file also declares string public constant beneficiary and uint256 public constant releaseTime = 6; under a comment that says liquidity is locked for 6 months. No function in this contract reads them or locks anything.
  8. What happened: De.Fi's REKT database lists the token as an Exit Scam/Honeypot. No transaction was opened, so the code evidence does not show which addresses were allowed to sell or when.

Protocol details

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

Build your security review skills

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