Laugh Out Loud Honeypot
What happened
Laugh Out Loud (LOL) is a BNB Smart Chain token whose internal _transfer reverts any transfer between two non-owner addresses unless the sender is the stored pancake address, and the owner can switch that check off with setTIME. The revert message claims "YOU CAN ONLY SELL 1 Sale PER 30 MIN", but the code contains no timer: the check is a plain sender test. A holder selling to the pair is a transfer from a non-owner, non-pancake address, so it reverts while the switch is on.
De.Fi's REKT database lists LOL as an Exit Scam/Honeypot in which the contract owner could disable transfers and so restrict holders from selling.
How it happened
- The constructor mints the whole supply (
_mint(msg.sender, 100000000000000e18)) to the deployer, who is theowner. The private flagTIMEis initialised totrue. - Whenever the owner is the sender,
_transferstores the recipient:if(sender == owner()){ pancake = recipient; }. The owner can also set it directly withaddPancake(address). - The trap line is
if(sender != owner() && recipient != owner() && sender != pancake && TIME == true){ revert("FOR VALUE PROTECTION, YOU CAN ONLY SELL 1 Sale PER 30 MIN"); }. A holder who sends tokens to anyone other than the owner, including to a liquidity pair, is a non-owner sender that is notpancake, so the call reverts. Transfers frompancake(for example buys, ifpancakeis the pair) and transfers to or from the owner pass. The code does not show which addresspancakeholds. - No timestamp is compared.
saveTransData(sender, block.timestamp)writestransData[sender], but nothing in the contract readstransData, so the "1 sale per 30 min" wording is not backed by logic. - The owner can lift or restore the block with
setTIME(bool). Separate owner-only levers exist:GTYA(address,bool)flags a sender inbot, and a flagged sender then hitsrequire(amount <=0, "bots......"), which cannot pass because_transferalready requiresamount > 1000.POOLandfireset theSWAPaddresses and theMAXcap checked asrequire(amount <= MAX, ...)for transfers to them whilesecurityis on, andsetFeeallows a fee of up to 10% (_newTxFee <= 100withamount.mul(txFee).div(1000)). renounceOwnership()exists, so the owner can give these powers up. The code alone does not show whether or when any of them was used.
Protocol details
Build your security review skills
Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.