BirdSwap Honeypot

Reported loss Not disclosed
Ethereum
Honeypot

What happened

BirdSwap (BIRD) is an Ethereum token deployed on 9 April 2021 at 0x23636350…a11976. Every transfer and transferFrom runs through a modifier, burnTokenCheck, that lets the owner, a designated _safeOwner address and whitelisted wallets move tokens freely, but makes an ordinary holder's transfer revert with the misleading message "ERC20: transfer amount exceeds balance" unless the amount is below an owner-set _sellAmount threshold, which starts at zero. A holder who does sell under the threshold to _safeOwner is blacklisted after that sale.

Owner-only functions disguised with allowance names edit the whitelist and blacklist, and the source claims liquidity is locked for six months, but the "lock" is only three constants with no logic. De.Fi's REKT database lists BirdSwap as an exit scam/honeypot, stating that the contract owner could disable transfers and so stop holders from selling.

How it happened

  1. The constructor sets _owner and _safeOwner to the owner argument and mints the initial supply to it.
  2. The first time _owner sends tokens, if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;} hands the _safeOwner role to that recipient. If that first transfer is the liquidity deposit, the DEX pair becomes _safeOwner, and transfers from it (buys) always pass.
  3. For any other sender, whitelisted addresses pass. A non-whitelisted holder passes only if amount < _sellAmount; otherwise the modifier runs require((sender == _safeOwner)||(recipient == _unirouter), "ERC20: transfer amount exceeds balance"). A sale sends tokens to the pair, not to the hard-coded _unirouter address, so it reverts while _sellAmount is zero.
  4. The owner can raise _sellAmount by sending tokens to itself (if (sender == _owner && sender == recipient){_sellAmount = amount;}). A holder who then sells under that amount to _safeOwner succeeds once and is added to _blackAddress, after which the same require blocks them.
  5. Owner-only increaseAllowance(address[]) whitelists wallets, addApprove(address[]) blacklists them, decreaseAllowance(address) replaces _safeOwner, and multiTransfer sends tokens to chosen wallets and whitelists them. The public _mint(address, uint256) lets _owner add any amount to its own balance while emitting a Transfer to a different address. No function changes _owner after deployment.

Protocol details

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

Build your security review skills

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