Crowny.io Honeypot
What happened
Crowny.io (CRWNY) is an Ethereum token deployed on 8 April 2021 at 0xc3756f83…62e0a2 by 0x66C618ed…8c7DAf. It is a different contract from the Crowny Token (CRWNY) that Etherscan lists at 0xDBdDf072…a143b1. Every transfer and transferFrom runs the burnTokenCheck modifier, which lets the fixed _owner, a stored _safeOwner address and whitelisted wallets move tokens but makes every other holder's transfer revert unless it is sent to the Uniswap V2 router address.
A Uniswap sale moves tokens into the pair, not the router, so ordinary holders can buy but not sell, and the revert shows the misleading message "ERC20: transfer amount exceeds balance". The whitelist and blacklist setters hide behind ERC-20 names (increaseAllowance, addApprove, decreaseAllowance), and a public owner-only _mint can create unlimited supply. De.Fi's REKT database lists Crowny.io as an exit scam/honeypot.
How it happened
- The constructor sets
_ownerand_safeOwnerto itsownerargument and then calls the public_mint, which requiresmsg.sender == _owner, so deployment only succeeds whenowneris the deploying account. No other code writes_owner, and there is no renounce function. - In
burnTokenCheck, while_owner == _safeOwner, the owner's first outgoing transfer runs_safeOwner = recipient. If that first transfer is the liquidity deposit into the Uniswap pair, the pair becomes_safeOwner; the owner can also set it directly withdecreaseAllowance(address safeOwner). - Transfers where the sender is
_owneror_safeOwner, or the recipient is_owner, always pass, so buys out of a pair set as_safeOwnergo through. Senders marked byincreaseAllowance(address[]), or by the firstapprovecountrecipients of the owner'smultiTransfer, are whitelisted and also pass. - Every other sender hits
require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance")._unirouteris 0x7a250d56…F2488D, the Uniswap V2 router, but a sale transfers the holder's tokens to the pair, so it reverts. Senders marked byaddApprove(address[])(the blacklist) are always held to this check. - An unlisted sender passes only if
amount < _sellAmount._sellAmountstarts at 0 and the owner can raise it by transferring tokens to itself; a transfer under the limit into_safeOwnerthen puts the seller on the blacklist, so at most one small sale works. _mint(address,uint256)is public, callable only by_owner, and always credits_balances[_owner], whateveraccountitsTransferevent names.
Protocol details
Evidence
- report Token Sniffer post 1374999601485291522 (seed link) twitter.com
- transaction Crowny.io contract creation transaction etherscan.io
- address Crowny.io (CRWNY) verified contract code on Etherscan etherscan.io
- analysis Sourcify exact match for 0xc3756f839739635bcf7504b16da4cd882662e0a2 on Ethereum repo.sourcify.dev
- analysis Crowny Token (CRWNY) Token Tracker etherscan.io
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.