Sniff

How Sniff checks a coin

Everything below is what the code actually does, with the real thresholds. If a number isn't here, Sniff doesn't use it.

Overview

Sniff is one scanner with three ways in. All three run the same checks and give the same verdict.

Website
Paste a contract address or a pump.fun, Solscan, GMGN, Birdeye or Photon link. You get a case file with a Clean, Shady, Risky or Rug stamp, the story check, and the live feed of fresh launches.
Telegram bot
Send the bot an address or link. It replies with the on-chain verdict first, then edits the same message to add the story verdict when it's ready. It can also post clean live launches to a channel.
Desktop dog
A small dog that walks along your screen. Copy an address and it sniffs it and tells you what it found.

On-chain checks

Data comes from Helius: standard Solana RPC (mint account, bonding curve, largest holders, transaction history), the DAS API (getAsset for name, image and metadata link) and the Enhanced Transactions API (the dev's past pump.fun launches). The coin's metadata file is fetched from IPFS.

Every coin starts at 100 points. Each finding is marked ✅ fine, ⚠️ caution or ❌ red flag, and cautions and red flags take points off.

CheckResultPointsWhy it matters
Everyone has sold❌ The coin has traded, but the bonding curve is back to its launch state: all tokens returned and under 1 SOL left−40, and the score is capped at 20 (Rug)Every buyer has left. Whatever else checks out, the next buyer is buying a dead coin.
Mint authority❌ Dev can still mint tokens−40New tokens dilute every holder to zero.
✅ Revoked0
Freeze authority❌ Dev can freeze wallets−40A frozen wallet can't sell.
✅ Revoked0
Token-2022: permanent delegate❌ Present−40The delegate can move tokens out of your wallet.
Token-2022: transfer hook⚠️ Present−15Every transfer runs custom code that could block sells.
Token-2022: transfer fee⚠️ Fee above 0%−15A cut is taken on every transfer.
Buys in the creation block❌ 3 or more−25Buys landing in the same block as the launch are the dev's own wallets or snipers (a bundle). They can dump on everyone who buys after.
⚠️ 1 or 2−10
✅ None0
Top 10 holders❌ Over 50%−25A few wallets holding a lot can crash the price. Counted from the 20 largest token accounts, leaving out the bonding curve, pools (program-owned accounts), known exchange wallets and the dev (the dev has its own check). Exchange holdings are shown on a separate line.
⚠️ Over 30%−10
✅ 30% or less0
Info: under 0.5%, coin under 10 minutes old (almost nobody holds it yet)0
⚠️ Under 0.5%, coin 10 minutes or older (or age unknown)−15
Single biggest wallet⚠️ Over 15%−15One wallet can move the price on its own.
Fresh wallets❌ Wallets made in the last day hold 20% or more−20How much of the supply the 15 biggest holders (same exclusions as the top 10) keep in wallets whose first transaction was in the last day or week. A wallet with 1,000+ transactions counts as old. Devs spread supply over brand-new wallets so it looks like real buyers. On the coins we measured, the 1-day share was usually 0 to 8%, so the limits sit above that.
⚠️ Wallets made in the last day hold 10% or more−10
⚠️ Wallets made in the last week hold 30% or more−10
✅ Under 5% in 1-day-old wallets (at least 5 wallets checked)0
Dev holdings⚠️ Dev holds over 10%−15A big dev bag can be dumped. A dev who sells everything while the coin is still on the bonding curve is the classic rug, worst in the first hour. After the coin migrates to PumpSwap, a dev holding nothing is common and isn't penalised. If the dev never bought at launch, holding nothing is normal and isn't penalised.
❌ Dev sold everything, coin under 1 hour old, not migrated−20
⚠️ Dev sold everything, coin 1 hour or older (or age unknown), not migrated−15
Dev wallet age⚠️ First transaction under 1 hour ago−15A fresh wallet made for one launch. Only checked when the wallet has fewer than 1,000 transactions, so its first one can be seen.
⚠️ First transaction 1 to 24 hours ago−10
Dev's previous launches❌ 5 or more−20Serial launchers make coins to sell them. Counted from the dev's last 100 transactions (Enhanced API) and from launches the feed has seen since the server started; the higher number wins.
⚠️ 2 to 4−10
Website, X, Telegram⚠️ None listed in the metadata−10No socials is a bad sign. Having them proves nothing, so listed socials give no points. If the metadata file can't be loaded, socials count as unknown and there's no penalty.

Some findings are information only and don't change the score: whether the coin is still on the bonding curve or has migrated to PumpSwap, which token the curve trades against when it isn't SOL (pump.fun curves can be paired with PUMP or a tokenized stock, and the market cap is then priced in that token), Mayhem-mode extra supply, the exchange share, and a note when a coin has too many trades to inspect its creation block.

When a busy coin has more transactions than Sniff can page through, the creation block (and so the bundle check) is out of reach. Sniff still finds the launch time from the coin's metadata account, which is only written at creation, so the age-based dev checks keep working. Token-2022 coins keep their metadata inside the mint, so for those the age can stay unknown.

Coins in the live feed get a lighter scan to save credits: Sniff reads at most 1,000 of the coin's transactions instead of 5,000 and skips the Enhanced API launch count. Opening the coin runs the full scan.

How the score works

  1. Start at 100 and subtract the points from the table.
  2. Red flags outweigh the total. Any ❌ caps the score at 70, so the best it can get is Shady. Two or more ❌ cap it at 40, which is Risky. A coin everyone has sold is capped at 20, which is a Rug.
  3. The score is kept between 0 and 100 and stamped:
Clean75–100
Shady45–74
Risky21–44
Rug0–20

Mixing in the story

When the story check finishes, the case file shows one final score: the on-chain score and the story score averaged 50/50, but never higher than the on-chain score. A great story can't rescue bad on-chain signals; a weak story can pull a clean coin down. If the verdict is Just a meme, the story doesn't change the score at all.

final = min(on-chain, round((on-chain + story) / 2))

Example: on-chain 90, story 30 (Larp) gives min(90, 60) = 60, so the stamp changes from Clean to Shady.

Story check: is the story real?

Plenty of coins claim to be an AI agent, an app or a brand's official mascot. The story check tests those claims in two steps. Community coins that only borrow a brand or stock name (often paired with a tokenized version of that stock) and claim nothing more are rated Just a meme, not Larp.

1. Code collects the facts

  • Metadata: name, ticker, description, launch time and the website, X and Telegram links from the coin's metadata.
  • Website: the page title, description and up to 5,000 characters of text. The fetch is locked down: only http and https on ports 80 and 443, addresses that resolve to private or internal networks are refused, at most 3 redirects, 400 KB and 8 seconds.
  • GitHub: up to 2 repositories linked from the description, the website or its page. For each: when it was created compared with the coin's launch (and how many days before), commit count, contributors, stars, forks, whether it's a fork and of what, last push and language. If only a GitHub account is linked, Sniff reads the account's age and public repo count.

2. Claude weighs the claims

Claude (Opus 5.5) gets those facts plus up to 4 web searches and 4 page fetches. It lists what the coin claims (technology, affiliations, utility), checks the important claims against the brand's own channels and credible sources, and returns a verdict with each claim, its status and a source link. The site shows it on a Larp → Real gauge.

Real70–100Main claims verified: working product, repo that predates the coin with real activity, confirmed affiliation.
Partly real40–69Some claims verified, some exaggerated or unverified.
Larp0–39Main claims false, faked or unverifiable.
Just a meme50No claims beyond being a meme. Doesn't affect the final score.

Red flags it looks for

  • A "brand mascot" or partnership that the brand's official site or X account never mentions.
  • A GitHub repo created after the coin launched, a fork with no new work, or a handful of commits behind "real tech".
  • A big claim (AI agent, revenue share, working app) with no evidence anywhere. Unverified counts against the coin.
  • A website that doesn't load or says nothing about the product.

Without an Anthropic key on the server, the story section shows the collected facts only, with no verdict.

Checking a website on its own

You can paste a website instead of a coin: on this site, in a private chat with the bot, or with /site example.com in a group. Sniff runs the same two steps on the site alone and stamps it Real, Partly real, Larp or Just a meme. If the page lists a pump.fun coin address, Sniff shows it with a button to scan it, but doesn't scan it automatically, because a site can list any address. A site check looks at what the site claims, not whether its code or wallet connection is safe.

Live feed

New coins arrive from the PumpPortal WebSocket the moment they launch. Sniff then watches each coin's bonding curve through a Helius WebSocket subscription. A coin enters the feed only when both are true within 5 minutes of launch:

  • at least FEED_MIN_SOL SOL is sitting in the curve (default 8 SOL);
  • the curve has updated at least 15 times, which is roughly 15 trades.

Why both: a dev can put 8 SOL into their own coin in the first second. One big buy isn't traction; many separate trades bringing in real SOL is. Coins that don't make it in 5 minutes are dropped, and so are coins whose curve trades against a token other than SOL, since their inflow can't be measured in SOL. Sniff watches up to 300 coins at once.

Coins that pass get the lighter scan and appear in the feed. Clean ones are also posted to the Telegram channel if one is set up.

Limits and cache

WhatLimit
Scans on the website10 per minute per IP (SCANS_PER_MINUTE). The same coin is cached for 60 seconds.
Story and site checks4 new checks per 10 minutes per IP (per chat in the bot). Opening a coin that was checked in the last 6 hours is free and doesn't count.
Story cache6 hours per coin.
Story checks per day200 new checks for the whole server (STORY_CHECKS_PER_DAY). After that it says to try again tomorrow.

Disclaimer

Sniff reads on-chain signals and public pages. It can't see intent. A Clean stamp means none of these checks found a problem, not that the coin won't dump. A dev can still sell, holders can still exit, and new tricks appear all the time. The story check is an AI's judgement from public sources and can be wrong. Nothing here is financial advice. Only trade what you can afford to lose.