@lfdecentralizedtrust/zeto-contracts 0.2.1 → 0.5.0

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 (155) hide show
  1. package/README.md +70 -162
  2. package/contracts/factory.sol +30 -34
  3. package/contracts/factory_upgradeable.sol +160 -0
  4. package/contracts/lib/common/util.sol +40 -0
  5. package/contracts/lib/interfaces/ILockableCapability.sol +318 -0
  6. package/contracts/lib/interfaces/{izeto.sol → IZeto.sol} +13 -1
  7. package/contracts/lib/interfaces/{izeto_initializable.sol → IZetoInitializable.sol} +14 -12
  8. package/contracts/lib/interfaces/{izeto_kyc.sol → IZetoKyc.sol} +3 -3
  9. package/contracts/lib/interfaces/IZetoLockableCapability.sol +237 -0
  10. package/contracts/lib/interfaces/IZetoStorage.sol +106 -0
  11. package/contracts/lib/interfaces/{izeto_lockable.sol → IZetoVerifier.sol} +8 -21
  12. package/contracts/lib/registry.sol +77 -27
  13. package/contracts/lib/storage/base.sol +210 -0
  14. package/contracts/lib/storage/nullifier.sol +166 -0
  15. package/contracts/lib/zeto_common.sol +277 -28
  16. package/contracts/lib/zeto_fungible.sol +451 -33
  17. package/contracts/lib/zeto_fungible_base.sol +69 -0
  18. package/contracts/lib/zeto_fungible_burn.sol +83 -53
  19. package/contracts/lib/zeto_fungible_burn_nullifier.sol +115 -72
  20. package/contracts/lib/zeto_fungible_nullifier.sol +167 -0
  21. package/contracts/lib/zeto_lockable.sol +613 -0
  22. package/contracts/lib/zeto_non_fungible.sol +236 -0
  23. package/contracts/lib/zeto_non_fungible_base.sol +61 -0
  24. package/contracts/lib/zeto_non_fungible_nullifier.sol +61 -0
  25. package/contracts/test/escrow1.sol +90 -34
  26. package/contracts/test/escrow2.sol +64 -29
  27. package/contracts/test/qurrency.sol +10 -2
  28. package/contracts/test/smt.sol +8 -3
  29. package/contracts/test/tendecimals.sol +14 -12
  30. package/contracts/verifiers/impl/anon.sol +189 -0
  31. package/contracts/verifiers/impl/anon_batch.sol +301 -0
  32. package/contracts/verifiers/impl/anon_enc.sol +266 -0
  33. package/contracts/verifiers/impl/anon_enc_batch.sol +602 -0
  34. package/contracts/verifiers/impl/anon_enc_nullifier.sol +287 -0
  35. package/contracts/verifiers/impl/anon_enc_nullifier_batch.sol +679 -0
  36. package/contracts/verifiers/impl/anon_enc_nullifier_kyc.sol +294 -0
  37. package/contracts/verifiers/impl/anon_enc_nullifier_kyc_batch.sol +686 -0
  38. package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation.sol +413 -0
  39. package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation_batch.sol +1141 -0
  40. package/contracts/verifiers/impl/anon_nullifier_kyc_transfer.sol +217 -0
  41. package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked.sol +196 -0
  42. package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked_batch.sol +308 -0
  43. package/contracts/verifiers/impl/anon_nullifier_kyc_transfer_batch.sol +385 -0
  44. package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer.sol +497 -0
  45. package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer_batch.sol +1001 -0
  46. package/contracts/verifiers/{verifier_anon_nullifier_transferLocked.sol → impl/anon_nullifier_transfer.sol} +12 -19
  47. package/contracts/verifiers/{verifier_anon_nullifier_transferLocked_batch.sol → impl/anon_nullifier_transfer_batch.sol} +44 -51
  48. package/contracts/verifiers/impl/burn.sol +182 -0
  49. package/contracts/verifiers/impl/burn_batch.sol +238 -0
  50. package/contracts/verifiers/impl/burn_nullifier.sol +203 -0
  51. package/contracts/verifiers/impl/burn_nullifier_batch.sol +315 -0
  52. package/contracts/verifiers/impl/deposit.sol +182 -0
  53. package/contracts/verifiers/impl/deposit_kyc.sol +189 -0
  54. package/contracts/verifiers/impl/nf_anon.sol +175 -0
  55. package/contracts/verifiers/{verifier_nf_anon_nullifier_transferLocked.sol → impl/nf_anon_nullifier_transfer.sol} +6 -13
  56. package/contracts/verifiers/impl/withdraw.sol +189 -0
  57. package/contracts/verifiers/impl/withdraw_batch.sol +245 -0
  58. package/contracts/verifiers/impl/withdraw_nullifier.sol +210 -0
  59. package/contracts/verifiers/impl/withdraw_nullifier_batch.sol +322 -0
  60. package/contracts/verifiers/verifier_anon.sol +31 -186
  61. package/contracts/verifiers/verifier_anon_batch.sol +31 -298
  62. package/contracts/verifiers/verifier_anon_enc.sol +31 -263
  63. package/contracts/verifiers/verifier_anon_enc_batch.sol +31 -599
  64. package/contracts/verifiers/verifier_anon_enc_nullifier.sol +31 -284
  65. package/contracts/verifiers/verifier_anon_enc_nullifier_batch.sol +33 -676
  66. package/contracts/verifiers/verifier_anon_enc_nullifier_kyc.sol +31 -291
  67. package/contracts/verifiers/verifier_anon_enc_nullifier_kyc_batch.sol +33 -683
  68. package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation.sol +33 -410
  69. package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation_batch.sol +33 -1138
  70. package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer.sol +33 -214
  71. package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked.sol +33 -221
  72. package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked_batch.sol +33 -389
  73. package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer_batch.sol +33 -382
  74. package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer.sol +33 -221
  75. package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer_batch.sol +33 -389
  76. package/contracts/verifiers/verifier_anon_nullifier_transfer.sol +33 -207
  77. package/contracts/verifiers/verifier_anon_nullifier_transfer_batch.sol +33 -375
  78. package/contracts/verifiers/verifier_burn.sol +31 -179
  79. package/contracts/verifiers/verifier_burn_batch.sol +31 -235
  80. package/contracts/verifiers/verifier_burn_nullifier.sol +31 -200
  81. package/contracts/verifiers/verifier_burn_nullifier_batch.sol +31 -312
  82. package/contracts/verifiers/verifier_deposit.sol +31 -179
  83. package/contracts/verifiers/verifier_deposit_kyc.sol +34 -0
  84. package/contracts/verifiers/verifier_nf_anon.sol +31 -172
  85. package/contracts/verifiers/verifier_nf_anon_nullifier_transfer.sol +33 -179
  86. package/contracts/verifiers/verifier_withdraw.sol +31 -186
  87. package/contracts/verifiers/verifier_withdraw_batch.sol +31 -242
  88. package/contracts/verifiers/verifier_withdraw_nullifier.sol +31 -207
  89. package/contracts/verifiers/verifier_withdraw_nullifier_batch.sol +33 -319
  90. package/contracts/zeto_anon.sol +77 -231
  91. package/contracts/zeto_anon_burnable.sol +56 -12
  92. package/contracts/zeto_anon_enc.sol +93 -190
  93. package/contracts/zeto_anon_enc_nullifier.sol +249 -195
  94. package/contracts/zeto_anon_enc_nullifier_kyc.sol +51 -232
  95. package/contracts/zeto_anon_enc_nullifier_non_repudiation.sol +231 -238
  96. package/contracts/zeto_anon_nullifier.sol +164 -298
  97. package/contracts/zeto_anon_nullifier_burnable.sol +68 -18
  98. package/contracts/zeto_anon_nullifier_kyc.sol +40 -345
  99. package/contracts/zeto_anon_nullifier_qurrency.sol +218 -360
  100. package/contracts/zeto_nf_anon.sol +55 -130
  101. package/contracts/zeto_nf_anon_nullifier.sol +90 -152
  102. package/hardhat.config.ts +9 -3
  103. package/ignition/modules/lib/deps.ts +9 -6
  104. package/ignition/modules/zeto_anon_burnable.ts +8 -7
  105. package/ignition/modules/zeto_anon_enc_nullifier.ts +33 -1
  106. package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +2 -2
  107. package/ignition/modules/zeto_anon_enc_nullifier_non_repudiation.ts +2 -1
  108. package/ignition/modules/zeto_anon_nullifier.ts +30 -5
  109. package/ignition/modules/zeto_anon_nullifier_burnable.ts +52 -17
  110. package/ignition/modules/zeto_anon_nullifier_kyc.ts +27 -12
  111. package/ignition/modules/zeto_anon_nullifier_qurrency.ts +2 -1
  112. package/ignition/modules/zeto_nf_anon_nullifier.ts +16 -12
  113. package/package.json +4 -2
  114. package/scripts/deploy_cloneable.ts +19 -10
  115. package/scripts/deploy_upgradeable.ts +9 -5
  116. package/scripts/tokens/Zeto_Anon.ts +3 -3
  117. package/scripts/tokens/Zeto_AnonBurnable.ts +1 -1
  118. package/scripts/tokens/Zeto_AnonEnc.ts +12 -3
  119. package/scripts/tokens/Zeto_AnonEncNullifier.ts +7 -3
  120. package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +1 -1
  121. package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +3 -1
  122. package/scripts/tokens/Zeto_AnonNullifier.ts +3 -1
  123. package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +3 -1
  124. package/scripts/tokens/Zeto_AnonNullifierKyc.ts +1 -1
  125. package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +3 -1
  126. package/scripts/tokens/Zeto_NfAnon.ts +2 -2
  127. package/scripts/tokens/Zeto_NfAnonNullifier.ts +3 -2
  128. package/test/factory.ts +46 -73
  129. package/test/factory_upgradeable.ts +311 -0
  130. package/test/lib/anon_nullifier_helpers.ts +89 -0
  131. package/test/lib/anon_zeto_helpers.ts +76 -0
  132. package/test/lib/deploy.ts +3 -2
  133. package/test/lib/utils.ts +74 -35
  134. package/test/test/escrow1.ts +185 -58
  135. package/test/test/escrow2.ts +200 -107
  136. package/test/test/qurrency.ts +13 -33
  137. package/test/usdc-shielding.ts +39 -26
  138. package/test/utils.ts +144 -21
  139. package/test/zeto_anon.ts +956 -465
  140. package/test/zeto_anon_enc.ts +881 -142
  141. package/test/zeto_anon_enc_nullifier.ts +847 -38
  142. package/test/zeto_anon_enc_nullifier_kyc.ts +120 -181
  143. package/test/zeto_anon_enc_nullifier_non_repudiation.ts +77 -46
  144. package/test/zeto_anon_nullifier.ts +1212 -953
  145. package/test/zeto_anon_nullifier_kyc.ts +674 -655
  146. package/test/zeto_anon_nullifier_qurrency.ts +452 -306
  147. package/test/zeto_nf_anon.ts +737 -137
  148. package/test/zeto_nf_anon_nullifier.ts +876 -246
  149. package/contracts/lib/zeto_base.sol +0 -293
  150. package/contracts/lib/zeto_fungible_withdraw.sol +0 -132
  151. package/contracts/lib/zeto_fungible_withdraw_nullifier.sol +0 -144
  152. package/contracts/lib/zeto_nullifier.sol +0 -334
  153. package/contracts/zkDvP.sol_ +0 -273
  154. package/test/zkDvP.ts_ +0 -455
  155. /package/contracts/lib/{common.sol → common/common.sol} +0 -0
