Ultra Anon

Ultra Anon

An experimental privacy token with maximum plausible deniability and anonymity set where we blur the lines of public and private state.

Created on 1st March 2025

Ultra Anon

Ultra Anon

An experimental privacy token with maximum plausible deniability and anonymity set where we blur the lines of public and private state.

The problem Ultra Anon solves

People who used tornadocash got censored from using popular front-ends, simply because they wanted to protect their privacy. This is because tornadocash "publicly announces" which public wallets are transferring money privately. In simple terms they see them making a transaction depositing into the protocol.
UltraAnon solves this by enabling full plausible plausible deniability. Inspired by EIP7503 (zkwormholes) but with even stronger guarantees. Since UltraAnons "burn-address" isnt actually a burn address and can still publicly spend. Which means we achieve maximum plausible deniability!

Achieved by having a single address type where its balance is tracked using a zk proof system. This system tracks balances differently, instead of a total balance, it tracks two states: a total amount recieved publicly, and the total amount spent privately. This allows accounts to recieve money publicly and show it on their balance, but once they make a private transaction, it looks like nothing happend to their account. And it just looks like the tokens stayed in their account while it actually is privately spent. The real balance (total_incoming_amount- total_outgoing_amount ) can only be seen by the user. While the rest of the world sees only the total_incoming_amout.

Furthermore, UltraAnon also has a anonymity set of every account. Even if they only make public transfers. Unlike is systems like zcash where users who only use public accounts, never contribute to the anonymity.

It also inherits the property of EIP-7503 (zkwormholes) where proof time is O(1). Unlike UTXO based privacy protocols like zcash and railgun where the proof time to spends increases for every transaction you recieve

User Interaction and Data Flow

We modified the ERC20 standard to enable both public and private transactions. Users can choose to send a transaction publicly or privately. We hosted a UI on IPFS and ENS for users to interact with.

The project architecture and development process

We modified the ERC20 standard in solidity and wrote ZK circuits in Noir. The user creates a private or public transaction and attatches a proof generated on the client-side with NoirJs. The proof along with the transaction arguments are sent to a relayer who executes the transaction on the user's behalf.
The smart contract updates users' balances after the proof has been verified on-chain.
We also added 2 merkle trees to track the public and private state in. This merkle tree updates on every transfer.

Product Integrations

We intended to deploy on ZK sync but we didn't realize they don't yet have the precompile needed to deploy our Noir verifier. This was undocumented.
We ended up using sepolia but we missed out on experimenting with zksync native account abstraction and paymaster, which we possibly could have used as relayer.

Key differentiators and uniqueness of the project

Full plausible deniability.
A new state model that mixes public and private state.
O(1) proof time, indepedent of the amount of transfers recieved.

Trade-offs and shortcuts while building

The state design was complex so we were left with little time to construct a front-end. Additionally, the relayer is self-hosted and acting out of good faith. In a full implementation there should be an incentive for relayers to execute transactions. We would also like to explorer more offchain compliance guarentees.
This gas fees are also incredibly high, especially for public transfer, which cost the same amount of gas as private transfers since it also uses almost the same zk-ciruit. And needs to update 2 merkle tree.
We think we can significantly reduce some of the gascost by using only one merkle tree or even better storage proofs. But fundamentally public transfer will cost far more than a normal erc20 since it uses the same expensive zkp as private transfer

Additional Features

The project was entirely built during the buildathon. It was inspired by EIP7503 and some previous research on account based nullifier schemes: https://github.com/jimjimvalkema/scrollZkWormholes/blob/main/docs/notes.md#partial-spends-address-reusability

Tracks Applied (2)

ZK is the Endgame

Zk is a critical part of our project and it would not be possible without verifying proofs on-chain. Additionally, nati...Read More

zkSync ∎

IDENTITY, PRIVACY + SECURITY

People who use Tornado Cash are censored from dApp frontends. This can be solved by enabling plausible deniability. Pl...Read More

Technologies used

Discussion

Builders also viewed

See more projects on Devfolio