SafeForever Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

De.Fi's REKT database lists SafeForever (SAFE4EVER) as an Exit Scam/Honeypot on Binance, noting that the contract owner could disable the transfer function, which restricted users in selling their tokens. In the verified source, every transfer and transferFrom passes through a burnTokenCheck modifier that, by default, only lets a holder send tokens to the hard-coded _unirouter address or to _owner; any other recipient reverts with "ERC20: transfer amount exceeds balance". The owner alone controls the whitelist, blacklist and _sellAmount values that loosen or tighten this rule, and _owner is fixed in the constructor with no function to change it.

The code shows what the owner can do; it does not show which addresses were whitelisted or blacklisted.

How it happened

  1. The constructor sets _owner = owner; and _safeOwner = owner; and mints the initial supply to the owner with _mint(_owner, initialSupply*(10**18));. No function reassigns _owner afterwards, and _mint stays callable by _owner (require(msg.sender == _owner, ...)), adding further tokens to the owner's balance.
  2. transfer and transferFrom both call _approveCheck, which is wrapped by the burnTokenCheck modifier.
  3. For an ordinary holder (not _owner, not _safeOwner, not whitelisted, not blacklisted) the modifier ends in require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"); while _sellAmount is still its initial 0, because amount < _sellAmount can never be true. Such a holder can only send tokens to _unirouter (0x05fF2B0D…608C7F) or, through an earlier branch (recipient == _owner), to the owner. Any other recipient makes the call revert and the holder's balance is unchanged.
  4. Senders that pass: _owner, _safeOwner (the first branch re-points it to the recipient of the owner's first transfer: if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}), addresses the owner whitelisted with increaseAllowance(address[] receivers) or through the first approvecount receivers of multiTransfer, and anyone sending an amount below _sellAmount once the owner has set it by transferring to itself.
  5. The owner can also call addApprove(address[] receivers), which sets _blackAddress and clears _whiteAddress; a blacklisted sender is again limited to recipient == _unirouter (or _owner). In the below-_sellAmount branch, a transfer to _safeOwner both goes through and blacklists the sender.
  6. The contract does not show whether the pair address is _safeOwner or _unirouter, so whether a given DEX sale reverts depends on the recipient of the token transfer. De.Fi's REKT database lists the token as a honeypot where selling was restricted; no transaction was opened that shows the owner calling these functions.

Protocol details

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

Build your security review skills

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