@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
@@ -15,245 +15,299 @@
15
15
  // limitations under the License.
16
16
  pragma solidity ^0.8.27;
17
17
 
18
- import {IZeto} from "./lib/interfaces/izeto.sol";
19
- import {Groth16Verifier_Deposit} from "./verifiers/verifier_deposit.sol";
20
- import {Groth16Verifier_WithdrawNullifier} from "./verifiers/verifier_withdraw_nullifier.sol";
21
- import {Groth16Verifier_WithdrawNullifierBatch} from "./verifiers/verifier_withdraw_nullifier_batch.sol";
22
- import {Groth16Verifier_AnonEncNullifier} from "./verifiers/verifier_anon_enc_nullifier.sol";
23
- import {Groth16Verifier_AnonEncNullifierBatch} from "./verifiers/verifier_anon_enc_nullifier_batch.sol";
24
- import {ZetoNullifier} from "./lib/zeto_nullifier.sol";
25
- import {ZetoFungibleWithdrawWithNullifiers} from "./lib/zeto_fungible_withdraw_nullifier.sol";
26
- import {Commonlib} from "./lib/common.sol";
27
- import {IZetoInitializable} from "./lib/interfaces/izeto_initializable.sol";
28
- import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
18
+ import {Zeto_AnonNullifier} from "./zeto_anon_nullifier.sol";
19
+ import {Commonlib} from "./lib/common/common.sol";
20
+ import {IZetoInitializable} from "./lib/interfaces/IZetoInitializable.sol";
29
21
 
30
- uint256 constant INPUT_SIZE = 18;
31
- uint256 constant BATCH_INPUT_SIZE = 74;
32
-
33
- /// @title A sample implementation of a Zeto based fungible token with anonymity, encryption and history masking
22
+ /// @title A sample implementation of a Zeto based fungible token with
23
+ /// anonymity, encryption, and history masking via nullifiers.
34
24
  /// @author Kaleido, Inc.
25
+ /// @notice Decimals: this token uses **4** decimals, inherited from
26
+ /// {ZetoCommon.decimals}. Indexers and UIs reading this contract
27
+ /// directly should treat balances accordingly.
35
28
  /// @dev The proof has the following statements:
36
29
  /// - each value in the output commitments must be a positive number in the range 0 ~ (2\*\*40 - 1)
37
30
  /// - the sum of the nullified values match the sum of output values
38
31
  /// - the hashes in the input and output match the hash(value, salt, owner public key) formula
39
32
  /// - the sender possesses the private BabyJubjub key, whose public key is part of the pre-image of the input commitment hashes, which match the corresponding nullifiers
40
- /// - the encrypted value in the input is derived from the receiver's UTXO value and encrypted with a shared secret using the ECDH protocol between the sender and receiver (this guarantees data availability for the receiver)
33
+ /// - the encrypted value in the output is derived from the receiver's UTXO value and encrypted with a shared secret using the ECDH protocol between the sender and receiver
41
34
  /// - the nullifiers represent input commitments that are included in a Sparse Merkle Tree represented by the root hash
