HolderFinance Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

HolderFinance (HFI) is a BNB Smart Chain token contract deployed on 2021-06-02 by 0x529aECE1…6Df103 in transaction 0x1667983d…b6cdb0. De.Fi's REKT database lists it as an Exit Scam/Honeypot, noting that the contract owner could disable the transfer function, which restricted users in selling their tokens. In the verified source, an owner-only setTracing switch turns on a check in transferFrom that records the recipient of the first call as nxOwner and then reverts every later transfer to that address; if the recorded address is the liquidity pair, router sales revert.

The constructor also sends half of the 1,000-token supply to the dead address while totalSupply() still reports 1,000. The code shows what the owner can do; no transaction showing setTracing being called was opened for this entry.

How it happened

  1. The constructor sets balances[owner] = _totalSupply (1000 * 10**9, 9 decimals) and calls transfer(dead, burnedAmount) with 500 * 10**9, moving half to 0x00000000…00dEaD. totalSupply() returns _totalSupply.sub(balances[address(0)]), so it still reports the full 1,000 tokens.
  2. tracing is false by default. setTracing(bool _tracing) can flip it, and onlyOwner accepts msg.sender == owner || msg.sender == nxOwner.
  3. With tracing on, transferFrom runs contextHandler(from, to): if(from != address(0) && nxOwner == address(0)) nxOwner = to; else require(to != nxOwner, "Order ContextHandler");. The first transferFrom after tracing is enabled succeeds and stores its recipient as nxOwner; every later transferFrom to that address reverts.
  4. A router sale pulls the holder's tokens into the pair with transferFrom(holder, pair, amount). If the pair is the stored nxOwner, every later sale reverts. transfer has a matching requestHandler that applies require(to != nxOwner, "Handling Request") while tracing is on.
  5. A buy is a transfer from the pair to the buyer, which stays allowed unless the buyer is nxOwner. The address stored as nxOwner also passes onlyOwner, so it can call setTracing and emitTransfer.
  6. emitTransfer(uint256 _input) is onlyOwner and does balances[msg.sender] = balances[msg.sender] + (_input) without touching _totalSupply, so an authorised caller can raise its own balance and emit a Transfer event from the zero address.
  7. renounceOwnership(address _newOwner) is public and unrestricted but only writes currentOwner, which no access check reads; no function reassigns owner.
  8. What the code allows is separate from what happened: De.Fi's REKT database lists the token as a honeypot, but no transaction showing setTracing, the value stored in nxOwner or a failed sale was opened.

Protocol details

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

Build your security review skills

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