Pool welds
Per transition the pool verifies the main proof and, for classes 0 and 1, the wrapper proof, then checks by plain equality on publics:
payment_rootequal across main proof, wrapper, and (class 1) the hold.time_bucket ∈ {now, now − 1}wherenow = block.timestamp / BUCKET(BUCKET = 300 s). The wrapper never sees raw time, which keeps policies coarse and lets a proof straddle a bucket boundary.registry_root ∈ Registry.recentRoots()and!Registry.revoked(fi_index).state_in == fiState[fi_index]; after success the pool writesfiState[fi_index] = state_out.- Class 0 (initiate):
counterparty_fi_index == recipient_fi_index(a public of the initiate circuit);attestation_in == 0; the pool storessender_fi_index = fi_index,recipient_fi_index,deadline_bucket,attestation = attestation_out, and the envelope in the hold. - Class 1 (resolve):
hold.status == open;fi_index == hold.recipient_fi_index;counterparty_fi_index == hold.sender_fi_index;attestation_in == hold.attestation; the pool recordsattestation_outin the closed hold for audit and appends the output commitment. - Reclaim:
hold.status == open;time_bucket > hold.deadline_bucket; no wrapper proof; appends the refund commitment.
State concurrency: a stateful FI's transitions are serialized by
state_in; two proofs against the same state_in cannot both land. FI
backends must serialize proving per FI. Stateless FIs (fiState = 0
forever) have no ordering constraint. Sharded state roots are an open
question (§12).
State at phase 0 is provisional by design: a velocity ledger counts a hold that later rejects or is reclaimed. The sender FI never runs again for that hold in v1; an optional settle callback is deferred (§12).