Regarding the UX concerns introduced by wrappers, I think the ZWToken-unaware workflow can significantly improve the situation. Users don’t necessarily need to be aware that a wrapper exists at all.
I still believe that even if new tokens are issued, wrappers remain the only viable path. Asset issuers generally prefer to avoid regulatory exposure (which is essential for the survival of their projects), so privacy inevitably has to be handled by a permissionless wrapper — even if that means we’ll need some additional UX improvements.
To clarify my previous comment:
I realized that what I’m exploring is not a wrapper-based model and not a dual-mode token.
It is actually a different token primitive, which I’m calling a ZW-Token (Zero-Wrapped Token) for now.
This primitive is based on three invariants:
1. Irreversible, deterministic burn
Supply strictly decreases over time.
Burned units can never re-enter circulation (no unwrap, no remint, no mirrored states).
2. Single-state supply (no private balances, no parallel ledgers)
Privacy does not hold or represent supply.
There is only one global supply counter:
totalSupply = initialSupply – irreversibleBurns
3. Unlinkable transfer layer on top of a single supply
Transfers can be made unlinkable (no A→B traceability) without creating wrapped supply or dual representations of the asset.
This produces a different category of token: supply-bounded, irreversible-burn assets with privacy that does not fragment supply.
It’s not a modification of ERC-8060;
it’s orthogonal to it — a separate primitive that could exist alongside it.
Great proposal. Before native account abstraction arrives, relayers/bundlers are still a necessary component, and the ERC should be able to support various types of relayers.
/// @notice Encapsulates all data required for remint operations
/// @param commitment The commitment (Merkle root) corresponding to the provided proof
/// @param nullifiers Array of unique nullifiers used to prevent double-remint
/// @param proverData Generic data for prover
/// @param relayerData Generic data for relayer, can contain fee information. Hash is used in ZK proof.
/// @param proof Zero-knowledge proof bytes verifying ownership of the provable burn address
struct RemintData {
bytes32 commitment;
bytes32[] nullifiers;
bytes proverData;
bytes relayerData;
bytes proof;
}
/// @notice Remint ZWToken using a zero-knowledge proof to unlink the source of funds
/// @param to Recipient address that will receive the reminted ZWToken or the underlying token
/// @param id The token identifier. For fungible tokens without IDs (e.g., ERC-20), this MUST be set to `0`.
/// @param amount Amount of ZWToken burned from the provable burn address for reminting
/// @param withdrawUnderlying If true, withdraw the equivalent underlying token instead of reminting ZWToken
/// @param data Encapsulated remint data including commitment, nullifiers, proof, and relayer information
function remint(
address to,
uint256 id,
uint256 amount,
bool withdrawUnderlying,
RemintData calldata data
) external;
Key changes
IntroducedRemintData to align the remint pattern with deposit and withdraw, and avoid the “stack too deep” issue.
ReplacedrelayerFeewithrelayerData to support generic, more flexible relayer payloads.
AddedproverData to support richer prover-side data structures.
Replacednullifierwith an arraynullifiers enabling batch remint capabilities.
Additional updates
Renamed depositTo → deposit and withdrawTo → withdraw for a cleaner, more streamlined API, since the to parameter already captures the destination semantics.
Notably, we will soon open-source our implementation of ERC-8065, along with a PoC demonstrating our new ZWToken-unawareness workflow.
Definetely. I’ll open a new thread as a proposal for start discussing about a potential ‘private chat’ and "stealth adresses’ extensions … Your perspective and help will be really appreciated onto this new proposal @doublespending
Burn-and-remint mainly obscures history for parties other than the operator, while the operator themselves remains fully aware.
With user consent, history can still be followed relatively easily: users can prove ownership of a given address—whether a burn address or a regular address—via signatures or zero-knowledge proofs. Within the scope explicitly authorized by the user, tracking historical continuity is therefore quite feasible.
How large is the anonymous collection of ERC8065, and how does it compare to Tornado Cash and Railgun?
The ZWToken approach should, in theory, have a larger anonymity set than a privacy dApp. Due to ZWToken’s pluggable privacy design, it can be used like a regular token and therefore supports many non-privacy use cases. In simple terms, ZWToken’s anonymity set consists of both regular token usage and privacy-preserving token usage, which is larger than that of a privacy dApp that only supports privacy-focused token usage.
I think there are some issues with defining fee formats and structures in the ERC, because fee models are not necessarily fully covered by the three values depositFee, remintFee, and withdrawFee. This is especially true when considering dynamic fees, or fees that are not proportional to token amounts. In addition, NFTs do not seem to be divisible, which makes them difficult to use for paying fees.
I think there are some issues with defining fee formats and structures in the ERC, because fee models are not necessarily fully covered by the three values depositFee, remintFee, and withdrawFee. This is especially true when considering dynamic fees, or fees that are not proportional to token amounts. In addition, NFTs do not seem to be divisible, which makes them difficult to use for paying fees.
That’s a really good suggestion. I agree that putting fee definitions directly into the ERC isn’t a great design choice, since fees can take many different forms—dynamic fees, membership-based fees, and so on—and they’re not necessarily a fixed percentage. Also, for tokens like NFTs that aren’t divisible, it’s simply not feasible to charge fees at the token level.
So I’m going to update the ERC and remove fees from it.
Originally, fees were added mainly so users could know how many tokens they would actually get at each stage—deposit, withdraw, and remint. With fees removed, we can still support this by adding optional preview functions for deposit, withdraw, and remint, similar to what existing vault ERCs already do.