Skip to content

The limits of private AMMs with zero-knowledge proofs

Zero-knowledge proofs let someone prove they know a value without revealing it, which sounds like exactly what a private decentralized exchange needs — but a constant function market maker (CFMM) only works because its reserves are shared, public state that every trader trades against, and a formal result shows that publishing those reserves before and after any trade lets an outside observer solve for exactly what was traded, no matter how well the trader’s own inputs were hidden. Every proposed workaround — batching many orders together, adding statistical noise to prices, or mixing trades through repeated coordinators — trades away some combination of privacy, execution price, or decentralization, and none has reached production. Solana faces the identical mathematical obstacle for AMM trades, and instead ships confidential balances and transfers (Token-2022) rather than a private swap.

Picture a village with one shared, visible grain silo: you deposit wheat, take out barley, and the fill-level is painted on the outside for everyone to see, because that’s how neighbors verify nobody is cheating the shared stock. Even if you never see who visited, you can watch the painted level before and after a visit and work out precisely how much wheat went in and how much barley came out — hiding the visitor’s face didn’t hide what they did, because the silo has to stay legible for anyone to trust it.

A proof system can let you show you followed the rules without showing your private numbers. That works when only you care about the result. But a trading pool has to let strangers trade against it, so its balances must be visible to everyone — that is the entire point of the pool. If you can see the pool’s balances right before someone trades and right after, simple math tells you exactly what they bought and sold, even if their own transaction was wrapped in a proof that hid everything about them personally. Hiding the trader doesn’t hide the trade, because the trade is written into a shared account book that has to stay readable for the pool to work at all.

Scenario: a hidden-input CFMM with the same 10,000 ETH / 30,000,000 USDC pool used elsewhere on this site (spot price 3,000 USDC/ETH), where Alice’s transaction hides her own trade size behind a zero-knowledge proof.

  1. Before Alice’s trade (state: pool reserves 10,000 ETH / 30,000,000 USDC, publicly readable). Eve, an outside observer, queries the pool’s marginal price and one valid feasible trade — enough to solve for the exact reserves RR using the pool’s publicly known trading function.
  2. Alice’s hidden trade executes (state: reserves change to some new, unrevealed values). Alice’s transaction proves, in zero knowledge, that her trade was valid — but says nothing else about its size.
  3. After Alice’s trade (state: new reserves RaR_a, still publicly readable because the pool must remain tradeable). Eve repeats the same query and solves for RaR_a.
  4. Eve recovers the trade (state: Eve now knows Alice’s exact trade). Eve computes RaRR_a - R — exactly what Alice deposited and withdrew — with no knowledge of her identity or transaction contents, from two ordinary price queries.
  • Myth: Wrapping a swap transaction in a zero-knowledge proof makes the swap private. Reality: The proof can hide the trader’s identity and the internal computation, but the CFMM’s reserves must stay public for anyone to trade against it, and reserves alone reveal the trade (Angeris, Evans & Chitra, 2021-03).
  • Myth: Hiding token ownership is the same as hiding trading activity. Reality: A system that only hides who holds which tokens while leaving the pool’s trading activity fully public “does not discount” the impossibility — the trade itself is still visible even if the trader’s wallet isn’t (barryWhiteHat, ethresear.ch, 2020-07).
  • Myth: Adding random noise to a private AMM’s reported price is enough for privacy. Reality: If the noise doesn’t depend on the trade itself, an adversary can average many observations to cancel the noise back out and recover the true trade (tchitra, ethresear.ch, 2021-08).
  • Myth: Randomly shuffling the order of a batch of trades hides which one was the “whale” trade. Reality: A large trade still causes a large price move, so an adversary who can classify price changes above or below a threshold can identify the whale trade with high probability even after shuffling (tchitra, ethresear.ch, 2021-08).

A zero-knowledge proof can hide what you know, but a market maker has to publish what it knows — and reserves before and after your trade is all the arithmetic an observer needs.

