German Shepherd Honeypot

Reported loss Not disclosed
Ethereum
Honeypot

What happened

German Shepherd (SHEPHERD) was an ERC-20 token on Ethereum whose transfer and transferFrom both run through a burnTokenCheck modifier. That modifier lets the owner, a designated _safeOwner address and owner-whitelisted wallets move tokens freely, but for every other holder it reverts any transfer unless the recipient is one hard-coded _unirouter address or the amount is below an owner-set _sellAmount. A holder who does send a small amount to _safeOwner is automatically blacklisted.

The revert message reads "ERC20: transfer amount exceeds balance", which hides the real reason. De.Fi's REKT database lists SHEPHERD as an exit scam/honeypot.

How it happened

  1. The constructor mints the whole supply to the owner argument and sets _safeOwner = owner. The first transfer the owner makes then runs if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;}, so the first recipient becomes _safeOwner. The owner can later point it anywhere with decreaseAllowance(address safeOwner).
  2. Transfers from _owner or _safeOwner, or to _owner, always pass: if (sender == _owner || sender == _safeOwner || recipient == _owner). Whitelisted senders also pass. If _safeOwner is the trading pair, buys go through.
  3. For any other holder the modifier falls through to require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance");. A sell sends tokens to the pair, not to _unirouter, so it reverts even though the holder has the balance.
  4. The one exception is if (amount < _sellAmount). _sellAmount starts at 0 and can only be changed by the owner sending tokens to itself (if (sender == _owner && sender == recipient){_sellAmount = amount;}). A holder who sends a sub-threshold amount to _safeOwner is then marked _blackAddress[sender] = true, after which every later transfer hits the same require.
  5. Owner-only functions with misleading names manage these lists: increaseAllowance(address[]) whitelists, addApprove(address[]) blacklists, and multiTransfer sends tokens while whitelisting recipients and approving _unirouter for them. _mint is public and owner-gated with no cap, and there is no function to change or renounce _owner.

Protocol details

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

Build your security review skills

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