@lfdecentralizedtrust/zeto-contracts 0.5.0 → 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 +6 -0
- package/config/eip170.ts +30 -0
- package/contracts/lib/interfaces/IZetoLockHooks.sol +42 -0
- package/contracts/lib/zeto_fungible.sol +9 -17
- package/contracts/lib/zeto_lockable.sol +85 -479
- 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 +8 -16
- package/hardhat.config.ts +11 -2
- package/ignition/modules/lib/deps.ts +5 -0
- package/ignition/modules/test/tendecimals.ts +7 -1
- package/ignition/modules/zeto_anon.ts +3 -0
- package/ignition/modules/zeto_anon_burnable.ts +3 -0
- package/ignition/modules/zeto_anon_enc.ts +3 -0
- package/ignition/modules/zeto_anon_enc_nullifier.ts +3 -0
- package/ignition/modules/zeto_anon_enc_nullifier_kyc.ts +3 -0
- package/ignition/modules/zeto_anon_enc_nullifier_non_repudiation.ts +3 -0
- package/ignition/modules/zeto_anon_nullifier.ts +3 -0
- package/ignition/modules/zeto_anon_nullifier_burnable.ts +3 -0
- package/ignition/modules/zeto_anon_nullifier_kyc.ts +3 -0
- 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 +3 -2
- package/package.json +4 -2
- package/scripts/lib/zeto_libraries.ts +47 -0
- package/scripts/tokens/Zeto_Anon.ts +3 -0
- package/scripts/tokens/Zeto_AnonBurnable.ts +3 -0
- package/scripts/tokens/Zeto_AnonEnc.ts +3 -0
- package/scripts/tokens/Zeto_AnonEncNullifier.ts +6 -5
- package/scripts/tokens/Zeto_AnonEncNullifierKyc.ts +6 -5
- package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +6 -5
- package/scripts/tokens/Zeto_AnonNullifier.ts +6 -5
- package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +6 -5
- package/scripts/tokens/Zeto_AnonNullifierKyc.ts +6 -5
- package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +6 -7
- package/scripts/tokens/Zeto_NfAnon.ts +3 -1
- package/scripts/tokens/Zeto_NfAnonNullifier.ts +6 -6
- package/test/factory.ts +10 -1
- package/test/lib/deploy.ts +2 -0
- package/test/lib/eip170.ts +23 -0
- package/test/usdc-shielding.ts +0 -1
- package/test/zeto_anon_enc.ts +0 -1
- package/test/zeto_anon_enc_nullifier.ts +3 -1
- package/test/zeto_anon_enc_nullifier_kyc.ts +3 -1
- package/test/zeto_anon_enc_nullifier_non_repudiation.ts +3 -1
- package/test/zeto_anon_nullifier.ts +0 -1
- package/test/zeto_anon_nullifier_kyc.ts +3 -1
- package/test/zeto_anon_nullifier_qurrency.ts +3 -1
- package/test/zeto_nf_anon.ts +0 -1
- package/test/zeto_nf_anon_nullifier.ts +0 -1
package/README.md
CHANGED
|
@@ -13,6 +13,10 @@ Privacy-preserving token implementations for fungible and non-fungible assets, b
|
|
|
13
13
|
|
|
14
14
|
Hardhat and related tooling are pulled in via `@nomicfoundation/hardhat-toolbox`; you do not need to run `hardhat init` in this repository.
|
|
15
15
|
|
|
16
|
+
### Contract size (EIP-170)
|
|
17
|
+
|
|
18
|
+
Mainnet limits deployed bytecode to **24,576 bytes**. This repo enforces that on the Hardhat network and at compile time via `hardhat-contract-sizer`. Run `npm run size` to print sizes after compile.
|
|
19
|
+
|
|
16
20
|
### Circuits and proving keys
|
|
17
21
|
|
|
18
22
|
Hardhat tests load circuit WASM via **`zeto-js`** (`file:../zkp/js`). Before running tests:
|
|
@@ -74,6 +78,8 @@ npx hardhat run scripts/deploy_cloneable.ts
|
|
|
74
78
|
|
|
75
79
|
This deploys the **implementation only**. Leaf tokens lock the impl with `_disableInitializers()`; **`initialize` runs on proxies** created by **`ZetoTokenFactory`**. Tests use **`USE_FACTORY=true`** in `test/lib/deploy.ts` to register the impl and deploy initialized clones. Running the script **by itself** does not yield a ready-to-use initialized token unless you finish that factory flow.
|
|
76
80
|
|
|
81
|
+
Every token implementation links the external **`ZetoLockableLib`** library (deployed once per chain via Ignition). Token deploy scripts in `scripts/tokens/` pass it in the `libraries` map alongside `SmtLib` / Poseidon where applicable.
|
|
82
|
+
|
|
77
83
|
For a single initialized deployment without the factory path, use **`deploy_upgradeable.ts`**.
|
|
78
84
|
|
|
79
85
|
Cheap repeat deployments: OpenZeppelin [minimal proxies / Clones](https://docs.openzeppelin.com/contracts/5.x/api/utils#Clones).
|
package/config/eip170.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EIP-170 (Spurious Dragon) maximum deployed runtime bytecode size.
|
|
3
|
+
* @see https://eips.ethereum.org/EIPS/eip-170
|
|
4
|
+
*/
|
|
5
|
+
export const EIP170_BYTE_LIMIT = 24_576;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Contracts that currently exceed EIP170_BYTE_LIMIT with the compiler settings
|
|
9
|
+
* in hardhat.config.ts. Exempt from `hardhat-contract-sizer` strict checks
|
|
10
|
+
* until further library splits land.
|
|
11
|
+
*
|
|
12
|
+
* Remove names from this list as implementations are brought under the limit.
|
|
13
|
+
*/
|
|
14
|
+
export const EIP170_EXEMPT_CONTRACTS: readonly string[] = [
|
|
15
|
+
"Zeto_AnonEncNullifier",
|
|
16
|
+
"Zeto_AnonEncNullifierKyc",
|
|
17
|
+
"Zeto_AnonEncNullifierNonRepudiation",
|
|
18
|
+
"Zeto_AnonNullifierBurnable",
|
|
19
|
+
"Zeto_AnonNullifierQurrency",
|
|
20
|
+
"Groth16Verifier_AnonEncNullifierNonRepudiationBatch",
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
export const EIP170_EXEMPT_CONTRACTS_SET = new Set<string>(
|
|
24
|
+
EIP170_EXEMPT_CONTRACTS,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
/** Token implementations in the exemption list (excludes standalone verifiers). */
|
|
28
|
+
export const EIP170_EXEMPT_TOKEN_SET = new Set<string>(
|
|
29
|
+
EIP170_EXEMPT_CONTRACTS.filter((name) => name.startsWith("Zeto_")),
|
|
30
|
+
);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// Copyright © 2025 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 "./IZetoLockableCapability.sol";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @title IZetoLockHooks
|
|
22
|
+
* @dev Callback surface invoked by {ZetoLockableLib} (via `address(this)`)
|
|
23
|
+
* so circuit-specific lock transitions stay in the embedding token
|
|
24
|
+
* while shared lock lifecycle logic lives in the external library.
|
|
25
|
+
*/
|
|
26
|
+
interface IZetoLockHooks {
|
|
27
|
+
/// @dev Thrown when a hook is invoked by an address other than `address(this)`.
|
|
28
|
+
error NotSelf(address caller);
|
|
29
|
+
|
|
30
|
+
function zetoLockDoLockTransition(
|
|
31
|
+
IZetoLockableCapability.ZetoCreateLockArgs calldata args
|
|
32
|
+
) external;
|
|
33
|
+
|
|
34
|
+
function zetoLockTransferLocked(
|
|
35
|
+
bytes32 lockId,
|
|
36
|
+
uint256[] calldata lockedInputs,
|
|
37
|
+
uint256[] calldata lockedOutputs,
|
|
38
|
+
uint256[] calldata outputs,
|
|
39
|
+
bytes calldata proof,
|
|
40
|
+
bytes calldata data
|
|
41
|
+
) external;
|
|
42
|
+
}
|
|
@@ -30,9 +30,9 @@ import {IZetoStorage} from "./interfaces/IZetoStorage.sol";
|
|
|
30
30
|
/// @dev Adds the ERC20-backed deposit/withdraw lifecycle and a multi-input
|
|
31
31
|
/// {transfer} flow on top of the lock-aware {ZetoLockable} base.
|
|
32
32
|
///
|
|
33
|
-
/// The lock-lifecycle plumbing (state,
|
|
34
|
-
///
|
|
35
|
-
/// only the two ZK-circuit-shaped hooks
|
|
33
|
+
/// The lock-lifecycle plumbing (state, external entry points, views)
|
|
34
|
+
/// lives in the linked external {ZetoLockableLib}; this contract
|
|
35
|
+
/// supplies only the two ZK-circuit-shaped hooks
|
|
36
36
|
/// ({_doLockTransition} and {_transferLocked}) that pad
|
|
37
37
|
/// inputs/outputs to the next supported batch size before
|
|
38
38
|
/// {constructPublicInputs}.
|
|
@@ -162,7 +162,7 @@ abstract contract ZetoFungible is ZetoLockable, ReentrancyGuardUpgradeable {
|
|
|
162
162
|
// ------------------------------------------------------------------
|
|
163
163
|
|
|
164
164
|
function _doLockTransition(
|
|
165
|
-
ZetoCreateLockArgs
|
|
165
|
+
ZetoCreateLockArgs calldata args
|
|
166
166
|
) internal override {
|
|
167
167
|
validateTransactionProposal(
|
|
168
168
|
args.inputs,
|
|
@@ -206,19 +206,15 @@ abstract contract ZetoFungible is ZetoLockable, ReentrancyGuardUpgradeable {
|
|
|
206
206
|
|
|
207
207
|
processInputsAndOutputs(paddedInputs, args.outputs, false);
|
|
208
208
|
processLockedOutputs(args.lockedOutputs);
|
|
209
|
-
// The freshly-locked outputs all start under the lock creator
|
|
210
|
-
// as both owner and spender; record that on the per-UTXO
|
|
211
|
-
// projection so {locked} can report it without a reverse lookup.
|
|
212
|
-
_setLockDelegates(args.lockedOutputs, msg.sender);
|
|
213
209
|
}
|
|
214
210
|
|
|
215
211
|
function _transferLocked(
|
|
216
212
|
bytes32 /* lockId */,
|
|
217
|
-
uint256[]
|
|
218
|
-
uint256[]
|
|
219
|
-
uint256[]
|
|
220
|
-
bytes
|
|
221
|
-
bytes
|
|
213
|
+
uint256[] calldata lockedInputs,
|
|
214
|
+
uint256[] calldata lockedOutputs,
|
|
215
|
+
uint256[] calldata outputs,
|
|
216
|
+
bytes calldata proof,
|
|
217
|
+
bytes calldata /* data */
|
|
222
218
|
) internal override {
|
|
223
219
|
validateTransactionProposal(
|
|
224
220
|
lockedInputs,
|
|
@@ -253,10 +249,6 @@ abstract contract ZetoFungible is ZetoLockable, ReentrancyGuardUpgradeable {
|
|
|
253
249
|
verifyProof(proofStruct, publicInputs, isBatch, true);
|
|
254
250
|
processInputsAndOutputs(paddedInputs, paddedOutputs, true);
|
|
255
251
|
processLockedOutputs(lockedOutputs);
|
|
256
|
-
// Any newly-locked outputs produced by this spend default to the
|
|
257
|
-
// current spender as their delegate. (When `lockedOutputs` is
|
|
258
|
-
// empty -- the common case -- this is a no-op.)
|
|
259
|
-
_setLockDelegates(lockedOutputs, msg.sender);
|
|
260
252
|
}
|
|
261
253
|
|
|
262
254
|
/**
|