Inside the analyzer: 52 on-chain signals, 8 dimensions, scored on every new Ethereum ERC-20

The full methodology behind RektRadar's 0-100 risk score: 8 analyzers (honeypot simulation, deployer history, bytecode similarity, liquidity, distribution, swap activity, deployer network, Etherscan patterns), 52 individual signals, applied to every new ERC-20 deployed on mainnet.

We run a scoring pipeline on every ERC-20 contract created on Ethereum mainnet. New token deployed at block N - we have a 0-100 risk score and a flag list within seconds.

This post is the methodology behind that number. 8 analyzers, 52 individual signals, the heuristics each one uses, and the trade-offs we accept (false positives and false negatives we know about).

The signal catalogue is also publicly browsable at rektradar.io/signals - one page per signal with the technique and rationale.

The 8 analyzers

Each analyzer is an independent module that returns a riskScore + a list of riskFlags. The aggregate score is a weighted sum capped at 100, with a flag-count floor (6+ flags = at least 70, 5 = at least 60, etc.) so we don’t return a misleading low score when a token has many smaller red flags.

AnalyzerSignalsTechnique
honeypot10eth_call simulation of buy / sell / transfer on a local fork
deployer9Deployer wallet history: age, prior deployments, prior scams
etherscan7Source-code verification + regex patterns on Solidity source
liquidity7LP token concentration, bundling, lock / burn status
swap_activity7Buy/sell ratio from on-chain swap events
network5Deployer-funder graph: mass deployers, mixer funding, serial scammers
bytecode4Function selectors + known scam hashes for unverified contracts
distribution3First Transfer events: holder concentration, distribution skew

Below is the technique each one actually uses. No marketing - this is what runs in production.

honeypot - eth_call simulation

The honeypot analyzer simulates a buy + a sell on the token’s Uniswap V2 pair (V3 as fallback) using eth_call against a forked state. We override the simulator’s ETH balance to 1000 ETH and use a non-zero gas price to defeat contracts that branch on tx.gasprice == 0 to detect simulation.

The flow:

  1. Find the V2 pair via IUniswapV2Factory.getPair(token, WETH). If absent, try V3 fee tiers [3000, 10000, 500, 100].
  2. Simulate swapExactETHForTokensSupportingFeeOnTransferTokens with a small ETH input.
  3. Capture the token output. Compute the implied buy tax (input vs output ratio).
  4. From the simulator address, simulate approve(router, MAX) + swapExactTokensForETHSupportingFeeOnTransferTokens for the token amount.
  5. If the sell call reverts → sell_blocked or sell_failed flag. If it succeeds but extracts less than 50 percent of value → extreme_sell_fee. If between 50 and 90 percent → elevated_sell_fee / moderate_sell_fee.

Signals from this analyzer include honeypot, buy_failed, sell_blocked, sell_failed, buy_only_pattern, amount_dependent (buy works at small amounts but fails at larger ones - common max-tx pattern), and the three sell-fee tiers.

Known limits

  • False positives: tokens with anti-bot cooldowns or temporary whitelists that simulate-fail in the first few blocks but trade fine after. We re-score these later via the swap_activity analyzer.
  • False negatives: time-delayed honeypots that flip after N transactions, owner-triggered kill switches, blacklist-on-demand. Static simulation can’t catch these - we rely on the deployer + network analyzers for that.

deployer - wallet history graph

For every token, we look up the deployer wallet and check four things:

  1. Age: block of the wallet’s first outgoing transaction (first_tx_block). Wallets less than ~24h old funding a deployment are fresh_deployer_funded, less than 7 days = new_wallet.
  2. Prior deployments: count of contracts deployed by this wallet. >5 = mass_deployer. >80% of the wallet’s tx history being contract creation = mostly_deploys_contracts (this catches dedicated deployer wallets that never trade).
  3. Prior scams: lookup in our own token_analysis table for previous tokens by the same deployer that scored ≥70. 3+ prior scams = serial_scammer (the heaviest deployer flag, 40 points).
  4. Funder chain: deployer → first funder → first funder, up to 2 hops. If any node in the chain is a Tornado Cash deposit address (or other mixer), we flag mixer_funded / tornado_funded.

The data for steps 1 and 2 comes from a graph-crawler service that maintains a deployer→funder graph in real time using trace_filter calls on a local Erigon node.

bytecode - selector heuristics for unverified contracts

When the contract isn’t verified on Etherscan, we work directly on the deployed bytecode. We extract the function selectors (first 4 bytes of each JUMPI target preceded by PUSH4) and check them against a curated list of suspicious selectors:

