@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,21 +15,11 @@
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_Withdraw} from "./verifiers/verifier_withdraw.sol";
21
- import {Groth16Verifier_WithdrawBatch} from "./verifiers/verifier_withdraw_batch.sol";
22
- import {Groth16Verifier_Anon} from "./verifiers/verifier_anon.sol";
23
- import {Groth16Verifier_AnonBatch} from "./verifiers/verifier_anon_batch.sol";
24
- import {Commonlib} from "./lib/common.sol";
25
- import {ZetoBase} from "./lib/zeto_base.sol";
26
- import {IZetoInitializable} from "./lib/interfaces/izeto_initializable.sol";
27
- import {ZetoFungibleWithdraw} from "./lib/zeto_fungible_withdraw.sol";
18
+ import {ZetoFungibleBase} from "./lib/zeto_fungible_base.sol";
19
+ import {Commonlib} from "./lib/common/common.sol";
20
+ import {IZetoInitializable} from "./lib/interfaces/IZetoInitializable.sol";
28
21
  import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
29
22
 
30
- uint256 constant INPUT_SIZE = 4;
31
- uint256 constant BATCH_INPUT_SIZE = 20;
32
-
33
23
  /// @title A sample implementation of a Zeto based fungible token with anonymity and no encryption
34
24
  /// @author Kaleido, Inc.
35
25
  /// @dev The proof has the following statements:
@@ -37,252 +27,108 @@ uint256 constant BATCH_INPUT_SIZE = 20;
37
27
  /// - the sum of the input values match the sum of output values
38
28
  /// - the hashes in the input and output match the `hash(value, salt, owner public key)` formula
39
29
  /// - the sender possesses the private BabyJubjub key, whose public key is part of the pre-image of the input commitment hashes
