SIGIL

Methodology

The published scoring rubric — deterministic first, AI second, dissent shown.

Sigil's scorer is pure, versioned, and public. The same input always produces the same verdict. This page is the rubric that ships in @sigil/coreRUBRIC_VERSION = "1.0.0".

Bands

Risk score = sum of triggered rule weights, capped at 100.

bandrange
PASSscore < 30
WARN30 ≤ score < 70
BLOCKscore ≥ 70

Any hard finding forces BLOCK and sets riskScore = max(rawSum, 90), capped at 100. The ambiguous band is [35, 65] — only there (or in explicit mode: "deep") may the AI panel convene.

The rule table (verbatim from the shipped engine)

rule idweighthard
COUNTERPARTY_SANCTIONED100hard
COUNTERPARTY_FLAGGED_MALICIOUS100hard
APPROVAL_ALL_TO_EOA100hard
TOKEN_HONEYPOT100hard
APPROVAL_UNLIMITED_UNVERIFIED45soft
TOKEN_SELL_TAX_EXTREME (≥ 2500 bps)40soft
RECIPIENT_FRESH_WALLET30soft
APPROVAL_UNLIMITED (verified spender)25soft
COUNTERPARTY_MIXER25soft
SIM_REVERTED20soft
TOKEN_SELL_TAX_HIGH (≥ 1000 bps)20soft
TOKEN_MINTABLE_ACTIVE_OWNER15soft
TOKEN_BLACKLIST_FUNCTION15soft
TOKEN_HOLDER_CONCENTRATION (≥ 30%)15soft
TOKEN_LOW_LIQUIDITY (< $10k)15soft
COUNTERPARTY_UNVERIFIED_CONTRACT10soft
TOKEN_UPGRADEABLE5soft

Findings are sorted by severity (critical, high, medium, low, info) in every verdict, each carrying evidence strings naming the sources that produced it.

Why deterministic-first

~95% of calls never touch an LLM. That is a trust feature, not a cost hack:

  • Reproducibility — anyone can re-run the rubric on the same inputs and get the same verdict. An LLM cannot promise that.
  • Auditability — every weight above is public; a verdict is explainable as a sum, not a vibe.
  • Adversarial resistance — prompt injection in calldata or token metadata cannot argue a deterministic rule out of firing.

The panel: escalate-only, dissent shown

Inside the ambiguous band, three differentiated adjudicators — a conservative auditor, a pragmatic operator, and an adversarial red-teamer — vote PASS/WARN/BLOCK using only the evidence the engine already produced (inventing facts is forbidden). Majority may escalate the verdict; it can never loosen one, and hard BLOCKs are untouchable.

Every vote — including disagreeing ones — ships verbatim in verdict.panel.votes / verdict.panel.dissents. Single-model tools hide uncertainty behind one confident answer; Sigil shows you the disagreement. If the panel times out, loses quorum, or hits its daily cost cap, the verdict degrades to the deterministic result and coverage.unavailable records panel.

Bypass-class defenses

Naive firewalls are beaten in known ways; Sigil closes them explicitly:

  • Real simulation, honestly labelled. With an X Layer RPC configured, Sigil runs the actual transaction (eth_call + a native-balance state override) so a honeypot/paused/blacklisted token that reverts on transfer is caught — the verdict's simulation.method reads "simulated". Without an RPC it degrades to "derived" (read from calldata) and says so; static output is never labelled as executed.
  • A failed sim is never a silent PASS. A transaction that actually reverted in simulation can never be reported PASS — it is floored to at least WARN. Silence is not safety.
  • Casing normalization. Every hex/address is normalized (a 0X… prefix can't slip past a startsWith("0x") check) and all address comparisons are case-insensitive.
  • Off-chain signatures. eth_signTypedData never appears as calldata, yet a malicious EIP-2612 Permit or Permit2 PermitSingle is how modern drainers take an allowance. Pass typedData and Sigil screens the signing request through the identical scorer before you sign.

Honest coverage

A failed data source never fakes an answer and never aborts a verdict. It is recorded in coverage.unavailable (and gap-tagged inside sources), so the caller always knows what was actually checked. Degradation semantics are part of the contract — see the Reference.