chainscore.netHolistix

How the Holistix score works

Holistix produces a continuous score from 0.0 (no material exposure) to 10.0 (do not transact). Higher is riskier. The score is computed once, across every chain the wallet can exist on, and every point of it is attributable to a named category.

1. Trace value in three layers

Direct counterparties are observed from chain data and count at full weight. The onward same-chain hop counts at 50% and each bridge crossing's far side at 70%. Online, the same-chain hop-2 walk is read from a live indexer; it is modelled from the seed only when SAFESCORE_OFFLINE=1. The far side of a bridge is always modelled: entering the bridge is observed, but no transfer links it to a particular address on the destination chain, so the value is attributed across the addresses that bridge is known to hold there. Every hop is marked observed or modelled, and a modelled hop cannot carry a sanctions or terrorism-financing category.

2. Turn exposure into a contribution

Each category has a weight, which is the most it can contribute. A category reaches that ceiling at its saturation share — the share of traced value at which the exposure is considered as bad as it is going to get:

intensity    = min(1, (weighted_share / saturation) ** 0.5)
contribution = category_weight * intensity
Category weight of at leastSaturates at
9.0 0.050% of traced value
7.0 1.000% of traced value
5.0 5.000% of traced value
3.0 50.000% of traced value
0.0 80.000% of traced value

Serious categories saturate almost immediately, which is the point: 0.05% of value touching a sanctioned entity is not a rounding error.

3. Combine contributions as a quadratic mean

score = min(10, sqrt(sum(contribution²)))

Summing would let a long tail of benign flow push a clean wallet up; taking the maximum would ignore the difference between one risky service and four. The quadratic mean does neither: the largest contribution dominates, but several moderate ones still accumulate. It also makes attribution exact — each category owns contribution² / total of the result, so the percentages in a report sum to 100% with nothing unexplained.

4. Override for the wallet itself

If the wallet is a designated entity (category weight 9 or above), flow analysis is irrelevant and the score is set to 10.0.

5. Apply institution risk tolerance

The 0–10 score is a measurement. The 1–5 level is the institution's policy applied to it: four boundaries the operator owns, plus an optional rule that any sanctions, terrorism-financing or CSAM match forces level 5 regardless of the score. Re-grading a stored report under a different profile never changes the stored score. Tune this at Risk tolerance.

Risk bands

ScoreBandGuidance
8.0 + critical Do not transact. Direct or heavy illicit exposure.
6.0 + high Block pending review by a compliance officer.
4.0 + medium Enhanced due diligence recommended before proceeding.
2.0 + low Proceed with standard monitoring.
0.0 + minimal No material risk exposure identified.

Bands are a reading aid. Decisions come from the 19 configured rules, which look at categories and layers directly rather than only at the band.

Category weights

CategoryWeight
Sanctioned entity or designated address
sanctioned
10
Terrorism financing
terrorism_financing
10
Child sexual abuse material
child_abuse_material
10
Ransomware operator or affiliate
ransomware
9
Darknet marketplace
darknet_market
9
Mixing or anonymising service
mixer
8
Proceeds of hacks and exploits
stolen_funds
8
Scam, phishing or investment fraud
scam
7
Fraud shop / stolen data vendor
fraud_shop
7
Exchange with weak or absent KYC
high_risk_exchange
6
Unlicensed peer-to-peer broker
unlicensed_p2p
5
Gambling or betting service
gambling
5
Cross-chain bridge
bridge
3
Decentralised finance protocol
defi
2
Unattributed address
unknown
2
Regulated exchange or VASP
exchange
1
Mining pool
mining
1
Merchant or payment processor
merchant
1
Regulated custodian
custodian
1
Token contract
token_contract
1

Data sources and honesty about them

Live chain data comes from Alchemy for Ethereum, BSC, Base, Optimism, Polygon, Arbitrum and Solana when a key is set (same key; enable each network in the dashboard), QuickNode as per-chain failover when an HTTP Provider URL is set, Blockscout as the keyless path and failover, TronGrid for TRX and TRC-20, Solana JSON-RPC for SOL and SPL (Alchemy/QuickNode when configured), mempool.space for Bitcoin, CoinGecko daily closes for native USD (and for wrapped natives that track those series), a stored issuer-contract list for stablecoin pegs, a dated FATF jurisdiction snapshot for geography flags, and optional Etherscan v2 failover when a key is set and Blockscout fails. An EVM address is screened on every EVM chain in one call; Tron, Solana and Bitcoin addresses stay on that family. When an indexer is unavailable or returns nothing, that chain is scored empty rather than filled with invented transfers. SAFESCORE_OFFLINE=1 still uses a deterministic dataset so tests and demos can run without outbound HTTP. Each report names its source per chain. IP/node geolocation is not inferred from first-seen time. Forensic reports include a cross-chain transfer map: chain lanes, time left-to-right, edge thickness by USD, dashed edges for multi-hop or bridged trails.

Attributions marked public are real, publicly known addresses (including a documented overlay on top of the seed). Those marked synthetic exist so the scoring model can be exercised end to end. Unlabelled counterparties stay unknown; Holistix does not invent a category or jurisdiction from a hash of the address.

Cross-product glossary

Shared score scales, provenance data_source values, observed vs modelled fields, EVM failover order, and typology family IDs live in the repository file docs/compute-glossary.md.