SAFEMOONSWAP Honeypot
What happened
SAFEMOONSWAP is an Ethereum token deployed on 16 May 2021 at 0xda8a938f…9c91f9 by 0x70e56D1E…69E97f. Every transfer and transferFrom runs the burnTokenCheck modifier. The owner's first outgoing transfer, normally the one that seeds the Uniswap pool, makes the recipient _safeOwner, and transfers from _safeOwner always pass, so buys out of the pool work.
A transfer from an ordinary holder passes only if it goes to the Uniswap V2 router, to the owner, or is smaller than _sellAmount, which starts at zero and only the owner can raise; a holder who sells below that threshold into _safeOwner is blacklisted. The owner also has an uncapped _mint and owner-only functions, under misleading names, that whitelist, blacklist and replace _safeOwner. De.Fi's REKT database lists the token as an exit scam/honeypot.
How it happened
- The constructor sets
_owner = ownerand_safeOwner = ownerand mints the supply to the owner._unirouteris hard-coded to 0x7a250d56…F2488D, the Uniswap V2 router. - In
burnTokenCheck,if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}means the owner's first outgoing transfer, such as adding liquidity, makes that recipient (the pair)_safeOwner. - Transfers pass unchecked when
sender == _owner || sender == _safeOwner || recipient == _owner, so the pair can pay out tokens to buyers. - For any other sender that is not whitelisted,
if (amount < _sellAmount)is the only open path._sellAmountstarts at0and is set only when the owner transfers to itself (if (sender == _owner && sender == recipient){_sellAmount = amount;}). Otherwise the modifier requires(sender == _safeOwner)||(recipient == _unirouter), and a sale sends tokens to the pair, not the router, so it reverts with the disguised message "ERC20: transfer amount exceeds balance". - If the owner does raise
_sellAmount, a holder who sends a smaller amount to_safeOwneris marked with_blackAddress[sender] = true, and blacklisted senders face the same router-only requirement afterward. - The owner-only functions
increaseAllowance(address[])(whitelist),addApprove(address[])(blacklist),decreaseAllowance(address)(sets_safeOwner) andmultiTransfer(sends tokens and whitelists recipients) decide who can sell._mintis public but restricted to_ownerand adds any amount to the owner's balance.
Protocol details
Evidence
- report Token Sniffer post 1374999601485291522 (seed link) twitter.com
- transaction SAFEMOONSWAP contract creation transaction etherscan.io
- address SAFEMOONSWAP verified contract code on Etherscan etherscan.io
- analysis Sourcify exact match for 0xda8a938fa494348aeefcc57a4b1927ebfc9c91f9 on Ethereum repo.sourcify.dev
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.