SafePlay Token Honeypot
What happened
SafePlay Token (SAFEPLAY) is a BNB Chain token whose fee-calculation hook doubles as a sell switch. Every transfer calls calculateFeesBeforeSend, which reverts with "Error: Can not sell this token" when the recipient is flagged in PanCakeSwapReciever, a mapping only the owner can write through setPanCakeSwapReciever. Once a DEX pair address is flagged, any transfer into the pair, including a router sell, reverts, while transfers out of the pair are not affected by this check.
De.Fi's REKT database lists SAFEPLAY as an exit scam/honeypot dated 2021-03-27 and describes the owner as able to disable the transfer function; it lists no loss figure. The contract was deployed in transaction 0xc6cc8582…b4a5fd on that day.
How it happened
- The constructor mints the whole supply to the deployer:
_transferTO(msg.sender, 1000000000e18);.Ownablemakes the deployer the owner, and a read ofowner()on 2026-09-30 still returned the deployer address 0xfcca2d6f…7b4e47. - The owner can mark any address as a sell destination:
function setPanCakeSwapReciever(address _recipient, bool _feeless) public onlyOwner { ... PanCakeSwapReciever[_recipient] = _feeless; }. Despite the_feelessparameter name, the value is only used by the check in the next step. There is no cap or time limit on this setter. transferandtransferFromboth call_transfer, which callscalculateFeesBeforeSend(sender, recipient, amount)after debiting the sender.- That function contains
if(PanCakeSwapReciever[recipient]){ revert("Error: Can not sell this token"); }. The test is on the recipient only, so every transfer to a flagged address reverts, whoever the sender is; the revert also undoes the sender's balance debit. If the flagged address is a DEX pair, a holder's sell, which moves tokens from the holder to the pair, cannot complete. - For unflagged recipients the function returns
(amount, 0), so ordinary transfers and buys pass with no fee, and thesetFeelessSender,setFeelessReciever,seTxFeeandtxFeesettings have no effect on this path. renounceOwnership()exists, so the owner could give up the flagging power, but the source does not do so on its own.- This is what the code allows. No transaction showing
setPanCakeSwapRecieverbeing called on a pair address was opened.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.