SPECTRE Exact-Rule Gap Analysis (2026-05-16)
Author: spectre-solana-max engineering
Status: Gap analysis on the 7 incidents that detect class-level but
not exact-rule on the historical-incident replay benchmark.
Companion: spectre-historical-incident-replay-2026-05-15.md
Topline
| Metric | Initial | ACC-014 | Bucket A | AUTH-100 ext | ACC-021 init-write | ACC-015 ship |
|---|---|---|---|---|---|---|
| Mapped incidents | 28 | 28 | 24 | 24 | 24 | 24 |
| Exact-rule | 21 (75%) | 23 (82%) | 21 (87%) | 22 (91%) | 23 (96%) | 24 (100%) |
| Class-level | 28 (100%) | 28 (100%) | 24 (100%) | 24 (100%) | 24 (100%) | 24 (100%) |
| โ rows | 7 | 5 | 3 | 2 | 1 | 0 |
๐ฏ 100% exact-rule detection achieved on the historical-incident
replay benchmark. Every mapped Solana exploit incident catalogued
under documents/incidents/*.yml now fires at least one rule from its
architectural fingerprint.
Update 2026-05-16: Bucket C (ACC-014 ship) flipped both
WORMHOLE-* incidents to โ at commit 06e5a568. Bucket A
(replay-script scoring fix) at commit d9a3e7a5 merges duplicate-id
incidents across yml files into a single row, which collapses the 5
dup rows (counted as 28 โ 24 mapped) and surfaces CASHIO-INFINITE-MINT's
dex_amm-variant fingerprint that fires ACC-013 exact-rule. Bucket B
(Raydium AMM v4 corpus probe) confirmed pre-incident source is NOT
publicly available (earliest raydium-amm commit is 2023-12-25, ~1
year after incident); added an architectural-reference snapshot at the
current sha (following the precedent of 25-drift-v2-architectural-reference
and cypher-protocol-cache-2023-08) and remapped both Raydium 2022-12
incidents to it. Status unchanged on the metric (RAYDIUM-OWNER-KEY
stays โ via GOV-001 on the new corpus; RAYDIUM-ADMIN-KEY stays โ
because AUTH-100 doesn't recognize Raydium's UpdateConfigAccount
generic-config-setter pattern โ that's a rule precision gap, not a
corpus issue). Remaining โ: CASHIO-FAKE-COLLATERAL (D.1),
RAYDIUM-ADMIN-KEY (rule-precision gap on AUTH-100, not corpus),
METAPLEX-CMV1-REINIT (D.2).
Every mapped incident now fires at the architectural-class level. The gap is exact-rule promotion: which existing rule should fire on each incident's specific shape, and what tuning closes the gap.
Per-incident analysis
The 7 โ incidents fall into four buckets, in order of fix cost:
Bucket A: Replay-script scoring bug (1 incident, ~1 hour to fix)
CASHIO-INFINITE-MINT-2022-03 appears twice in the incident
catalogue: one entry in lending_perps_incidents.yml (fingerprint =
ACC-010 + ACC-011 + MINT-001) and one in dex_amm_incidents.yml
(fingerprint = ACC-013 + ACC-010 + MINT-001 + INV-002). The Cashio
corpus emits ACC-013 โ so the dex_amm fingerprint would score exact-
rule โ, but the replay script keys scored[] by incident id and the
two YAMLs share an id. The second-loaded fingerprint silently overwrites
the first.
Fix: in replay_incidents.py, key scored[] by (id, source_file),
or merge fingerprint variants per id. Either way, Cashio's dex_amm
variant becomes โ ACC-013. Trivial. Promotes 1 incident.
Bucket B: Corpus mapping mismatch (1 incident, ~3 days to fix)
RAYDIUM-ADMIN-KEY-2022-12 is mapped to 37-raydium-cp-swap, but
the incident was on Raydium AMM v4, not the CP-Swap program. AMM v4
is where the single-admin upgrade authority lived; CP-Swap is a newer
redesign. The CP-Swap corpus emits GOV-001 (which catches the sibling
incident RAYDIUM-OWNER-KEY โ) but doesn't carry the AMM-v4 admin
surface that RAYDIUM-ADMIN-KEY's fingerprint (AUTH-100 + AUTH-120 +
AUTH-110) targets.
Fix: add a raydium-amm-v4 corpus snapshot, map RAYDIUM-ADMIN-KEY
to it. Either AMM v4 source is public on the Raydium org or the
incident is "no public source" (the same case as Pump.fun in the
backlog). Probe required. Promotes 1 incident if source available.
Bucket C: Sysvar binding-check tuning on ACC-013 (2 incidents, ~1 week)
Both WORMHOLE-SIG-REPLAY-2022-02 and WORMHOLE-SOLANA-2022-02 fire
on the same root cause: the Wormhole pre-hack program accepts a
Sysvar Instructions account passed by the caller without binding it
to the canonical sysvar pubkey
(Sysvar1nstructions1111111111111111111111111). The attacker substitutes
a forged account with crafted contents and bypasses signature
verification.
Both fingerprints cite ACC-010 (account-ownership) and ACC-013
(account-binding constraint). Neither fires on the Wormhole corpus โ
ACC-013's current implementation looks for typed Anchor Account<'info, T> fields whose #[account(...)] constraints are missing, but the
Wormhole bug is in a native Solana program that processes accounts via
the legacy AccountInfo route. No binding-constraint check applies
in that route.
Fix: extend ACC-013 (or a sibling ACC-014) to recognize the
sysvar-misuse pattern: any account field whose type is AccountInfo
and whose name matches sysvar.*instruction (or similar) without a
paired if account.key != solana_program::sysvar::instructions::ID { return Err(...) } body check. Same for clock, rent, etc.
This is the closest existing-rule path. Alternatively, ship a new
detector SYSVAR-010 scoped to "untrusted sysvar accept" โ cleaner
ontology but more wiring. Estimated ~1 week. Promotes 2 incidents.
Bucket D: Per-rule precision tuning (2 incidents, ~1-2 weeks each)
CASHIO-FAKE-COLLATERAL-2022-03
Fingerprint = ACC-010 + ACC-011 + PDA-030 + MINT-001. Cashio
corpus emits ACC-013 (3x), ACC-020, ACC-021, CPI-003,
CPI-020. None of the four fingerprint rules fire. Sibling rule
ACC-013 IS firing but isn't in this fingerprint variant (it IS in the
CASHIO-INFINITE-MINT dex_amm variant โ see Bucket A).
The bug shape: Cashio's saber_swap.arrow account is accepted without
verifying its mint field; the attacker constructs a fake arrow account
with a worthless mint. ACC-013 (Anchor binding-constraint gap) IS the
right rule architecturally, but the existing v1 implementation requires
the field type to be a typed Anchor Account<'info, T> โ Cashio's
field is AccountInfo per native conventions. ACC-013 needs the same
extension as Bucket C: native-mode awareness.
Fix: same ACC-013 lift to native programs as Bucket C. The two
buckets share the fix. Promotes Cashio Fake Collateral to โ via
ACC-013 once the native lift lands.
This was the pattern of work we already shipped for AUTH-100 / GOV-001
/ ORC-002 / ARI-040 in the May 15 session. ACC-013 native-lift is
the natural next entry in that family.
METAPLEX-CMV1-REINIT-2022-01
Fingerprint = ACC-021 + AUTH-100. Metaplex CMv1 corpus emits
ACC-010, ACC-013, ACC-020, CONFIG-010, CROSS-005, INV-001,
LIAB-001, QUAL-003. Neither ACC-021 (re-init check) nor AUTH-100
(single-step admin) fire on CMv1, even though sibling ACC-013 (account-
binding) and CONFIG-010 (config-field gap) DO fire on the same corpus.
ACC-021 IS firing on other corpora (Cashio, Jet v1) so the rule itself
works. The CMv1 source pattern must not match ACC-021's detection
heuristic. Worth a focused read of CMv1's initialize_candy_machine
handler against ACC-021's discriminator-check pattern. Likely an
implementation detail (CMv1's init pattern uses a different idiom).
Fix: trace CMv1's initialize handler shape, adjust ACC-021's matcher to recognize the variant. Estimated ~1 week. Promotes 1 incident.
Promotion path
If executed in order:
| Bucket | Fix scope | Incidents promoted | Cumulative exact-rule rate |
|---|---|---|---|
| Start | โ | 0 | 21/28 = 75% |
| A: scoring fix | ~1 hour | +1 | 22/28 = 79% |
| C: ACC-013 native-lift | ~1 week | +2 (both Wormhole) | 24/28 = 86% |
| D.1: ACC-013 native-lift (already) | covered by C | +1 (Cashio Fake) | 25/28 = 89% |
| B: Raydium AMM v4 corpus | ~3 days | +1 (if source public) | 26/28 = 93% |
| D.2: ACC-021 CMv1 matcher | ~1 week | +1 | 27/28 = 96% |
~3 weeks of focused work promotes 6 of 7 โ incidents to โ, taking exact-rule from 75% to ~96%. The remaining 1 incident (Raydium AMM v4) is gated by corpus source availability, not rule work.
Note on "extras" counts
Every โ incident also has extras (other rules that fire on the same
corpus, not in the fingerprint). Median extras = 7. This is informative
for triage: e.g. Metaplex CMv1 fires 8 distinct rules including
CONFIG-010 and CROSS-005 โ both genuine architectural patterns on
the CMv1 source that simply don't correspond to the historical bug
class. The replay benchmark deliberately scores against the published
fingerprint, not against "all reasonable concerns" โ extras count
preserves the signal that SPECTRE is finding real things even when
the fingerprint-specific match is a miss.
Out of scope for this analysis
- Unmapped incidents (16 of 44): need corpus snapshots first; see
incident-corpus-backlog-2026-05-15.md. - Tier-1/2 distribution items: see
spectre-distribution-roadmap-2026-05-16.md. - Tier-3 integration tracks (FV / fuzzing / monitoring): see the
three
spectre-*-integration-2026-05-16.mddocs.
Recommended ordering
- Bucket A (1 hour, +1 incident) โ trivial replay fix; lands a real โ for free.
- Bucket C + D.1 (~1 week, +3 incidents) โ
ACC-013native-lift single piece of work covers both Wormhole incidents AND Cashio Fake Collateral. Highest leverage per unit work. - Bucket B (probe + ~3 days, +1 if source available) โ Raydium AMM v4 corpus discovery. May be blocked by source availability.
- Bucket D.2 (~1 week, +1) โ Metaplex CMv1 ACC-021 matcher tune.
After all four: exact-rule rate ~96% (27 of 28 mapped).