On-chain
ShieldedPool — the entry point for every user action. Holds the commitment tree, the nullifier set, and the proof verifiers. Never learns an amount. ElGamalAccumulator — holds the running encrypted total per market, per side. It stores ciphertext points and has no ability to decrypt anything. Adding a stake is point addition on BabyJubJub. Vault — custodies collateral and holds the outcome. Splits deposits into YES/NO positions and pays out against the winning side. EncryptedParimutuelPool — settlement. Accepts the decrypted final totals along with a Chaum-Pedersen proof that the decryption is honest with respect to the published committee key. This is the only path a payout ever reads. PythResolver — resolves a market from signed price data at a timestamp committed before betting opened. See Resolution.Off-chain
Sequencer — batches commitments into the tree and serves Merkle paths.Inserting one commitment costs more gas than a user action can afford, so actions only queue
a commitment and the sequencer grafts 64 at a time. Batching is a correctness requirement of
the gas budget, not an optimisation.
Mid-market odds are indicative. Verifying them on-chain would require the plaintext totals,
which is exactly what the encryption exists to prevent — so no payout ever reads them.
Settlement goes through a cryptographic proof instead. The odds inform; the money is proved.
The flow
1
Deposit
Collateral enters the Vault, a commitment is queued, and the sequencer grafts it into the
tree.
2
Bet
A proof shows you own an unspent note without revealing which. The encrypted stake is
added to the accumulator. A position note is queued.
3
Resolve
The oracle resolver reads a signed price at the committed timestamp and sets the outcome.
4
Settle
The committee publishes final totals with a proof that the decryption is honest.
5
Redeem
A winning position becomes a settled note. No collateral moves.
6
Withdraw
A settled note becomes public collateral, in a fixed denomination, at a time of your
choosing.