42
- contract Zeto_AnonEncNullifier is
43
- IZeto,
44
- IZetoInitializable,
45
- ZetoNullifier,
46
- ZetoFungibleWithdrawWithNullifiers,
47
- UUPSUpgradeable
48
- {
49
- Groth16Verifier_AnonEncNullifier internal _verifier;
50
- Groth16Verifier_AnonEncNullifierBatch internal _batchVerifier;
35
+ contract Zeto_AnonEncNullifier is Zeto_AnonNullifier {
36
+ /// @dev Decoded proof payload for one `constructPublicInputs` call lives in
37
+ /// {ZetoAnonEncNullifierStorage} (ERC-7201).
38
+
39
+ /// @dev Lock the implementation contract on construction. The parent
40
+ /// {Zeto_AnonNullifier} already does this via its own constructor
41
+ /// (which Solidity invokes as part of every leaf's deployment),
42
+ /// but we restate it here so the H-2 protection survives any
43
+ /// future refactor that changes the inheritance graph.
44
+ /// @custom:oz-upgrades-unsafe-allow constructor
45
+ constructor() {
46
+ _disableInitializers();
47
+ }
51
48
 
52
49
  function initialize(
53
- string memory name,
54
- string memory symbol,
50
+ string calldata name,
51
+ string calldata symbol,
55
52
  address initialOwner,
56
53
  IZetoInitializable.VerifiersInfo calldata verifiers
57
- ) public initializer {
58
- __ZetoNullifier_init(name, symbol, initialOwner);
59
- __ZetoFungibleWithdrawWithNullifiers_init(
60
- (Groth16Verifier_Deposit)(verifiers.depositVerifier),
61
- (Groth16Verifier_WithdrawNullifier)(verifiers.withdrawVerifier),
62
- (Groth16Verifier_WithdrawNullifierBatch)(
63
- verifiers.batchWithdrawVerifier
64
- )
65
- );
66
- _verifier = (Groth16Verifier_AnonEncNullifier)(verifiers.verifier);
67
- _batchVerifier = (Groth16Verifier_AnonEncNullifierBatch)(
68
- verifiers.batchVerifier
69
- );
54
+ ) public virtual override initializer {
55
+ __ZetoAnonEncNullifier_init(name, symbol, initialOwner, verifiers);
70
56
  }
71
57
 
72
- function _authorizeUpgrade(address) internal override onlyOwner {}
58
+ function __ZetoAnonEncNullifier_init(
59
+ string calldata name_,
60
+ string calldata symbol_,
61
+ address initialOwner,
62
+ IZetoInitializable.VerifiersInfo calldata verifiers
63
+ ) internal onlyInitializing {
64
+ __ZetoAnonNullifier_init(name_, symbol_, initialOwner, verifiers);
65
+ }
73
66
 
74
- function constructPublicInputs(
67
+ function emitTransferEvent(
75
68
  uint256[] memory nullifiers,
76
69
  uint256[] memory outputs,
77
- uint256 root,
78
- uint256 encryptionNonce,
79
- uint256[2] memory ecdhPublicKey,
80
- uint256[] memory encryptedValues,
81
- uint256 size
82
- ) internal pure returns (uint256[] memory publicInputs) {
83
- publicInputs = new uint256[](size);
84
- uint256 piIndex = 0;
85
- // copy the ecdh public key
86
- for (uint256 i = 0; i < ecdhPublicKey.length; ++i) {
87
- publicInputs[piIndex++] = ecdhPublicKey[i];
88
- }
89
- // copy the encrypted value, salt and parity bit
90
- for (uint256 i = 0; i < encryptedValues.length; ++i) {
91
- publicInputs[piIndex++] = encryptedValues[i];
92
- }
93
- // copy input commitments
94
- for (uint256 i = 0; i < nullifiers.length; i++) {
95
- publicInputs[piIndex++] = nullifiers[i];
96
- }
97
-
98
- // copy root
99
- publicInputs[piIndex++] = root;
100
-
101
- // populate enables
102
- for (uint256 i = 0; i < nullifiers.length; i++) {
103
- publicInputs[piIndex++] = (nullifiers[i] == 0) ? 0 : 1;
104
- }
105
-
106
- // copy output commitments
107
- for (uint256 i = 0; i < outputs.length; i++) {
108
- publicInputs[piIndex++] = outputs[i];
109
- }
110
-
111
- // copy encryption nonce
112
- publicInputs[piIndex++] = encryptionNonce;
113
- return publicInputs;
70
+ bytes memory proof,
71
+ bytes memory data
72
+ ) internal virtual override {
73
+ ZetoAnonEncNullifierStorage.DecodedProofEncNullifier memory dp;
74
+ (dp, ) = decodeProof_EncNullifier(proof);
75
+ emit UTXOTransferWithEncryptedValues(
76
+ nullifiers,
77
+ outputs,
78
+ dp.encryptionNonce,
79
+ dp.ecdhPublicKey,
80
+ dp.encryptedValues,
81
+ msg.sender,
82
+ data
83
+ );
114
84
  }
115
85
 
116
86
  /**
117
- * @dev the main function of the contract, which transfers values from one account (represented by Babyjubjub public keys)
118
- * to one or more receiver accounts (also represented by Babyjubjub public keys). One of the two nullifiers may be zero
119
- * if the transaction only needs one UTXO to be spent. Equally one of the two outputs may be zero if the transaction
120
- * only needs to create one new UTXO.
87
+ * @dev Layout of `proof` (ABI-encoded tuple):
88
+ * (uint256 root,
89
+ * uint256 encryptionNonce,
90
+ * uint256[2] ecdhPublicKey,
91
+ * uint256[] encryptedValues,
92
+ * Commonlib.Proof groth16Proof)
121
93
  *
122
- * @param nullifiers Array of nullifiers that are secretly bound to UTXOs to be spent by the transaction.
123
- * @param outputs Array of new UTXOs to generate, for future transactions to spend.
124
- * @param root The root hash of the Sparse Merkle Tree that contains the nullifiers.
125
- * @param proof A zero knowledge proof that the submitter is authorized to spend the inputs, and
126
- * that the outputs are valid in terms of obeying mass conservation rules.
127
- *
128
- * Emits a {UTXOTransferWithEncryptedValues} event.
94
+ * Root validation is performed here whenever inputs are unlocked
95
+ * so the proof bytes are decoded exactly once per transition
96
+ * (mirrors the L-4 cleanup applied to {Zeto_AnonNullifier}).
129
97
  */
130
- function transfer(
98
+ function constructPublicInputs(
131
99
  uint256[] memory nullifiers,
132
100
  uint256[] memory outputs,
133
- uint256 root,
134
- uint256 encryptionNonce,
135
- uint256[2] memory ecdhPublicKey,
136
- uint256[] memory encryptedValues,
137
- Commonlib.Proof calldata proof,
138
- bytes calldata data
139
- ) public returns (bool) {
140
- // Check and pad commitments
141
- nullifiers = checkAndPadCommitments(nullifiers);
142
- outputs = checkAndPadCommitments(outputs);
143
- validateTransactionProposal(nullifiers, outputs, root, false);
101
+ bytes memory proof,
102
+ bool inputsLocked
103
+ )
104
+ internal
105
+ virtual
106
+ override
107
+ returns (uint256[] memory, Commonlib.Proof memory)
108
+ {
109
+ (
110
+ ZetoAnonEncNullifierStorage.DecodedProofEncNullifier memory dp,
111
+ Commonlib.Proof memory proofStruct
112
+ ) = decodeProof_EncNullifier(proof);
144
113
 
145
- // Check the proof
146
- if (nullifiers.length > 2 || outputs.length > 2) {
147
- uint256[] memory publicInputs = constructPublicInputs(
148
- nullifiers,
149
- outputs,
150
- root,
151
- encryptionNonce,
152
- ecdhPublicKey,
153
- encryptedValues,
154
- BATCH_INPUT_SIZE
155
- );
156
- // construct the public inputs for batchVerifier
157
- uint256[BATCH_INPUT_SIZE] memory fixedSizeInputs;
158
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
159
- fixedSizeInputs[i] = publicInputs[i];
160
- }
114
+ if (!inputsLocked) {
115
+ validateRoot(dp.root);
116
+ }
117
+
118
+ ZetoAnonEncNullifierStorage.layout().dpe = dp;
119
+
120
+ uint256[] memory extra = extraInputs();
121
+ uint256 size = _calcSize_EncNullifier(
122
+ nullifiers,
123
+ outputs,
124
+ extra,
125
+ inputsLocked
126
+ );
161
127
 
162
- // Check the proof using batchVerifier
163
- require(
164
- _batchVerifier.verifyProof(
165
- proof.pA,
166
- proof.pB,
167
- proof.pC,
168
- fixedSizeInputs
169
- ),
170
- "Invalid proof (batch)"
128
+ uint256[] memory publicInputs = new uint256[](size);
129
+ _fillPublicInputs_EncNullifier(
130
+ publicInputs,
131
+ nullifiers,
132
+ outputs,
133
+ extra,
134
+ inputsLocked
135
+ );
136
+ return (publicInputs, proofStruct);
137
+ }
138
+
139
+ function decodeProof_EncNullifier(
140
+ bytes memory proof
141
+ )
142
+ private
143
+ pure
144
+ returns (
145
+ ZetoAnonEncNullifierStorage.DecodedProofEncNullifier memory,
146
+ Commonlib.Proof memory
147
+ )
148
+ {
149
+ (
150
+ uint256 root,
151
+ uint256 encryptionNonce,
152
+ uint256[2] memory ecdhPublicKey,
153
+ uint256[] memory encryptedValues,
154
+ Commonlib.Proof memory proofStruct
155
+ ) = abi.decode(
156
+ proof,
157
+ (uint256, uint256, uint256[2], uint256[], Commonlib.Proof)
171
158
  );
172
- } else {
173
- uint256[] memory publicInputs = constructPublicInputs(
174
- nullifiers,
175
- outputs,
159
+ return (
160
+ ZetoAnonEncNullifierStorage.DecodedProofEncNullifier(
176
161
  root,
177
162
  encryptionNonce,
178
163
  ecdhPublicKey,
179
- encryptedValues,
180
- INPUT_SIZE
164
+ encryptedValues
165
+ ),
166
+ proofStruct
167
+ );
168
+ }
169
+
170
+ /// @dev Public-inputs vector size. For unlocked spends the layout is
171
+ /// ecdhPublicKey ++ encryptedValues ++ nullifiers ++ root
172
+ /// ++ enabled-flags ++ extra ++ outputs ++ encryptionNonce
173
+ /// For locked-input spends the nullifier-history (root + flags)
174
+ /// portion of the witness is absent because locked inputs are
175
+ /// raw UTXOs, not nullifiers; the encryption commitments and the
176
+ /// output commitments still apply.
177
+ function _calcSize_EncNullifier(
178
+ uint256[] memory nullifiers,
179
+ uint256[] memory outputs,
180
+ uint256[] memory extra,
181
+ bool inputsLocked
182
+ ) internal view returns (uint256) {
183
+ if (inputsLocked) {
184
+ return
185
+ ZetoAnonEncNullifierStorage.layout().dpe.ecdhPublicKey.length +
186
+ ZetoAnonEncNullifierStorage.layout().dpe.encryptedValues.length +
187
+ nullifiers.length +
188
+ extra.length +
189
+ outputs.length +
190
+ 1; // encryptionNonce
191
+ }
192
+ return
193
+ ZetoAnonEncNullifierStorage.layout().dpe.ecdhPublicKey.length +
194
+ ZetoAnonEncNullifierStorage.layout().dpe.encryptedValues.length +
195
+ (nullifiers.length * 2) + // nullifiers + enabled flags
196
+ 1 + // root
197
+ extra.length +
198
+ outputs.length +
199
+ 1; // encryptionNonce
200
+ }
201
+
202
+ function _fillPublicInputs_EncNullifier(
203
+ uint256[] memory publicInputs,
204
+ uint256[] memory nullifiers,
205
+ uint256[] memory outputs,
206
+ uint256[] memory extra,
207
+ bool inputsLocked
208
+ ) internal view {
209
+ uint256 piIndex = 0;
210
+ piIndex = _fillEcdhAndEncrypted(publicInputs, piIndex);
211
+ if (!inputsLocked) {
212
+ piIndex = _fillNullifiersAndRoot(publicInputs, nullifiers, piIndex);
213
+ piIndex = _fillEnablesAndExtra(
214
+ publicInputs,
215
+ nullifiers,
216
+ extra,
217
+ piIndex
181
218
  );
182
- // construct the public inputs for verifier
183
- uint256[INPUT_SIZE] memory fixedSizeInputs;
184
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
185
- fixedSizeInputs[i] = publicInputs[i];
219
+ } else {
220
+ for (uint256 i = 0; i < nullifiers.length; i++) {
221
+ publicInputs[piIndex++] = nullifiers[i];
222
+ }
223
+ for (uint256 i = 0; i < extra.length; i++) {
224
+ publicInputs[piIndex++] = extra[i];
186
225
  }
187
- // Check the proof
188
- require(
189
- _verifier.verifyProof(
190
- proof.pA,
191
- proof.pB,
192
- proof.pC,
193
- fixedSizeInputs
194
- ),
195
- "Invalid proof"
196
- );
197
226
  }
227
+ _fillOutputsAndNonce(publicInputs, outputs, piIndex);
228
+ }
198
229
 
199
- // accept the transaction to consume the input UTXOs and produce new UTXOs
200
- uint256[] memory empty;
201
- processInputsAndOutputs(nullifiers, outputs, empty, address(0));
230
+ function _fillEcdhAndEncrypted(
231
+ uint256[] memory publicInputs,
232
+ uint256 piIndex
233
+ ) internal view returns (uint256) {
234
+ for (uint256 i = 0; i < ZetoAnonEncNullifierStorage.layout().dpe.ecdhPublicKey.length; ++i) {
235
+ publicInputs[piIndex++] = ZetoAnonEncNullifierStorage.layout().dpe.ecdhPublicKey[i];
236
+ }
237
+ for (uint256 i = 0; i < ZetoAnonEncNullifierStorage.layout().dpe.encryptedValues.length; ++i) {
238
+ publicInputs[piIndex++] = ZetoAnonEncNullifierStorage.layout().dpe.encryptedValues[i];
239
+ }
240
+ return piIndex;
241
+ }
202
242
 
203
- uint256[] memory encryptedValuesArray = new uint256[](
204
- encryptedValues.length
205
- );
206
- for (uint256 i = 0; i < encryptedValues.length; ++i) {
207
- encryptedValuesArray[i] = encryptedValues[i];
243
+ function _fillNullifiersAndRoot(
244
+ uint256[] memory publicInputs,
245
+ uint256[] memory nullifiers,
246
+ uint256 piIndex
247
+ ) internal view returns (uint256) {
248
+ for (uint256 i = 0; i < nullifiers.length; i++) {
249
+ publicInputs[piIndex++] = nullifiers[i];
208
250
  }
251
+ publicInputs[piIndex++] = ZetoAnonEncNullifierStorage.layout().dpe.root;
252
+ return piIndex;
253
+ }
209
254
 
210
- emit UTXOTransferWithEncryptedValues(
211
- nullifiers,
212
- outputs,
213
- encryptionNonce,
214
- ecdhPublicKey,
215
- encryptedValuesArray,
216
- msg.sender,
217
- data
218
- );
219
- return true;
255
+ function _fillEnablesAndExtra(
256
+ uint256[] memory publicInputs,
257
+ uint256[] memory nullifiers,
258
+ uint256[] memory extra,
259
+ uint256 piIndex
260
+ ) internal pure returns (uint256) {
261
+ for (uint256 i = 0; i < nullifiers.length; i++) {
262
+ publicInputs[piIndex++] = (nullifiers[i] == 0) ? 0 : 1;
263
+ }
264
+ for (uint256 i = 0; i < extra.length; i++) {
265
+ publicInputs[piIndex++] = extra[i];
266
+ }
267
+ return piIndex;
220
268
  }
221
269
 
222
- function deposit(
223
- uint256 amount,
270
+ function _fillOutputsAndNonce(
271
+ uint256[] memory publicInputs,
224
272
  uint256[] memory outputs,
225
- Commonlib.Proof calldata proof,
226
- bytes calldata data
227
- ) public {
228
- _deposit(amount, outputs, proof);
229
- _mint(outputs, data);
273
+ uint256 piIndex
274
+ ) internal view {
275
+ for (uint256 i = 0; i < outputs.length; i++) {
276
+ publicInputs[piIndex++] = outputs[i];
277
+ }
278
+ publicInputs[piIndex++] = ZetoAnonEncNullifierStorage.layout().dpe.encryptionNonce;
230
279
  }
231
280
 
232
- function withdraw(
233
- uint256 amount,
234
- uint256[] memory nullifiers,
235
- uint256 output,
236
- uint256 root,
237
- Commonlib.Proof calldata proof,
238
- bytes calldata data
239
- ) public {
240
- uint256[] memory outputs = new uint256[](nullifiers.length);
241
- outputs[0] = output;
242
- // Check and pad commitments
243
- nullifiers = checkAndPadCommitments(nullifiers);
244
- outputs = checkAndPadCommitments(outputs);
245
- validateTransactionProposal(nullifiers, outputs, root, false);
281
+ function extraInputs()
282
+ internal
283
+ view
284
+ virtual
285
+ override
286
+ returns (uint256[] memory)
287
+ {
288
+ return new uint256[](0);
289
+ }
290
+ }
291
+
292
+ /// @dev ERC-7201 (`erc7201:zeto.storage.Zeto_AnonEncNullifier`).
293
+ library ZetoAnonEncNullifierStorage {
294
+ struct DecodedProofEncNullifier {
295
+ uint256 root;
296
+ uint256 encryptionNonce;
297
+ uint256[2] ecdhPublicKey;
298
+ uint256[] encryptedValues;
299
+ }
246
300
 
247
- _withdrawWithNullifiers(amount, nullifiers, output, root, proof);
248
- uint256[] memory empty;
249
- processInputsAndOutputs(nullifiers, outputs, empty, address(0));
250
- emit UTXOWithdraw(amount, nullifiers, output, msg.sender, data);
301
+ struct Layout {
302
+ DecodedProofEncNullifier dpe;
251
303
  }
252
304
 
253
- function mint(
254
- uint256[] memory utxos,
255
- bytes calldata data
256
- ) public onlyOwner {
257
- _mint(utxos, data);
305
+ bytes32 private constant STORAGE_LOCATION =
306
+ 0x36fc6ea34fa875375a7d6586407c2399b00c74acd3ef1f71bd14e60259234b00;
307
+
308
+ function layout() internal pure returns (Layout storage $) {
309
+ assembly {
310
+ $.slot := STORAGE_LOCATION
311
+ }
258
312
  }
259
313
  }