@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/README.md
CHANGED
|
@@ -1,191 +1,99 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Zeto Solidity contracts
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Privacy-preserving token implementations for fungible and non-fungible assets, built with the Zeto ZK toolkit (Groth16 circuits, UTXO model, optional nullifiers and encryption).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Prerequisites
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Node.js (see repo CI for supported versions).
|
|
8
|
+
- From this directory (`solidity/`), install dependencies:
|
|
9
|
+
|
|
10
|
+
```console
|
|
11
|
+
npm install
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Hardhat and related tooling are pulled in via `@nomicfoundation/hardhat-toolbox`; you do not need to run `hardhat init` in this repository.
|
|
15
|
+
|
|
16
|
+
### Circuits and proving keys
|
|
17
|
+
|
|
18
|
+
Hardhat tests load circuit WASM via **`zeto-js`** (`file:../zkp/js`). Before running tests:
|
|
19
|
+
|
|
20
|
+
1. Build **zkp/js** and produce **proving keys** and verification artifacts as described in [`../zkp/js/README.md`](../zkp/js/README.md) (build section).
|
|
21
|
+
2. Ensure **`zeto-js` unit tests pass** in `zkp/js` before relying on Solidity tests here.
|
|
22
|
+
3. Set environment variables so tests can find WASM and keys (same layout as CI):
|
|
23
|
+
|
|
24
|
+
- **`CIRCUITS_ROOT`**: directory containing compiled circuit artifacts (e.g. `anon_js/`, `anon_nullifier_transfer_js/`, …).
|
|
25
|
+
- **`PROVING_KEYS_ROOT`**: directory containing the proving key files referenced by the test harness.
|
|
26
|
+
|
|
27
|
+
Example:
|
|
8
28
|
|
|
9
29
|
```console
|
|
10
|
-
|
|
11
|
-
|
|
30
|
+
export CIRCUITS_ROOT=/path/to/zeto-artifacts
|
|
31
|
+
export PROVING_KEYS_ROOT=/path/to/zeto-artifacts
|
|
32
|
+
npm test
|
|
12
33
|
```
|
|
13
34
|
|
|
14
|
-
|
|
35
|
+
### `@iden3/contracts` (nullifier / SMT)
|
|
36
|
+
|
|
37
|
+
Tokens that use nullifiers depend on iden3’s Sparse Merkle Tree Solidity library. This workspace expects it at **`../../contracts`** relative to `solidity/` (see `package.json`: `"@iden3/contracts": "file:../../contracts"`).
|
|
15
38
|
|
|
16
|
-
|
|
39
|
+
Clone [kaleido-io/contracts](https://github.com/kaleido-io/contracts) (branch **`keccak256`**) next to the **zeto** repo root so the layout is:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
contracts/ # iden3 SMT package (branch keccak256)
|
|
43
|
+
package.json
|
|
44
|
+
...
|
|
45
|
+
zeto/
|
|
46
|
+
solidity/
|
|
47
|
+
zkp/
|
|
48
|
+
...
|
|
49
|
+
```
|
|
17
50
|
|
|
18
|
-
|
|
51
|
+
Run **`npm install`** in the **`contracts`** checkout so the file dependency resolves.
|
|
19
52
|
|
|
20
|
-
##
|
|
53
|
+
## Deploying token contracts
|
|
21
54
|
|
|
22
|
-
|
|
55
|
+
Scripts deploy the token named by **`ZETO_NAME`** (see `scripts/tokens.json` / Ignition modules for valid names).
|
|
56
|
+
|
|
57
|
+
### Upgradeable (UUPS proxy)
|
|
58
|
+
|
|
59
|
+
Deploys the implementation plus an ERC1967 proxy and runs `initialize`. Suitable when you want upgradeability via OpenZeppelin’s UUPS pattern.
|
|
23
60
|
|
|
24
61
|
```console
|
|
25
62
|
export ZETO_NAME=Zeto_AnonEncNullifier
|
|
26
63
|
npx hardhat run scripts/deploy_upgradeable.ts
|
|
27
64
|
```
|
|
28
65
|
|
|
29
|
-
|
|
66
|
+
Background: [Transparent vs UUPS proxies](https://docs.openzeppelin.com/contracts/5.x/api/proxy#transparent-vs-uups), [Upgrades plugin](https://docs.openzeppelin.com/upgrades-plugins/proxies).
|
|
30
67
|
|
|
31
|
-
|
|
68
|
+
### Cloneable / factory workflow
|
|
32
69
|
|
|
33
70
|
```console
|
|
34
71
|
export ZETO_NAME=Zeto_AnonEncNullifier
|
|
35
72
|
npx hardhat run scripts/deploy_cloneable.ts
|
|
36
73
|
```
|
|
37
74
|
|
|
38
|
-
|
|
75
|
+
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
|
+
|
|
77
|
+
For a single initialized deployment without the factory path, use **`deploy_upgradeable.ts`**.
|
|
39
78
|
|
|
40
|
-
|
|
79
|
+
Cheap repeat deployments: OpenZeppelin [minimal proxies / Clones](https://docs.openzeppelin.com/contracts/5.x/api/utils#Clones).
|
|
41
80
|
|
|
42
|
-
|
|
81
|
+
## Running tests
|
|
43
82
|
|
|
44
83
|
```console
|
|
45
|
-
npm
|
|
46
|
-
npm
|
|
47
|
-
|
|
48
|
-
> zeto@0.0.1 test
|
|
49
|
-
> npx hardhat test
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Registry tests
|
|
54
|
-
Registry deployed to 0x5FbDB2315678afecb367f032d93F642f64180aa3
|
|
55
|
-
✔ should register a new user (43ms)
|
|
56
|
-
✔ should return the correct public key
|
|
57
|
-
|
|
58
|
-
Zeto based fungible token with anonymity without encryption or nullifier
|
|
59
|
-
Method mint() complete. Gas used: 75301
|
|
60
|
-
Witness calculation time: 38ms, Proof generation time: 334ms
|
|
61
|
-
Method transfer() complete. Gas used: 336231
|
|
62
|
-
✔ mint to Alice and transfer UTXOs honestly to Bob should succeed (395ms)
|
|
63
|
-
Method mint() complete. Gas used: 50947
|
|
64
|
-
Witness calculation time: 19ms, Proof generation time: 179ms
|
|
65
|
-
Method transfer() complete. Gas used: 336337
|
|
66
|
-
✔ Bob transfers UTXOs, previously received from Alice, honestly to Charlie should succeed (215ms)
|
|
67
|
-
✔ mint existing unspent UTXOs should fail
|
|
68
|
-
✔ mint existing spent UTXOs should fail
|
|
69
|
-
Witness calculation time: 20ms, Proof generation time: 178ms
|
|
70
|
-
✔ transfer non-existing UTXOs should fail (207ms)
|
|
71
|
-
Witness calculation time: 20ms, Proof generation time: 181ms
|
|
72
|
-
✔ transfer spent UTXOs should fail (double spend protection) (210ms)
|
|
73
|
-
Witness calculation time: 19ms, Proof generation time: 193ms
|
|
74
|
-
✔ spend by using the same UTXO as both inputs should fail (222ms)
|
|
75
|
-
|
|
76
|
-
Zeto based fungible token with anonymity and encryption
|
|
77
|
-
Method mint() complete. Gas used: 75301
|
|
78
|
-
Witness calculation time: 52ms, Proof generation time: 359ms
|
|
79
|
-
Method transfer() complete. Gas used: 362628
|
|
80
|
-
✔ mint to Alice and transfer UTXOs honestly to Bob should succeed (449ms)
|
|
81
|
-
Witness calculation time: 33ms, Proof generation time: 336ms
|
|
82
|
-
Method transfer() complete. Gas used: 355662
|
|
83
|
-
✔ Bob transfers UTXOs, previously received from Alice, honestly to Charlie should succeed (383ms)
|
|
84
|
-
✔ mint existing unspent UTXOs should fail
|
|
85
|
-
✔ mint existing spent UTXOs should fail
|
|
86
|
-
Witness calculation time: 32ms, Proof generation time: 334ms
|
|
87
|
-
✔ transfer non-existing UTXOs should fail (376ms)
|
|
88
|
-
Witness calculation time: 33ms, Proof generation time: 378ms
|
|
89
|
-
✔ transfer spent UTXOs should fail (double spend protection) (421ms)
|
|
90
|
-
Method mint() complete. Gas used: 50959
|
|
91
|
-
Witness calculation time: 33ms, Proof generation time: 341ms
|
|
92
|
-
✔ spend by using the same UTXO as both inputs should fail (385ms)
|
|
93
|
-
|
|
94
|
-
Zeto based fungible token with anonymity using nullifiers and encryption
|
|
95
|
-
✔ onchain SMT root should be equal to the offchain SMT root
|
|
96
|
-
Method mint() complete. Gas used: 823254
|
|
97
|
-
Witness calculation time: 118ms. Proof generation time: 2288ms.
|
|
98
|
-
Time to execute transaction: 40ms. Gas used: 1763072
|
|
99
|
-
✔ mint to Alice and transfer UTXOs honestly to Bob should succeed (2491ms)
|
|
100
|
-
Witness calculation time: 80ms. Proof generation time: 2235ms.
|
|
101
|
-
Time to execute transaction: 28ms. Gas used: 1677252
|
|
102
|
-
✔ Bob transfers UTXOs, previously received from Alice, honestly to Charlie should succeed (2351ms)
|
|
103
|
-
✔ mint existing unspent UTXOs should fail
|
|
104
|
-
✔ mint existing spent UTXOs should fail
|
|
105
|
-
Witness calculation time: 77ms. Proof generation time: 2345ms.
|
|
106
|
-
✔ transfer spent UTXOs should fail (double spend protection) (2435ms)
|
|
107
|
-
Method mint() complete. Gas used: 878936
|
|
108
|
-
Witness calculation time: 78ms. Proof generation time: 2248ms.
|
|
109
|
-
✔ transfer with existing UTXOs in the output should fail (mass conservation protection) (2362ms)
|
|
110
|
-
Witness calculation time: 77ms. Proof generation time: 2292ms.
|
|
111
|
-
✔ spend by using the same UTXO as both inputs should fail (2381ms)
|
|
112
|
-
Witness calculation time: 78ms. Proof generation time: 2324ms.
|
|
113
|
-
✔ transfer non-existing UTXOs should fail (2454ms)
|
|
114
|
-
|
|
115
|
-
Zeto based fungible token with anonymity using nullifiers without encryption
|
|
116
|
-
✔ onchain SMT root should be equal to the offchain SMT root
|
|
117
|
-
Method mint() complete. Gas used: 906173
|
|
118
|
-
Witness calculation time: 105ms. Proof generation time: 2151ms.
|
|
119
|
-
Time to execute transaction: 30ms. Gas used: 1737824
|
|
120
|
-
✔ mint to Alice and transfer UTXOs honestly to Bob should succeed (2312ms)
|
|
121
|
-
Witness calculation time: 63ms. Proof generation time: 2137ms.
|
|
122
|
-
Time to execute transaction: 33ms. Gas used: 2025451
|
|
123
|
-
✔ Bob transfers UTXOs, previously received from Alice, honestly to Charlie should succeed (2245ms)
|
|
124
|
-
✔ mint existing unspent UTXOs should fail
|
|
125
|
-
✔ mint existing spent UTXOs should fail
|
|
126
|
-
Witness calculation time: 64ms. Proof generation time: 2181ms.
|
|
127
|
-
✔ transfer spent UTXOs should fail (double spend protection) (2256ms)
|
|
128
|
-
Method mint() complete. Gas used: 941948
|
|
129
|
-
Witness calculation time: 64ms. Proof generation time: 2171ms.
|
|
130
|
-
✔ transfer with existing UTXOs in the output should fail (mass conservation protection) (2272ms)
|
|
131
|
-
Witness calculation time: 64ms. Proof generation time: 2128ms.
|
|
132
|
-
✔ spend by using the same UTXO as both inputs should fail (2202ms)
|
|
133
|
-
Witness calculation time: 63ms. Proof generation time: 2183ms.
|
|
134
|
-
✔ transfer non-existing UTXOs should fail (2294ms)
|
|
135
|
-
|
|
136
|
-
Zeto based non-fungible token with anonymity without encryption or nullifiers
|
|
137
|
-
Method mint() complete. Gas used: 50959
|
|
138
|
-
Witness calculation time: 39ms, Proof generation time: 116ms
|
|
139
|
-
Method transfer() complete. Gas used: 288112
|
|
140
|
-
✔ mint to Alice and transfer UTXOs honestly to Bob should succeed (170ms)
|
|
141
|
-
Witness calculation time: 19ms, Proof generation time: 120ms
|
|
142
|
-
Method transfer() complete. Gas used: 288136
|
|
143
|
-
✔ Bob transfers UTXOs, previously received from Alice, honestly to Charlie should succeed (152ms)
|
|
144
|
-
✔ mint existing unspent UTXOs should fail
|
|
145
|
-
✔ mint existing spent UTXOs should fail
|
|
146
|
-
Witness calculation time: 19ms, Proof generation time: 150ms
|
|
147
|
-
✔ transfer non-existing UTXOs should fail (179ms)
|
|
148
|
-
Witness calculation time: 18ms, Proof generation time: 115ms
|
|
149
|
-
✔ transfer spent UTXOs should fail (double spend protection) (141ms)
|
|
150
|
-
|
|
151
|
-
Zeto based non-fungible token with anonymity using nullifiers without encryption
|
|
152
|
-
✔ onchain SMT root should be equal to the offchain SMT root
|
|
153
|
-
Method mint() complete. Gas used: 338260
|
|
154
|
-
Witness calculation time: 84ms. Proof generation time: 1137ms.
|
|
155
|
-
Time to execute transaction: 17ms. Gas used: 796127
|
|
156
|
-
✔ mint to Alice and transfer UTXOs honestly to Bob should succeed (1250ms)
|
|
157
|
-
Witness calculation time: 46ms. Proof generation time: 1172ms.
|
|
158
|
-
Time to execute transaction: 19ms. Gas used: 909983
|
|
159
|
-
✔ Bob transfers UTXOs, previously received from Alice, honestly to Charlie should succeed (1243ms)
|
|
160
|
-
✔ mint existing unspent UTXOs should fail
|
|
161
|
-
✔ mint existing spent UTXOs should fail
|
|
162
|
-
Witness calculation time: 41ms. Proof generation time: 1146ms.
|
|
163
|
-
✔ transfer spent UTXOs should fail (double spend protection) (1196ms)
|
|
164
|
-
Witness calculation time: 38ms. Proof generation time: 1163ms.
|
|
165
|
-
✔ transfer non-existing UTXOs should fail (1229ms)
|
|
166
|
-
|
|
167
|
-
DvP flows between fungible and non-fungible tokens based on Zeto with anonymity without encryption or nullifiers
|
|
168
|
-
ZK Asset contract deployed at 0xf4B146FbA71F41E0592668ffbF264F1D186b2Ca8
|
|
169
|
-
ZK Payment contract deployed at 0xBEc49fA140aCaA83533fB00A2BB19bDdd0290f25
|
|
170
|
-
Method mint() complete. Gas used: 75289
|
|
171
|
-
✔ mint to Alice some payment tokens
|
|
172
|
-
Method mint() complete. Gas used: 75277
|
|
173
|
-
✔ mint to Bob some asset tokens
|
|
174
|
-
✔ Initiating a DvP transaction without payment input or asset input should fail
|
|
175
|
-
✔ Initiating a DvP transaction with payment input but no payment output should fail
|
|
176
|
-
✔ Initiating a DvP transaction with payment inputs and asset inputs should fail
|
|
177
|
-
✔ Initiating a DvP transaction with asset input but no asset output should fail
|
|
178
|
-
✔ Initiating a successful DvP transaction with payment inputs
|
|
179
|
-
✔ Initiating a successful DvP transaction with asset inputs
|
|
180
|
-
✔ Accepting a trade using an invalid trade ID should fail
|
|
181
|
-
✔ Failing cases for accepting a trade with payment terms
|
|
182
|
-
✔ Failing cases for accepting a trade with asset terms
|
|
183
|
-
Method mint() complete. Gas used: 50959
|
|
184
|
-
Method mint() complete. Gas used: 50959
|
|
185
|
-
Witness calculation time: 36ms, Proof generation time: 183ms
|
|
186
|
-
Witness calculation time: 38ms, Proof generation time: 121ms
|
|
187
|
-
✔ Initiating a successful DvP transaction with payment inputs and accepting by specifying asset inputs (421ms)
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
59 passing (41s)
|
|
84
|
+
npm install
|
|
85
|
+
npm test
|
|
191
86
|
```
|
|
87
|
+
|
|
88
|
+
`pretest` runs Prettier on `contracts`, `scripts`, `ignition`, and `test`; fix formatting or run `npm run prettier:fix` if the check fails.
|
|
89
|
+
|
|
90
|
+
Optional:
|
|
91
|
+
|
|
92
|
+
- **`USE_FACTORY=true`**: exercise the factory deployment path (cloneable impl + `ZetoTokenFactory`) in addition to the default upgradeable path when relevant tests support it.
|
|
93
|
+
|
|
94
|
+
Successful runs exercise mint/transfer/withdraw flows, nullifier trees, registry helpers, DvP samples, and gas-heavy suites depending on which circuits and keys are present.
|
|
95
|
+
|
|
96
|
+
## Further reading
|
|
97
|
+
|
|
98
|
+
- Token variants and feature matrix: [`doc-site/docs/implementations/`](../doc-site/docs/implementations/) (repository root).
|
|
99
|
+
- Circuit sources: [`../zkp/circuits/`](../zkp/circuits/).
|
package/contracts/factory.sol
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
// limitations under the License.
|
|
16
16
|
pragma solidity ^0.8.27;
|
|
17
17
|
|
|
18
|
-
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
|
|
19
18
|
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
|
20
|
-
import {
|
|
19
|
+
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
|
20
|
+
import {IZetoInitializable} from "./lib/interfaces/IZetoInitializable.sol";
|
|
21
21
|
|
|
22
22
|
contract ZetoTokenFactory is Ownable {
|
|
23
23
|
// all the addresses needed by the factory to
|
|
@@ -36,7 +36,7 @@ contract ZetoTokenFactory is Ownable {
|
|
|
36
36
|
constructor() Ownable(msg.sender) {}
|
|
37
37
|
|
|
38
38
|
function registerImplementation(
|
|
39
|
-
string
|
|
39
|
+
string calldata name,
|
|
40
40
|
ImplementationInfo memory implementation
|
|
41
41
|
) public onlyOwner {
|
|
42
42
|
require(
|
|
@@ -44,7 +44,7 @@ contract ZetoTokenFactory is Ownable {
|
|
|
44
44
|
"Factory: implementation address is required"
|
|
45
45
|
);
|
|
46
46
|
require(
|
|
47
|
-
implementation.verifiers.verifier != address(0),
|
|
47
|
+
address(implementation.verifiers.verifier) != address(0),
|
|
48
48
|
"Factory: verifier address is required"
|
|
49
49
|
);
|
|
50
50
|
// the depositVerifier and withdrawVerifier are optional
|
|
@@ -53,9 +53,9 @@ contract ZetoTokenFactory is Ownable {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
function deployZetoFungibleToken(
|
|
56
|
-
string
|
|
57
|
-
string
|
|
58
|
-
string
|
|
56
|
+
string calldata name,
|
|
57
|
+
string calldata symbol,
|
|
58
|
+
string calldata tokenImplementation,
|
|
59
59
|
address initialOwner
|
|
60
60
|
) public returns (address) {
|
|
61
61
|
ImplementationInfo memory args = implementations[tokenImplementation];
|
|
@@ -66,40 +66,38 @@ contract ZetoTokenFactory is Ownable {
|
|
|
66
66
|
// check that the registered implementation is for a fungible token
|
|
67
67
|
// and has the required verifier addresses
|
|
68
68
|
require(
|
|
69
|
-
args.verifiers.depositVerifier != address(0),
|
|
69
|
+
address(args.verifiers.depositVerifier) != address(0),
|
|
70
70
|
"Factory: depositVerifier address is required"
|
|
71
71
|
);
|
|
72
72
|
require(
|
|
73
|
-
args.verifiers.withdrawVerifier != address(0),
|
|
73
|
+
address(args.verifiers.withdrawVerifier) != address(0),
|
|
74
74
|
"Factory: withdrawVerifier address is required"
|
|
75
75
|
);
|
|
76
76
|
require(
|
|
77
|
-
args.verifiers.batchVerifier != address(0),
|
|
77
|
+
address(args.verifiers.batchVerifier) != address(0),
|
|
78
78
|
"Factory: batchVerifier address is required"
|
|
79
79
|
);
|
|
80
80
|
require(
|
|
81
|
-
args.verifiers.batchWithdrawVerifier != address(0),
|
|
81
|
+
address(args.verifiers.batchWithdrawVerifier) != address(0),
|
|
82
82
|
"Factory: batchWithdrawVerifier address is required"
|
|
83
83
|
);
|
|
84
|
-
address instance =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
initialOwner,
|
|
93
|
-
args.verifiers
|
|
84
|
+
address instance = address(
|
|
85
|
+
new ERC1967Proxy(
|
|
86
|
+
args.implementation,
|
|
87
|
+
abi.encodeCall(
|
|
88
|
+
IZetoInitializable.initialize,
|
|
89
|
+
(name, symbol, initialOwner, args.verifiers)
|
|
90
|
+
)
|
|
91
|
+
)
|
|
94
92
|
);
|
|
95
93
|
emit ZetoTokenDeployed(instance);
|
|
96
94
|
return instance;
|
|
97
95
|
}
|
|
98
96
|
|
|
99
97
|
function deployZetoNonFungibleToken(
|
|
100
|
-
string
|
|
101
|
-
string
|
|
102
|
-
string
|
|
98
|
+
string calldata name,
|
|
99
|
+
string calldata symbol,
|
|
100
|
+
string calldata tokenImplementation,
|
|
103
101
|
address initialOwner
|
|
104
102
|
) public returns (address) {
|
|
105
103
|
ImplementationInfo memory args = implementations[tokenImplementation];
|
|
@@ -107,16 +105,14 @@ contract ZetoTokenFactory is Ownable {
|
|
|
107
105
|
args.implementation != address(0),
|
|
108
106
|
"Factory: failed to find implementation"
|
|
109
107
|
);
|
|
110
|
-
address instance =
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
initialOwner,
|
|
119
|
-
args.verifiers
|
|
108
|
+
address instance = address(
|
|
109
|
+
new ERC1967Proxy(
|
|
110
|
+
args.implementation,
|
|
111
|
+
abi.encodeCall(
|
|
112
|
+
IZetoInitializable.initialize,
|
|
113
|
+
(name, symbol, initialOwner, args.verifiers)
|
|
114
|
+
)
|
|
115
|
+
)
|
|
120
116
|
);
|
|
121
117
|
emit ZetoTokenDeployed(instance);
|
|
122
118
|
return instance;
|
|
@@ -19,9 +19,13 @@ import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Ini
|
|
|
19
19
|
import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
|
20
20
|
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
|
21
21
|
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
|
|
22
|
-
import {IZetoInitializable} from "./lib/interfaces/
|
|
22
|
+
import {IZetoInitializable} from "./lib/interfaces/IZetoInitializable.sol";
|
|
23
23
|
|
|
24
|
-
contract ZetoTokenFactoryUpgradeable is
|
|
24
|
+
contract ZetoTokenFactoryUpgradeable is
|
|
25
|
+
Initializable,
|
|
26
|
+
OwnableUpgradeable,
|
|
27
|
+
UUPSUpgradeable
|
|
28
|
+
{
|
|
25
29
|
// all the addresses needed by the factory to
|
|
26
30
|
// clone a Zeto token and initialize it. The
|
|
27
31
|
// "implementation" is used to clone the token,
|
|
@@ -71,7 +75,7 @@ contract ZetoTokenFactoryUpgradeable is Initializable, OwnableUpgradeable, UUPSU
|
|
|
71
75
|
"Factory: implementation address is required"
|
|
72
76
|
);
|
|
73
77
|
require(
|
|
74
|
-
implementation.verifiers.verifier != address(0),
|
|
78
|
+
address(implementation.verifiers.verifier) != address(0),
|
|
75
79
|
"Factory: verifier address is required"
|
|
76
80
|
);
|
|
77
81
|
// the depositVerifier and withdrawVerifier are optional
|
|
@@ -95,19 +99,19 @@ contract ZetoTokenFactoryUpgradeable is Initializable, OwnableUpgradeable, UUPSU
|
|
|
95
99
|
// check that the registered implementation is for a fungible token
|
|
96
100
|
// and has the required verifier addresses
|
|
97
101
|
require(
|
|
98
|
-
args.verifiers.depositVerifier != address(0),
|
|
102
|
+
address(args.verifiers.depositVerifier) != address(0),
|
|
99
103
|
"Factory: depositVerifier address is required"
|
|
100
104
|
);
|
|
101
105
|
require(
|
|
102
|
-
args.verifiers.withdrawVerifier != address(0),
|
|
106
|
+
address(args.verifiers.withdrawVerifier) != address(0),
|
|
103
107
|
"Factory: withdrawVerifier address is required"
|
|
104
108
|
);
|
|
105
109
|
require(
|
|
106
|
-
args.verifiers.batchVerifier != address(0),
|
|
110
|
+
address(args.verifiers.batchVerifier) != address(0),
|
|
107
111
|
"Factory: batchVerifier address is required"
|
|
108
112
|
);
|
|
109
113
|
require(
|
|
110
|
-
args.verifiers.batchWithdrawVerifier != address(0),
|
|
114
|
+
address(args.verifiers.batchWithdrawVerifier) != address(0),
|
|
111
115
|
"Factory: batchWithdrawVerifier address is required"
|
|
112
116
|
);
|
|
113
117
|
address instance = Clones.clone(args.implementation);
|
|
@@ -0,0 +1,40 @@
|
|
|
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 {Arrays} from "@openzeppelin/contracts/utils/Arrays.sol";
|
|
19
|
+
import {PoseidonUnit3L} from "@iden3/contracts/contracts/lib/Poseidon.sol";
|
|
20
|
+
|
|
21
|
+
library Util {
|
|
22
|
+
function sortCommitments(
|
|
23
|
+
uint256[] memory utxos
|
|
24
|
+
) internal pure returns (uint256[] memory) {
|
|
25
|
+
uint256[] memory sorted = new uint256[](utxos.length);
|
|
26
|
+
for (uint256 i = 0; i < utxos.length; ++i) {
|
|
27
|
+
sorted[i] = utxos[i];
|
|
28
|
+
}
|
|
29
|
+
sorted = Arrays.sort(sorted);
|
|
30
|
+
return sorted;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function getLeafNodeHash(
|
|
34
|
+
uint256 index,
|
|
35
|
+
uint256 value
|
|
36
|
+
) internal pure returns (uint256) {
|
|
37
|
+
uint256[3] memory params = [index, value, uint256(1)];
|
|
38
|
+
return PoseidonUnit3L.poseidon(params);
|
|
39
|
+
}
|
|
40
|
+
}
|