Logo
Back to Hub

Simple Confidential Vault

Encrypted token storage with confidential balance tracking

Basics
Documentation

FHE Simple Vault

An encrypted vault contract demonstrating balance management, access control, and safe encrypted arithmetic with FHEVM.

What You'll Learn

This example teaches intermediate FHEVM patterns:

  • Encrypted Balance Management: Store and manage encrypted balances per user
  • Conditional Logic with FHE: Use FHE.select() for encrypted if/else logic
  • Encrypted Comparisons: Check balances with FHE.gte() without decryption
  • Multi-User State: Manage isolated encrypted state for multiple users
  • Safe Withdrawal Patterns: Prevent overdraft using encrypted checks

Contract Overview

The FHESimpleVault contract maintains encrypted balances for users, allowing deposits and withdrawals without revealing amounts on-chain.

Key Features

Loading...
  • deposit(inputAmount, inputProof) - Add encrypted funds to your balance
  • withdraw(inputAmount, inputProof) - Remove encrypted funds with balance check
  • getBalance() - Get your encrypted balance for decryption
  • getBalanceOf(user) - Query another user's encrypted balance

Quick Start

Prerequisites

  • Node.js >= 20
  • npm >= 7.0.0

Installation

Loading...

Compile

Loading...

Test

Loading...

Usage Example

Loading...

Key Patterns Demonstrated

1. Encrypted Balance Management

Loading...

Each user has their own encrypted balance that accumulates deposits.

2. Safe Encrypted Withdrawal with Conditional Logic

Loading...

Key Insight: We can't use regular if statements with encrypted values. Instead:

  • FHE.ge() performs encrypted comparison, returns ebool
  • FHE.select() implements encrypted conditional: condition ? valueIfTrue : valueIfFalse
  • Everything stays encrypted - no decryption needed!

3. Encrypted Comparison Operations

Loading...

Available encrypted comparisons:

  • FHE.eq() - Equal to
  • FHE.ne() - Not equal to
  • FHE.lt() - Less than
  • FHE.le() - Less than or equal
  • FHE.gt() - Greater than
  • FHE.ge() - Greater than or equal

All return ebool (encrypted boolean).

4. Permission System

Loading...

Permissions must be set after every state change to encrypted values.

5. Multi-User State Isolation

Loading...

Each address has completely isolated encrypted state - no user can see another's balance without explicit permission.

Important Patterns

Handling Insufficient Balance

This contract uses a silent failure pattern - if you try to withdraw more than your balance, the transaction succeeds but your balance doesn't change:

Loading...

Alternative Pattern (for production): You could use gateway decryption to check balance and revert:

Loading...

Why Not Regular require()?

Loading...

Regular require() needs a plaintext boolean, but our comparison is encrypted!

Testing

The test suite demonstrates:

  • Depositing encrypted amounts
  • Accumulating multiple deposits
  • Withdrawing valid amounts
  • Handling overdraft attempts (balance remains unchanged)
  • Multi-user balance isolation
  • Balance queries with decryption
  • Event emission

Run tests:

Loading...

Production Considerations

1. Add Event Data

Currently events just emit the user address. Consider adding encrypted amount handles:

Loading...

2. Minimum Balance Checks

Add minimum balance requirements:

Loading...

3. Gateway Decryption for Errors

For better UX, use gateway decryption to check balances and provide clear error messages:

Loading...

4. Access Control for getBalanceOf

Currently anyone can query anyone's encrypted balance. Add access control:

Loading...

Next Steps

After mastering this example, explore:

  • Confidential Bank - Gateway decryption and interest calculations
  • ERC7984 - Confidential ERC20 token standard
  • Sealed Auction - Bid sealing and revealing patterns

Resources

License

BSD-3-Clause-Clear


Part of ZCraft FHEVM Examples | Built with Zama FHEVM

Loading...