Security

Monitoring

The pool is immutable, so the interesting question is not whether it changed — it cannot. The question is whether what it holds still matches what it owes, and whether the one lever anybody holds has been touched. Both are read straight off the chain, by a script that ships in the repository and runs on your machine.

Open source · run it yourself
npm run watch in the CLI repository. It needs no key and no permission — every fact it reads is public.

What it checks

CheckWhat it reads
The turnstilePer token, the pool’s accounted value against its real balance. Every token that ever entered either pool reconciles exact to the wei.
GovernanceOwner, and both verifier addresses, against a committed baseline. A verifier swap is timelocked for seven days, and a swap already executed shows up as address drift even if the proposal was never seen.
Relayer floatThe balance of each relayer’s payout address, read from chain and divided by the relayer’s own quoted fee, so the number is in spends rather than ether.
Relayer identityThat it answers, serves this chain and this pool, quotes a non-zero fee, and pays out from the address the baseline names.
A control that asks the thing it watches is not a control
The relayer reports its own float in every quote, and reading that number would have been one HTTP call. The measurement is the on-chain balance instead. The daemon’s own figure is still read, purely as a cross-check, and it alarms when it claims more than the chain shows.

State, not logs

A log watcher on this chain is either blind or throttled: one public RPC refuses historical log queries outright and the other rate-limits them hard. So the watcher reads state. That turns out to be the stronger design anyway — state catches a change that already happened even if nobody was watching when it did, which is exactly the case a log tail misses.

Exit codes

0   clean
1   alert — something drifted from the baseline
2   could not check — an RPC failed, and that is not the same as clean

The third one exists on purpose. A monitor that reports success when it could not reach the chain is worse than no monitor.

The alarms are proven to fire

A monitor that has never alarmed is untested, not clean. A mutation harness stands a stub relayer on loopback, breaks one thing at a time, and requires every alarm to fire — all seven of them do. It runs a control first and refuses to report at all if the unmutated watcher already alarms.

npm run watch                # governance + turnstile + relayer float
npm run test:watch-mutants   # prove every alarm still fires

Related

  • Audits — every artifact behind these checks, published in full.
  • Trust model — what governance can and cannot do.
  • Onchain events — if you would rather index it yourself.