Scaleswap Honeypot

Reported loss Not disclosed
Ethereum
Honeypot

What happened

Scaleswap (SCA) is an ERC-20 token on Ethereum, deployed 2021-06-25 at 0xb552898c…eb10b7, with a supply of 25,000,000 tokens. Every transfer passes through a modifier, burnTokenCheck, that lets the owner and a stored _safeOwner address move tokens freely but restricts every other sender to sending only to the Uniswap V2 router (_unirouter). A holder's sell moves tokens to the trading pair rather than to the router, so it reverts with "ERC20: transfer amount exceeds balance", while the owner can whitelist addresses, blacklist others, raise a small-transfer threshold and mint more supply.

De.Fi's REKT database lists SCA as an Exit Scam/Honeypot with no loss figure.

How it happened

What the code allows (the owner is _owner, set once in the constructor; the contract has no function that changes it):

  1. The constructor sets _owner = owner; _safeOwner = owner; and mints initialSupply*(10**18) to the owner. _unirouter is hard-coded as 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D, and _sellAmount starts at 0.
  2. transfer and transferFrom both call _approveCheck, which runs the burnTokenCheck modifier. While _owner == _safeOwner, any transfer from the owner takes the first branch, _safeOwner = recipient;. In a normal liquidity add the owner's first transfer goes to the pair, which would make the pair _safeOwner. From then on _owner != _safeOwner.
  3. Second branch: if sender == _owner || sender == _safeOwner || recipient == _owner the transfer passes. If the pair is _safeOwner, this is why a buy, which sends tokens out of the pair, succeeds. if (sender == _owner && sender == recipient){_sellAmount = amount;} also lets the owner set a threshold by sending to itself.
  4. Every other sender: if _whiteAddress[sender] == true the transfer passes. If _blackAddress[sender] == true, it requires (sender == _safeOwner)||(recipient == _unirouter) or reverts with "ERC20: transfer amount exceeds balance". If the sender is on neither list and amount < _sellAmount, the transfer passes, and if recipient == _safeOwner the sender is blacklisted by _blackAddress[sender] = true;. Otherwise it reverts unless recipient == _unirouter.
  5. With _sellAmount at its initial 0, amount < _sellAmount is never true, so an ordinary holder can send tokens only to the router address. A sell through a router calls transferFrom(holder, pair, amount), whose recipient is the pair, so it reverts. Plain wallet-to-wallet sends revert for the same reason.
  6. The owner-only functions increaseAllowance(address[]) (whitelists and un-blacklists), addApprove(address[]) (blacklists and un-whitelists) and decreaseAllowance(address safeOwner) (rewrites _safeOwner) change who passes. multiTransfer whitelists the first approvecount receivers and approves the router for them.
  7. _mint(address account, uint256 amount) public requires msg.sender == _owner and adds amount to _balances[_owner], so the owner can increase supply at any time.

De.Fi's REKT database lists SCA as an Exit Scam/Honeypot with no stated loss. No transaction was examined here, so which address became _safeOwner, which addresses were whitelisted or blacklisted, and whether any mint or liquidity removal occurred are not established.

Protocol details

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

Build your security review skills

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