@lfdecentralizedtrust/zeto-contracts 0.2.2 → 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 (152) hide show
  1. package/README.md +70 -162
  2. package/contracts/factory.sol +30 -34
  3. package/contracts/factory_upgradeable.sol +11 -7
  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 +74 -26
  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 +6 -1
  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 +217 -361
  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 +8 -0
  104. package/ignition/modules/zeto_anon_burnable.ts +8 -7
  105. package/ignition/modules/zeto_anon_enc_nullifier.ts +31 -0
  106. package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +2 -2
  107. package/ignition/modules/zeto_anon_nullifier.ts +28 -4
  108. package/ignition/modules/zeto_anon_nullifier_burnable.ts +50 -16
  109. package/ignition/modules/zeto_anon_nullifier_kyc.ts +27 -12
  110. package/ignition/modules/zeto_nf_anon_nullifier.ts +14 -10
  111. package/package.json +4 -2
  112. package/scripts/deploy_cloneable.ts +19 -10
  113. package/scripts/deploy_upgradeable.ts +9 -5
  114. package/scripts/tokens/Zeto_Anon.ts +3 -3
  115. package/scripts/tokens/Zeto_AnonBurnable.ts +1 -1
  116. package/scripts/tokens/Zeto_AnonEnc.ts +12 -3
  117. package/scripts/tokens/Zeto_AnonEncNullifier.ts +5 -3
  118. package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +1 -1
  119. package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +1 -1
  120. package/scripts/tokens/Zeto_AnonNullifier.ts +1 -1
  121. package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +1 -1
  122. package/scripts/tokens/Zeto_AnonNullifierKyc.ts +1 -1
  123. package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +1 -1
  124. package/scripts/tokens/Zeto_NfAnon.ts +2 -2
  125. package/scripts/tokens/Zeto_NfAnonNullifier.ts +1 -1
  126. package/test/factory.ts +46 -73
  127. package/test/lib/anon_nullifier_helpers.ts +89 -0
  128. package/test/lib/anon_zeto_helpers.ts +76 -0
  129. package/test/lib/deploy.ts +3 -2
  130. package/test/lib/utils.ts +74 -35
  131. package/test/test/escrow1.ts +185 -58
  132. package/test/test/escrow2.ts +200 -107
  133. package/test/test/qurrency.ts +13 -33
  134. package/test/usdc-shielding.ts +39 -26
  135. package/test/utils.ts +144 -21
  136. package/test/zeto_anon.ts +956 -465
  137. package/test/zeto_anon_enc.ts +881 -142
  138. package/test/zeto_anon_enc_nullifier.ts +847 -38
  139. package/test/zeto_anon_enc_nullifier_kyc.ts +120 -181
  140. package/test/zeto_anon_enc_nullifier_non_repudiation.ts +77 -46
  141. package/test/zeto_anon_nullifier.ts +1212 -953
  142. package/test/zeto_anon_nullifier_kyc.ts +674 -655
  143. package/test/zeto_anon_nullifier_qurrency.ts +452 -306
  144. package/test/zeto_nf_anon.ts +737 -137
  145. package/test/zeto_nf_anon_nullifier.ts +876 -246
  146. package/contracts/lib/zeto_base.sol +0 -293
  147. package/contracts/lib/zeto_fungible_withdraw.sol +0 -132
  148. package/contracts/lib/zeto_fungible_withdraw_nullifier.sol +0 -144
  149. package/contracts/lib/zeto_nullifier.sol +0 -340
  150. package/contracts/zkDvP.sol_ +0 -273
  151. package/test/zkDvP.ts_ +0 -455
  152. /package/contracts/lib/{common.sol → common/common.sol} +0 -0
@@ -15,32 +15,59 @@
15
15
  // limitations under the License.
16
16
  pragma solidity ^0.8.27;
17
17
 
18
- import {Commonlib} from "./common.sol";
19
- import {IZeto, MAX_BATCH} from "./interfaces/izeto.sol";
20
- import {Arrays} from "@openzeppelin/contracts/utils/Arrays.sol";
21
- import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
18
+ import {Commonlib} from "./common/common.sol";
19
+ import {IZeto, MAX_BATCH} from "./interfaces/IZeto.sol";
20
+ import {IGroth16Verifier} from "./interfaces/IZetoVerifier.sol";
21
+ import {IZetoInitializable} from "./interfaces/IZetoInitializable.sol";
22
+ import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
23
+ import {Util} from "./common/util.sol";
24
+ import {IZetoStorage} from "./interfaces/IZetoStorage.sol";
22
25
 
23
26
  /// @title A sample base implementation of a Zeto based token contract
24
27
  /// @author Kaleido, Inc.
