This guide walks through a systematic process for evaluating Solana token safety. It combines the Token Risk Assessment (which evaluates 17 risk factors) with Address Risk Score (which checks the token deployer) to produce a comprehensive risk picture.
When to Use This
- Exchanges - Before listing a new token for trading
- DEX aggregators - Before including a token in routing
- Portfolio trackers - Before displaying a token’s price and details
- DeFi protocols - Before accepting a token as collateral or in liquidity pools
- Wallet providers - Before showing token metadata to users
Step 1: Assess Token Risk
Submit the token’s mint address to get a multi-factor risk assessment.
curl -X GET "https://api.range.org/api/v1/ml/risk/assessment/token?mint_address=MINT_ADDRESS&network=solana" \
-H "Authorization: Bearer your_api_key_here"
async function assessToken(mintAddress) {
const params = new URLSearchParams({
mint_address: mintAddress,
network: "solana",
});
const response = await fetch(
`https://api.range.org/api/v1/ml/risk/assessment/token?${params}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
return response.json();
}
Interpreting the Response
The response contains an overall_assessment with the aggregate risk, and risk_factors with individual assessments.
| Overall Risk Level | Risk Percentage | Interpretation |
|---|
| LOW | <30% | Token passes most risk checks. Suitable for listing with standard monitoring. |
| MEDIUM | 30–60% | Some risk factors flagged. Requires manual review before listing. |
| HIGH | ≥60% | Multiple risk factors flagged. Not recommended for listing without thorough investigation. |
Step 2: Understand the Risk Factors
The 17 risk factors fall into 5 categories. Focus on the factors most relevant to your use case:
Critical Factors for Listing Decisions
| Factor | Why It Matters | What HIGH Means |
|---|
| Mint Authority | Can new tokens be created? | Active - unlimited supply inflation possible |
| Freeze Authority | Can token accounts be frozen? | Active - users could be blocked from transferring |
| Top Holder Concentration | Is supply concentrated? | >90% held by top holders - coordinated dump risk |
| Liquidity | Can holders sell? | <$10K liquidity - holders may be trapped |
| Wash Trading | Is volume real? | Suspicious patterns in ≥2 timeframes |
Contextual Factors
| Factor | Why It Matters | What HIGH Means |
|---|
| Token Age | Is there a track record? | <7 days old - insufficient history |
| Market Cap | Size and manipulation risk | <$1M - more susceptible to manipulation |
| Organic Activity | Is demand genuine? | Low organic score - bot-driven trading activity |
| Exchange Listings | Has it passed other due diligence? | No exchange listings |
Using the errors Array
Not all 17 factors can be assessed for every token. The errors array lists skipped assessments:
"errors": [
"Dev migration data not available - dev_migrations assessment skipped",
"Exchange listing data not available - exchange_listings assessment skipped"
]
Tokens with fewer assessed factors need extra caution. A LOW score based on 3 factors is less reliable than one based on 13. The API adjusts the maximum possible score accordingly, but partial data should prompt additional manual review.
Step 3: Check the Deployer Address
For additional context, check the risk score of the address that deployed the token. A high-risk deployer is a strong signal of a problematic token.
curl -G https://api.range.org/v1/risk/address \
--data-urlencode "address=DEPLOYER_ADDRESS" \
--data-urlencode "network=solana" \
-H "Authorization: Bearer your_api_key_here"
The deployer address isn’t returned by the Token Risk Assessment API - you’ll need to look it up onchain (e.g., via the Solana Explorer or your own indexer). If you don’t have the deployer address, you can skip this step. The Token Risk Assessment is comprehensive on its own.
Step 4: Make a Listing Decision
Combine the token risk assessment and deployer check into a decision framework. Different platforms have different risk tolerances:
Exchange Listing Criteria
| Token Risk | Deployer Risk | Assessed Factors | Decision |
|---|
| LOW | 1–3 | ≥10 | List - Comprehensive data, low risk |
| LOW | 1–3 | <10 | Review - Low risk but limited data |
| MEDIUM | Any | Any | Review - Manual investigation required |
| HIGH | Any | Any | Reject - Multiple risk signals |
| Any | 8–10 | Any | Reject - Deployer connected to malicious activity |
DEX Aggregator / Portfolio Tracker Criteria
DEX aggregators and portfolio trackers typically have broader inclusion criteria since users are selecting tokens themselves:
| Token Risk | Action |
|---|
| LOW | Include with no warnings |
| MEDIUM | Include with a risk indicator |
| HIGH | Include with a prominent warning, or exclude from default lists |
Step 5: Monitor Over Time
Token risk is not static. Tokens that pass initial due diligence can deteriorate:
- Rug pull preparation - Authority controls re-enabled, liquidity removed
- Wash trading emergence - Artificial volume after listing
- Holder concentration shifts - Token accumulation by few addresses
Set up periodic re-assessment for listed tokens:
async function periodicTokenCheck(mintAddresses) {
const results = [];
for (const mint of mintAddresses) {
const risk = await assessToken(mint);
results.push({
mint,
risk_level: risk.overall_assessment.risk_level,
risk_percentage: risk.overall_assessment.risk_percentage,
high_risk_factors: risk.summary.high_risk_count,
checked_at: new Date().toISOString(),
});
}
// Flag tokens whose risk has increased
return results.filter((r) => r.risk_level !== "LOW");
}
Complete Due Diligence Function
async function tokenDueDiligence(mintAddress, deployerAddress = null) {
// Token risk assessment
const tokenRisk = await assessToken(mintAddress);
const result = {
token: tokenRisk.token_info,
risk_level: tokenRisk.overall_assessment.risk_level,
risk_percentage: tokenRisk.overall_assessment.risk_percentage,
factors_assessed: tokenRisk.summary.total_factors,
high_risk_factors: tokenRisk.summary.high_risk_count,
critical_flags: [],
};
// Check critical factors
const factors = tokenRisk.risk_factors;
if (factors.minting_authority?.level === "HIGH")
result.critical_flags.push("Mint authority active");
if (factors.freeze_authority?.level === "HIGH")
result.critical_flags.push("Freeze authority active");
if (factors.top_holder_concentration?.level === "HIGH")
result.critical_flags.push("High holder concentration (>90%)");
if (factors.wash_trading?.level === "HIGH")
result.critical_flags.push("Wash trading detected");
// Deployer check (optional)
if (deployerAddress) {
const deployerRisk = await checkAddressRisk(deployerAddress, "solana");
result.deployer_risk = {
score: deployerRisk.riskScore,
level: deployerRisk.riskLevel,
reasoning: deployerRisk.reasoning,
};
if (deployerRisk.riskScore >= 6) {
result.critical_flags.push(
`Deployer risk score: ${deployerRisk.riskScore}/10`
);
}
}
// Recommendation
if (
result.risk_level === "HIGH" ||
result.critical_flags.length >= 3 ||
result.deployer_risk?.score >= 8
) {
result.recommendation = "reject";
} else if (
result.risk_level === "MEDIUM" ||
result.critical_flags.length >= 1 ||
result.factors_assessed < 10
) {
result.recommendation = "review";
} else {
result.recommendation = "list";
}
return result;
}
What’s Next