Honeypot Token Detection: Case Files from BSC and ETH

DeFi has taught me to treat every new token like a suspicious package. If you have traded long enough on PancakeSwap or Uniswap, you have met the dreaded token you can buy but never sell. That is the honeypot. It hides the trap behind friendly branding, a busy Telegram, or even a fake CertiK badge on the site. Let me walk through how I analyze these on BSC and Ethereum, with practical examples and the habits that keep me out of trouble.

What a honeypot actually is

A honeypot token is a contract that appears to trade normally, but enforces a covert restriction so holders cannot exit. Sometimes the restriction is total, reverting every sell; sometimes it is economic, taxing sells at 70 to 100 percent so the seller eats all the slippage. The trick often sits inside the token’s transfer logic, the DEX router allowance path, or an owner-only function that flips behavior after launch.

Most buyers never read the code. Scammers know that, so they rely on code patterns that slip past a casual Etherscan contract check. A good honeypot token checker can catch many, but not all. You still need to know the manual tells.

Case file 1: BSC blacklist plus dynamic tax

BSC has a steady stream of fee-on-transfer tokens. The pattern I see weekly is a PancakeSwap pair, a few minutes of liquidity, and a soft launch inside a Telegram. The code looks benign on BscScan at first glance, often using OpenZeppelin’s ERC20. Then you scroll down and see a custom _transfer:

Function _transfer(address from, address to, uint256 amount) internal override Require(!isBlacklisted[from] && !isBlacklisted[to], "blocked"); Uint256 tax = 0; If (isMarketPair[to]) // selling to the pair If (!isExcludedFromFee[from]) Tax = amount * sellTax / 100; else if (isMarketPair[from]) // buying from the pair If (!isExcludedFromFee[to]) Tax = amount * buyTax / 100; Super._transfer(from, address(this), tax); Super._transfer(from, to, amount - tax);

So far, normal. Then a privileged setter:

Function setFeeTx(uint256 _buy, uint256 _sell) external onlyOwner Require(_sell <= 100 && _buy <= 100, "too high"); SellTax = _sell; BuyTax = _buy; <p> On launch, sellTax is modest, like 10. After the first volume spike, the owner or a hidden role cranks sellTax to 95 or 100. Buyers panic and try to exit, but the tax drains them into the contract. The team then swaps the tax tokens for BNB through the router and pulls the BNB.

I have also seen a double trap, where a blacklist is silently populated:

Function setBots(address[] calldata wallets, bool value) external onlyOwner For (uint i; i < wallets.length; i++) IsBlacklisted[wallets[i]] = value;

They run this right before the sell wave hits. The BscScan write tab often shows these functions sitting in plain sight. The tell is activity on setFeeTx right before a price dump, plus events that mark blacklist additions. This is where a safe token scanner can help, but your eyes on the write functions are faster.

Two forgery tricks are common on BSC:

    Fake renounce: renounceOwnership() calls do not actually set owner to the zero address. Some contracts override renounceOwnership to set a shadow role or keep a second admin mapping. If ownership is “renounced” yet someone can still call setFeeTx, that is your answer. Exemption list: a hidden role can bypass fees, trade without limits, and dump into the pool while others get taxed into oblivion. Inspect isExcludedFromFee mappings on the Read tab.

In these setups, a bsc honeypot check sometimes flags abnormal sell paths. If the checker fails, simulate a swap with a Tenderly fork or use PancakeSwap with high slippage in a test wallet and tiny size. Watch for a revert or a 90 percent loss.

Case file 2: ETH sell reverts behind anti-bot logic

Ethereum honeypots often hide behind anti-MEV or “bot protection” claims. The code delays trading, tracks first block buyers, and enforces cool-downs. Some parts are legitimate, but look for sells that require a whitelist or special router.

I have seen this a lot in Uniswap v2 forks:

