Kwikswap Honeypot

Reported loss Not disclosed
Ethereum
Honeypot

What happened

This "Kwikswap" (KWIK) token was deployed on Ethereum on 21 May 2021 at 0x00e25f0f…cf5bf9 by 0x72cbDFB9…6A5820. It copies the name and symbol of the Kwikswap protocol's token, which Etherscan lists at 0x286C0936…5d229D. Every transfer and transferFrom runs the burnTokenCheck modifier.

The owner's first outgoing transfer, normally the one that seeds the Uniswap pool, makes the recipient _safeOwner, and transfers from _safeOwner always pass, so buys out of the pool work. A transfer from an ordinary holder passes only if it goes to the Uniswap V2 router, to the owner, or is smaller than _sellAmount, which starts at zero and only the owner can raise; a holder who sells below that threshold into _safeOwner is blacklisted. The owner also has an uncapped _mint and owner-only functions, under misleading names, that whitelist, blacklist and replace _safeOwner.

De.Fi's REKT database lists the token as an exit scam/honeypot.

How it happened

  1. The constructor sets _owner = owner and _safeOwner = owner and mints the supply to the owner. _unirouter is hard-coded to 0x7a250d56…F2488D, the Uniswap V2 router.
  2. In burnTokenCheck, if (_owner == _safeOwner && sender == _owner){_safeOwner = recipient;_;} means the owner's first outgoing transfer, such as adding liquidity, makes that recipient (the pair) _safeOwner.
  3. Transfers pass unchecked when sender == _owner || sender == _safeOwner || recipient == _owner, so the pair can pay out tokens to buyers.
  4. For any other sender that is not whitelisted, if (amount < _sellAmount) is the only open path. _sellAmount starts at 0 and is set only when the owner transfers to itself (if (sender == _owner && sender == recipient){_sellAmount = amount;}). Otherwise the modifier requires (sender == _safeOwner)||(recipient == _unirouter), and a sale sends tokens to the pair, not the router, so it reverts with the disguised message "ERC20: transfer amount exceeds balance".
  5. If the owner does raise _sellAmount, a holder who sends a smaller amount to _safeOwner is marked with _blackAddress[sender] = true, and blacklisted senders face the same router-only requirement afterward.
  6. The owner-only functions increaseAllowance(address[]) (whitelist), addApprove(address[]) (blacklist), decreaseAllowance(address) (sets _safeOwner) and multiTransfer (sends tokens and whitelists recipients) decide who can sell. _mint is public but restricted to _owner and adds any amount to the owner's balance.

Protocol details

Classification Exchange (DEX)
Protocol Type DEX
Affected asset / contract KWIK
Protocol links @kwikswapdex

Build your security review skills

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