🤖The Nonce Protocol
Private Token Transfers
Private transfers form the foundation of Nonce's privacy features. A transfer from Alice to Bob consumes one or more of Alice's notes and creates new notes: one or more for Bob representing the transferred amount, and typically one change note back to Alice for any remaining value. The zero-knowledge proof establishes that Alice knows the input notes, owns them through knowledge of the corresponding private key, and that the output values sum correctly with the inputs.
The circuit implementation takes as private inputs Alice's notes (values, tokens, public keys, blinding factors), her private key, Merkle paths proving note inclusion, Bob's public key for the recipient note, and random blinding factors for the output notes. It computes several things: first, commitment verification by hashing each input note and verifying the Merkle path leads to the public root. Second, ownership proof by verifying Alice's private key corresponds to the public keys in her notes through an elliptic curve signature verification within the circuit. Third, nullifier computation for each input note using Alice's private key. Fourth, output commitment creation for the recipient and change notes.
The public outputs include the Merkle root (verified against the contract's stored root), the nullifiers for spent notes (checked for uniqueness), and the commitments for new notes (added to the Merkle tree). Observers learn nothing about the transfer amount, sender identity, or recipient identity. They see only that some notes were consumed (via nullifiers) and some notes were created (via commitments), with no way to correlate these even if they occurred in the same transaction.
Private Swaps Through DeFi Integration
Private swaps present a more complex challenge because they require interaction with external decentralized exchanges while preserving privacy. Nonce solves this through adapter contracts that execute swaps on behalf of the privacy pool. The process involves several coordinated steps that happen atomically in a single transaction.
First, the user creates a zero-knowledge proof that they own notes denominated in the input token (say ETH) totaling at least the swap amount. The proof outputs nullifiers for these notes and reveals the swap amount publicly. Second, the privacy pool contract verifies this proof and marks the input notes as spent. Third, an adapter contract temporarily unshields the input tokens from the privacy pool, making them available as normal ERC-20 tokens. Fourth, the adapter executes the swap on a target DEX (like Uniswap) using the unshielded tokens, receiving the output token (like USDC). Fifth, the adapter immediately shields the received output tokens back into the privacy pool, creating a new note owned by the user.
This entire sequence happens in one atomic transaction. If any step fails, the whole transaction reverts and no state changes occur. The critical privacy property is that external observers (including the DEX) see only that the privacy pool contract swapped tokens. They cannot determine which user initiated the swap, how many users participated in the transaction, or the relationship between the input amount and previous transactions.
The zero-knowledge proof for a swap must establish several properties beyond a simple transfer. It proves ownership of sufficient input tokens through Merkle proofs and signature verification. It computes nullifiers for the consumed notes. It specifies the swap parameters (input token, output token, minimum output amount for slippage protection) as public outputs. It ensures the user will receive the output tokens by committing to their public key in the new note.
Private Yield Farming
Yield farming involves depositing tokens into lending protocols or liquidity pools to earn interest or fees. Nonce enables private yield farming through specialized yield adapters that interact with protocols like Aave and Moonwell. The privacy model ensures that individual positions remain hidden while allowing users to earn returns from their shielded assets.
When a user deposits to a lending protocol privately, they create a proof showing ownership of notes in the deposit token. The yield adapter verifies this proof, unshields the tokens, and deposits them to the lending protocol using the privacy pool's address as the depositor. The protocol issues receipt tokens (like aTokens from Aave) to the privacy pool. The user receives a yield note within Nonce that represents their claim on these receipt tokens and the corresponding accrued interest.
Yield notes differ from regular notes because they represent claims on external protocol positions rather than direct token holdings. A yield note contains the deposited amount, the target protocol identifier, the deposit timestamp, and the user's public key. The commitment to a yield note is cm_yield = Poseidon(v_deposited, protocol_id, timestamp, pkₒ, ρ). When withdrawing, the user proves ownership of their yield note, and the adapter withdraws from the lending protocol, receiving both principal and accrued interest. Both amounts are immediately shielded back into new regular notes owned by the user.
The privacy pool maintains separate Merkle trees for yield notes versus regular notes because they represent different types of claims. The total value deposited in each protocol must match the sum of all active yield notes for that protocol, ensuring the accounting remains consistent. Users can check their positions by decrypting their yield notes locally, seeing exactly how much they've deposited and the current interest rate, without revealing this information publicly.
DEX Aggregation for Optimal Rates
To provide the best swap rates, Nonce integrates with multiple decentralized exchanges and implements DEX aggregation. Before executing a private swap, the Nonce client queries various DEXs (Uniswap V3, Aerodrome, Curve, Balancer) to find the best available rate for the token pair. The swap adapter can split orders across multiple exchanges or route through intermediate tokens if that provides better effective pricing.
The aggregation logic runs off-chain in the client before proof generation. Once the optimal route is determined, those parameters get encoded into the zero-knowledge proof's public inputs. The proof commits to the swap route, ensuring the adapter must execute the exact trade the user approved. The adapter contract verifies the proof and then executes the trades according to the specified route, potentially interacting with multiple DEX contracts in sequence.
This approach preserves privacy because all route optimization happens before any on-chain transaction. The privacy pool makes the trades, not the individual user, so observers cannot correlate trading strategies with specific users. Even if an observer notices the privacy pool frequently uses optimal routes, they cannot determine whether this reflects one sophisticated user or the aggregate behavior of many users.
Last updated