Mapping(address => bool) public allowedSellers; Mapping(address => bool) public isMarketPair; Bool tradingOpen; Function _transfer(address from, address to, uint256 amount) internal override If (!tradingOpen) If (isMarketPair[to]) Require(allowedSellers[from], "no sell"); Super._transfer(from, to, amount);

They whitelist their own wallets, then open trading. Buyers can only buy because isMarketPair[from] lets them in, but sells revert with “no sell.” After enough volume, liquidity is pulled or the team sells from the whitelisted wallets into trapped demand.

You can spot this on Etherscan by checking allowedSellers in the Read tab. If it is empty, tread carefully. If it is populated only with owner and deployer wallets, you know what is coming. On DexScreener, you might see volume, but the sell side looks strangely muted or concentrated from a few addresses.

Another ETH variant uses the transferFrom path to trap DEX routers. Uniswap’s router uses transferFrom when taking tokens from your wallet for a sell. A honeypot can allow direct transfer, but fail transferFrom with a subtle condition, usually a gas check or a timestamp rule. Manual wallet to wallet transfers look fine, so naive testers miss it. A quick way to test is to approve the token and try a tiny swap out. If transferFrom fails or the gas spikes into absurd territory, it is suspect.

Case file 3: Proxy upgrade bait and switch

Some projects deploy a clean implementation, pass a community sniff test, maybe even a light smart contract audit. They then upgrade the proxy to a malicious implementation after TVL builds up.

Look for the TransparentUpgradeableProxy pattern on Etherscan. There will be an Admin slot, an Implementation slot, and an upgradeTo function in proxy admin. If you see an Upgrade event after trading went live, review the new implementation. I have caught honeypots where the original code had plain OpenZeppelin logic, then the new implementation added a setFeeTx, a blacklist, or a sell-only whitelist. A seasoned firm like Consensys Diligence or PeckShield often warns that upgradable tokens keep centralization risk long past launch.

If the team claims “ownership renounced” but the proxy admin is still active, your sell rights are one admin transaction away from disappearing.

How I manually check a token before buying

Here is the routine I follow in the first two minutes. It has saved me far more than any automated crypto scam detection tool:

    Pull the token on Etherscan or BscScan. Verify source, proxy status, and if the compiler settings match the verified code. Scan the Read and Write tabs for functions like setFeeTx, setBots, setMaxTxAmount, setMaxWallet, enableTrading, and any custom renounceOwnership. Open the Holders tab. If the top wallet controls most of the supply or the LP tokens are in the deployer wallet, pass. Look for LP locked in a known locker or burned to the zero or dead address. Check the Pair on DexScreener. Confirm the liquidity size, age of pool, and trade distribution. Sudden walls of buys with no sells are a red flag. Test a simulated sell. Approve the token in a throwaway wallet and try a tiny sell with reasonable slippage. If it reverts, spikes gas, or requires 50 percent slippage, walk away. Skim X for mentions by on-chain sleuths. Reputable accounts often flag honeypots early. Security firms like PeckShield and Hacken regularly post alerts.

Reading the code like an auditor

You do not need to be a Solidity expert to spot the big red flags.

Start with the transfer logic. Any custom code wrapping _transfer or transferFrom deserves time. Require statements that single out pair addresses, the router, or a mapping like allowedSellers usually control whether you can dump into the pool. If you spot a condition that blocks transfers when to == pair or when block.number < launchBlock + N, sellers are at the mercy of an owner or a timer.

Next, review ownership and roles. Many tokens rely on OpenZeppelin’s Ownable. That is fine. The problem is when the owner controls fee setters, trading toggles, or a blacklist without time locks. Some contracts implement AccessControl and hide a role called FEE_ROLE or MARKET_ROLE that allows changing taxes after launch. If the project brags about “renounced,” search for an actual owner at zero address and no proxy admin. If there is a proxy, renouncing the implementation owner is meaningless while the proxy admin remains.

Proxies deserve special attention. On Etherscan, click through the proxy to the implementation. If the code is unverified at any point, assume worst case. Upgrades soon after liquidity adds are a pattern. Security firms such as CertiK and Consensys routinely emphasize upgrade governance and timelocks for exactly this reason.

