Skip to content
S

shielded-lending-oracle

The protocol knows the decision, not the position.

Created on 21st August 2026

•

S

shielded-lending-oracle

The protocol knows the decision, not the position.

The problem shielded-lending-oracle solves

In almost every DeFi lending market, your collateral amount, debt, and health factor are public on-chain. Anyone can read exactly how leveraged you are, target your position for liquidation, or build a financial profile of you. Privacy simply isn't an option.

Shielded Lending Oracle flips this: the protocol knows the decision, not the position.

A user generates a zero-knowledge proof via EZKL that their position satisfies the lending health requirements. Only the verdict — HEALTHY or LIQUIDATABLE — plus a public price and threshold, ever touches Ethereum. The underlying collateral and debt values remain private and are computed and proven offline.

What people can use it for:

  • Private lending positions where the network verifies safety without learning your exposure.
  • Confidential health checks where a position can be evaluated and acted upon without revealing the private inputs behind the decision.
  • A reusable privacy-preserving oracle pattern for applications that need a yes/no verdict, such as "is this position solvent?", without exposing the underlying numbers.

Challenges I ran into

  • Proof/verifier drift (the big one). Our first on-chain submission reverted with no reason string because proof.json and the deployed Verifier.sol had been generated from different EZKL circuits/setups. The pairing check therefore failed. I fixed this by rebuilding the entire pipeline — train → ONNX → gen_settings → compile_circuit → setup → create_evm_verifier → witness → prove — in a single script run, ensuring the verification key and proof are always consistent. The Foundry integration test then passed against the real verifier.

  • EZKL number encoding. Public signals use little-endian encoding and are scaled by powers of two (2^scale), not base-10. Incorrect decoding initially produced nonsense values, such as a price of 4.48 instead of 2800, causing on-chain submission mismatches. I wrote a shared leHexToBigInt helper and used the same decoding logic across the TypeScript frontend, viem verification script, and contract submission flow.

  • Vercel build failure caused by .gitignore. A repo-wide lib/ ignore rule, originally intended for Foundry's contracts/lib/, also excluded apps/web/lib/. As a result, contracts.ts and proof.ts were missing from Git, causing Vercel to fail with Module not found: Can't resolve '@/lib/proof'. I fixed this by scoping the ignore rules specifically to contracts/lib/, contracts/cache/, and contracts/broadcast/.

  • wagmi v3 + Next.js 16 wiring. Getting wallet connection working without SSR or hydration mismatches required careful handling. I used injected() and coinbaseWallet() connectors, added a mounted guard to the navbar, and configured Sepolia as the default chain because the oracle and verifier are deployed there.

  • End-to-end consistency. The biggest lesson was that a ZK application is only as reliable as the consistency between its circuit, proving key, verifier, proof encoding, and frontend submission logic. I treated the complete pipeline as one system and verified the final result against the live Sepolia contracts.

Tracks Applied (3)

Private DeFi & Mempools

Overall

Devcon Tickets

Discussion

Builders also viewed

See more projects on Devfolio