|=[ RESEARCH :: FILE 02 ]=

HOW CONFIDENTIAL IS ZAMA'S CONFIDENTIAL VAULT?

ZAMA · CUSDC · MORPHO VAULT V2 · ETHEREUM MAINNET

The Steakhouse Confidential Prime USDC vault lets you supply Zama's cUSDC, an encrypted token, into a Morpho Vault V2 where balances and transfers are sealed. I re-indexed every public event the system emits between 19.06.2026 and 19.08.2026 to see how much an outside observer can reconstruct. The headline: 98.1% of depositors are traced at the wrap, with amount, address, timestamp, and batch deposit all visible onchain.

ORIGINAL RESEARCH 5 LEAKS PUBLIC DATA ONLY

DATA — 19.06.2026 → 19.08.2026 · ETHEREUM MAINNET

379
Depositors
unique addresses joined a batch
657
Batch joins
597 claims · 58 settlements
98.1%
Traced at the wrap
372 of 379 depositors
$684,354
Est. interest
from the public share price
1
Batch of one
a $49,990 solo deposit

EVERY PUBLIC EVENT THE SYSTEM EMITS, RE-INDEXED FROM THE CONTRACTS

WHAT IS A CONFIDENTIAL YIELD VAULT?

tl;dr: Not very confidential. 98.1% of the depositors can be traced via their original wrapping of USDC to cUSDC, with amount, address, timestamp, batch deposit into the vault all visible onchain.

Steakhouse Confidential Prime USDC is a Morpho Vault V2 curated by Steakhouse, where you can supply Zama's cUSDC, a confidential token, that uses ERC-7984 to obfuscate transfers and balances. You wrap USDC into cUSDC, then deposit into a batch, and wait for it to hit the vault. Zama's batcher collects everyone's encrypted deposits, the KMS decrypts only the batch's aggregate, and one public lump sum lands in the vault. You claim confidential share tokens whose balance is encrypted, so the vault never reveals how much any address holds.

Flow of funds through the Zama x Morpho system, from wrapping USDC into cUSDC to batched deposit into the vault.

WHAT DID I ACTUALLY DO?

I set out to answer one question, to find out how confidential the deposits are in a "confidential" vault, using only publicly available data.

Every action inside the Zama x Morpho system emits a public event from the smart contracts, which can be re-indexed and investigated for links between depositors, deposits, and withdrawals. The window I analysed covers activity between the 19ᵗʰ June and 19ᵗʰ August 2026, with 657 batch joins from 379 addresses, 597 claims, and 58 batch settlements. I looked through depositors, when and how much USDC they wrapped, which batch their deposit was included in, and if they withdrew or claimed from the vault.

Similar to my piece on Privacy Pools, all data used is onchain and from public record. I didn't break FHE (imagine), so actual balances and transfers stay confidential, but you can reconstruct the information around this quite easily. There is a small gap between the actual TVL and the reconstructed TVL of 2.1%, explained by yield accrual and cUSDC sitting idle.

USDC to cUSDC wrapping activity by depositors over the analysis window.

FIVE LEAKS

I analysed transactions and tested transactions any observer could use to connect a person to their confidential deposit, and rank them by how often it occurs and how sure the link is when it does.

#1 · The Wrapoooor

98.1% (372/379) of the depositors wrapped their USDC directly before joining a batch, revealing the depositor, amount, and timestamp.

To enter the Morpho vault you need to deposit cUSDC or USDC into the batcher contract. The overwhelming majority of depositors wrapped their USDC to cUSDC then joined the batch from the same address. The encryption only occurs once the USDC has been wrapped, so anything you do before that can be seen in plain text. This lowers your anonymity set to just yourself.

0xa7ab09fd…5e431 deposited $1M, and every step is verifiable on etherscan. Of the five transactions, four of them are fully public. The only encrypted moment, the Joined amount, is sandwiched between a public $1M wrap and a public $3.34M batch total, with his address on both. Their participation is proven, the amount is inferred from the wrap, in this case it is exact as they wrapped once and joined once.

Worked example of a $1M depositor whose wrap, join, and batch deposit are all verifiable on etherscan.

Only seven depositors avoided this; receiving cUSDC from somewhere else and leave no amount trace at the wrap. Everyone else signed their deposit slip in public.

#2 Privacy is better with friends

1 of the 61 batches included a single deposit from one person, no one else could help obfuscate their balance.

