@openzeppelin/compact-contracts 0.3.0-rc.1 → 0.4.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.
Files changed (46) hide show
  1. package/README.md +14 -4
  2. package/access/AccessControl.compact +14 -14
  3. package/access/Ownable.compact +16 -10
  4. package/access/ShieldedAccessControl.compact +26 -2
  5. package/access/ZOwnablePK.compact +9 -9
  6. package/crypto/EcdhMask.compact +5 -5
  7. package/crypto/Ecdsa.compact +111 -0
  8. package/crypto/Eip712.compact +168 -0
  9. package/crypto/ElGamal.compact +33 -107
  10. package/multisig/EcdsaSignerManager.compact +246 -0
  11. package/multisig/ForwarderPrivate.compact +12 -6
  12. package/multisig/ForwarderShielded.compact +3 -3
  13. package/multisig/ForwarderUnshielded.compact +3 -3
  14. package/multisig/ProposalManager.compact +195 -23
  15. package/multisig/ShieldedTreasury.compact +29 -2
  16. package/multisig/ShieldedTreasuryStateless.compact +2 -2
  17. package/multisig/Signer.compact +28 -80
  18. package/multisig/UnshieldedTreasury.compact +10 -2
  19. package/multisig/{presets/forwarder/ForwarderPrivate.compact → examples/ForwarderPrivateExample.compact} +4 -4
  20. package/multisig/{presets/forwarder/ForwarderShielded.compact → examples/ForwarderShieldedExample.compact} +4 -4
  21. package/multisig/{presets/forwarder/ForwarderUnshielded.compact → examples/ForwarderUnshieldedExample.compact} +4 -4
  22. package/multisig/examples/NativeShieldedTokenIssuerExample.compact +143 -0
  23. package/multisig/examples/ShieldedMultiSigV2Example.compact +77 -0
  24. package/multisig/presets/NativeShieldedTokenIssuer.compact +542 -0
  25. package/multisig/presets/ShieldedMultiSigV2.compact +267 -259
  26. package/package.json +31 -25
  27. package/security/Allowlist.compact +6 -6
  28. package/security/Blocklist.compact +6 -6
  29. package/security/Initializable.compact +9 -5
  30. package/security/Pausable.compact +11 -7
  31. package/token/ConfidentialFungibleToken.compact +143 -270
  32. package/token/FungibleToken.compact +36 -22
  33. package/token/MultiToken.compact +16 -16
  34. package/token/NativeShieldedToken.compact +17 -66
  35. package/token/NativeShieldedTokenCore.compact +26 -48
  36. package/token/NativeShieldedTokenFamily.compact +17 -67
  37. package/token/NonFungibleToken.compact +40 -79
  38. package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +12 -7
  39. package/token/extensions/NativeShieldedTokenDerivedNonce.compact +3 -3
  40. package/token/extensions/NativeShieldedTokenFamilyPublicSupply.compact +8 -8
  41. package/token/extensions/NativeShieldedTokenPublicSupply.compact +8 -8
  42. package/token/extensions/NativeShieldedTokenPublicSupplyCore.compact +6 -6
  43. package/utils/EvmAbi.compact +134 -0
  44. package/utils/Utils.compact +2 -12
  45. package/multisig/presets/ShieldedMultiSig.compact +0 -227
  46. package/multisig/presets/ShieldedMultiSigV3.compact +0 -368
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.3.0-rc.1 (token/NativeShieldedTokenCore.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.2 (token/NativeShieldedTokenCore.compact)
3
3
 
4
- pragma language_version >= 0.23.0;
4
+ pragma language_version >= 0.26.0;
5
5
 
6
6
  /**
7
7
  * @module NativeShieldedTokenCore
@@ -44,18 +44,6 @@ pragma language_version >= 0.23.0;
44
44
  * compose `NativeShieldedTokenDerivedNonce` and pass its `_deriveNonce()`
45
45
  * output, at the cost of making those mints recipient-public.
46
46
  *
47
- * @notice A recipient may be any coin public key, or this contract's own
48
- * address. Any other contract address is rejected.
49
- *
50
- * @dev Recipient arm
51
- * The ledger accepts a contract-addressed commitment only if the recipient
52
- * contract's own call claims it as a shielded receive in the same transaction,
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
57
- * contract-held coins.
58
- *
59
47
  * @dev Burn variants
60
48
  * `_burn` destroys value from a coin provided within the current transaction
61
49
  * (e.g. the caller's wallet pays the contract): it receives the coin and spends
@@ -82,8 +70,18 @@ module NativeShieldedTokenCore {
82
70
  */
83
71
  export ledger _isInitialized: Boolean;
84
72
 
73
+ /**
74
+ * @description The token's human-readable name, set once at construction.
75
+ */
85
76
  export sealed ledger _name: Opaque<"string">;
77
+ /**
78
+ * @description The token's ticker symbol, set once at construction.
79
+ */
86
80
  export sealed ledger _symbol: Opaque<"string">;
81
+ /**
82
+ * @description The number of decimals used to display balances, set once at
83
+ * construction. Purely presentational; no circuit scales by it.
84
+ */
87
85
  export sealed ledger _decimals: Uint<8>;
88
86
 
89
87
  /**
@@ -142,7 +140,7 @@ module NativeShieldedTokenCore {
142
140
  * @dev Does not gate on init (it reports it), so it is safe to call before
143
141
  * `initialize`.
144
142
  *
145
- * @circuitInfo k=6, rows=26
143
+ * @constraints k=6, rows=24
146
144
  *
147
145
  * @return {Boolean} - True once `initialize` has run.
148
146
  */
@@ -153,7 +151,7 @@ module NativeShieldedTokenCore {
153
151
  /**
154
152
  * @description Returns the token name.
155
153
  *
156
- * @circuitInfo k=6, rows=28
154
+ * @constraints k=6, rows=26
157
155
  *
158
156
  * Requirements:
159
157
  *
@@ -169,7 +167,7 @@ module NativeShieldedTokenCore {
169
167
  /**
170
168
  * @description Returns the symbol of the token.
171
169
  *
172
- * @circuitInfo k=6, rows=28
170
+ * @constraints k=6, rows=26
173
171
  *
174
172
  * Requirements:
175
173
  *
@@ -187,7 +185,7 @@ module NativeShieldedTokenCore {
187
185
  * @dev This is a display convention only. The protocol stores and operates
188
186
  * on integer values without reference to decimals.
189
187
  *
190
- * @circuitInfo k=6, rows=28
188
+ * @constraints k=6, rows=26
191
189
  *
192
190
  * Requirements:
193
191
  *
@@ -204,7 +202,7 @@ module NativeShieldedTokenCore {
204
202
  * @description Returns the coin color for `domain` under this contract's
205
203
  * address: `tokenType(domain, kernel.self())`, computed at call time.
206
204
  *
207
- * @circuitInfo k=13, rows=4248
205
+ * @constraints k=13, rows=4239
208
206
  *
209
207
  * Requirements:
210
208
  *
@@ -224,26 +222,21 @@ module NativeShieldedTokenCore {
224
222
  *
225
223
  * @dev The caller is fully responsible for nonce uniqueness. Reusing a
226
224
  * nonce for the same (domain, value, recipient) produces a duplicate
227
- * commitment, which the protocol rejects. A `right(kernel.self())` recipient
228
- * is claimed via `receiveShielded` in this same call, so the consumer SHOULD
229
- * persist the returned coin info: it is the contract's holding and is not
230
- * otherwise recoverable.
225
+ * commitment, which the protocol rejects.
231
226
  *
232
227
  * @notice The returned coin info is the only copy available to the
233
228
  * recipient; callers SHOULD deliver it out of band. Wallets cannot detect
234
229
  * contract-minted coins by scanning the chain.
235
230
  *
236
- * @circuitInfo k=15, rows=17017
231
+ * @constraints k=14, rows=11096
237
232
  *
238
233
  * Requirements:
239
234
  *
240
235
  * - Contract is initialized.
241
236
  * - `recipient` is not zero.
242
- * - `recipient`, if a contract address, is this contract's own address.
243
237
  *
244
238
  * @param {Bytes<32>} domain - 32-byte token discriminator.
245
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} recipient - The coin
246
- * recipient: any coin public key, or this contract's own address.
239
+ * @param {Either<ZswapCoinPublicKey, ContractAddress>} recipient - The coin recipient.
247
240
  * @param {Uint<64>} amount - Quantity to mint. Capped at `Uint<64>` by the protocol.
248
241
  * @param {Bytes<32>} nonce - Caller-supplied nonce. Must be unique per (domain, contract).
249
242
  * @return {ShieldedCoinInfo} - The newly created coin's info (nonce, color, value).
@@ -255,16 +248,9 @@ module NativeShieldedTokenCore {
255
248
  nonce: Bytes<32>
256
249
  ): ShieldedCoinInfo {
257
250
  assertInitialized();
258
- const self = kernel.self();
259
251
  assert(!Utils_isKeyOrAddressZero(recipient), "NativeShieldedToken: invalid recipient");
260
- assert(recipient.is_left || recipient.right == self, "NativeShieldedToken: recipient contract must be self");
261
252
 
262
- const coin = mintShieldedToken(disclose(domain), disclose(amount), disclose(nonce), disclose(recipient));
263
- if (disclose(!recipient.is_left)) {
264
- receiveShielded(coin);
265
- }
266
-
267
- return coin;
253
+ return mintShieldedToken(disclose(domain), disclose(amount), disclose(nonce), disclose(recipient));
268
254
  }
269
255
 
270
256
  /**
@@ -279,14 +265,13 @@ module NativeShieldedTokenCore {
279
265
  * @dev The coin is received by the contract and spent in the same
280
266
  * transaction, so the spend goes through `sendImmediateShielded` (the
281
267
  * transient path). For coins the contract already holds, use
282
- * `_burnFromSelf` instead. A `right(kernel.self())` refund is claimed via
283
- * `receiveShielded` in this same call.
268
+ * `_burnFromSelf` instead.
284
269
  *
285
270
  * @notice The returned refund coin info is the only copy available to
286
271
  * `refundTo`; callers SHOULD deliver it out of band. Wallets cannot detect
287
272
  * contract-sent coins by scanning the chain.
288
273
  *
289
- * @circuitInfo k=16, rows=53832
274
+ * @constraints k=16, rows=47753
290
275
  *
291
276
  * Requirements:
292
277
  *
@@ -295,14 +280,12 @@ module NativeShieldedTokenCore {
295
280
  * - `amount` is less than or equal to `coin.value`.
296
281
  * - `refundTo` is not zero (the zero key is the burn address; a zero
297
282
  * `refundTo` would silently burn the change as well).
298
- * - `refundTo`, if a contract address, is this contract's own address.
299
283
  *
300
284
  * @param {Bytes<32>} domain - 32-byte token discriminator.
301
285
  * @param {ShieldedCoinInfo} coin - The coin to burn from.
302
286
  * @param {Uint<128>} amount - Value to destroy. Must be <= `coin.value`.
303
287
  * @param {Either<ZswapCoinPublicKey, ContractAddress>} refundTo - Where to
304
- * route the unspent portion (`coin.value - amount`): any coin public key, or
305
- * this contract's own address.
288
+ * route the unspent portion (`coin.value - amount`).
306
289
  * @return {Maybe<ShieldedCoinInfo>} - The refund coin created for `refundTo`,
307
290
  * or `none` if the coin was burned in full.
308
291
  */
@@ -313,11 +296,9 @@ module NativeShieldedTokenCore {
313
296
  refundTo: Either<ZswapCoinPublicKey, ContractAddress>
314
297
  ): Maybe<ShieldedCoinInfo> {
315
298
  assertInitialized();
316
- const self = kernel.self();
317
- assert(coin.color == tokenType(disclose(domain), self), "NativeShieldedToken: wrong token");
299
+ assert(coin.color == tokenType(disclose(domain), kernel.self()), "NativeShieldedToken: wrong token");
318
300
  assert(coin.value >= amount, "NativeShieldedToken: insufficient coin value");
319
301
  assert(!Utils_isKeyOrAddressZero(refundTo), "NativeShieldedToken: invalid refund target");
320
- assert(refundTo.is_left || refundTo.right == self, "NativeShieldedToken: refund contract must be self");
321
302
 
322
303
  receiveShielded(disclose(coin));
323
304
  const sendRes = sendImmediateShielded(disclose(coin), shieldedBurnAddress(), disclose(amount));
@@ -328,9 +309,6 @@ module NativeShieldedTokenCore {
328
309
  disclose(refundTo),
329
310
  disclose(sendRes.change.value.value)
330
311
  );
331
- if (disclose(!refundTo.is_left)) {
332
- receiveShielded(refundRes.sent);
333
- }
334
312
  return some<ShieldedCoinInfo>(refundRes.sent);
335
313
  }
336
314
  return none<ShieldedCoinInfo>();
@@ -345,7 +323,7 @@ module NativeShieldedTokenCore {
345
323
  * ledger state: the change replaces `coin` as the contract's holding, and
346
324
  * its info is not otherwise recoverable.
347
325
  *
348
- * @circuitInfo k=15, rows=23583
326
+ * @constraints k=15, rows=23484
349
327
  *
350
328
  * Requirements:
351
329
  *
@@ -1,7 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.3.0-rc.1 (token/NativeShieldedTokenFamily.compact)
2
+ // OpenZeppelin Compact Contracts v0.4.0-alpha.2 (token/NativeShieldedTokenFamily.compact)
3
3
 
4
- pragma language_version >= 0.23.0;
4
+ pragma language_version >= 0.26.0;
5
5
 
6
6
  /**
7
7
  * @module NativeShieldedTokenFamily
@@ -26,10 +26,6 @@ pragma language_version >= 0.23.0;
26
26
  * set of core state (a single init flag and one name/symbol/decimals).
27
27
  * Pick one flavor per contract.
28
28
  *
29
- * @notice Recipients must be coin public keys: contract-addressed recipients
30
- * are not supported at this layer. For a coin the contract holds itself, use
31
- * `_mintToSelf`, which mints to `kernel.self()` and claims it in the same call.
32
- *
33
29
  * @notice This module exposes composable building blocks for minting and
34
30
  * burning native shielded coins. It does NOT include access control: consuming
35
31
  * contracts compose that via the module/contract pattern (Ownable,
@@ -101,7 +97,7 @@ module NativeShieldedTokenFamily {
101
97
  /**
102
98
  * @description Returns whether the contract has been initialized.
103
99
  *
104
- * @circuitInfo k=6, rows=26
100
+ * @constraints k=6, rows=24
105
101
  *
106
102
  * @return {Boolean} - True once `initialize` has run.
107
103
  */
@@ -114,7 +110,7 @@ module NativeShieldedTokenFamily {
114
110
  * contract. Per-type identity belongs in the consumer's own state; see the
115
111
  * module notes.
116
112
  *
117
- * @circuitInfo k=6, rows=28
113
+ * @constraints k=6, rows=26
118
114
  *
119
115
  * Requirements:
120
116
  *
@@ -130,7 +126,7 @@ module NativeShieldedTokenFamily {
130
126
  * @description Returns the family symbol shared by all token types of this
131
127
  * contract.
132
128
  *
133
- * @circuitInfo k=6, rows=28
129
+ * @constraints k=6, rows=26
134
130
  *
135
131
  * Requirements:
136
132
  *
@@ -146,7 +142,7 @@ module NativeShieldedTokenFamily {
146
142
  * @description Returns the family-wide number of decimals used to get the
147
143
  * user representation.
148
144
  *
149
- * @circuitInfo k=6, rows=28
145
+ * @constraints k=6, rows=26
150
146
  *
151
147
  * Requirements:
152
148
  *
@@ -162,7 +158,7 @@ module NativeShieldedTokenFamily {
162
158
  * @description Returns the coin color (token type) for `domain` under this
163
159
  * contract's address, so integrators do not have to re-derive it by hand.
164
160
  *
165
- * @circuitInfo k=13, rows=4248
161
+ * @constraints k=13, rows=4239
166
162
  *
167
163
  * Requirements:
168
164
  *
@@ -190,7 +186,7 @@ module NativeShieldedTokenFamily {
190
186
  * recipient; callers SHOULD deliver it out of band. Wallets cannot detect
191
187
  * contract-minted coins by scanning the chain.
192
188
  *
193
- * @circuitInfo k=14, rows=10750
189
+ * @constraints k=14, rows=11096
194
190
  *
195
191
  * Requirements:
196
192
  *
@@ -199,59 +195,18 @@ module NativeShieldedTokenFamily {
199
195
  *
200
196
  * @param {Bytes<32>} domain - 32-byte token discriminator. Same domain + same
201
197
  * contract address produces the same coin color (i.e. same token type).
202
- * @param {ZswapCoinPublicKey} recipient - The coin recipient.
198
+ * @param {Either<ZswapCoinPublicKey, ContractAddress>} recipient - The coin recipient.
203
199
  * @param {Uint<64>} amount - Quantity to mint. Capped at `Uint<64>` by the protocol.
204
200
  * @param {Bytes<32>} nonce - Caller-supplied nonce. Must be unique per (domain, contract).
205
201
  * @return {ShieldedCoinInfo} - The newly created coin's info (nonce, color, value).
206
202
  */
207
203
  export circuit _mint(
208
204
  domain: Bytes<32>,
209
- recipient: ZswapCoinPublicKey,
210
- amount: Uint<64>,
211
- nonce: Bytes<32>
212
- ): ShieldedCoinInfo {
213
- return Core__mint(
214
- domain,
215
- left<ZswapCoinPublicKey, ContractAddress>(recipient),
216
- amount,
217
- nonce
218
- );
219
- }
220
-
221
- /**
222
- * @description Mints `amount` of the token identified by `domain` to this
223
- * contract itself, claiming the coin in the same call. Forwards to
224
- * `NativeShieldedTokenCore._mint` with `right(kernel.self())`.
225
- *
226
- * @dev Nonce uniqueness is the caller's responsibility, as in `_mint`. Spend
227
- * the coin later with `_burnFromSelf`, once it carries an `mt_index`.
228
- *
229
- * @notice The consumer SHOULD persist the returned coin info in its own
230
- * ledger state: it is the contract's holding and is not otherwise
231
- * recoverable.
232
- *
233
- * @circuitInfo k=14, rows=16346
234
- *
235
- * Requirements:
236
- *
237
- * - Contract is initialized.
238
- *
239
- * @param {Bytes<32>} domain - 32-byte token discriminator.
240
- * @param {Uint<64>} amount - Quantity to mint. Capped at `Uint<64>` by the protocol.
241
- * @param {Bytes<32>} nonce - Caller-supplied nonce. Must be unique per (domain, contract).
242
- * @return {ShieldedCoinInfo} - The newly created coin's info (nonce, color, value).
243
- */
244
- export circuit _mintToSelf(
245
- domain: Bytes<32>,
205
+ recipient: Either<ZswapCoinPublicKey, ContractAddress>,
246
206
  amount: Uint<64>,
247
207
  nonce: Bytes<32>
248
208
  ): ShieldedCoinInfo {
249
- return Core__mint(
250
- domain,
251
- right<ZswapCoinPublicKey, ContractAddress>(kernel.self()),
252
- amount,
253
- nonce
254
- );
209
+ return Core__mint(domain, recipient, amount, nonce);
255
210
  }
256
211
 
257
212
  /**
@@ -272,7 +227,7 @@ module NativeShieldedTokenFamily {
272
227
  * `refundTo`; callers SHOULD deliver it out of band. Wallets cannot detect
273
228
  * contract-sent coins by scanning the chain.
274
229
  *
275
- * @circuitInfo k=16, rows=41768
230
+ * @constraints k=16, rows=47753
276
231
  *
277
232
  * Requirements:
278
233
  *
@@ -285,8 +240,8 @@ module NativeShieldedTokenFamily {
285
240
  * @param {Bytes<32>} domain - 32-byte token discriminator.
286
241
  * @param {ShieldedCoinInfo} coin - The coin to burn from.
287
242
  * @param {Uint<128>} amount - Value to destroy. Must be <= `coin.value`.
288
- * @param {ZswapCoinPublicKey} refundTo - Where to route the unspent
289
- * portion (`coin.value - amount`).
243
+ * @param {Either<ZswapCoinPublicKey, ContractAddress>} refundTo - Where to
244
+ * route the unspent portion (`coin.value - amount`).
290
245
  * @return {Maybe<ShieldedCoinInfo>} - The refund coin created for `refundTo`,
291
246
  * or `none` if the coin was burned in full.
292
247
  */
@@ -294,14 +249,9 @@ module NativeShieldedTokenFamily {
294
249
  domain: Bytes<32>,
295
250
  coin: ShieldedCoinInfo,
296
251
  amount: Uint<128>,
297
- refundTo: ZswapCoinPublicKey
252
+ refundTo: Either<ZswapCoinPublicKey, ContractAddress>
298
253
  ): Maybe<ShieldedCoinInfo> {
299
- return Core__burn(
300
- domain,
301
- coin,
302
- amount,
303
- left<ZswapCoinPublicKey, ContractAddress>(refundTo)
304
- );
254
+ return Core__burn(domain, coin, amount, refundTo);
305
255
  }
306
256
 
307
257
  /**
@@ -313,7 +263,7 @@ module NativeShieldedTokenFamily {
313
263
  * ledger state: the change replaces `coin` as the contract's holding, and
314
264
  * its info is not otherwise recoverable.
315
265
  *
316
- * @circuitInfo k=15, rows=23583
266
+ * @constraints k=15, rows=23484
317
267
  *
318
268
  * Requirements:
319
269
  *