@openzeppelin/compact-contracts 0.4.0-alpha.3 → 0.4.0-alpha.5

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 (40) 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/Ecdsa.compact +1 -1
  7. package/crypto/Eip712.compact +1 -1
  8. package/crypto/ElGamal.compact +1 -1
  9. package/multisig/EcdsaSignerManager.compact +9 -7
  10. package/multisig/ForwarderPrivate.compact +1 -1
  11. package/multisig/ForwarderShielded.compact +14 -5
  12. package/multisig/ForwarderUnshielded.compact +1 -1
  13. package/multisig/ProposalManager.compact +1 -1
  14. package/multisig/ShieldedTreasury.compact +1 -1
  15. package/multisig/ShieldedTreasuryStateless.compact +1 -1
  16. package/multisig/Signer.compact +1 -1
  17. package/multisig/UnshieldedTreasury.compact +5 -3
  18. package/multisig/examples/ForwarderPrivateExample.compact +1 -1
  19. package/multisig/examples/ForwarderShieldedExample.compact +8 -5
  20. package/multisig/examples/ForwarderUnshieldedExample.compact +1 -1
  21. package/multisig/examples/NativeShieldedTokenIssuerExample.compact +29 -7
  22. package/multisig/examples/ShieldedMultiSigV2Example.compact +2 -2
  23. package/multisig/presets/NativeShieldedTokenIssuer.compact +278 -123
  24. package/multisig/presets/ShieldedMultiSigV2.compact +16 -7
  25. package/package.json +6 -4
  26. package/security/Allowlist.compact +1 -1
  27. package/security/Blocklist.compact +1 -1
  28. package/security/Initializable.compact +1 -1
  29. package/security/Pausable.compact +1 -1
  30. package/token/ConfidentialFungibleToken.compact +17 -1
  31. package/token/FungibleToken.compact +1 -1
  32. package/token/MultiToken.compact +1 -1
  33. package/token/NativeShieldedToken.compact +2 -2
  34. package/token/NativeShieldedTokenCore.compact +11 -18
  35. package/token/NativeShieldedTokenFamily.compact +2 -2
  36. package/token/NonFungibleToken.compact +1 -1
  37. package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +1 -1
  38. package/token/extensions/NativeShieldedTokenDerivedNonce.compact +1 -1
  39. package/utils/EvmAbi.compact +1 -1
  40. package/utils/Utils.compact +1 -1
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (multisig/presets/ShieldedMultiSigV2.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (multisig/presets/ShieldedMultiSigV2.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -82,11 +82,11 @@ module ShieldedMultiSigV2 {
82
82
  *
83
83
  * - `instanceSalt` should be cryptographically random.
84
84
  * - `signerCommitments` must not contain duplicates.
85
- * - `thresh` must be non-zero and must not exceed 2.
85
+ * - `thresh` must be 2, the number of signatures `execute` verifies.
86
86
  *
87
87
  * @param {Bytes<32>} instanceSalt - Per-deployment salt for commitment derivation.
88
88
  * @param {Vector<3, Bytes<32>>} signerCommitments - Hashed signer identities.
89
- * @param {Uint<8>} thresh - Minimum approvals required.
89
+ * @param {Uint<8>} thresh - Approvals required. Must be 2.
90
90
  * @returns {[]} Empty tuple.
91
91
  */
92
92
  export circuit initialize(
@@ -165,7 +165,10 @@ module ShieldedMultiSigV2 {
165
165
  * commitment from their public key and the instance salt, rejects duplicates,
166
166
  * and enforces the threshold.
167
167
  *
168
- * @constraints k=17, rows=104644 (zkir-v3)
168
+ * @notice `to` must be a `ShieldedUser`. A contract-addressed coin would be
169
+ * unclaimable, making the transaction malformed.
170
+ *
171
+ * @constraints k=17, rows=98977 (zkir-v3)
169
172
  *
170
173
  * Requirements:
171
174
  *
@@ -173,6 +176,7 @@ module ShieldedMultiSigV2 {
173
176
  * - Both signatures must be valid over the message hash and use the low-s
174
177
  * encoding.
175
178
  * - Signers must not be duplicates.
179
+ * - `to.kind` must be `ShieldedUser`.
176
180
  * - Coin value must be >= amount.
177
181
  *
178
182
  * @param {Proposal_Recipient} to - The recipient.
@@ -210,9 +214,14 @@ module ShieldedMultiSigV2 {
210
214
 
211
215
  EcdsaSignerManager_assertApprovals(msgHash, pubkeys, signatures);
212
216
 
213
- // Execute transfer
214
- const normalizedRecipient = Proposal_toShieldedRecipient(to);
215
- return Treasury__send(coin, normalizedRecipient, amount);
217
+ assert(
218
+ to.kind == Proposal_RecipientKind.ShieldedUser,
219
+ "Multisig: recipient must be a coin public key"
220
+ );
221
+ const recipient = left<ZswapCoinPublicKey, ContractAddress>(
222
+ ZswapCoinPublicKey { bytes: to.address }
223
+ );
224
+ return Treasury__send(coin, recipient, amount);
216
225
  }
217
226
 
218
227
  // ─── Commitments ────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/compact-contracts",
3
- "version": "0.4.0-alpha.3",
3
+ "version": "0.4.0-alpha.5",
4
4
  "description": "OpenZeppelin Compact contract library",
5
5
  "keywords": [
6
6
  "openzeppelin",
@@ -63,13 +63,15 @@
63
63
  "@midnightntwrk/ledger-v9": "1.0.0-rc.5",
64
64
  "@midnightntwrk/wallet-sdk-address-format": "4.0.0-beta.2",
65
65
  "@noble/curves": "^2.2.0",
66
- "@noble/hashes": "^2.2.0",
67
- "@openzeppelin/compact-simulator": "^0.4.0",
66
+ "@noble/hashes": "^2.4.0",
67
+ "@openzeppelin/compact-deployer": "^0.3.1",
68
+ "@openzeppelin/compact-simulator": "^0.4.1",
68
69
  "@tsconfig/node24": "^24.0.5",
69
- "@types/node": "26.5.1",
70
+ "@types/node": "26.6.2",
70
71
  "@vitest/coverage-v8": "^5.0.0",
71
72
  "ethers": "^6.17.0",
72
73
  "fast-check": "^4.10.1",
74
+ "pino": "^9.7.0",
73
75
  "ts-node": "^10.9.2",
74
76
  "typescript": "^6.0.3",
75
77
  "vite": "^8.3.0",
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (security/Allowlist.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (security/Allowlist.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (security/Blocklist.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (security/Blocklist.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (security/Initializable.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (security/Initializable.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (security/Pausable.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (security/Pausable.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/ConfidentialFungibleToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/ConfidentialFungibleToken.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -242,6 +242,22 @@ pragma language_version >= 0.26.0;
242
242
  * Raising the limit itself is a node-side change, tracked upstream:
243
243
  * https://github.com/midnightntwrk/midnight-node/issues/1202.
244
244
  *
245
+ * Upgrades. Add operations, never change how existing state is derived or laid
246
+ * out. A CMA upgrade swaps verifier keys on an instance whose ledger already
247
+ * holds data so whatever that data was written under has to stay fixed e.g. slot
248
+ * indices, nonce and key derivation, stored encodings. Slot changes at least
249
+ * show up in a diff. Key derivation is the quiet one. `_encryptionKeys` holds
250
+ * the key `derivePk` returned at `register` time, `register` refuses a second
251
+ * key for an account id, and the id does not move (untagged by design, see
252
+ * `Utils.computeAccountId`), so a circuit deriving a different key leaves
253
+ * `assertDecryptsTo` and `_assertOwnsEncryptionKey` rejecting the stored one
254
+ * with no way to re-register. This means balances, pending balances, escrow and
255
+ * memos are all permanently unreachable. An instance's derivation is fixed when
256
+ * it is deployed, so off-chain code mirroring `derivePk` must use that one for
257
+ * the life of the instance. Adopting a newer derivation cannot recover an
258
+ * instance whose keys were stored under the old one. A changed derivation
259
+ * applies to fresh deployments only.
260
+ *
245
261
  * Residual griefing. The dual-balance split (see `sweep`) stops dust
246
262
  * credits from churning a victim's spendable ciphertext, but every `_credit`
247
263
  * still appends a memo, and only the recipient can `clearMemos`. An attacker
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/FungibleToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/FungibleToken.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/MultiToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/MultiToken.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/NativeShieldedToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/NativeShieldedToken.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -232,7 +232,7 @@ module NativeShieldedToken {
232
232
  * ledger state: it is the contract's holding and is not otherwise
233
233
  * recoverable.
234
234
  *
235
- * @constraints k=14, rows=16033
235
+ * @constraints k=14, rows=10221
236
236
  *
237
237
  * Requirements:
238
238
  *
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/NativeShieldedTokenCore.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/NativeShieldedTokenCore.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -51,9 +51,10 @@ pragma language_version >= 0.26.0;
51
51
  * The ledger accepts a contract-addressed commitment only if the recipient
52
52
  * contract's own call claims it as a shielded receive in the same transaction,
53
53
  * and no primitive claims a receive on another contract's behalf. So the
54
- * address arm is accepted only for `kernel.self()`, where `_mint` / `_burn`
55
- * claim the coin themselves in the same call. The flavors do not expose the
56
- * arm at all: they take a `ZswapCoinPublicKey` and offer `_mintToSelf` for
54
+ * address arm is accepted only for `kernel.self()`, which `mintShieldedToken`
55
+ * and `sendShielded` claim as a receive themselves. A `receiveShielded` on top
56
+ * emits a duplicate output for the same commitment. The flavors do not expose
57
+ * the arm at all: they take a `ZswapCoinPublicKey` and offer `_mintToSelf` for
57
58
  * contract-held coins.
58
59
  *
59
60
  * @dev Burn variants
@@ -235,7 +236,7 @@ module NativeShieldedTokenCore {
235
236
  * @dev The caller is fully responsible for nonce uniqueness. Reusing a
236
237
  * nonce for the same (domain, value, recipient) produces a duplicate
237
238
  * commitment, which the protocol rejects. A `right(kernel.self())` recipient
238
- * is claimed via `receiveShielded` in this same call, so the consumer SHOULD
239
+ * is claimed by `mintShieldedToken` in this same call, so the consumer SHOULD
239
240
  * persist the returned coin info: it is the contract's holding and is not
240
241
  * otherwise recoverable.
241
242
  *
@@ -243,7 +244,7 @@ module NativeShieldedTokenCore {
243
244
  * recipient; callers SHOULD deliver it out of band. Wallets cannot detect
244
245
  * contract-minted coins by scanning the chain.
245
246
  *
246
- * @constraints k=15, rows=16980
247
+ * @constraints k=14, rows=11109
247
248
  *
248
249
  * Requirements:
249
250
  *
@@ -269,12 +270,7 @@ module NativeShieldedTokenCore {
269
270
  assert(!Utils_isKeyOrAddressZero(recipient), "NativeShieldedToken: invalid recipient");
270
271
  assert(recipient.is_left || recipient.right == self, "NativeShieldedToken: recipient contract must be self");
271
272
 
272
- const coin = mintShieldedToken(disclose(domain), disclose(amount), disclose(nonce), disclose(recipient));
273
- if (disclose(!recipient.is_left)) {
274
- receiveShielded(coin);
275
- }
276
-
277
- return coin;
273
+ return mintShieldedToken(disclose(domain), disclose(amount), disclose(nonce), disclose(recipient));
278
274
  }
279
275
 
280
276
  /**
@@ -289,14 +285,14 @@ module NativeShieldedTokenCore {
289
285
  * @dev The coin is received by the contract and spent in the same
290
286
  * transaction, so the spend goes through `sendImmediateShielded` (the
291
287
  * transient path). For coins the contract already holds, use
292
- * `_burnFromSelf` instead. A `right(kernel.self())` refund is claimed via
293
- * `receiveShielded` in this same call.
288
+ * `_burnFromSelf` instead. A `right(kernel.self())` refund is claimed by
289
+ * `sendImmediateShielded` in this same call.
294
290
  *
295
291
  * @notice The returned refund coin info is the only copy available to
296
292
  * `refundTo`; callers SHOULD deliver it out of band. Wallets cannot detect
297
293
  * contract-sent coins by scanning the chain.
298
294
  *
299
- * @constraints k=16, rows=53639
295
+ * @constraints k=16, rows=47764
300
296
  *
301
297
  * Requirements:
302
298
  *
@@ -338,9 +334,6 @@ module NativeShieldedTokenCore {
338
334
  disclose(refundTo),
339
335
  disclose(sendRes.change.value.value)
340
336
  );
341
- if (disclose(!refundTo.is_left)) {
342
- receiveShielded(refundRes.sent);
343
- }
344
337
  return some<ShieldedCoinInfo>(refundRes.sent);
345
338
  }
346
339
  return none<ShieldedCoinInfo>();
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/NativeShieldedTokenFamily.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/NativeShieldedTokenFamily.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -230,7 +230,7 @@ module NativeShieldedTokenFamily {
230
230
  * ledger state: it is the contract's holding and is not otherwise
231
231
  * recoverable.
232
232
  *
233
- * @constraints k=14, rows=16309
233
+ * @constraints k=14, rows=10497
234
234
  *
235
235
  * Requirements:
236
236
  *
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/NonFungibleToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/NonFungibleToken.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/extensions/ConfidentialFungibleTokenPublicSupply.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/extensions/ConfidentialFungibleTokenPublicSupply.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (token/extensions/NativeShieldedTokenDerivedNonce.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (token/extensions/NativeShieldedTokenDerivedNonce.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (utils/EvmAbi.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (utils/EvmAbi.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.4.0-alpha.3 (utils/Utils.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.5 (utils/Utils.compact)
3
3
 
4
4
  pragma language_version >= 0.26.0;
5
5