Contract Risk API

On-chain contract risk score: detects upgradeable proxies and privileged functions from live bytecode. Use before trading/interacting with an unfamiliar contract.

How each mode works

Risk score (scan and full modes)

Every scan reads the contract's live bytecode and the EIP-1967 proxy storage slot, then adds a weight for each risk signal it finds. The total is riskScore; riskLevel is just that total sorted into a band.

LevelScoreReading
low0–9No centralised-control signals found.
medium10–29Privileged functions or upgradeability present.
high30+Several powerful owner capabilities at once.
unknown—No code at this address (a wallet, or not deployed yet).

A high score is not proof of a scam, and a low score is not a safety guarantee. Plenty of legitimate tokens are pausable and mintable by design — the score tells you how much power the owner holds, so you can decide whether you trust whoever holds it.

What each risk signal adds

SignalWeight
Upgradeable proxy (EIP-1967 implementation slot is set)+10
owner()+5
transferOwnership(address)+5
mint(address,uint256)+15
pause()+10
blacklist(address)+20
setBlacklist(address,bool)+20
excludeFromFee(address)+5
setTaxFee(uint256)+15

Maximum possible score is 105. Function detection searches the bytecode for each function's dispatcher pattern, so it can under-report on heavily optimised or obfuscated contracts, and proxy detection currently only reads the EIP-1967 slot — contracts using older proxy layouts (USDC among them) are reported as isProxy: false.

Alert-channel monitoring (alert and full modes)

Scrapes the public preview of 10 crypto Telegram channels — security-alert feeds, whale trackers, and ecosystem news — and counts how many times the queried address or ticker appears in each. Results are categorized by keyword:

CategoryWhat it flags
securityAlerthack, exploit, rug, drain, vulnerable, attack, phish, compromised, stolen, malicious, blacklist, frozen
whaleMovementminted, burned, transferred, whale, moved, deposit, withdraw
listinglisted, listing, launch, upgrade, integration, partnership
otherMentions that matched none of the above

Read alertMentions as a live snapshot, not a historical record. It counts appearances in the current rolling window — the last 30 messages of each channel, cached for 5 minutes (15 for low-volume security feeds). securityAlert: 0 means no security-channel mentions in this window, not “never flagged.” A contract exploited yesterday, before the window rolled, will show zero. Absence of alerts is not a safety guarantee. lastCheckedAt reports the scan timestamp so a caller can reason about freshness.

Combined check (full mode)

Returns both signals in one response, running the bytecode fetch and the channel scrape in parallel — so latency is the slower of the two, not the sum. It is also cheaper than calling scan and alert separately. The two signals are worth more together than either alone: a contract with powerful owner functions that is also being flagged in a security channel is a different situation from either signal on its own.

Response fields

riskLevel
Band from the table above: low, medium, high, or unknown.
riskScore
Sum of the weights of every signal found.
isContract
Whether the address has bytecode. False means a wallet or an undeployed address.
isProxy
Whether the EIP-1967 implementation slot is set, meaning an admin can swap the contract's logic.
flags
Each signal found, as a human-readable label and its weight.
alertMentions
Total mentions in the rolling window across all tracked channels.
categories
Counts split by securityAlert / whaleMovement / listing / other.
channels
Which tracked channels contained a mention.
samples
Up to 5 matching messages, truncated to 200 characters.
lastCheckedAt
Timestamp of the scrape, for freshness reasoning.
note
Present when there is no data, or when a category is empty — explains what that absence does and does not mean.
address, chain
Echoed back so a stored result is self-describing.