Jin Finance Honeypot

Reported loss $277
Ethereum
Honeypot

What happened

De.Fi's REKT database lists JIN (jin.finance) on Ethereum as an exit scam / honeypot with about $277 lost, and states that the deployer removed the initial liquidity in transaction 0x55a99c66…c60e2a. That transaction and the listing's proof tweet could not be opened for this review.

The verified source (0x704d4bDc…b5FdEc) contains a transfer filter that the owner can switch on. The constructor sets both _address0 and _address1 to the owner, which leaves transfers unrestricted. ints(address addressn) lets only _address0 point _address1 at a different address; once _address0 != _address1, every transfer that does not involve the owner and has a non-zero amount reverts unless the sender is _address1, the Uniswap V2 router or an address whitelisted by the owner. Because transferFrom passes the holder as sender, a router-based sell from an ordinary holder reverts under that filter, while the owner (who is exempt as sender or recipient) can still move tokens and liquidity. The owner address is fixed in the constructor and there is no function to transfer or renounce it.

How it happened

  1. The constructor sets _address0 = owner; _address1 = owner; and mints the whole supply to _address0. With both equal, the filter in _ints is inactive, so transfers, buys and sells behave normally.
  2. _transfer calls _ints(sender, recipient, amount) before any balance changes. Its condition is if(recipient != _address0 && sender != _address0 && _address0!=_address1 && amount > _zero){require(sender == _address1 ||sender==_router || _Addressint[sender], "ERC20: transfer from the zero address");}.
  3. The owner can arm the filter with function ints(address addressn) public { require(msg.sender == _address0, "!_address0");_address1 = addressn; }. After any call that sets _address1 to an address other than the owner, _address0!=_address1 is true.
  4. When the filter is armed, a holder selling through the router triggers transferFrom(holder, pair, amount), so sender is the holder. Unless that holder is _address1, the router or whitelisted, the require reverts and the sell fails. The same check applies to any holder-to-holder transfer that does not involve the owner.
  5. The owner can whitelist addresses with multiaddress(uint8 AllowN, address[] receivers, uint256[] amounts): for the first AllowN receivers it sets _Addressint[receivers[i]] = true and approves the router for the maximum amount from that receiver, and only _address0 can call it.
  6. Transfers from or to the owner skip the filter (recipient != _address0 && sender != _address0), so the owner can add and remove liquidity while other holders cannot exit. De.Fi's REKT database lists a liquidity removal by the deployer in transaction 0x55a99c66…c60e2a. No transaction showing a call to ints or multiaddress was opened, so whether and when the filter was armed is not verified here.

Protocol details

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

Build your security review skills

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