Angeris, Evans, and Chitra formalize a CFMM as reserves RR and trading function ψ\psi, and consider an adversary “Eve” who can query the pool’s marginal price and any single feasible trade, both before and after a target trade by “Alice,” but sees none of Alice’s own transaction data. Their attack: (1) query the marginal price cc and a feasible nonzero trade Δ\Delta; (2) solve ψ(R)=λc, ψ(R+Δ)=ψ(R)\nabla\psi(R)=\lambda c,\ \psi(R+\Delta)=\psi(R) for the unique reserves RR; (3) after Alice trades, repeat the same two queries to solve for the new reserves RaR_a; (4) compute RaRR_a - R — exactly Alice’s trade. This has a unique solution whenever ψ\psi is strictly concave (essentially all live CFMMs, including Uniswap), with a binary-search extension sketched for non-strictly-concave functions like constant-sum markets.

This formalizes barryWhiteHat’s earlier intuition: “ZKPs allow you to prove the state of some data that you know. They do not let you prove about things that you do not know.” Anyone updating the shared pool state needs to know that state to construct a valid proof — and if they can see the state change, they can see what everyone else is doing, because the pool’s state is exactly the “global state” a zero-knowledge proof cannot keep both shared and hidden at once.

Proposed mitigations and why each is partial

Section titled “Proposed mitigations and why each is partial”

Angeris, Evans, and Chitra list two incomplete ways out: randomness in price (noise fixed per block so repeated queries can’t average it away, at the cost of new LP arbitrage losses) and batching orders (updating reserves once per batch, requiring enough non-Alice volume to hide inside, and a settlement delay).