0x44337ea1  blacklist(address)
0x0ecb93c0  blacklistAddress(address)
0x8a8c523c  pause()
0x83197ef0  destroy()
0xfd9eb20a  setMaxTxAmount(uint256)
0x6c19e783  setFee(uint256)
...

Selectors alone aren’t proof of malice - many legitimate tokens have pause(). The signal is combinatorial: an unverified contract with blacklist + pause + setFee selectors and no verified source scores higher than the same combination in a verified contract where we can read the implementation.

We also compute a hash of the cleaned bytecode (strip metadata + constructor args) and look it up against a library of known scam-template hashes. Verbatim copy of a known rug = known_scam_bytecode flag.

liquidity - bundling and LP ownership

Two checks here, both V2-only (V3 LP positions are NFTs and we treat them separately):

  1. Bundling: was liquidity added in the same transaction as the PairCreated event? Legit projects usually add liquidity in a separate tx after the pair is wired up. Bundling is a stealth-launch tell and correlates strongly with rug patterns. Flag: liquidity_at_creation.

  2. LP ownership: query the pair contract’s totalSupply() and balanceOf(deployer), plus balances of known LP locker contracts (Unicrypt, Team.Finance, PinkLock) and the dead address 0x000…dEaD. If the deployer holds >80% of LP supply → creator_holds_all_lp. If the LP is sent to a known locker → lp_locked (positive signal). If burned → lp_burned (positive signal).

A token that’s liquidity_at_creation + creator_holds_all_lp + no_renounce_ownership is a textbook rug setup.

swap_activity - on-chain trade pattern

This one is our hedge against honeypot-simulation false negatives. We query the events table for the most recent ~100 swaps on the token’s pair and compute the buy/sell ratio.

  • 100% buys, 0 sells, with >10 swaps: buy_only_pattern flag, 40 points (highest single-flag weight). This catches cases like $FWD and $SLTE where the honeypot simulator passed but real on-chain activity showed nobody could sell.
  • 95% buys: high_buy_ratio, warning level.

The simulation lies; the on-chain reality doesn’t.

network - deployer cluster graph

Last layer, slightly different shape: we ask the scoring-engine service for a graph score that aggregates funder-level data. The signals:

  • mass_deployer_network: deployer’s funder has financed ≥5 deployers
  • scam_factory_funder: the funder has financed ≥10 deployers who each scored ≥70
  • serial_scammer: the deployer itself has ≥3 prior tokens flagged scam
  • mixer_funded / tornado_funded: any node in the 2-hop funding chain is a known mixer deposit address
  • disposable_wallet: wallet age < 24h + only-deploys-then-vanishes pattern

The score from this analyzer is capped at 50 so it doesn’t override the honeypot signals if those fire.

etherscan - source-code patterns + distribution

The Etherscan analyzer fetches the verified source (if any) and runs a small regex set:

  • function blacklist / mapping(address => bool) (private )?_?(isBlackListed|blacklisted)blacklist_detected
  • function setMaxTxAmount + require(amount <= _maxTxAmount)name_mimics_known_token if the name also matches a known popular ticker

If the source is not verified, we fall back to the bytecode analyzer. An unverified contract that’s been live for >7 days without verification is treated more suspiciously than a fresh one (legit projects usually verify within 24-48h).

distribution - initial Transfer events

The smallest analyzer. We pull the first ~200 Transfer(address,address,uint256) log entries and look at where the initial supply went:

  • One wallet (excluding 0x0, dEaD, the pair) gets >50% of supply: creator_holds_all_supply → high concentration risk
  • Top 5 wallets cumulatively hold >90%: warning flag
  • More than 20 unique recipients in the first 200 transfers: positive signal (broad initial distribution)

What we can’t catch (yet)

Being honest:

  • Soft rugs: legit-looking tokens that get abandoned with deployer dumping over weeks. Our deployer history catches them retroactively, but not at launch.
  • Sophisticated upgradable proxies: a UUPS proxy that points to a benign implementation today and a malicious one tomorrow. We flag beacon_proxy / proxy_contract but we don’t simulate the upgrade outcome.
  • Off-chain rugs: deployer abandons the project, social channels go silent, contract stays “safe” on-chain. Out of scope.
  • Cross-chain replays: a token deployed on mainnet that was previously rugged on BSC. We’re mainnet-only for now.

The catalog

Every signal above has its own page with the rationale, the threshold, and the severity:

rektradar.io/signals

Drop any address on rektradar.io to see which of these fire for a specific token - risk score, the full flag list with weights, and the deployer cluster as a 3D graph. No signup.

If you’ve shipped a similar pipeline and see signals we’re missing - especially in the off-chain / proxy upgrade space - we’d love to compare notes.