create-fhevm-example 1.4.4 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/contracts/advanced/BlindAuction.sol +5 -1
  2. package/contracts/advanced/EncryptedEscrow.sol +5 -1
  3. package/contracts/advanced/HiddenVoting.sol +5 -1
  4. package/contracts/advanced/PrivateKYC.sol +6 -1
  5. package/contracts/advanced/PrivatePayroll.sol +5 -1
  6. package/contracts/basic/decryption/PublicDecryptMultipleValues.sol +11 -5
  7. package/contracts/basic/decryption/PublicDecryptSingleValue.sol +11 -5
  8. package/contracts/basic/decryption/UserDecryptMultipleValues.sol +5 -1
  9. package/contracts/basic/decryption/UserDecryptSingleValue.sol +5 -1
  10. package/contracts/basic/encryption/EncryptMultipleValues.sol +4 -1
  11. package/contracts/basic/encryption/EncryptSingleValue.sol +6 -2
  12. package/contracts/basic/encryption/FHECounter.sol +4 -1
  13. package/contracts/basic/fhe-operations/FHEAdd.sol +5 -1
  14. package/contracts/basic/fhe-operations/FHEArithmetic.sol +5 -1
  15. package/contracts/basic/fhe-operations/FHEComparison.sol +5 -1
  16. package/contracts/basic/fhe-operations/FHEIfThenElse.sol +5 -1
  17. package/contracts/concepts/FHEAccessControl.sol +8 -3
  18. package/contracts/concepts/FHEAntiPatterns.sol +5 -1
  19. package/contracts/concepts/FHEHandles.sol +5 -1
  20. package/contracts/concepts/FHEInputProof.sol +5 -1
  21. package/contracts/gaming/EncryptedLottery.sol +5 -1
  22. package/contracts/gaming/EncryptedPoker.sol +5 -1
  23. package/contracts/gaming/RockPaperScissors.sol +5 -1
  24. package/contracts/openzeppelin/ERC7984.sol +6 -1
  25. package/contracts/openzeppelin/ERC7984ERC20Wrapper.sol +5 -1
  26. package/contracts/openzeppelin/SwapERC7984ToERC20.sol +5 -1
  27. package/contracts/openzeppelin/SwapERC7984ToERC7984.sol +5 -1
  28. package/contracts/openzeppelin/VestingWallet.sol +6 -1
  29. package/dist/scripts/commands/generate-config.js +18 -3
  30. package/dist/scripts/shared/config.d.ts.map +1 -1
  31. package/dist/scripts/shared/config.js +81 -75
  32. package/package.json +1 -1
