@openzeppelin/compact-contracts 0.3.0-alpha.1 → 0.3.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/access/AccessControl.compact +1 -1
  2. package/access/Ownable.compact +1 -1
  3. package/access/ShieldedAccessControl.compact +1 -1
  4. package/access/ZOwnablePK.compact +1 -1
  5. package/crypto/EcdhMask.compact +1 -1
  6. package/crypto/ElGamal.compact +44 -3
  7. package/multisig/ForwarderPrivate.compact +2 -2
  8. package/multisig/ForwarderShielded.compact +2 -2
  9. package/multisig/ForwarderUnshielded.compact +2 -2
  10. package/multisig/ProposalManager.compact +35 -1
  11. package/multisig/ShieldedTreasury.compact +34 -4
  12. package/multisig/ShieldedTreasuryStateless.compact +46 -17
  13. package/multisig/Signer.compact +45 -41
  14. package/multisig/UnshieldedTreasury.compact +44 -17
  15. package/multisig/presets/ShieldedMultiSig.compact +4 -4
  16. package/multisig/presets/ShieldedMultiSigV2.compact +2 -2
  17. package/multisig/presets/ShieldedMultiSigV3.compact +2 -2
  18. package/multisig/presets/forwarder/ForwarderPrivate.compact +1 -1
  19. package/multisig/presets/forwarder/ForwarderShielded.compact +1 -1
  20. package/multisig/presets/forwarder/ForwarderUnshielded.compact +1 -1
  21. package/package.json +3 -3
  22. package/security/Allowlist.compact +1 -1
  23. package/security/Blocklist.compact +1 -1
  24. package/security/Initializable.compact +1 -1
  25. package/security/Pausable.compact +1 -1
  26. package/token/ConfidentialFungibleToken.compact +289 -75
  27. package/token/FungibleToken.compact +1 -1
  28. package/token/MultiToken.compact +1 -1
  29. package/token/NativeShieldedToken.compact +60 -11
  30. package/token/NativeShieldedTokenCore.compact +41 -9
  31. package/token/NativeShieldedTokenFamily.compact +61 -11
  32. package/token/NonFungibleToken.compact +63 -19
  33. package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +1 -1
  34. package/token/extensions/NativeShieldedTokenDerivedNonce.compact +1 -1
  35. package/token/extensions/{NativeShieldedTokenFamilySupply.compact → NativeShieldedTokenFamilyPublicSupply.compact} +11 -11
  36. package/token/extensions/{NativeShieldedTokenSupply.compact → NativeShieldedTokenPublicSupply.compact} +11 -11
  37. package/token/extensions/{NativeShieldedTokenSupplyCore.compact → NativeShieldedTokenPublicSupplyCore.compact} +9 -9
  38. package/utils/Utils.compact +11 -1
  39. package/multisig/SignerManager.compact +0 -205
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.3.0-alpha.1 (multisig/UnshieldedTreasury.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (multisig/UnshieldedTreasury.compact)
3
3
 
4
4
  pragma language_version >= 0.23.0;
5
5
 
@@ -8,10 +8,24 @@ pragma language_version >= 0.23.0;
8
8
  * @description Manages unshielded (transparent) token deposits and
9
9
  * transfers for multisig governance contracts.
10
10
  *
11
- * Balances are tracked per token color in a single map. Protocol-level
12
- * balance comparison circuits (`unshieldedBalanceLte`,
13
- * `unshieldedBalanceGte`) are used for overflow and sufficiency checks,
14
- * avoiding the exact-match problem of `unshieldedBalance`.
11
+ * Balances are tracked per token color in `_balances`, this module's own
12
+ * accounting and the authority for its overflow and sufficiency guards. The
13
+ * protocol balance remains authoritative for what the contract actually holds,
14
+ * and the ledger independently enforces conservation — a contract cannot send
15
+ * funds it does not have.
16
+ *
17
+ * @notice The guards deliberately do NOT consult `unshieldedBalance` or its
18
+ * comparison circuits. That balance is fixed to the value provided at the start
19
+ * of execution, so it cannot observe a credit or debit made earlier in the same
20
+ * transaction: guarding on it rejects a legitimate receive-then-spend and misses
21
+ * an intra-transaction overspend. Guarding on `_balances` (the same value the
22
+ * arithmetic mutates) is correct in both cases, and keeps the named asserts
23
+ * reachable for the conditions they describe.
24
+ *
25
+ * @notice Consumers must route every unshielded credit and debit through
26
+ * `_deposit` / `_send`. A flow that calls `receiveUnshielded` or
27
+ * `sendUnshielded` directly leaves `_balances` out of step with the protocol
28
+ * balance, and `getTokenBalance` will misreport.
15
29
  *
16
30
  * Underscore-prefixed circuits (_deposit, _send) have no access control
17
31
  * enforcement. The consuming contract must gate these behind its own
@@ -35,7 +49,9 @@ module UnshieldedTreasury {
35
49
  *
36
50
  * Zero-value deposits are permitted. While currently a no-op
37
51
  * economically, they may serve as signaling mechanisms when events
38
- * are supported.
52
+ * are supported. On a color the treasury has not held, a zero-value
53
+ * operation creates a zero-valued `_balances` entry, which
54
+ * `getTokenBalance` reports the same as absence.
39
55
  *
40
56
  * @notice Access control is NOT enforced here.
41
57
  * The consuming contract must gate this behind its own
@@ -51,21 +67,35 @@ module UnshieldedTreasury {
51
67
  * @returns {[]} Empty tuple.
52
68
  */
53
69
  export circuit _deposit(color: Bytes<32>, amount: Uint<128>): [] {
54
- assert(
55
- unshieldedBalanceLte(disclose(color), Utils_UINT128_MAX() - disclose(amount)),
56
- "UnshieldedTreasury: overflow"
57
- );
70
+ // `Utils_UINT128_MAX() - amount` stays in-circuit. Passing it to a protocol
71
+ // balance comparison would hand that built-in an operand near 2^128, which
72
+ // fails at runtime with "failed to decode for built-in type u64" despite the
73
+ // circuit's declared `Uint<128>` parameter.
74
+ const bal = getTokenBalance(color);
75
+ assert(bal <= Utils_UINT128_MAX() - amount, "UnshieldedTreasury: overflow");
58
76
 
59
77
  receiveUnshielded(disclose(color), disclose(amount));
60
78
 
61
- const bal = getTokenBalance(color);
62
79
  _balances.insert(disclose(color), disclose(bal + amount as Uint<128>));
63
80
  }
64
81
 
65
82
  // ─── Send ───────────────────────────────────────────────────────
66
83
 
67
84
  /**
68
- * @description Sends unshielded tokens from the treasury.
85
+ * @description Sends unshielded tokens from the treasury. Zero-amount sends
86
+ * are permitted and are value-preserving no-ops.
87
+ *
88
+ * @warning Recipients are not validated. An unspendable recipient (such as a
89
+ * zero address) is accepted and permanently removes the funds from the
90
+ * contract. This is not a sanctioned burn — no unshielded equivalent of
91
+ * `shieldedBurnAddress` is exposed to contracts — so treat recipient
92
+ * validation as the consuming contract's responsibility.
93
+ *
94
+ * @warning Sending to this contract's own address zeroes the tracked balance
95
+ * while the funds stay held and spendable at the protocol level, after which
96
+ * `_send` will refuse to touch them. Recovery is only possible outside this
97
+ * module: a consumer may reconcile the exported `_balances`, or spend the
98
+ * funds through its own `sendUnshielded` call.
69
99
  *
70
100
  * @notice Access control is NOT enforced here.
71
101
  * The consuming contract must gate this behind its own
@@ -86,12 +116,9 @@ module UnshieldedTreasury {
86
116
  color: Bytes<32>,
87
117
  amount: Uint<128>
88
118
  ): [] {
89
- assert(
90
- unshieldedBalanceGte(disclose(color), disclose(amount)),
91
- "UnshieldedTreasury: insufficient balance"
92
- );
93
-
94
119
  const bal = getTokenBalance(color);
120
+ assert(bal >= amount, "UnshieldedTreasury: insufficient balance");
121
+
95
122
  _balances.insert(disclose(color), disclose(bal - amount as Uint<128>));
96
123
  sendUnshielded(disclose(color), disclose(amount), disclose(recipient));
97
124
  }
@@ -1,11 +1,11 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.3.0-alpha.1 (multisig/presets/ShieldedMultiSig.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (multisig/presets/ShieldedMultiSig.compact)
3
3
 
4
4
  pragma language_version >= 0.23.0;
5
5
 
6
6
  /**
7
7
  * @module ShieldedMultiSig
8
- * @description A shielded multisig preset composing `SignerManager`,
8
+ * @description A shielded multisig preset composing `Signer`,
9
9
  * `ProposalManager`, and `ShieldedTreasury`. Signers approve proposals that
10
10
  * transfer shielded tokens out of the treasury once the configured threshold
11
11
  * is met.
@@ -29,7 +29,7 @@ import CompactStandardLibrary;
29
29
 
30
30
  import "../ProposalManager" prefix Proposal_;
31
31
  import "../ShieldedTreasury" prefix Treasury_;
32
- import "../SignerManager"<Either<ZswapCoinPublicKey, ContractAddress>> prefix Signer_;
32
+ import "../Signer"<Either<ZswapCoinPublicKey, ContractAddress>> prefix Signer_;
33
33
 
34
34
  // ─── State ───────────────────────────────────────────────────────────────
35
35
 
@@ -212,7 +212,7 @@ export circuit getSentTotal(color: Bytes<32>): Uint<128> {
212
212
  return Treasury_getSentTotal(color);
213
213
  }
214
214
 
215
- // ISignerManager
215
+ // ISigner
216
216
 
217
217
  export circuit getSignerCount(): Uint<8> {
218
218
  return Signer_getSignerCount();
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.3.0-alpha.1 (multisig/presets/ShieldedMultiSigV2.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (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 "../SignerManager"<Bytes<32>> prefix Signer_;
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 `burnAddress()`. Only
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 `burnAddress()` via
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.1 (multisig/presets/forwarder/ForwarderPrivate.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (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.1 (multisig/presets/forwarder/ForwarderShielded.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (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.1 (multisig/presets/forwarder/ForwarderUnshielded.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (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.1",
3
+ "version": "0.3.0-rc.1",
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.2.0",
63
+ "@openzeppelin/compact-simulator": "^0.3.1",
64
64
  "@tsconfig/node24": "^24.0.4",
65
- "@types/node": "26.1.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.1 (security/Allowlist.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (security/Allowlist.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.1 (security/Blocklist.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (security/Blocklist.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.1 (security/Initializable.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (security/Initializable.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.1 (security/Pausable.compact)
2
+ // OpenZeppelin Compact Contracts v0.3.0-rc.1 (security/Pausable.compact)
3
3
 
4
4
  pragma language_version >= 0.23.0;
5
5