Whackd Honeypot
What happened
Whackd (WHACKD) is an ERC-20 token on Ethereum, deployed 2021-06-24 at 0x8b40c8ae…65f7c3. Every transfer passes through a modifier, burnTokenCheck, that lets the owner and a stored _safeOwner address move tokens freely but restricts every other sender to sending only to the Uniswap V2 router (_unirouter). A holder's sell moves tokens to the trading pair rather than to the router, so it reverts with "ERC20: transfer amount exceeds balance", while the owner can whitelist or blacklist addresses, set a small-transfer threshold and mint more supply.
De.Fi's REKT database lists WHACKD as an Exit Scam/Honeypot with no loss figure.
How it happened
What the code allows (the owner is _owner, set once in the constructor; the contract has no function that changes it):
- The constructor sets
_owner = owner; _safeOwner = owner;and calls_mintten times withinitialSupply*(10**18), five times naming 0xCF833572…439eEE and five times naming 0x23D3808f…6E5972._mintcredits_balances[_owner], not theaccountargument, so the balance goes to the owner while the emittedTransferevents name those two addresses._unirouteris hard-coded as0x7a250d5630B4cF539739dF2C5dAcb4c659F2488Dand_sellAmountstarts at 0. transferandtransferFromboth call_approveCheck, which runs theburnTokenCheckmodifier. While_owner == _safeOwner, any transfer from the owner takes the first branch,_safeOwner = recipient;. In a normal liquidity add the owner's first transfer goes to the pair, which would make the pair_safeOwner. From then on_owner != _safeOwner.- Second branch: if
sender == _owner || sender == _safeOwner || recipient == _ownerthe transfer passes. If the pair is_safeOwner, this is why a buy, which sends tokens out of the pair, succeeds.if (sender == _owner && sender == recipient){_sellAmount = amount;}lets the owner set a threshold by sending to itself. - Every other sender: if
_whiteAddress[sender] == truethe transfer passes. If_blackAddress[sender] == true, it requires(sender == _safeOwner)||(recipient == _unirouter)or reverts. If the sender is on neither list andamount < _sellAmount, the transfer passes, and ifrecipient == _safeOwnerthe sender is blacklisted. Otherwise it reverts unlessrecipient == _unirouter. - With
_sellAmountat its initial 0,amount < _sellAmountis never true, so an ordinary holder can send tokens only to the router address. A sell through a router callstransferFrom(holder, pair, amount), whose recipient is the pair, so it reverts. Plain wallet-to-wallet sends revert for the same reason. - The owner-only functions
increaseAllowance(address[])(whitelists and un-blacklists),addApprove(address[])(blacklists and un-whitelists) anddecreaseAllowance(address safeOwner)(rewrites_safeOwner) change who passes.multiTransferwhitelists the firstapprovecountreceivers. _mint(address account, uint256 amount) publicrequiresmsg.sender == _owner, so the owner can add supply at any time; no function burns it.
De.Fi's REKT database lists WHACKD as an Exit Scam/Honeypot with no stated loss. No transaction was examined here, so which address became _safeOwner, which addresses were listed, and whether any later mint or liquidity removal occurred are not established.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.