25
- /// @dev Implements common functionalities of Zeto based tokens
26
- abstract contract ZetoCommon is IZeto, OwnableUpgradeable {
27
- string private _name;
28
- string private _symbol;
28
+ /// @dev Implements common functionalities of Zeto based tokens.
29
+ ///
30
+ /// Ownership uses {Ownable2StepUpgradeable}: the current owner cannot
31
+ /// transfer ownership in a single call. {transferOwnership} stages a
32
+ /// pending owner that the candidate must accept by calling
33
+ /// {acceptOwnership}. This eliminates the "fat-finger to the wrong
34
+ /// address" risk of single-step transfer for accounts that, in this
35
+ /// contract, can mint, configure verifiers (via upgrades), bind the
36
+ /// backing ERC20 (via {ZetoFungible.setERC20}), and authorize UUPS
37
+ /// upgrades on the concrete tokens.
38
+ ///
39
+ /// Operators are nonetheless STRONGLY advised to assign ownership to
40
+ /// a multisig (e.g. Gnosis Safe) or a timelock-governed account, since
41
+ /// the privileges above are still concentrated in a single role.
42
+ abstract contract ZetoCommon is IZeto, Ownable2StepUpgradeable {
43
+ /// @dev Thrown when the supplied Groth16 proof fails verification.
44
+ /// Replaces the previous `require(..., "Invalid proof")` strings
45
+ /// so callers can match a typed error in their error decoders.
46
+ error InvalidProof();
29
47
 
30
48
  function __ZetoCommon_init(
31
- string memory name_,
32
- string memory symbol_,
33
- address initialOwner
49
+ string calldata name_,
50
+ string calldata symbol_,
51
+ address initialOwner,
52
+ IZetoInitializable.VerifiersInfo calldata verifiers,
53
+ IZetoStorage storage_
34
54
  ) internal onlyInitializing {
35
55
  __Ownable_init(initialOwner);
36
- _name = name_;
37
- _symbol = symbol_;
56
+ ZetoCommonStorage.Layout storage $ = ZetoCommonStorage.layout();
57
+ $.tokenName = name_;
58
+ $.tokenSymbol = symbol_;
59
+ $.verifier = verifiers.verifier;
60
+ $.lockVerifier = verifiers.lockVerifier;
61
+ $.batchVerifier = verifiers.batchVerifier;
62
+ $.batchLockVerifier = verifiers.batchLockVerifier;
63
+ $.utxoStorage = storage_;
38
64
  }
65
+
39
66
  /**
40
67
  * @dev Returns the name of the token.
41
68
  */
42
69
  function name() public view virtual returns (string memory) {
43
- return _name;
70
+ return ZetoCommonStorage.layout().tokenName;
44
71
  }
45
72
 
46
73
  /**
@@ -48,7 +75,7 @@ abstract contract ZetoCommon is IZeto, OwnableUpgradeable {
48
75
  * name.
49
76
  */
50
77
  function symbol() public view virtual returns (string memory) {
51
- return _symbol;
78
+ return ZetoCommonStorage.layout().tokenSymbol;
52
79
  }
53
80
 
54
81
  /**
@@ -67,10 +94,65 @@ abstract contract ZetoCommon is IZeto, OwnableUpgradeable {
67
94
  return 4;
68
95
  }
69
96
 
97
+ /**
98
+ * @dev This function is used to mint new UTXOs, as an example implementation,
99
+ * which is only callable by the owner.
100
+ *
101
+ * @param utxos Array of UTXOs to be minted.
102
+ * @param data Additional data to be passed to the mint function.
103
+ *
104
+ * Emits a {UTXOMint} event.
105
+ */
106
+ function mint(
107
+ uint256[] calldata utxos,
108
+ bytes calldata data
109
+ ) public virtual onlyOwner {
110
+ _mint(utxos, data);
111
+ }
112
+
113
+ /**
114
+ * @dev construct the public inputs and verify the proof. it's a utility function useful for situations
115
+ * like an escrow contract orchestrating locking and settlement flows
116
+ *
117
+ * @param inputs Array of UTXOs to be spent by the transaction.
118
+ * @param outputs Array of new UTXOs to generate, for future transactions to spend.
119
+ * @param proof A zero knowledge proof that the submitter is authorized to spend the inputs, and
120
+ * that the outputs are valid in terms of obeying mass conservation rules.
121
+ * @param inputsLocked Whether the inputs are locked.
122
+ *
123
+ * @return True if the proof is valid, false otherwise.
124
+ */
125
+ function constructPublicSignalsAndVerifyProof(
126
+ uint256[] memory inputs,
127
+ uint256[] memory outputs,
128
+ bytes memory proof,
129
+ bool inputsLocked
130
+ ) public returns (bool) {
131
+ (
132
+ uint256[] memory publicInputs,
133
+ Commonlib.Proof memory proofStruct
134
+ ) = constructPublicInputs(inputs, outputs, proof, inputsLocked);
135
+ bool isBatch = inputs.length > 2 || outputs.length > 2;
136
+ verifyProof(proofStruct, publicInputs, isBatch, inputsLocked);
137
+ return true;
138
+ }
139
+
140
+ function _mint(
141
+ uint256[] memory utxos,
142
+ bytes calldata data
143
+ ) internal virtual {
144
+ validateOutputs(utxos);
145
+ processOutputs(utxos);
146
+ emit UTXOMint(utxos, msg.sender, data);
147
+ }
148
+
70
149
  function checkAndPadCommitments(
71
- uint256[] memory commitments
72
- ) public pure returns (uint256[] memory) {
73
- uint256 len = commitments.length;
150
+ uint256[] memory inputs,
151
+ uint256[] memory outputs
152
+ ) public pure returns (uint256[] memory, uint256[] memory) {
153
+ uint256 len = (inputs.length > outputs.length)
154
+ ? inputs.length
155
+ : outputs.length;
74
156
 
75
157
  // Check if inputs or outputs exceed batchMax and revert with custom error if necessary
76
158
  if (len > MAX_BATCH) {
@@ -91,18 +173,185 @@ abstract contract ZetoCommon is IZeto, OwnableUpgradeable {
91
173
  }
92
174
 
93
175
  // Pad commitments to the determined maxLength
94
- commitments = Commonlib.padUintArray(commitments, maxLength, 0);
176
+ inputs = Commonlib.padUintArray(inputs, maxLength, 0);
177
+ outputs = Commonlib.padUintArray(outputs, maxLength, 0);
178
+
179
+ return (inputs, outputs);
180
+ }
181
+
182
+ // this is a utility function that constructs the public inputs for a proof.
183
+ // specific implementations of this function are provided by each token implementation
184
+ function constructPublicInputs(
185
+ uint256[] memory inputs,
186
+ uint256[] memory outputs,
187
+ bytes memory proof,
188
+ bool inputsLocked
189
+ )
190
+ internal
191
+ virtual
192
+ returns (
193
+ uint256[] memory publicInputs,
194
+ Commonlib.Proof memory proofStruct
195
+ )
196
+ {}
197
+
198
+ function validateTransactionProposal(
199
+ uint256[] memory inputs,
200
+ uint256[] memory outputs,
201
+ uint256[] memory lockedOutputs,
202
+ bytes memory proof,
203
+ bool inputsLocked
204
+ ) internal view virtual {
205
+ uint256[] memory allOutputs = new uint256[](
206
+ outputs.length + lockedOutputs.length
207
+ );
208
+ for (uint256 i = 0; i < outputs.length; i++) {
209
+ allOutputs[i] = outputs[i];
210
+ }
211
+ for (uint256 i = 0; i < lockedOutputs.length; i++) {
212
+ allOutputs[outputs.length + i] = lockedOutputs[i];
213
+ }
214
+ validateInputs(inputs, inputsLocked);
215
+ validateOutputs(allOutputs);
216
+ }
217
+
218
+ function validateInputs(
219
+ uint256[] memory inputs,
220
+ bool inputsLocked
221
+ ) internal view virtual {
222
+ ZetoCommonStorage.layout().utxoStorage.validateInputs(
223
+ inputs,
224
+ inputsLocked
225
+ );
226
+ }
227
+
228
+ function validateOutputs(uint256[] memory outputs) internal view virtual {
229
+ ZetoCommonStorage.layout().utxoStorage.validateOutputs(outputs);
230
+ }
231
+
232
+ function validateRoot(uint256 root) internal view virtual {
233
+ ZetoCommonStorage.layout().utxoStorage.validateRoot(root);
234
+ }
235
+
236
+ function getRoot() public view virtual returns (uint256) {
237
+ return ZetoCommonStorage.layout().utxoStorage.getRoot();
238
+ }
239
+
240
+ function processInputsAndOutputs(
241
+ uint256[] memory inputs,
242
+ uint256[] memory outputs,
243
+ bool inputsLocked
244
+ ) internal virtual {
245
+ processInputs(inputs, inputsLocked);
246
+ processOutputs(outputs);
247
+ }
248
+
249
+ function processInputs(
250
+ uint256[] memory inputs,
251
+ bool inputsLocked
252
+ ) internal virtual {
253
+ ZetoCommonStorage.layout().utxoStorage.processInputs(
254
+ inputs,
255
+ inputsLocked
256
+ );
257
+ }
95
258
 
96
- return commitments;
259
+ function processOutputs(uint256[] memory outputs) internal virtual {
260
+ ZetoCommonStorage.layout().utxoStorage.processOutputs(outputs);
97
261
  }
98
- function sortCommitments(
99
- uint256[] memory utxos
100
- ) internal pure returns (uint256[] memory) {
101
- uint256[] memory sorted = new uint256[](utxos.length);
102
- for (uint256 i = 0; i < utxos.length; ++i) {
103
- sorted[i] = utxos[i];
262
+
263
+ /**
264
+ * @dev Forward freshly-minted locked outputs to storage.
265
+ *
266
+ * Callers reach this function only after `validateOutputs` has been
267
+ * invoked (via {validateTransactionProposal} in the lock-creation
268
+ * flow), which already rejects any output that is known to storage
269
+ * as locked or unlocked (revert {UTXOAlreadyOwned} /
270
+ * {UTXOAlreadySpent}). It is therefore an invariant at this point
271
+ * that none of the `lockedOutputs` already exist as locked.
272
+ *
273
+ * The storage layer no longer tracks who can spend a locked UTXO;
274
+ * the Zeto contract on top owns that state (e.g.
275
+ * `_locks[lockId].spender` in `ZetoFungible`-style lockable
276
+ * capabilities). Subclasses that implement a lock model are
277
+ * responsible for recording the spender for each locked output
278
+ * after calling this function.
279
+ */
280
+ function processLockedOutputs(
281
+ uint256[] memory lockedOutputs
282
+ ) internal virtual {
283
+ ZetoCommonStorage.layout().utxoStorage.processLockedOutputs(
284
+ lockedOutputs
285
+ );
286
+ }
287
+
288
+ /**
289
+ * @dev Verify a Groth16 proof against the appropriate verifier for the
290
+ * requested flavour (regular vs batch, locked-input vs unlocked).
291
+ *
292
+ * Reverts with {InvalidProof} on failure. The boolean return value
293
+ * is preserved for ABI compatibility with existing off-chain
294
+ * callers, and is always `true` when the call returns: a `false`
295
+ * verification result is never observed.
296
+ */
297
+ function verifyProof(
298
+ Commonlib.Proof memory proof,
299
+ uint256[] memory publicInputs,
300
+ bool isBatch,
301
+ bool inputsLocked
302
+ ) public view returns (bool) {
303
+ ZetoCommonStorage.Layout storage $ = ZetoCommonStorage.layout();
304
+ IGroth16Verifier verifier = inputsLocked
305
+ ? (isBatch ? $.batchLockVerifier : $.lockVerifier)
306
+ : (isBatch ? $.batchVerifier : $.verifier);
307
+ if (!verifier.verify(proof.pA, proof.pB, proof.pC, publicInputs)) {
308
+ revert InvalidProof();
309
+ }
310
+ return true;
311
+ }
312
+
313
+ function spent(uint256 utxo) public view returns (IZetoStorage.UTXOStatus) {
314
+ return ZetoCommonStorage.layout().utxoStorage.spent(utxo);
315
+ }
316
+
317
+ /**
318
+ * @dev Return whether `utxo` is currently locked, plus the address
319
+ * authorized to spend it.
320
+ *
321
+ * The base implementation returns `address(0)` for the spender
322
+ * because `ZetoCommon` itself does not implement any lock model.
323
+ * Subclasses that DO implement a lock model (e.g. `ZetoFungible`
324
+ * via `IZetoLockableCapability`) MUST override this to return the
325
+ * spender for the lock that owns `utxo`.
326
+ */
327
+ function locked(uint256 utxo) public view virtual returns (bool, address) {
328
+ return (
329
+ ZetoCommonStorage.layout().utxoStorage.locked(utxo),
330
+ address(0)
331
+ );
332
+ }
333
+ }
334
+
335
+ /// @dev ERC-7201 (`erc7201:zeto.storage.ZetoCommon`): namespaced state for this
336
+ /// abstract contract. Slot =
337
+ /// `keccak256(abi.encode(uint256(keccak256(bytes("zeto.storage.ZetoCommon"))) - 1)) & ~bytes32(uint256(0xff))`.
338
+ library ZetoCommonStorage {
339
+ struct Layout {
340
+ string tokenName;
341
+ string tokenSymbol;
342
+ IZetoStorage utxoStorage;
343
+ IGroth16Verifier verifier;
344
+ IGroth16Verifier batchVerifier;
345
+ IGroth16Verifier lockVerifier;
346
+ IGroth16Verifier batchLockVerifier;
347
+ }
348
+
349
+ bytes32 private constant STORAGE_LOCATION =
350
+ 0xa8e6638051295a10c620add524cf3f88cb1c178af3b129e4469afe38b68b5500;
351
+
352
+ function layout() internal pure returns (Layout storage $) {
353
+ assembly {
354
+ $.slot := STORAGE_LOCATION
104
355
  }
105
- sorted = Arrays.sort(sorted);
106
- return sorted;
107
356
  }
108
357
  }