skip to content
litmus

how LITMUS checks

every finding is one of four things: confirmed (a source shows it), a flag (a source shows a risk, rated critical / high / medium / low), unverifiable (no free public source could answer) or a note (context, never scored). LITMUS only reads public data. it never sends a transaction and never asks for a private key.

the Litmus Score

computed by code from the findings. the AI never sees or changes it. these numbers are read from the same file the scorer uses.

  1. start at 100.
  2. penalties per flag: critical −40 · high −15 · medium −6 · low −2.
  3. bonuses for confirmed facts (at most +10 in total):
    • +3: the project website lists this exact contract address
    • +2: website and X link to each other
    • +3: GitHub repository with code and more than 30 days of history
    • +2: mint and freeze authority both revoked
  4. caps: two or more critical flags → score at most 15; any critical flag → score at most 35.
  5. coverage: unverifiable findings are not penalised, but when more than 50% of scored checks are unverifiable the report says low coverage next to the score.
  6. the result is clamped to 0–100.

the scale

  • 0–20: several serious flags
  • 21–40: at least one critical flag
  • 41–60: many flags
  • 61–80: some flags
  • 81–100: few or no flags

a high score is not a safety guarantee. it means the automated checks found little — nothing more.

every check

deep = Analyst tier only · watch = re-run by the watchlist job

on-chain (Solana RPC)

checkrulesourcescope

Mint authority

onchain.mint_authority
active → critical; revoked → confirmedSolana RPC getAccountInfowatch

Freeze authority

onchain.freeze_authority
active → critical; revoked → confirmedSolana RPC getAccountInfowatch

Token program

onchain.token_program
SPL Token or Token-2022 (info)Solana RPCwatch

Token-2022 transfer fee

onchain.ext.transfer_fee
fee > 0 → high; fee > 5% → criticalToken-2022 extensionswatch

Token-2022 transfer hook

onchain.ext.transfer_hook
hook program set → highToken-2022 extensionswatch

Token-2022 permanent delegate

onchain.ext.permanent_delegate
set → criticalToken-2022 extensionswatch

Token-2022 non-transferable

onchain.ext.non_transferable
present → criticalToken-2022 extensionswatch

Token-2022 default frozen

onchain.ext.default_frozen
default account state frozen → criticalToken-2022 extensionswatch

Token-2022 confidential transfers

onchain.ext.confidential
infoToken-2022 extensionswatch

Token-2022 mint close authority

onchain.ext.mint_close
set → mediumToken-2022 extensionswatch

Metadata mutability

onchain.metadata_mutable
mutable with update authority → mediumMetaplex / Token-2022 metadatawatch

Metadata links

onchain.metadata_links
links used by later checks (info)off-chain metadata JSONwatch

Supply

onchain.supply
supply, decimals, burned part (info)Solana RPC

holders & creator (Solana RPC)

checkrulesourcescope

Top-10 concentration

holders.top10
excl. curve/pools/burn: > 30% → high; > 50% → criticalgetTokenLargestAccountswatch

Largest wallet

holders.top1
> 10% → highgetTokenLargestAccounts

Creator share

holders.creator_share
> 5% → medium; > 15% → high; 0 after launch buy → infogetTokenAccountsByOwnerwatch

Same-slot bundle

holders.bundle
only tokens with ≤ 1000 txs; same-slot buyers' share > 10% → high, > 25% → criticalgetSignaturesForAddress + getTransaction

Common funder

holders.common_funder
≥ 3 top-10 wallets funded by one address → high (≤ 30 RPC calls)first incoming SOL transferdeep

Creator wallet age

creator.age
< 24 h → mediumgetSignaturesForAddress

Creator launch history

creator.history
> 5 pump.fun launches → high (serial launcher)getProgramAccounts on pump.fun curves (creator field)deep

market (DexScreener)

checkrulesourcescope

Trading pair

market.pair
no pair → low; pair < 1 h → infoDexScreener

Liquidity

market.liquidity
liquidity / mcap < 2% → highDexScreenerwatch

Bonding curve

market.bonding
graduated or progress % (info)pump.fun bonding curve account

Buy / sell ratio

market.buy_sell
sells > 3× buys (≥ 20 txs) → mediumDexScreener

Price change

market.price_change
24h drop > 80% → highDexScreenerwatch

DexScreener profile

market.dex_profile
filled or not (info)DexScreener

website (direct fetch, RDAP, Wayback)

checkrulesourcescope

Website reachable

website.reachable
does not load → medium; no HTTPS → lowdirect fetch (SSRF-safe)watch

Domain age

website.domain_age
< 7 days → mediumRDAP (rdap.org)

Wayback history

website.wayback
first snapshot date (info)Wayback Machine CDX

CA on the site

website.mentions_ca
this CA → confirmed; a different CA → highsite HTML

Site ↔ X

website.links_x
same X as metadata → confirmed; different → mediumsite links

Site text

website.content
≤ 20 000 chars for claim checks (info)site HTMLwatch

X & Telegram (free public endpoints)

checkrulesourcescope

X profile exists

social.x_exists
not found → low (mirror only) or medium (mirror + post oEmbed agree); no free data → unverifiableX oEmbed + public mirror

X account age

social.x_age
< 7 days → mediumpublic mirror (best effort)

X followers

social.x_followers
infopublic mirror (best effort)

X links back

social.x_links_back
X profile links the same site → confirmedpublic mirror (best effort)

Telegram

social.tg
public page exists → confirmed (members if visible); missing → lowt.me preview page

GitHub (REST API)

checkrulesourcescope

Repository exists

github.exists
linked but missing → mediumGitHub REST APIwatch

Repository age

github.age
< 7 days → medium; > 30 days → confirmedGitHub REST API

Fork

github.is_fork
fork with no own commits → highGitHub REST API compare

Commits

github.commits
< 5 commits → mediumGitHub REST API

Contributors

github.contributors
infoGitHub REST API

Last commit

github.last_commit
infoGitHub REST API

Has code

github.has_code
README only → mediumGitHub REST API contents

License

github.license
infoGitHub REST API

Star quality

github.star_quality
> 50% of last 30 stargazers younger than 30 days → mediumGitHub REST APIdeep

claims (AI extraction, rules decide)

checkrulesourcescope

Claims summary

claims.summary
AI extracts ≤ 10 claims; rules decide the status (info)site text + AI extraction

Contradicted claims

claims.contradicted
any claim contradicted by data → mediumrules over DexScreener / GitHub / site

the AI's job, and its limits

  • it extracts up to 10 claims from the project's own text, with a verbatim quote. claims whose quote is not in the text are dropped.
  • rules decide each claim, not the AI: audits need a linked report, listings are checked against DexScreener pairs, products need a repo with code. team and partnership claims stay unverifiable.
  • it writes a 3–5 sentence summary from the findings JSON only. every sentence must cite a finding id; sentences citing unknown ids are discarded.
  • website text is passed as untrusted data between markers; instructions inside it are ignored. input is capped at 20 000 characters.
  • when the free daily AI budget runs out, the summary is assembled by code.

sources & etiquette

  • Solana mainnet RPC (Helius free tier, public endpoint as fallback); DexScreener public API; RDAP (rdap.org); Wayback Machine; GitHub REST API; X oEmbed and a public profile mirror; t.me public pages.
  • project websites are fetched once per check by LitmusBot/1.0: http/https only, ports 80/443, no private networks, ≤ 3 redirects, ≤ 2 MB, 8 s.
  • reports are point-in-time snapshots. recheck, compare versions, or add a token to your watchlist to follow changes.
  • projects can sign with their creator or update-authority wallet to publish a response next to the report. responses never change the score.