Privacy-preserving swap gating on Uniswap v4 using ZK group membership proofs
https://effe-production.up.railway.app/
Effe is a Uniswap v4 hook that enforces compliance gating without revealing trader identities. The allowlist is a Semaphore group -- an on-chain Merkle tree of identity commitments. To swap, a trader generates a Groth16 zero-knowledge proof that their commitment is in the tree and passes it as hookData to the router.
The hook's beforeSwap function calls the Semaphore verifier on-chain: valid proof means the swap executes, missing or invalid proof means the transaction reverts. The only thing visible on-chain is a nullifier hash -- not the trader's identity or address. This gives you composable, privacy-preserving swap authorization at the protocol layer.
The project includes verified contracts on Ethereum Sepolia and a live web demo where you can join the group, generate proofs, execute authorized swaps, and see unauthorized swaps revert on-chain.
The core is a Solidity hook contract (ZKComplianceHook) built against the Uniswap v4 hook interface. It integrates with the Semaphore protocol for on-chain ZK proof verification -- Semaphore uses Groth16 SNARKs over a Poseidon-based Merkle tree.
I wrote a custom HookedSwapRouter that forwards arbitrary hookData through the PoolManager.swap call so the proof reaches beforeSwap. Contracts were developed and deployed with Foundry, using CREATE2 salt mining to get a hook address whose lowest bits match the required permission flags (beforeSwap only).
The frontend is a vanilla HTML/JS app served by a Node.js backend (TypeScript, using viem for all chain interactions). Proof generation runs server-side via @semaphore-protocol/proof (snarkjs under the hood).

