@lfdecentralizedtrust/zeto-contracts 0.2.2 → 0.5.1

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 (164) hide show
  1. package/README.md +76 -162
  2. package/config/eip170.ts +30 -0
  3. package/contracts/factory.sol +30 -34
  4. package/contracts/factory_upgradeable.sol +11 -7
  5. package/contracts/lib/common/util.sol +40 -0
  6. package/contracts/lib/interfaces/ILockableCapability.sol +318 -0
  7. package/contracts/lib/interfaces/{izeto.sol → IZeto.sol} +13 -1
  8. package/contracts/lib/interfaces/{izeto_initializable.sol → IZetoInitializable.sol} +14 -12
  9. package/contracts/lib/interfaces/{izeto_kyc.sol → IZetoKyc.sol} +3 -3
  10. package/contracts/lib/interfaces/IZetoLockHooks.sol +42 -0
  11. package/contracts/lib/interfaces/IZetoLockableCapability.sol +237 -0
  12. package/contracts/lib/interfaces/IZetoStorage.sol +106 -0
  13. package/contracts/lib/interfaces/{izeto_lockable.sol → IZetoVerifier.sol} +8 -21
  14. package/contracts/lib/registry.sol +74 -26
  15. package/contracts/lib/storage/base.sol +210 -0
  16. package/contracts/lib/storage/nullifier.sol +166 -0
  17. package/contracts/lib/zeto_common.sol +277 -28
  18. package/contracts/lib/zeto_fungible.sol +443 -33
  19. package/contracts/lib/zeto_fungible_base.sol +69 -0
  20. package/contracts/lib/zeto_fungible_burn.sol +83 -53
  21. package/contracts/lib/zeto_fungible_burn_nullifier.sol +115 -72
  22. package/contracts/lib/zeto_fungible_nullifier.sol +167 -0
  23. package/contracts/lib/zeto_lockable.sol +219 -0
  24. package/contracts/lib/zeto_lockable_lib.sol +460 -0
  25. package/contracts/lib/zeto_lockable_storage.sol +43 -0
  26. package/contracts/lib/zeto_non_fungible.sol +228 -0
  27. package/contracts/lib/zeto_non_fungible_base.sol +61 -0
  28. package/contracts/lib/zeto_non_fungible_nullifier.sol +61 -0
  29. package/contracts/test/escrow1.sol +90 -34
  30. package/contracts/test/escrow2.sol +64 -29
  31. package/contracts/test/qurrency.sol +10 -2
  32. package/contracts/test/smt.sol +6 -1
  33. package/contracts/test/tendecimals.sol +14 -12
  34. package/contracts/verifiers/impl/anon.sol +189 -0
  35. package/contracts/verifiers/impl/anon_batch.sol +301 -0
  36. package/contracts/verifiers/impl/anon_enc.sol +266 -0
  37. package/contracts/verifiers/impl/anon_enc_batch.sol +602 -0
  38. package/contracts/verifiers/impl/anon_enc_nullifier.sol +287 -0
  39. package/contracts/verifiers/impl/anon_enc_nullifier_batch.sol +679 -0
  40. package/contracts/verifiers/impl/anon_enc_nullifier_kyc.sol +294 -0
  41. package/contracts/verifiers/impl/anon_enc_nullifier_kyc_batch.sol +686 -0
  42. package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation.sol +413 -0
  43. package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation_batch.sol +1141 -0
  44. package/contracts/verifiers/impl/anon_nullifier_kyc_transfer.sol +217 -0
  45. package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked.sol +196 -0
  46. package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked_batch.sol +308 -0
  47. package/contracts/verifiers/impl/anon_nullifier_kyc_transfer_batch.sol +385 -0
  48. package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer.sol +497 -0
  49. package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer_batch.sol +1001 -0
  50. package/contracts/verifiers/{verifier_anon_nullifier_transferLocked.sol → impl/anon_nullifier_transfer.sol} +12 -19
  51. package/contracts/verifiers/{verifier_anon_nullifier_transferLocked_batch.sol → impl/anon_nullifier_transfer_batch.sol} +44 -51
  52. package/contracts/verifiers/impl/burn.sol +182 -0
  53. package/contracts/verifiers/impl/burn_batch.sol +238 -0
  54. package/contracts/verifiers/impl/burn_nullifier.sol +203 -0
  55. package/contracts/verifiers/impl/burn_nullifier_batch.sol +315 -0
  56. package/contracts/verifiers/impl/deposit.sol +182 -0
  57. package/contracts/verifiers/impl/deposit_kyc.sol +189 -0
  58. package/contracts/verifiers/impl/nf_anon.sol +175 -0
  59. package/contracts/verifiers/{verifier_nf_anon_nullifier_transferLocked.sol → impl/nf_anon_nullifier_transfer.sol} +6 -13
  60. package/contracts/verifiers/impl/withdraw.sol +189 -0
  61. package/contracts/verifiers/impl/withdraw_batch.sol +245 -0
  62. package/contracts/verifiers/impl/withdraw_nullifier.sol +210 -0
  63. package/contracts/verifiers/impl/withdraw_nullifier_batch.sol +322 -0
  64. package/contracts/verifiers/verifier_anon.sol +31 -186
  65. package/contracts/verifiers/verifier_anon_batch.sol +31 -298
  66. package/contracts/verifiers/verifier_anon_enc.sol +31 -263
  67. package/contracts/verifiers/verifier_anon_enc_batch.sol +31 -599
  68. package/contracts/verifiers/verifier_anon_enc_nullifier.sol +31 -284
  69. package/contracts/verifiers/verifier_anon_enc_nullifier_batch.sol +33 -676
  70. package/contracts/verifiers/verifier_anon_enc_nullifier_kyc.sol +31 -291
  71. package/contracts/verifiers/verifier_anon_enc_nullifier_kyc_batch.sol +33 -683
  72. package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation.sol +33 -410
  73. package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation_batch.sol +33 -1138
  74. package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer.sol +33 -214
  75. package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked.sol +33 -221
  76. package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked_batch.sol +33 -389
  77. package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer_batch.sol +33 -382
  78. package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer.sol +33 -221
  79. package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer_batch.sol +33 -389
  80. package/contracts/verifiers/verifier_anon_nullifier_transfer.sol +33 -207
  81. package/contracts/verifiers/verifier_anon_nullifier_transfer_batch.sol +33 -375
  82. package/contracts/verifiers/verifier_burn.sol +31 -179
  83. package/contracts/verifiers/verifier_burn_batch.sol +31 -235
  84. package/contracts/verifiers/verifier_burn_nullifier.sol +31 -200
  85. package/contracts/verifiers/verifier_burn_nullifier_batch.sol +31 -312
  86. package/contracts/verifiers/verifier_deposit.sol +31 -179
  87. package/contracts/verifiers/verifier_deposit_kyc.sol +34 -0
  88. package/contracts/verifiers/verifier_nf_anon.sol +31 -172
  89. package/contracts/verifiers/verifier_nf_anon_nullifier_transfer.sol +33 -179
  90. package/contracts/verifiers/verifier_withdraw.sol +31 -186
  91. package/contracts/verifiers/verifier_withdraw_batch.sol +31 -242
  92. package/contracts/verifiers/verifier_withdraw_nullifier.sol +31 -207
  93. package/contracts/verifiers/verifier_withdraw_nullifier_batch.sol +33 -319
  94. package/contracts/zeto_anon.sol +77 -231
  95. package/contracts/zeto_anon_burnable.sol +56 -12
  96. package/contracts/zeto_anon_enc.sol +93 -190
  97. package/contracts/zeto_anon_enc_nullifier.sol +249 -195
  98. package/contracts/zeto_anon_enc_nullifier_kyc.sol +51 -232
  99. package/contracts/zeto_anon_enc_nullifier_non_repudiation.sol +231 -238
  100. package/contracts/zeto_anon_nullifier.sol +164 -298
  101. package/contracts/zeto_anon_nullifier_burnable.sol +68 -18
  102. package/contracts/zeto_anon_nullifier_kyc.sol +40 -345
  103. package/contracts/zeto_anon_nullifier_qurrency.sol +217 -361
  104. package/contracts/zeto_nf_anon.sol +55 -130
  105. package/contracts/zeto_nf_anon_nullifier.sol +90 -152
  106. package/hardhat.config.ts +18 -3
  107. package/ignition/modules/lib/deps.ts +13 -0
  108. package/ignition/modules/test/tendecimals.ts +7 -1
  109. package/ignition/modules/zeto_anon.ts +3 -0
  110. package/ignition/modules/zeto_anon_burnable.ts +11 -7
  111. package/ignition/modules/zeto_anon_enc.ts +3 -0
  112. package/ignition/modules/zeto_anon_enc_nullifier.ts +34 -0
  113. package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +5 -2
  114. package/ignition/modules/zeto_anon_enc_nullifier_non_repudiation.ts +3 -0
  115. package/ignition/modules/zeto_anon_nullifier.ts +31 -4
  116. package/ignition/modules/zeto_anon_nullifier_burnable.ts +53 -16
  117. package/ignition/modules/zeto_anon_nullifier_kyc.ts +30 -12
  118. package/ignition/modules/zeto_anon_nullifier_qurrency.ts +3 -0
  119. package/ignition/modules/zeto_nf_anon.ts +3 -1
  120. package/ignition/modules/zeto_nf_anon_nullifier.ts +17 -12
  121. package/package.json +7 -3
  122. package/scripts/deploy_cloneable.ts +19 -10
  123. package/scripts/deploy_upgradeable.ts +9 -5
  124. package/scripts/lib/zeto_libraries.ts +47 -0
  125. package/scripts/tokens/Zeto_Anon.ts +6 -3
  126. package/scripts/tokens/Zeto_AnonBurnable.ts +4 -1
  127. package/scripts/tokens/Zeto_AnonEnc.ts +15 -3
  128. package/scripts/tokens/Zeto_AnonEncNullifier.ts +11 -8
  129. package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +7 -6
  130. package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +7 -6
  131. package/scripts/tokens/Zeto_AnonNullifier.ts +7 -6
  132. package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +7 -6
  133. package/scripts/tokens/Zeto_AnonNullifierKyc.ts +7 -6
  134. package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +7 -8
  135. package/scripts/tokens/Zeto_NfAnon.ts +5 -3
  136. package/scripts/tokens/Zeto_NfAnonNullifier.ts +7 -7
  137. package/test/factory.ts +55 -73
  138. package/test/lib/anon_nullifier_helpers.ts +89 -0
  139. package/test/lib/anon_zeto_helpers.ts +76 -0
  140. package/test/lib/deploy.ts +5 -2
  141. package/test/lib/eip170.ts +23 -0
  142. package/test/lib/utils.ts +74 -35
  143. package/test/test/escrow1.ts +185 -58
  144. package/test/test/escrow2.ts +200 -107
  145. package/test/test/qurrency.ts +13 -33
  146. package/test/usdc-shielding.ts +39 -27
  147. package/test/utils.ts +144 -21
  148. package/test/zeto_anon.ts +956 -465
  149. package/test/zeto_anon_enc.ts +881 -143
  150. package/test/zeto_anon_enc_nullifier.ts +850 -39
  151. package/test/zeto_anon_enc_nullifier_kyc.ts +123 -182
  152. package/test/zeto_anon_enc_nullifier_non_repudiation.ts +80 -47
  153. package/test/zeto_anon_nullifier.ts +1212 -954
  154. package/test/zeto_anon_nullifier_kyc.ts +677 -656
  155. package/test/zeto_anon_nullifier_qurrency.ts +455 -307
  156. package/test/zeto_nf_anon.ts +737 -138
  157. package/test/zeto_nf_anon_nullifier.ts +876 -247
  158. package/contracts/lib/zeto_base.sol +0 -293
  159. package/contracts/lib/zeto_fungible_withdraw.sol +0 -132
  160. package/contracts/lib/zeto_fungible_withdraw_nullifier.sol +0 -144
  161. package/contracts/lib/zeto_nullifier.sol +0 -340
  162. package/contracts/zkDvP.sol_ +0 -273
  163. package/test/zkDvP.ts_ +0 -455
  164. /package/contracts/lib/{common.sol → common/common.sol} +0 -0