@@ -30,11 +30,31 @@ const VerifierModule = buildModule(
30
30
  },
31
31
  );
32
32
 
33
+ // Locked-input transfers reuse the plain {Groth16Verifier_Anon} verifier
34
+ // (the same one the non-nullifier {Zeto_Anon} token uses for its regular
35
+ // transfers), NOT a nullifier-aware verifier.
36
+ //
37
+ // Rationale: under the new ILockableCapability storage, locked UTXOs are
38
+ // kept in a flat per-lock mapping keyed by lockId. Previously they were
39
+ // shadowed in a dedicated locked-state Sparse Merkle Tree (separate from
40
+ // the unlocked-UTXO SMT) so that the locked-input proof could assert
41
+ // SMT membership against a locked-state root; that secondary tree has
42
+ // been removed. As a result, settling a lock now consumes the locked
43
+ // UTXOs by their raw commitment hashes (the on-chain mapping enforces
44
+ // single-spend semantics — a lock can only be cleared once), so the
45
+ // proof has no nullifiers and no SMT membership to bind against. That
46
+ // matches exactly what the simpler `anon` circuit asserts: hash + sum +
47
+ // owner-key derivation over input/output commitments.
48
+ //
49
+ // The corresponding contract code path is
50
+ // {Zeto_AnonNullifier.constructPublicInputs(..., inputsLocked = true)},
51
+ // which emits public inputs as `[inputCommitments, outputCommitments]`
52
+ // — exactly the layout `Groth16Verifier_Anon` expects.
33
53
  const LockVerifierModule = buildModule(
34
- "Groth16Verifier_AnonNullifierTransferLocked",
54
+ "Groth16Verifier_Anon",
35
55
  (m) => {
36
56
  const verifier = m.contract(
37
- "Groth16Verifier_AnonNullifierTransferLocked",
57
+ "Groth16Verifier_Anon",
38
58
  [],
39
59
  );
40
60
  return { verifier };
@@ -52,11 +72,15 @@ const BatchVerifierModule = buildModule(
52
72
  },
53
73
  );
54
74
 
75
+ // Batched (10-in / 10-out) twin of {LockVerifierModule}. Same rationale:
76
+ // locked-input settlements consume raw UTXO commitments — not nullifiers
77
+ // — so the lock-side verifier is the plain `anon_batch` one, not the
78
+ // nullifier-aware `anon_nullifier_transfer_batch`.
55
79
  const BatchLockVerifierModule = buildModule(
56
- "Groth16Verifier_AnonNullifierTransferLockedBatch",
80
+ "Groth16Verifier_AnonBatch",
57
81
  (m) => {
58
82
  const verifier = m.contract(
59
- "Groth16Verifier_AnonNullifierTransferLockedBatch",
83
+ "Groth16Verifier_AnonBatch",
60
84
  [],
61
85
  );
62
86
  return { verifier };
@@ -64,7 +88,7 @@ const BatchLockVerifierModule = buildModule(
64
88
  );
65
89
 
66
90
  export default buildModule("Zeto_AnonNullifier", (m) => {
67
- const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
91
+ const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
68
92
  const { verifier } = m.useModule(VerifierModule);
69
93
  const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
70
94
  const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
@@ -86,6 +110,7 @@ export default buildModule("Zeto_AnonNullifier", (m) => {
86
110
  batchLockVerifier,
87
111
  batchWithdrawVerifier,
88
112
  smtLib,
113
+ poseidon2,
89
114
  poseidon3,
90
115
  };
91
116
  });
@@ -30,11 +30,31 @@ const VerifierModule = buildModule(
30
30
  },
31
31
  );
32
32
 
33
+ // Locked-input transfers reuse the plain {Groth16Verifier_Anon} verifier
34
+ // (the same one the non-nullifier {Zeto_Anon} token uses for its regular
35
+ // transfers), NOT a nullifier-aware verifier.
36
+ //
37
+ // Rationale: under the new ILockableCapability storage, locked UTXOs are
38
+ // kept in a flat per-lock mapping keyed by lockId. Previously they were
39
+ // shadowed in a dedicated locked-state Sparse Merkle Tree (separate from
40
+ // the unlocked-UTXO SMT) so that the locked-input proof could assert
41
+ // SMT membership against a locked-state root; that secondary tree has
42
+ // been removed. As a result, settling a lock now consumes the locked
43
+ // UTXOs by their raw commitment hashes (the on-chain mapping enforces
44
+ // single-spend semantics — a lock can only be cleared once), so the
45
+ // proof has no nullifiers and no SMT membership to bind against. That
46
+ // matches exactly what the simpler `anon` circuit asserts: hash + sum +
47
+ // owner-key derivation over input/output commitments.
48
+ //
49
+ // The corresponding contract code path is
50
+ // {Zeto_AnonNullifier.constructPublicInputs(..., inputsLocked = true)},
51
+ // which emits public inputs as `[inputCommitments, outputCommitments]`
52
+ // — exactly the layout `Groth16Verifier_Anon` expects.
33
53
  const LockVerifierModule = buildModule(
34
- "Groth16Verifier_AnonNullifierTransferLocked",
54
+ "Groth16Verifier_Anon",
35
55
  (m) => {
36
56
  const verifier = m.contract(
37
- "Groth16Verifier_AnonNullifierTransferLocked",
57
+ "Groth16Verifier_Anon",
38
58
  [],
39
59
  );
40
60
  return { verifier };
@@ -44,31 +64,47 @@ const LockVerifierModule = buildModule(
44
64
  const BatchVerifierModule = buildModule(
45
65
  "Groth16Verifier_AnonNullifierTransferBatch",
46
66
  (m) => {
47
- const verifier = m.contract("Groth16Verifier_AnonNullifierTransferBatch", []);
67
+ const verifier = m.contract(
68
+ "Groth16Verifier_AnonNullifierTransferBatch",
69
+ [],
70
+ );
48
71
  return { verifier };
49
72
  },
50
73
  );
51
74
 
75
+ // Batched (10-in / 10-out) twin of {LockVerifierModule}. Same rationale:
76
+ // locked-input settlements consume raw UTXO commitments — not nullifiers
77
+ // — so the lock-side verifier is the plain `anon_batch` one, not the
78
+ // nullifier-aware `anon_nullifier_transfer_batch`.
52
79
  const BatchLockVerifierModule = buildModule(
53
- "Groth16Verifier_AnonNullifierTransferLockedBatch",
80
+ "Groth16Verifier_AnonBatch",
54
81
  (m) => {
55
- const verifier = m.contract("Groth16Verifier_AnonNullifierTransferLockedBatch", []);
82
+ const verifier = m.contract(
83
+ "Groth16Verifier_AnonBatch",
84
+ [],
85
+ );
56
86
  return { verifier };
57
87
  },
58
88
  );
59
89
 
60
- const BurnNullifierVerifierModule = buildModule("Groth16Verifier_BurnNullifier", (m) => {
61
- const verifier = m.contract("Groth16Verifier_BurnNullifier", []);
62
- return { verifier };
63
- });
90
+ const BurnNullifierVerifierModule = buildModule(
91
+ "Groth16Verifier_BurnNullifier",
92
+ (m) => {
93
+ const verifier = m.contract("Groth16Verifier_BurnNullifier", []);
94
+ return { verifier };
95
+ },
96
+ );
64
97
 
65
- const BatchBurnNullifierVerifierModule = buildModule("Groth16Verifier_BurnNullifierBatch", (m) => {
66
- const verifier = m.contract("Groth16Verifier_BurnNullifierBatch", []);
67
- return { verifier };
68
- });
98
+ const BatchBurnNullifierVerifierModule = buildModule(
99
+ "Groth16Verifier_BurnNullifierBatch",
100
+ (m) => {
101
+ const verifier = m.contract("Groth16Verifier_BurnNullifierBatch", []);
102
+ return { verifier };
103
+ },
104
+ );
69
105
 
70
106
  export default buildModule("Zeto_AnonNullifier", (m) => {
71
- const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
107
+ const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
72
108
  const { verifier } = m.useModule(VerifierModule);
73
109
  const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
74
110
  const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
@@ -80,9 +116,7 @@ export default buildModule("Zeto_AnonNullifier", (m) => {
80
116
  const { verifier: batchWithdrawVerifier } = m.useModule(
81
117
  BatchWithdrawNullifierVerifierModule,
82
118
  );
83
- const { verifier: burnVerifier } = m.useModule(
84
- BurnNullifierVerifierModule,
85
- );
119
+ const { verifier: burnVerifier } = m.useModule(BurnNullifierVerifierModule);
86
120
  const { verifier: batchBurnVerifier } = m.useModule(
87
121
  BatchBurnNullifierVerifierModule,
88
122
  );
@@ -98,6 +132,7 @@ export default buildModule("Zeto_AnonNullifier", (m) => {
98
132
  burnVerifier,
99
133
  batchBurnVerifier,
100
134
  smtLib,
135
+ poseidon2,
101
136
  poseidon3,
102
137
  };
103
138
  });
@@ -17,33 +17,48 @@
17
17
  import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
18
18
  import {
19
19
  SmtLibModule,
20
- DepositVerifierModule,
21
20
  WithdrawNullifierVerifierModule,
22
21
  BatchWithdrawNullifierVerifierModule,
22
+ DepositKycVerifierModule,
23
23
  } from "./lib/deps";
24
24
 
25
- const VerifierModule = buildModule("Groth16Verifier_AnonNullifierKycTransfer", (m) => {
26
- const verifier = m.contract("Groth16Verifier_AnonNullifierKycTransfer", []);
27
- return { verifier };
28
- });
25
+ const VerifierModule = buildModule(
26
+ "Groth16Verifier_AnonNullifierKycTransfer",
27
+ (m) => {
28
+ const verifier = m.contract("Groth16Verifier_AnonNullifierKycTransfer", []);
29
+ return { verifier };
30
+ },
31
+ );
29
32
 
30
33
  const BatchVerifierModule = buildModule(
31
34
  "Groth16Verifier_AnonNullifierKycTransferBatch",
32
35
  (m) => {
33
- const verifier = m.contract("Groth16Verifier_AnonNullifierKycTransferBatch", []);
36
+ const verifier = m.contract(
37
+ "Groth16Verifier_AnonNullifierKycTransferBatch",
38
+ [],
39
+ );
34
40
  return { verifier };
35
41
  },
36
42
  );
37
43
 
38
- const LockVerifierModule = buildModule("Groth16Verifier_AnonNullifierKycTransferLocked", (m) => {
39
- const verifier = m.contract("Groth16Verifier_AnonNullifierKycTransferLocked", []);
40
- return { verifier };
41
- });
44
+ const LockVerifierModule = buildModule(
45
+ "Groth16Verifier_AnonNullifierKycTransferLocked",
46
+ (m) => {
47
+ const verifier = m.contract(
48
+ "Groth16Verifier_AnonNullifierKycTransferLocked",
49
+ [],
50
+ );
51
+ return { verifier };
52
+ },
53
+ );
42
54
 
43
55
  const BatchLockVerifierModule = buildModule(
44
56
  "Groth16Verifier_AnonNullifierKycTransferLockedBatch",
45
57
  (m) => {
46
- const verifier = m.contract("Groth16Verifier_AnonNullifierKycTransferLockedBatch", []);
58
+ const verifier = m.contract(
59
+ "Groth16Verifier_AnonNullifierKycTransferLockedBatch",
60
+ [],
61
+ );
47
62
  return { verifier };
48
63
  },
49
64
  );
@@ -54,7 +69,7 @@ export default buildModule("Zeto_AnonNullifierKyc", (m) => {
54
69
  const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
55
70
  const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
56
71
  const { verifier: batchLockVerifier } = m.useModule(BatchLockVerifierModule);
57
- const { verifier: depositVerifier } = m.useModule(DepositVerifierModule);
72
+ const { verifier: depositVerifier } = m.useModule(DepositKycVerifierModule);
58
73
  const { verifier: withdrawVerifier } = m.useModule(
59
74
  WithdrawNullifierVerifierModule,
60
75
  );
@@ -64,7 +64,7 @@ const BatchVerifierModule = buildModule(
64
64
  // );
65
65
 
66
66
  export default buildModule("Zeto_AnonNullifierQurrency", (m) => {
67
- const { smtLib, poseidon3, poseidon5, poseidon6 } = m.useModule(SmtLibModule);
67
+ const { smtLib, poseidon2, poseidon3, poseidon5, poseidon6 } = m.useModule(SmtLibModule);
68
68
  const { verifier } = m.useModule(VerifierModule);
69
69
  // const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
70
70
  const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
@@ -86,6 +86,7 @@ export default buildModule("Zeto_AnonNullifierQurrency", (m) => {
86
86
  // batchLockVerifier,
87
87
  batchWithdrawVerifier,
88
88
  smtLib,
89
+ poseidon2,
89
90
  poseidon3,
90
91
  poseidon5,
91
92
  poseidon6,
@@ -25,21 +25,25 @@ const VerifierModule = buildModule(
25
25
  },
26
26
  );
27
27
 
28
- const LockVerifierModule = buildModule(
29
- "Groth16Verifier_NfAnonNullifierTransferLocked",
30
- (m) => {
31
- const verifier = m.contract(
32
- "Groth16Verifier_NfAnonNullifierTransferLocked",
33
- [],
34
- );
35
- return { verifier };
36
- },
37
- );
28
+ // Locked-input transition for the NF nullifier token reuses the simple
29
+ // {Groth16Verifier_NfAnon} verifier, mirroring how Zeto_AnonNullifier
30
+ // reuses {Groth16Verifier_Anon} for its lock path. In the new
31
+ // {ILockableCapability} architecture the locked-UTXO ledger is a flat
32
+ // mapping (no Merkle tree, no per-UTXO delegate SMT), so the proof for
33
+ // a locked-input spend collapses to the same `[input, output]` shape as
34
+ // the non-nullifier NF transfer. The historical
35
+ // `Groth16Verifier_NfAnonNullifierTransferLocked` (which baked the
36
+ // locked-SMT inclusion + delegate-binding into the proof) is no longer
37
+ // needed and intentionally not deployed.
38
+ const LockVerifierModule = buildModule("Groth16Verifier_NfAnon", (m) => {
39
+ const verifier = m.contract("Groth16Verifier_NfAnon", []);
40
+ return { verifier };
41
+ });
38
42
 
39
43
  export default buildModule("Zeto_NfAnonNullifier", (m) => {
40
- const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
44
+ const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
41
45
  const { verifier } = m.useModule(VerifierModule);
42
46
  const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
43
47
 
44
- return { verifier, lockVerifier, smtLib, poseidon3 };
48
+ return { verifier, lockVerifier, smtLib, poseidon2, poseidon3 };
45
49
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lfdecentralizedtrust/zeto-contracts",
3
- "version": "0.2.1",
3
+ "version": "0.5.0",
4
4
  "description": "Zero knowledge proof based UTXO tokens toolkit for fungible or non-fungible assets",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,12 +22,14 @@
22
22
  "@nomicfoundation/hardhat-toolbox": "^5.0.0",
23
23
  "circomlibjs": "^0.1.7",
24
24
  "maci-crypto": "1.1.1",
25
+ "mlkem": "^2.3.1",
25
26
  "prettier": "^3.3.3",
26
27
  "snarkjs": "0.7.5",
28
+ "tslog": "^4.10.2",
27
29
  "zeto-js": "file:../zkp/js"
28
30
  },
29
31
  "dependencies": {
30
- "@iden3/contracts": "^2.5.0",
32
+ "@iden3/contracts": "file:../../contracts",
31
33
  "@openzeppelin/contracts": "^5.1.0",
32
34
  "@openzeppelin/contracts-upgradeable": "^5.0.2",
33
35
  "@openzeppelin/hardhat-upgrades": "^3.2.1",
@@ -1,4 +1,11 @@
1
1
  import { ethers, ignition } from "hardhat";
2
+ import { Logger, ILogObj } from "tslog";
3
+ const logLevel = process.env.LOG_LEVEL || "3";
4
+ export const logger: Logger<ILogObj> = new Logger({
5
+ name: "deploy_cloneable",
6
+ minLevel: parseInt(logLevel),
7
+ });
8
+
2
9
  import erc20Module from "../ignition/modules/erc20";
3
10
  import { getLinkedContractFactory, deploy } from "./lib/common";
4
11
 
@@ -17,14 +24,15 @@ export async function deployFungible(tokenName: string) {
17
24
 
18
25
  const zetoImpl: any = await zetoFactory.deploy();
19
26
  await zetoImpl.waitForDeployment();
20
- // console.log(args);
21
- await zetoImpl.connect(deployer).initialize(...args);
22
-
23
- const tx3 = await zetoImpl.connect(deployer).setERC20(erc20.target);
24
- await tx3.wait();
27
+ // Do not call {initialize} or {setERC20} on the implementation. Leaf Zeto
28
+ // contracts lock the impl with {_disableInitializers} in the constructor,
29
+ // so {initialize} here would always revert with {InvalidInitialization}.
30
+ // Factory tests ({ZetoTokenFactory}) deploy ERC1967 proxies whose constructor
31
+ // delegates {initialize} into fresh proxy storage; {deployZeto} then binds
32
+ // ERC20 on each proxy via {setERC20}.
25
33
 
26
- console.log(`ERC20 deployed: ${erc20.target}`);
27
- console.log(`ZetoToken deployed: ${zetoImpl.target}`);
34
+ logger.debug(`ERC20 deployed: ${erc20.target}`);
35
+ logger.debug(`ZetoToken impl deployed: ${zetoImpl.target}`);
28
36
 
29
37
  return { deployer, zetoImpl, erc20, args };
30
38
  }
@@ -42,9 +50,10 @@ export async function deployNonFungible(tokenName: string) {
42
50
  }
43
51
  const zetoImpl: any = await zetoFactory.deploy();
44
52
  await zetoImpl.waitForDeployment();
45
- await zetoImpl.connect(deployer).initialize(...args);
53
+ // Same rationale as {deployFungible}: impl stays uninitialized; proxies
54
+ // created by the factory run {initialize} via ERC1967Proxy constructor data.
46
55
 
47
- console.log(`ZetoToken deployed: ${zetoImpl.target}`);
56
+ logger.debug(`ZetoToken impl deployed: ${zetoImpl.target}`);
48
57
 
49
58
  return { deployer, zetoImpl, args };
50
59
  }
@@ -57,6 +66,6 @@ deploy(deployFungible, deployNonFungible)
57
66
  process.exit(0);
58
67
  })
59
68
  .catch((error) => {
60
- console.error(error);
69
+ logger.error(error);
61
70
  process.exit(1);
62
71
  });
@@ -1,4 +1,8 @@
1
1
  import { ethers, ignition, upgrades } from "hardhat";
2
+ import { Logger, ILogObj } from "tslog";
3
+ const logLevel = process.env.LOG_LEVEL || "3";
4
+ export const logger: Logger<ILogObj> = new Logger({ name: "deploy_upgradeable", minLevel: parseInt(logLevel) });
5
+
2
6
  import erc20Module from "../ignition/modules/erc20";
3
7
  import { getLinkedContractFactory, deploy } from "./lib/common";
4
8
 
@@ -6,13 +10,13 @@ export async function deployFungible(tokenName: string, erc20Address?: string) {
6
10
  let erc20: any;
7
11
  if (!erc20Address) {
8
12
  ({ erc20 } = await ignition.deploy(erc20Module));
9
- console.log(`ERC20 deployed: ${erc20.target}`);
13
+ logger.debug(`ERC20 deployed: ${erc20.target}`);
10
14
  } else {
11
15
  erc20 = await ethers.getContractAt("SampleERC20", erc20Address);
12
16
  if (!erc20) {
13
17
  throw new Error(`ERC20 contract not found at address: ${erc20Address}`);
14
18
  }
15
- console.log(`Using existing ERC20 contract at: ${erc20.target}`);
19
+ logger.debug(`Using existing ERC20 contract at: ${erc20.target}`);
16
20
  }
17
21
  const verifiersDeployer = require(`./tokens/${tokenName}`);
18
22
  const { deployer, args, libraries } =
@@ -39,7 +43,7 @@ export async function deployFungible(tokenName: string, erc20Address?: string) {
39
43
  const tx3 = await zeto.connect(deployer).setERC20(erc20.target);
40
44
  await tx3.wait();
41
45
 
42
- console.log(`ZetoToken deployed: ${zeto.target}`);
46
+ logger.debug(`ZetoToken deployed: ${zeto.target}`);
43
47
 
44
48
  return { deployer, zeto, erc20 };
45
49
  }
@@ -67,7 +71,7 @@ export async function deployNonFungible(tokenName: string) {
67
71
  const zetoAddress = await proxy.getAddress();
68
72
  const zeto: any = await ethers.getContractAt(tokenName, zetoAddress);
69
73
 
70
- console.log(`ZetoToken deployed: ${zeto.target}`);
74
+ logger.debug(`ZetoToken deployed: ${zeto.target}`);
71
75
 
72
76
  return { deployer, zeto };
73
77
  }
@@ -80,6 +84,6 @@ deploy(deployFungible, deployNonFungible)
80
84
  process.exit(0);
81
85
  })
82
86
  .catch((error) => {
83
- console.error(error);
87
+ logger.error(error);
84
88
  process.exit(1);
85
89
  });
@@ -39,11 +39,11 @@ export async function deployDependencies() {
39
39
  withdrawVerifier: withdrawVerifier.target,
40
40
  batchVerifier: batchVerifier.target,
41
41
  batchWithdrawVerifier: batchWithdrawVerifier.target,
42
- lockVerifier: "0x0000000000000000000000000000000000000000",
43
- batchLockVerifier: "0x0000000000000000000000000000000000000000",
42
+ lockVerifier: verifier.target, // for this token, the lock verifier is the same as the regular verifier
43
+ batchLockVerifier: batchVerifier.target,
44
44
  burnVerifier: "0x0000000000000000000000000000000000000000",
45
45
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
46
- }
46
+ },
47
47
  ],
48
48
  };
49
49
  }
@@ -45,7 +45,7 @@ export async function deployDependencies() {
45
45
  batchBurnVerifier: batchBurnVerifier.target,
46
46
  lockVerifier: "0x0000000000000000000000000000000000000000",
47
47
  batchLockVerifier: "0x0000000000000000000000000000000000000000",
48
- }
48
+ },
49
49
  ],
50
50
  };
51
51
  }
@@ -39,11 +39,20 @@ export async function deployDependencies() {
39
39
  withdrawVerifier: withdrawVerifier.target,
40
40
  batchVerifier: batchVerifier.target,
41
41
  batchWithdrawVerifier: batchWithdrawVerifier.target,
42
- lockVerifier: "0x0000000000000000000000000000000000000000",
43
- batchLockVerifier: "0x0000000000000000000000000000000000000000",
42
+ // Same rationale as `Zeto_Anon`: the encryption-aware
43
+ // {Zeto_AnonEnc.constructPublicInputs} ignores `inputsLocked`
44
+ // and emits an identical public-input layout (ecdhPublicKey ++
45
+ // encryptedValues ++ inputs ++ outputs ++ encryptionNonce) for
46
+ // both the regular `transfer` flow and the locked-input flow
47
+ // driven by `spendLock`/`cancelLock`. We therefore wire the
48
+ // lockVerifier slots to the same Groth16 verifier as the
49
+ // unlocked path so {ZetoCommon.verifyProof} routes locked-input
50
+ // proofs to the encryption circuit's verifier.
51
+ lockVerifier: verifier.target,
52
+ batchLockVerifier: batchVerifier.target,
44
53
  burnVerifier: "0x0000000000000000000000000000000000000000",
45
54
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
46
- }
55
+ },
47
56
  ],
48
57
  };
49
58
  }
@@ -24,9 +24,12 @@ export async function deployDependencies() {
24
24
  depositVerifier,
25
25
  withdrawVerifier,
26
26
  verifier,
27
+ lockVerifier,
27
28
  batchVerifier,
29
+ batchLockVerifier,
28
30
  batchWithdrawVerifier,
29
31
  smtLib,
32
+ poseidon2,
30
33
  poseidon3,
31
34
  } = await ignition.deploy(zetoModule);
32
35
  return {
@@ -41,14 +44,15 @@ export async function deployDependencies() {
41
44
  withdrawVerifier: withdrawVerifier.target,
42
45
  batchVerifier: batchVerifier.target,
43
46
  batchWithdrawVerifier: batchWithdrawVerifier.target,
44
- lockVerifier: "0x0000000000000000000000000000000000000000",
45
- batchLockVerifier: "0x0000000000000000000000000000000000000000",
47
+ lockVerifier: lockVerifier.target,
48
+ batchLockVerifier: batchLockVerifier.target,
46
49
  burnVerifier: "0x0000000000000000000000000000000000000000",
47
50
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
48
- }
51
+ },
49
52
  ],
