Oracle05
Reason codes
The rulebook is twenty-one codes with fixed weights (two of them negative: ERC-8004 agent signals subtract, the total is clamped at 0), and the weights below are read from the code that scores. Every verdict lists the codes that fired with the evidence behind each one; nothing else can move the score.
Codes and weights
| Code | Weight | What it means | Source |
|---|---|---|---|
SANCTIONS_DIRECT | 100 | The address, or the entity resolved from the optional name, is a hit in OpenSanctions (self-hosted yente). | yente /match: CryptoWallet.publicKey, or Person/Organization name |
USDC_BLACKLISTED | 100 | Circle's USDC contract on Arc answers isBlacklisted(address) == true. | FiatTokenV2.isBlacklisted, 1 RPC call |
PROTOCOL_BLOCKLISTED | 100 | Listed on the Arc protocol blocklist contract. No such contract is documented today, so PROTOCOL_BLOCKLIST_ADDRESS is empty and this never fires. | PROTOCOL_BLOCKLIST_ADDRESS (unset) |
FUNDER_1HOP_SANCTIONED | 30 | A wallet that sent USDC to the subject is sanctioned. | funder trace (hop 1) + yente |
FUNDER_1HOP_BLACKLISTED | 30 | A hop-1 funder is USDC-blacklisted or protocol-blocklisted. | funder trace + isBlacklisted |
FUNDER_2HOP_SANCTIONED | 15 | A wallet that funded one of the subject's funders is sanctioned. | funder trace (hop 2) + yente |
FUNDER_2HOP_BLACKLISTED | 15 | A hop-2 funder is USDC-blacklisted or protocol-blocklisted. | funder trace + isBlacklisted |
LOOKALIKE_OF_KNOWN_PAYEE | 25 | Address poisoning: the subject shares the first 4 and last 4 hex characters with a payee in your book, or is ≥ 0.8 similar by normalised Levenshtein, but is a different address. | your payeeBook |
PRIOR_HIGH_TIER | 20 | CompliR itself graded this address HIGH within the last 30 days. | own attestation history |
NETWORK_HELD_ELSEWHERE | 10 / 20 | Other integrators rated this address HIGH in the last 7 days. Evidence is a count only; no other client is identifiable. | shared screenings store (internal client ids excluded) |
PAYEE_ADDRESS_CHANGED | 15 | Same payee label as before, new address (compared with the previous book on a re-screen). | your payeeBook |
COMMUNITY_TIP_VERIFIED | 15 | A staked tip about this address was verified by the agent in the last 180 days. Evidence carries tip ids, categories and strength only. | tip market |
INBOUND_FLAGGED | 20 | The subject received bridged USDC through CCTP from a source-chain wallet that is sanctioned or USDC-blacklisted on its own chain, within 30 days. Evidence carries counts and source chains only. | CCTP MessageTransmitterV2 tail + yente + source-chain FiatToken.isBlacklisted (src/lib/cctp) |
AGENT_DISPUTED | 15 | That agent carries negative feedback (value < 0 or a dispute/fraud/scam tag) or a failed validation (response < 50). | ERC-8004 Reputation + Validation registries |
NO_HISTORY | 10 | No on-chain footprint on Arc at all (never seen, zero txs). Takes precedence over FRESH_WALLET. | RPC |
HIGH_CONCENTRATION | 10 | A hop-1 funder of the subject also funded several other payees or graded nodes across the network. | network store (NETWORK_MIN_CONCENTRATION, default 3) |
FRESH_WALLET | 8 | First seen under 7 days ago, or fewer than 5 transactions. | RPC nonce + first incoming USDC transfer |
NETWORK_SHARED_FUNDER | 8 | The subject shares a hop-1 funder with 3 or more of your own payees. | your payee funders (client-scoped) |
AGENT_REGISTERED | -5 | Positive signal: the subject owns (or is the agentWallet of) an ERC-8004 agent in Arc's IdentityRegistry. Evidence carries the agentId, agentURI and registry addresses. | ERC-8004 IdentityRegistry 0x8004A169… (src/lib/erc8004) |
AGENT_VALIDATED | -5 | Positive signal: that agent has at least one answered validation from a validator other than itself. | ERC-8004 ValidationRegistry 0x8004Cc84… |
CLEAN | 0 | Explicit positive: no signal from any source. Score 0. | - |
NETWORK_HELD_ELSEWHERE scores 10 for exactly one other client and 20 for two or more. NETWORK_SHARED_FUNDER needs 3 of your payees on the same funder. Source: src/lib/scoring/rules.ts.
How weights combine
// Repeated hits at the same hop and signal stack with diminishing returns.
weight(i) = round(base × 0.5 ^ i) // i = 0, 1, 2 … per (hop, signal)
// two sanctioned hop-1 funders: 30 + 15 = 45 · three: 30 + 15 + 8 = 53
score = clamp(0, 100, Σ weights)
if (any of SANCTIONS_DIRECT | USDC_BLACKLISTED | PROTOCOL_BLOCKLISTED) score = max(score, 61)
tier = score ≤ 20 ? LOW : score ≤ 60 ? MEDIUM : HIGH- Hard-hit floor
- SANCTIONS_DIRECT, USDC_BLACKLISTED, PROTOCOL_BLOCKLISTED each weigh 100 and force the score to at least 61, the bottom of HIGH.
- Name matches
- A sanctions hit matched on a name needs matcher confidence ≥ 0.7; address matches always count.
- Fresh wallet
- first seen < 7 days or < 5 txs; NO_HISTORY wins when both are zero.
- Prior HIGH
- looks back 30 days in CompliR's own history.
- Determinism
- “now” is the bundle's collectedAt, never the clock; funders are de-duplicated by (hop, address) and sorted before scoring; reasons are sorted (weight desc, code asc).
- CLEAN
- returned alone with weight 0 when nothing fired; evidence records depth and how many funders were checked.
Worked example: a fresh wallet (8) whose hop-2 funder is sanctioned (15) scores 23 → MEDIUM. Add a verified community tip (15) and it is 38, still MEDIUM; a tip can corroborate but never reach HIGH on its own. A direct USDC blacklist flag is 100 → HIGH regardless of anything else.
Rules decide score and tier; the Risk Analyst decides everything else.