07

V1 Mainnet · Private → private, another token

Swap

A private swap trades one token for another without leaving the pool. Your notes pay, the pool itself trades on a DEX, and what you buy lands as a new private note. The chain sees a trade happen — never whose it was, or where the output went.

Sent by

The relayer

Proof

withdraw circuit, reused

Venues

Uniswap V3 · Capricorn

Notes

up to 4 in → 3 out

Menoid app

takes the best quote

makes the proof

proof + swap data

Relayer

checks its fee

submits swap()

swap()

NoidPool

verifies · spends

finishes your note

tokenIn → · ← tokenOut

DEX

Uniswap V3

or Capricorn

The pool trades through a whitelisted adapter and measures what came back; the bought note is finished on-chain.

The quote

Menoid’s backend — public data only

  1. 1Quotes every route — each Uniswap V3 fee tier, two-hop paths and, on Monad, Capricorn’s pools — and returns the best: the adapter, the route, the expected output.

In your browser

  1. 2Sets minOut from the quote and your slippage, and a deadline.
  2. 3Picks notes of the token you sell covering amountIn + fee; the outputs are your change and the relayer’s fee note.
  3. 4Fixes the owner of the note you’re buying before its amount exists: a fresh rOut, npkOut = Poseidon(3, userCommitment, rOut).
  4. 5Encrypts (tokenOut, rOut) to your viewing key with the flag “amount from event”.
  5. 6Hashes the adapter, tokenOut, minOut, deadline, npkOut, route and encrypted data into extDataHash, and proves with the withdraw circuit (publicToken = tokenIn, publicAmount = amountIn).

At the relayer

  1. 7Checks its fee note, simulates, and submits swap(calls).

Inside NoidPool

  1. 8Checks swaps aren’t paused, tokenOut is accepted, the adapter is whitelisted, the deadline hasn’t passed, minOut > 0 and npkOut is valid — then the root and nullifiers.
  2. 9Verifies the proof and marks the nullifiers spent — before any external call.
  3. 10Sends amountIn to the adapter, which trades on the DEX and returns tokenOut to the pool.
  4. 11Measures: exactly amountIn left the pool, and out = its tokenOut balance after − before, with out ≥ minOut.
  5. 12Finishes your note: commitment = Poseidon(4, tokenOut, out, npkOut). Inserts the change, fee and bought notes, and emits NoteCreated ×3, OutgoingRecord and Swapped(tokenIn, tokenOut, amountIn, amountOut, commitment, adapter).

Back in your browser

  1. 13Decrypts the bought note, sees the flag, reads amountOut from the Swapped event and rebuilds the commitment — it’s yours.
VenueChainsHow the pool trades
Uniswap V3Monad · BaseUniswapV3Adapter → Uniswap’s SwapRouter02; every fee tier, one or two hops
CapricornMonadV3PoolAdapter swaps directly in the pools of nad.fun’s DEX (a Uniswap V3 fork), where Monad’s memecoins trade

If the price moves

Output below minOut, or the deadline passed? The whole transaction reverts — the nullifiers stay unspent and your notes stay exactly as they were.

On-chain, anyone can see

  • That a swap happened: the token pair and both amounts
  • Which venue’s adapter traded

Stays private

  • Who swapped
  • Which notes paid
  • Who owns the note that was bought