@@ -0,0 +1,318 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ pragma solidity ^0.8.27;
3
+
4
+ /**
5
+ * @title ILockableCapability
6
+ * @dev Generic interface for representing a locked capability that can be
7
+ * delegated and eventually consumed ("spent") or cancelled by a
8
+ * designated spender.
9
+ *
10
+ * A "capability" here is any predefined state-changing operation: it may
11
+ * involve tokens, a function call, or any other effect defined by the
12
+ * implementing contract.
13
+ *
14
+ * Core guarantees:
15
+ * - Each lock is identified by a unique lockId, generated by the
16
+ * implementing contract.
17
+ * - For each active lock, there is exactly one current spender
18
+ * address (the "authorized spender").
19
+ * - Initially, the lock creator is both the owner and the spender.
20
+ * - Only the current spender is allowed to spend, cancel, or delegate
21
+ * the lock.
22
+ * - This interface does not prescribe expiry, auto-cancellation, or
23
+ * owner-controlled clawback. Once a lock is created and delegated,
24
+ * the original owner cannot prevent the current spender from using
25
+ * it (except by becoming the current spender again through delegation).
26
+ * - Constraints beyond this base model should be implemented by delegating
27
+ * the lock to a separate policy contract.
28
+ *
29
+ * The intent is that, so long as a lock remains active and the caller is
30
+ * the current spender, the implementing contract MUST NOT introduce
31
+ * arbitrary revocation or expiry logic beyond:
32
+ * - the lock having already been spent or cancelled; or
33
+ * - the caller not being the current spender; or
34
+ * - the provided data failing validation as defined by the specific
35
+ * implementation.
36
+ *
37
+ * Notes on dynamically typed arguments:
38
+ * - Each `*Args` parameter contains implementation-specific,
39
+ * ABI-encoded calldata used to carry out that lifecycle action.
40
+ * Implementations are RECOMMENDED to define and document a canonical
41
+ * struct type for each such argument payload, and to encode that
42
+ * struct using `abi.encode(...)` when calling the interface methods.
43
+ * - Each `data` parameter contains application-specific calldata,
44
+ * which is passed through to emitted events.
45
+ */
46
+ interface ILockableCapability {
47
+ /**
48
+ * @dev Stored lock info available to query by lockId.
49
+ */
50
+ struct LockInfo {
51
+ /**
52
+ * @dev The address that originally created the lock.
53
+ * Immutable for the lifetime of the lock.
54
+ */
55
+ address owner;
56
+ /**
57
+ * @dev The address currently authorized to spend, cancel, or delegate the lock.
58
+ * Mutable by the current spender while the lock remains active.
59
+ */
60
+ address spender;
61
+ /**
62
+ * @dev An implementation-defined commitment to the spend operation permitted for this lock.
63
+ * Zero must be supported by the spending logic and treated as "unrestricted".
64
+ * Mutable if and only if the lock is active and owner-controlled
65
+ * (`spender == owner`).
66
+ */
67
+ bytes32 spendCommitment;
68
+ /**
69
+ * @dev An implementation-defined commitment to the cancellation operation permitted for this lock.
70
+ * Zero must be supported by the cancellation logic and treated as "unrestricted".
71
+ * Mutable if and only if the lock is active and owner-controlled
72
+ * (`spender == owner`).
73
+ */
74
+ bytes32 cancelCommitment;
75
+ }
76
+
77
+ /**
78
+ * @dev Emitted when a lock is created.
79
+ */
80
+ event LockCreated(
81
+ bytes32 indexed lockId,
82
+ address indexed owner,
83
+ address indexed spender,
84
+ bytes32 spendCommitment,
85
+ bytes32 cancelCommitment,
86
+ bytes data
87
+ );
88
+
89
+ /**
90
+ * @dev Emitted when an active lock is updated.
91
+ */
92
+ event LockUpdated(
93
+ bytes32 indexed lockId,
94
+ address indexed owner,
95
+ bytes32 spendCommitment,
96
+ bytes32 cancelCommitment,
97
+ bytes data
98
+ );
99
+
100
+ /**
101
+ * @dev Emitted when spending authority is delegated from one address to another.
102
+ */
103
+ event LockDelegated(
104
+ bytes32 indexed lockId,
105
+ address indexed from,
106
+ address indexed to,
107
+ bytes data
108
+ );
109
+
110
+ /**
111
+ * @dev Emitted when a lock is successfully spent.
112
+ */
113
+ event LockSpent(
114
+ bytes32 indexed lockId,
115
+ address indexed spender,
116
+ bytes data
117
+ );
118
+
119
+ /**
120
+ * @dev Emitted when a lock is successfully cancelled.
121
+ */
122
+ event LockCancelled(
123
+ bytes32 indexed lockId,
124
+ address indexed spender,
125
+ bytes data
126
+ );
127
+
128
+ /**
129
+ * @dev Thrown when a lock does not exist or is not active.
130
+ */
131
+ error LockNotActive(bytes32 lockId);
132
+
133
+ /**
134
+ * @dev Thrown when the caller is not the current spender for the given lock.
135
+ */
136
+ error LockUnauthorized(bytes32 lockId, address spender, address caller);
137
+
138
+ /**
139
+ * @dev Thrown when an attempted mutation is not permitted under the lock's
140
+ * mutability rules.
141
+ */
142
+ error LockImmutable(bytes32 lockId);
143
+
144
+ /**
145
+ * @dev Create a new lock.
146
+ * Moves control of the relevant value/state/activity to the lock.
147
+ *
148
+ * Locks are identified by a unique lockId, generated in an
149
+ * implementation-specific way.
150
+ * Implementations SHOULD generate lockId deterministically from
151
+ * immutable lock properties where practical.
152
+ *
153
+ * Requirements:
154
+ * - MUST create the lock in the active state
155
+ * - MUST set owner to msg.sender
156
+ * - MUST set spender to msg.sender initially
157
+ *
158
+ * @param createArgs Implementation-specific calldata needed to create the lock.
159
+ * @param spendCommitment An implementation-defined commitment to the spend operation permitted for this lock.
160
+ * @param cancelCommitment An implementation-defined commitment to the cancellation operation permitted for this lock.
161
+ * @param data Auxiliary application-specific calldata.
162
+ * @return lockId The generated unique identifier for the lock.
163
+ *
164
+ * Emits a {LockCreated} event.
165
+ */
166
+ function createLock(
167
+ bytes calldata createArgs,
168
+ bytes32 spendCommitment,
169
+ bytes32 cancelCommitment,
170
+ bytes calldata data
171
+ ) external returns (bytes32 lockId);
172
+
173
+ /**
174
+ * @dev Update an existing active, owner-controlled lock.
175
+ *
176
+ * `spendCommitment` and `cancelCommitment` fully replace the previous
177
+ * commitment values.
178
+ * Delegates can never alter the shape or purpose of a lock.
179
+ *
180
+ * Requirements:
181
+ * - MUST revert with LockNotActive(lockId) if the lock is not active
182
+ * - MUST revert with LockImmutable(lockId) unless the lock is currently
183
+ * owner-controlled (`spender == owner`) and the requested mutation is
184
+ * permitted by the implementation
185
+ *
186
+ * @param lockId The unique identifier for the lock.
187
+ * @param updateArgs Implementation-specific calldata needed to update the lock.
188
+ * @param spendCommitment Replacement spend commitment.
189
+ * @param cancelCommitment Replacement cancel commitment.
190
+ * @param data Auxiliary application-specific calldata.
191
+ *
192
+ * Emits a {LockUpdated} event.
193
+ */
194
+ function updateLock(
195
+ bytes32 lockId,
196
+ bytes calldata updateArgs,
197
+ bytes32 spendCommitment,
198
+ bytes32 cancelCommitment,
199
+ bytes calldata data
200
+ ) external;
201
+
202
+ /**
203
+ * @dev Delegate spending authority for this lock to a new address.
204
+ *
205
+ * After delegation:
206
+ * - The previous spender MUST no longer be allowed to spend or
207
+ * cancel the lock (unless they later regain spender status).
208
+ * - `spendCommitment` and `cancelCommitment` MUST be immutable while
209
+ * the lock is not owner-controlled.
210
+ *
211
+ * Delegation is reversible by the current spender, including
212
+ * delegation back to the owner.
213
+ *
214
+ * Requirements:
215
+ * - MUST revert with LockUnauthorized(lockId, currentSpender, msg.sender)
216
+ * if msg.sender is not the current spender for lockId
217
+ * - MUST revert with LockNotActive(lockId) if the lock is not active
218
+ *
219
+ * @param lockId The unique identifier for the lock.
220
+ * @param delegateArgs Implementation-specific calldata needed to delegate the lock.
221
+ * @param newSpender The address to delegate the lock to.
222
+ * @param data Auxiliary application-specific calldata.
223
+ *
224
+ * Emits a {LockDelegated} event.
225
+ */
226
+ function delegateLock(
227
+ bytes32 lockId,
228
+ bytes calldata delegateArgs,
229
+ address newSpender,
230
+ bytes calldata data
231
+ ) external;
232
+
233
+ /**
234
+ * @dev Spend the lock.
235
+ * Consumes or executes the effect of the lock (for example: releasing tokens,
236
+ * executing a function call, etc).
237
+ *
238
+ * Requirements:
239
+ * - MUST revert with LockUnauthorized(lockId, currentSpender, msg.sender)
240
+ * if msg.sender is not the current spender for lockId
241
+ * - MUST revert with LockNotActive(lockId) if the lock is not active
242
+ * - MUST remove the lock (or mark as inactive) if successful
243
+ *
244
+ * @param lockId The unique identifier for the lock.
245
+ * @param spendArgs Implementation-specific calldata needed to spend the lock.
246
+ * @param data Auxiliary application-specific calldata.
247
+ *
248
+ * Emits a {LockSpent} event.
249
+ */
250
+ function spendLock(
251
+ bytes32 lockId,
252
+ bytes calldata spendArgs,
253
+ bytes calldata data
254
+ ) external;
255
+
256
+ /**
257
+ * @dev Cancel the lock.
258
+ * Performs the cancellation operation for the lock (for example: refunding
259
+ * tokens, executing a function call, etc).
260
+ *
261
+ * Requirements:
262
+ * - MUST revert with LockUnauthorized(lockId, currentSpender, msg.sender)
263
+ * if msg.sender is not the current spender for lockId
264
+ * - MUST revert with LockNotActive(lockId) if the lock is not active
265
+ * - MUST remove the lock (or mark as inactive) if successful
266
+ *
267
+ * @param lockId The unique identifier for the lock.
268
+ * @param cancelArgs Implementation-specific calldata needed to cancel the lock.
269
+ * @param data Auxiliary application-specific calldata.
270
+ *
271
+ * Emits a {LockCancelled} event.
272
+ */
273
+ function cancelLock(
274
+ bytes32 lockId,
275
+ bytes calldata cancelArgs,
276
+ bytes calldata data
277
+ ) external;
278
+
279
+ /**
280
+ * @dev Get stored lock information for an active lock.
281
+ *
282
+ * Requirements:
283
+ * - MUST revert with LockNotActive(lockId) if the lock is not active.
284
+ *
285
+ * @param lockId The unique identifier for the lock.
286
+ * @return info Stored lock information.
287
+ */
288
+ function getLock(
289
+ bytes32 lockId
290
+ ) external view returns (LockInfo memory info);
291
+
292
+ /**
293
+ * @dev Query whether the lock is currently active.
294
+ *
295
+ * MUST return false for locks that do not exist and for locks that
296
+ * have been spent or cancelled.
297
+ *
298
+ * @param lockId The unique identifier for the lock.
299
+ * @return active Whether the lock is currently active.
300
+ */
301
+ function isLockActive(bytes32 lockId) external view returns (bool active);
302
+
303
+ /**
304
+ * @dev Get implementation-specific lock content for an active lock.
305
+ *
306
+ * This represents the data or operation that was locked, and is
307
+ * immutable once the lock is created.
308
+ *
309
+ * Requirements:
310
+ * - MUST revert with LockNotActive(lockId) if the lock is not active.
311
+ *
312
+ * @param lockId The unique identifier for the lock.
313
+ * @return content The implementation-specific lock content.
314
+ */
315
+ function getLockContent(
316
+ bytes32 lockId
317
+ ) external view returns (bytes memory content);
318
+ }
@@ -17,7 +17,8 @@ pragma solidity ^0.8.27;
17
17
 