50
53
  libraries: {
51
54
  SmtLib: smtLib.target,
55
+ PoseidonUnit2L: poseidon2.target,
52
56
  PoseidonUnit3L: poseidon3.target,
53
57
  },
54
58
  };
@@ -46,7 +46,7 @@ export async function deployDependencies() {
46
46
  batchLockVerifier: "0x0000000000000000000000000000000000000000",
47
47
  burnVerifier: "0x0000000000000000000000000000000000000000",
48
48
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
49
- }
49
+ },
50
50
  ],
51
51
  libraries: {
52
52
  SmtLib: smtLib.target,
@@ -27,6 +27,7 @@ export async function deployDependencies() {
27
27
  batchVerifier,
28
28
  batchWithdrawVerifier,
29
29
  smtLib,
30
+ poseidon2,
30
31
  poseidon3,
31
32
  } = await ignition.deploy(zetoModule);
32
33
  return {
@@ -45,10 +46,11 @@ export async function deployDependencies() {
45
46
  batchLockVerifier: "0x0000000000000000000000000000000000000000",
46
47
  burnVerifier: "0x0000000000000000000000000000000000000000",
47
48
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
48
- }
49
+ },
49
50
  ],
50
51
  libraries: {
51
52
  SmtLib: smtLib.target,
53
+ PoseidonUnit2L: poseidon2.target,
52
54
  PoseidonUnit3L: poseidon3.target,
53
55
  },
