EIP-8182: Private ETH and ERC-20 Transfers

EIP-8182 doesn’t require a proof for deposits and so there is no auth circuit to correlate with a shielding event. A POI framework that requires proofs at shielding could harm privacy, but not through auth verifier visibility (which doesn’t exist in a shield tx).

On soundness, users definitely take on risk to their own funds when they register an auth verifier. But this seems orthogonal to whether the system staticcalls these verifiers or uses a different design like recursion.

Can you give an example of how the current auth verifier setup could be used to deanonymize, @rdubois-crypto?

This frames soundness risk as borne by the registering user. That only holds if a note is cryptographically bound to a single auth verifier. If any registered verifier can authorize spending any note, a soundness bug in ONE verifier lets an attacker forge ownership of the ENTIRE shared tree.

Concerning the real aim, merging the pools, there are many signals that leaks which leaf belongs to which circuit:

  • POI
  • Ciphering bundles
  • Wallet/UI behavior (if a wallet doesn’t integrate a given circuit, if the infra like relayers/broadcasters is not shared among wallets).

This frames soundness risk as borne by the registering user. That only holds if a note is cryptographically bound to a single auth verifier.

In EIP-8182, soundness risk caused by a buggy or malicious auth verifier is only borne by the registering user, but not because notes are bound to a specific verifier.

The reason is that every spend must pass two independent gates.

The first gate is the fork-managed “pool proof.” This is the pool soundness layer. It proves the transaction is a valid shielded-pool state transition:

  • The inputs are real notes in the tree
  • The corresponding nullifiers aren’t already consumed
  • Value is conserved between inputs and outputs.

A user-selected auth verifier cannot relax any of those constraints.

The second gate is the “auth proof.” This proof answers whether the selected auth method authorizes this particular transaction intent. It is a per-user authorization gate layered on top of the pool soundness gate enforced by the pool proof.

So even if an auth verifier is maximally broken and returns true for everything, it cannot print money, spend non-existent notes, bypass nullifiers, or violate value conservation. What it can do is make authorization too permissive for only those users who opted into that verifier.

Concerning the real aim, merging the pools, there are many signals that leaks which leaf belongs to which circuit

I agree, my point is just that these signals aren’t materially exacerbated by EIP-8182’s approach to authorization relative to the risks present in all shielded pools of this sort.

That said, it would certainly be better else-equal to not leak the auth method used for a given shielded transaction. But I can’t see a way to do that aside from either (a) forcing every tx to use the same auth method or (b) recursively verifying the auth proof in the pool proof.

Both of these I found less palatable than the current approach (though an earlier version of EIP-8182 did use the recursive approach, but the complexity was not worth it).

It is not better or equal, this is acting like if complying to a standard comes for free. Anyone having ever integrated a complex one (like 4337 :wink: ) will admit it is not, and it must come with strong benefit. It also have other costs:

  • indexing of POI like will be harder
  • POI itself, if circuit B is banned because its POI/compliance is “Thorchain” level, allowing bad actors to launder, other circuit will not be able to maintain their curating
  • network privacy layer must also be shared, currently only Railgun offers it with Waku (with unsufficient avaibility IMHO, but provides the privacy by default of users IP),

And there actually might be another solution, without having to write anything new:

  • Zk bridging from circuit A to circuit B.
    Write a circuit being able to verify circuit A, B, C and add a liquidity provider to privately transfer from each.

Doing so, you attain the aim: the zk state becomes shared for users subscribing to the service, without adding a new burden to existing products.

1 Like

Interesting idea! To make sure I understand, do you have in mind something like this?

