Stellar Hacks: Real-World ZK · DoraHacks 2026

Bridge privately between Ethereum & Stellar

A bidirectional, fully Zero-Knowledge bridge. Move USDC in either direction without ever revealing which deposit or lock transaction triggered your claim. The link between source and destination is cryptographically severed.

9,337
Circuit constraints
32,768
Max privacy set
~0.2%
Total bridge fee
2
Chains bridged
The privacy gap

Normal bridges leave a trail. Zephyr doesn't.

On a standard bridge, anyone watching can correlate the address that locks funds with the address that claims them. Zephyr uses ZK proofs so the deposit and claim are mathematically decoupled.

Normal bridge
Alice locks $100 on ETH
Alice claims $100 on Stellar

→ Anyone correlates the two addresses. Privacy broken.
Zephyr bridge
Alice locks $100 on ETH
SOMEONE claims $100 on Stellar

→ No link between deposit & claim. Proven by ZK.
How it works

Four steps, fully private

The same ZK flow powers both directions. Your secret never leaves your browser — the proof is generated client-side and verified on-chain.

1

Lock

Lock USDC or ZUSDC on the source chain. A Poseidon commitment Poseidon(amount, secret, recipient) is recorded — no plaintext address stored.

2

Merkle sync

The relayer monitors events, builds a Poseidon Merkle tree, and posts the root to the destination chain. The frontend auto-detects when it's ready.

3

Generate proof

Your browser runs the Groth16 prover (snarkjs WASM) to build a zero-knowledge proof of membership, amount, and nullifier — all in ~30–60 seconds.

4

Claim privately

Submit the proof on-chain. The contract verifies it via native BN254 pairing, checks the nullifier, and releases net funds. No link to the original deposit.

Bidirectional

Private in both directions

ZK proofs are load-bearing in both directions — a valid proof is strictly required to claim bridged funds, no matter which way you're going.

Ethereum Stellar
ETH → Stellar
1 Lock USDC on Ethereum. commitment = Poseidon(netAmount, secret, recipient) recorded, 0.1% fee collected.
2 Relayer builds Poseidon Merkle tree from Locked events, posts root to Stellar via set_src_root.
3 Auto-detect: frontend polls Stellar contract root and enables Claim when it matches local tree.
4 Claim via Groth16 proof + claim(proof, pub, recipient, commitment) on Soroban. Native BN254 verifies.
Stellar Ethereum
Stellar → ETH
1 Lock ZUSDC via lock_stellar_private(amount, commitment). ETH recipient is completely hidden on-chain.
2 Relayer accumulates all historical commitments (survives Soroban pruning), posts root to Ethereum via setStellarRoot.
3 Auto-detect: frontend fetches full commitment list from relayer API, confirms yours is in the tree.
4 Claim via claimFromStellar(proof, ...) on EVM. Native alt_bn128 precompiles verify.
Zero-knowledge

One circuit, two chains

A single shared Circom circuit powers both directions. The exact same Groth16 proof generated in your browser verifies on both Ethereum's alt_bn128 and Stellar's native BN254 host functions.

Circuit metrics

Groth16 over BN254, Poseidon hashes, depth-15 Merkle tree.

Curve
BN254
Proof system
Groth16
Constraints
9,337 NL
Tree depth
15
Privacy set
32,768
Ceremony
pot14_final

What the proof guarantees

Five statements proven in a single Groth16 proof.

1commitment = Poseidon(amount, secret, recipient)
2leaf = commitment (exists in tree)
3nullifierHash = Poseidon(secret, leaf)
4leaf ∈ Merkle tree (path matches root)
5amountCommitment = Poseidon(amount)
Fee economy

Symmetric, transparent fees

A flat 0.1% is collected on each side (lock + claim) to fund operations and maintain liquidity. Fees accumulate on-chain and are withdrawable by admin only.

Direction Source fee Destination fee Total
ETH → Stellar 0.1% on lock 0.1% on claim ~0.2%
Stellar → ETH (ZK) 0.1% on lock_private 0.1% on claimFromStellar ~0.2%
Stellar → ETH (release) 0.1% on lock_stellar 0.1% on claimBurned ~0.2%
Deployed

Live on testnet

Depth-15 deployment with burn-proof release path and VK-init bypass. Click any address to view on the explorer.

Ethereum Ethereum Sepolia

MockUSDC
0x82eDeE25b30DA4629FAa73b58880569184eaF55B
BridgeEscrow
0xE2E882f8b74032CF56739003Ae2c21CC3Bdcb351
Groth16Verifier
0xAaA8A825778E5ff8ccD9cE69952b1D1AdebA6fbC

Stellar Stellar Testnet

ZephyrBridge
CALV7CZLDXJKHJOXKHMA4KOTKS7BZVBQACP7MCPZI5RTGQBUFQMNGFUN
ZUSDC Token (SAC)
CB42VBDIGTKDSHG43335RSYU3VUE3VVVBA7Q6NA575TZOUAQC4DGPFSD
ZUSDC Issuer
GBCWIZI5TMATWJ6WCF2SUM6GF7OBDPTOIFDUTWVGZ5BZEANUINILQJRW
Tech stack

Built on solid primitives

Every layer chosen for soundness and auditability — from the ZK proving toolkit down to the smart contract languages.

ZK Proving
Circom 2.2 + snarkjs
ZK circuit DSL and the in-browser WASM prover.
Proof System
Groth16 / BN254
Economical on-chain verification on both chains.
Hash Function
Poseidon
ZK-friendly, native in Stellar Protocol 25/26.
Ethereum
Solidity 0.8.28 + Hardhat
Escrow, verifier, and burn-proof registry.
Stellar
Soroban SDK 26 (Rust)
Native BN254 pairing and commitment state.
Frontend
React 19 + Vite + wagmi
Wallet integration and client-side Merkle + prover.

Ready to bridge privately?

Connect your wallets, lock your funds, and let Zero-Knowledge proofs do the rest. Your deposit and claim will never be linked.

Launch the App