Skip to content

Latest commit

 

History

History
115 lines (78 loc) · 6.67 KB

File metadata and controls

115 lines (78 loc) · 6.67 KB

ShieldLend — Tech Stack Rationale

Every technology choice in ShieldLend was made deliberately. This document explains the reasoning behind each decision, including what we evaluated and why we chose what we chose.


Chain: Horizen L3 on Base

What it is: An EVM-native Layer 3 built on Base, with a privacy-first design philosophy. Full Solidity compatibility — no new VM, no new language.

Why we chose it:

  • EVM-compatible: all Solidity contracts, Foundry tooling, and wagmi frontend work unchanged
  • Inherits Base L2's security model and liquidity without requiring a separate bridge setup
  • Privacy-native execution environment — aligns with ShieldLend's core purpose
  • Developer ecosystem includes privacy DeFi projects (ZENDEX, Obscura, Unwallet) that we can learn from and integrate with

Fallback: Base Sepolia. If Horizen L3 testnet infrastructure is unavailable at deployment time, Base Sepolia is the fallback — it is in the same Base ecosystem and migration to Horizen L3 later requires only an RPC URL change.

What we evaluated and rejected:

  • Ethereum L1 mainnet: proof verification is prohibitively expensive (~500K gas per verifyProof() call)
  • Polygon zkEVM / Scroll: ZK-rollup chains, but not purpose-built for privacy DeFi; more complex bridge setup
  • Aztec: would require rewriting everything in Noir and building a full privacy L2 (see "Why not Aztec" below)

Proof Verification: zkVerify

What it is: A modular proof verification chain from Horizen Labs. Accepts ZK proofs (Groth16, PLONK, FFLONK) via the zkVerifyJS SDK and emits on-chain attestations.

Why we chose it:

Cost: Verifying a Groth16 proof on Ethereum L1 requires ~500,000 gas per call. At 20 gwei gas price and $3,000/ETH, that is ~$30 per withdrawal. zkVerify amortizes verification cost across all proof submitters — reducing the per-user cost by ~91%.

Modularity: zkVerify is chain-agnostic. The same proof submission pipeline works whether the contracts are on Horizen L3, Base Sepolia, or any other EVM chain. There is no need to deploy a custom verifier contract per chain.

Native support: zkVerify supports Groth16 and PLONK natively — no custom adapter code needed. The zkVerifyJS SDK handles proof submission in ~3 lines of TypeScript.

What we evaluated and rejected:

  • On-chain Groth16 verifier (generated by snarkjs): works but costs ~$30 per proof on L1; acceptable on L2/L3 but couples the verifier to a specific chain
  • PLONK with universal setup: eliminates per-circuit trusted setup, but Groth16 has smaller proof sizes (192 bytes vs ~700 bytes) and faster verification; we use Groth16 for the MVP and can switch to PLONK later

Circuit Language: Circom + circomlib

What it is: Circom is a domain-specific language for writing ZK-SNARK arithmetic circuits. circomlib is the standard library of reusable circuit templates.

Why we chose it:

  • Most mature ZK toolchain for the EVM ecosystem — largest community, most examples, most production deployments
  • snarkjs compiles Circom circuits to WebAssembly — enabling browser-side proof generation with no server trust assumption
  • circomlib provides battle-tested implementations of Pedersen commitments, Poseidon hashes, and Merkle tree checkers — we do not need to implement these primitives from scratch
  • The Tornado Cash codebase (our architectural blueprint) was written in Circom — their circuits are a direct reference

What we evaluated and rejected:

  • Noir (Aztec): would require rewriting circuits in a different language and deploying on Aztec's infrastructure
  • Halo2 (zcash): Rust-based, no snarkjs/WASM compilation path, no browser proving
  • Leo (Aleo): Aleo-specific, not EVM-compatible

Proof System: Groth16 (via snarkjs)

What it is: A non-interactive zero-knowledge proof system. Three elliptic curve pairings produce a proof that is just 3 elliptic curve points (192 bytes).

Why we chose it:

  • Smallest proof size of any practical SNARK system (192 bytes) — minimizes calldata cost when submitting to zkVerify
  • Fastest verification time — 3 pairing operations regardless of circuit size
  • snarkjs has first-class Groth16 support and compiles to WASM
  • zkVerify supports Groth16 natively

Trade-off: Groth16 requires a per-circuit trusted setup (Powers of Tau + circuit-specific contribution). This is a one-time cost per circuit. PLONK uses a universal setup (one ceremony for all circuits) but produces larger proofs (~700 bytes). For the MVP, Groth16's smaller proofs and faster verification outweigh the setup overhead.


Smart Contracts: Solidity + Foundry

What it is: Solidity is the EVM contract language. Foundry is a Solidity testing and deployment framework written in Rust.

Why Foundry over Hardhat:

  • Significantly faster test execution (Rust vs Node.js)
  • Built-in fork testing — we can fork the Aave V3 mainnet deployment and run integration tests against real contract state without deploying anything
  • forge test --match-test for targeted test runs during development
  • forge script for reproducible deployments with full type safety

Frontend: Next.js + wagmi

Why Next.js:

  • Server-side rendering for fast initial page load
  • API routes for the relayer (watches zkVerify attestation events, calls ShieldedPool.withdraw)
  • snarkjs WASM loads cleanly in Next.js with dynamic imports (next/dynamic with ssr: false)

Why wagmi:

  • React hooks for wallet connection (MetaMask, WalletConnect)
  • Built-in support for reading contract state and submitting transactions
  • Type-safe contract interactions with viem
  • Works with any EVM chain including Horizen L3 and Base Sepolia

Why browser-side proof generation: The alternative — server-side proof generation — would require the user to send their secret and nullifier to a server. If that server is compromised or malicious, the user's funds can be stolen. By generating proofs in the browser using snarkjs WASM, the user's secret never leaves their device. This is the same trust model used by Tornado Cash.


Summary

Decision Choice Key Reason
Chain Horizen L3 on Base EVM-native, privacy-aligned, inherits Base security
Proof verification zkVerify 91% cheaper than L1; modular; native Groth16 support
Circuit language Circom Most mature EVM ZK toolchain; WASM compilation; circomlib
Proof system Groth16 Smallest proof size; fastest verification; snarkjs support
Contracts Solidity + Foundry EVM standard; fastest test runner; fork testing
Frontend Next.js + wagmi SSR; type-safe contracts; snarkjs WASM integration
Proof generation location Browser (WASM) User's secret never leaves their device