v0.3 · 5 detectors · MIT

Watch the chain
before it drains your treasury.

Custos Nox is an open-source real-time attack monitor for Solana multisigs and DAOs. It detects all 4 on-chain vectors used to drain $285M from Drift on April 1, 2026 — before the stolen funds leave the chain.

5
Detectors live
205
Tests passing
$285M
Drift loss tracked
< 1s
Alert latency

What it catches

Every detector maps directly to a step in the Drift April 2026 attack chain. Any single one firing would have bought hours of response time.

Timelock Removal

Squads v4 + SPL Governance

CRITICAL
attack step · Realm timelock 6 days → 0

Fires when a governance timelock is removed or dropped below half. Matches the Drift step where the attacker collapsed the response window before draining funds.

Multisig Weakening

Squads v4

HIGH
attack step · Squads threshold 5-of-9 → 1-of-9

Fires when a Squads multisig signer threshold is reduced. Catches the moment a treasury becomes single-signer controlled — the irreversible pivot in most exploits.

Signer Set Change

Squads v4

HIGH
attack step · Members rotated — honest signers evicted

Fires when a Squads multisig's members vector is mutated. Removal of a legitimate signer or rotation fires high; pure additions fire medium. Catches the takeover vector where an attacker swaps honest co-signers for their own keys.

Privileged Nonce

System Program

CRITICAL
attack step · Durable nonce under attacker key

Fires on initialization or authority rotation of a watched durable-nonce account. Flags the precondition for pre-signed, replay-at-will withdrawal transactions.

Stale Nonce Execution

System Program

HIGH
attack step · Pre-signed tx executed from stale nonce

Fires when a durable nonce is advanced (a pre-signed transaction executes) more than 1 hour after the nonce was first initialized. Catches the final step in the Drift attack chain — the moment the attacker's pre-signed drain transaction lands.

How the Drift attack unfolded

The April 2026 Drift exploit was not a zero-day — it was a 9-day on-chain preparation. Every step was observable. None were flagged.

First alert fires 9 days before the drain.

Any single one of these detectors firing would have given treasury managers days to respond — pause withdrawals, rotate signers, or escalate to the community.

CRITICAL9 days before drain

Mar 23, 2026

Nonce initialized

PrivilegedNonceDetector

Attacker creates a durable nonce under a privileged key. A pre-signed drain tx is now valid and waiting.

CRITICAL6 days before drain

Mar 26, 2026

Timelock removed

TimelockRemovalDetector

Governance timelock dropped from 6 days to 0, closing the community's response window.

HIGH6 days before drain

Mar 26, 2026

Multisig migrated

MultisigWeakeningDetector

Security Council multisig migrated to a new 2-of-5 threshold with zero timelock — minimum quorum, instant execution.

HIGHDRAIN

Apr 1, 2026

$285M drained

StaleNonceExecutionDetector

Week-old pre-signed admin transfer executes. Funds move to attacker wallet within 12 minutes.

Attack chain replay

All four Drift attack steps replayed against a devnet harness, plus an adjacent signer-rotation event. Each fires a distinct detector within a second — the Drift sequence is the one that went undetected on mainnet in April 2026.

⚠ Not live mainnet data — sample events for demo purposes

2
Critical
3
High
0
Medium
0
Low

Severity breakdown — 5 sample events

Alert feed · devnet5 events
  • CRITICAL1m ago
    squads-timelock-removal
    Timelock removed on multisig AjULUVaCpzdGvCXgUkHLitkBR6nmn1M7AsHJ8sGgMZNy
    reason
    timelock_reduced
    previousTimelockSeconds
    86400
    currentTimelockSeconds
    0
    account
    AjUL…MZNy
  • HIGH3m ago
    squads-multisig-weakening
    Threshold weakened 3 → 1 on multisig AjULUVaCpzdGvCXgUkHLitkBR6nmn1M7AsHJ8sGgMZNy
    reason
    threshold_reduced
    previousThreshold
    3
    currentThreshold
    1
    account
    AjUL…MZNy
  • HIGH4m ago
    squads-signer-set-change
    Multisig AjULUVaCpzdGvCXgUkHLitkBR6nmn1M7AsHJ8sGgMZNy: 1 signer(s) removed, 1 added
    reason
    signer_set_changed
    account
    AjUL…MZNy
    removed
    8wNT…KuaB
    added
    Gpoj…x5Yh
    previousCount
    5
    currentCount
    5
  • CRITICAL5m ago
    privileged-nonce
    Nonce account 9rK8Ke7ZazGS7Knaj1i6oh9HBa2ocJCNhF9eDQegnfAS initialized with authority E9Q5UGyezdKVCZ8GDiAFRQfDarRb3REpTrYN3ytgEMzs
    reason
    nonce_initialized
    account
    9rK8…nfAS
    authority
    E9Q5…EMzs
  • HIGH8m ago
    stale-nonce-execution
    Stale nonce 9rK8Ke7ZazGS7Knaj1i6oh9HBa2ocJCNhF9eDQegnfAS advanced 73 min after creation (authority: E9Q5UGyezdKVCZ8GDiAFRQfDarRb3REpTrYN3ytgEMzs)
    reason
    stale_nonce_advanced
    account
    9rK8…nfAS
    authority
    E9Q5…EMzs
    staleMs
    4380000
    staleMins
    73
    thresholdMs
    3600000
    firstSeenAt
    2026…000Z

Self-host in 5 minutes

One binary, zero vendor lock-in. Runs on any Node.js 20+ or the published Docker image. Free-tier Helius or the public devnet RPC is enough to get started.

bash
git clone https://github.com/cryptoyasenka/custos-nox
cd custos-nox
npm install
cp .env.example .env        # edit CUSTOS_WATCH with your accounts
npm run dev                 # daemon connects, seeds baseline, starts watching
Prereqs
Node.js 20+, an RPC endpoint (Helius free tier works), accounts to watch (Squads PDA, SPL Governance realm, or nonce account).
Alerts go to
stdout by default. Optional Discord and Slack webhooks fan out every alert to every configured sink.
Reliability
WebSocket reconnect with exponential backoff, baseline seeding before subscribe, 5s per-detector timeout with low-severity surfaced errors.