hackquest logo

zk-VEILRWA

VeilRWA is a Zero-knowledge privacy layer for RWA yield on Mantle. Institutions earn verified returns without revealing portfolio balances using Groth16 ZK proofs.

视频

技术栈

Next
React
Web3
Solidity
Node

描述

VeilRWA - Zero-Knowledge Privacy Layer for Real-World Asset Yields

🔗 Links:


🔴 The Problem

Institutional investors face a critical privacy dilemma in DeFi RWA markets. When depositing tokenized real-world assets (T-Bills, bonds, treasuries) on-chain, their entire portfolio balance becomes publicly visible. A $100M fund depositing treasury tokens reveals exact holdings to competitors, enabling front-running and market manipulation. Traditional DeFi protocols force investors to choose between transparency and yield—compromising institutional privacy requirements and regulatory compliance.

Current solutions fail:

  • Mixing protocols sacrifice auditability

  • Private chains lack composability

  • Centralized custodians reintroduce counterparty risk

Institutions need cryptographic privacy that preserves verifiable compliance.


✅ Our Solution

VeilRWA enables institutions to earn verified yields on tokenized RWAs without revealing portfolio balances on-chain. Using zero-knowledge proofs on Mantle's L2, investors deposit assets behind cryptographic commitments—the blockchain stores only a hash, never the amount.

When claiming accrued yield, users generate ZK proofs that cryptographically verify:

  1. ✅ They own the commitment

  2. ✅ Yield calculations are correct

  3. ✅ Time-based accrual is valid

All without exposing the principal balance.


🔧 How It Works

User Workflow

1. Connect Wallet & KYC Verification

User → Connect Wallet → Generate KYC Proof (off-chain)

→ Submit ZK-KYC Proof → Registry verifies → Status: VERIFIED

  • Users prove regulatory credentials using ZK proofs

  • No personal data stored on-chain, only cryptographic proof of eligibility

  • KYC status linked to wallet address via KYCRegistry contract

2. Deposit RWA Tokens (Private)

User selects amount → Generates random salt → Computes commitment

→ commitment = Poseidon(balance, salt)

→ Transfers TBILL tokens to vault

→ Submits commitment hash on-chain

→ Blockchain stores: commitment hash (not balance!)

What's stored on-chain:

Commitment: 0x2a5c8b... (32-byte Poseidon hash)

