Version: V2B (cross-shard withdrawal) | Network: Base Sepolia (chain ID 84532) | Status: Testnet pre-alpha — not audited, not for real funds
ShieldLend is a privacy-first lending protocol. Users deposit ETH into a shielded pool, borrow against collateral without revealing their identity, and withdraw to fresh cryptographic addresses. No on-chain linkage between depositor and borrower/withdrawer.
| Layer | Mechanism | What It Hides |
|---|---|---|
| 1. Browser | In-browser ring proof generation; AES-256-GCM note encryption | Note contents never leave device |
| 2. ZK Circuits | Ring proof K=16 across last 30 epochs; Poseidon nullifier | Which commitment is being withdrawn (1-in-16 ring) |
| 3. Smart Contracts | Accounting-only lending; nullifier locking; auto-settle | Loan amount + recipient hidden from event logs |
| 4. zkVerify | Off-chain Groth16 verification (Volta testnet); only the aggregation root is posted to Base | Proof computation off main chain |
| 5. Epoch Batching | 50-block queue + Fisher-Yates shuffle + adaptive dummy commitments | Timing correlation between deposit and withdrawal |
| Feature | Mechanism | Status |
|---|---|---|
| A. Stealth withdrawal addresses | ERC-5564 per-withdrawal fresh address (@scopelift/stealth-address-sdk), auto-forward to the user's wallet |
Implemented for withdraw + borrow |
| B. Server-side deposit relay | Next.js API route submits the deposit, so the user's wallet never calls the pool | Implemented |
| C. Auditor viewing keys | Separate AES-256-GCM key for selective note disclosure | Key context implemented; recovery UI not built |
| D. On-chain encrypted notes | 72-byte binary-packed encrypted note emitted in the Deposit event |
Implemented, verified live |
| E. Sharding + cross-shard withdrawal | 5 shard pools share one circuit and vkHash, so a proof is valid on every shard: deposit on shard X, withdraw from random shard Y | Implemented, verified live |
See docs/privacy-architecture.md for the design and ARCHITECTURE_DECISIONS.md for the 31 ADRs behind it.
V1 (single note Merkle proof, variable amounts, flat rate)
↓
V2A (K=16 ring, epoch batching, fixed denominations, Aave v3 interest, HF liquidation)
↓
V2A+ (stealth addresses, deposit relay, viewing keys, encrypted notes, CREATE2 sharding)
↓
V2B (cross-shard withdrawal and borrow disbursement — all shards share the same vkHash,
so proofs are fungible across shards without a circuit change)
See docs/architecture.md for the full system diagram and data flows.
Smart contracts:
ShieldedPool.sol— ETH vault with epoch batching and ZK withdrawal verification; deployed as 5 shardsLendingPool.sol— accounting-only (never holds ETH); Aave v3 two-slope interest; health factor liquidationNullifierRegistry.sol— global nullifier spend registry shared by all shardsZkVerifyAggregation.sol— zkVerify on-chain aggregation verification
Circuits:
withdraw_ring.circom— K=16 ring membership + depth-24 Merkle inclusion + nullifier bindingcollateral_ring.circom— same structure; proves collateral ownership for borrow
| Contract | Address |
|---|---|
Shard 1 (SHIELDED_POOL_ADDRESS) |
0xcF78eaEA131747c67BBD1869130f0710bA646D8D |
| Shard 2 | 0x3110C104542745c55cCA31A63839F418d1354F5D |
| Shard 3 | 0x39769faD54c21d3D8163D9f24F63473eCC528bE0 |
| Shard 4 | 0x02dfe4aed5Ba2A2085c80F8Fe7c20686d047111B |
| Shard 5 | 0xf3F7C4c1a352371eC3ae7e70387c259c7051b348 |
| LendingPool | 0xA1d0F1A35F547698031F14fE984981632AC26240 |
| NullifierRegistry | 0xEBC14761D4A2E30771E422F52677ed17896ec21F |
| ZkVerifyAggregation | 0x8b722840538d9101bfd8c1c228fb704fbe47f460 |
zkVerify network: Volta testnet | Domain ID: 0 | withdraw_ring vkHash: 0x1702813c4e71d1e48547214eae39ad1b2d07d3643713094e92e619f4f2b0e572
# Contracts — 86 Foundry tests
cd contracts
forge install foundry-rs/forge-std --no-commit
forge install iden3/poseidon-solidity --no-commit
forge test
# Frontend — proving keys and circuit WASM ship in frontend/public/circuits
cd frontend
npm ci # frontend/.npmrc sets legacy-peer-deps
npm run dev # -> http://localhost:3000Create frontend/.env.local:
NEXT_PUBLIC_SHIELDED_POOL_ADDRESS=0xcF78eaEA131747c67BBD1869130f0710bA646D8D
NEXT_PUBLIC_SHARD_1=0xcF78eaEA131747c67BBD1869130f0710bA646D8D
NEXT_PUBLIC_SHARD_2=0x3110C104542745c55cCA31A63839F418d1354F5D
NEXT_PUBLIC_SHARD_3=0x39769faD54c21d3D8163D9f24F63473eCC528bE0
NEXT_PUBLIC_SHARD_4=0x02dfe4aed5Ba2A2085c80F8Fe7c20686d047111B
NEXT_PUBLIC_SHARD_5=0xf3F7C4c1a352371eC3ae7e70387c259c7051b348
NEXT_PUBLIC_LENDING_POOL_ADDRESS=0xA1d0F1A35F547698031F14fE984981632AC26240
NEXT_PUBLIC_NULLIFIER_REGISTRY_ADDRESS=0xEBC14761D4A2E30771E422F52677ed17896ec21F
NEXT_PUBLIC_RELAY_ADDRESS=<relay wallet address>
ZKVERIFY_AGGREGATION_ADDRESS=0x8b722840538d9101bfd8c1c228fb704fbe47f460
DEPLOYER_PRIVATE_KEY=0x... # relay wallet; server-side only
ZKVERIFY_SEED_PHRASE=... # zkVerify Volta account; server-side onlyLive on-chain check against the deployment (32 checks, makes one 0.001 ETH test deposit):
DEPLOYER_PRIVATE_KEY=0x... node frontend/live-test.mjs| Area | Status |
|---|---|
| Contract test suite | 86/86 passing |
Live deployment checks (live-test.mjs) |
32/32 passing on Base Sepolia |
| Frontend production build | Passing |
| Deposit → epoch flush → ZK ring withdraw | Confirmed live in browser |
| Stealth auto-forward after withdraw/borrow | Code-complete (Base L1 data-fee reserve fix); browser re-test pending |
| Borrow → repay | Frontend + API wired; not yet confirmed end-to-end in browser |
| Viewing-key recovery page | Not built |
Known limitations (accepted for testnet):
- zkVerify and LendingPool operator is a single EOA — needs a multisig before mainnet
- The withdrawal recipient is bound by the operator's attestation leaf, not inside the proof; making it a public circuit input is the next circuit change (see
docs/circuits.md) - Shard shuffle is
keccak256-seeded, not Chainlink VRF - Repaying from the user's wallet reveals that the wallet had a loan (not which note or depositor)
- Groth16 keys come from a local development setup, not a public multi-party ceremony
- Security review is internal only — no external audit
| Document | Description |
|---|---|
docs/architecture.md |
System diagram, data flows, smart contract ABIs |
docs/privacy-architecture.md |
Complete privacy model |
docs/circuits.md |
ZK circuit design, public inputs, commitment formula |
docs/tech-stack.md |
Technology choices and rationale |
docs/verification.md |
ZK verification flow, zkVerify integration |
ARCHITECTURE_DECISIONS.md |
ADR-01 to ADR-31 |
AUDIT_REPORT.md |
Internal security review findings and fixes |
SESSION_LOGS/ |
Dated build log for every development session |
ROADMAP.md |
Build history and upcoming milestones |
MIT — see LICENSE.