dogejavu.com Honeypot
What happened
dogejavu.com (DOGEJAVU) is a token on BNB Smart Chain whose transferFrom function, which transfer also calls, only lets four kinds of sender move tokens: the owner, any transfer addressed to the owner, the stored tradeAddress, and addresses the owner marks in canSale. Every other sender reaches require(condition(_from, _value)). condition returns false whenever the three limit variables _saleNum, _minSale and _maxSale are all zero, and the source has no function that sets them.
A holder's sale into a pool, or a transfer to another wallet, therefore reverts. Whether the pool was allowed to send tokens out to buyers depends on whether the owner called transferownership or approveAndCall for it; the code permits this, but no transaction was opened. De.Fi's REKT database lists DOGEJAVU as an Exit Scam/Honeypot and says the contract owner could disable the transfer function, which restricted users in selling their tokens.
No loss amount is listed there.
How it happened
- The constructor sets
owner = msg.senderand mints the full supply to that account (totalSupply = _supply*(10**uint256(decimals)), 18 decimals; the on-chain supply is 100,000,000 tokens). The source has no function that changesowner;transferownershiponly setstradeAddress. transferforwards totransferFrom(msg.sender, _to, _value).transferFromreturns early for zero values, then callsrequire(ensure(_from, _to, _value))before moving balances.ensurelets a transfer through only if_from == owner || _to == owner || _from == tradeAddress||canSale[_from]. Any other sender must satisfyrequire(condition(_from, _value)).conditionbeginsif(_saleNum == 0 && _minSale == 0 && _maxSale == 0) return false;. The variables_saleNum,_minSaleand_maxSaleareprivateand the source never assigns them, so they stay zero andconditionreturns false for every non-exempt sender. A holder who sells (router callstransferFrom(holder, pool, amount)) or sends tokens to another wallet fails therequireand the transaction reverts. Sending tokens to the owner is the one transfer by an ordinary holder that passes (_to == owner).- The owner can exempt addresses.
transferownership(address addr)setstradeAddress = addr, andapproveAndCall(address spender, uint256 addedValue)setscanSale[spender]=true. Either lets that address send tokens, which is what a liquidity pool needs for buys to work. Which addresses, if any, were exempted was not checked against a transaction. approveAndCallalso containsif(addedValue > 0) {balanceOf[spender] = addedValue*(10**uint256(decimals));}. It overwrites the target's balance with a value the owner chooses and does not changetotalSupply. This is a balance-creation power; no transaction was opened showing it was used.- The source header comment says all tokens were locked in a PancakeSwap pool and the keys burned. The code contains no function that renounces or reassigns
owner, and the owner keeps thecanSale,tradeAddressand balance-setting powers described above.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.