Skip to content

Security audit 2026-09-23: ADR 0003 payment-scan analysis - #11

Draft
RunTimeAdmin wants to merge 3 commits into
mainfrom
cursor/security-audit-2026-09-23-cd7b
Draft

RunTimeAdmin wants to merge 3 commits into
mainfrom
cursor/security-audit-2026-09-23-cd7b

Conversation

@RunTimeAdmin

@RunTimeAdmin RunTimeAdmin commented Sep 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

Comprehensive security audit of the Sigvara protocol, corrected against commit c98e462 (current HEAD of main after the checkpoint fix), covering:

  • Contracts: SigvaraStaking, SigvaraIdentity, SigvaraReputation, SigvaraOracleBond, SigvaraEpochFees, SVRToken
  • Oracle operators: Payment-scan (ADR 0003 — now implemented), epoch proposals, checker divergence detection, HTTP endpoints
  • SDK/SigvaraGate: Nonce handling, challenge-response authentication, audience binding
  • Deployment/ops: Secrets handling, compose networking, admin role configuration

Correction Note

SEC-01 as originally written was factually wrong: it reported the ADR 0003 pull scanner as unmerged. It was not — oracle/payment-scan.js landed in 68a871d, before this audit was published. One of the predicted risks (checkpoint advance past unprocessed events) was present in the merged code and is fixed in c98e462.

Key Findings

Go/No-Go Recommendations

Decision Point Recommendation
Enable paymentScan on both live oracles CONDITIONAL GO
Further product work vs pause-for-fixes GO

Finding Summary

Severity Count Status
Critical 0 —
High 2 Testnet-acceptable, mainnet blockers
Medium 5 Testnet-acceptable
Low 4 Informational/minor
Informational 3 Design notes

SEC-01: Payment-Scan Implementation Analysis

The audit now includes detailed analysis of the implemented payment-scan with file:line citations:

Risk Status Location
Silent empty filters Partly addressed via batching payment-scan.js:47-55
Double-credit vs /attest Addressed via usedPaymentTxs payment-scan.js:179, index.js:315
success: null / hasOutcome Addressed payment-scan.js:193-195, payments.js:269-270
Reorg handling Addressed via MIN_SCAN_CONFIRMATIONS=6 floor payment-scan.js:57-83
Checkpoint advance Fixed in c98e462 payment-scan.js:215-232
Self-payment bypass Addressed payment-scan.js:183-186
Named refusals Addressed payment-scan.js:175-186

High-Severity Items (Mainnet Blockers)

  1. SEC-02: All privileged roles on testnet are single EOA — SplitAuthority.s.sol exists but not run
  2. SEC-03: Oracle operator key compromise blast radius — no HSM/threshold signature support

Gaps Closed

  • SEC-10: Evidence gap now CLOSED by ADR 0003 implementation
  • Registration signature requirement properly implemented
  • Dispute freeze works correctly
  • Bond check on all Active transitions

Files Changed

  • docs/SECURITY_AUDIT_2026-09-23.md — Full audit report with severity-ordered findings, updated with real code analysis
Open in Web Open in Cursor 

cursoragent and others added 3 commits September 23, 2026 04:09
Comprehensive security review covering:
- Contracts (staking, identity, reputation, oracle bond)
- Oracle operators (payment-scan ADR 0003 analysis)
- SDK/SigvaraGate nonce handling
- Deployment/ops configuration

Key findings:
- CONDITIONAL GO for enabling paymentScan on testnet
- GO for further product work
- 2 High severity items (mainnet blockers, testnet acceptable)
- 5 Medium severity items (testnet acceptable)
- Regression check against 17 Sep review shows most gaps closed

No critical blockers for testnet operations.

Co-authored-by: David Cooper <david@runtimeadmin.com>
SEC-01 reported the ADR 0003 scanner as unmerged. It was not. oracle/payment-scan.js
landed in 68a871d, two commits before the pin this audit used, so the finding was
written against code that had already been superseded.

The error inverted the finding rather than merely dating it. SEC-01 listed risks to
watch for when the scanner was eventually built. One of them, checkpoint advance past
unprocessed events, was present in merged code: a credit whose block timestamp could
not be read was left uncredited while the checkpoint advanced past it anyway, and the
scan only moves forward, so that payment would never have been looked at again. Fixed
in c98e462 by checkpointAfter.

So the auditor's list was good enough to find a live defect, and the wording buried
that as hypothetical future risk. Recorded plainly rather than quietly corrected.

Each predicted risk is now checked against the real code and marked addressed, partly
addressed or fixed, with the remaining gap named: there is still no canary to tell a
filter that matches nothing from a genuinely quiet range.

Nothing else is altered. SEC-02 through SEC-06 were verified against the live
deployment and stand as written, and the Go / Conditional Go verdict is unchanged.
Claims added here were checked against main: 24 scanner tests, checkpointAfter with
five, recipient batching at 50, confirmations floor of 6, scan disabled by default.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Add file:line locations to SEC-01 risk table
- Add success:null/hasOutcome, self-payment, and named refusals to risk table
- Update SEC-04: document split confirmation defaults between /attest and scan
- Update SEC-10: mark evidence gap as CLOSED by ADR 0003
- Add Implementation Location table with file:line references
- Add Test Coverage section documenting payment-scan.test.js
- Update Risks table with current status
- Mark verified items in ADR 0003 recommendations
- Update operational checklist with verified items and metrics to monitor

Co-authored-by: David Cooper <david@runtimeadmin.com>
@cursor
cursor Bot force-pushed the cursor/security-audit-2026-09-23-cd7b branch from 05befd0 to 1857e60 Compare September 23, 2026 04:11
@cursor cursor Bot changed the title Add security audit report 2026-09-23 Security audit 2026-09-23: ADR 0003 payment-scan analysis Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants