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
proof + swap data
Relayer
checks its fee
submits swap()
swap()
swap()
NoidPool
verifies · spends
finishes your note
tokenIn →← tokenOut
tokenIn → · ← tokenOut
DEX
Uniswap V3
or Capricorn
The quote
Menoid’s backend — public data only
- 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
- 2Sets minOut from the quote and your slippage, and a deadline.
- 3Picks notes of the token you sell covering amountIn + fee; the outputs are your change and the relayer’s fee note.
- 4Fixes the owner of the note you’re buying before its amount exists: a fresh rOut, npkOut = Poseidon(3, userCommitment, rOut).
- 5Encrypts (tokenOut, rOut) to your viewing key with the flag “amount from event”.
- 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
- 7Checks its fee note, simulates, and submits swap(calls).
Inside NoidPool
- 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.
- 9Verifies the proof and marks the nullifiers spent — before any external call.
- 10Sends amountIn to the adapter, which trades on the DEX and returns tokenOut to the pool.
- 11Measures: exactly amountIn left the pool, and out = its tokenOut balance after − before, with out ≥ minOut.
- 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
- 13Decrypts the bought note, sees the flag, reads amountOut from the Swapped event and rebuilds the commitment — it’s yours.
| Venue | Chains | How the pool trades |
|---|---|---|
| Uniswap V3 | Monad · Base | UniswapV3Adapter → Uniswap’s SwapRouter02; every fee tier, one or two hops |
| Capricorn | Monad | V3PoolAdapter 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