Balance: HIDDEN ❌ (Never leaves user's browser)

Owner: 0xYourAddress

Timestamp: 1736985600

Privacy guarantee: Even with full blockchain access, balance is computationally infeasible to reverse from the commitment hash.

3. Earn Yield (Off-Chain Accrual)

Time passes → Yield accrues based on APY (e.g., 5% annual)

→ User tracks: balance, salt, deposit time (client-side)

→ No on-chain updates = Zero gas costs

Example:

  • Deposit: 100 TBILL at 5% APY

  • After 1 year: 105 TBILL claimable

  • Blockchain shows: Same commitment hash (balance still hidden)

4. Claim Yield (ZK-Verified)

User requests claim → Computes yield locally

→ Generates ZK proof in browser (SnarkJS):

• Proves ownership of commitment

• Proves yield = balance × rate × time

• Proves time elapsed since deposit

→ Submits proof + nullifier to vault

→ Vault verifies proof via YieldVerifier contract

→ If valid: Transfers yield tokens

→ Nullifier prevents double-claims

On-chain verification (200K gas):

YieldVerifier.verifyProof(

proof, // Groth16 proof (200 bytes)

publicInputs // [commitment, nullifier, yield, timestamp]

) → returns true/false

Result:

  • User receives 5 TBILL yield

  • Balance remains private (commitment unchanged)

  • Transaction shows yield amount, not principal


🏗️ System Architecture

┌─────────────────────────────────────────────────────────────────┐

│ USER (Browser) │

│ • Generates proofs with SnarkJS (client-side, 2-3 sec) │

│ • Stores: balance, salt, witness data (never leaves device) │

└──────────────────────┬──────────────────────────────────────────┘

│ ZK Proof + Public Inputs

┌─────────────────────────────────────────────────────────────────┐

│ MANTLE L2 BLOCKCHAIN │

│ │

│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │

│ │ VeilRWAVault │◄──►│ Verifiers │◄──►│ KYCRegistry │ │

│ │ │ │ • Deposit │ │ │ │

│ │ - Commitments│ │ • Yield │ │ - KYC Status │ │

│ │ - Nullifiers │ │ • KYC │ │ │ │

│ └──────┬───────┘ └──────────────┘ └──────────────┘ │

│ │ │

│ ▼ │

│ ┌──────────────┐ │

│ │ TBILL Token │ (ERC20 RWA) │

│ └──────────────┘ │

└─────────────────────────────────────────────────────────────────┘

Smart Contract Flow

// 1. DEPOSIT

function depositPrivate(bytes32 commitment) external {

require(kycRegistry.isVerified(msg.sender)); // KYC check

commitments[commitment] = CommitmentData({

owner: msg.sender,

timestamp: block.timestamp,

claimed: false

});

rwaToken.transferFrom(msg.sender, address(this), amount);

// ⚠️ 'amount' never stored on-chain!

}

// 2. CLAIM YIELD

function claimYield(

uint256[2] memory a, // Proof component A

uint256[2][2] memory b, // Proof component B

uint256[2] memory c, // Proof component C

uint256[4] memory input // [commitment, nullifier, yield, time]

) external {

require(

yieldVerifier.verifyProof(a, b, c, input),

"Invalid ZK proof"

);

require(!nullifiers[input[1]], "Already claimed");

nullifiers[input[1]] = true; // Prevent double-claim

rwaToken.transfer(msg.sender, input[2]); // Transfer yield

}


🔐 Zero-Knowledge Architecture

Circom Circuits (Groth16 SNARKs)

1. Deposit Circuit (250 constraints)

template DepositCircuit() {

signal input balance; // Private: user's deposit amount

signal input salt; // Private: random 32-byte value

signal output commitment; // Public: Poseidon(balance, salt)

component hasher = Poseidon(2);

hasher.inputs[0] <== balance;

hasher.inputs[1] <== salt;

commitment <== hasher.out;

}

Purpose: Generate commitment hash for private deposits

2. Yield Claim Circuit (2500 constraints)

Purpose: Prove valid yield calculation without revealing balance

template YieldClaimCircuit() {

signal input balance; // Private: original deposit

signal input salt; // Private: commitment salt

signal input rate; // Private: yield rate (e.g., 5%)

signal input depositTime; // Private: deposit timestamp

signal input claimTime; // Private: current timestamp

signal output commitment; // Public: verify ownership

signal output nullifier; // Public: prevent double-claim

signal output yieldAmount; // Public: calculated yield

// Verify commitment ownership

commitment <== Poseidon(balance, salt);

// Calculate yield: balance × rate × timeElapsed / 365 days

signal timeElapsed <== claimTime - depositTime;

yieldAmount <== (balance rate timeElapsed) / 31536000;

// Generate nullifier: Poseidon(commitment, claimTime)

nullifier <== Poseidon(commitment, claimTime);

}

3. KYC Circuit (1800 constraints)

template KYCCircuit() {

signal input credentialHash; // Private: user's KYC credentials

signal input walletAddress; // Public: user's ETH address

signal input kycProvider; // Private: trusted issuer ID

signal output isValid; // Public: 1 if valid, 0 otherwise

// Verify credential matches registered provider

// Prove user owns wallet without revealing identity

isValid <== verifyCredential(credentialHash, kycProvider);

}

Purpose: Prove regulatory compliance without exposing identity

Cryptographic Components

Component

Purpose

Security Level

Groth16

ZK proving system

128-bit security

Poseidon Hash

ZK-friendly commitment

Collision-resistant

BN254 Curve

Pairing-friendly elliptic curve

128-bit security

Nullifiers

Prevent double-claims

Hash-based uniqueness

Random Salt

Commitment hiding

256-bit entropy

Gas Costs (Mantle Sepolia)

Operation

Gas Used

Cost (Est.)

Ethereum L1 Equivalent

Deposit (Private)

~150K gas

$0.03

$90 (3000x cheaper)

Yield Claim (ZK Verify)

~200K gas

$0.05

$120 (2400x cheaper)

KYC Proof Verify

~180K gas

$0.04

$108 (2700x cheaper)

Total cost for full workflow: $0.12 on Mantle vs $318 on Ethereum L1


🚀 Key Differentiators

vs. Tornado Cash / Privacy Pools

  • Privacy for yield, not transfers

  • ✅ Maintains institutional auditability via selective disclosure

  • ✅ Regulatory-compliant (KYC-gated)

  • ❌ Tornado: Mixing-based privacy, sanctioned by OFAC

vs. Aztec / Aleo / ZK-VMs

  • Purpose-built for RWA compliance

  • ✅ Circuit constraints optimized for yield (60% less gas)

  • ✅ Works on existing Mantle L2 (no new VM deployment)

  • ❌ General ZK-VMs: Higher overhead for specialized use cases

vs. Private Chains (Hyperledger, Corda)

  • Full DeFi composability on public Mantle L2

  • ✅ Interacts with AMMs, lending, oracles while maintaining privacy

  • ✅ Censorship-resistant (permissionless blockchain)

  • ❌ Private chains: Isolated networks, no public DeFi access

vs. Centralized Custodians (Fireblocks, Copper)

  • Self-custody + cryptographic verification

  • ✅ Smart contracts enforce rules (no trusted intermediaries)

  • ✅ Permissionless: Anyone with KYC can participate

  • ❌ Custodians: Counterparty risk, centralized control

vs. ZK-Rollups (zkSync, StarkNet)

  • Provides privacy, not just scalability

  • ✅ Balances hidden via commitments (rollups show balances publicly)

  • ✅ Selective disclosure for auditors

  • ❌ Rollups: Focus on scaling, balances remain transparent


📦 Deployed Contracts (Mantle Sepolia)

Core Protocol

Contract

Address

Explorer Link

VeilRWAVault (V3)

0x332dca53aC3C7b86bCb7F9f58E2d6b8284705231

View

MockRWAToken (TBILL)

0x35FB06244022403dc1a0cC308E150b5744e37A6b

View

KYCRegistry

0x0f61cB672d345797f6A1505A282240583F902cb2

View

ZK Verifier Contracts (Groth16)

Verifier

Address

Circuit

Explorer

DepositVerifier

0x20032EA6f975FbfA5aFbA329f2c2fCE51B60FE94

250 constraints

View

YieldVerifier

0x4040D46b287993060eE7f51B7c87F8bfd913508C

2500 constraints

View

KYCVerifier

0x870f9724047acba94885359f38cA55D639A4C564

1800 constraints

View


📊 Live Demo Walkthrough

Try it yourself: https://zk-veilrwa.vercel.app

Step-by-step demo:

  1. Connect Wallet (MetaMask/Coinbase/WalletConnect)

    • Switch to Mantle Sepolia network (auto-prompt)

    • Get test TBILL tokens from faucet

  2. Complete KYC (Mock verification for demo)

    • Navigate to KYC page

    • Generate ZK-KYC proof (off-chain)

    • Submit proof → Status: ✅ VERIFIED

  3. Deposit Assets (Private)

    • Enter amount: 100 TBILL

    • System generates commitment hash

    • Approve + Deposit transaction

    • Result: Commitment stored, balance hidden

  4. Check Balance (On-chain Explorer)

    • Visit Mantle Explorer

    • See: Commitment hash only

    • Privacy preserved ✅

  5. Claim Yield (ZK-Verified)

    • Navigate to Claim page

    • Generate ZK proof (2-3 seconds)

    • Submit proof → Receive 5 TBILL yield

    • Result: Principal still hidden


🌐 Use Cases

Institutional Treasury Management

Problem: Fortune 500 companies don't want competitors seeing cash reserves
Solution: Deposit treasury tokens privately, earn yield, maintain confidentiality

Hedge Fund RWA Allocations

Problem: Alpha strategies revealed through on-chain portfolio analysis
Solution: ZK commitments hide allocation sizes while proving returns

Corporate Bond Portfolios

Problem: Bond holdings signal creditworthiness and strategic positions
Solution: Private bond tokenization with public yield verification

Pension Fund Fixed-Income

Problem: Public pension funds disclose holdings, facing regulatory scrutiny
Solution: Selective disclosure for auditors, privacy from general public

Private Credit Markets

Problem: Loan terms and amounts are commercially sensitive
Solution: ZK proofs of creditworthiness without revealing loan size

Compliant DeFi for TradFi

Problem: Traditional finance can't use DeFi due to transparency concerns.
Solution: Bridge TradFi and DeFi with cryptographic privacy guarantees


🏗️ Built With

Smart Contracts: Solidity 0.8.20 | Hardhat | OpenZeppelin
Zero-Knowledge: Circom 2.0 | SnarkJS | Groth16 SNARKs | Poseidon Hashing
Frontend: Next.js 16.1 | Wagmi v3 | Reown AppKit | TailwindCSS 3.4
Blockchain: Mantle L2 Sepolia Testnet


Privacy meets institutional compliance on Mantle. 🔐

队长
RRohit Amal Raj
项目链接
赛道
RWADeFiDAO