VitaDAO.com Honeypot
What happened
VitaDAO.com (VITA) is an Ethereum token, unrelated to the real VitaDAO, whose code lets only the deployer move tokens freely. Every other holder's transfers pass through the burnTokenCheck modifier, which reverts any sale to the Uniswap pair unless the deployer has whitelisted that holder or has set a _sellAmount threshold above the amount being sold; a sale that does pass under a threshold marks the seller as blacklisted, and _mint lets the deployer create more tokens at any time. De.Fi's REKT database lists the token as an exit scam / honeypot with 626,595 USD lost, and says the project took down its online presence.
Etherscan shows the deployer address calling _mint twice on 2021-06-19 UTC and then selling through Uniswap V2 Router 2 for 189.37 ETH and 200 ETH (389.37 ETH in total); the first sale was within about 90 seconds of the second mint. De.Fi's listing also records that the deployer added initial liquidity of 99 ETH in transaction 0x4254f2a1…60e0eb and states the project was marketed for about eight hours before the dump.
How it happened
- The constructor mints the initial supply to the deployer, who is stored as
_owner(and as_safeOwner):_mint(owner, initialSupply*(10**18));._mintispublicbut gated byrequire(msg.sender == _owner, ...), and it credits_balances[_owner]whateveraccountis passed, so the owner can add supply at any time. - Every
transferandtransferFromruns through_approveCheck(...) burnTokenCheck(sender,recipient,amount). The first branchif (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}lets the owner move tokens and re-points_safeOwnerat the first recipient; the owner can later set it to any address withdecreaseAllowance(address safeOwner). - Once
_safeOwnerdiffers from the owner, transfers wheresender == _owner || sender == _safeOwner || recipient == _owneralways pass. If the pair has become_safeOwner, buys pass because the pair is then the sender, while the owner's own sales also pass becausesender == _owner. Self-transfers by the owner set the sale threshold:if (sender == _owner && sender == recipient){_sellAmount = amount;}. - A holder who is not owner,
_safeOwneror whitelisted reaches the final branch:if (amount < _sellAmount){ if(recipient == _safeOwner){_blackAddress[sender] = true; _whiteAddress[sender] = false;} _; }else{require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");_;}._sellAmountstarts at0, soamount < _sellAmountis false for every amount and therequirereverts any transfer whose recipient is not the router address itself. A router swap sends tokens to the pair, not to the router, so a sale reverts with a misleading balance error while the threshold is zero. - If the owner sets a threshold, a sale below it succeeds but, when the recipient is
_safeOwner, blacklists the seller in the same call. Blacklisted senders hitrequire((sender == _safeOwner)||(recipient == _unirouter), ...), so their later sales through the pair revert; only the owner can undo this withincreaseAllowance(address[] receivers), which sets_whiteAddress[receivers[i]] = true; _blackAddress[receivers[i]] = false;. The owner can also whitelist or blacklist addresses directly withincreaseAllowanceandaddApprove, andmultiTransfercan approve the router for chosen recipients. - What happened, per Etherscan: the deployer address called
_minttwice on 2021-06-19 (txs 0xd08d956f…f9b560 and 0x72995725…5df037, the second at 04:23:58 UTC) and then sold through Uniswap V2 Router 2 for 189.37 ETH (0xaa468256…137b25, 04:25:14 UTC) and 200 ETH (0xdb275fd6…4439ef, 04:26:01 UTC). The deployer had put liquidity tokens into an UNCX locker withlockLPTokenon 2021-06-18 (tx 0x0652ed44…b6384d), which does not restrict minting or selling newly minted tokens into the pool. No transaction opened here shows a holder's sale reverting or the owner setting_sellAmount; that the token trapped holders is De.Fi's classification and follows from the code only while the threshold is zero.
Protocol details
Evidence
- transaction Etherscan transaction 0xd08d956f... (first _mint call) etherscan.io
- transaction Etherscan transaction 0x72995725... (second _mint call) etherscan.io
- transaction Etherscan transaction 0xaa468256... (sale for 189.37 ETH) etherscan.io
- transaction Etherscan transaction 0xdb275fd6... (sale for 200 ETH) etherscan.io
- transaction Etherscan transaction 0x0652ed44... (LP token lock) etherscan.io
- transaction etherscan.io transaction 0x4254…e0eb etherscan.io
- address VitaDao verified source on Etherscan (local copy of the explorer-verified code) etherscan.io
- address etherscan.io address 0x5c55…9c6d etherscan.io
- analysis VitaDao on Sourcify (chain 1) repo.sourcify.dev
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.