54
56
  };
@@ -29,6 +29,7 @@ export async function deployDependencies() {
29
29
  batchLockVerifier,
30
30
  batchWithdrawVerifier,
31
31
  smtLib,
32
+ poseidon2,
32
33
  poseidon3,
33
34
  } = await ignition.deploy(zetoModule);
34
35
  return {
@@ -47,10 +48,11 @@ export async function deployDependencies() {
47
48
  batchLockVerifier: batchLockVerifier.target,
48
49
  burnVerifier: "0x0000000000000000000000000000000000000000",
49
50
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
50
- }
51
+ },
51
52
  ],
52
53
  libraries: {
53
54
  SmtLib: smtLib.target,
55
+ PoseidonUnit2L: poseidon2.target,
54
56
  PoseidonUnit3L: poseidon3.target,
55
57
  },
56
58
  };
@@ -31,6 +31,7 @@ export async function deployDependencies() {
31
31
  burnVerifier,
32
32
  batchBurnVerifier,
33
33
  smtLib,
34
+ poseidon2,
34
35
  poseidon3,
35
36
  } = await ignition.deploy(zetoModule);
36
37
  return {
@@ -49,10 +50,11 @@ export async function deployDependencies() {
49
50
  batchLockVerifier: batchLockVerifier.target,
50
51
  burnVerifier: burnVerifier.target,
51
52
  batchBurnVerifier: batchBurnVerifier.target,
52
- }
53
+ },
53
54
  ],
