JUST FAIR LAUNCH Honeypot
What happened
DOGEGANG (on-chain name starting "JUST FAIR LAUNCH") is an ERC-20 whose transfer and transferFrom both run through a burnTokenCheck modifier. A holder who is not the owner, not the stored _safeOwner and not whitelisted can transfer only to the hard-coded Uniswap V2 router address (_unirouter) or to the owner, while _sellAmount is 0; once the owner sets _sellAmount, transfers below that amount pass to any recipient. Any other transfer reverts with the misleading message "ERC20: transfer amount exceeds balance".
The owner can whitelist or blacklist individual addresses, repoint _safeOwner, and call a public _mint. De.Fi's REKT database lists the token as an Exit Scam/Honeypot on Ethereum and describes it as a contract whose owner could disable the transfer function, which restricted users in selling their tokens. No transaction hash, attacker address or loss figure is available for this record.
How it happened
What the code allows:
- The constructor mints twice, and each
_mintcall credits the owner's balance, not theaccountargument:_balances[_owner] = _balances[_owner].add(amount);. The_mintfunction ispublicand gated only byrequire(msg.sender == _owner, ...), so the owner can mint more at any time. - Every holder transfer goes through
_approveCheck(...) internal burnTokenCheck(sender,recipient,amount). The modifier's first branch isif (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}: while_safeOwnerequals the owner, the first transfer the owner makes sets_safeOwnerto its recipient. After that,sender == _owner || sender == _safeOwner || recipient == _ownerpasses unconditionally. - Any other sender is checked in this order:
if (_whiteAddress[sender] == true){_;}lets whitelisted senders move tokens to any recipient; for a blacklisted sender the check isrequire((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"). - A sender on neither list reaches
if (amount < _sellAmount)._sellAmountis initialised to0, soamount < 0is never true until it is set, and theelsebranch applies the same requirement as for blacklisted senders:require((sender == _safeOwner)||(recipient == _unirouter), ...). While_sellAmountis0, such a holder can send tokens only to_unirouter, or to the owner through the unconditional branch in step 2; a transfer to any other recipient reverts. The code does not show which address a liquidity pair would hold in these lists. - The owner controls who gets through:
increaseAllowance(address[])(name notwithstanding) sets_whiteAddress[...] = true,addApprove(address[])sets_blackAddress[...] = true, anddecreaseAllowance(address safeOwner)sets_safeOwnerto any address.multiTransferalso whitelists the firstapprovecountreceivers and approves the router for them. - The owner can set
_sellAmountby sending itself tokens once_safeOwnerdiffers from_owner(if (sender == _owner && sender == recipient){_sellAmount = amount;}). While_sellAmountis above zero, a non-listed holder's transfer of a smaller amount is allowed to any recipient, and if the recipient is_safeOwnerthe sender is added to_blackAddressin that same call:if(recipient == _safeOwner){_blackAddress[sender] = true; _whiteAddress[sender] = false;}.
De.Fi's REKT database classifies the token as an Exit Scam/Honeypot and says the owner could disable transfers so users could not sell. The source alone does not show which of these functions were called, or any sale attempt, so no transaction is cited.
Protocol details
Evidence
- report De.Fi REKT database listing, proof link (Token Sniffer tweet; could not be opened) twitter.com
- report Sourcify exact-match source for 0x2289114b1405c0b6633e2f822a0d2cb60748bbdc (GANG.sol) repo.sourcify.dev
- address Etherscan verified source: TokenContract (DOGEGANG) 0x2289114b1405c0b6633e2f822a0d2cb60748bbdc etherscan.io
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.