How we compute a rug score
A trading bot that buys a fresh pump.fun token has a few seconds to decide. Our rug-check gives it one number from 0 to 100 and a list of reasons. Here is exactly how that number is built, so you can decide whether to trust it.
1. What we read on-chain
For every check we make three reads from a Solana RPC node:
- The mint account: total supply, the mint authority and the freeze authority.
- The largest token accounts for that mint (
getTokenLargestAccounts). - The owner of each of the top 12 accounts, and which program owns it. That tells us whether an account belongs to a person, a pool or a lock.
If the token has the Token-2022 metadata extension, we also read its name and symbol for the name check (section 5).
2. Mint and freeze authority
These are the two classic rug switches.
| Finding | Severity | Why it matters |
|---|---|---|
MINT_AUTHORITY | danger (+40) | Someone can still create new tokens and dilute every holder to zero. |
FREEZE_AUTHORITY | danger (+40) | Someone can freeze your token account, so you can buy but never sell. |
MINT_REVOKED | info (0) | The supply is fixed. Standard for pump.fun tokens. |
A token with both authorities still set scores 80 before we even look at the holders.
3. Holder concentration, without the noise
Most rugs are not clever: one wallet, or a handful of wallets, holds a large part of the supply and sells into the first buyers. So we measure how much the largest holders own. The hard part is deciding who counts as a holder.
On a fresh pump.fun token, the biggest account is almost always the bonding curve, often holding over 90% of the supply. That is not a person who can dump on you; it is the market itself. A naive top-10 check would flag every new token as a rug. So before we count, we label each large account:
| Label | How we detect it | Counted as holder? |
|---|---|---|
pool | The account is owned by the pump.fun bonding-curve program or the PumpSwap AMM | No |
mayhem_agent | Owned by pump.fun's Mayhem Mode AI agent. Its unsold tokens are burned after 24 hours | No, and its tokens are taken out of the supply too |
excluded | You passed the account in exclude, for example your own pool | No |
locked | Held by a lock or vesting program such as Streamflow | Yes. Locked tokens unlock later, so they still count |
That last row is a deliberate choice. A team that locks 20% of the supply for a year cannot dump today, but it can in a year. We report the lock as an info finding (LOCKED_TOKENS) so your bot knows, and keep the tokens in the concentration math so the score does not look rosier than the future.
Then the thresholds:
| Finding | Rule | Severity |
|---|---|---|
WHALE_HOLDER | Largest holder owns 20% or more | danger (+40) |
LARGE_HOLDER | Largest holder owns 10% to 20% | warn (+15) |
CONCENTRATED | Top 10 holders own 50% or more | danger (+40) |
SOMEWHAT_CONCENTRATED | Top 10 holders own 30% to 50% | warn (+15) |
4. From findings to one number
Every finding has a severity, and every severity has a fixed weight: danger 40, warn 15, info 0. The risk score is the sum, capped at 100. The level follows from the score:
- low: below 15. No warnings or dangers found.
- medium: 15 to 39. At least one warning, no danger.
- high: 40 or more. At least one danger, or several warnings.
We keep it additive on purpose. A bot developer can read the findings list and reproduce the score by hand. If you disagree with our weights, ignore riskScore and build your own rule from findings; the codes are stable.
// Example response, shortened (made-up token) { "riskScore": 55, "level": "high", "findings": [ { "code": "MINT_REVOKED", "severity": "info" }, { "code": "POOL_EXCLUDED", "severity": "info" }, { "code": "WHALE_HOLDER", "severity": "danger", "message": "The largest holder owns 24.1% of the supply." }, { "code": "SOMEWHAT_CONCENTRATED", "severity": "warn" } ], "top10SharePct": 38.7 }
5. The name check
Not every scam is in the holder list. Some tokens copy a famous name, or describe themselves as "official" or "guaranteed". For that we ask Jev by TypeSafe to judge the token's name, symbol and description. It returns three probabilities, and at 0.8 or higher we add a warning:
NAME_IMPERSONATION: the token pretends to be a known brand, person or project.NAME_CLONE: it copies an existing token's name or ticker.SCAM_WORDING: its text uses typical scam language.
The raw probabilities come back in nameCheck, so you can pick your own threshold. In the launch feed we also flag COPYCAT_NAME when two or more other pump.fun tokens used the same name or ticker in the hour before.
6. What the score does not tell you
A low score means we found no red flags in these checks. It does not mean a token is safe. Things we do not catch:
- Many wallets controlled by one person, each holding just under our thresholds.
- A developer who sells everything a minute after your check.
- Liquidity that is thin, or a price that has already run up.
- Off-chain promises, fake socials or a team that simply disappears.
That is why the response always carries a disclaimer, and why we suggest a second check right before signing: safe_buy combines the rug-check with Presign Guard, which looks at the actual buy transaction before your bot signs it.
Use it
One call, 0.002 USDC over x402, or free through MCP:
curl -i https://api.agentfuel.eu/v1/rugcheck/<mint>
The first answer is a 402 with the price and the payment address. Full details in the docs.
claude mcp add --transport http agentfuel https://api.agentfuel.eu/mcpBots without MCP pay per call over x402: see the docs.