CFInu Honeypot

Reported loss Not disclosed
BNB Chain
Honeypot

What happened

De.Fi's REKT database lists CFInu (Chinese Floki Inu) on BNB Chain as an exit scam/honeypot and describes the owner as able to disable the transfer function so that users could not sell. In the verified source, transferFrom runs a contextHandler modifier that lets the deployer-owner through and gates everyone else. A non-owner sender reverts outright when swapAndLiquifyEnabled is true, and otherwise only passes while the sender's whole balance is below _maxTrxLimit, a threshold the owner can change to any value with setMaxTrxLimit.

Plain transfer has no such check. The sources opened do not include a transaction for this token, so whether the owner changed these settings, held the liquidity or removed it is not established here.

How it happened

  1. The constructor sets owner = msg.sender, starts with swapAndLiquifyEnabled = false, sets _maxTrxLimit = 50000 * 10**15; and gives the whole supply to the owner with balances[owner] = _totalSupply;. With 8 decimals the limit is 5e11 tokens, 0.5% of the 1e14-token supply (10000000 * 10**15).
  2. Two owner-only setters have no bounds: function setSwapAndLiquifyEnabled(bool _swapAndLiquifyEnabled) onlyOwner public and function setMaxTrxLimit(uint _input) onlyOwner public. Despite its name, renounceOwnership(address _newOwner) only writes currentOwner, which no access check reads. onlyOwner tests msg.sender == owner || msg.sender == nxOwner and no function assigns either, so control stays with the deployer.
  3. transferFrom carries contextHandler(from, to). When from == owner, the modifier does nothing. When from != owner and swapAndLiquifyEnabled is true, require(from == owner, "Order ContextHandler"); always reverts. When from != owner and it is false, require(balances[from] < _maxTrxLimit , "Order ContextHandler"); compares the sender's entire balance, not the amount sent, so any holder with a balance at or above the limit cannot call transferFrom.
  4. Spending an allowance, which is how a router moves a holder's tokens in a sale, uses transferFrom, so it hits this gate. transfer has no check, so direct wallet-to-wallet moves and transfers out of a pool are not gated by the modifier.
  5. The owner can call setMaxTrxLimit(0): balances[from] < 0 is never true for a uint, so every non-owner transferFrom reverts. setSwapAndLiquifyEnabled(true) has the same effect. The owner is exempt in both cases. The code allows this; no transaction opened here shows it was done.
  6. burnTokens does the opposite of its name: balances[msg.sender] = balances[msg.sender] + (_input); with emit Transfer(address(0), msg.sender, _input); adds any amount to the owner's balance and leaves _totalSupply unchanged, so the owner can mint without limit. No transaction opened here shows it was used.

Protocol details

Classification Token
Protocol Type Exit Scam/Honeypot
Affected asset / contract Chinese Floki Inu

Build your security review skills

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