Token checks
A token report returns a list of checks. Each one reads a public field and applies a fixed threshold. There is no composite score, by design. You read each check and decide what it means for your use.
{
"id": "top10",
"title": "Top 10 holder share",
"status": "warn",
"detail": "46.2% (contracts and exchanges are included).",
"source": "goplus",
"field": "holders[].percent"
}| Status | Meaning |
|---|---|
pass | The field was read and it is within the threshold. It is not a statement that the token is safe. |
warn | The field was read and it crosses the softer threshold, or the feature exists and has legitimate uses. |
fail | The field was read and it crosses the harder threshold. |
unknown | The field was absent, or the source failed. Unknown is never a pass. |
counts holds the number of checks per status. sources[] shows each call with ok and ms.
#Market checks (all chains)
These two run on EVM and Solana, using the pools DexScreener returns for the token.
| Id | Title | pass | warn | fail | unknown when | Source and field |
|---|---|---|---|---|---|---|
liquidity | DEX liquidity | $100,000 or more | $10,000 to below $100,000 | Below $10,000 | No pool data | dexscreener, liquidity.usd |
pool_age | Oldest pool age | 7 days or more | 1 day to below 7 days | Below 1 day | Creation time absent | dexscreener, pairCreatedAt |
Liquidity is the sum across pools. DexScreener returned at most 30 pools per token in every capture, so very widely traded tokens are undercounted.
Each check also holds checked_at, the UTC time of the check. A cached report keeps the time of the first read. Pools whose implied token price is more than 1.5 times away from the median are left out of the sums. This removes spoofed pools that report large liquidity against junk tokens. The detail text and market.outlier_pools_excluded give the count.
#EVM checks
All of these read the GoPlus token_security result for the chain.
| Id | Title | pass when | Otherwise | Field |
|---|---|---|---|---|
open_source | Contract source published | Value is 1 | fail | is_open_source |
honeypot | Honeypot simulation | Value is 0 | fail | is_honeypot |
mintable | Owner can mint | Value is 0 | warn | is_mintable |
proxy | Upgradeable proxy | Value is 0 | warn | is_proxy |
balance_change | Owner can change balances | Value is 0 | fail | owner_change_balance |
hidden_owner | Hidden owner | Value is 0 | fail | hidden_owner |
pausable | Transfers can pause | Value is 0 | warn | transfer_pausable |
blacklist | Blacklist function | Value is 0 | warn | is_blacklisted |
Each reads unknown when the field is absent.
The next four have numeric thresholds.
| Id | Title | pass | warn | fail | Field |
|---|---|---|---|---|---|
buy_tax | Buy tax | 1% or lower | Above 1%, below 10% | 10% or more | buy_tax |
sell_tax | Sell tax | 1% or lower | Above 1%, below 10% | 10% or more | sell_tax |
top10 | Top 10 holder share | 40% or lower | Above 40%, up to 70% | Above 70% | holders[].percent |
lp_locked | LP tokens locked | 50% or more | Below 50% | Never | lp_holders[].is_locked |
top10 sums the first 10 holders GoPlus returns, including contracts and exchanges. A token held mainly by exchange wallets or a staking contract can show warn or fail for ordinary reasons. Read holders[], which shows is_contract and label.
lp_locked reads unknown when lp_holders is empty or absent. This can happen for tokens that trade in pools with no LP token, such as concentrated liquidity pools.
#Solana checks
| Id | Title | pass | warn | fail | Source and field |
|---|---|---|---|---|---|
mint_authority | Mint authority | Revoked | Still set | Never | solana-rpc, mintAuthority |
freeze_authority | Freeze authority | Revoked | Still set | Never | solana-rpc, freezeAuthority |
top10 | Top 10 token accounts share | 70% or lower | Above 70% | Never | solana-rpc, getTokenLargestAccounts |
closable | Accounts can be closed by authority | Status 0 | Status 1 | Never | goplus, closable |
balance_mutable | Balance can be changed by authority | Status 0 | Never | Status 1 | goplus, balance_mutable_authority |
non_transferable | Non-transferable token | Status 0 | Never | Status 1 | goplus, non_transferable |
rugcheck | RugCheck normalised score | Below 50 | 50 or more | Never | rugcheck, score_normalised, or score when absent |
Each reads unknown when its field or source is absent.
Solana top10 counts token accounts, not owners. Pool vaults are token accounts and are included, so a share can look high because of a pool. getTokenLargestAccounts also fails at the RPC for some large tokens, which gives unknown.
The RugCheck value is passed through as reported: a higher score means more risk flags at that source. Farbeam does not control how RugCheck computes it.
#What the checks do not do
- They do not predict price. The report's
notefield says so on each response. - They do not audit code. They read fields from third parties, which can be wrong or late.
honeypotis a simulation by GoPlus. A contract can behave differently later, or for other addresses.- A
passon a mint check does not rule out other paths to new supply, such as a proxy upgrade. - A set of passes does not make a token safe, and a
faildoes not make it a scam. Major stablecoins show warnings for admin powers.
Read reading token reports for worked examples.
#Handling results in code
Key by id, because the order can change and items can be added. Handle unknown as its own branch.
curl -s "https://farbeamlabs.com/api/v1/tokens/ethereum/0xdAC17F958D2ee523a2206206994597C13D831ec7" \
| jq '.data.checks[] | select(.status != "pass") | {id, status, detail}'const url = "https://farbeamlabs.com/api/v1/tokens/ethereum/0xdAC17F958D2ee523a2206206994597C13D831ec7";
const { data } = await (await fetch(url)).json();
const byId = Object.fromEntries(data.checks.map((c) => [c.id, c]));
console.log(byId.honeypot?.status, data.counts);import requests
url = "https://farbeamlabs.com/api/v1/tokens/ethereum/0xdAC17F958D2ee523a2206206994597C13D831ec7"
data = requests.get(url, timeout=30).json()["data"]
by_id = {c["id"]: c for c in data["checks"]}
print(by_id["honeypot"]["status"], data["counts"])Checks are information only and are not financial advice. See the disclaimer.