Keep3r.info Honeypot

Reported loss $2K
Ethereum
Honeypot

What happened

keep3r.info (KP3RI) is an ERC-20 whose _transfer calls a check named _ints. While the owner address and a second control address _address1 are equal, the check does nothing. Once the owner calls ints(addr) with a different address, every transfer is checked: unless the owner address is the sender or the recipient, the sender must be _address1, the Uniswap router, or an address the owner whitelisted through multiaddress, otherwise the transfer reverts.

Which holders or pool transfers that blocks therefore depends on which address _address1 is set to. Etherscan shows the deploying address 0x228aB8bB…1aE83B added 41,800 KP3RI and 50 ETH of liquidity at 07:44:49 UTC on 2020-12-08 (tx 0xc9f0c6b0…bd7bdd) and removed liquidity at 14:11:20 UTC, receiving 38,354.97 KP3RI and 54.43 ETH (tx 0x19dceefc…a25033). De.Fi's REKT database lists the token as an exit scam / honeypot with 2,457 USD lost and states the owner could disable the transfer function so users could not sell.

No transaction calling ints was opened, so the code shows a sender restriction was possible, not that it was switched on.

How it happened

  1. The constructor sets _address0 = owner; and _address1 = owner; from its owner argument, so the check in _ints starts disabled because its condition includes _address0!=_address1.
  2. ints(address addressn) can only be called by _address0 and sets _address1 = addressn;. Pointing _address1 at any address other than _address0 arms the check; pointing it back at _address0 disarms it.
  3. Once armed, _transfer calls _ints(sender, recipient, amount), which runs require(sender == _address1 ||sender==_router || _Addressint[sender], "ERC20: transfer from the zero address"); whenever recipient != _address0 && sender != _address0 && amount > _zero. So a transfer between two addresses other than the owner address goes through only if the sender is _address1, the Uniswap V2 Router 2 address, or a whitelisted address. A holder selling through the router is the sender of the pair-bound transfer, so that sale reverts unless the holder is _address1 or whitelisted. Whether a transfer coming out of the pair (a buy) passes depends on whether the pair address is _address1 or whitelisted; the source does not show which address _address1 was set to.
  4. The owner address is exempt as a sender or a recipient: sender != _address0 is false when it sends, and recipient != _address0 is false when it receives. multiaddress(AllowN, receivers, amounts) lets _address0 send tokens to a list and, for the first AllowN entries, set _Addressint[receivers[i]] = true; and _approve(receivers[i], _router, _valuehash);, giving those addresses sell access and giving the router an unlimited allowance over their balances.
  5. On 2020-12-08 the deployer address added liquidity at 07:44:49 UTC (tx 0xc9f0c6b0…bd7bdd) and called removeLiquidityETHWithPermit at 14:11:20 UTC, receiving 38,354.97 KP3RI and 54.43 ETH (tx 0x19dceefc…a25033).

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract KP3RI
Protocol links Website

Build your security review skills

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