@@ -10,7 +10,11 @@ import {
10
10
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
11
11
 
12
12
  /**
13
- * @notice Blind Auction with encrypted bids - only the winning price is revealed after bidding ends
13
+ * @notice Blind auction where bids remain encrypted until the end.
14
+ * Bidders submit encrypted amounts. The contract finds the highest bid
15
+ * using FHE.gt and FHE.select without ever decrypting losing bids.
16
+ * Only the winning bid amount is revealed after the auction closes.
17
+ * Losing bids remain private forever, ensuring true bid confidentiality.
14
18
 
15
19
  * @dev Flow: bid() → endAuction() → revealWinner()
16
20
  * Uses FHE.gt/select to find winner without revealing losing bids.
@@ -10,7 +10,11 @@ import {
10
10
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
11
11
 
12
12
  /**
13
- * @notice Encrypted Escrow service - amounts hidden until release!
13
+ * @notice Confidential escrow service with hidden transaction amounts.
14
+ * Buyer and seller agree on encrypted escrow amount. Funds are held
15
+ * securely until conditions are met. Amount remains hidden from public
16
+ * view until release or refund. Includes arbiter for dispute resolution.
17
+ * Perfect for high-value transactions requiring privacy.
14
18
  *
15
19
  * @dev Flow: createEscrow() → fundEscrow() → release()/requestRefund()/raiseDispute()
16
20
  * Multi-party agreement with arbiter for disputes.
@@ -5,7 +5,11 @@ import {FHE, euint64, ebool, externalEuint8} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Hidden Voting with encrypted ballots and homomorphic tallying - individual votes stay private forever!
8
+ * @notice Private voting system with homomorphic vote tallying.
9
+ * Voters submit encrypted ballots (Yes/No). Votes are tallied using
10
+ * homomorphic addition WITHOUT decrypting individual ballots. Only the
11
+ * final tally is revealed - individual votes remain private forever.
12
+ * Perfect for DAO governance, elections, or any scenario requiring ballot secrecy.
9
13
  *
10
14
  * @dev Flow: vote() → closeVoting() → revealResults()
11
15
  * ⚡ Gas: Each vote costs ~200k gas (FHE.add + FHE.select operations)
@@ -12,7 +12,12 @@ import {
12
12
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
13
13
 
14
14
  /**
15
- * @notice Private KYC - verify identity without revealing personal data!
15
+ * @notice Privacy-preserving identity verification using predicate proofs.
16
+ * Users submit encrypted personal data (age, country, credit score).
17
+ * Contract can verify predicates like "Is user 18+?" or "Good credit?"
18
+ * without learning the actual values. Returns encrypted booleans that
19
+ * prove compliance without revealing sensitive information. Revolutionary
20
+ * for KYC/AML compliance while preserving user privacy.
16
21
  *
17
22
  * @dev Flow: submitKYC() → verifyAge18()/verifyGoodCredit()/etc.
18
23
  * Returns encrypted booleans: "Is 18+?", "Good credit?" without revealing actual values.
@@ -10,7 +10,11 @@ import {
10
10
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
11
11
 
12
12
  /**
13
- * @notice Private Payroll system - salaries stay encrypted, only employees see their own!
13
+ * @notice Confidential payroll system with encrypted salaries.
14
+ * Employers can add employees with encrypted salary amounts. Each employee
15
+ * can decrypt only their own salary - other salaries remain hidden.
16
+ * Demonstrates selective decryption permissions where different users
17
+ * see different encrypted values. Perfect for privacy-preserving HR systems.
14
18
  *
15
19
  * @dev Flow: addEmployee() → fund() → processPayment()
16
20
  * Each employee can decrypt only their own salary.
@@ -5,7 +5,11 @@ import {FHE, euint8} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice 8-sided die roll game demonstrating public decryption of multiple encrypted values.
8
+ * @notice Highest die roll game with public decryption of multiple values.
9
+ * Two players roll encrypted 8-sided dice, results are made publicly
10
+ * decryptable. Demonstrates handling multiple encrypted values in
11
+ * checkSignatures() where ORDER MATTERS - the cts[] array must match
12
+ * the order of values in the ABI-encoded result.
9
13
  *
10
14
  * @dev Uses FHE.randEuint8() + FHE.makePubliclyDecryptable() for both dice rolls.
11
15
  * ⚠️ Order matters in cts[] array for checkSignatures!
@@ -29,7 +33,8 @@ contract HighestDieRoll is ZamaEthereumConfig {
29
33
  // Mapping to store all game states, accessible by a unique game ID.
30
34
  mapping(uint256 gameId => Game game) public games;
31
35
 
32
- /// @notice Emitted when a new game is started, providing the encrypted handle required for decryption
36
+ /// @notice Emitted when a new game is started,
37
+ /// providing the encrypted handle required for decryption
33
38
  /// @param gameId The unique identifier for the game
34
39
  /// @param playerA The address of playerA
35
40
  /// @param playerB The address of playerB
@@ -97,7 +102,8 @@ contract HighestDieRoll is ZamaEthereumConfig {
97
102
  return games[gameId].playerBEncryptedDieRoll;
98
103
  }
99
104
 
100
- /// @notice Returns the address of the game winner. If the game is finalized, the function returns `address(0)`
105
+ /// @notice Returns the address of the game winner.
106
+ /// If the game is finalized, the function returns `address(0)`
101
107
  /// @notice if the game is a draw.
102
108
  function getWinner(uint256 gameId) public view returns (address) {
103
109
  require(games[gameId].revealed, "Game winner not yet revealed");
@@ -109,8 +115,8 @@ contract HighestDieRoll is ZamaEthereumConfig {
109
115
  return games[gameId].revealed;
110
116
  }
111
117
 
112
- /// @notice Verifies the provided (decryption proof, ABI-encoded clear values) pair against the stored ciphertext,
113
- /// @notice and then stores the winner of the game.
118
+ /// @notice Verifies the provided (decryption proof, ABI-encoded clear values)
119
+ /// pair against the stored ciphertext, and then stores the winner of the game.
114
120
  function recordAndVerifyWinner(
115
121
  uint256 gameId,
116
122
  bytes memory abiEncodedClearGameResult,
@@ -5,7 +5,11 @@ import {FHE, ebool} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Simple Heads or Tails game demonstrating public, permissionless decryption with FHE.
8
+ * @notice Heads or Tails game with public, permissionless decryption.
9
+ * Demonstrates makePubliclyDecryptable() which allows ANYONE to decrypt
10
+ * the result (not just allowed users). Perfect for public game results,
11
+ * lottery winners, or voting tallies. Uses FHE.randEbool() for fair
12
+ * randomness and KMS-verified decryption proofs.
9
13
  *
10
14
  * @dev Uses FHE.randEbool() for random result + FHE.makePubliclyDecryptable() for revealing.
11
15
  * Anyone can decrypt results with valid KMS proof.
@@ -27,7 +31,8 @@ contract HeadsOrTails is ZamaEthereumConfig {
27
31
  // Mapping to store all game states, accessible by a unique game ID.
28
32
  mapping(uint256 gameId => Game game) public games;
29
33
 
30
- /// @notice Emitted when a new game is started, providing the encrypted handle required for decryption
34
+ /// @notice Emitted when a new game is started,
35
+ /// providing the encrypted handle required for decryption
31
36
  /// @param gameId The unique identifier for the game
32
37
  /// @param headsPlayer The address choosing Heads
33
38
  /// @param tailsPlayer The address choosing Tails
@@ -97,10 +102,11 @@ contract HeadsOrTails is ZamaEthereumConfig {
97
102
  return games[gameId].winner;
98
103
  }
99
104
 
100
- /// @notice Verifies the provided (decryption proof, ABI-encoded clear value) pair against the stored ciphertext,
101
- /// @notice and then stores the winner of the game.
105
+ /// @notice Verifies the provided (decryption proof, ABI-encoded clear value)
106
+ /// pair against the stored ciphertext, and then stores the winner of the game.
102
107
  /// @dev gameId: The ID of the game to settle.
103
- /// abiEncodedClearGameResult: The ABI-encoded clear value (bool) associated to the `decryptionProof`.
108
+ /// abiEncodedClearGameResult: The ABI-encoded clear value (bool)
109
+ /// associated to the `decryptionProof`.
104
110
  /// decryptionProof: The proof that validates the decryption.
105
111
  function recordAndVerifyWinner(
106
112
  uint256 gameId,
@@ -5,7 +5,11 @@ import {FHE, ebool, euint32, euint64} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Demonstrates user decryption of multiple encrypted values with different types.
8
+ * @notice Decrypting multiple encrypted values of different types for a user.
9
+ * Shows how to handle ebool, euint32, and euint64 in one contract.
10
+ * Each value requires individual permission grants - there's no batching
11
+ * for permissions (unlike input proofs). Demonstrates the pattern of
12
+ * granting allowThis() for each value separately.
9
13
  *
10
14
  * @dev Each value needs separate permission grants (no batching).
11
15
  * ⚠️ Cannot batch permission grants - must call allow() for each value!
@@ -5,7 +5,11 @@ import {FHE, euint32} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Demonstrates FHE decryption mechanism and highlights the critical permission pattern.
8
+ * @notice User-controlled decryption with proper permission management.
9
+ * Demonstrates the critical two-step permission pattern: allowThis()
10
+ * grants the contract permission to store/compute, while allow() grants
11
+ * the user permission to decrypt. Missing either step causes decryption
12
+ * to fail. Includes examples of both correct and incorrect patterns.
9
13
  *
10
14
  * @dev Shows CORRECT vs INCORRECT permission granting.
11
15
  * ⚠️ Both allowThis + allow required for user decryption!
@@ -13,7 +13,10 @@ import {
13
13
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
14
14
 
15
15
  /**
16
- * @notice Encrypting and handling multiple values in a single transaction efficiently.
16
+ * @notice Efficient handling of multiple encrypted values in one transaction.
17
+ * Demonstrates batched input validation where a single proof covers
18
+ * multiple encrypted values (ebool, euint32, eaddress), saving ~50k gas
19
+ * per additional value compared to separate proofs.
17
20
  *
18
21
  * @dev Demonstrates batched input (ONE proof for multiple values).
19
22
  * ⚡ Gas: Batching saves ~50k gas vs separate proofs!
@@ -5,7 +5,10 @@ import {FHE, externalEuint32, euint32} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice FHE encryption mechanism with single values, including common pitfalls and best practices.
8
+ * @notice Single value encryption with proof validation.
9
+ * Shows how to receive encrypted data from users, validate proofs,
10
+ * and grant proper permissions. Includes examples of common mistakes
11
+ * and the correct permission pattern (allowThis + allow).
9
12
 
10
13
  * @dev Shows the complete flow: receiving encrypted input from user, validating proof,
11
14
  * storing the encrypted value, and granting permissions for decryption.
@@ -20,7 +23,8 @@ contract EncryptSingleValue is ZamaEthereumConfig {
20
23
  externalEuint32 inputEuint32,
21
24
  bytes calldata inputProof
22
25
  ) external {
23
- // 🔐 Why proof? Prevents: replay attacks, wrong contract, invalid ciphertext
26
+ // 🔐 Why proof?
27
+ // Prevents: replay attacks, wrong contract, invalid ciphertext
24
28
  _encryptedEuint32 = FHE.fromExternal(inputEuint32, inputProof);
25
29
 
26
30
  // 🔑 Why both?
@@ -5,7 +5,10 @@ import {FHE, euint32, externalEuint32} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Confidential counter implementation using FHEVM, compared with a standard counter to highlight encryption benefits.
8
+ * @notice Confidential counter with encrypted increment/decrement operations.
9
+ * Demonstrates the complete FHE workflow: encryption, computation,
10
+ * and permission management. The counter value remains private,
11
+ * only accessible through decryption by authorized users.
9
12
 
10
13
  * @dev Demonstrates basic FHE workflow: fromExternal() → compute → allow permissions.
11
14
  * All arithmetic happens on encrypted values without revealing the count.
@@ -5,7 +5,11 @@ import {FHE, euint8, externalEuint8} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Simple example demonstrating addition of two encrypted values (a + b)
8
+ * @notice Introduction to homomorphic addition on encrypted values.
9
+ * Demonstrates the most fundamental FHE operation: adding two encrypted
10
+ * numbers without decrypting them. Shows the complete flow from receiving
11
+ * encrypted inputs, performing the addition, and granting permissions
12
+ * for both contract storage and user decryption.
9
13
 
10
14
  * @dev Shows the most basic FHE operation and permission flow.
11
15
  * ⚡ Gas: FHE.add() costs ~100k gas (coprocessor call)
@@ -5,7 +5,11 @@ import {FHE, euint32, externalEuint32} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Demonstrates all FHE arithmetic operations: add, sub, mul, div, rem, min, max
8
+ * @notice Complete suite of FHE arithmetic operations on encrypted values.
9
+ * Covers all basic math: addition, subtraction, multiplication, division,
10
+ * remainder (modulo), minimum, and maximum. Includes gas cost comparisons
11
+ * and important limitations (e.g., division/remainder only work with
12
+ * plaintext divisors, not encrypted divisors).
9
13
  *
10
14
  * @dev ⚡ Gas costs vary: add/sub (~100k) < mul (~150k) < div/rem (~300k)
11
15
  * ⚠️ div/rem only work with plaintext divisor (not encrypted!)
@@ -10,7 +10,11 @@ import {
10
10
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
11
11
 
12
12
  /**
13
- * @notice Demonstrates all FHE comparison operations: eq, ne, gt, lt, ge, le, select
13
+ * @notice Complete guide to encrypted comparisons and conditional selection.
14
+ * Covers all comparison operators (eq, ne, gt, lt, ge, le) that return
15
+ * encrypted booleans (ebool), and demonstrates FHE.select for branching
16
+ * without information leakage. Critical for implementing logic like
17
+ * "find maximum" or "check threshold" without revealing values.
14
18
  *
15
19
  * @dev Results are encrypted booleans (ebool) - comparisons reveal nothing!
16
20
  * ⚡ Gas: Comparisons ~100k, select ~120k
@@ -5,7 +5,11 @@ import {FHE, ebool, euint8, externalEuint8} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Demonstrates conditional logic: max(a, b) using encrypted comparison
8
+ * @notice Conditional logic without information leakage using FHE.select.
9
+ * Demonstrates how to implement if-then-else logic on encrypted values
10
+ * (computing max of two numbers). Using regular if/else would decrypt
11
+ * and leak which branch was taken. FHE.select evaluates BOTH branches
12
+ * and picks one based on the encrypted condition, preserving privacy.
9
13
  *
10
14
  * @dev ❌ Can't use if/else (leaks info!) ✅ Use FHE.select instead
11
15
  * ⚡ Gas: ~120k for select operation
@@ -5,9 +5,14 @@ import {FHE, euint32, externalEuint32} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Critical access control patterns in FHEVM: FHE.allow, FHE.allowThis, FHE.allowTransient with common mistakes.
9
-
10
- * @dev allow() = permanent, allowThis() = contract permission, allowTransient() = expires at TX end
8
+ * @notice Master class for FHE permission patterns and access control.
9
+ * Explains the three permission types: allow() for permanent access,
10
+ * allowThis() for contract operations, and allowTransient() for
11
+ * temporary cross-contract calls. Includes correct and incorrect
12
+ * usage examples to prevent common decryption failures.
13
+
14
+ * @dev allow() = permanent, allowThis() = contract permission,
15
+ * allowTransient() = expires at TX end
11
16
  * Both allowThis + allow required for user decryption!
12
17
  */
13
18
  contract FHEAccessControl is ZamaEthereumConfig {
@@ -10,7 +10,11 @@ import {
10
10
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
11
11
 
12
12
  /**
13
- * @notice Common FHE mistakes and correct alternatives: branching, permissions, require, loops, noise, deprecated APIs.
13
+ * @notice Comprehensive guide to FHE anti-patterns and their solutions.
14
+ * Covers 9 critical mistakes: using if/else on encrypted values,
15
+ * incorrect permission patterns, require() statements that leak info,
16
+ * unbounded loops, noise accumulation, and deprecated APIs.
17
+ * Each pattern shows both ❌ WRONG and ✅ CORRECT implementations.
14
18
  *
15
19
  * @dev Covers 9 critical anti-patterns with ❌ WRONG and ✅ CORRECT examples.
16
20
  * This is an educational contract - study each pattern before building production code!
@@ -5,7 +5,11 @@ import {FHE, euint32, externalEuint32} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Understanding FHE handles: creation, computation, and immut ability.
8
+ * @notice Deep dive into FHE handles: what they are and how they work.
9
+ * Explains that handles are uint256 pointers to encrypted data,
10
+ * demonstrates three creation methods (fromExternal, asEuint, operations),
11
+ * and emphasizes immutability - every operation creates a NEW handle.
12
+ * Includes gas cost comparisons for different operations.
9
13
  *
10
14
  * @dev Handle = uint256 pointer to encrypted data. Operations create NEW handles (immutable).
11
15
  * ⚡ Gas: asEuint32 ~20k, fromExternal ~50k, add/sub ~100k
@@ -11,7 +11,11 @@ import {
11
11
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
12
12
 
13
13
  /**
14
- * @notice Explains input proof validation in FHEVM: why proofs matter and how to batch inputs efficiently.
14
+ * @notice Input proof validation and batching strategies in FHEVM.
15
+ * Explains why proofs are essential (prevent garbage data, wrong types,
16
+ * and replay attacks) and demonstrates the gas-efficient batching pattern
17
+ * where one proof validates multiple encrypted inputs, saving ~50k gas
18
+ * per additional value.
15
19
  *
16
20
  * @dev Proofs ensure: valid ciphertext + correct range + proof of knowledge.
17
21
  * ⚡ Gas: Batching multiple values in ONE proof saves ~50k gas vs separate proofs!
@@ -11,7 +11,11 @@ import {
11
11
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
12
12
 
13
13
  /**
14
- * @notice Encrypted Lottery with private ticket numbers - fair and verifiable!
14
+ * @notice Provably fair lottery with encrypted ticket numbers.
15
+ * Players buy tickets with encrypted numbers. Winning number is generated
16
+ * using FHE randomness. Winner is determined by comparing encrypted values
17
+ * without revealing losing tickets. Ensures fairness and privacy - no one
18
+ * can see ticket numbers before the draw.
15
19
  *
16
20
  * @dev Flow: buyTicket() → startDrawing() → checkAndClaim() → revealWinner()
17
21
  * ⚡ Gas: Loop in checkAndClaim can be expensive with many tickets!
@@ -11,7 +11,11 @@ import {
11
11
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
12
12
 
13
13
  /**
14
- * @notice Encrypted Poker - Texas Hold'em with hidden hole cards!
14
+ * @notice On-chain Texas Hold'em poker with encrypted hole cards.
15
+ * Two players receive encrypted hole cards that remain hidden throughout
16
+ * the game. Hand strength is computed using FHE operations. Winner is
17
+ * determined by comparing encrypted hand strengths. Demonstrates complex
18
+ * game logic with multiple encrypted states and conditional operations.
15
19
  *
16
20
  * @dev Flow: joinGame() → bet()/fold() → showdown() → revealWinner()
17
21
  * Hand strength = card1 + card2 (simplified for demo)
@@ -5,7 +5,11 @@ import {FHE, euint8, ebool, externalEuint8} from "@fhevm/solidity/lib/FHE.sol";
5
5
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
6
6
 
7
7
  /**
8
- * @notice Rock-Paper-Scissors game with encrypted moves - fair play guaranteed using FHE!
8
+ * @notice Fair Rock-Paper-Scissors game with encrypted moves.
9
+ * Players submit encrypted moves (0=Rock, 1=Paper, 2=Scissors) ensuring
10
+ * neither player can see the other's choice before committing. Winner is
11
+ * determined using FHE operations and revealed publicly. No trusted third
12
+ * party needed - cryptography guarantees fairness.
9
13
 
10
14
  * @dev Commit-reveal pattern without trusted third party.
11
15
  * Move encoding: 0=Rock, 1=Paper, 2=Scissors
@@ -12,7 +12,12 @@ import {
12
12
  } from "@openzeppelin/confidential-contracts/token/ERC7984/ERC7984.sol";
13
13
 
14
14
  /**
15
- * @notice Confidential token using OpenZeppelin's ERC7984 standard
15
+ * @notice Confidential ERC20-compatible token using OpenZeppelin's ERC7984 standard.
16
+ * Implements a fully private token where balances and transfer amounts
17
+ * are encrypted. Compatible with standard ERC20 interfaces but with FHE
18
+ * under the hood. Supports both visible minting (owner knows amount) and
19
+ * confidential minting (fully private). Foundation for building private
20
+ * DeFi applications.
16
21
  *
17
22
  * @dev Demonstrates minting and burning with both visible and encrypted amounts.
18
23
  * Shows how to integrate FHE with standard token operations.
@@ -9,7 +9,11 @@ import {
9
9
  } from "@openzeppelin/confidential-contracts/token/ERC7984/extensions/ERC7984ERC20Wrapper.sol";
10
10
 
11
11
  /**
12
- * @notice Wraps ERC20 tokens into confidential ERC7984 tokens
12
+ * @notice Bridge between public ERC20 and confidential ERC7984 tokens.
13
+ * Allows users to wrap regular ERC20 tokens into privacy-preserving
14
+ * ERC7984 tokens (public → private) and unwrap them back (private → public).
15
+ * Wrapping is instant, unwrapping requires decryption proof from KMS.
16
+ * Essential for bringing existing tokens into the confidential ecosystem.
13
17
  *
14
18
  * @dev WRAP: ERC20 → ERC7984 (public → private)
15
19
  * UNWRAP: ERC7984 → ERC20 (private → public, requires decryption)
@@ -12,7 +12,11 @@ import {
12
12
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
13
13
 
14
14
  /**
15
- * @notice Swap confidential ERC7984 tokens to regular ERC20 tokens
15
+ * @notice Atomic swap from confidential ERC7984 to public ERC20 tokens.
16
+ * Two-step process: (1) Initiate swap with encrypted amount, request
17
+ * decryption from KMS. (2) Finalize swap with decryption proof, receive
18
+ * ERC20 tokens. Demonstrates the FHEVM v0.9 public decryption flow with
19
+ * makePubliclyDecryptable() and checkSignatures() for trustless swaps.
16
20
  *
17
21
  * @dev Uses FHEVM v0.9 decryption flow:
18
22
  * FHE.makePubliclyDecryptable() + FHE.checkSignatures()
@@ -8,7 +8,11 @@ import {
8
8
  import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";
9
9
 
10
10
  /**
11
- * @notice Fully confidential swap between two ERC7984 tokens
11
+ * @notice Fully private atomic swap between two confidential ERC7984 tokens.
12
+ * Both input and output amounts remain encrypted throughout the entire
13
+ * swap process. No decryption needed - amounts stay private from start
14
+ * to finish. Perfect for confidential DEX operations where trade sizes
15
+ * must remain hidden. The ultimate privacy-preserving token exchange.
12
16
  *
13
17
  * @dev Both input and output amounts remain encrypted throughout the swap.
14
18
  */
@@ -12,7 +12,12 @@ import {
12
12
  } from "@openzeppelin/confidential-contracts/interfaces/IERC7984.sol";
13
13
 
14
14
  /**
15
- * @notice Linear vesting wallet for ERC7984 tokens with fully encrypted amounts and schedules.
15
+ * @notice Time-locked vesting wallet with fully encrypted token amounts.
16
+ * Implements linear vesting for ERC7984 confidential tokens. Vesting
17
+ * schedule, amounts, and release calculations all happen on encrypted
18
+ * values using FHE operations. Beneficiary can release vested tokens
19
+ * over time without revealing the total allocation or vesting progress
20
+ * to observers.
16
21
 
17
22
  * @dev Timeline: |--START--|---VESTING---|--END--| (0% → linear → 100%)
18
23
  * All vesting calculations performed on encrypted values using FHE.
@@ -56,9 +56,24 @@ const OUTPUT_FILE = path.join(ROOT_DIR, "scripts/shared/config.ts");
56
56
  // =============================================================================
57
57
  function extractNotice(contractPath) {
58
58
  const content = fs.readFileSync(contractPath, "utf-8");
59
- const noticeRegex = /\/\*\*[\s\S]*?@notice\s+([^\n*]+)[\s\S]*?\*\/[\s\S]*?contract\s+\w+/;
59
+ // Match @notice and capture everything until @dev or end of comment block
60
+ const noticeRegex = /\/\*\*[\s\S]*?@notice\s+([\s\S]*?)(?:@dev|@param|\*\/)/;
60
61
  const match = content.match(noticeRegex);
61
- return match && match[1] ? match[1].trim() : null;
62
+ if (!match || !match[1]) {
63
+ return null;
64
+ }
65
+ // Clean up the extracted text:
66
+ // 1. Remove leading asterisks and whitespace from each line
67
+ // 2. Join lines with space
68
+ // 3. Collapse multiple spaces
69
+ const cleaned = match[1]
70
+ .split("\n")
71
+ .map((line) => line.replace(/^\s*\*\s?/, "").trim())
72
+ .filter((line) => line.length > 0)
73
+ .join(" ")
74
+ .replace(/\s+/g, " ")
75
+ .trim();
76
+ return cleaned || null;
62
77
  }
63
78
  function readExistingConfig() {
64
79
  try {
@@ -160,7 +175,7 @@ function generateExamplesConfig(contracts) {
160
175
  contract: "${c.contractPath}",
161
176
  test: "${c.testPath}",${npmDepsField}${depsField}
162
177
  description:
163
- "${c.description}",
178
+ "${c.description.replace(/"/g, '\\"')}",
164
179
  category: "${c.category}",
165
180
  docsOutput: "${c.docsOutput}",
166
181
  title: "${c.title}"
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../scripts/shared/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAMD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CA+QlD,CAAC;AAMF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAoJrD,CAAC;AAMF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../scripts/shared/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,uCAAuC;IACvC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,SAAS,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAClD;AAMD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CA6RlD,CAAC;AAMF,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAoJrD,CAAC;AAMF;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAE3C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAElE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEpE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE3D"}
@@ -19,253 +19,259 @@ exports.EXAMPLES = {
19
19
  "blind-auction": {
20
20
  contract: "contracts/advanced/BlindAuction.sol",
21
21
  test: "test/advanced/BlindAuction.ts",
22
- description: "Blind Auction with encrypted bids - only the winning price is revealed",
22
+ description: "Blind auction where bids remain encrypted until the end. Bidders submit encrypted amounts. The contract finds the highest bid using FHE.gt and FHE.select without ever decrypting losing bids. Only the winning bid amount is revealed after the auction closes. Losing bids remain private forever, ensuring true bid confidentiality.",
23
23
  category: "Advanced",
24
24
  docsOutput: "docs/advanced/blind-auction.md",
25
- title: "Blind Auction",
25
+ title: "Blind Auction"
26
26
  },
27
27
  "encrypted-escrow": {
28
28
  contract: "contracts/advanced/EncryptedEscrow.sol",
29
29
  test: "test/advanced/EncryptedEscrow.ts",
30
- description: "Encrypted Escrow service - amounts hidden until release!",
30
+ description: "Confidential escrow service with hidden transaction amounts. Buyer and seller agree on encrypted escrow amount. Funds are held securely until conditions are met. Amount remains hidden from public view until release or refund. Includes arbiter for dispute resolution. Perfect for high-value transactions requiring privacy.",
31
31
  category: "Advanced",
32
32
  docsOutput: "docs/advanced/encrypted-escrow.md",
33
- title: "Encrypted Escrow",
33
+ title: "Encrypted Escrow"
34
34
  },
35
35
  "hidden-voting": {
36
36
  contract: "contracts/advanced/HiddenVoting.sol",
37
37
  test: "test/advanced/HiddenVoting.ts",
38
- description: "Hidden Voting with encrypted ballots and homomorphic tallying",
38
+ description: "Private voting system with homomorphic vote tallying. Voters submit encrypted ballots (Yes/No). Votes are tallied using homomorphic addition WITHOUT decrypting individual ballots. Only the final tally is revealed - individual votes remain private forever. Perfect for DAO governance, elections, or any scenario requiring ballot secrecy.",
39
39
  category: "Advanced",
40
40
  docsOutput: "docs/advanced/hidden-voting.md",
41
- title: "Hidden Voting",
41
+ title: "Hidden Voting"
42
42
  },
43
43
  "private-kyc": {
44
44
  contract: "contracts/advanced/PrivateKYC.sol",
45
45
  test: "test/advanced/PrivateKYC.ts",
46
- description: "Private KYC - verify identity without revealing personal data!",
46
+ description: "Privacy-preserving identity verification using predicate proofs. Users submit encrypted personal data (age, country, credit score). Contract can verify predicates like \"Is user 18+?\" or \"Good credit?\" without learning the actual values. Returns encrypted booleans that prove compliance without revealing sensitive information. Revolutionary for KYC/AML compliance while preserving user privacy.",
47
47
  category: "Advanced",
48
48
  docsOutput: "docs/advanced/private-kyc.md",
49
- title: "Private KYC",
49
+ title: "Private KYC"
50
50
  },
51
51
  "private-payroll": {
52
52
  contract: "contracts/advanced/PrivatePayroll.sol",
53
53
  test: "test/advanced/PrivatePayroll.ts",
54
- description: "Private Payroll system - salaries stay encrypted, only employees see their own!",
54
+ description: "Confidential payroll system with encrypted salaries. Employers can add employees with encrypted salary amounts. Each employee can decrypt only their own salary - other salaries remain hidden. Demonstrates selective decryption permissions where different users see different encrypted values. Perfect for privacy-preserving HR systems.",
55
55
  category: "Advanced",
56
56
  docsOutput: "docs/advanced/private-payroll.md",
57
- title: "Private Payroll",
57
+ title: "Private Payroll"
58
58
  },
59
59
  "public-decrypt-multiple-values": {
60
60
  contract: "contracts/basic/decryption/PublicDecryptMultipleValues.sol",
61
61
  test: "test/basic/decryption/PublicDecryptMultipleValues.ts",
62
- description: "Implements a simple 8-sided Die Roll game demonstrating public, permissionless decryption",
62
+ description: "Highest die roll game with public decryption of multiple values. Two players roll encrypted 8-sided dice, results are made publicly decryptable. Demonstrates handling multiple encrypted values in checkSignatures() where ORDER MATTERS - the cts[] array must match the order of values in the ABI-encoded result.",
63
63
  category: "Basic - Decryption",
64
64
  docsOutput: "docs/basic/decryption/public-decrypt-multiple-values.md",
65
- title: "Public Decrypt Multiple Values",
65
+ title: "Public Decrypt Multiple Values"
66
66
  },
67
67
  "public-decrypt-single-value": {
68
68
  contract: "contracts/basic/decryption/PublicDecryptSingleValue.sol",
69
69
  test: "test/basic/decryption/PublicDecryptSingleValue.ts",
70
- description: "Implements a simple Heads or Tails game demonstrating public, permissionless decryption",
70
+ description: "Heads or Tails game with public, permissionless decryption. Demonstrates makePubliclyDecryptable() which allows ANYONE to decrypt the result (not just allowed users). Perfect for public game results, lottery winners, or voting tallies. Uses FHE.randEbool() for fair randomness and KMS-verified decryption proofs.",
71
71
  category: "Basic - Decryption",
72
72
  docsOutput: "docs/basic/decryption/public-decrypt-single-value.md",
73
- title: "Public Decrypt Single Value",
73
+ title: "Public Decrypt Single Value"
74
74
  },
75
75
  "user-decrypt-multiple-values": {
76
76
  contract: "contracts/basic/decryption/UserDecryptMultipleValues.sol",
77
77
  test: "test/basic/decryption/UserDecryptMultipleValues.ts",
78
- description: "Demonstrates user decryption of multiple encrypted values",
78
+ description: "Decrypting multiple encrypted values of different types for a user. Shows how to handle ebool, euint32, and euint64 in one contract. Each value requires individual permission grants - there's no batching for permissions (unlike input proofs). Demonstrates the pattern of granting allowThis() for each value separately.",
79
79
  category: "Basic - Decryption",
80
80
  docsOutput: "docs/basic/decryption/user-decrypt-multiple-values.md",
81
- title: "User Decrypt Multiple Values",
81
+ title: "User Decrypt Multiple Values"
82
82
  },
83
83
  "user-decrypt-single-value": {
84
84
  contract: "contracts/basic/decryption/UserDecryptSingleValue.sol",
85
85
  test: "test/basic/decryption/UserDecryptSingleValue.ts",
86
- description: "Demonstrates the FHE decryption mechanism and highlights common pitfalls",
86
+ description: "User-controlled decryption with proper permission management. Demonstrates the critical two-step permission pattern: allowThis() grants the contract permission to store/compute, while allow() grants the user permission to decrypt. Missing either step causes decryption to fail. Includes examples of both correct and incorrect patterns.",
87
87
  category: "Basic - Decryption",
88
88
  docsOutput: "docs/basic/decryption/user-decrypt-single-value.md",
89
- title: "User Decrypt Single Value",
89
+ title: "User Decrypt Single Value"
90
90
  },
91
91
  "encrypt-multiple-values": {
92
92
  contract: "contracts/basic/encryption/EncryptMultipleValues.sol",
93
93
  test: "test/basic/encryption/EncryptMultipleValues.ts",
94
- description: "Encrypting and handling multiple values in a single transaction efficiently.",
94
+ description: "Efficient handling of multiple encrypted values in one transaction. Demonstrates batched input validation where a single proof covers multiple encrypted values (ebool, euint32, eaddress), saving ~50k gas per additional value compared to separate proofs.",
95
95
  category: "Basic - Encryption",
96
96
  docsOutput: "docs/basic/encryption/encrypt-multiple-values.md",
97
- title: "Encrypt Multiple Values",
97
+ title: "Encrypt Multiple Values"
98
98
  },
99
99
  "encrypt-single-value": {
100
100
  contract: "contracts/basic/encryption/EncryptSingleValue.sol",
101
101
  test: "test/basic/encryption/EncryptSingleValue.ts",
102
- description: "FHE encryption mechanism with single values, including common pitfalls and best practices for developers.",
102
+ description: "Single value encryption with proof validation. Shows how to receive encrypted data from users, validate proofs, and grant proper permissions. Includes examples of common mistakes and the correct permission pattern (allowThis + allow).",
103
103
  category: "Basic - Encryption",
104
104
  docsOutput: "docs/basic/encryption/encrypt-single-value.md",
105
- title: "Encrypt Single Value",
105
+ title: "Encrypt Single Value"
106
106
  },
107
107
  "fhe-counter": {
108
108
  contract: "contracts/basic/encryption/FHECounter.sol",
109
109
  test: "test/basic/encryption/FHECounter.ts",
110
- description: "Confidential counter implementation using FHEVM, compared with a standard counter to highlight encryption benefits.",
110
+ description: "Confidential counter with encrypted increment/decrement operations. Demonstrates the complete FHE workflow: encryption, computation, and permission management. The counter value remains private, only accessible through decryption by authorized users.",
111
111
  category: "Basic - Encryption",
112
112
  docsOutput: "docs/basic/encryption/fhe-counter.md",
113
- title: "FHE Counter",
113
+ title: "FHE Counter"
114
114
  },
115
115
  "fhe-add": {
116
116
  contract: "contracts/basic/fhe-operations/FHEAdd.sol",
117
117
  test: "test/basic/fhe-operations/FHEAdd.ts",
118
- description: "Simple example: adding two encrypted values (a + b)",
118
+ description: "Introduction to homomorphic addition on encrypted values. Demonstrates the most fundamental FHE operation: adding two encrypted numbers without decrypting them. Shows the complete flow from receiving encrypted inputs, performing the addition, and granting permissions for both contract storage and user decryption.",
119
119
  category: "Basic - FHE Operations",
120
120
  docsOutput: "docs/basic/fhe-operations/fhe-add.md",
121
- title: "FHE Add",
121
+ title: "FHE Add"
122
122
  },
123
123
  "fhe-arithmetic": {
124
124
  contract: "contracts/basic/fhe-operations/FHEArithmetic.sol",
125
125
  test: "test/basic/fhe-operations/FHEArithmetic.ts",
126
- description: "Demonstrates all FHE arithmetic operations on encrypted integers",
126
+ description: "Complete suite of FHE arithmetic operations on encrypted values. Covers all basic math: addition, subtraction, multiplication, division, remainder (modulo), minimum, and maximum. Includes gas cost comparisons and important limitations (e.g., division/remainder only work with plaintext divisors, not encrypted divisors).",
127
127
  category: "Basic - FHE Operations",
128
128
  docsOutput: "docs/basic/fhe-operations/fhe-arithmetic.md",
129
- title: "FHE Arithmetic",
129
+ title: "FHE Arithmetic"
130
130
  },
131
131
  "fhe-comparison": {
132
132
  contract: "contracts/basic/fhe-operations/FHEComparison.sol",
133
133
  test: "test/basic/fhe-operations/FHEComparison.ts",
134
- description: "Demonstrates all FHE comparison operations on encrypted integers",
134
+ description: "Complete guide to encrypted comparisons and conditional selection. Covers all comparison operators (eq, ne, gt, lt, ge, le) that return encrypted booleans (ebool), and demonstrates FHE.select for branching without information leakage. Critical for implementing logic like \"find maximum\" or \"check threshold\" without revealing values.",
135
135
  category: "Basic - FHE Operations",
136
136
  docsOutput: "docs/basic/fhe-operations/fhe-comparison.md",
137
- title: "FHE Comparison",
137
+ title: "FHE Comparison"
138
138
  },
139
139
  "fhe-if-then-else": {
140
140
  contract: "contracts/basic/fhe-operations/FHEIfThenElse.sol",
141
141
  test: "test/basic/fhe-operations/FHEIfThenElse.ts",
142
- description: "Demonstrates conditional logic: max(a, b) using encrypted comparison",
142
+ description: "Conditional logic without information leakage using FHE.select. Demonstrates how to implement if-then-else logic on encrypted values (computing max of two numbers). Using regular if/else would decrypt and leak which branch was taken. FHE.select evaluates BOTH branches and picks one based on the encrypted condition, preserving privacy.",
143
143
  category: "Basic - FHE Operations",
144
144
  docsOutput: "docs/basic/fhe-operations/fhe-if-then-else.md",
145
- title: "FHE If Then Else",
145
+ title: "FHE If Then Else"
146
146
  },
147
147
  "fhe-access-control": {
148
148
  contract: "contracts/concepts/FHEAccessControl.sol",
149
149
  test: "test/concepts/FHEAccessControl.ts",
150
- description: "Critical access control patterns in FHEVM: FHE.allow, FHE.allowThis, FHE.allowTransient. Includes common mistakes and correct implementations.",
150
+ description: "Master class for FHE permission patterns and access control. Explains the three permission types: allow() for permanent access, allowThis() for contract operations, and allowTransient() for temporary cross-contract calls. Includes correct and incorrect usage examples to prevent common decryption failures.",
151
151
  category: "Concepts",
152
152
  docsOutput: "docs/concepts/fhe-access-control.md",
153
- title: "FHE Access Control",
153
+ title: "FHE Access Control"
154
154
  },
155
155
  "fhe-anti-patterns": {
156
156
  contract: "contracts/concepts/FHEAntiPatterns.sol",
157
157
  test: "test/concepts/FHEAntiPatterns.ts",
158
- description: "Common FHE mistakes and their correct alternatives. Covers: branching, permissions, require/revert, re-encryption, loops, noise, and deprecated APIs.",
158
+ description: "Comprehensive guide to FHE anti-patterns and their solutions. Covers 9 critical mistakes: using if/else on encrypted values, incorrect permission patterns, require() statements that leak info, unbounded loops, noise accumulation, and deprecated APIs. Each pattern shows both ❌ WRONG and ✅ CORRECT implementations.",
159
159
  category: "Concepts",
160
160
  docsOutput: "docs/concepts/fhe-anti-patterns.md",
161
- title: "FHE Anti Patterns",
161
+ title: "FHE Anti Patterns"
162
162
  },
163
163
  "fhe-handles": {
164
164
  contract: "contracts/concepts/FHEHandles.sol",
165
165
  test: "test/concepts/FHEHandles.ts",
166
- description: "Understanding FHE handles: creation, computation, immutability, and symbolic execution in mock mode.",
166
+ description: "Deep dive into FHE handles: what they are and how they work. Explains that handles are uint256 pointers to encrypted data, demonstrates three creation methods (fromExternal, asEuint, operations), and emphasizes immutability - every operation creates a NEW handle. Includes gas cost comparisons for different operations.",
167
167
  category: "Concepts",
168
168
  docsOutput: "docs/concepts/fhe-handles.md",
169
- title: "FHE Handles",
169
+ title: "FHE Handles"
170
170
  },
171
171
  "fhe-input-proof": {
172
172
  contract: "contracts/concepts/FHEInputProof.sol",
173
173
  test: "test/concepts/FHEInputProof.ts",
174
- description: "Explains input proof validation in FHEVM: what proofs are, why they are needed, and how to use them correctly with single and batched inputs.",
174
+ description: "Input proof validation and batching strategies in FHEVM. Explains why proofs are essential (prevent garbage data, wrong types, and replay attacks) and demonstrates the gas-efficient batching pattern where one proof validates multiple encrypted inputs, saving ~50k gas per additional value.",
175
175
  category: "Concepts",
176
176
  docsOutput: "docs/concepts/fhe-input-proof.md",
177
- title: "FHE Input Proof",
177
+ title: "FHE Input Proof"
178
178
  },
179
179
  "encrypted-lottery": {
180
180
  contract: "contracts/gaming/EncryptedLottery.sol",
181
181
  test: "test/gaming/EncryptedLottery.ts",
182
- description: "Encrypted Lottery with private ticket numbers - fair and verifiable!",
182
+ description: "Provably fair lottery with encrypted ticket numbers. Players buy tickets with encrypted numbers. Winning number is generated using FHE randomness. Winner is determined by comparing encrypted values without revealing losing tickets. Ensures fairness and privacy - no one can see ticket numbers before the draw.",
183
183
  category: "Gaming",
184
184
  docsOutput: "docs/gaming/encrypted-lottery.md",
185
- title: "Encrypted Lottery",
185
+ title: "Encrypted Lottery"
186
186
  },
187
187
  "encrypted-poker": {
188
188
  contract: "contracts/gaming/EncryptedPoker.sol",
189
189
  test: "test/gaming/EncryptedPoker.ts",
190
- description: "Encrypted Poker - Texas Hold'em with hidden hole cards!",
190
+ description: "On-chain Texas Hold'em poker with encrypted hole cards. Two players receive encrypted hole cards that remain hidden throughout the game. Hand strength is computed using FHE operations. Winner is determined by comparing encrypted hand strengths. Demonstrates complex game logic with multiple encrypted states and conditional operations.",
191
191
  category: "Gaming",
192
192
  docsOutput: "docs/gaming/encrypted-poker.md",
193
- title: "Encrypted Poker",
193
+ title: "Encrypted Poker"
194
194
  },
195
195
  "rock-paper-scissors": {
196
196
  contract: "contracts/gaming/RockPaperScissors.sol",
197
197
  test: "test/gaming/RockPaperScissors.ts",
198
- description: "Rock-Paper-Scissors game with encrypted moves - fair play guaranteed!",
198
+ description: "Fair Rock-Paper-Scissors game with encrypted moves. Players submit encrypted moves (0=Rock, 1=Paper, 2=Scissors) ensuring neither player can see the other's choice before committing. Winner is determined using FHE operations and revealed publicly. No trusted third party needed - cryptography guarantees fairness.",
199
199
  category: "Gaming",
200
200
  docsOutput: "docs/gaming/rock-paper-scissors.md",
201
- title: "Rock Paper Scissors",
201
+ title: "Rock Paper Scissors"
202
202
  },
203
- erc7984: {
203
+ "erc7984": {
204
204
  contract: "contracts/openzeppelin/ERC7984.sol",
205
205
  test: "test/openzeppelin/ERC7984.ts",
206
206
  npmDependencies: {
207
207
  "@openzeppelin/contracts": "^5.4.0",
208
- "@openzeppelin/confidential-contracts": "^0.3.0",
208
+ "@openzeppelin/confidential-contracts": "^0.3.0"
209
209
  },
210
- description: "Confidential token using OpenZeppelin's ERC7984 standard",
210
+ description: "Confidential ERC20-compatible token using OpenZeppelin's ERC7984 standard. Implements a fully private token where balances and transfer amounts are encrypted. Compatible with standard ERC20 interfaces but with FHE under the hood. Supports both visible minting (owner knows amount) and confidential minting (fully private). Foundation for building private DeFi applications.",
211
211
  category: "Openzeppelin",
212
212
  docsOutput: "docs/openzeppelin/erc7984.md",
213
- title: "ERC7984",
213
+ title: "ERC7984"
214
214
  },
215
215
  "erc7984-erc20-wrapper": {
216
216
  contract: "contracts/openzeppelin/ERC7984ERC20Wrapper.sol",
217
217
  test: "test/openzeppelin/ERC7984ERC20Wrapper.ts",
218
218
  npmDependencies: {
219
219
  "@openzeppelin/contracts": "^5.4.0",
220
- "@openzeppelin/confidential-contracts": "^0.3.0",
220
+ "@openzeppelin/confidential-contracts": "^0.3.0"
221
221
  },
222
- dependencies: ["contracts/openzeppelin/mocks/ERC20Mock.sol"],
223
- description: "Wraps ERC20 tokens into confidential ERC7984 tokens",
222
+ dependencies: [
223
+ "contracts/openzeppelin/mocks/ERC20Mock.sol"
224
+ ],
225
+ description: "Bridge between public ERC20 and confidential ERC7984 tokens. Allows users to wrap regular ERC20 tokens into privacy-preserving ERC7984 tokens (public → private) and unwrap them back (private → public). Wrapping is instant, unwrapping requires decryption proof from KMS. Essential for bringing existing tokens into the confidential ecosystem.",
224
226
  category: "Openzeppelin",
225
227
  docsOutput: "docs/openzeppelin/erc7984-erc20-wrapper.md",
226
- title: "ERC7984 ERC20 Wrapper",
228
+ title: "ERC7984 ERC20 Wrapper"
227
229
  },
228
230
  "swap-erc7984-to-erc20": {
229
231
  contract: "contracts/openzeppelin/SwapERC7984ToERC20.sol",
230
232
  test: "test/openzeppelin/SwapERC7984ToERC20.ts",
231
233
  npmDependencies: {
232
234
  "@openzeppelin/contracts": "^5.4.0",
233
- "@openzeppelin/confidential-contracts": "^0.3.0",
235
+ "@openzeppelin/confidential-contracts": "^0.3.0"
234
236
  },
235
237
  dependencies: [
236
238
  "contracts/openzeppelin/mocks/ERC20Mock.sol",
237
- "contracts/openzeppelin/ERC7984.sol",
239
+ "contracts/openzeppelin/ERC7984.sol"
238
240
  ],
239
- description: "Swap confidential ERC7984 tokens to regular ERC20 tokens",
241
+ description: "Atomic swap from confidential ERC7984 to public ERC20 tokens. Two-step process: (1) Initiate swap with encrypted amount, request decryption from KMS. (2) Finalize swap with decryption proof, receive ERC20 tokens. Demonstrates the FHEVM v0.9 public decryption flow with makePubliclyDecryptable() and checkSignatures() for trustless swaps.",
240
242
  category: "Openzeppelin",
241
243
  docsOutput: "docs/openzeppelin/swap-erc7984-to-erc20.md",
242
- title: "Swap ERC7984 To ERC20",
244
+ title: "Swap ERC7984 To ERC20"
243
245
  },
244
246
  "swap-erc7984-to-erc7984": {
245
247
  contract: "contracts/openzeppelin/SwapERC7984ToERC7984.sol",
246
248
  test: "test/openzeppelin/SwapERC7984ToERC7984.ts",
247
249
  npmDependencies: {
248
- "@openzeppelin/confidential-contracts": "^0.3.0",
250
+ "@openzeppelin/confidential-contracts": "^0.3.0"
249
251
  },
250
- dependencies: ["contracts/openzeppelin/ERC7984.sol"],
251
- description: "Fully confidential swap between two ERC7984 tokens",
252
+ dependencies: [
253
+ "contracts/openzeppelin/ERC7984.sol"
254
+ ],
255
+ description: "Fully private atomic swap between two confidential ERC7984 tokens. Both input and output amounts remain encrypted throughout the entire swap process. No decryption needed - amounts stay private from start to finish. Perfect for confidential DEX operations where trade sizes must remain hidden. The ultimate privacy-preserving token exchange.",
252
256
  category: "Openzeppelin",
253
257
  docsOutput: "docs/openzeppelin/swap-erc7984-to-erc7984.md",
254
- title: "Swap ERC7984 To ERC7984",
258
+ title: "Swap ERC7984 To ERC7984"
255
259
  },
256
260
  "vesting-wallet": {
257
261
  contract: "contracts/openzeppelin/VestingWallet.sol",
258
262
  test: "test/openzeppelin/VestingWallet.ts",
259
263
  npmDependencies: {
260
264
  "@openzeppelin/contracts": "^5.4.0",
261
- "@openzeppelin/confidential-contracts": "^0.3.0",
265
+ "@openzeppelin/confidential-contracts": "^0.3.0"
262
266
  },
263
- dependencies: ["contracts/openzeppelin/ERC7984.sol"],
264
- description: "Linear vesting wallet for ERC7984 tokens - amounts stay encrypted!",
267
+ dependencies: [
268
+ "contracts/openzeppelin/ERC7984.sol"
269
+ ],
270
+ description: "Time-locked vesting wallet with fully encrypted token amounts. Implements linear vesting for ERC7984 confidential tokens. Vesting schedule, amounts, and release calculations all happen on encrypted values using FHE operations. Beneficiary can release vested tokens over time without revealing the total allocation or vesting progress to observers.",
265
271
  category: "Openzeppelin",
266
272
  docsOutput: "docs/openzeppelin/vesting-wallet.md",
267
- title: "Vesting Wallet",
268
- },
273
+ title: "Vesting Wallet"
274
+ }
269
275
  };
270
276
  // =============================================================================
271
277
  // Category Configurations
@@ -293,7 +299,7 @@ exports.CATEGORIES = {
293
299
  {
294
300
  sol: "contracts/advanced/PrivatePayroll.sol",
295
301
  test: "test/advanced/PrivatePayroll.ts",
296
- },
302
+ }
297
303
  ],
298
304
  },
299
305
  basicdecryption: {
@@ -314,7 +320,7 @@ exports.CATEGORIES = {
314
320
  {
315
321
  sol: "contracts/basic/decryption/UserDecryptSingleValue.sol",
316
322
  test: "test/basic/decryption/UserDecryptSingleValue.ts",
317
- },
323
+ }
318
324
  ],
319
325
  },
320
326
  basicencryption: {
@@ -331,7 +337,7 @@ exports.CATEGORIES = {
331
337
  {
332
338
  sol: "contracts/basic/encryption/FHECounter.sol",
333
339
  test: "test/basic/encryption/FHECounter.ts",
334
- },
340
+ }
335
341
  ],
336
342
  },
337
343
  basicfheoperations: {
@@ -352,7 +358,7 @@ exports.CATEGORIES = {
352
358
  {
353
359
  sol: "contracts/basic/fhe-operations/FHEIfThenElse.sol",
354
360
  test: "test/basic/fhe-operations/FHEIfThenElse.ts",
355
- },
361
+ }
356
362
  ],
357
363
  },
358
364
  concepts: {
@@ -373,7 +379,7 @@ exports.CATEGORIES = {
373
379
  {
374
380
  sol: "contracts/concepts/FHEInputProof.sol",
375
381
  test: "test/concepts/FHEInputProof.ts",
376
- },
382
+ }
377
383
  ],
378
384
  },
379
385
  gaming: {
@@ -390,7 +396,7 @@ exports.CATEGORIES = {
390
396
  {
391
397
  sol: "contracts/gaming/RockPaperScissors.sol",
392
398
  test: "test/gaming/RockPaperScissors.ts",
393
- },
399
+ }
394
400
  ],
395
401
  },
396
402
  openzeppelin: {
@@ -415,9 +421,9 @@ exports.CATEGORIES = {
415
421
  {
416
422
  sol: "contracts/openzeppelin/VestingWallet.sol",
417
423
  test: "test/openzeppelin/VestingWallet.ts",
418
- },
424
+ }
419
425
  ],
420
- },
426
+ }
421
427
  };
422
428
  // =============================================================================
423
429
  // Helper Functions
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fhevm-example",
3
- "version": "1.4.4",
3
+ "version": "1.4.5",
4
4
  "description": "Create FHEVM example projects with a single command - A comprehensive toolkit for building privacy-preserving smart contracts",
5
5
  "bin": {
6
6
  "create-fhevm-example": "./dist/scripts/index.js"