08

V1 Mainnet · Private → public

Unmask

Unmasking sends private funds back to a public address — your own wallet or anyone else’s. Your notes are spent and the pool pays the tokens out. Like a send, it is proven in your browser and submitted by the relayer.

Sent by

The relayer

Proof

withdraw (Groth16)

Pays to

Any address

Notes

up to 4 in → 2 out

Menoid app

picks your notes

proves the unmask

proof + recipient

Relayer

checks its fee

submits withdraw()

withdraw()

NoidPool

verifies · spends

pays out

tokens

Any address

receives the tokens

publicly

In your browser

  1. 1You choose the amount and the receiving address — your wallet by default. For MON or ETH you can receive the coin itself instead of WMON or WETH.
  2. 2Picks notes covering amount + fee; the outputs are your change and the relayer’s fee note.
  3. 3Locks the recipient, the unwrap choice, the encrypted outputs and your outgoing record into extDataHash.
  4. 4Proves with the withdraw circuit: publicToken and publicAmount are the token and amount leaving the pool.

At the relayer

  1. 5Checks its fee note, simulates, and submits withdraw(calls).

Inside NoidPool

  1. 6Checks the amount (non-zero, below 2¹²⁸), the recipient (non-zero), and that only the wrapped native token is ever unwrapped.
  2. 7Checks the root and nullifiers, and verifies the proof against [root, 4 nullifiers, 2 commitments, relayer, token, amount, extDataHash].
  3. 8Marks the nullifiers spent, inserts the change and fee notes, and emits NoteCreated ×2 and OutgoingRecord.
  4. 9Only then — with every state change final — pays the recipient (unwrapping if asked) and emits Withdrawn(token, recipient, amount).

The recipient can’t be changed

The recipient is not an instruction to the relayer — it is part of extDataHash, which the proof commits to. A relayer that edits it makes the proof fail. The relayer is a courier, not a custodian: it can deliver your unmask or drop it, never re-address it.

Sends and unmasks can’t be paused

The pool’s owner can pause new masks and swaps, but sends and unmasks have no pause switch: funds in the pool can always leave.

On-chain, anyone can see

  • The token, the amount and the receiving address
  • When it happened

Stays private

  • Who unmasked
  • Which notes — and so which mask — paid for it

Stay in the crowd

The pool hides the link between a mask and an unmask, but amounts and timing can still speak: mask 7.31 USDC and unmask 7.31 USDC a minute later, and the coincidence is obvious. Different amounts and some time in between keep you hidden among everyone else.