An educational demonstration of Railgun-inspired privacy pool concepts on Sepolia testnet. This project shows how commitments, nullifiers, and shielded transactions can provide privacy for DEX swaps.
This is NOT production-ready code. It uses simplified verification instead of real ZK proofs for educational purposes.
┌─────────────────────────────────────────────────────────────┐
│ Frontend (Next.js 14) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ SwapCard │ │ EducationPanel │ │ TransactionFlow │ │
│ │ (main UI) │ │ (under hood) │ │ (step visualizer)│ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │ │
│ RainbowKit + wagmi + viem │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Smart Contracts (Sepolia) │
│ ┌─────────────────┐ ┌─────────────────────────────────┐ │
│ │ MockPrivacyPool │───▶│ PrivateSwapCoordinator │ │
│ │ - commitments │ │ - shield → swap → unshield │ │
│ │ - nullifiers │ │ - integrates Uniswap │ │
│ │ - deposits[] │ │ - educational events │ │
│ └─────────────────┘ └─────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────┐ │
│ │ Uniswap SwapRouter02 │ │
│ │ (Sepolia) │ │
│ └───────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
rgprivswap/
├── contracts/ # Foundry project
│ ├── src/
│ │ ├── MockPrivacyPool.sol # Core privacy primitives
│ │ ├── PrivateSwapCoordinator.sol # Orchestrates the flow
│ │ └── MockTokens.sol # Faucet-enabled test tokens
│ ├── test/
│ │ └── PrivateSwap.t.sol
│ ├── script/
│ │ └── Deploy.s.sol
│ └── foundry.toml
│
├── frontend/ # Next.js 14 app
│ ├── src/
│ │ ├── app/
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── lib/
│ │ └── styles/
│ ├── package.json
│ └── tailwind.config.ts
│
└── README.md
- Node.js 18+
- Foundry
- A wallet with Sepolia ETH for gas
cd contracts
# Install dependencies
forge install
# Build contracts
forge build
# Run tests
forge test -vv
# Deploy to Sepolia
cp .env.example .env
# Edit .env with your private key and RPC URL
forge script script/Deploy.s.sol --rpc-url $SEPOLIA_RPC_URL --broadcastcd frontend
# Install dependencies
npm install
# Set up environment
cp .env.example .env.local
# Edit .env.local with your WalletConnect project ID
# Update contract addresses in src/lib/constants.ts after deployment
# Start development server
npm run devOpen http://localhost:3000 to see the app.
A cryptographic hash that hides deposit details while proving you made a deposit:
commitment = keccak256(secret, nullifier, amount, token)
A unique identifier that prevents double-spending. Once revealed during withdrawal, it marks the deposit as spent.
The pool of active deposits that could potentially be the source of any withdrawal. Larger pool = more privacy.
- Shield: Deposit tokens with a commitment
- Swap: Execute trade through Uniswap from the privacy pool
- Unshield: Withdraw with your secret, revealing the nullifier
shield(token, amount, commitment)- Deposit tokensunshield(token, amount, nullifier, secret, recipient)- Withdraw tokensgenerateCommitment(secret, nullifier, amount, token)- Helper to create commitments
shieldForSwap(...)- Step 1: Shield tokens for swapexecutePrivateSwap(...)- Step 2: Execute swapunshieldResult(...)- Step 3: Unshield resultdemoPrivateSwap(...)- All-in-one demo function
MockWETH- Mock Wrapped ETH with faucetMockUSDC- Mock USDC (6 decimals) with faucet
| Feature | This Demo | Real Privacy (e.g., Railgun) |
|---|---|---|
| Commitment hiding | Simple hash | ZK-SNARK proof |
| Proof verification | Check hash matches | Verify ZK proof |
| Privacy level | None (visible on-chain) | Cryptographic privacy |
| Anonymity set | Basic mixing | Merkle tree proofs |
| Contract | Address |
|---|---|
| MockWETH | 0xc575150185EbeC28FEa92c1B11aB98Ae8be2aAF8 |
| MockUSDC | 0xf96d309a84214BcE3646533B8a022240F02b9C9D |
| MockPrivacyPool | 0x927279e7d10d7D578FeFA215e6B510f5bd1F9813 |
| PrivateSwapCoordinator | 0x36124694dd9EcaE7C6067a7a1E3f93EbA718eab5 |
| Contract | Address |
|---|---|
| SwapRouter02 | 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E |
| V3 Factory | 0x0227628f3F023bb0B980b67D528571c95c6DaC1c |
| NonfungiblePositionManager | 0x1238536071E1c677A632429e3655c799b22cDA52 |
These addresses are configured in frontend/src/lib/constants.ts.
- Railgun Protocol - Real privacy protocol
- Zero-Knowledge Proofs
- Tornado Cash Docs - Historic reference
- Foundry Book