whodrained.me / methodology
How the Exposure score works
Exposure runs 0–100 and lower is better. It measures how much of you is visible from public data, which is a fact, not a judgement about how safe you are. Every weight, curve and constant is on this page. An opaque score in crypto reads as a grift within a day, so check the arithmetic.
01 / components
The six components
Each component turns its findings into a severity between 0 and 1, then contributes weight × severity to the total. A component we could not measure scores nothing and forfeits its weight — it never counts as no risk.
| Component | What it measures, and how | Weight |
|---|---|---|
Open approvals open-approvals | Contracts holding a standing permission to move your tokens. Each approval scores 1, plus 1 if the allowance is unlimited, plus 1 if it is over a year old and unused for six months. Full severity at 27, nine maximally bad approvals. | 25 |
Address linkage address-linkage | Addresses a stranger can tie to this one from public data. 70% from the node count, full at 45. 30% from flagged nodes, full at 4. | 20 |
Exchange identity link cex-identity-link | Deposit addresses that tie this wallet to a KYC'd account. 0.75 for the first link, 0.15 for each additional one, 0.15 more where a link carries 10 or more transfers. | 20 |
Drainer contact drainer-contact | Addresses in known drainer sets that this wallet has touched. 0.2 for each address that reached you, 0.5 for each one you sent to. Sending is worse than receiving, and it does not come off. | 15 |
Address reuse address-reuse | How much of your activity runs through this single address. The measured share, used directly. One address doing every job is one address to watch. | 12 |
Poisoning surface poisoning-surface | Lookalike addresses that have sent dust to bait a mistake. 75% from the attempt count, full at 15. 25% from how many characters the closest lookalike matches, full at 10. | 8 |
| Total | 100 | |
02 / mitigations
Completing an item caps a component. It does not discount it.
A cap sets the ceiling a component can sit at once you have done the work. It is not a percentage off. That distinction is what makes the score safe to recompute at any moment: the scan already detects some of these items as done from your own history, and every cap is set to exactly the severity at which its detection fires. Re-applying an item the scan already found is a no-op, so a fix is never paid for twice.
8 of the 12 checklist items carry no cap, on purpose. This score measures standing, visible state. Revoking an approval changes that state. Reading every signature from now on keeps the number from going back up, but it cannot un-sign what the chain already recorded — and paying out points for a promise is how a security score becomes a horoscope.
| Component | Checklist item | Cap | What changes |
|---|---|---|---|
| Open approvals | Revoke stale token approvals | 0% | Revoked. No contract holds a standing permission on this wallet. |
| Move long-term holds off your trading wallet | none | Nothing on this number. It reduces what happens next, which the chain has not recorded yet. | |
| Address linkage | Move between chains without connecting your addresses | 60% | The graph stops growing. What is already public stays public, and that part does not come back. |
| Stop using one address for everything | none | Nothing on this number. It reduces what happens next, which the chain has not recorded yet. | |
| Exchange identity link | Break the exchange deposit link | 0% | No deposit address ties this wallet to a KYC'd account. |
| Drainer contact | Never sign a message you can't read | none | Nothing on this number. It reduces what happens next, which the chain has not recorded yet. |
| Turn on signature simulation in your wallet | none | Nothing on this number. It reduces what happens next, which the chain has not recorded yet. | |
| Address reuse | Stop using one address for everything | 30% | Activity is split across addresses instead of running through one. |
| Separate your hot wallet from cold storage | none | Nothing on this number. It reduces what happens next, which the chain has not recorded yet. | |
| Poisoning surface | Never sign a message you can't read | none | Nothing on this number. It reduces what happens next, which the chain has not recorded yet. |
03 / bands
The four bands
The band is what the number means out loud. It is drawn straight from the value, with one exception, in section 04.
| Band | Range | What it means |
|---|---|---|
| ghost | 0–24 | Very little about you is publicly connected. |
| tight | 25–49 | A stranger would have to work for it. |
| loose | 50–74 | A stranger can build a picture of you in a few minutes. |
| exposed | 75–100 | Your size, your habits and your identity all read from here. |
04 / partial reads
Weight we could not assess is forfeited, never assumed safe.
A check that does not resolve scores zero points, and its whole weight is set aside and shown to you as unassessed. It is never folded into the total as if it came back clean. A 20 with 40 points unassessed is not a 20.
Past 25 forfeited points the number stops describing your wallet and starts describing our coverage, so the surface prints Partial read in place of a band. A quarter of the scale is the line: one whole component can fail and the score still stands, two cannot.
Worked example — nothing resolved
| Points counted | 0 |
| Weight forfeited | 100 |
| Band it would fall in | ghost |
| What we print | Partial read |
Zero points in the lowest band is precisely the reading this rule exists to stop. A wallet nobody managed to read is not a clean wallet.
05 / constants
Every tunable in the curves
These are the exact values the methods in section 01 refer to, printed under the names they carry in the source.
| Constant | Value |
|---|---|
| approvalRiskCeiling | 27 |
| approvalStaleAfterDays | 365 |
| approvalIdleAfterDays | 180 |
| linkageNodeShare | 0.7 |
| linkageNodeCeiling | 45 |
| linkageFlagCeiling | 4 |
| cexFirstLink | 0.75 |
| cexPerExtraLink | 0.15 |
| cexActiveBoost | 0.15 |
| cexActiveTransfers | 10 |
| drainerInbound | 0.2 |
| drainerOutbound | 0.5 |
| poisoningAttemptShare | 0.75 |
| poisoningAttemptCeiling | 15 |
| poisoningMatchCeiling | 10 |
| PARTIAL_READ_THRESHOLD | 25 |
lib/score.ts
06 / limits
What this score is not
It is not a safety rating, and it does not predict whether you will be drained. It counts what a stranger can read about you from public data today. 6 of the 12 checklist items leave no trace on a Solana address at all — a hardware signature and a hot-key signature are the same bytes — so the scan does not guess at them, and they never move this number.
Ages are measured against the moment of the scan rather than the wall clock, so a report you saved yields the same number a year from now.