40
- contract Zeto_Anon is
41
- IZeto,
42
- IZetoInitializable,
43
- ZetoBase,
44
- ZetoFungibleWithdraw,
45
- UUPSUpgradeable
46
- {
47
- Groth16Verifier_Anon internal _verifier;
48
- Groth16Verifier_AnonBatch internal _batchVerifier;
30
+ ///
31
+ /// Implements the {IZetoLockableCapability} lifecycle (createLock /
32
+ /// updateLock / delegateLock / spendLock / cancelLock) by inheriting
33
+ /// {ZetoFungibleBase}, the non-nullifier sibling of
34
+ /// {ZetoFungibleNullifier}. Both siblings funnel locked-input spends
35
+ /// through the same `constructPublicInputs(_, _, _, inputsLocked=true)`
36
+ /// hook implemented below; for the anon (non-nullifier) circuit the
37
+ /// proof and public-input layout is identical regardless of
38
+ /// `inputsLocked`, since neither a nullifier merkle root nor an
39
+ /// enabled-flags vector is part of the witness.
40
+ /// @notice Decimals: this token uses **4** decimals, inherited from
41
+ /// {ZetoCommon.decimals}. Indexers and UIs reading this contract
42
+ /// directly should treat balances accordingly.
43
+ /// @custom:storage erc7201:zeto.storage.Zeto_Anon — extend {ZetoAnonStorage.Layout} on upgrade (library below).
44
+ contract Zeto_Anon is ZetoFungibleBase, UUPSUpgradeable {
45
+ /// @dev Lock the implementation contract on construction so that
46
+ /// {initialize} can only ever run on a proxy. Without this,
47
+ /// anyone could call {initialize} directly on the deployed
48
+ /// implementation, become its owner, and then `upgradeTo(any)`
49
+ /// via {_authorizeUpgrade} (the OZ "implementation takeover"
50
+ /// pattern, CVE-2022-35961 family). See OpenZeppelin's
51
+ /// `Initializable._disableInitializers` for the rationale.
52
+ /// @custom:oz-upgrades-unsafe-allow constructor
53
+ constructor() {
54
+ _disableInitializers();
55
+ }
49
56
 
50
57
  function initialize(
51
- string memory name,
52
- string memory symbol,
58
+ string calldata name,
59
+ string calldata symbol,
53
60
  address initialOwner,
54
- VerifiersInfo calldata verifiers
61
+ IZetoInitializable.VerifiersInfo calldata verifiers
55
62
  ) public virtual initializer {
56
63
  __ZetoAnon_init(name, symbol, initialOwner, verifiers);
57
64
  }
58
65
 
59
66
  function __ZetoAnon_init(
60
- string memory name_,
61
- string memory symbol_,
67
+ string calldata name_,
68
+ string calldata symbol_,
62
69
  address initialOwner,
63
- VerifiersInfo calldata verifiers
70
+ IZetoInitializable.VerifiersInfo calldata verifiers
64
71
  ) internal onlyInitializing {
65
- __ZetoBase_init(name_, symbol_, initialOwner);
66
- __ZetoFungibleWithdraw_init(
67
- (Groth16Verifier_Deposit)(verifiers.depositVerifier),
68
- (Groth16Verifier_Withdraw)(verifiers.withdrawVerifier),
69
- (Groth16Verifier_WithdrawBatch)(verifiers.batchWithdrawVerifier)
70
- );
71
- _verifier = (Groth16Verifier_Anon)(verifiers.verifier);
72
- _batchVerifier = (Groth16Verifier_AnonBatch)(verifiers.batchVerifier);
72
+ __ZetoFungibleBase_init(name_, symbol_, initialOwner, verifiers);
73
73
  }
74
74
 
75
75
  function _authorizeUpgrade(address) internal override onlyOwner {}
76
76
 
77
77
  /**
78
- * @dev transfer funds by spending the input UTXOs (owned by the sender) and creating
79
- * output UTXOs (owned by the receiver). Some of the output UTXOs may be owned by the
80
- * sender, to return the change.
81
- *
82
- * @param inputs Array of UTXOs to be spent by the transaction. They must be unlocked.
83
- * @param outputs Array of new UTXOs to generate, for future transactions to spend.
84
- * @param proof A zero knowledge proof that the submitter is authorized to spend the inputs, and
85
- * that the outputs are valid in terms of obeying mass conservation rules.
86
- *
87
- * Emits a {UTXOTransfer} event.
88
- */
89
- function transfer(
90
- uint256[] memory inputs,
91
- uint256[] memory outputs,
92
- Commonlib.Proof calldata proof,
93
- bytes calldata data
94
- ) public returns (bool) {
95
- // Check and pad inputs and outputs based on the max size
96
- inputs = checkAndPadCommitments(inputs);
97
- outputs = checkAndPadCommitments(outputs);
98
-
99
- uint256[] memory lockedOutputs;
100
- validateTransactionProposal(inputs, outputs, lockedOutputs, false);
101
- verifyProof(inputs, outputs, proof);
102
-
103
- processInputsAndOutputs(inputs, outputs, lockedOutputs, false);
104
- emit UTXOTransfer(inputs, outputs, msg.sender, data);
105
-
106
- return true;
107
- }
108
-
109
- /**
110
- * @dev transfer funds that have been previously locked by the sender. The submitted must
111
- * be the current delegate of the locked UTXOs.
112
- *
113
- * @param inputs Array of UTXOs to be spent by the transaction, they must be locked.
114
- * @param outputs Array of new UTXOs to generate, for future transactions to spend. They are unlocked.
115
- * @param proof A zero knowledge proof that the submitter is authorized to spend the inputs, and
116
- * that the outputs are valid in terms of obeying mass conservation rules.
78
+ * @dev Construct the public-inputs vector for the anon circuit.
117
79
  *
118
- * Emits a {UTXOTransfer} event.
80
+ * For Zeto_Anon the proof layout is the same in both the unlocked
81
+ * `transfer` flow and the locked-input `_transferLocked` flow that
82
+ * runs inside {spendLock} and {cancelLock}: the witness is just
83
+ * `inputs ++ outputs`. We therefore ignore `inputsLocked` here and
84
+ * let `ZetoCommon.verifyProof` pick the right verifier
85
+ * (`_verifier` vs `_lockVerifier`) based on the same flag. The two
86
+ * verifiers are typically wired to the same Groth16 verifier
87
+ * contract for this token (see scripts/tokens/Zeto_Anon.ts) so the
88
+ * flag is purely a routing concern at this layer.
119
89
  */
120
- function transferLocked(
121
- uint256[] memory inputs,
122
- uint256[] memory outputs,
123
- Commonlib.Proof calldata proof,
124
- bytes calldata data
125
- ) public returns (bool) {
126
- // Check and pad inputs and outputs based on the max size
127
- inputs = checkAndPadCommitments(inputs);
128
- outputs = checkAndPadCommitments(outputs);
129
-
130
- uint256[] memory lockedOutputs;
131
- validateTransactionProposal(inputs, outputs, lockedOutputs, true);
132
-
133
- // Check the proof
134
- verifyProof(inputs, outputs, proof);
135
-
136
- processInputsAndOutputs(inputs, outputs, lockedOutputs, false);
137
- emit UTXOTransfer(inputs, outputs, msg.sender, data);
138
-
139
- return true;
140
- }
141
-
142
- function deposit(
143
- uint256 amount,
144
- uint256[] memory outputs,
145
- Commonlib.Proof calldata proof,
146
- bytes calldata data
147
- ) public {
148
- _deposit(amount, outputs, proof);
149
- _mint(outputs, data);
150
- }
151
-
152
- function withdraw(
153
- uint256 amount,
154
- uint256[] memory inputs,
155
- uint256 output,
156
- Commonlib.Proof calldata proof,
157
- bytes calldata data
158
- ) public {
159
- // Check and pad inputs and outputs based on the max size
160
- uint256[] memory outputs = new uint256[](inputs.length);
161
- outputs[0] = output;
162
- inputs = checkAndPadCommitments(inputs);
163
- outputs = checkAndPadCommitments(outputs);
164
- uint256[] memory lockedOutputs;
165
- validateTransactionProposal(inputs, outputs, lockedOutputs, false);
166
-
167
- _withdraw(amount, inputs, output, proof);
168
- processInputsAndOutputs(inputs, outputs, lockedOutputs, false);
169
- emit UTXOWithdraw(amount, inputs, output, msg.sender, data);
170
- }
171
-
172
- function mint(
173
- uint256[] memory utxos,
174
- bytes calldata data
175
- ) public onlyOwner {
176
- _mint(utxos, data);
177
- }
178
-
179
- function lock(
90
+ function constructPublicInputs(
180
91
  uint256[] memory inputs,
181
92
  uint256[] memory outputs,
182
- uint256[] memory lockedOutputs,
183
- Commonlib.Proof calldata proof,
184
- address delegate,
185
- bytes calldata data
186
- ) public {
187
- validateTransactionProposal(inputs, outputs, lockedOutputs, false);
188
-
189
- // Check the proof
190
- // merge the outputs and lockedOutputs and do a regular transfer
191
- uint256[] memory allOutputs = new uint256[](
192
- outputs.length + lockedOutputs.length
93
+ bytes memory proof,
94
+ bool /* inputsLocked */
95
+ )
96
+ internal
97
+ view
98
+ virtual
99
+ override
100
+ returns (uint256[] memory, Commonlib.Proof memory)
101
+ {
102
+ Commonlib.Proof memory proofStruct = abi.decode(
103
+ proof,
104
+ (Commonlib.Proof)
193
105
  );
194
- for (uint256 i = 0; i < outputs.length; i++) {
195
- allOutputs[i] = outputs[i];
106
+ uint256 size = inputs.length + outputs.length;
107
+ uint256[] memory publicInputs = new uint256[](size);
108
+ uint256 piIndex = 0;
109
+ for (uint256 i = 0; i < inputs.length; i++) {
110
+ publicInputs[piIndex++] = inputs[i];
196
111
  }
197
- for (uint256 i = 0; i < lockedOutputs.length; i++) {
198
- allOutputs[outputs.length + i] = lockedOutputs[i];
112
+ for (uint256 i = 0; i < outputs.length; i++) {
113
+ publicInputs[piIndex++] = outputs[i];
199
114
  }
200
- verifyProof(inputs, allOutputs, proof);
201
115
 
202
- processInputsAndOutputs(inputs, outputs, lockedOutputs, false);
203
-
204
- // lock the intended outputs
205
- _lock(inputs, outputs, lockedOutputs, delegate, data);
206
- }
207
-
208
- function unlock(
209
- uint256[] memory inputs,
210
- uint256[] memory outputs,
211
- Commonlib.Proof calldata proof,
212
- bytes calldata data
213
- ) public {
214
- transferLocked(inputs, outputs, proof, data);
116
+ return (publicInputs, proofStruct);
215
117
  }
118
+ }
216
119
 
217
- function verifyProof(
218
- uint256[] memory inputs,
219
- uint256[] memory outputs,
220
- Commonlib.Proof calldata proof
221
- ) public view returns (bool) {
222
- if (inputs.length > 2 || outputs.length > 2) {
223
- uint256[] memory publicInputs = constructPublicInputs(
224
- inputs,
225
- outputs,
226
- BATCH_INPUT_SIZE
227
- );
228
- // construct the public inputs for batchVerifier
229
- uint256[BATCH_INPUT_SIZE] memory fixedSizeInputs;
230
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
231
- fixedSizeInputs[i] = publicInputs[i];
232
- }
233
-
234
- // Check the proof using batchVerifier
235
- require(
236
- _batchVerifier.verifyProof(
237
- proof.pA,
238
- proof.pB,
239
- proof.pC,
240
- fixedSizeInputs
241
- ),
242
- "Invalid proof (batch)"
243
- );
244
- } else {
245
- uint256[] memory publicInputs = constructPublicInputs(
246
- inputs,
247
- outputs,
248
- INPUT_SIZE
249
- );
250
- // construct the public inputs for verifier
251
- uint256[INPUT_SIZE] memory fixedSizeInputs;
252
- for (uint256 i = 0; i < fixedSizeInputs.length; i++) {
253
- fixedSizeInputs[i] = publicInputs[i];
254
- }
255
- // Check the proof
256
- require(
257
- _verifier.verifyProof(
258
- proof.pA,
259
- proof.pB,
260
- proof.pC,
261
- fixedSizeInputs
262
- ),
263
- "Invalid proof"
264
- );
265
- }
266
- return true;
120
+ /// @dev ERC-7201 (`erc7201:zeto.storage.Zeto_Anon`): reserved for leaf-only state.
121
+ library ZetoAnonStorage {
122
+ struct Layout {
123
+ uint256 __reserved;
267
124
  }
268
125
 
269
- function constructPublicInputs(
270
- uint256[] memory inputs,
271
- uint256[] memory outputs,
272
- uint256 size
273
- ) internal pure returns (uint256[] memory publicInputs) {
274
- publicInputs = new uint256[](size);
275
- uint256 piIndex = 0;
276
- // copy input commitments
277
- for (uint256 i = 0; i < inputs.length; i++) {
278
- publicInputs[piIndex++] = inputs[i];
279
- }
126
+ bytes32 private constant STORAGE_LOCATION =
127
+ 0x55dc1d3a15de9f45cbdb6ca703ca412b79d40234f2782d90869f053dd2e9ef00;
280
128
 
281
- // copy output commitments
282
- for (uint256 i = 0; i < outputs.length; i++) {
283
- publicInputs[piIndex++] = outputs[i];
129
+ function layout() internal pure returns (Layout storage $) {
130
+ assembly {
131
+ $.slot := STORAGE_LOCATION
284
132
  }
285
-
286
- return publicInputs;
287
133
  }
288
134
  }
@@ -15,32 +15,76 @@
15
15
  // limitations under the License.
16
16
  pragma solidity ^0.8.27;
17
17
 
18
- import {Groth16Verifier_Burn} from "./verifiers/verifier_burn.sol";
19
- import {Groth16Verifier_BurnBatch} from "./verifiers/verifier_burn_batch.sol";
18
+ import {IZetoInitializable} from "./lib/interfaces/IZetoInitializable.sol";
20
19
  import {Zeto_Anon} from "./zeto_anon.sol";
21
20
  import {ZetoFungibleBurnable} from "./lib/zeto_fungible_burn.sol";
21
+ import {Commonlib} from "./lib/common/common.sol";
22
+ import {ZetoCommon} from "./lib/zeto_common.sol";
22
23
 
23
- uint256 constant INPUT_SIZE = 4;
24
- uint256 constant BATCH_INPUT_SIZE = 20;
25
-
26
- /// @title A sample implementation of a Zeto based fungible token with anonymity and no encryption
24
+ /// @title A sample implementation of a Zeto based fungible token with
25
+ /// anonymity, no encryption, and {burn} support.
27
26
  /// @author Kaleido, Inc.
28
- /// @dev The proof has the following statements:
27
+ /// @notice Decimals: this token uses **4** decimals, inherited from
28
+ /// {ZetoCommon.decimals}. Indexers and UIs reading this contract
29
+ /// directly should treat balances accordingly.
30
+ /// @dev The transfer proof has the following statements:
29
31
  /// - each value in the output commitments must be a positive number in the range 0 ~ (2\*\*40 - 1)
30
32
  /// - the sum of the input values match the sum of output values
31
33
  /// - the hashes in the input and output match the `hash(value, salt, owner public key)` formula
32
34
  /// - the sender possesses the private BabyJubjub key, whose public key is part of the pre-image of the input commitment hashes
35
+ ///
36
+ /// The burn proof has the analogous statements with the output side
37
+ /// collapsed to a single remainder commitment.
38
+ ///
39
+ /// Composes {Zeto_Anon} (transfer + lock lifecycle) with
40
+ /// {ZetoFungibleBurnable} (burn entry point). Both base paths converge
41
+ /// on the abstract {ZetoCommon.constructPublicInputs} hook, so this
42
+ /// leaf contract must explicitly disambiguate the override; it simply
43
+ /// forwards to {Zeto_Anon}'s implementation, which is the same proof
44
+ /// layout used for both unlocked transfers and the locked-input spend
45
+ /// flow inherited from {ZetoFungible}.
46
+ ///
47
+ /// Unlike the pre-{ILockableCapability} version, there is no longer a
48
+ /// separate `constructPublicInputsForLock` hook to override; the lock
49
+ /// lifecycle now reuses {constructPublicInputs} with `inputsLocked = true`.
33
50
  contract Zeto_AnonBurnable is Zeto_Anon, ZetoFungibleBurnable {
51
+ /// @dev Lock the implementation contract on construction. The parent
52
+ /// {Zeto_Anon} already does this via its own constructor (which
53
+ /// Solidity invokes as part of every leaf's deployment), but we
54
+ /// restate it here so the H-2 protection survives any future
55
+ /// refactor that changes the inheritance graph.
56
+ /// `_disableInitializers()` is idempotent, so the duplicate call
57
+ /// is a harmless no-op.
58
+ /// @custom:oz-upgrades-unsafe-allow constructor
59
+ constructor() {
60
+ _disableInitializers();
61
+ }
62
+
34
63
  function initialize(
35
- string memory name,
36
- string memory symbol,
64
+ string calldata name,
65
+ string calldata symbol,
37
66
  address initialOwner,
38
- VerifiersInfo calldata verifiers
67
+ IZetoInitializable.VerifiersInfo calldata verifiers
39
68
  ) public override initializer {
40
69
  __ZetoAnon_init(name, symbol, initialOwner, verifiers);
41
70
  __ZetoFungibleBurnable_init(
42
- (Groth16Verifier_Burn)(verifiers.burnVerifier),
43
- (Groth16Verifier_BurnBatch)(verifiers.batchBurnVerifier)
71
+ verifiers.burnVerifier,
72
+ verifiers.batchBurnVerifier
44
73
  );
45
74
  }
75
+
76
+ function constructPublicInputs(
77
+ uint256[] memory inputs,
78
+ uint256[] memory outputs,
79
+ bytes memory proof,
80
+ bool isLocked
81
+ )
82
+ internal
83
+ view
84
+ override(Zeto_Anon, ZetoCommon)
85
+ returns (uint256[] memory, Commonlib.Proof memory)
86
+ {
87
+ return
88
+ Zeto_Anon.constructPublicInputs(inputs, outputs, proof, isLocked);
89
+ }
46
90
  }