Virgin Elon Honeypot
What happened
Virgin Elon (VELON) was an Ethereum token (0x06c11906…5d1f18, deployed on 25 May 2021) whose transfer code let anyone buy from the pool but blocked ordinary holders from selling. A modifier on every transfer and transferFrom only lets a holder move tokens if they are the owner, the _safeOwner address, on an owner-controlled whitelist, or sending to the Uniswap router address itself; a sale to the pool fails with the misleading error "ERC20: transfer amount exceeds balance". The owner can whitelist or blacklist any address through functions disguised as increaseAllowance and addApprove, can mint through a public _mint, and the contract has no function to transfer or renounce ownership.
De.Fi's REKT database lists the token as a honeypot exit scam on 25 May 2021 in which the owner restricted users from selling; no loss figure is recorded.
How it happened
- The constructor stores the
ownerargument as_ownerand_safeOwnerand mints the initial supply with_mint(0x553989aAAD5ab9e28f764db151a52D51632B8CB4, initialSupply*(10**18)). Because_mintrequiresmsg.sender == _owner, the deploy could only succeed with the deployer, 0x553989aA…2B8CB4, as owner. - On the owner's first outgoing transfer,
if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}makes that recipient_safeOwner. If that transfer is the liquidity deposit, the pool becomes_safeOwnerand can send tokens freely, so buys go through. - Every other transfer passes only if
sender == _owner || sender == _safeOwner || recipient == _owneror_whiteAddress[sender] == true. - A holder who is not whitelisted falls through to
require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"). A Uniswap sale moves tokens from the holder to the pool, not to the router, so it reverts with an error that looks like a balance problem. - The only exception is
if (amount < _sellAmount)._sellAmountstarts at 0 and is set only by an owner transfer to itself. Below that threshold a transfer succeeds, but a transfer to_safeOwnerthen blacklists the sender:if(recipient == _safeOwner){_blackAddress[sender] = true; _whiteAddress[sender] = false;}. - Owner-only functions with standard-looking names manage the lists:
increaseAllowance(address[])whitelists,addApprove(address[])blacklists,decreaseAllowance(address)sets_safeOwner, andmultiTransfersends tokens and whitelists the firstapprovecountreceivers. The public owner-only_mintcredits_balances[_owner]whateveraccountit names in theTransferevent.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.