Finally, check approval and allowance pitfalls. A clever click here honeypot will accept approve, then throw on transferFrom with a crafted revert. Some check the remaining allowance against a fake max limit or inject a fee so high that the router cannot compute outputs under your slippage. If your honeypot token detection routine never tests transferFrom, you will miss this class.

Economic traps that are not pure reverts

Not every trap is a straight revert. Some simply make selling non-economic. I have seen:

    Dynamic sell tax that spikes to 80 to 100 percent after a volume milestone. Max sell amount that is set to near zero, so you need hundreds of transactions to exit, each paying gas and tax. Sandwich honeypot, where the project runs a private backrun that soaks your sells into a tax wallet, then dumps tax tokens into the same block. It looks like “market activity,” but liquidity migrates to the tax wallet and the chart bleeds.

A good honeypot crypto scanner may label these as “high tax” or “suspicious fees,” but it might not catch conditional spikes. On CoinGecko, tokens with shifting taxes often fail listing or trigger warnings. Do not treat a listing as a stamp of safety.

image

A short walk-through on BSC: checking a live pair

Imagine a fresh BSC token with 50 BNB liquidity. The site links to BscScan, code verified. I open the contract, control-F for “fee,” “tax,” “blacklist,” and “pair.” I see setFeeTx and a setBots function. Ownership is not renounced, and LP tokens sit in the deployer wallet, not a locker.

On DexScreener, trades look one-sided. The sell volume is a handful of small exits, mostly from one wallet. That wallet appears in isExcludedFromFee. The team claims an audit in the banner, but the report is a PNG with the logo of a known firm. I check the firm’s site, no such report. At this point, I do not need a safe token scanner to decide. I pass.

A short walk-through on Ethereum: tracing a failed sell

On ETH, I grabbed a small bag of a trendy token in a test wallet. Buy went through. I tried to sell 0.01 ETH worth, and the transaction reverted with “no sell.” Etherscan’s “Click to see more” shows the failing call was transferFrom. I ran a Tenderly simulation. The trace stopped at a require checking allowedSellers[msg.sender] == true. The mapping was empty on Etherscan. Classic sell whitelist. I burned the remainder by sending to the zero address and chalked the gas up to tuition.

This is why a check if token is scam mindset is not paranoid. It is practical.

Red flags I do not ignore on explorers

    Unverified implementation behind a proxy, or a recent proxy upgrade around launch time. Owner retains fee setters, blacklist, or trading toggles with no timelock or multisig, and no clear plan to remove controls. LP tokens not locked or burned, or LP held by deployer. Suspicious renounce where owner() is zero but a separate admin mapping still exists, or a proxy admin remains active. Sells clustered from a small set of whitelisted or fee-exempt wallets while others show failed transactions.

What scanners and audits can and cannot do

A reputable audit from firms like CertiK, PeckShield, Hacken, or Consensys is a positive, but audits are snapshots. Upgrades, parameter changes, or stealth roles can reintroduce risk. Community on-chain sleuths on X often spot live abuse faster than any PDF report. Use both.

Automated honeypot token checker tools are helpful. They simulate swaps, detect blacklist functions, and flag abusive taxes. Still, some contracts throttle behavior based on block numbers, sender classes, or a “launch phase” switch. A checker that buys and sells on its own address may pass, while you fail. Treat tools as a first pass, not a green light.

Practical habits that reduce pain

Trade with a test wallet, not your main. Avoid buying right on launch, give it time to reveal behavior. Favor contracts with source verified, no proxy or a well-governed upgrade path, LP locked, and ownership renounced in a way that is meaningful. When in doubt, back off. There is always another chart.

DeFi moves fast. Scammers move faster. A solid routine, a quick explorer review, and a small test trade save you from the token that looks alive but will not let you leave. That is how you practice defi safety every day without turning it into a full-time job.