MoonElevator Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

MoonElevator (ELEVATOR) is a token on BNB Smart Chain whose transfer logic runs through a burnTokenCheck modifier. Senders who are not the owner, the owner-set _safeOwner, or on the owner's whitelist may only send tokens to the hard-coded _unirouter address or to the owner (amounts below the owner-set _sellAmount are the exception); any other recipient reverts with 'ERC20: transfer amount exceeds balance', although the sender's balance is untouched. The owner can whitelist or blacklist addresses, change _safeOwner, and set a _sellAmount threshold through functions with misleading names.

De.Fi's REKT database lists the token as an Exit Scam/Honeypot and says the owner could restrict users from selling; it gives no loss figure.

How it happened

  1. The constructor sets _owner = owner; _safeOwner = owner; and mints the initial supply to the owner. _mint is public but requires msg.sender == _owner, so the owner can mint more later.
  2. Every transfer and transferFrom calls _approveCheck, which is wrapped in burnTokenCheck(sender,recipient,amount). First branch: if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}. While _safeOwner still equals the owner, the owner's first outgoing transfer stores its recipient as _safeOwner.
  3. Privileged paths pass: if (sender == _owner || sender == _safeOwner || recipient == _owner) lets the transfer through. Inside it, if (sender == _owner && sender == recipient){_sellAmount = amount;} lets the owner set _sellAmount by sending tokens to itself. Anyone can therefore send tokens to the owner address.
  4. For other senders: if (_whiteAddress[sender] == true){ _; } passes with no restriction. A blacklisted sender hits require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"), and since _safeOwner was already handled above, it can only send to _unirouter.
  5. A sender on neither list: if (amount < _sellAmount) the transfer passes, and if recipient == _safeOwner the sender is added to _blackAddress and removed from _whiteAddress (the transfer still completes). Otherwise the same require applies. _sellAmount starts at 0 (uint256 private _sellAmount = 0;), so until the owner raises it no amount is below it, and an ordinary holder can only send to _unirouter or the owner. Any other recipient, such as a pair contract, reverts.
  6. Control sits with the owner: increaseAllowance(address[]) whitelists, addApprove(address[]) blacklists, decreaseAllowance(address safeOwner) replaces _safeOwner, and multiTransfer can whitelist the first approvecount receivers and give them an unlimited allowance to _unirouter. The code has no function that changes _owner or renounces it.
  7. What happened on-chain is not established here: no opened source shows who was whitelisted or blacklisted, what _safeOwner or _sellAmount held, or any losses.

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract ELEVATOR

Build your security review skills

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