@lfdecentralizedtrust/zeto-contracts 0.2.1 → 0.2.2
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/contracts/factory_upgradeable.sol +156 -0
- package/contracts/lib/registry.sol +4 -2
- package/contracts/lib/zeto_nullifier.sol +8 -2
- package/contracts/test/smt.sol +2 -2
- package/contracts/zeto_anon_nullifier_qurrency.sol +3 -1
- package/ignition/modules/lib/deps.ts +1 -6
- package/ignition/modules/zeto_anon_enc_nullifier.ts +2 -1
- package/ignition/modules/zeto_anon_enc_nullifier_non_repudiation.ts +2 -1
- package/ignition/modules/zeto_anon_nullifier.ts +2 -1
- package/ignition/modules/zeto_anon_nullifier_burnable.ts +2 -1
- package/ignition/modules/zeto_anon_nullifier_qurrency.ts +2 -1
- package/ignition/modules/zeto_nf_anon_nullifier.ts +2 -2
- package/package.json +2 -2
- package/scripts/tokens/Zeto_AnonEncNullifier.ts +2 -0
- package/scripts/tokens/Zeto_AnonEncNullifierNonRepudiation.ts +2 -0
- package/scripts/tokens/Zeto_AnonNullifier.ts +2 -0
- package/scripts/tokens/Zeto_AnonNullifierBurnable.ts +2 -0
- package/scripts/tokens/Zeto_AnonNullifierQurrency.ts +2 -0
- package/scripts/tokens/Zeto_NfAnonNullifier.ts +2 -1
- package/test/factory_upgradeable.ts +311 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// Copyright © 2026 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 {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
|
19
|
+
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
20
|
+
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
21
|
+
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
|
|
22
|
+
import {IZetoInitializable} from "./lib/interfaces/izeto_initializable.sol";
|
|
23
|
+
|
|
24
|
+
contract ZetoTokenFactoryUpgradeable is Initializable, OwnableUpgradeable, UUPSUpgradeable {
|
|
25
|
+
// all the addresses needed by the factory to
|
|
26
|
+
// clone a Zeto token and initialize it. The
|
|
27
|
+
// "implementation" is used to clone the token,
|
|
28
|
+
// the rest of the addresses are used to initialize
|
|
29
|
+
struct ImplementationInfo {
|
|
30
|
+
address implementation;
|
|
31
|
+
IZetoInitializable.VerifiersInfo verifiers;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/// @custom:storage-location erc7201:zeto.storage.ZetoTokenFactory
|
|
35
|
+
struct ZetoTokenFactoryStorage {
|
|
36
|
+
mapping(string => ImplementationInfo) implementations;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// keccak256(abi.encode(uint256(keccak256("zeto.storage.ZetoTokenFactory")) - 1)) & ~bytes32(uint256(0xff))
|
|
40
|
+
bytes32 private constant ZETO_TOKEN_FACTORY_STORAGE_LOCATION =
|
|
41
|
+
0xea00970f7a43a8afae26fee4308a7f177a9692a756b610fca8a1c058954e4800;
|
|
42
|
+
|
|
43
|
+
event ZetoTokenDeployed(address indexed zetoToken);
|
|
44
|
+
|
|
45
|
+
function _getZetoTokenFactoryStorage()
|
|
46
|
+
private
|
|
47
|
+
pure
|
|
48
|
+
returns (ZetoTokenFactoryStorage storage $)
|
|
49
|
+
{
|
|
50
|
+
assembly {
|
|
51
|
+
$.slot := ZETO_TOKEN_FACTORY_STORAGE_LOCATION
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/// @custom:oz-upgrades-unsafe-allow constructor
|
|
56
|
+
constructor() {
|
|
57
|
+
_disableInitializers();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function initialize() public virtual initializer {
|
|
61
|
+
__Ownable_init(_msgSender());
|
|
62
|
+
__UUPSUpgradeable_init();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function registerImplementation(
|
|
66
|
+
string memory name,
|
|
67
|
+
ImplementationInfo memory implementation
|
|
68
|
+
) public onlyOwner {
|
|
69
|
+
require(
|
|
70
|
+
implementation.implementation != address(0),
|
|
71
|
+
"Factory: implementation address is required"
|
|
72
|
+
);
|
|
73
|
+
require(
|
|
74
|
+
implementation.verifiers.verifier != address(0),
|
|
75
|
+
"Factory: verifier address is required"
|
|
76
|
+
);
|
|
77
|
+
// the depositVerifier and withdrawVerifier are optional
|
|
78
|
+
// for the non-fungible token implementations
|
|
79
|
+
ZetoTokenFactoryStorage storage $ = _getZetoTokenFactoryStorage();
|
|
80
|
+
$.implementations[name] = implementation;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function deployZetoFungibleToken(
|
|
84
|
+
string memory name,
|
|
85
|
+
string memory symbol,
|
|
86
|
+
string memory tokenImplementation,
|
|
87
|
+
address initialOwner
|
|
88
|
+
) public returns (address) {
|
|
89
|
+
ZetoTokenFactoryStorage storage $ = _getZetoTokenFactoryStorage();
|
|
90
|
+
ImplementationInfo memory args = $.implementations[tokenImplementation];
|
|
91
|
+
require(
|
|
92
|
+
args.implementation != address(0),
|
|
93
|
+
"Factory: failed to find implementation"
|
|
94
|
+
);
|
|
95
|
+
// check that the registered implementation is for a fungible token
|
|
96
|
+
// and has the required verifier addresses
|
|
97
|
+
require(
|
|
98
|
+
args.verifiers.depositVerifier != address(0),
|
|
99
|
+
"Factory: depositVerifier address is required"
|
|
100
|
+
);
|
|
101
|
+
require(
|
|
102
|
+
args.verifiers.withdrawVerifier != address(0),
|
|
103
|
+
"Factory: withdrawVerifier address is required"
|
|
104
|
+
);
|
|
105
|
+
require(
|
|
106
|
+
args.verifiers.batchVerifier != address(0),
|
|
107
|
+
"Factory: batchVerifier address is required"
|
|
108
|
+
);
|
|
109
|
+
require(
|
|
110
|
+
args.verifiers.batchWithdrawVerifier != address(0),
|
|
111
|
+
"Factory: batchWithdrawVerifier address is required"
|
|
112
|
+
);
|
|
113
|
+
address instance = Clones.clone(args.implementation);
|
|
114
|
+
require(
|
|
115
|
+
instance != address(0),
|
|
116
|
+
"Factory: failed to clone implementation"
|
|
117
|
+
);
|
|
118
|
+
(IZetoInitializable(instance)).initialize(
|
|
119
|
+
name,
|
|
120
|
+
symbol,
|
|
121
|
+
initialOwner,
|
|
122
|
+
args.verifiers
|
|
123
|
+
);
|
|
124
|
+
emit ZetoTokenDeployed(instance);
|
|
125
|
+
return instance;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function deployZetoNonFungibleToken(
|
|
129
|
+
string memory name,
|
|
130
|
+
string memory symbol,
|
|
131
|
+
string memory tokenImplementation,
|
|
132
|
+
address initialOwner
|
|
133
|
+
) public returns (address) {
|
|
134
|
+
ZetoTokenFactoryStorage storage $ = _getZetoTokenFactoryStorage();
|
|
135
|
+
ImplementationInfo memory args = $.implementations[tokenImplementation];
|
|
136
|
+
require(
|
|
137
|
+
args.implementation != address(0),
|
|
138
|
+
"Factory: failed to find implementation"
|
|
139
|
+
);
|
|
140
|
+
address instance = Clones.clone(args.implementation);
|
|
141
|
+
require(
|
|
142
|
+
instance != address(0),
|
|
143
|
+
"Factory: failed to clone implementation"
|
|
144
|
+
);
|
|
145
|
+
(IZetoInitializable(instance)).initialize(
|
|
146
|
+
name,
|
|
147
|
+
symbol,
|
|
148
|
+
initialOwner,
|
|
149
|
+
args.verifiers
|
|
150
|
+
);
|
|
151
|
+
emit ZetoTokenDeployed(instance);
|
|
152
|
+
return instance;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function _authorizeUpgrade(address) internal override onlyOwner {}
|
|
156
|
+
}
|
|
@@ -16,8 +16,9 @@
|
|
|
16
16
|
pragma solidity ^0.8.27;
|
|
17
17
|
|
|
18
18
|
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
19
|
-
import {SmtLib} from "@iden3/contracts/lib/SmtLib.sol";
|
|
20
|
-
import {
|
|
19
|
+
import {SmtLib} from "@iden3/contracts/contracts/lib/SmtLib.sol";
|
|
20
|
+
import {PoseidonHasher} from "@iden3/contracts/contracts/lib/hash/PoseidonHasher.sol";
|
|
21
|
+
import {PoseidonUnit2L, PoseidonUnit3L} from "@iden3/contracts/contracts/lib/Poseidon.sol";
|
|
21
22
|
import {Commonlib} from "./common.sol";
|
|
22
23
|
import {IZeto} from "./interfaces/izeto.sol";
|
|
23
24
|
import {IZetoKyc} from "./interfaces/izeto_kyc.sol";
|
|
@@ -38,6 +39,7 @@ abstract contract Registry is OwnableUpgradeable, IZetoKyc {
|
|
|
38
39
|
|
|
39
40
|
function __Registry_init() internal onlyInitializing {
|
|
40
41
|
_publicKeysTree.initialize(MAX_SMT_DEPTH);
|
|
42
|
+
_publicKeysTree.setHasher(new PoseidonHasher());
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
function register(
|
|
@@ -20,8 +20,10 @@ import {IZeto} from "./interfaces/izeto.sol";
|
|
|
20
20
|
import {MAX_SMT_DEPTH} from "./interfaces/izeto.sol";
|
|
21
21
|
import {IZetoLockable} from "./interfaces/izeto_lockable.sol";
|
|
22
22
|
import {ZetoCommon} from "./zeto_common.sol";
|
|
23
|
-
import {SmtLib} from "@iden3/contracts/lib/SmtLib.sol";
|
|
24
|
-
import {
|
|
23
|
+
import {SmtLib} from "@iden3/contracts/contracts/lib/SmtLib.sol";
|
|
24
|
+
import {PoseidonHasher} from "@iden3/contracts/contracts/lib/hash/PoseidonHasher.sol";
|
|
25
|
+
import {IHasher} from "@iden3/contracts/contracts/interfaces/IHasher.sol";
|
|
26
|
+
import {PoseidonUnit3L} from "@iden3/contracts/contracts/lib/Poseidon.sol";
|
|
25
27
|
import {console} from "hardhat/console.sol";
|
|
26
28
|
|
|
27
29
|
/// @title A sample base implementation of a Zeto based token contract with nullifiers
|
|
@@ -38,6 +40,7 @@ abstract contract ZetoNullifier is IZeto, IZetoLockable, ZetoCommon {
|
|
|
38
40
|
SmtLib.Data internal _lockedCommitmentsTree;
|
|
39
41
|
using SmtLib for SmtLib.Data;
|
|
40
42
|
mapping(uint256 => bool) private _nullifiers;
|
|
43
|
+
IHasher private _hasher;
|
|
41
44
|
|
|
42
45
|
error UTXORootNotFound(uint256 root);
|
|
43
46
|
|
|
@@ -49,6 +52,9 @@ abstract contract ZetoNullifier is IZeto, IZetoLockable, ZetoCommon {
|
|
|
49
52
|
__ZetoCommon_init(name_, symbol_, initialOwner);
|
|
50
53
|
_commitmentsTree.initialize(MAX_SMT_DEPTH);
|
|
51
54
|
_lockedCommitmentsTree.initialize(MAX_SMT_DEPTH);
|
|
55
|
+
_hasher = new PoseidonHasher();
|
|
56
|
+
_commitmentsTree.setHasher(_hasher);
|
|
57
|
+
_lockedCommitmentsTree.setHasher(_hasher);
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
function validateTransactionProposal(
|
package/contracts/test/smt.sol
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
// limitations under the License.
|
|
16
16
|
pragma solidity ^0.8.27;
|
|
17
17
|
|
|
18
|
-
import {SmtLib} from "@iden3/contracts/lib/SmtLib.sol";
|
|
19
|
-
import {PoseidonUnit3L} from "@iden3/contracts/lib/Poseidon.sol";
|
|
18
|
+
import {SmtLib} from "@iden3/contracts/contracts/lib/SmtLib.sol";
|
|
19
|
+
import {PoseidonUnit3L} from "@iden3/contracts/contracts/lib/Poseidon.sol";
|
|
20
20
|
|
|
21
21
|
// test ground for better understanding of the SmtLib library implementation
|
|
22
22
|
contract TestSmt {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// limitations under the License.
|
|
16
16
|
pragma solidity ^0.8.27;
|
|
17
17
|
|
|
18
|
-
import {PoseidonUnit5L} from "@iden3/contracts/lib/Poseidon.sol";
|
|
18
|
+
import {PoseidonUnit5L} from "@iden3/contracts/contracts/lib/Poseidon.sol";
|
|
19
19
|
import {IZeto} from "./lib/interfaces/izeto.sol";
|
|
20
20
|
import {MAX_BATCH} from "./lib/interfaces/izeto.sol";
|
|
21
21
|
import {Groth16Verifier_Deposit} from "./verifiers/verifier_deposit.sol";
|
|
@@ -35,6 +35,7 @@ import {console} from "hardhat/console.sol";
|
|
|
35
35
|
uint256 constant INPUT_SIZE = 9;
|
|
36
36
|
// uint256 constant INPUT_SIZE_LOCKED = 8;
|
|
37
37
|
uint256 constant BATCH_INPUT_SIZE = 33;
|
|
38
|
+
|
|
38
39
|
// uint256 constant BATCH_INPUT_SIZE_LOCKED = 32;
|
|
39
40
|
|
|
40
41
|
/// @title A sample implementation of a Zeto based fungible token with anonymity and history masking
|
|
@@ -54,6 +55,7 @@ contract Zeto_AnonNullifierQurrency is
|
|
|
54
55
|
{
|
|
55
56
|
Groth16Verifier_AnonNullifierQurrencyTransfer internal _verifier;
|
|
56
57
|
Groth16Verifier_AnonNullifierQurrencyTransferBatch internal _batchVerifier;
|
|
58
|
+
|
|
57
59
|
// Groth16Verifier_AnonNullifierTransferLocked internal _lockVerifier;
|
|
58
60
|
// Groth16Verifier_AnonNullifierTransferLockedBatch
|
|
59
61
|
// internal _batchLockVerifier;
|
|
@@ -23,12 +23,7 @@ export const SmtLibModule = buildModule("SmtLib", (m) => {
|
|
|
23
23
|
const poseidon3 = m.library("Poseidon3", PoseidonArtifact(3));
|
|
24
24
|
const poseidon5 = m.library("Poseidon5", PoseidonArtifact(5));
|
|
25
25
|
const poseidon6 = m.library("Poseidon6", PoseidonArtifact(6));
|
|
26
|
-
const smtLib = m.contract("SmtLib", []
|
|
27
|
-
libraries: {
|
|
28
|
-
PoseidonUnit2L: poseidon2,
|
|
29
|
-
PoseidonUnit3L: poseidon3,
|
|
30
|
-
},
|
|
31
|
-
});
|
|
26
|
+
const smtLib = m.contract("SmtLib", []);
|
|
32
27
|
return { smtLib, poseidon2, poseidon3, poseidon5, poseidon6 };
|
|
33
28
|
});
|
|
34
29
|
|
|
@@ -36,7 +36,7 @@ const BatchVerifierModule = buildModule(
|
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
export default buildModule("Zeto_AnonEncNullifier", (m) => {
|
|
39
|
-
const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
|
|
39
|
+
const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
|
|
40
40
|
const { verifier } = m.useModule(VerifierModule);
|
|
41
41
|
const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
|
|
42
42
|
const { verifier: depositVerifier } = m.useModule(DepositVerifierModule);
|
|
@@ -54,6 +54,7 @@ export default buildModule("Zeto_AnonEncNullifier", (m) => {
|
|
|
54
54
|
batchVerifier,
|
|
55
55
|
batchWithdrawVerifier,
|
|
56
56
|
smtLib,
|
|
57
|
+
poseidon2,
|
|
57
58
|
poseidon3,
|
|
58
59
|
};
|
|
59
60
|
});
|
|
@@ -45,7 +45,7 @@ const BatchVerifierModule = buildModule(
|
|
|
45
45
|
);
|
|
46
46
|
|
|
47
47
|
export default buildModule("Zeto_AnonEncNullifierNonRepudiation", (m) => {
|
|
48
|
-
const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
|
|
48
|
+
const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
|
|
49
49
|
const { verifier } = m.useModule(VerifierModule);
|
|
50
50
|
const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
|
|
51
51
|
const { verifier: depositVerifier } = m.useModule(DepositVerifierModule);
|
|
@@ -62,6 +62,7 @@ export default buildModule("Zeto_AnonEncNullifierNonRepudiation", (m) => {
|
|
|
62
62
|
batchVerifier,
|
|
63
63
|
batchWithdrawVerifier,
|
|
64
64
|
smtLib,
|
|
65
|
+
poseidon2,
|
|
65
66
|
poseidon3,
|
|
66
67
|
};
|
|
67
68
|
});
|
|
@@ -64,7 +64,7 @@ const BatchLockVerifierModule = buildModule(
|
|
|
64
64
|
);
|
|
65
65
|
|
|
66
66
|
export default buildModule("Zeto_AnonNullifier", (m) => {
|
|
67
|
-
const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
|
|
67
|
+
const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
|
|
68
68
|
const { verifier } = m.useModule(VerifierModule);
|
|
69
69
|
const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
|
|
70
70
|
const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
|
|
@@ -86,6 +86,7 @@ export default buildModule("Zeto_AnonNullifier", (m) => {
|
|
|
86
86
|
batchLockVerifier,
|
|
87
87
|
batchWithdrawVerifier,
|
|
88
88
|
smtLib,
|
|
89
|
+
poseidon2,
|
|
89
90
|
poseidon3,
|
|
90
91
|
};
|
|
91
92
|
});
|
|
@@ -68,7 +68,7 @@ const BatchBurnNullifierVerifierModule = buildModule("Groth16Verifier_BurnNullif
|
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
export default buildModule("Zeto_AnonNullifier", (m) => {
|
|
71
|
-
const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
|
|
71
|
+
const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
|
|
72
72
|
const { verifier } = m.useModule(VerifierModule);
|
|
73
73
|
const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
|
|
74
74
|
const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
|
|
@@ -98,6 +98,7 @@ export default buildModule("Zeto_AnonNullifier", (m) => {
|
|
|
98
98
|
burnVerifier,
|
|
99
99
|
batchBurnVerifier,
|
|
100
100
|
smtLib,
|
|
101
|
+
poseidon2,
|
|
101
102
|
poseidon3,
|
|
102
103
|
};
|
|
103
104
|
});
|
|
@@ -64,7 +64,7 @@ const BatchVerifierModule = buildModule(
|
|
|
64
64
|
// );
|
|
65
65
|
|
|
66
66
|
export default buildModule("Zeto_AnonNullifierQurrency", (m) => {
|
|
67
|
-
const { smtLib, poseidon3, poseidon5, poseidon6 } = m.useModule(SmtLibModule);
|
|
67
|
+
const { smtLib, poseidon2, poseidon3, poseidon5, poseidon6 } = m.useModule(SmtLibModule);
|
|
68
68
|
const { verifier } = m.useModule(VerifierModule);
|
|
69
69
|
// const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
|
|
70
70
|
const { verifier: batchVerifier } = m.useModule(BatchVerifierModule);
|
|
@@ -86,6 +86,7 @@ export default buildModule("Zeto_AnonNullifierQurrency", (m) => {
|
|
|
86
86
|
// batchLockVerifier,
|
|
87
87
|
batchWithdrawVerifier,
|
|
88
88
|
smtLib,
|
|
89
|
+
poseidon2,
|
|
89
90
|
poseidon3,
|
|
90
91
|
poseidon5,
|
|
91
92
|
poseidon6,
|
|
@@ -37,9 +37,9 @@ const LockVerifierModule = buildModule(
|
|
|
37
37
|
);
|
|
38
38
|
|
|
39
39
|
export default buildModule("Zeto_NfAnonNullifier", (m) => {
|
|
40
|
-
const { smtLib, poseidon3 } = m.useModule(SmtLibModule);
|
|
40
|
+
const { smtLib, poseidon2, poseidon3 } = m.useModule(SmtLibModule);
|
|
41
41
|
const { verifier } = m.useModule(VerifierModule);
|
|
42
42
|
const { verifier: lockVerifier } = m.useModule(LockVerifierModule);
|
|
43
43
|
|
|
44
|
-
return { verifier, lockVerifier, smtLib, poseidon3 };
|
|
44
|
+
return { verifier, lockVerifier, smtLib, poseidon2, poseidon3 };
|
|
45
45
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lfdecentralizedtrust/zeto-contracts",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Zero knowledge proof based UTXO tokens toolkit for fungible or non-fungible assets",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"zeto-js": "file:../zkp/js"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@iden3/contracts": "
|
|
30
|
+
"@iden3/contracts": "git+https://github.com/kaleido-io/contracts.git#keccak256",
|
|
31
31
|
"@openzeppelin/contracts": "^5.1.0",
|
|
32
32
|
"@openzeppelin/contracts-upgradeable": "^5.0.2",
|
|
33
33
|
"@openzeppelin/hardhat-upgrades": "^3.2.1",
|
|
@@ -27,6 +27,7 @@ export async function deployDependencies() {
|
|
|
27
27
|
batchVerifier,
|
|
28
28
|
batchWithdrawVerifier,
|
|
29
29
|
smtLib,
|
|
30
|
+
poseidon2,
|
|
30
31
|
poseidon3,
|
|
31
32
|
} = await ignition.deploy(zetoModule);
|
|
32
33
|
return {
|
|
@@ -49,6 +50,7 @@ export async function deployDependencies() {
|
|
|
49
50
|
],
|
|
50
51
|
libraries: {
|
|
51
52
|
SmtLib: smtLib.target,
|
|
53
|
+
PoseidonUnit2L: poseidon2.target,
|
|
52
54
|
PoseidonUnit3L: poseidon3.target,
|
|
53
55
|
},
|
|
54
56
|
};
|
|
@@ -27,6 +27,7 @@ export async function deployDependencies() {
|
|
|
27
27
|
batchVerifier,
|
|
28
28
|
batchWithdrawVerifier,
|
|
29
29
|
smtLib,
|
|
30
|
+
poseidon2,
|
|
30
31
|
poseidon3,
|
|
31
32
|
} = await ignition.deploy(zetoModule);
|
|
32
33
|
return {
|
|
@@ -49,6 +50,7 @@ export async function deployDependencies() {
|
|
|
49
50
|
],
|
|
50
51
|
libraries: {
|
|
51
52
|
SmtLib: smtLib.target,
|
|
53
|
+
PoseidonUnit2L: poseidon2.target,
|
|
52
54
|
PoseidonUnit3L: poseidon3.target,
|
|
53
55
|
},
|
|
54
56
|
};
|
|
@@ -29,6 +29,7 @@ export async function deployDependencies() {
|
|
|
29
29
|
batchLockVerifier,
|
|
30
30
|
batchWithdrawVerifier,
|
|
31
31
|
smtLib,
|
|
32
|
+
poseidon2,
|
|
32
33
|
poseidon3,
|
|
33
34
|
} = await ignition.deploy(zetoModule);
|
|
34
35
|
return {
|
|
@@ -51,6 +52,7 @@ export async function deployDependencies() {
|
|
|
51
52
|
],
|
|
52
53
|
libraries: {
|
|
53
54
|
SmtLib: smtLib.target,
|
|
55
|
+
PoseidonUnit2L: poseidon2.target,
|
|
54
56
|
PoseidonUnit3L: poseidon3.target,
|
|
55
57
|
},
|
|
56
58
|
};
|
|
@@ -31,6 +31,7 @@ export async function deployDependencies() {
|
|
|
31
31
|
burnVerifier,
|
|
32
32
|
batchBurnVerifier,
|
|
33
33
|
smtLib,
|
|
34
|
+
poseidon2,
|
|
34
35
|
poseidon3,
|
|
35
36
|
} = await ignition.deploy(zetoModule);
|
|
36
37
|
return {
|
|
@@ -53,6 +54,7 @@ export async function deployDependencies() {
|
|
|
53
54
|
],
|
|
54
55
|
libraries: {
|
|
55
56
|
SmtLib: smtLib.target,
|
|
57
|
+
PoseidonUnit2L: poseidon2.target,
|
|
56
58
|
PoseidonUnit3L: poseidon3.target,
|
|
57
59
|
},
|
|
58
60
|
};
|
|
@@ -29,6 +29,7 @@ export async function deployDependencies() {
|
|
|
29
29
|
// batchLockVerifier,
|
|
30
30
|
batchWithdrawVerifier,
|
|
31
31
|
smtLib,
|
|
32
|
+
poseidon2,
|
|
32
33
|
poseidon3,
|
|
33
34
|
poseidon5,
|
|
34
35
|
poseidon6,
|
|
@@ -53,6 +54,7 @@ export async function deployDependencies() {
|
|
|
53
54
|
],
|
|
54
55
|
libraries: {
|
|
55
56
|
SmtLib: smtLib.target,
|
|
57
|
+
PoseidonUnit2L: poseidon2.target,
|
|
56
58
|
PoseidonUnit3L: poseidon3.target,
|
|
57
59
|
PoseidonUnit5L: poseidon5.target,
|
|
58
60
|
PoseidonUnit6L: poseidon6.target,
|
|
@@ -20,7 +20,7 @@ import zetoModule from "../../ignition/modules/zeto_nf_anon_nullifier";
|
|
|
20
20
|
export async function deployDependencies() {
|
|
21
21
|
const [deployer] = await ethers.getSigners();
|
|
22
22
|
|
|
23
|
-
const { verifier, lockVerifier, smtLib, poseidon3 } =
|
|
23
|
+
const { verifier, lockVerifier, smtLib, poseidon2, poseidon3 } =
|
|
24
24
|
await ignition.deploy(zetoModule);
|
|
25
25
|
return {
|
|
26
26
|
deployer,
|
|
@@ -42,6 +42,7 @@ export async function deployDependencies() {
|
|
|
42
42
|
],
|
|
43
43
|
libraries: {
|
|
44
44
|
SmtLib: smtLib.target,
|
|
45
|
+
PoseidonUnit2L: poseidon2.target,
|
|
45
46
|
PoseidonUnit3L: poseidon3.target,
|
|
46
47
|
},
|
|
47
48
|
};
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
// Copyright © 2026 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
|
+
|
|
17
|
+
import { ethers, network, upgrades } from "hardhat";
|
|
18
|
+
import { Signer } from "ethers";
|
|
19
|
+
import { expect } from "chai";
|
|
20
|
+
|
|
21
|
+
describe("(factory upgradeable) Zeto based fungible token with anonymity without encryption or nullifier", function () {
|
|
22
|
+
let deployer: Signer;
|
|
23
|
+
let nonOwner: Signer;
|
|
24
|
+
|
|
25
|
+
before(async function () {
|
|
26
|
+
if (network.name !== "hardhat") {
|
|
27
|
+
// accommodate for longer block times on public networks
|
|
28
|
+
this.timeout(120000);
|
|
29
|
+
}
|
|
30
|
+
[deployer, nonOwner] = await ethers.getSigners();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
async function deployFactory() {
|
|
34
|
+
const Factory = await ethers.getContractFactory(
|
|
35
|
+
"ZetoTokenFactoryUpgradeable",
|
|
36
|
+
);
|
|
37
|
+
const proxy = await upgrades.deployProxy(Factory, [], {
|
|
38
|
+
kind: "uups",
|
|
39
|
+
initializer: "initialize",
|
|
40
|
+
});
|
|
41
|
+
await proxy.waitForDeployment();
|
|
42
|
+
return await ethers.getContractAt(
|
|
43
|
+
"ZetoTokenFactoryUpgradeable",
|
|
44
|
+
await proxy.getAddress(),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
it("attempting to register an implementation as a non-owner should fail", async function () {
|
|
49
|
+
const factory = await deployFactory();
|
|
50
|
+
|
|
51
|
+
const implInfo = {
|
|
52
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
53
|
+
verifiers: {
|
|
54
|
+
verifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
55
|
+
batchVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
56
|
+
depositVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
57
|
+
withdrawVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
58
|
+
batchWithdrawVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
59
|
+
lockVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
60
|
+
batchLockVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
61
|
+
burnVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
62
|
+
batchBurnVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
await expect(
|
|
66
|
+
factory.connect(nonOwner).registerImplementation("test", implInfo as any),
|
|
67
|
+
).rejectedWith(`reverted with custom error 'OwnableUnauthorizedAccount(`);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it("attempting to initialize twice should fail", async function () {
|
|
71
|
+
const factory = await deployFactory();
|
|
72
|
+
|
|
73
|
+
await expect(factory.initialize()).rejectedWith("InvalidInitialization");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("attempting to register an implementation without the required implementation value should fail", async function () {
|
|
77
|
+
const factory = await deployFactory();
|
|
78
|
+
|
|
79
|
+
const implInfo = {
|
|
80
|
+
implementation: "0x0000000000000000000000000000000000000000",
|
|
81
|
+
verifiers: {
|
|
82
|
+
verifier: "0x0000000000000000000000000000000000000000",
|
|
83
|
+
batchVerifier: "0x0000000000000000000000000000000000000000",
|
|
84
|
+
depositVerifier: "0x0000000000000000000000000000000000000000",
|
|
85
|
+
withdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
86
|
+
batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
87
|
+
lockVerifier: "0x0000000000000000000000000000000000000000",
|
|
88
|
+
batchLockVerifier: "0x0000000000000000000000000000000000000000",
|
|
89
|
+
burnVerifier: "0x0000000000000000000000000000000000000000",
|
|
90
|
+
batchBurnVerifier: "0x0000000000000000000000000000000000000000",
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
await expect(
|
|
94
|
+
factory.connect(deployer).registerImplementation("test", implInfo as any),
|
|
95
|
+
).rejectedWith("Factory: implementation address is required");
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("attempting to register an implementation without the required verifier value should fail", async function () {
|
|
99
|
+
const factory = await deployFactory();
|
|
100
|
+
|
|
101
|
+
const implInfo = {
|
|
102
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
103
|
+
verifiers: {
|
|
104
|
+
verifier: "0x0000000000000000000000000000000000000000",
|
|
105
|
+
batchVerifier: "0x0000000000000000000000000000000000000000",
|
|
106
|
+
depositVerifier: "0x0000000000000000000000000000000000000000",
|
|
107
|
+
withdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
108
|
+
batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
109
|
+
lockVerifier: "0x0000000000000000000000000000000000000000",
|
|
110
|
+
batchLockVerifier: "0x0000000000000000000000000000000000000000",
|
|
111
|
+
burnVerifier: "0x0000000000000000000000000000000000000000",
|
|
112
|
+
batchBurnVerifier: "0x0000000000000000000000000000000000000000",
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
await expect(
|
|
116
|
+
factory.connect(deployer).registerImplementation("test", implInfo as any),
|
|
117
|
+
).rejectedWith("Factory: verifier address is required");
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("attempting to register an implementation with the required values should succeed", async function () {
|
|
121
|
+
const factory = await deployFactory();
|
|
122
|
+
|
|
123
|
+
const implInfo = {
|
|
124
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
125
|
+
verifiers: {
|
|
126
|
+
verifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
127
|
+
batchVerifier: "0x0000000000000000000000000000000000000000",
|
|
128
|
+
depositVerifier: "0x0000000000000000000000000000000000000000",
|
|
129
|
+
withdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
130
|
+
batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
131
|
+
lockVerifier: "0x0000000000000000000000000000000000000000",
|
|
132
|
+
batchLockVerifier: "0x0000000000000000000000000000000000000000",
|
|
133
|
+
burnVerifier: "0x0000000000000000000000000000000000000000",
|
|
134
|
+
batchBurnVerifier: "0x0000000000000000000000000000000000000000",
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
await expect(
|
|
138
|
+
factory.connect(deployer).registerImplementation("test", implInfo as any),
|
|
139
|
+
).fulfilled;
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("attempting to deploy a fungible token but with a registered implementation that misses required batchVerifier should fail", async function () {
|
|
143
|
+
const factory = await deployFactory();
|
|
144
|
+
|
|
145
|
+
const implInfo = {
|
|
146
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
147
|
+
verifiers: {
|
|
148
|
+
verifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
149
|
+
batchVerifier: "0x0000000000000000000000000000000000000000",
|
|
150
|
+
depositVerifier: "0x0000000000000000000000000000000000000000",
|
|
151
|
+
withdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
152
|
+
batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
153
|
+
lockVerifier: "0x0000000000000000000000000000000000000000",
|
|
154
|
+
batchLockVerifier: "0x0000000000000000000000000000000000000000",
|
|
155
|
+
burnVerifier: "0x0000000000000000000000000000000000000000",
|
|
156
|
+
batchBurnVerifier: "0x0000000000000000000000000000000000000000",
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
const tx1 = await factory
|
|
160
|
+
.connect(deployer)
|
|
161
|
+
.registerImplementation("test", implInfo as any);
|
|
162
|
+
await tx1.wait();
|
|
163
|
+
|
|
164
|
+
await expect(
|
|
165
|
+
factory
|
|
166
|
+
.connect(deployer)
|
|
167
|
+
.deployZetoFungibleToken(
|
|
168
|
+
"name",
|
|
169
|
+
"symbol",
|
|
170
|
+
"test",
|
|
171
|
+
await deployer.getAddress(),
|
|
172
|
+
),
|
|
173
|
+
).rejectedWith("Factory: depositVerifier address is required");
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("attempting to deploy a fungible token but with a registered implementation that misses required depositVerifier should fail", async function () {
|
|
177
|
+
const factory = await deployFactory();
|
|
178
|
+
|
|
179
|
+
const implInfo = {
|
|
180
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
181
|
+
verifiers: {
|
|
182
|
+
verifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
183
|
+
batchVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
184
|
+
depositVerifier: "0x0000000000000000000000000000000000000000",
|
|
185
|
+
withdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
186
|
+
batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
187
|
+
lockVerifier: "0x0000000000000000000000000000000000000000",
|
|
188
|
+
batchLockVerifier: "0x0000000000000000000000000000000000000000",
|
|
189
|
+
burnVerifier: "0x0000000000000000000000000000000000000000",
|
|
190
|
+
batchBurnVerifier: "0x0000000000000000000000000000000000000000",
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
const tx1 = await factory
|
|
194
|
+
.connect(deployer)
|
|
195
|
+
.registerImplementation("test", implInfo as any);
|
|
196
|
+
await tx1.wait();
|
|
197
|
+
|
|
198
|
+
await expect(
|
|
199
|
+
factory
|
|
200
|
+
.connect(deployer)
|
|
201
|
+
.deployZetoFungibleToken(
|
|
202
|
+
"name",
|
|
203
|
+
"symbol",
|
|
204
|
+
"test",
|
|
205
|
+
await deployer.getAddress(),
|
|
206
|
+
),
|
|
207
|
+
).rejectedWith("Factory: depositVerifier address is required");
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it("attempting to deploy a fungible token but with a registered implementation that misses required withdrawVerifier should fail", async function () {
|
|
211
|
+
const factory = await deployFactory();
|
|
212
|
+
|
|
213
|
+
const implInfo = {
|
|
214
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
215
|
+
verifiers: {
|
|
216
|
+
verifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
217
|
+
batchVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
218
|
+
depositVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
219
|
+
withdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
220
|
+
batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
221
|
+
lockVerifier: "0x0000000000000000000000000000000000000000",
|
|
222
|
+
batchLockVerifier: "0x0000000000000000000000000000000000000000",
|
|
223
|
+
burnVerifier: "0x0000000000000000000000000000000000000000",
|
|
224
|
+
batchBurnVerifier: "0x0000000000000000000000000000000000000000",
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
const tx1 = await factory
|
|
228
|
+
.connect(deployer)
|
|
229
|
+
.registerImplementation("test", implInfo as any);
|
|
230
|
+
await tx1.wait();
|
|
231
|
+
|
|
232
|
+
await expect(
|
|
233
|
+
factory
|
|
234
|
+
.connect(deployer)
|
|
235
|
+
.deployZetoFungibleToken(
|
|
236
|
+
"name",
|
|
237
|
+
"symbol",
|
|
238
|
+
"test",
|
|
239
|
+
await deployer.getAddress(),
|
|
240
|
+
),
|
|
241
|
+
).rejectedWith("Factory: withdrawVerifier address is required");
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
it("attempting to deploy a fungible token but with a registered implementation that misses required batchWithdrawVerifier should fail", async function () {
|
|
245
|
+
const factory = await deployFactory();
|
|
246
|
+
|
|
247
|
+
const implInfo = {
|
|
248
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
249
|
+
verifiers: {
|
|
250
|
+
verifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
251
|
+
batchVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
252
|
+
depositVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
253
|
+
withdrawVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
254
|
+
batchWithdrawVerifier: "0x0000000000000000000000000000000000000000",
|
|
255
|
+
lockVerifier: "0x0000000000000000000000000000000000000000",
|
|
256
|
+
batchLockVerifier: "0x0000000000000000000000000000000000000000",
|
|
257
|
+
burnVerifier: "0x0000000000000000000000000000000000000000",
|
|
258
|
+
batchBurnVerifier: "0x0000000000000000000000000000000000000000",
|
|
259
|
+
},
|
|
260
|
+
};
|
|
261
|
+
const tx1 = await factory
|
|
262
|
+
.connect(deployer)
|
|
263
|
+
.registerImplementation("test", implInfo as any);
|
|
264
|
+
await tx1.wait();
|
|
265
|
+
|
|
266
|
+
await expect(
|
|
267
|
+
factory
|
|
268
|
+
.connect(deployer)
|
|
269
|
+
.deployZetoFungibleToken(
|
|
270
|
+
"name",
|
|
271
|
+
"symbol",
|
|
272
|
+
"test",
|
|
273
|
+
await deployer.getAddress(),
|
|
274
|
+
),
|
|
275
|
+
).rejectedWith("Factory: batchWithdrawVerifier address is required");
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("attempting to deploy a fungible token with a properly registered implementation should succeed", async function () {
|
|
279
|
+
const factory = await deployFactory();
|
|
280
|
+
|
|
281
|
+
const implInfo = {
|
|
282
|
+
implementation: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
283
|
+
verifiers: {
|
|
284
|
+
verifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
285
|
+
batchVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
286
|
+
depositVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
287
|
+
withdrawVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
288
|
+
batchWithdrawVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
289
|
+
lockVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
290
|
+
batchLockVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
291
|
+
burnVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
292
|
+
batchBurnVerifier: "0xae92d5aD7583AD66E49A0c67BAd18F6ba52dDDc1",
|
|
293
|
+
},
|
|
294
|
+
};
|
|
295
|
+
const tx1 = await factory
|
|
296
|
+
.connect(deployer)
|
|
297
|
+
.registerImplementation("test", implInfo as any);
|
|
298
|
+
await tx1.wait();
|
|
299
|
+
|
|
300
|
+
await expect(
|
|
301
|
+
factory
|
|
302
|
+
.connect(deployer)
|
|
303
|
+
.deployZetoFungibleToken(
|
|
304
|
+
"name",
|
|
305
|
+
"symbol",
|
|
306
|
+
"test",
|
|
307
|
+
await deployer.getAddress(),
|
|
308
|
+
),
|
|
309
|
+
).fulfilled;
|
|
310
|
+
});
|
|
311
|
+
});
|