Each batch into the vault settles as one public aggregate that anyone can see. The design of this is that batches will stay crowded and help obfuscate deposits. For the most part, this was true; the mean batch was ~11 depositors, median 8, and max 68. Batch 185 had exactly one joiner: 0x5e310f01…a82d who deposited exactly $49,990 (join · finalize). Privacy degrades significantly when demand is low.

Distribution of deposit batch sizes, with batch 185 containing a single joiner.
#3 · The exit boundary

There were 104 direct redeemers and 81 unwrappers, $27.8M was withdrawn from the vault with public redemptions, and $4.4M exited cUSDC via unwrapping.

There are two ways to remove yourself from the vault. 104 addresses held plain vault shares at the time of exit, and called redeem themselves. The biggest redeemer (0xb81a0e6c…0c5bfd) did it sixteen times; with one notable transaction on 4ᵗʰ July burning 1,690,207.80 shares and received $1,700,000.92 in one public transaction (0x59190a3c…b53ad).

All 0xb81a0e6c…0c5bfd Redemptions: 0x4b5cf3d5 · 0x59190a3c · 0xbb15b7bd · 0x00b45d01 · 0xddae47de · 0xb801fbac · 0xef557638 · 0x2734a83a · 0xa0ca40e4 · 0xd4d137d0 · 0x4351b938 · 0xaf8ce257 · 0x96f1f161 · 0xc2e44de6 · 0xb6a130e4 · 0x2375fd7d

You can also withdraw through cUSDC and wait to be batched. 81 addresses exited this way and later unwrapped to plain USDC ($4.37M), where the unwrap is again a public transfer. You can work out the yield by doing unwrap minus wrap equals yield.

0x72ea177f…6565 shows the full round trip:

They held for ~19 days and gained $3,782.05 on their $1M deposit, which is 0.378% ROI or ~7.4% annualised, close to the advertised APY.

Worked example of a full round trip, a $1M deposit withdrawn after about 19 days with $3,782.05 of yield.
#4 · The Funding Trail

Every deposit starts somewhere, I selected 15 depositors to trace the funding of them. At least seven were funded directly from Binance, with our worked example from earlier, 0xa7ab09fd, getting its gas (0x0c9cd80d…f8972b) and $1M from Binance (0xba7f9be0…6e559c). Three depositors (0xcb20a2bf, 0x72ea177f, 0x485c07c5) received USDC from direct Circle mints, and two (0x598fa9e4, 0x485c07c5) shared gas funders (0x5a207d5c · 0x1c099d57) and a USDC intermediary. Zama hides the amounts, but it cannot hide where the funds came from.

Even the seven depositors whose amounts cannot be identified are unable to hide. cUSDC emits a public ConfidentialTransfer(from, to, handle) for every move, with only the handles being encrypted.

Looking at those seven depositors, all of them are funded by other depositors:

The majority of the cUSDC is deposited into the Morpho vault, with the wrapper holding ~$4M of USDC.

#5 Patience is a virtue

Median wrap → join time is 96 seconds, effectively making the wrap transaction a deposit receipt.

Users are not wrapping and waiting, they immediately join. 66% of depositors joined within 5 minutes of wrapping, with the median gap 96 seconds. Combine this with the batchers strict ~24 hour settlement cadence, you can time-box nearly every positions entry and exit. Unique, distinctive amounts are the enemy of privacy. Round totals aare common and shared at retail size, but the whale flow is particularly visible: $7M, $3M, $3M, $2.01M, $2M. At that size every total is a fingerprint, round or not.

Time between wrapping USDC and joining a batch, with a median gap of 96 seconds.

Waiting is the natural fix for the timing link, so I measured the amount of privacy you get for waiting. If you wrap and join from the same wallet, waiting buys you nothing as your address sits in both events. Waiting really only matters once you move your cUSDC to a fresh wallet before joining. If you do that, a one hour gap hides you among a median of 8 other wraps, 24 hours hides you among 180, and a week among 970. If you filter by size, after waiting 24 hours you are hidden in a median of 9 wraps within ±10% of your size, and one third of wraps do not have a matching amount. Approximately one in five wraps are globally unique, and no amount of patience will ever help.

How much anonymity waiting buys, measured in the number of wraps you hide among.

DEPOSITOR INTEREST (ESTIMATED)

