Nullark keeps ETH and settlement state in a public contract. You keep the recovery material for each deposited bundle. The client restores a child, builds its witness, and proves the withdrawal locally.

Protocol map

Three records, three jobs

Each layer has one job. The recovery envelope restores secrets, the pool records deposits and spends, events reconstruct public state, and the runtime keeps every piece pointed at the same deployment.

Value lifecycle

  1. The client prepares a template, child secrets, encrypted recovery envelope, and deposit proof. Save the recovery envelope before submission.
  2. The wallet deposits the template’s parent amount with one bundle commitment.
  3. The pool inserts that commitment and accepts a new root.
  4. The client restores the bundle and selects one unspent child.
  5. The client proves child ownership and bundle membership without publishing the witness.
  6. The pool records that child’s nullifier, accrues the fee, and sends net ETH.
  7. Any sibling remains available under the original bundle commitment.

Read by question

Core invariants

  • Each bundle commitment is inserted once.
  • Each child nullifier is spent once.
  • Parent value equals the sum of its two child slots.
  • Proof inputs bind the intended root, child, destination, amount, fee, chain, pool, context, and payload.
  • Pool accounting and ETH balance cover allowed exits without double-counting fees.
  • Recovery material stays out of RPC requests, analytics, logs, and public support channels.
These are design rules, not a blanket security claim. Read What a Groth16 proof proves and Published status for the evidence boundary.