THANKS ELON Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

THANKS ELON is a BNB Smart Chain token whose transferFrom is restricted by a switch, trans, that starts as false. While it is off, transferFrom only succeeds when the deployer is the sender or the recipient, or when the sender is the token's own liquidity pair, so a holder's swap through a router, which moves tokens with transferFrom, reverts. Only an account with MINTER_ROLE can turn the switch on with setTrans.

The functions renounceOwnership() and lockLiquidity() only emit events and change no state. De.Fi's REKT database lists THANKS ELON as an Exit Scam/Honeypot in which the contract owner could disable transfers and so restrict holders from selling.

How it happened

  1. The constructor stores the deployer in moi, sets trans = false, gives the deployer DEFAULT_ADMIN_ROLE, PAUSER_ROLE and MINTER_ROLE, mints 1000000000000 * 10 ** decimals() tokens to the deployer, and creates the token's pair on the router at the hard-coded address 0x05fF2B0D…608C7F, storing it in the immutable uniswapV2Pair.
  2. transferFrom is overridden with this gate: require (trans || moi == sender || moi == recipient || sender == UNI); where UNI is uniswapV2Pair. While trans is false, a transferFrom passes only if the deployer is the sender or recipient, or if the pair is the sender.
  3. A holder who swaps tokens for BNB through a router makes the router call transferFrom(holder, pair, amount). The holder is not moi, the recipient is the pair rather than moi, and the sender is not the pair, so the require fails and the sell reverts while trans is false. Buys, where the pair is the sender, and transfers involving the deployer are not blocked by this line.
  4. Plain transfer is not overridden and is not gated by trans, so holder-to-holder transfers made with transfer are not stopped by this check.
  5. Only setTrans(bool value) changes the switch, and it requires MINTER_ROLE: require(hasRole(MINTER_ROLE, msg.sender)); trans=value;. The deployer holds that role from the constructor, and DEFAULT_ADMIN_ROLE can grant it to others.
  6. Other owner-side powers: piocher(address to, uint256 amount) mints new tokens for any MINTER_ROLE holder, and pause()/unpause() (PAUSER_ROLE) toggle a pause that _beforeTokenTransfer enforces through whenNotPaused, which blocks all transfers.
  7. renounceOwnership() (emit OwnershipRenounced(address(0), address(this));) and lockLiquidity() (emit liquidityLocked(uniswapV2Pair, address(0));) contain only emit statements. They write nothing to storage and revoke no role, so calling them gives no on-chain effect other than the event.
  8. These are the powers the code allows. The code alone does not show whether trans was ever turned on, whether piocher or pause was called, or who holds the liquidity tokens.

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract THANKS ELON

Build your security review skills

Work through hands-on labs covering real exploit mechanics, review techniques, and defensive patterns.