The vault's share price is public and accrues smoothly, going from 1 to 1.015567 at the time of my snapshot. If a user's entry date is public (their join), and their size is public (their wrap), we can estimate their cost basis and yield.

The total comes to $684,354 of estimated interest earned, you can see some of the estimated yield for large depositors:

Estimated interest earned by large depositors, derived from the public share price.

Method: shares ≈ wrapped ÷ share price at first join; redemptions valued at burn-date share price; unwraps at face; remainder marked at 1.015567. For fully-exited users realized yield is exact (out − in); everything else is an estimate bounded by the wrap. A handful of users who received cUSDC from third parties (e.g. two wallets with ~$500 in and $5.5-6.5k out) are excluded as unestimable.

WHAT STAYS PRIVATE

It is important to note that the core product is doing what it is meant to do, keeping your balances hidden from the outside. 7 of the depositors used the product how it was meant to be done, receiving cUSDC from elsewhere and depositing into the vault, no one on the outside is able to see their amounts.

The rest of the depositors are thinking they are keeping their balances secret, but poor opsec means they are leaking their balances regardless.

  • The leak starts when you wrap USDC to cUSDC - wrap from a different wallet before depositing. Caveat: the transfer graph is public, so your sender is visible even though the amount isn't.
  • Break the timing link. 66% of users join a batch within five minutes of wrapping; the median is 96 seconds. The wrap and the join are effectively one event. Waiting hours or days before joining costs nothing and severs the exact match. Caveat: this vault launched with a time-bound incentive campaign, so there was a rush to join. This is not a user failure, but a campaign design failure. Privacy protocols need to run incentives that reward slow, spread out behaviour or they manufacture the leak themselves.
  • Avoid distinctive or unique amounts when wrapping. Unique amounts identify you, deposit across multiple days in multiple chunks.
  • Use a fresh wallet. A new wallet funded straight from an exchange hot wallet is not private from the exchange, and the funding trail is visible to anyone who looks. At minimum, fund it through a path that isn't one hop from your KYC account.
  • Exit with the same care you entered with. Redeeming shares directly for USDC to your own wallet, as $27.8M did, publishes your position, your exit, and your yield in one transaction. Exit through the confidential path, and don't unwrap straight back to the wallet everyone already knows.
  • Know the limit of hygiene. Even perfect opsec leaves your batch membership, your timing, and your counterparty's side of the trail. Users can shrink the leak; only the protocol can close it.

SO, IS IT CONFIDENTIAL?

Confidential, per the dictionary: Private and meant to be kept secret. Information that should not be shared with others, often because it is sensitive, personal, or legally protected.

Using this definition, we can hold the Zama launch post to the standard:

Naming matters because users calibrate behavior to it. A user who reads "confidential vault" and wraps $1,000,000.00 from their main wallet believes their amount is secret. It is in a block explorer. The cryptography delivers exactly what the architecture allows; the marketing describes the architecture's best case as if it were the default.

Table comparing the confidential vault's claims against what the public data actually reveals.

A confidential vault whose books I can reconcile to within 2.1% from public data is not confidential. The cryptography is sound, and FHE does exactly what it promises. Balances and transfer amounts are sealed, the batcher mostly hides the individuals inside aggregates, and seven careful users proved the design can deliver what it advertises.

Education around the product needs to improve. 379 people deposited into a vault marketed as confidential, and I can show you nearly all of their amounts, timings, funders, and earnings, to the cent.

The fixes are not mysterious, and most of them are cheap:

  • Batch the wrap, not just the deposit
  • Bucket the amounts
  • Build onramps that never touch a public wallet.
  • Warn the user whose wrap and join are ninety seconds apart.

The infrastructure is still useful, but this is a public vault with a confidential middle.

Thanks to @FryCookVC for proof reading and feedback.

Evaluating confidential vaults but not sure if one fits your product? Talk to Ben.

TALK TO BEN →

FILE UNDER — RESEARCH

NEXT READS

HOW MUCH STEALTH DOES A STEALTH ADDRESS GET YOU? three generations of stealth protocols measured on public data: most active users linked at the spend HOW "PRIVATE" IS STARKNET'S BUILT-IN PRIVACY? 113,022 pool events re-indexed: 40.4% of withdrawals certainly linked to their funding deposit HOW PRIVATE IS PRIVACY POOLS? seven heuristics across every v1 transaction: what actually links a withdrawal to its deposit

DEEP DIVES · RESEARCH · WORK WITH ME