@openzeppelin/compact-contracts 0.3.0-alpha.1 → 0.3.0-alpha.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/access/AccessControl.compact +1 -1
- package/access/Ownable.compact +1 -1
- package/access/ShieldedAccessControl.compact +1 -1
- package/access/ZOwnablePK.compact +1 -1
- package/crypto/EcdhMask.compact +1 -1
- package/crypto/ElGamal.compact +1 -1
- package/multisig/ForwarderPrivate.compact +2 -2
- package/multisig/ForwarderShielded.compact +2 -2
- package/multisig/ForwarderUnshielded.compact +2 -2
- package/multisig/ProposalManager.compact +35 -1
- package/multisig/ShieldedTreasury.compact +34 -4
- package/multisig/ShieldedTreasuryStateless.compact +46 -17
- package/multisig/Signer.compact +45 -41
- package/multisig/UnshieldedTreasury.compact +44 -17
- package/multisig/presets/ShieldedMultiSig.compact +4 -4
- package/multisig/presets/ShieldedMultiSigV2.compact +2 -2
- package/multisig/presets/ShieldedMultiSigV3.compact +2 -2
- package/multisig/presets/forwarder/ForwarderPrivate.compact +1 -1
- package/multisig/presets/forwarder/ForwarderShielded.compact +1 -1
- package/multisig/presets/forwarder/ForwarderUnshielded.compact +1 -1
- package/package.json +3 -3
- package/security/Allowlist.compact +1 -1
- package/security/Blocklist.compact +1 -1
- package/security/Initializable.compact +1 -1
- package/security/Pausable.compact +1 -1
- package/token/ConfidentialFungibleToken.compact +39 -11
- package/token/FungibleToken.compact +1 -1
- package/token/MultiToken.compact +1 -1
- package/token/NativeShieldedToken.compact +2 -2
- package/token/NativeShieldedTokenCore.compact +1 -1
- package/token/NativeShieldedTokenFamily.compact +2 -2
- package/token/NonFungibleToken.compact +1 -1
- package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +1 -1
- package/token/extensions/NativeShieldedTokenDerivedNonce.compact +1 -1
- package/token/extensions/{NativeShieldedTokenFamilySupply.compact → NativeShieldedTokenFamilyPublicSupply.compact} +9 -9
- package/token/extensions/{NativeShieldedTokenSupply.compact → NativeShieldedTokenPublicSupply.compact} +9 -9
- package/token/extensions/{NativeShieldedTokenSupplyCore.compact → NativeShieldedTokenPublicSupplyCore.compact} +9 -9
- package/utils/Utils.compact +1 -1
- package/multisig/SignerManager.compact +0 -205
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (multisig/presets/ShieldedMultiSigV2.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -24,7 +24,7 @@ import CompactStandardLibrary;
|
|
|
24
24
|
|
|
25
25
|
import "../ProposalManager" prefix Proposal_;
|
|
26
26
|
import "../ShieldedTreasuryStateless" prefix Treasury_;
|
|
27
|
-
import "../
|
|
27
|
+
import "../Signer"<Bytes<32>> prefix Signer_;
|
|
28
28
|
|
|
29
29
|
// ─── Types ──────────────────────────────────────────────────────
|
|
30
30
|
|
|
@@ -20,7 +20,7 @@ pragma language_version >= 0.23.0;
|
|
|
20
20
|
*
|
|
21
21
|
* - `mint` creates a new UTXO via `mintShieldedToken`, addressed to the
|
|
22
22
|
* contract. No external coin input; supply is produced on-chain.
|
|
23
|
-
* - `burn` consumes a UTXO via `sendShielded` to `
|
|
23
|
+
* - `burn` consumes a UTXO via `sendShielded` to `shieldedBurnAddress()`. Only
|
|
24
24
|
* coins of this contract's token type can be burned. Change is handled
|
|
25
25
|
* automatically by the transaction layer.
|
|
26
26
|
*
|
|
@@ -194,7 +194,7 @@ export circuit mint(
|
|
|
194
194
|
* @description Burns a shielded coin of this contract's token type,
|
|
195
195
|
* authorized by threshold signatures.
|
|
196
196
|
*
|
|
197
|
-
* Sends the specified amount of the supplied coin to `
|
|
197
|
+
* Sends the specified amount of the supplied coin to `shieldedBurnAddress()` via
|
|
198
198
|
* `sendShielded`. The nullifier is submitted on-chain, permanently marking
|
|
199
199
|
* the UTXO as spent.
|
|
200
200
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (multisig/presets/forwarder/ForwarderPrivate.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (multisig/presets/forwarder/ForwarderShielded.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (multisig/presets/forwarder/ForwarderUnshielded.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/compact-contracts",
|
|
3
|
-
"version": "0.3.0-alpha.
|
|
3
|
+
"version": "0.3.0-alpha.2",
|
|
4
4
|
"description": "OpenZeppelin Compact contract library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openzeppelin",
|
|
@@ -60,9 +60,9 @@
|
|
|
60
60
|
"@midnight-ntwrk/midnight-js-protocol": "4.1.1",
|
|
61
61
|
"@midnight-ntwrk/midnight-js-types": "4.1.1",
|
|
62
62
|
"@midnight-ntwrk/testkit-js": "4.1.1",
|
|
63
|
-
"@openzeppelin/compact-simulator": "^0.
|
|
63
|
+
"@openzeppelin/compact-simulator": "^0.3.1",
|
|
64
64
|
"@tsconfig/node24": "^24.0.4",
|
|
65
|
-
"@types/node": "26.1.
|
|
65
|
+
"@types/node": "26.1.2",
|
|
66
66
|
"@vitest/coverage-v8": "^4.1.10",
|
|
67
67
|
"fast-check": "^4.9.0",
|
|
68
68
|
"ts-node": "^10.9.2",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (token/ConfidentialFungibleToken.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -70,6 +70,14 @@ pragma language_version >= 0.23.0;
|
|
|
70
70
|
* depth), but that counter RESETS on `clearMemos`, so it is an in-epoch
|
|
71
71
|
* backstop only, never a substitute for freshness.
|
|
72
72
|
*
|
|
73
|
+
* Seed generation is a WALLET responsibility and OUT OF SCOPE for this
|
|
74
|
+
* contract, which cannot enforce it. The witness shipped in this repo
|
|
75
|
+
* (`test/witnesses/ConfidentialFungibleTokenWitnesses.ts`) is TEST-ONLY and
|
|
76
|
+
* returns a FIXED seed for reproducibility; it is NOT a production wallet. A
|
|
77
|
+
* production integration MUST supply a fresh, high-entropy, secret 32-byte seed
|
|
78
|
+
* per invocation from a CSPRNG; there is no production reference witness here, so
|
|
79
|
+
* confidentiality is only as strong as that external, not-yet-built wallet layer.
|
|
80
|
+
*
|
|
73
81
|
* @dev Plaintext disclosures (what reaches the public ledger):
|
|
74
82
|
* - This base discloses no amounts; supply accounting lives in a layer.
|
|
75
83
|
* - A public-supply layer reveals each mint/burn amount via the totalSupply
|
|
@@ -119,6 +127,17 @@ pragma language_version >= 0.23.0;
|
|
|
119
127
|
* calls dominate the credit-path row counts; there is currently no cheaper,
|
|
120
128
|
* upgrade-safe hasher available.
|
|
121
129
|
*
|
|
130
|
+
* @dev Runtime trust boundary. Confidentiality and integrity rest on the
|
|
131
|
+
* Midnight runtime enforcing two curve invariants this module does NOT re-check:
|
|
132
|
+
* every JubjubPoint reaching a curve op is cofactor-cleared into the prime-order
|
|
133
|
+
* subgroup (so off-curve, low-order, or mixed-order points make the circuit
|
|
134
|
+
* unsatisfiable), and `ecMul` faults on a scalar >= the subgroup order. These are
|
|
135
|
+
* regression-pinned with adversarial inputs in
|
|
136
|
+
* `crypto/test/CurveRuntimeInvariants.test.ts`, which fails loudly if a future
|
|
137
|
+
* runtime stops enforcing them. That is behavioral verification of the shipped
|
|
138
|
+
* runtime, NOT a formal audit of its circuit implementation (`midnight-circuits`),
|
|
139
|
+
* which remains an external trust assumption.
|
|
140
|
+
*
|
|
122
141
|
* @dev Caller-identity gating (composability). This module is unopinionated
|
|
123
142
|
* about compliance policy (freeze, KYC, pause); a composing contract layers
|
|
124
143
|
* that on top. Gating a circuit on an EXPLICIT argument (e.g. the recipient
|
|
@@ -147,18 +166,27 @@ pragma language_version >= 0.23.0;
|
|
|
147
166
|
* conflict. Documented limitation; acceptable for the v1 target use case
|
|
148
167
|
* (tokenized deposits).
|
|
149
168
|
*
|
|
169
|
+
* Domain separation. The memo KDF and per-operation randomness are
|
|
170
|
+
* domain-separated by a version tag but NOT bound to a chain id or
|
|
171
|
+
* contract-instance identifier, so cross-DEPLOYMENT isolation (the same wallet
|
|
172
|
+
* seed reused against two instances or two chains) relies on the seed-freshness
|
|
173
|
+
* requirement above rather than on the derivation itself. Binding `kernel.self()`
|
|
174
|
+
* into the derivations is a possible defense-in-depth hardening; under review, deferred.
|
|
175
|
+
*
|
|
150
176
|
* Block weight. A deploy bundles every exported entry point's on-chain IR into
|
|
151
177
|
* one transaction, and the value circuits are SHA256-heavy (k=16), so a
|
|
152
|
-
* full-surface deployment
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
178
|
+
* full-surface deployment is byte-heavy. Whether it fits is a property of the
|
|
179
|
+
* target network, not the contract: the per-transaction block byte budget is a
|
|
180
|
+
* governance-configurable, node-side ledger parameter. On the local ledger-8 dev
|
|
181
|
+
* stack the full surface exceeded it and was rejected (`1010: Transaction would
|
|
182
|
+
* exhaust the block limits`), while a reduced surface (e.g. receive + transfer,
|
|
183
|
+
* dropping allowances and supply accounting) fit. So confirm deployability
|
|
184
|
+
* against the target network; if a deployment is over budget there, the lever is
|
|
185
|
+
* exposing only the k=16 value operations it needs, not just trimming getters.
|
|
186
|
+
* A deployed contract can also be upgraded by its Contract Maintenance Authority
|
|
187
|
+
* (CMA), so an over-budget deployment can start with a lean surface and add
|
|
188
|
+
* operations by upgrade instead of fitting the whole surface into one deploy.
|
|
189
|
+
* Raising the limit itself is a node-side change, tracked upstream:
|
|
162
190
|
* https://github.com/midnightntwrk/midnight-node/issues/1202.
|
|
163
191
|
*
|
|
164
192
|
* Residual griefing. The dual-balance split (see `sweep`) stops dust
|
package/token/MultiToken.compact
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (token/NativeShieldedToken.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -45,7 +45,7 @@ pragma language_version >= 0.23.0;
|
|
|
45
45
|
* recipient-public.
|
|
46
46
|
*
|
|
47
47
|
* @notice Supply accounting is opt-in: this module tracks NO supply totals.
|
|
48
|
-
* Compose the optional `
|
|
48
|
+
* Compose the optional `NativeShieldedTokenPublicSupply` extension only if you need an
|
|
49
49
|
* on-chain `totalSupply()`; see it for the privacy trade-off it introduces (it
|
|
50
50
|
* makes contract-mediated burn amounts public).
|
|
51
51
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (token/NativeShieldedTokenFamily.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -53,7 +53,7 @@ pragma language_version >= 0.23.0;
|
|
|
53
53
|
* output, at the cost of making those mints recipient-public.
|
|
54
54
|
*
|
|
55
55
|
* @notice Supply accounting is opt-in: this module tracks NO supply totals.
|
|
56
|
-
* Compose the optional `
|
|
56
|
+
* Compose the optional `NativeShieldedTokenFamilyPublicSupply` extension only if you
|
|
57
57
|
* need an on-chain `totalSupply(domain)`; see it for the privacy trade-off it
|
|
58
58
|
* introduces (it makes contract-mediated burn amounts public).
|
|
59
59
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (token/extensions/ConfidentialFungibleTokenPublicSupply.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.3.0-alpha.2 (token/extensions/NativeShieldedTokenDerivedNonce.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.2.0 (token/extensions/
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.2.0 (token/extensions/NativeShieldedTokenFamilyPublicSupply.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @module
|
|
7
|
+
* @module NativeShieldedTokenFamilyPublicSupply
|
|
8
8
|
* @description Optional standalone extension that adds per-domain on-chain
|
|
9
9
|
* supply accounting to a `NativeShieldedTokenFamily`. It exposes `_addMinted` /
|
|
10
10
|
* `_addBurned` building blocks plus the `totalMinted` / `totalBurned` /
|
|
11
11
|
* `totalSupply` getters, each keyed by domain. It imports no token module.
|
|
12
12
|
*
|
|
13
|
-
* It is a thin wrapper over `
|
|
13
|
+
* It is a thin wrapper over `NativeShieldedTokenPublicSupplyCore`, forwarding the
|
|
14
14
|
* caller's per-call `domain`, so the accounting logic and guarantees live in
|
|
15
15
|
* the shared core.
|
|
16
16
|
*
|
|
@@ -51,25 +51,25 @@ pragma language_version >= 0.23.0;
|
|
|
51
51
|
*
|
|
52
52
|
* @dev Mint amounts are already public via the protocol's `shieldedMints`
|
|
53
53
|
* effect, so `_addMinted` adds accounting, not disclosure. See
|
|
54
|
-
* `
|
|
54
|
+
* `NativeShieldedTokenPublicSupplyCore` for the exact / lower-bound / upper-bound
|
|
55
55
|
* guarantees, the per-domain `burned <= minted` invariant, and the mint-side
|
|
56
56
|
* drift caveat.
|
|
57
57
|
*
|
|
58
58
|
* @warning Pair every mint with `_addMinted` and every burn with `_addBurned` on
|
|
59
59
|
* every path, under the matching domain; mis-wiring is a security-critical,
|
|
60
60
|
* undetectable error (e.g. an undercounted mint makes `_addBurned` reject
|
|
61
|
-
* legitimate burns). See `
|
|
61
|
+
* legitimate burns). See `NativeShieldedTokenPublicSupplyCore`.
|
|
62
62
|
*/
|
|
63
|
-
module
|
|
63
|
+
module NativeShieldedTokenFamilyPublicSupply {
|
|
64
64
|
import CompactStandardLibrary;
|
|
65
|
-
import "./
|
|
65
|
+
import "./NativeShieldedTokenPublicSupplyCore" prefix Core_;
|
|
66
66
|
|
|
67
67
|
// Circuits use the `Core_` prefix above. The named import/re-export below is
|
|
68
68
|
// only for the core supply ledger keys, so the implementing contract's ledger
|
|
69
69
|
// keys read as `_totalMinted` / `_totalBurned` rather than
|
|
70
|
-
// `
|
|
70
|
+
// `NativeShieldedTokenPublicSupplyCore__totalMinted`. The circuit names are
|
|
71
71
|
// intentionally NOT imported unprefixed, to avoid potential clashes.
|
|
72
|
-
import { _totalMinted, _totalBurned } from "./
|
|
72
|
+
import { _totalMinted, _totalBurned } from "./NativeShieldedTokenPublicSupplyCore";
|
|
73
73
|
export { _totalMinted, _totalBurned };
|
|
74
74
|
|
|
75
75
|
/**
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.2.0 (token/extensions/
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.2.0 (token/extensions/NativeShieldedTokenPublicSupply.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @module
|
|
7
|
+
* @module NativeShieldedTokenPublicSupply
|
|
8
8
|
* @description Optional standalone extension that adds on-chain supply
|
|
9
9
|
* accounting to a `NativeShieldedToken`. It exposes scalar `_addMinted` /
|
|
10
10
|
* `_addBurned` building blocks plus the `totalMinted` / `totalBurned` /
|
|
11
11
|
* `totalSupply` getters. It imports no token module.
|
|
12
12
|
*
|
|
13
|
-
* It is a thin wrapper over `
|
|
13
|
+
* It is a thin wrapper over `NativeShieldedTokenPublicSupplyCore`, forwarding a
|
|
14
14
|
* single fixed key (the paired contract has exactly one token type), so the
|
|
15
15
|
* accounting logic and guarantees live in the shared core.
|
|
16
16
|
*
|
|
@@ -48,24 +48,24 @@ pragma language_version >= 0.23.0;
|
|
|
48
48
|
*
|
|
49
49
|
* @dev Mint amounts are already public via the protocol's `shieldedMints`
|
|
50
50
|
* effect, so `_addMinted` adds accounting, not disclosure. See
|
|
51
|
-
* `
|
|
51
|
+
* `NativeShieldedTokenPublicSupplyCore` for the exact / lower-bound / upper-bound
|
|
52
52
|
* guarantees, the `burned <= minted` invariant, and the mint-side drift caveat.
|
|
53
53
|
*
|
|
54
54
|
* @warning Pair every mint with `_addMinted` and every burn with `_addBurned` on
|
|
55
55
|
* every path; mis-wiring is a security-critical, undetectable error (e.g. an
|
|
56
56
|
* undercounted mint makes `_addBurned` reject legitimate burns). See
|
|
57
|
-
* `
|
|
57
|
+
* `NativeShieldedTokenPublicSupplyCore`.
|
|
58
58
|
*/
|
|
59
|
-
module
|
|
59
|
+
module NativeShieldedTokenPublicSupply {
|
|
60
60
|
import CompactStandardLibrary;
|
|
61
|
-
import "./
|
|
61
|
+
import "./NativeShieldedTokenPublicSupplyCore" prefix Core_;
|
|
62
62
|
|
|
63
63
|
// Circuits use the `Core_` prefix above. The named import/re-export below is
|
|
64
64
|
// only for the core supply ledger keys, so the implementing contract's ledger
|
|
65
65
|
// keys read as `_totalMinted` / `_totalBurned` rather than
|
|
66
|
-
// `
|
|
66
|
+
// `NativeShieldedTokenPublicSupplyCore__totalMinted`. The circuit names are
|
|
67
67
|
// intentionally NOT imported unprefixed, to avoid potential clashes.
|
|
68
|
-
import { _totalMinted, _totalBurned } from "./
|
|
68
|
+
import { _totalMinted, _totalBurned } from "./NativeShieldedTokenPublicSupplyCore";
|
|
69
69
|
export { _totalMinted, _totalBurned };
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.2.0 (token/extensions/
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.2.0 (token/extensions/NativeShieldedTokenPublicSupplyCore.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.23.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
* @module
|
|
7
|
+
* @module NativeShieldedTokenPublicSupplyCore
|
|
8
8
|
* @description Shared, domain-keyed core of the optional supply-accounting
|
|
9
9
|
* extension. It owns the per-domain minted/burned maps and exposes the
|
|
10
10
|
* `_addMinted` / `_addBurned` building blocks plus the `totalMinted` /
|
|
@@ -13,12 +13,12 @@ pragma language_version >= 0.23.0;
|
|
|
13
13
|
* This module is NOT meant to be composed directly. It is the de-duplicated
|
|
14
14
|
* base behind the two user-facing flavors:
|
|
15
15
|
*
|
|
16
|
-
* - `
|
|
16
|
+
* - `NativeShieldedTokenPublicSupply` — pairs with `NativeShieldedToken`; forwards a
|
|
17
17
|
* single fixed key (the contract has one token type).
|
|
18
|
-
* - `
|
|
18
|
+
* - `NativeShieldedTokenFamilyPublicSupply` — pairs with `NativeShieldedTokenFamily`;
|
|
19
19
|
* forwards the caller's per-call `domain`.
|
|
20
20
|
*
|
|
21
|
-
* @dev Assertion messages use the generic `
|
|
21
|
+
* @dev Assertion messages use the generic `NativeShieldedTokenPublicSupply:` prefix
|
|
22
22
|
* so they read sensibly from either flavor. There is no initialization: an
|
|
23
23
|
* absent domain key reads as 0, and the getters do not gate on the paired token
|
|
24
24
|
* module's init flag (a counter reading 0 before init is correct), so init
|
|
@@ -51,7 +51,7 @@ pragma language_version >= 0.23.0;
|
|
|
51
51
|
* overstates circulating supply.
|
|
52
52
|
* Call the matching accounting block on every mint and burn path, same domain.
|
|
53
53
|
*/
|
|
54
|
-
module
|
|
54
|
+
module NativeShieldedTokenPublicSupplyCore {
|
|
55
55
|
import CompactStandardLibrary;
|
|
56
56
|
import "../../utils/Utils" prefix Utils_;
|
|
57
57
|
|
|
@@ -79,7 +79,7 @@ module NativeShieldedTokenSupplyCore {
|
|
|
79
79
|
*/
|
|
80
80
|
export circuit _addMinted(domain: Bytes<32>, amount: Uint<64>): [] {
|
|
81
81
|
const current = totalMinted(domain);
|
|
82
|
-
assert(Utils_UINT128_MAX() - current >= amount, "
|
|
82
|
+
assert(Utils_UINT128_MAX() - current >= amount, "NativeShieldedTokenPublicSupply: arithmetic overflow");
|
|
83
83
|
_totalMinted.insert(disclose(domain), disclose((current + amount) as Uint<128>));
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -103,8 +103,8 @@ module NativeShieldedTokenSupplyCore {
|
|
|
103
103
|
// First guards the subtraction below from underflowing on an already-corrupt
|
|
104
104
|
// state (stored burned past minted); the second is the reachable per-call
|
|
105
105
|
// check that this burn does not push the domain past its minted total.
|
|
106
|
-
assert(minted >= current, "
|
|
107
|
-
assert(minted - current >= amount, "
|
|
106
|
+
assert(minted >= current, "NativeShieldedTokenPublicSupply: burned total exceeds minted");
|
|
107
|
+
assert(minted - current >= amount, "NativeShieldedTokenPublicSupply: burn exceeds available supply");
|
|
108
108
|
_totalBurned.insert(disclose(domain), disclose((current + amount) as Uint<128>));
|
|
109
109
|
}
|
|
110
110
|
|
package/utils/Utils.compact
CHANGED
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.3.0-alpha.1 (multisig/SignerManager.compact)
|
|
3
|
-
|
|
4
|
-
pragma language_version >= 0.23.0;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @module SignerManager<T>
|
|
8
|
-
* @description Manages signer registry, threshold enforcement, and signer
|
|
9
|
-
* validation for multisig governance contracts.
|
|
10
|
-
*
|
|
11
|
-
* Parameterized over the signer identity type `T`, allowing the consuming
|
|
12
|
-
* contract to choose the identity mechanism at import time. Common
|
|
13
|
-
* instantiations include:
|
|
14
|
-
*
|
|
15
|
-
* - `Either<ZswapCoinPublicKey, ContractAddress>` for ownPublicKey()-based identity
|
|
16
|
-
* - `Bytes<32>` for commitment-based identity (e.g., hash of ECDSA public key)
|
|
17
|
-
* - `NativePoint` for Schnorr/MuSig aggregated key
|
|
18
|
-
*
|
|
19
|
-
* SignerManager does not resolve caller identity. It receives a validated
|
|
20
|
-
* caller from the contract layer and checks it against the registry.
|
|
21
|
-
* This separation allows the identity mechanism to change without
|
|
22
|
-
* modifying the module.
|
|
23
|
-
*
|
|
24
|
-
* Underscore-prefixed circuits (_addSigner, _removeSigner,
|
|
25
|
-
* _changeThreshold) have no access control enforcement. The consuming
|
|
26
|
-
* contract must gate these behind its own authorization policy.
|
|
27
|
-
*/
|
|
28
|
-
module SignerManager<T> {
|
|
29
|
-
import CompactStandardLibrary;
|
|
30
|
-
|
|
31
|
-
// ─── State ──────────────────────────────────────────────────────────────────
|
|
32
|
-
|
|
33
|
-
export ledger _signers: Set<T>;
|
|
34
|
-
export ledger _signerCount: Uint<8>;
|
|
35
|
-
export ledger _threshold: Uint<8>;
|
|
36
|
-
|
|
37
|
-
// ─── Initialization ─────────────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @description Initializes the signer manager with the given threshold
|
|
41
|
-
* and an initial set of signers.
|
|
42
|
-
* Must be called in the contract's constructor.
|
|
43
|
-
*
|
|
44
|
-
* Requirements:
|
|
45
|
-
*
|
|
46
|
-
* - `thresh` must be greater than 0.
|
|
47
|
-
* - `signers` must not contain duplicates.
|
|
48
|
-
*
|
|
49
|
-
* @param {Vector<n, T>} signers - The initial signer set.
|
|
50
|
-
* @param {Uint<8>} thresh - The minimum number of approvals required.
|
|
51
|
-
*
|
|
52
|
-
* @returns {[]} Empty tuple.
|
|
53
|
-
*/
|
|
54
|
-
export circuit initialize<#n>(
|
|
55
|
-
signers: Vector<n, T>,
|
|
56
|
-
thresh: Uint<8>
|
|
57
|
-
): [] {
|
|
58
|
-
assert(thresh > 0, "SignerManager: threshold must be > 0");
|
|
59
|
-
_threshold = disclose(thresh);
|
|
60
|
-
|
|
61
|
-
for (const signer of signers) {
|
|
62
|
-
_addSigner(signer);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
assert(_signerCount >= thresh, "SignerManager: threshold exceeds signer count");
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// ─── Guards ─────────────────────────────────────────────────────────────
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* @description Asserts that the given caller is an active signer.
|
|
72
|
-
*
|
|
73
|
-
* Requirements:
|
|
74
|
-
*
|
|
75
|
-
* - `caller` must be a member of the signers registry.
|
|
76
|
-
*
|
|
77
|
-
* @param {T} caller - The identity to validate.
|
|
78
|
-
*
|
|
79
|
-
* @returns {[]} Empty tuple.
|
|
80
|
-
*/
|
|
81
|
-
export circuit assertSigner(caller: T): [] {
|
|
82
|
-
assert(isSigner(caller), "SignerManager: not a signer");
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* @description Asserts that the given approval count meets the threshold.
|
|
87
|
-
*
|
|
88
|
-
* Requirements:
|
|
89
|
-
*
|
|
90
|
-
* - `approvalCount` must be >= threshold.
|
|
91
|
-
*
|
|
92
|
-
* @param {Uint<8>} approvalCount - The current number of approvals.
|
|
93
|
-
*
|
|
94
|
-
* @returns {[]} Empty tuple.
|
|
95
|
-
*/
|
|
96
|
-
export circuit assertThresholdMet(approvalCount: Uint<8>): [] {
|
|
97
|
-
assert(approvalCount >= _threshold, "SignerManager: threshold not met");
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// ─── View ──────────────────────────────────────────────────────────
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* @description Returns the current signer count.
|
|
104
|
-
*
|
|
105
|
-
* @returns {Uint<8>} The number of active signers.
|
|
106
|
-
*/
|
|
107
|
-
export circuit getSignerCount(): Uint<8> {
|
|
108
|
-
return _signerCount;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* @description Returns the approval threshold.
|
|
113
|
-
*
|
|
114
|
-
* @returns {Uint<8>} The threshold.
|
|
115
|
-
*/
|
|
116
|
-
export circuit getThreshold(): Uint<8> {
|
|
117
|
-
return _threshold;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* @description Returns whether the given account is an active signer.
|
|
122
|
-
*
|
|
123
|
-
* @param {T} account - The account to check.
|
|
124
|
-
*
|
|
125
|
-
* @returns {Boolean} True if the account is an active signer.
|
|
126
|
-
*/
|
|
127
|
-
export circuit isSigner(account: T): Boolean {
|
|
128
|
-
return _signers.member(disclose(account));
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// ─── Signer Management ─────────────────────────────────────────────────────
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @description Adds a new signer to the registry.
|
|
135
|
-
*
|
|
136
|
-
* @notice Access control is NOT enforced here.
|
|
137
|
-
* The consuming contract must gate this behind its own
|
|
138
|
-
* authorization policy.
|
|
139
|
-
*
|
|
140
|
-
* Requirements:
|
|
141
|
-
*
|
|
142
|
-
* - `signer` must not already be an active signer.
|
|
143
|
-
*
|
|
144
|
-
* @param {T} signer - The signer to add.
|
|
145
|
-
*
|
|
146
|
-
* @returns {[]} Empty tuple.
|
|
147
|
-
*/
|
|
148
|
-
export circuit _addSigner(signer: T): [] {
|
|
149
|
-
assert(
|
|
150
|
-
!isSigner(signer),
|
|
151
|
-
"SignerManager: signer already active"
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
_signers.insert(disclose(signer));
|
|
155
|
-
_signerCount = _signerCount + 1 as Uint<8>;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* @description Removes a signer from the registry.
|
|
160
|
-
*
|
|
161
|
-
* @notice Access control is NOT enforced here.
|
|
162
|
-
* The consuming contract must gate this behind its own
|
|
163
|
-
* authorization policy.
|
|
164
|
-
*
|
|
165
|
-
* Requirements:
|
|
166
|
-
*
|
|
167
|
-
* - `signer` must be an active signer.
|
|
168
|
-
* - Removal must not drop signer count below threshold.
|
|
169
|
-
*
|
|
170
|
-
* @param {T} signer - The signer to remove.
|
|
171
|
-
*
|
|
172
|
-
* @returns {[]} Empty tuple.
|
|
173
|
-
*/
|
|
174
|
-
export circuit _removeSigner(signer: T): [] {
|
|
175
|
-
assert(isSigner(signer), "SignerManager: not a signer");
|
|
176
|
-
|
|
177
|
-
const newCount = _signerCount - 1 as Uint<8>;
|
|
178
|
-
assert(newCount >= _threshold, "SignerManager: removal would breach threshold");
|
|
179
|
-
|
|
180
|
-
_signers.remove(disclose(signer));
|
|
181
|
-
_signerCount = newCount;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* @description Updates the approval threshold.
|
|
186
|
-
*
|
|
187
|
-
* @notice Access control is NOT enforced here.
|
|
188
|
-
* The consuming contract must gate this behind its own
|
|
189
|
-
* authorization policy.
|
|
190
|
-
*
|
|
191
|
-
* Requirements:
|
|
192
|
-
*
|
|
193
|
-
* - `newThreshold` must be greater than 0.
|
|
194
|
-
* - `newThreshold` must not exceed the current signer count.
|
|
195
|
-
*
|
|
196
|
-
* @param {Uint<8>} newThreshold - The new minimum number of approvals required.
|
|
197
|
-
*
|
|
198
|
-
* @returns {[]} Empty tuple.
|
|
199
|
-
*/
|
|
200
|
-
export circuit _changeThreshold(newThreshold: Uint<8>): [] {
|
|
201
|
-
assert(newThreshold > 0, "SignerManager: threshold must be > 0");
|
|
202
|
-
assert(newThreshold <= _signerCount, "SignerManager: threshold exceeds signer count");
|
|
203
|
-
_threshold = disclose(newThreshold);
|
|
204
|
-
}
|
|
205
|
-
}
|