ORAO Network Honeypot

Reported loss Not disclosed
Ethereum
Honeypot

What happened

ORAO Network (ORAO) is an Ethereum ERC-20 token whose transfers all pass through a burnTokenCheck modifier that treats senders differently. The deployer is the owner, the first address the owner sends tokens to becomes a privileged _safeOwner (on a DEX, typically the liquidity pair), and every other holder can only send tokens to one hard-coded _unirouter address, so a sell into the pair reverts with "ERC20: transfer amount exceeds balance". The owner can whitelist or blacklist holders, change _safeOwner, and set a _sellAmount threshold.

De.Fi's REKT database lists the token as an Exit Scam/Honeypot and describes it as a contract where the owner could disable the transfer function, which restricted users in selling their tokens.

How it happened

  1. The constructor sets _owner = msg.sender; and _safeOwner = msg.sender; and mints 198*1e6*(10**18) tokens (198,000,000 at 18 decimals) to the owner with _mint(_owner, ...).
  2. transfer and transferFrom both call _approveCheck, which is wrapped by burnTokenCheck(sender,recipient,amount). Its first branch is if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}: while the owner and safe owner are the same address, the recipient of the owner's first outgoing transfer becomes _safeOwner. On a DEX that recipient would typically be the liquidity pair.
  3. Next branch: if (sender == _owner || sender == _safeOwner || recipient == _owner) lets the transfer pass with no restriction. That covers the owner, the _safeOwner (a pair pays out buyers through this path) and anyone sending to the owner. Inside it, if (sender == _owner && sender == recipient){_sellAmount = amount;} lets the owner set the _sellAmount threshold by sending tokens to itself.
  4. Every other sender falls to the remaining branches. If _whiteAddress[sender] is true the transfer passes. If _blackAddress[sender] is true it must satisfy require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");, and since sender != _safeOwner here, the recipient must be _unirouter. A sell sends tokens to the pair, not to _unirouter, so it reverts.
  5. An address on neither list reaches if (amount < _sellAmount). With the default uint256 private _sellAmount = 0; this is never true, so the else branch runs the same require and the sell reverts. If the owner has set a threshold, a transfer below it passes and, when recipient == _safeOwner, the sender is added to _blackAddress by _blackAddress[sender] = true; _whiteAddress[sender] = false;; larger amounts revert.
  6. The owner-only list functions carry misleading ERC-20 names: increaseAllowance(address[] memory receivers) whitelists and un-blacklists, addApprove(address[] memory receivers) blacklists and un-whitelists, and decreaseAllowance(address safeOwner) replaces _safeOwner. multiTransfer sends tokens from the owner and whitelists and gives the router a maximum allowance for the first approvecount receivers. _mint is public but requires msg.sender == _owner, so the owner can add to its own balance and the total supply at any time. The contract has no function to renounce or transfer _owner.
  7. What happened: De.Fi's REKT database lists this token as an Exit Scam/Honeypot dated 2021-09-13 with no loss figure. No opened transaction or holder page in this review shows a specific whitelist, blacklist, _sellAmount, _mint or liquidity-removal call, or a failed sell.

Protocol details

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

Build your security review skills

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