SaveFlipper Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

De.Fi's REKT database lists SaveFlipper (SFR) on BNB Smart Chain 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. Instead 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 and blacklist, so the code lets the owner decide who can sell. It does not show which addresses were whitelisted or blacklisted.

How it happened

  1. The constructor sets _owner = owner; and _safeOwner = owner;. _unirouter is hard-coded as 0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F 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. 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 Exchange (DEX)
Protocol Type Exit Scam/Honeypot
Affected asset / contract SFR

Build your security review skills

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