@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.
- package/README.md +76 -162
- package/config/eip170.ts +30 -0
- 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/IZetoLockHooks.sol +42 -0
- 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 +443 -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 +219 -0
- package/contracts/lib/zeto_lockable_lib.sol +460 -0
- package/contracts/lib/zeto_lockable_storage.sol +43 -0
- package/contracts/lib/zeto_non_fungible.sol +228 -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 +18 -3
- package/ignition/modules/lib/deps.ts +13 -0
- package/ignition/modules/test/tendecimals.ts +7 -1
- package/ignition/modules/zeto_anon.ts +3 -0
- package/ignition/modules/zeto_anon_burnable.ts +11 -7
- package/ignition/modules/zeto_anon_enc.ts +3 -0
- package/ignition/modules/zeto_anon_enc_nullifier.ts +34 -0
- package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +5 -2
- package/ignition/modules/zeto_anon_enc_nullifier_non_repudiation.ts +3 -0
- package/ignition/modules/zeto_anon_nullifier.ts +31 -4
- package/ignition/modules/zeto_anon_nullifier_burnable.ts +53 -16
- package/ignition/modules/zeto_anon_nullifier_kyc.ts +30 -12
- package/ignition/modules/zeto_anon_nullifier_qurrency.ts +3 -0
- package/ignition/modules/zeto_nf_anon.ts +3 -1
- package/ignition/modules/zeto_nf_anon_nullifier.ts +17 -12
- package/package.json +7 -3
- package/scripts/deploy_cloneable.ts +19 -10
- package/scripts/deploy_upgradeable.ts +9 -5
- package/scripts/lib/zeto_libraries.ts +47 -0
- package/scripts/tokens/Zeto_Anon.ts +6 -3
- package/scripts/tokens/Zeto_AnonBurnable.ts +4 -1
- package/scripts/tokens/Zeto_AnonEnc.ts +15 -3
- package/scripts/tokens/Zeto_AnonEncNullifier.ts +11 -8
- package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +7 -6
- package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +7 -6
- package/scripts/tokens/Zeto_AnonNullifier.ts +7 -6
- package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +7 -6
- package/scripts/tokens/Zeto_AnonNullifierKyc.ts +7 -6
- package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +7 -8
- package/scripts/tokens/Zeto_NfAnon.ts +5 -3
- package/scripts/tokens/Zeto_NfAnonNullifier.ts +7 -7
- package/test/factory.ts +55 -73
- package/test/lib/anon_nullifier_helpers.ts +89 -0
- package/test/lib/anon_zeto_helpers.ts +76 -0
- package/test/lib/deploy.ts +5 -2
- package/test/lib/eip170.ts +23 -0
- 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 -27
- package/test/utils.ts +144 -21
- package/test/zeto_anon.ts +956 -465
- package/test/zeto_anon_enc.ts +881 -143
- package/test/zeto_anon_enc_nullifier.ts +850 -39
- package/test/zeto_anon_enc_nullifier_kyc.ts +123 -182
- package/test/zeto_anon_enc_nullifier_non_repudiation.ts +80 -47
- package/test/zeto_anon_nullifier.ts +1212 -954
- package/test/zeto_anon_nullifier_kyc.ts +677 -656
- package/test/zeto_anon_nullifier_qurrency.ts +455 -307
- package/test/zeto_nf_anon.ts +737 -138
- package/test/zeto_nf_anon_nullifier.ts +876 -247
- 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
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
// Copyright © 2024 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
pragma solidity ^0.8.27;
|
|
17
|
+
|
|
18
|
+
import {IZetoLockableCapability} from "./interfaces/IZetoLockableCapability.sol";
|
|
19
|
+
import {IZetoLockHooks} from "./interfaces/IZetoLockHooks.sol";
|
|
20
|
+
import {ILockableCapability} from "./interfaces/ILockableCapability.sol";
|
|
21
|
+
import {ZetoCommon} from "./zeto_common.sol";
|
|
22
|
+
import {ZetoLockableLib} from "./zeto_lockable_lib.sol";
|
|
23
|
+
|
|
24
|
+
/// @title ZetoLockable
|
|
25
|
+
/// @author Kaleido, Inc.
|
|
26
|
+
/// @dev Thin embedding layer for {IZetoLockableCapability}. Shared lock
|
|
27
|
+
/// lifecycle logic lives in the linked external {ZetoLockableLib};
|
|
28
|
+
/// this contract forwards interface entry points to the library and
|
|
29
|
+
/// exposes {IZetoLockHooks} callbacks for circuit-specific work in
|
|
30
|
+
/// descendants ({ZetoFungible}, {ZetoNonFungible}).
|
|
31
|
+
abstract contract ZetoLockable is
|
|
32
|
+
ZetoCommon,
|
|
33
|
+
IZetoLockableCapability,
|
|
34
|
+
IZetoLockHooks
|
|
35
|
+
{
|
|
36
|
+
modifier onlySelf() {
|
|
37
|
+
if (msg.sender != address(this)) {
|
|
38
|
+
revert NotSelf(msg.sender);
|
|
39
|
+
}
|
|
40
|
+
_;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/// @inheritdoc IZetoLockableCapability
|
|
44
|
+
function computeLockId(
|
|
45
|
+
bytes calldata createArgs
|
|
46
|
+
) external view override returns (bytes32) {
|
|
47
|
+
return ZetoLockableLib.computeLockId(createArgs);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// @inheritdoc IZetoLockableCapability
|
|
51
|
+
function computeSpendHash(
|
|
52
|
+
uint256[] calldata lockedInputs,
|
|
53
|
+
uint256[] calldata lockedOutputs,
|
|
54
|
+
uint256[] calldata outputs,
|
|
55
|
+
bytes calldata data
|
|
56
|
+
) external pure override returns (bytes32) {
|
|
57
|
+
return
|
|
58
|
+
ZetoLockableLib.computeSpendHash(
|
|
59
|
+
lockedInputs,
|
|
60
|
+
lockedOutputs,
|
|
61
|
+
outputs,
|
|
62
|
+
data
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// @inheritdoc IZetoLockableCapability
|
|
67
|
+
function computeCancelHash(
|
|
68
|
+
uint256[] calldata lockedInputs,
|
|
69
|
+
uint256[] calldata lockedOutputs,
|
|
70
|
+
uint256[] calldata outputs,
|
|
71
|
+
bytes calldata data
|
|
72
|
+
) external pure override returns (bytes32) {
|
|
73
|
+
return
|
|
74
|
+
ZetoLockableLib.computeCancelHash(
|
|
75
|
+
lockedInputs,
|
|
76
|
+
lockedOutputs,
|
|
77
|
+
outputs,
|
|
78
|
+
data
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/// @inheritdoc ILockableCapability
|
|
83
|
+
function createLock(
|
|
84
|
+
bytes calldata createArgs,
|
|
85
|
+
bytes32 spendCommitment,
|
|
86
|
+
bytes32 cancelCommitment,
|
|
87
|
+
bytes calldata data
|
|
88
|
+
) external override returns (bytes32) {
|
|
89
|
+
return
|
|
90
|
+
ZetoLockableLib.createLock(
|
|
91
|
+
createArgs,
|
|
92
|
+
spendCommitment,
|
|
93
|
+
cancelCommitment,
|
|
94
|
+
data
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/// @inheritdoc ILockableCapability
|
|
99
|
+
function updateLock(
|
|
100
|
+
bytes32 lockId,
|
|
101
|
+
bytes calldata updateArgs,
|
|
102
|
+
bytes32 spendCommitment,
|
|
103
|
+
bytes32 cancelCommitment,
|
|
104
|
+
bytes calldata data
|
|
105
|
+
) external override {
|
|
106
|
+
ZetoLockableLib.updateLock(
|
|
107
|
+
lockId,
|
|
108
|
+
updateArgs,
|
|
109
|
+
spendCommitment,
|
|
110
|
+
cancelCommitment,
|
|
111
|
+
data
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/// @inheritdoc ILockableCapability
|
|
116
|
+
function delegateLock(
|
|
117
|
+
bytes32 lockId,
|
|
118
|
+
bytes calldata delegateArgs,
|
|
119
|
+
address newSpender,
|
|
120
|
+
bytes calldata data
|
|
121
|
+
) external override {
|
|
122
|
+
ZetoLockableLib.delegateLock(
|
|
123
|
+
lockId,
|
|
124
|
+
delegateArgs,
|
|
125
|
+
newSpender,
|
|
126
|
+
data
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/// @inheritdoc ILockableCapability
|
|
131
|
+
function spendLock(
|
|
132
|
+
bytes32 lockId,
|
|
133
|
+
bytes calldata spendArgs,
|
|
134
|
+
bytes calldata data
|
|
135
|
+
) external override {
|
|
136
|
+
ZetoLockableLib.spendLock(lockId, spendArgs, data);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/// @inheritdoc ILockableCapability
|
|
140
|
+
function cancelLock(
|
|
141
|
+
bytes32 lockId,
|
|
142
|
+
bytes calldata cancelArgs,
|
|
143
|
+
bytes calldata data
|
|
144
|
+
) external override {
|
|
145
|
+
ZetoLockableLib.cancelLock(lockId, cancelArgs, data);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/// @inheritdoc ILockableCapability
|
|
149
|
+
function getLock(
|
|
150
|
+
bytes32 lockId
|
|
151
|
+
) external view override returns (LockInfo memory) {
|
|
152
|
+
return ZetoLockableLib.getLock(lockId);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// @inheritdoc ILockableCapability
|
|
156
|
+
function isLockActive(
|
|
157
|
+
bytes32 lockId
|
|
158
|
+
) external view override returns (bool) {
|
|
159
|
+
return ZetoLockableLib.isLockActive(lockId);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/// @inheritdoc ILockableCapability
|
|
163
|
+
function getLockContent(
|
|
164
|
+
bytes32 lockId
|
|
165
|
+
) external view override returns (bytes memory content) {
|
|
166
|
+
return ZetoLockableLib.getLockContent(lockId);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/// @inheritdoc IZetoLockableCapability
|
|
170
|
+
function getLockedInputs(
|
|
171
|
+
bytes32 lockId
|
|
172
|
+
) external view override returns (uint256[] memory lockedInputs) {
|
|
173
|
+
return ZetoLockableLib.getLockedInputs(lockId);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/// @inheritdoc ZetoCommon
|
|
177
|
+
function locked(uint256 utxo) public view override returns (bool, address) {
|
|
178
|
+
return ZetoLockableLib.locked(utxo);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/// @inheritdoc IZetoLockHooks
|
|
182
|
+
function zetoLockDoLockTransition(
|
|
183
|
+
ZetoCreateLockArgs calldata args
|
|
184
|
+
) external override onlySelf {
|
|
185
|
+
_doLockTransition(args);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/// @inheritdoc IZetoLockHooks
|
|
189
|
+
function zetoLockTransferLocked(
|
|
190
|
+
bytes32 lockId,
|
|
191
|
+
uint256[] calldata lockedInputs,
|
|
192
|
+
uint256[] calldata lockedOutputs,
|
|
193
|
+
uint256[] calldata outputs,
|
|
194
|
+
bytes calldata proof,
|
|
195
|
+
bytes calldata data
|
|
196
|
+
) external override onlySelf {
|
|
197
|
+
_transferLocked(
|
|
198
|
+
lockId,
|
|
199
|
+
lockedInputs,
|
|
200
|
+
lockedOutputs,
|
|
201
|
+
outputs,
|
|
202
|
+
proof,
|
|
203
|
+
data
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function _doLockTransition(
|
|
208
|
+
ZetoCreateLockArgs calldata args
|
|
209
|
+
) internal virtual;
|
|
210
|
+
|
|
211
|
+
function _transferLocked(
|
|
212
|
+
bytes32 lockId,
|
|
213
|
+
uint256[] calldata lockedInputs,
|
|
214
|
+
uint256[] calldata lockedOutputs,
|
|
215
|
+
uint256[] calldata outputs,
|
|
216
|
+
bytes calldata proof,
|
|
217
|
+
bytes calldata data
|
|
218
|
+
) internal virtual;
|
|
219
|
+
}
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
// Copyright © 2024 Kaleido, Inc.
|
|
2
|
+
//
|
|
3
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
//
|
|
5
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
// you may not use this file except in compliance with the License.
|
|
7
|
+
// You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
// See the License for the specific language governing permissions and
|
|
15
|
+
// limitations under the License.
|
|
16
|
+
pragma solidity ^0.8.27;
|
|
17
|
+
|
|
18
|
+
import {ILockableCapability} from "./interfaces/ILockableCapability.sol";
|
|
19
|
+
import {IZetoLockableCapability} from "./interfaces/IZetoLockableCapability.sol";
|
|
20
|
+
import {IZetoLockHooks} from "./interfaces/IZetoLockHooks.sol";
|
|
21
|
+
import {ZetoCommonStorage} from "./zeto_common.sol";
|
|
22
|
+
import {ZetoLockableStorage} from "./zeto_lockable_storage.sol";
|
|
23
|
+
|
|
24
|
+
/// @title ZetoLockableLib
|
|
25
|
+
/// @author Kaleido, Inc.
|
|
26
|
+
/// @dev External library holding the shared {IZetoLockableCapability} lock
|
|
27
|
+
/// lifecycle. Deploy once per chain and link into every Zeto token
|
|
28
|
+
/// implementation; logic runs in the token's storage context via
|
|
29
|
+
/// `DELEGATECALL`. Circuit-specific work is delegated back to the
|
|
30
|
+
/// embedding token through {IZetoLockHooks}.
|
|
31
|
+
library ZetoLockableLib {
|
|
32
|
+
/// @dev Domain-separation tag for spend-intent commitments.
|
|
33
|
+
bytes32 private constant _SPEND_HASH_DOMAIN =
|
|
34
|
+
keccak256("Zeto.spendCommitment.v1");
|
|
35
|
+
|
|
36
|
+
/// @dev Domain-separation tag for cancel-intent commitments.
|
|
37
|
+
bytes32 private constant _CANCEL_HASH_DOMAIN =
|
|
38
|
+
keccak256("Zeto.cancelCommitment.v1");
|
|
39
|
+
|
|
40
|
+
function computeLockId(
|
|
41
|
+
bytes calldata createArgs
|
|
42
|
+
) public view returns (bytes32) {
|
|
43
|
+
IZetoLockableCapability.ZetoCreateLockArgs memory args = abi.decode(
|
|
44
|
+
createArgs,
|
|
45
|
+
(IZetoLockableCapability.ZetoCreateLockArgs)
|
|
46
|
+
);
|
|
47
|
+
return _computeLockId(args.txId);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function computeSpendHash(
|
|
51
|
+
uint256[] calldata lockedInputs,
|
|
52
|
+
uint256[] calldata lockedOutputs,
|
|
53
|
+
uint256[] calldata outputs,
|
|
54
|
+
bytes calldata data
|
|
55
|
+
) public pure returns (bytes32) {
|
|
56
|
+
return
|
|
57
|
+
_buildUnlockHash(
|
|
58
|
+
lockedInputs,
|
|
59
|
+
lockedOutputs,
|
|
60
|
+
outputs,
|
|
61
|
+
data,
|
|
62
|
+
_SPEND_HASH_DOMAIN
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function computeCancelHash(
|
|
67
|
+
uint256[] calldata lockedInputs,
|
|
68
|
+
uint256[] calldata lockedOutputs,
|
|
69
|
+
uint256[] calldata outputs,
|
|
70
|
+
bytes calldata data
|
|
71
|
+
) public pure returns (bytes32) {
|
|
72
|
+
return
|
|
73
|
+
_buildUnlockHash(
|
|
74
|
+
lockedInputs,
|
|
75
|
+
lockedOutputs,
|
|
76
|
+
outputs,
|
|
77
|
+
data,
|
|
78
|
+
_CANCEL_HASH_DOMAIN
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function createLock(
|
|
83
|
+
bytes calldata createArgs,
|
|
84
|
+
bytes32 spendCommitment,
|
|
85
|
+
bytes32 cancelCommitment,
|
|
86
|
+
bytes calldata data
|
|
87
|
+
) public returns (bytes32) {
|
|
88
|
+
IZetoLockableCapability.ZetoCreateLockArgs memory args = abi.decode(
|
|
89
|
+
createArgs,
|
|
90
|
+
(IZetoLockableCapability.ZetoCreateLockArgs)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
bytes32 lockId = _computeLockId(args.txId);
|
|
94
|
+
if (ZetoLockableStorage.layout().locks[lockId].owner != address(0)) {
|
|
95
|
+
revert IZetoLockableCapability.DuplicateLock(lockId);
|
|
96
|
+
}
|
|
97
|
+
_useTxId(args.txId);
|
|
98
|
+
|
|
99
|
+
IZetoLockHooks(address(this)).zetoLockDoLockTransition(args);
|
|
100
|
+
|
|
101
|
+
// Delegate projection must be set here (not in the hook): the hook
|
|
102
|
+
// runs as an external self-call where msg.sender is address(this).
|
|
103
|
+
setLockDelegates(args.lockedOutputs, msg.sender);
|
|
104
|
+
|
|
105
|
+
ZetoLockableStorage.ZetoLockInfo storage lock = ZetoLockableStorage
|
|
106
|
+
.layout()
|
|
107
|
+
.locks[lockId];
|
|
108
|
+
lock.owner = msg.sender;
|
|
109
|
+
lock.spender = msg.sender;
|
|
110
|
+
lock.spendCommitment = spendCommitment;
|
|
111
|
+
lock.cancelCommitment = cancelCommitment;
|
|
112
|
+
lock.lockedInputs = args.lockedOutputs;
|
|
113
|
+
|
|
114
|
+
emit ILockableCapability.LockCreated(
|
|
115
|
+
lockId,
|
|
116
|
+
msg.sender,
|
|
117
|
+
msg.sender,
|
|
118
|
+
spendCommitment,
|
|
119
|
+
cancelCommitment,
|
|
120
|
+
data
|
|
121
|
+
);
|
|
122
|
+
emit IZetoLockableCapability.ZetoLockCreated(
|
|
123
|
+
args.txId,
|
|
124
|
+
lockId,
|
|
125
|
+
msg.sender,
|
|
126
|
+
args.inputs,
|
|
127
|
+
args.outputs,
|
|
128
|
+
args.lockedOutputs,
|
|
129
|
+
args.proof,
|
|
130
|
+
data
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
return lockId;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function updateLock(
|
|
137
|
+
bytes32 lockId,
|
|
138
|
+
bytes calldata updateArgs,
|
|
139
|
+
bytes32 spendCommitment,
|
|
140
|
+
bytes32 cancelCommitment,
|
|
141
|
+
bytes calldata data
|
|
142
|
+
) public {
|
|
143
|
+
_requireLockActive(lockId);
|
|
144
|
+
_requireLockOwner(lockId);
|
|
145
|
+
|
|
146
|
+
ZetoLockableStorage.ZetoLockInfo storage lock = ZetoLockableStorage
|
|
147
|
+
.layout()
|
|
148
|
+
.locks[lockId];
|
|
149
|
+
if (lock.spender != lock.owner) {
|
|
150
|
+
revert ILockableCapability.LockImmutable(lockId);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
IZetoLockableCapability.ZetoUpdateLockArgs memory args = abi.decode(
|
|
154
|
+
updateArgs,
|
|
155
|
+
(IZetoLockableCapability.ZetoUpdateLockArgs)
|
|
156
|
+
);
|
|
157
|
+
_useTxId(args.txId);
|
|
158
|
+
|
|
159
|
+
lock.spendCommitment = spendCommitment;
|
|
160
|
+
lock.cancelCommitment = cancelCommitment;
|
|
161
|
+
|
|
162
|
+
emit ILockableCapability.LockUpdated(
|
|
163
|
+
lockId,
|
|
164
|
+
msg.sender,
|
|
165
|
+
spendCommitment,
|
|
166
|
+
cancelCommitment,
|
|
167
|
+
data
|
|
168
|
+
);
|
|
169
|
+
emit IZetoLockableCapability.ZetoLockUpdated(
|
|
170
|
+
args.txId,
|
|
171
|
+
lockId,
|
|
172
|
+
msg.sender,
|
|
173
|
+
data
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function delegateLock(
|
|
178
|
+
bytes32 lockId,
|
|
179
|
+
bytes calldata delegateArgs,
|
|
180
|
+
address newSpender,
|
|
181
|
+
bytes calldata data
|
|
182
|
+
) public {
|
|
183
|
+
_requireLockActive(lockId);
|
|
184
|
+
_requireLockSpender(lockId);
|
|
185
|
+
|
|
186
|
+
IZetoLockableCapability.ZetoDelegateLockArgs memory args = abi.decode(
|
|
187
|
+
delegateArgs,
|
|
188
|
+
(IZetoLockableCapability.ZetoDelegateLockArgs)
|
|
189
|
+
);
|
|
190
|
+
_useTxId(args.txId);
|
|
191
|
+
|
|
192
|
+
ZetoLockableStorage.ZetoLockInfo storage lock = ZetoLockableStorage
|
|
193
|
+
.layout()
|
|
194
|
+
.locks[lockId];
|
|
195
|
+
address previousSpender = lock.spender;
|
|
196
|
+
lock.spender = newSpender;
|
|
197
|
+
|
|
198
|
+
setLockDelegates(lock.lockedInputs, newSpender);
|
|
199
|
+
|
|
200
|
+
emit ILockableCapability.LockDelegated(
|
|
201
|
+
lockId,
|
|
202
|
+
previousSpender,
|
|
203
|
+
newSpender,
|
|
204
|
+
data
|
|
205
|
+
);
|
|
206
|
+
emit IZetoLockableCapability.ZetoLockDelegated(
|
|
207
|
+
args.txId,
|
|
208
|
+
lockId,
|
|
209
|
+
previousSpender,
|
|
210
|
+
newSpender,
|
|
211
|
+
data
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function spendLock(
|
|
216
|
+
bytes32 lockId,
|
|
217
|
+
bytes calldata spendArgs,
|
|
218
|
+
bytes calldata data
|
|
219
|
+
) public {
|
|
220
|
+
_requireLockActive(lockId);
|
|
221
|
+
_requireLockSpender(lockId);
|
|
222
|
+
|
|
223
|
+
IZetoLockableCapability.ZetoSpendLockArgs memory args = abi.decode(
|
|
224
|
+
spendArgs,
|
|
225
|
+
(IZetoLockableCapability.ZetoSpendLockArgs)
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
uint256[] memory lockedInputs = ZetoLockableStorage
|
|
229
|
+
.layout()
|
|
230
|
+
.locks[lockId]
|
|
231
|
+
.lockedInputs;
|
|
232
|
+
bytes32 expectedHash = ZetoLockableStorage
|
|
233
|
+
.layout()
|
|
234
|
+
.locks[lockId]
|
|
235
|
+
.spendCommitment;
|
|
236
|
+
_consumeLock(
|
|
237
|
+
lockId,
|
|
238
|
+
lockedInputs,
|
|
239
|
+
expectedHash,
|
|
240
|
+
_SPEND_HASH_DOMAIN,
|
|
241
|
+
args
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
emit ILockableCapability.LockSpent(lockId, msg.sender, data);
|
|
245
|
+
emit IZetoLockableCapability.ZetoLockSpent(
|
|
246
|
+
args.txId,
|
|
247
|
+
lockId,
|
|
248
|
+
msg.sender,
|
|
249
|
+
lockedInputs,
|
|
250
|
+
args.lockedOutputs,
|
|
251
|
+
args.outputs,
|
|
252
|
+
args.proof,
|
|
253
|
+
data
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function cancelLock(
|
|
258
|
+
bytes32 lockId,
|
|
259
|
+
bytes calldata cancelArgs,
|
|
260
|
+
bytes calldata data
|
|
261
|
+
) public {
|
|
262
|
+
_requireLockActive(lockId);
|
|
263
|
+
_requireLockSpender(lockId);
|
|
264
|
+
|
|
265
|
+
IZetoLockableCapability.ZetoSpendLockArgs memory args = abi.decode(
|
|
266
|
+
cancelArgs,
|
|
267
|
+
(IZetoLockableCapability.ZetoSpendLockArgs)
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
uint256[] memory lockedInputs = ZetoLockableStorage
|
|
271
|
+
.layout()
|
|
272
|
+
.locks[lockId]
|
|
273
|
+
.lockedInputs;
|
|
274
|
+
bytes32 expectedHash = ZetoLockableStorage
|
|
275
|
+
.layout()
|
|
276
|
+
.locks[lockId]
|
|
277
|
+
.cancelCommitment;
|
|
278
|
+
_consumeLock(
|
|
279
|
+
lockId,
|
|
280
|
+
lockedInputs,
|
|
281
|
+
expectedHash,
|
|
282
|
+
_CANCEL_HASH_DOMAIN,
|
|
283
|
+
args
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
emit ILockableCapability.LockCancelled(lockId, msg.sender, data);
|
|
287
|
+
emit IZetoLockableCapability.ZetoLockCancelled(
|
|
288
|
+
args.txId,
|
|
289
|
+
lockId,
|
|
290
|
+
msg.sender,
|
|
291
|
+
lockedInputs,
|
|
292
|
+
args.lockedOutputs,
|
|
293
|
+
args.outputs,
|
|
294
|
+
args.proof,
|
|
295
|
+
data
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function getLock(
|
|
300
|
+
bytes32 lockId
|
|
301
|
+
) public view returns (ILockableCapability.LockInfo memory) {
|
|
302
|
+
_requireLockActive(lockId);
|
|
303
|
+
ZetoLockableStorage.ZetoLockInfo storage lock = ZetoLockableStorage
|
|
304
|
+
.layout()
|
|
305
|
+
.locks[lockId];
|
|
306
|
+
return
|
|
307
|
+
ILockableCapability.LockInfo({
|
|
308
|
+
owner: lock.owner,
|
|
309
|
+
spender: lock.spender,
|
|
310
|
+
spendCommitment: lock.spendCommitment,
|
|
311
|
+
cancelCommitment: lock.cancelCommitment
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function isLockActive(bytes32 lockId) public view returns (bool) {
|
|
316
|
+
return ZetoLockableStorage.layout().locks[lockId].owner != address(0);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function getLockContent(
|
|
320
|
+
bytes32 lockId
|
|
321
|
+
) public view returns (bytes memory content) {
|
|
322
|
+
_requireLockActive(lockId);
|
|
323
|
+
return
|
|
324
|
+
abi.encode(ZetoLockableStorage.layout().locks[lockId].lockedInputs);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function getLockedInputs(
|
|
328
|
+
bytes32 lockId
|
|
329
|
+
) public view returns (uint256[] memory lockedInputs) {
|
|
330
|
+
_requireLockActive(lockId);
|
|
331
|
+
return ZetoLockableStorage.layout().locks[lockId].lockedInputs;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function locked(uint256 utxo) public view returns (bool, address) {
|
|
335
|
+
if (!ZetoCommonStorage.layout().utxoStorage.locked(utxo)) {
|
|
336
|
+
return (false, address(0));
|
|
337
|
+
}
|
|
338
|
+
return (true, ZetoLockableStorage.layout().utxoDelegates[utxo]);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function setLockDelegates(
|
|
342
|
+
uint256[] memory utxos,
|
|
343
|
+
address spender
|
|
344
|
+
) public {
|
|
345
|
+
for (uint256 i = 0; i < utxos.length; ++i) {
|
|
346
|
+
if (utxos[i] != 0) {
|
|
347
|
+
ZetoLockableStorage.layout().utxoDelegates[utxos[i]] = spender;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
function _computeLockId(bytes32 txId) private view returns (bytes32) {
|
|
353
|
+
return keccak256(abi.encode(address(this), msg.sender, txId));
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
function _useTxId(bytes32 txId) private {
|
|
357
|
+
if (ZetoLockableStorage.layout().txIds[msg.sender][txId]) {
|
|
358
|
+
revert IZetoLockableCapability.DuplicateTransaction(txId);
|
|
359
|
+
}
|
|
360
|
+
ZetoLockableStorage.layout().txIds[msg.sender][txId] = true;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
function _requireLockActive(bytes32 lockId) private view {
|
|
364
|
+
if (ZetoLockableStorage.layout().locks[lockId].owner == address(0)) {
|
|
365
|
+
revert ILockableCapability.LockNotActive(lockId);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function _requireLockOwner(bytes32 lockId) private view {
|
|
370
|
+
address owner = ZetoLockableStorage.layout().locks[lockId].owner;
|
|
371
|
+
if (owner != msg.sender) {
|
|
372
|
+
revert ILockableCapability.LockUnauthorized(
|
|
373
|
+
lockId,
|
|
374
|
+
owner,
|
|
375
|
+
msg.sender
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function _requireLockSpender(bytes32 lockId) private view {
|
|
381
|
+
address spender = ZetoLockableStorage.layout().locks[lockId].spender;
|
|
382
|
+
if (spender != msg.sender) {
|
|
383
|
+
revert ILockableCapability.LockUnauthorized(
|
|
384
|
+
lockId,
|
|
385
|
+
spender,
|
|
386
|
+
msg.sender
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function _consumeLock(
|
|
392
|
+
bytes32 lockId,
|
|
393
|
+
uint256[] memory lockedInputs,
|
|
394
|
+
bytes32 expectedHash,
|
|
395
|
+
bytes32 hashDomain,
|
|
396
|
+
IZetoLockableCapability.ZetoSpendLockArgs memory args
|
|
397
|
+
) private {
|
|
398
|
+
_useTxId(args.txId);
|
|
399
|
+
|
|
400
|
+
if (expectedHash != 0) {
|
|
401
|
+
bytes32 actualHash = _buildUnlockHash(
|
|
402
|
+
lockedInputs,
|
|
403
|
+
args.lockedOutputs,
|
|
404
|
+
args.outputs,
|
|
405
|
+
args.data,
|
|
406
|
+
hashDomain
|
|
407
|
+
);
|
|
408
|
+
if (actualHash != expectedHash) {
|
|
409
|
+
revert IZetoLockableCapability.InvalidUnlockHash(
|
|
410
|
+
expectedHash,
|
|
411
|
+
actualHash
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
_clearLockDelegates(lockedInputs);
|
|
417
|
+
delete ZetoLockableStorage.layout().locks[lockId];
|
|
418
|
+
|
|
419
|
+
IZetoLockHooks(address(this)).zetoLockTransferLocked(
|
|
420
|
+
lockId,
|
|
421
|
+
lockedInputs,
|
|
422
|
+
args.lockedOutputs,
|
|
423
|
+
args.outputs,
|
|
424
|
+
args.proof,
|
|
425
|
+
args.data
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
// Same msg.sender rationale as {createLock}: hook is external self-call.
|
|
429
|
+
if (args.lockedOutputs.length > 0) {
|
|
430
|
+
setLockDelegates(args.lockedOutputs, msg.sender);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
function _clearLockDelegates(uint256[] memory utxos) private {
|
|
435
|
+
for (uint256 i = 0; i < utxos.length; ++i) {
|
|
436
|
+
if (utxos[i] != 0) {
|
|
437
|
+
delete ZetoLockableStorage.layout().utxoDelegates[utxos[i]];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function _buildUnlockHash(
|
|
443
|
+
uint256[] memory lockedInputs,
|
|
444
|
+
uint256[] memory lockedOutputs,
|
|
445
|
+
uint256[] memory outputs,
|
|
446
|
+
bytes memory data,
|
|
447
|
+
bytes32 domain
|
|
448
|
+
) private pure returns (bytes32) {
|
|
449
|
+
return
|
|
450
|
+
keccak256(
|
|
451
|
+
abi.encode(
|
|
452
|
+
domain,
|
|
453
|
+
keccak256(abi.encode(lockedInputs)),
|
|
454
|
+
keccak256(abi.encode(lockedOutputs)),
|
|
455
|
+
keccak256(abi.encode(outputs)),
|
|
456
|
+
keccak256(data)
|
|
457
|
+
)
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
}
|