Simple Confidential Vault
Encrypted token storage with confidential balance tracking
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 balancewithdraw(inputAmount, inputProof)- Remove encrypted funds with balance checkgetBalance()- Get your encrypted balance for decryptiongetBalanceOf(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, returnseboolFHE.select()implements encrypted conditional:condition ? valueIfTrue : valueIfFalse- Everything stays encrypted - no decryption needed!
3. Encrypted Comparison Operations
Loading...
Available encrypted comparisons:
FHE.eq()- Equal toFHE.ne()- Not equal toFHE.lt()- Less thanFHE.le()- Less than or equalFHE.gt()- Greater thanFHE.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...
