SafeAndromeda Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

Every transfer of this token passes through a burnTokenCheck modifier that lets only the owner, a stored _safeOwner address and owner-whitelisted addresses move tokens freely. Any other holder can only send tokens to the hard-coded router address 0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F or to the owner, because _sellAmount starts at zero and the exception amount < _sellAmount can never be met. A holder selling into a pair is sending to neither, so the transfer reverts.

The owner can whitelist or blacklist addresses, change _safeOwner and mint. De.Fi's REKT database lists this token as an Exit Scam/Honeypot, saying the owner could disable the transfer function, which restricted users in selling their tokens.

How it happened

  1. The constructor sets _owner = owner; and _safeOwner = owner;. _sellAmount is initialised to 0. The deployed contract has no function that changes _owner. A comment at the top of the source says 8 BNB and 95% of the supply would be added to the pool and locked for 365 days; the code enforces no lock.
  2. transfer and transferFrom both call _approveCheck, which carries the burnTokenCheck modifier. While _owner == _safeOwner, the first transfer out of the owner runs if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}, so the recipient of the owner's first outgoing transfer becomes _safeOwner. The code alone does not show which address that was.
  3. After that, if (sender == _owner || sender == _safeOwner || recipient == _owner) passes. Whitelisted senders pass through if (_whiteAddress[sender] == true){ _;. Both lists are set only by the owner: increaseAllowance whitelists and addApprove blacklists, despite their names.
  4. Every other sender reaches if (amount < _sellAmount). With _sellAmount == 0 this is never true, so the code runs require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");. Since sender == _safeOwner was already handled above, an ordinary holder can only send to the router address. A swap that pulls tokens from the holder into a pair has a pair as recipient, not the router or the owner, and reverts. Blacklisted senders face the same require.
  5. The owner can change this: if (sender == _owner && sender == recipient){_sellAmount = amount;} sets _sellAmount when the owner transfers tokens to itself. Once it is set, a non-whitelisted sender whose amount < _sellAmount passes, but if the recipient == _safeOwner the sender is added to _blackAddress and removed from _whiteAddress.
  6. decreaseAllowance(address safeOwner) lets the owner reassign _safeOwner, and _mint lets the owner create tokens credited to _balances[_owner].
  7. Buys from a pair also go through the modifier. They pass only if the pair is _safeOwner, is whitelisted, or is the owner; the code does not show which of these applied.

Protocol details

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

Build your security review skills

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