18
18
  uint256 constant MAX_BATCH = 10;
19
19
  uint256 constant MAX_SMT_DEPTH = 64;
20
- interface IZeto {
20
+
21
+ interface IZetoConstants {
21
22
  error UTXODuplicate(uint256 utxo);
22
23
  error UTXOArrayTooLarge(uint256 maxAllowed);
23
24
  error UTXONotMinted(uint256 utxo);
@@ -46,6 +47,15 @@ interface IZeto {
46
47
  address indexed submitter,
47
48
  bytes data
48
49
  );
50
+ event UTXOTransferWithMlkemEncryptedValues(
51
+ uint256[] inputs,
52
+ uint256[] outputs,
53
+ uint256 encryptionNonce,
54
+ uint256[25] encapsulatedSharedSecret,
55
+ uint256[] encryptedValues,
56
+ address indexed submitter,
57
+ bytes data
58
+ );
49
59
  event UTXOWithdraw(
50
60
  uint256 amount,
51
61
  uint256[] inputs,
@@ -53,7 +63,9 @@ interface IZeto {
53
63
  address indexed submitter,
54
64
  bytes data
55
65
  );
66
+ }
56
67
 
68
+ interface IZeto is IZetoConstants {
57
69
  /**
58
70
  * @dev Returns the name of the token.
59
71
  */
@@ -15,23 +15,25 @@
15
15
  // limitations under the License.
16
16
  pragma solidity ^0.8.27;
17
17
 
18
+ import {IGroth16Verifier} from "./IZetoVerifier.sol";
19
+
18
20
  interface IZetoInitializable {
19
21
  struct VerifiersInfo {
20
- address verifier;
21
- address depositVerifier;
22
- address withdrawVerifier;
23
- address lockVerifier;
24
- address burnVerifier;
25
- address batchVerifier;
26
- address batchWithdrawVerifier;
27
- address batchLockVerifier;
28
- address batchBurnVerifier;
22
+ IGroth16Verifier verifier;
23
+ IGroth16Verifier depositVerifier;
24
+ IGroth16Verifier withdrawVerifier;
25
+ IGroth16Verifier lockVerifier;
26
+ IGroth16Verifier burnVerifier;
27
+ IGroth16Verifier batchVerifier;
28
+ IGroth16Verifier batchWithdrawVerifier;
29
+ IGroth16Verifier batchLockVerifier;
30
+ IGroth16Verifier batchBurnVerifier;
29
31
  }
30
32
 
31
33
  function initialize(
32
- string memory name,
33
- string memory symbol,
34
+ string calldata name,
35
+ string calldata symbol,
34
36
  address initialOwner,
35
- VerifiersInfo memory verifiersInfo
37
+ VerifiersInfo calldata verifiersInfo
36
38
  ) external;
37
39
  }
@@ -15,18 +15,18 @@
15
15
  // limitations under the License.
16
16
  pragma solidity ^0.8.27;
17
17
 
18
- import {Commonlib} from "../common.sol";
18
+ import {Commonlib} from "../common/common.sol";
19
19
 
20
20
  interface IZetoKyc {
21
21
  event IdentityRegistered(uint256[2] publicKey, bytes data);
22
22
 
23
23
  function register(
24
- uint256[2] memory publicKey,
24
+ uint256[2] calldata publicKey,
25
25
  bytes calldata data
26
26
  ) external;
27
27
 
28
28
  function isRegistered(
29
- uint256[2] memory publicKey
29
+ uint256[2] calldata publicKey
30
30
  ) external view returns (bool);
31
31
 
32
32
  function getIdentitiesRoot() external view returns (uint256);
@@ -0,0 +1,42 @@
1
+ // Copyright © 2025 Kaleido, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ pragma solidity ^0.8.27;
17
+
18
+ import {IZetoLockableCapability} from "./IZetoLockableCapability.sol";
19
+
20
+ /**
21
+ * @title IZetoLockHooks
22
+ * @dev Callback surface invoked by {ZetoLockableLib} (via `address(this)`)
23
+ * so circuit-specific lock transitions stay in the embedding token
24
+ * while shared lock lifecycle logic lives in the external library.
25
+ */
26
+ interface IZetoLockHooks {
27
+ /// @dev Thrown when a hook is invoked by an address other than `address(this)`.
28
+ error NotSelf(address caller);
29
+
30
+ function zetoLockDoLockTransition(
31
+ IZetoLockableCapability.ZetoCreateLockArgs calldata args
32
+ ) external;
33
+
34
+ function zetoLockTransferLocked(
35
+ bytes32 lockId,
36
+ uint256[] calldata lockedInputs,
37
+ uint256[] calldata lockedOutputs,
38
+ uint256[] calldata outputs,
39
+ bytes calldata proof,
40
+ bytes calldata data
41
+ ) external;
42
+ }
@@ -0,0 +1,237 @@
1
+ // Copyright © 2025 Kaleido, Inc.
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+ //
5
+ // Licensed under the Apache License, Version 2.0 (the "License");
6
+ // you may not use this file except in compliance with the License.
7
+ // You may obtain a copy of the License at
8
+ //
9
+ // http://www.apache.org/licenses/LICENSE-2.0
10
+ //
11
+ // Unless required by applicable law or agreed to in writing, software
12
+ // distributed under the License is distributed on an "AS IS" BASIS,
13
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ // See the License for the specific language governing permissions and
15
+ // limitations under the License.
16
+ pragma solidity ^0.8.27;
17
+
18
+ import {ILockableCapability} from "./ILockableCapability.sol";
19
+
20
+ /**
21
+ * @title IZetoLockableCapability
22
+ * @dev Zeto-specific extension of {ILockableCapability}.
23
+ *
24
+ * Defines the canonical ABI-encoded payloads (`*Args` parameters) and the
25
+ * Zeto-specific events emitted alongside the generic ILockableCapability
26
+ * events, mirroring the pattern used by the noto domain in Paladin.
27
+ *
28
+ * The lockId is generated deterministically as
29
+ * `keccak256(abi.encode(address(this), msg.sender, args.txId))` and can be
30
+ * predicted via {computeLockId} before calling {createLock}.
31
+ */
32
+ interface IZetoLockableCapability is ILockableCapability {
33
+ // ----------------------------------------------------------------------
34
+ // Errors retained from the previous IZetoLockable interface
35
+ // ----------------------------------------------------------------------
36
+
37
+ /// @dev Thrown when a UTXO is already locked at the storage layer.
38
+ error AlreadyLocked(uint256 utxo);
39
+
40
+ /// @dev Thrown when a UTXO is referenced as locked input but is not locked.
41
+ error NotLocked(uint256 utxo);
42
+
43
+ /// @dev Thrown when the caller is not the current per-UTXO storage delegate.
44
+ error NotLockDelegate(
45
+ uint256 utxo,
46
+ address currentDelegate,
47
+ address sender
48
+ );
49
+
50
+ /// @dev Thrown when a provided spend/cancel payload does not hash to the
51
+ /// previously committed value.
52
+ error InvalidUnlockHash(bytes32 expected, bytes32 actual);
53
+
54
+ /// @dev Thrown when the caller-supplied txId has already been used.
55
+ error DuplicateTransaction(bytes32 txId);
56
+
57
+ /// @dev Thrown when computeLockId would collide with an already-active lock.
58
+ error DuplicateLock(bytes32 lockId);
59
+
60
+ // ----------------------------------------------------------------------
61
+ // ABI-encoded argument payloads carried by the generic *Args parameters
62
+ // ----------------------------------------------------------------------
63
+
64
+ /**
65
+ * @dev Payload for {ILockableCapability.createLock}.createArgs.
66
+ *
67
+ * The transaction consumes `inputs` (regular UTXOs/nullifiers) and
68
+ * produces `outputs` (regular UTXOs) and `lockedOutputs` (the locked
69
+ * content held under the lock). `proof` is the ZK proof authorising
70
+ * the state transition.
71
+ */
72
+ struct ZetoCreateLockArgs {
73
+ bytes32 txId;
74
+ uint256[] inputs;
75
+ uint256[] outputs;
76
+ uint256[] lockedOutputs;
77
+ bytes proof;
78
+ }
79
+
80
+ /**
81
+ * @dev Payload for {ILockableCapability.updateLock}.updateArgs.
82
+ *
83
+ * Update is metadata-only on Zeto (it rewrites the spend/cancel
84
+ * commitments), so only a fresh txId is required.
85
+ */
86
+ struct ZetoUpdateLockArgs {
87
+ bytes32 txId;
88
+ }
89
+
90
+ /**
91
+ * @dev Payload for {ILockableCapability.delegateLock}.delegateArgs.
92
+ */
93
+ struct ZetoDelegateLockArgs {
94
+ bytes32 txId;
95
+ }
96
+
97
+ /**
98
+ * @dev Payload for {ILockableCapability.spendLock}.spendArgs and
99
+ * {ILockableCapability.cancelLock}.cancelArgs.
100
+ *
101
+ * The set of locked UTXOs being consumed is intentionally NOT carried
102
+ * here: it is taken verbatim from the lock's storage-pinned content
103
+ * (see {getLockContent}) so that "spending lock A always consumes lock
104
+ * A's UTXOs" is a hard contract invariant rather than a soft hash
105
+ * check. The {InvalidUnlockHash} check is therefore computed over
106
+ * `(lock.lockedInputs, lockedOutputs, outputs, data)` where
107
+ * `lock.lockedInputs` is read from storage.
108
+ */
109
+ struct ZetoSpendLockArgs {
110
+ bytes32 txId;
111
+ uint256[] lockedOutputs;
112
+ uint256[] outputs;
113
+ bytes proof;
114
+ bytes data;
115
+ }
116
+
117
+ // ----------------------------------------------------------------------
118
+ // Zeto-specific events emitted alongside the generic events
119
+ // ----------------------------------------------------------------------
120
+
121
+ /// @dev Emitted alongside {LockCreated} with decoded Zeto parameters.
122
+ event ZetoLockCreated(
123
+ bytes32 indexed txId,
124
+ bytes32 indexed lockId,
125
+ address indexed owner,
126
+ uint256[] inputs,
127
+ uint256[] outputs,
128
+ uint256[] lockedOutputs,
129
+ bytes proof,
130
+ bytes data
131
+ );
132
+
133
+ /// @dev Emitted alongside {LockUpdated} with the Zeto txId.
134
+ event ZetoLockUpdated(
135
+ bytes32 indexed txId,
136
+ bytes32 indexed lockId,
137
+ address indexed owner,
138
+ bytes data
139
+ );
140
+
141
+ /// @dev Emitted alongside {LockDelegated} with the Zeto txId.
142
+ event ZetoLockDelegated(
143
+ bytes32 indexed txId,
144
+ bytes32 indexed lockId,
145
+ address indexed from,
146
+ address to,
147
+ bytes data
148
+ );
149
+
150
+ /// @dev Emitted alongside {LockSpent} with decoded Zeto parameters.
151
+ /// `lockedInputs` is the lock's storage-pinned content, not a
152
+ /// caller-supplied value (see {ZetoSpendLockArgs}).
153
+ event ZetoLockSpent(
154
+ bytes32 indexed txId,
155
+ bytes32 indexed lockId,
156
+ address indexed spender,
157
+ uint256[] lockedInputs,
158
+ uint256[] lockedOutputs,
159
+ uint256[] outputs,
160
+ bytes proof,
161
+ bytes data
162
+ );
163
+
164
+ /// @dev Emitted alongside {LockCancelled} with decoded Zeto parameters.
165
+ /// `lockedInputs` is the lock's storage-pinned content, not a
166
+ /// caller-supplied value (see {ZetoSpendLockArgs}).
167
+ event ZetoLockCancelled(
168
+ bytes32 indexed txId,
169
+ bytes32 indexed lockId,
170
+ address indexed spender,
171
+ uint256[] lockedInputs,
172
+ uint256[] lockedOutputs,
173
+ uint256[] outputs,
174
+ bytes proof,
175
+ bytes data
176
+ );
177
+
178
+ // ----------------------------------------------------------------------
179
+ // Zeto-specific view helpers
180
+ // ----------------------------------------------------------------------
181
+
182
+ /**
183
+ * @dev Compute the lockId that {createLock} would generate for a given
184
+ * caller and createArgs payload. Useful for off-chain pre-computation.
185
+ *
186
+ * @param createArgs ABI-encoded {ZetoCreateLockArgs}.
187
+ * @return lockId The lockId that would be assigned.
188
+ */
189
+ function computeLockId(
190
+ bytes calldata createArgs
191
+ ) external view returns (bytes32 lockId);
192
+
193
+ /**
194
+ * @dev Compute the spend-intent commitment for a prospective
195
+ * {ZetoSpendLockArgs} payload. The returned hash is what the lock
196
+ * creator should pass as `spendCommitment` to {createLock} (or to
197
+ * {updateLock}) if they want to bind the spender to a specific
198
+ * spend payload.
199
+ *
200
+ * Implementations MUST compute this in a hash space that is
201
+ * disjoint from {computeCancelHash} so that a spender cannot
202
+ * transpose a spend payload into {cancelLock} (or vice versa).
203
+ */
204
+ function computeSpendHash(
205
+ uint256[] calldata lockedInputs,
206
+ uint256[] calldata lockedOutputs,
207
+ uint256[] calldata outputs,
208
+ bytes calldata data
209
+ ) external pure returns (bytes32);
210
+
211
+ /**
212
+ * @dev Compute the cancel-intent commitment for a prospective
213
+ * {ZetoSpendLockArgs} payload. See {computeSpendHash} for the
214
+ * domain-separation rationale.
215
+ */
216
+ function computeCancelHash(
217
+ uint256[] calldata lockedInputs,
218
+ uint256[] calldata lockedOutputs,
219
+ uint256[] calldata outputs,
220
+ bytes calldata data
221
+ ) external pure returns (bytes32);
222
+
223
+ /**
224
+ * @dev Typed view returning the locked UTXOs held under `lockId`.
225
+ *
226
+ * This is the canonical accessor for the lock content. The generic
227
+ * {ILockableCapability.getLockContent} returns the same data
228
+ * `abi.encode`-d into `bytes` for compatibility with callers that
229
+ * treat lock contents opaquely.
230
+ *
231
+ * Requirements:
232
+ * - MUST revert with {LockNotActive}(lockId) if the lock is not active.
233
+ */
234
+ function getLockedInputs(
235
+ bytes32 lockId
236
+ ) external view returns (uint256[] memory lockedInputs);
237
+ }