Chitra’s follow-up formalizes this as differential privacy: a mechanism is (ϵ,δ)(\epsilon,\delta)-differentially private if Pr[A(S)B]eϵPr[A(S)B]+δ\Pr[\mathcal{A}(S)\in B] \le e^{\epsilon}\Pr[\mathcal{A}(S')\in B]+\delta for any two trade sequences S,SS, S' differing by one trade. The construction combines permuting trade order, adding Laplace-distributed noise to each trade size, and splitting large trades into comparable-sized pieces — because permutation alone is insufficient: for a vector like (T,1,,1)(T,1,\dots,1), permuting cuts an adversary’s uncertainty from logT!\log T! bits to only logT\log T (just TT distinct outcomes exist), letting a simple threshold classifier win. Splitting a trade of curvature κ\kappa into pieces costs roughly κlog(maxiΔi)\kappa\log(\max_i \Delta_i) in price impact — exponentially cheaper than raw batching’s Ω(T)\Omega(T) cost for equivalent privacy.

A structural counter-proposal: “weak secrecy”

Section titled “A structural counter-proposal: “weak secrecy””

leohio argues the impossibility can be circumvented, not solved, by keeping transaction history as a private zkRollup input with only the net state diff public, so many transactions resolve to one indistinguishable diff — provided balances are hidden behind per-user Merkle proofs and every user rotates through the coordinator role. barryWhiteHat’s reply raises the gap: rotating coordinators still requires sharing enough state with each new one to build their proofs, reintroducing the same leak one layer up.

A different kind of “zkAMM”: hiding computation, not trades

Section titled “A different kind of “zkAMM”: hiding computation, not trades”

A separate direction, exemplified by zkUniswap, uses a zk co-processor to move a swap’s arithmetic off-chain and verify it with a cheap on-chain proof — a scaling technique, not a privacy one: inputs, outputs, and reserve changes remain fully public for the proof to be checked against.

Same pool as the walkthrough: x=10,000x=10{,}000 ETH, y=30,000,000y=30{,}000{,}000 USDC, no fee for simplicity (ψ(x,y)=xy\psi(x,y)=xy, so ψ=(y,x)\nabla\psi = (y,x)).

Eve’s first query (before Alice’s trade). Eve reads the marginal price: c=(y,x)=(30,000,000, 10,000)c = (y,x) = (30{,}000{,}000,\ 10{,}000), normalized to 3,0003{,}000 USDC per ETH. She also observes one feasible trade, e.g. someone swapping Δ=(10, 29,970.03)\Delta=(10,\ -29{,}970.03) (10 ETH in, 29,970.03 USDC out, since y=xy/(x+10)=300,000,000,000/10,010=29,970,029.97y'=xy/(x+10)=300{,}000{,}000{,}000/10{,}010=29{,}970{,}029.97). Solving ψ(R)=λc\nabla\psi(R)=\lambda c and ψ(R+Δ)=ψ(R)\psi(R+\Delta)=\psi(R) for RR recovers R=(10,000, 30,000,000)R=(10{,}000,\ 30{,}000{,}000) exactly — the true reserves, even though Eve never saw them announced directly.

Alice’s hidden trade. Alice’s proof-wrapped transaction sells 500 ETH into the pool. The invariant requires xy=xy=3×1011x'y'=xy=3\times10^{11}; with x=10,500x'=10{,}500, y=3×1011/10,500=28,571,428.57y' = 3\times10^{11}/10{,}500 = 28{,}571{,}428.57 USDC. Alice receives 30,000,00028,571,428.57=1,428,571.4330{,}000{,}000-28{,}571{,}428.57=1{,}428{,}571.43 USDC. None of this — her identity, the 500 ETH, or the 1,428,571.43 USDC — appears in her transaction’s public fields.

Eve’s second query (after Alice’s trade). The pool’s reserves are now genuinely (10,500, 28,571,428.57)(10{,}500,\ 28{,}571{,}428.57), and both numbers are still exactly what any trader needs to compute their own trade against the pool, so they are necessarily public. Eve repeats her marginal-price-plus-feasible-trade query and solves the same two equations to recover Ra=(10,500, 28,571,428.57)R_a=(10{,}500,\ 28{,}571{,}428.57).

Recovering Alice’s trade. RaR=(500, 1,428,571.43)R_a - R = (500,\ -1{,}428{,}571.43) — Eve now knows, to the cent, that someone sold exactly 500 ETH for exactly 1,428,571.43 USDC, purely from two ordinary price queries either side of Alice’s transaction. No zero-knowledge proof Alice attached to her own transaction changes this, because Eve never needed to look inside it.

  • zkUniswap — a research proof-of-concept forking Uniswap v3 to compute the swap step off-chain via a zkVM (RISC Zero) and verify the result on-chain; explicitly a computation-scaling design, not a privacy design — inputs, outputs, and reserve changes remain public. github.com/0xfuturistic/zkUniswap
  • No production private CFMM, as of 2026-08. Across every design discussed in this research — noise-based, batching-based, differentially-private, or “weak secrecy” rotating-coordinator — none has shipped as a live, general-purpose private AMM; each remains a research proposal or proof-of-concept.
  • Shielded-pool privacy (Tornado-style mixers, zk payment systems) solves a different, narrower problem — hiding the link between a deposit and a withdrawal of the same asset — and does not extend to an AMM, where the whole point is exchanging one asset for a different one through shared, priced reserves.
  • n/a for AMM-level trade privacy — no source in this research describes a live, privacy-preserving swap mechanism on a Solana AMM; the underlying obstacle (a CFMM’s reserves must be public to be tradeable) applies identically regardless of chain.
  • Token-2022 Confidential Transfers — the closest Solana primitive, but it operates one level down: it hides account balances and transfer amounts between two parties using ElGamal encryption and zero-knowledge range proofs, for ordinary token transfers — not for AMM swap arithmetic, which still needs plaintext reserve values to compute a price. See /foundations/token-standards/.
  • The reserve-recovery attack itself. Angeris, Evans, and Chitra’s algorithm is not hypothetical friction but a concrete, five-step procedure requiring only public queries any trader can already make — any CFMM that claims privacy purely by obscuring trade data, without also changing how its reserves are read, is vulnerable to it by construction.
  • False sense of security from partial privacy. barryWhiteHat directly critiques a proposed design (pEthereum) that hides only token ownership: “the ownership of the tokens is private but what you do with them trade on Uniswap or compound is completely public. This post is claiming that you cannot make a uniswap which is not public. So your approach does not discount that” — a caution against privacy products that hide one layer while leaving the economically meaningful layer exposed.
  • Statistical de-anonymization of “noised” trades. tchitra shows that noise which is independent of the trades submitted can be removed given enough samples, and that a naive random permutation of a batch containing one outsized trade barely helps: permuting (T,1,,1)(T,1,\dots,1) only produces TT distinct outcomes (one per position of TT), so an adversary needs just logT\log T bits of information to find it, versus logT!\log T! bits if trade sizes were truly indistinguishable.
  • Probabilistic sandwich attacks survive imperfect privacy. If an adversary has binary classifiers accurate with probability 12+γ\ge \tfrac12+\gamma for identifying whether the large (“whale”) trade occurred among the first ii of a sequence, they can identify its position with probability 1O(γT)1-O(\gamma^T) using standard boosting arguments, and then front-run and back-run it — a “probabilistic sandwich attack” that degrades gracefully rather than failing outright as privacy weakens.
  • Does the impossibility generalize beyond strictly convex CFMMs? The paper proves its attack for strictly concave trading functions and sketches an extension for constant-sum markets, but explicitly states: “does the attack outlined here work for all strictly convex CFMMs, not just those that are 1-homogeneous? We suspect this is the case, but have not been able to give a reasonable proof except in other special cases” (Angeris, Evans & Chitra, 2021-03, Conclusion).
  • What would a genuinely privacy-preserving CFMM look like? The same paper calls this “likely much harder, but also far more important” than the impossibility result itself, and leaves it fully open.
  • Local differential privacy. tchitra asks whether users could add their own randomness individually and “pre-pay” for a chosen amount of privacy, removing the need for a shared source of on-chain entropy — left as an open research question in the ETH2 differential-privacy post.
  • Is “weak secrecy” real privacy or just relocated trust? leohio’s rotating-coordinator proposal and barryWhiteHat’s rebuttal that it “loses privacy when you gain the ability for anyone to execute” represent a live, unresolved disagreement about whether any design can escape the base impossibility rather than merely move the trust assumption around.
AspectEthereumSolana
Core obstacleCFMM reserves must be public for anyone to price and trade against themIdentical — the impossibility is about AMM mechanics, not chain architecture
Closest research artifactAngeris/Evans/Chitra impossibility proof; Chitra’s differential-privacy mechanism; zkUniswap (computation-hiding, not trade-hiding)None found specific to AMM trade privacy in this research
Adjacent primitive that does shipShielded pools / mixers (hide deposit–withdrawal linkage for one asset)Token-2022 Confidential Transfers (hide balances/amounts for transfers, not swaps)
Production private AMMNoneNone

The obstacle here is mathematical, not chain-specific: an AMM’s reserves are, by definition, the shared state that lets anyone trade against it without a counterparty, so hiding that state and keeping the AMM usable are in direct tension on any chain. Ethereum has produced the deepest published research on exactly how far around this obstacle one can get (noise, batching, differential privacy, rotating coordinators); Solana’s ecosystem has instead invested in confidential transfers as a chain-level primitive, which solves a real but narrower problem — private balances and payments — without addressing AMM swap privacy at all.

A Note on Privacy in Constant Function Market Makers — Guillermo Angeris, Alex Evans, Tarun Chitra, 1 March 2021. arxiv.org/abs/2103.01193

The paper asks directly: given that CFMMs like Uniswap, Balancer, and Curve publish every transaction, could a privacy-preserving version exist where “an adversary cannot correctly reconstruct the traded quantities from other public information”? It answers no, “under most reasonable models of an adversary,” and then explores what can be salvaged.

Setup. A CFMM is defined by reserves RR and trading function ψ\psi; the paper assumes ψ\psi strictly concave and increasing, the case for essentially all deployed CFMMs. The adversary, “Eve,” cannot see Alice’s transaction contents but can query the CFMM’s marginal price and any feasible trade both before and after Alice’s transaction, and knows only that Alice traded at some point in between.

The attack. Eve’s core tool is a reusable “atom”: given the marginal price and one feasible nonzero trade at a set of reserves, she can always reconstruct the exact reserves by solving a small nonlinear system, because the pair of equations ψ(R)=λc\nabla\psi(R)=\lambda c and ψ(R+Δ)=ψ(R)\psi(R+\Delta)=\psi(R) has a unique solution when ψ\psi is strictly concave. Applying this atom once before and once after Alice’s trade and subtracting recovers her exact trade — a five-step procedure spelled out explicitly in the paper.

Non-strict concavity. For CFMMs like constant-sum markets (e.g. mStable) where the trading function is not strictly concave and multiple reserve states share a marginal price, Eve instead does a binary search: since the marginal price is flat, she queries progressively larger trades until one becomes infeasible, narrowing down the true reserves to within ϵ\epsilon in log(1/ϵ)\log(1/\epsilon) queries.

Mitigating strategies. The paper proposes randomized prices (fixed per block, so repeated queries can’t be averaged away — with the caveat that arbitrageurs can exploit the resulting price gaps) and order batching (with the caveat that Eve must be locked out of controlling every other order in the batch, and that batching introduces settlement delay). It explicitly declines to prove either is sufficient.

Conclusion. The paper states plainly that CFMM privacy “requires more than simply obscuring reserve and trade quantities,” since the information needed for the system to function at all — a price, and what a given input yields — is enough to break privacy on its own. It leaves two explicit open questions: whether the attack generalizes beyond 1-homogeneous strictly-convex CFMMs, and what a genuinely privacy-preserving CFMM would even look like.

“In this note, we show that privacy is impossible with the usual implementations of CFMMs under most reasonable models of an adversary and provide some mitigating strategies.” (Abstract)

“Eve is always able to reconstruct the reserve amounts given (a) the marginal price at the current reserves and (b) a single nonzero feasible trade.” (§1.2, Attack description)

“We have shown that privacy in CFMMs requires more than simply obscuring reserve and trade quantities from possible attackers.” (§4, Conclusion)

“What does a privacy-preserving CFMM look like, and what privacy guarantees can it make? This question is likely much harder, but also far more important.” (§4, Conclusion)

Background needed: the definition of a CFMM (reserves, trading function, marginal price) and basic familiarity with convex optimization notation (supporting hyperplanes). Skip the non-strict-concavity extension in §1.2 on a first pass unless you specifically care about constant-sum markets. The hardest part is not any single equation but the framing itself: read the “attack” as “anything a legitimate trader needs to know to use the pool correctly is exactly the information an outside observer needs to break privacy” rather than as a cryptographic exploit — the paper’s point is that this is an economic/mechanism-design impossibility, not a fixable implementation bug.

  • Chitra’s own follow-up (with Angeris), “Differential Privacy in Constant Function Market Makers” (August 2021, summarized in the ethresear.ch ETH2 post used above), turned this paper’s “randomness + batching” mitigation sketch into a formal (ϵ,δ)(\epsilon,\delta)-differential-privacy mechanism with concrete noise and trade-splitting formulas.
  • zkUniswap (2023-10) and similar zk-co-processor AMM designs redirected “zkAMM” research toward computation scaling rather than privacy, a distinction this page treats explicitly as answering a different question.
  • No production private CFMM has shipped as of this research; the practical response on both Ethereum and Solana has instead been confidential transfers (Token-2022) and shielded payment pools, which sidestep rather than solve the AMM-specific impossibility.
  1. barryWhiteHat, “Why you can’t build a private uniswap with ZKPs” (2020-07, ethresear.ch) — read first for the plain-language intuition behind the formal result.
  2. tchitra, “Differentially Private Uniswap in ETH2” (2021-08, ethresear.ch) — read for the concrete differential-privacy mechanism and the probabilistic-sandwich-attack argument.
  3. leohio, “Why you can build a private Uniswap with weak secrecy in zkRollup” (2021-10, ethresear.ch) — read for the strongest counter-argument, and barryWhiteHat’s reply, for the strongest rebuttal.
  4. diego et al., “zkUniswap: a first-of-its-kind zkAMM” (2023-10, ethresear.ch) — read to understand the (different) computation-hiding sense of “zkAMM.”