@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,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
  }