Example:

  1. Alice has a private 100 USDC note in Pool A. Bob can only receive in Pool B. Alice wants to pay Bob 25 USDC without publicly withdrawing from A and depositing into B.

  2. Alice creates a Pool A spend that consumes her 100 USDC note and creates:

    • a 75 USDC change note back to Alice in Pool A;
    • maybe a fee note;
    • a hidden “export-credit commitment” for 25 USDC addressed to Bob’s Pool B receive key.
  3. Observers of Pool A only see that an export-credit commitment was inserted. They do not learn that the destination is Pool B, that the token is USDC, that the amount is 25, or that Bob is the recipient.

  4. Later, Alice, Bob, or a batcher submits an import transaction to Pool B. The import proof shows that a valid unspent export credit exists, that it is addressed to Pool B, and that it creates the correct private Pool B note for Bob.

  5. Pool B inserts an ordinary 25 USDC private note for Bob. Alice never needs to receive a Pool B note herself; the export credit is just the hidden payment rail from Alice’s Pool A liquidity to Bob’s Pool B note.

  6. The export credit has a nullifier. Importing consumes that nullifier. If the import never happens, Alice can later cancel/refund the export credit back into Pool A, consuming the same nullifier.

  7. At the end of a settlement epoch, a batcher submits a settlement proof for many imported A→B credits. For example, the proof shows that 10,000 imported credits from Pool A to Pool B sum to 1,000,000 USDC. Pool A then transfers 1,000,000 USDC from its escrow to Pool B’s escrow.

Publicly, observers see Pool A inserting export commitments, Pool B importing credits, and later Pool A settling 1,000,000 USDC to Pool B for the epoch. They do not see Alice’s specific 25 USDC payment edge.

So the architecture would be: private source note → hidden export credit → destination private note, with aggregate escrow settlement later. That seems like the cleanest version of the inter-pool bridge idea to me. Is that what you were thinking?

If EIP-8182 passes, it will drastically increase the stealth and obscurity of fraudulent activities.

Previously on Ethereum, when victims were scammed by Ponzi schemes, pig-butchering scams, or fake investment apps, ordinary people could follow the money trails via blockchain explorers to see exactly who the scammers transferred the funds to. Yet, even with this level of transparency, these cases have continuously mushroomed over the past decade!

Once native privacy becomes a reality, scammers will be able to slide the victims’ USDT into the shielded pool with a single click. Victims and grassroots rights-protection organizations will completely lose their ability to track the funds, becoming blind to even the general flow of the laundered money. This will make on-chain investigations and analysis for law enforcement agencies extremely difficult.

Of course, saying all this is futile. After all, the Ethereum ICO and The DAO incident have already set everything in stone. So, let it completely bring Ethereum down.

8182 deliberately makes authentication permissionless and lets companion standards define richer authorization relations. Have you considered multi-party intent authorization, where an auth proof demonstrates not merely that one credential approved the transactionIntentDigest, but that the digest was authorised by a coordinated set of principals/agents under a shared intent?

Yes—multi-party intent authorization is already expressible in the permissionless auth layer. A companion standard can define an authDataCommitment representing a signer set, threshold, roles, delegation structure, or other shared policy, and its auth proof can demonstrate that several principals or agents jointly authorized the same transactionIntentDigest or that their independently authorized constraints all resolve to that final intent.

The base protocol still treats this as one authorization policy belonging to one authorizingAddress; it does not natively combine independent registry entries or jointly spend notes belonging to different ownerNullifierKeys.

There is also a lifecycle distinction: the address owning the registry leaf controls addition and removal of policies. If that address is an EOA, its key can replace the multiparty policy. The intended way to make lifecycle control multiparty today is to use a smart-contract wallet as the authorizingAddress, so calls to setAuthPolicy are themselves governed by multisig or other collective rules.

A future extension could introduce a separately proof-governed lifecycle policy or native multi-identity co-authorization, but that would be a larger feature with meaningful circuit, recovery, and privacy complexity rather than something missing from the current auth-proof interface.

That makes sense — thanks, that clears it up.

I think the clean boundary is that 8182 can already handle how multiple parties authorise a spend.

At a higher level of abstraction, ERC-8001 is more about the coordination that happens before that point: who proposed it, who accepted, under what conditions, and when that shared intent becomes executable.

So I’d see it as:

ERC-8001 → coordination / shared authority lifecycle
EIP-8182 → proof of authorisation / private execution

In other words, the participants coordinate first, the authority resolves, and 8182 can then prove and privately execute the resulting authorisation.

That separation feels pretty clean to me. Does that make sense to you as well?