@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.
- package/README.md +70 -162
- package/contracts/factory.sol +30 -34
- package/contracts/factory_upgradeable.sol +11 -7
- package/contracts/lib/common/util.sol +40 -0
- package/contracts/lib/interfaces/ILockableCapability.sol +318 -0
- package/contracts/lib/interfaces/{izeto.sol → IZeto.sol} +13 -1
- package/contracts/lib/interfaces/{izeto_initializable.sol → IZetoInitializable.sol} +14 -12
- package/contracts/lib/interfaces/{izeto_kyc.sol → IZetoKyc.sol} +3 -3
- package/contracts/lib/interfaces/IZetoLockableCapability.sol +237 -0
- package/contracts/lib/interfaces/IZetoStorage.sol +106 -0
- package/contracts/lib/interfaces/{izeto_lockable.sol → IZetoVerifier.sol} +8 -21
- package/contracts/lib/registry.sol +74 -26
- package/contracts/lib/storage/base.sol +210 -0
- package/contracts/lib/storage/nullifier.sol +166 -0
- package/contracts/lib/zeto_common.sol +277 -28
- package/contracts/lib/zeto_fungible.sol +451 -33
- package/contracts/lib/zeto_fungible_base.sol +69 -0
- package/contracts/lib/zeto_fungible_burn.sol +83 -53
- package/contracts/lib/zeto_fungible_burn_nullifier.sol +115 -72
- package/contracts/lib/zeto_fungible_nullifier.sol +167 -0
- package/contracts/lib/zeto_lockable.sol +613 -0
- package/contracts/lib/zeto_non_fungible.sol +236 -0
- package/contracts/lib/zeto_non_fungible_base.sol +61 -0
- package/contracts/lib/zeto_non_fungible_nullifier.sol +61 -0
- package/contracts/test/escrow1.sol +90 -34
- package/contracts/test/escrow2.sol +64 -29
- package/contracts/test/qurrency.sol +10 -2
- package/contracts/test/smt.sol +6 -1
- package/contracts/test/tendecimals.sol +14 -12
- package/contracts/verifiers/impl/anon.sol +189 -0
- package/contracts/verifiers/impl/anon_batch.sol +301 -0
- package/contracts/verifiers/impl/anon_enc.sol +266 -0
- package/contracts/verifiers/impl/anon_enc_batch.sol +602 -0
- package/contracts/verifiers/impl/anon_enc_nullifier.sol +287 -0
- package/contracts/verifiers/impl/anon_enc_nullifier_batch.sol +679 -0
- package/contracts/verifiers/impl/anon_enc_nullifier_kyc.sol +294 -0
- package/contracts/verifiers/impl/anon_enc_nullifier_kyc_batch.sol +686 -0
- package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation.sol +413 -0
- package/contracts/verifiers/impl/anon_enc_nullifier_non_repudiation_batch.sol +1141 -0
- package/contracts/verifiers/impl/anon_nullifier_kyc_transfer.sol +217 -0
- package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked.sol +196 -0
- package/contracts/verifiers/impl/anon_nullifier_kyc_transferLocked_batch.sol +308 -0
- package/contracts/verifiers/impl/anon_nullifier_kyc_transfer_batch.sol +385 -0
- package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer.sol +497 -0
- package/contracts/verifiers/impl/anon_nullifier_qurrency_transfer_batch.sol +1001 -0
- package/contracts/verifiers/{verifier_anon_nullifier_transferLocked.sol → impl/anon_nullifier_transfer.sol} +12 -19
- package/contracts/verifiers/{verifier_anon_nullifier_transferLocked_batch.sol → impl/anon_nullifier_transfer_batch.sol} +44 -51
- package/contracts/verifiers/impl/burn.sol +182 -0
- package/contracts/verifiers/impl/burn_batch.sol +238 -0
- package/contracts/verifiers/impl/burn_nullifier.sol +203 -0
- package/contracts/verifiers/impl/burn_nullifier_batch.sol +315 -0
- package/contracts/verifiers/impl/deposit.sol +182 -0
- package/contracts/verifiers/impl/deposit_kyc.sol +189 -0
- package/contracts/verifiers/impl/nf_anon.sol +175 -0
- package/contracts/verifiers/{verifier_nf_anon_nullifier_transferLocked.sol → impl/nf_anon_nullifier_transfer.sol} +6 -13
- package/contracts/verifiers/impl/withdraw.sol +189 -0
- package/contracts/verifiers/impl/withdraw_batch.sol +245 -0
- package/contracts/verifiers/impl/withdraw_nullifier.sol +210 -0
- package/contracts/verifiers/impl/withdraw_nullifier_batch.sol +322 -0
- package/contracts/verifiers/verifier_anon.sol +31 -186
- package/contracts/verifiers/verifier_anon_batch.sol +31 -298
- package/contracts/verifiers/verifier_anon_enc.sol +31 -263
- package/contracts/verifiers/verifier_anon_enc_batch.sol +31 -599
- package/contracts/verifiers/verifier_anon_enc_nullifier.sol +31 -284
- package/contracts/verifiers/verifier_anon_enc_nullifier_batch.sol +33 -676
- package/contracts/verifiers/verifier_anon_enc_nullifier_kyc.sol +31 -291
- package/contracts/verifiers/verifier_anon_enc_nullifier_kyc_batch.sol +33 -683
- package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation.sol +33 -410
- package/contracts/verifiers/verifier_anon_enc_nullifier_non_repudiation_batch.sol +33 -1138
- package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer.sol +33 -214
- package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked.sol +33 -221
- package/contracts/verifiers/verifier_anon_nullifier_kyc_transferLocked_batch.sol +33 -389
- package/contracts/verifiers/verifier_anon_nullifier_kyc_transfer_batch.sol +33 -382
- package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer.sol +33 -221
- package/contracts/verifiers/verifier_anon_nullifier_qurrency_transfer_batch.sol +33 -389
- package/contracts/verifiers/verifier_anon_nullifier_transfer.sol +33 -207
- package/contracts/verifiers/verifier_anon_nullifier_transfer_batch.sol +33 -375
- package/contracts/verifiers/verifier_burn.sol +31 -179
- package/contracts/verifiers/verifier_burn_batch.sol +31 -235
- package/contracts/verifiers/verifier_burn_nullifier.sol +31 -200
- package/contracts/verifiers/verifier_burn_nullifier_batch.sol +31 -312
- package/contracts/verifiers/verifier_deposit.sol +31 -179
- package/contracts/verifiers/verifier_deposit_kyc.sol +34 -0
- package/contracts/verifiers/verifier_nf_anon.sol +31 -172
- package/contracts/verifiers/verifier_nf_anon_nullifier_transfer.sol +33 -179
- package/contracts/verifiers/verifier_withdraw.sol +31 -186
- package/contracts/verifiers/verifier_withdraw_batch.sol +31 -242
- package/contracts/verifiers/verifier_withdraw_nullifier.sol +31 -207
- package/contracts/verifiers/verifier_withdraw_nullifier_batch.sol +33 -319
- package/contracts/zeto_anon.sol +77 -231
- package/contracts/zeto_anon_burnable.sol +56 -12
- package/contracts/zeto_anon_enc.sol +93 -190
- package/contracts/zeto_anon_enc_nullifier.sol +249 -195
- package/contracts/zeto_anon_enc_nullifier_kyc.sol +51 -232
- package/contracts/zeto_anon_enc_nullifier_non_repudiation.sol +231 -238
- package/contracts/zeto_anon_nullifier.sol +164 -298
- package/contracts/zeto_anon_nullifier_burnable.sol +68 -18
- package/contracts/zeto_anon_nullifier_kyc.sol +40 -345
- package/contracts/zeto_anon_nullifier_qurrency.sol +217 -361
- package/contracts/zeto_nf_anon.sol +55 -130
- package/contracts/zeto_nf_anon_nullifier.sol +90 -152
- package/hardhat.config.ts +9 -3
- package/ignition/modules/lib/deps.ts +8 -0
- package/ignition/modules/zeto_anon_burnable.ts +8 -7
- package/ignition/modules/zeto_anon_enc_nullifier.ts +31 -0
- package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +2 -2
- package/ignition/modules/zeto_anon_nullifier.ts +28 -4
- package/ignition/modules/zeto_anon_nullifier_burnable.ts +50 -16
- package/ignition/modules/zeto_anon_nullifier_kyc.ts +27 -12
- package/ignition/modules/zeto_nf_anon_nullifier.ts +14 -10
- package/package.json +4 -2
- package/scripts/deploy_cloneable.ts +19 -10
- package/scripts/deploy_upgradeable.ts +9 -5
- package/scripts/tokens/Zeto_Anon.ts +3 -3
- package/scripts/tokens/Zeto_AnonBurnable.ts +1 -1
- package/scripts/tokens/Zeto_AnonEnc.ts +12 -3
- package/scripts/tokens/Zeto_AnonEncNullifier.ts +5 -3
- package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +1 -1
- package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +1 -1
- package/scripts/tokens/Zeto_AnonNullifier.ts +1 -1
- package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +1 -1
- package/scripts/tokens/Zeto_AnonNullifierKyc.ts +1 -1
- package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +1 -1
- package/scripts/tokens/Zeto_NfAnon.ts +2 -2
- package/scripts/tokens/Zeto_NfAnonNullifier.ts +1 -1
- package/test/factory.ts +46 -73
- package/test/lib/anon_nullifier_helpers.ts +89 -0
- package/test/lib/anon_zeto_helpers.ts +76 -0
- package/test/lib/deploy.ts +3 -2
- package/test/lib/utils.ts +74 -35
- package/test/test/escrow1.ts +185 -58
- package/test/test/escrow2.ts +200 -107
- package/test/test/qurrency.ts +13 -33
- package/test/usdc-shielding.ts +39 -26
- package/test/utils.ts +144 -21
- package/test/zeto_anon.ts +956 -465
- package/test/zeto_anon_enc.ts +881 -142
- package/test/zeto_anon_enc_nullifier.ts +847 -38
- package/test/zeto_anon_enc_nullifier_kyc.ts +120 -181
- package/test/zeto_anon_enc_nullifier_non_repudiation.ts +77 -46
- package/test/zeto_anon_nullifier.ts +1212 -953
- package/test/zeto_anon_nullifier_kyc.ts +674 -655
- package/test/zeto_anon_nullifier_qurrency.ts +452 -306
- package/test/zeto_nf_anon.ts +737 -137
- package/test/zeto_nf_anon_nullifier.ts +876 -246
- package/contracts/lib/zeto_base.sol +0 -293
- package/contracts/lib/zeto_fungible_withdraw.sol +0 -132
- package/contracts/lib/zeto_fungible_withdraw_nullifier.sol +0 -144
- package/contracts/lib/zeto_nullifier.sol +0 -340
- package/contracts/zkDvP.sol_ +0 -273
- package/test/zkDvP.ts_ +0 -455
- /package/contracts/lib/{common.sol → common/common.sol} +0 -0
package/contracts/zeto_anon.sol
CHANGED
|
@@ -15,21 +15,11 @@
|
|
|
15
15
|
// limitations under the License.
|
|
16
16
|
pragma solidity ^0.8.27;
|
|
17
17
|
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
|
52
|
-
string
|
|
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
|
|
61
|
-
string
|
|
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
|
-
|
|
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
|
|
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
|
-
*
|
|
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
|
|
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
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
195
|
-
|
|
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 <
|
|
198
|
-
|
|
112
|
+
for (uint256 i = 0; i < outputs.length; i++) {
|
|
113
|
+
publicInputs[piIndex++] = outputs[i];
|
|
199
114
|
}
|
|
200
|
-
verifyProof(inputs, allOutputs, proof);
|
|
201
115
|
|
|
202
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
270
|
-
|
|
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
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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 {
|
|
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
|
-
|
|
24
|
-
|
|
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
|
-
/// @
|
|
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
|
|
36
|
-
string
|
|
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
|
-
|
|
43
|
-
|
|
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
|
}
|