54
55
  libraries: {
55
56
  SmtLib: smtLib.target,
57
+ PoseidonUnit2L: poseidon2.target,
56
58
  PoseidonUnit3L: poseidon3.target,
57
59
  },
58
60
  };
@@ -48,7 +48,7 @@ export async function deployDependencies() {
48
48
  batchLockVerifier: batchLockVerifier.target,
49
49
  burnVerifier: "0x0000000000000000000000000000000000000000",
50
50
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
51
- }
51
+ },
52
52
  ],
53
53
  libraries: {
54
54
  SmtLib: smtLib.target,
@@ -29,6 +29,7 @@ export async function deployDependencies() {
29
29
  // batchLockVerifier,
30
30
  batchWithdrawVerifier,
31
31
  smtLib,
32
+ poseidon2,
32
33
  poseidon3,
33
34
  poseidon5,
34
35
  poseidon6,
@@ -49,10 +50,11 @@ export async function deployDependencies() {
49
50
  batchLockVerifier: "0x0000000000000000000000000000000000000000", //batchLockVerifier.target,
50
51
  burnVerifier: "0x0000000000000000000000000000000000000000",
51
52
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
52
- }
53
+ },
53
54
  ],
54
55
  libraries: {
55
56
  SmtLib: smtLib.target,
57
+ PoseidonUnit2L: poseidon2.target,
56
58
  PoseidonUnit3L: poseidon3.target,
57
59
  PoseidonUnit5L: poseidon5.target,
58
60
  PoseidonUnit6L: poseidon6.target,
@@ -33,11 +33,11 @@ export async function deployDependencies() {
33
33
  withdrawVerifier: "0x0000000000000000000000000000000000000000",
34
34
  batchVerifier: "0x0000000000000000000000000000000000000000",
35
35
  batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
36
- lockVerifier: "0x0000000000000000000000000000000000000000",
36
+ lockVerifier: verifier.target, // for this token, the lock verifier is the same as the regular verifier
37
37
  batchLockVerifier: "0x0000000000000000000000000000000000000000",
38
38
  burnVerifier: "0x0000000000000000000000000000000000000000",
39
39
  batchBurnVerifier: "0x0000000000000000000000000000000000000000",
40
- }
40
+ },
41
41
  ],
42
42
  };
43
43
  }