V1 Mainnet · For builders
Reference
Constants
| Value | |
|---|---|
| Proof system | Groth16 on BN254 · Circom circuits · snarkjs, in the browser |
| Circuits | transfer (4 in, 3 out) · withdraw (4 in, 2 out; swap uses it too) |
| Field p (BN254) | 21888242871839275222246405745257275088548364400416034343698204186575808495617 |
| BabyJubJub order l | 2736030358979909402780800718157159386076813972158567259200215660948447373041 |
| Merkle trees | depth 20 (1,048,576 leaves) · 4-leaf chunks · last 100 roots · a new tree when full |
| Inputs per proof | 4, dummies filling the gaps · up to 4 proofs per transaction |
| Amounts | below 2¹²⁸ in every circuit |
| Note encryption | ECIES on secp256k1, compressed ephemeral key · 70-byte plaintext |
| Outgoing records | HKDF-SHA256 + AES-256-GCM · 138-byte plaintext |
| Domain separators | 1 userCommitment · 2 nk · 3 npk · 4 commitment · 5 nullifier |
Events
| Event | When |
|---|---|
| Registered(wallet, userCommitment, viewingPublicKey) | an address registers |
| ViewingKeyUpdated(wallet, viewingPublicKey, viewingEpoch) | updateViewingKey |
| KeysRotated(wallet, userCommitment, viewingPublicKey, keyIndex) | rotateKeys |
| NoteCreated(treeId, leafIndex, commitment, encryptedNote) | every new note |
| NullifierSpent(nullifier) | every spent note — 4 per proof |
| OutgoingRecord(firstNullifier, record) | every send, swap and unmask |
| Deposited(depositor, token, amount, commitment) | a mask |
| Withdrawn(token, recipient, amount) | an unmask |
| Swapped(tokenIn, tokenOut, amountIn, amountOut, commitment, adapter) | a swap |
| NewTree(treeId) | a tree filled and a new one opened |
Trusted setup
Groth16 needs a one-time setup per circuit; whoever knew all of its secret randomness could forge proofs. Menoid’s mainnet keys come from two phases. Phase 1 is the public Hermez / Polygon perpetual powers of tau. Phase 2 is Menoid’s own ceremony, per circuit: two contributions, then a random beacon taken from Monad block 113,529,011. The setup is sound if any single contributor was honest. Testnets use a separate development setup.
Who controls what
- NoidPool is an upgradeable proxy (UUPS, ERC-1967). Its owner can upgrade it, choose the accepted tokens and their per-mask caps, whitelist swap adapters, and pause masks or swaps.
- Sends and unmasks have no pause: funds can always leave the pool.
- Anyone can relay — a proof names who gets the fee. The relayer can refuse a transaction; it can’t read, redirect or forge one, or keep anything but its fee note.
- Your keys never leave your browser. The backend serves public data only.
