@openzeppelin/compact-contracts 0.4.0-alpha.4 → 0.4.0-alpha.6
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 +1 -1
- package/access/AccessControl.compact +1 -1
- package/access/Ownable.compact +1 -1
- package/access/ShieldedAccessControl.compact +1 -1
- package/access/ZOwnablePK.compact +13 -4
- package/crypto/EcdhMask.compact +1 -1
- package/crypto/Ecdsa.compact +1 -1
- package/crypto/Eip712.compact +1 -1
- package/crypto/ElGamal.compact +1 -1
- package/multisig/ForwarderPrivate.compact +1 -1
- package/multisig/ForwarderShielded.compact +14 -5
- package/multisig/ForwarderUnshielded.compact +1 -1
- package/multisig/ProposalManager.compact +1 -1
- package/multisig/Secp256k1EcdsaMultisig.compact +275 -0
- package/multisig/ShieldedTreasury.compact +1 -1
- package/multisig/ShieldedTreasuryStateless.compact +1 -1
- package/multisig/Signer.compact +1 -1
- package/multisig/UnshieldedTreasury.compact +5 -3
- package/multisig/examples/ForwarderPrivateExample.compact +1 -1
- package/multisig/examples/ForwarderShieldedExample.compact +8 -5
- package/multisig/examples/ForwarderUnshieldedExample.compact +1 -1
- package/multisig/examples/NativeShieldedTokenIssuerExample.compact +10 -8
- package/multisig/examples/ShieldedMultiSigV2Example.compact +6 -8
- package/multisig/presets/NativeShieldedTokenIssuer.compact +126 -108
- package/multisig/presets/ShieldedMultiSigV2.compact +46 -45
- package/package.json +2 -2
- 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 +17 -1
- package/token/FungibleToken.compact +1 -1
- package/token/MultiToken.compact +1 -1
- package/token/NativeShieldedToken.compact +2 -2
- package/token/NativeShieldedTokenCore.compact +11 -18
- package/token/NativeShieldedTokenFamily.compact +2 -2
- package/token/NonFungibleToken.compact +1 -1
- package/token/examples/ZOwnableNativeShieldedTokenExample.compact +109 -0
- package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +1 -1
- package/token/extensions/NativeShieldedTokenDerivedNonce.compact +1 -1
- package/token/presets/ZOwnableNativeShieldedToken.compact +314 -0
- package/utils/EvmAbi.compact +1 -1
- package/utils/Utils.compact +1 -1
- package/multisig/EcdsaSignerManager.compact +0 -246
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.4.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (multisig/presets/ShieldedMultiSigV2.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @module ShieldedMultiSigV2
|
|
8
|
-
* @description Privacy-preserving
|
|
8
|
+
* @description Privacy-preserving threshold multisig contract.
|
|
9
9
|
*
|
|
10
10
|
* Signer identities are stored as commitments: hashes of ECDSA public
|
|
11
11
|
* keys combined with an instance salt and domain separator. Signature
|
|
@@ -14,6 +14,12 @@ pragma language_version >= 0.26.0;
|
|
|
14
14
|
* and replay protection. All other coordination (signature collection,
|
|
15
15
|
* coin selection) happens off-chain.
|
|
16
16
|
*
|
|
17
|
+
* `t` is the approval width and the threshold: `execute` verifies exactly
|
|
18
|
+
* `t` distinct signers. Import as `"../presets/ShieldedMultiSigV2"<t>`; the
|
|
19
|
+
* implementing contract fixes the signer count `n` at `initialize`. Import
|
|
20
|
+
* one width per contract: two widths share one signer registry, see
|
|
21
|
+
* `Secp256k1EcdsaMultisig`.
|
|
22
|
+
*
|
|
17
23
|
* Treasury is fully stateless meaning coin data is not stored on the public ledger.
|
|
18
24
|
* Deposits call receiveShielded only. The operator discovers coin indices
|
|
19
25
|
* through ZswapOutput events from the indexer, constructs QualifiedShieldedCoinInfo
|
|
@@ -23,12 +29,12 @@ pragma language_version >= 0.26.0;
|
|
|
23
29
|
*
|
|
24
30
|
* @notice Implementing contracts register the signer set from their
|
|
25
31
|
* constructor by calling this module's `initialize`, and MUST NOT import
|
|
26
|
-
* `
|
|
32
|
+
* `Signer` or `Secp256k1EcdsaMultisig` directly.
|
|
27
33
|
*/
|
|
28
|
-
module ShieldedMultiSigV2 {
|
|
34
|
+
module ShieldedMultiSigV2<#t> {
|
|
29
35
|
import CompactStandardLibrary;
|
|
30
36
|
|
|
31
|
-
import "../
|
|
37
|
+
import "../Secp256k1EcdsaMultisig"<t> prefix Secp256k1EcdsaMultisig_;
|
|
32
38
|
import "../../crypto/Eip712" prefix Eip712_;
|
|
33
39
|
import "../../utils/EvmAbi" prefix EvmAbi_;
|
|
34
40
|
import "../ProposalManager" prefix Proposal_;
|
|
@@ -39,8 +45,6 @@ module ShieldedMultiSigV2 {
|
|
|
39
45
|
// unwritten copy of its state.
|
|
40
46
|
export { Proposal_Recipient };
|
|
41
47
|
|
|
42
|
-
// ─── State ──────────────────────────────────────────────────────
|
|
43
|
-
|
|
44
48
|
/**
|
|
45
49
|
* @description Monotonic operation counter. `execute` reads it as that
|
|
46
50
|
* operation's nonce and then increments, so no two executions share one.
|
|
@@ -54,10 +58,8 @@ module ShieldedMultiSigV2 {
|
|
|
54
58
|
*/
|
|
55
59
|
export sealed ledger _domainSeparator: Bytes<32>;
|
|
56
60
|
|
|
57
|
-
// ─── Initialization ─────────────────────────────────────────────
|
|
58
|
-
|
|
59
61
|
/**
|
|
60
|
-
* @description Registers the signer set
|
|
62
|
+
* @description Registers the signer set at threshold `t` and fixes the
|
|
61
63
|
* EIP-712 domain separator.
|
|
62
64
|
*
|
|
63
65
|
* @notice Call from the implementing contract's constructor only. It writes
|
|
@@ -82,19 +84,17 @@ module ShieldedMultiSigV2 {
|
|
|
82
84
|
*
|
|
83
85
|
* - `instanceSalt` should be cryptographically random.
|
|
84
86
|
* - `signerCommitments` must not contain duplicates.
|
|
85
|
-
* - `
|
|
87
|
+
* - `n` must be at least `t`.
|
|
86
88
|
*
|
|
87
89
|
* @param {Bytes<32>} instanceSalt - Per-deployment salt for commitment derivation.
|
|
88
|
-
* @param {Vector<
|
|
89
|
-
* @param {Uint<8>} thresh - Minimum approvals required.
|
|
90
|
+
* @param {Vector<n, Bytes<32>>} signerCommitments - Hashed signer identities.
|
|
90
91
|
* @returns {[]} Empty tuple.
|
|
91
92
|
*/
|
|
92
|
-
export circuit initialize(
|
|
93
|
+
export circuit initialize<#n>(
|
|
93
94
|
instanceSalt: Bytes<32>,
|
|
94
|
-
signerCommitments: Vector<
|
|
95
|
-
thresh: Uint<8>
|
|
95
|
+
signerCommitments: Vector<n, Bytes<32>>
|
|
96
96
|
): [] {
|
|
97
|
-
|
|
97
|
+
Secp256k1EcdsaMultisig_initialize<n>(instanceSalt, signerCommitments);
|
|
98
98
|
|
|
99
99
|
const hashedName = keccak256<Bytes<18>>(pad(18, "ShieldedMultiSigV2"));
|
|
100
100
|
const hashedVersion = keccak256<Bytes<1>>(pad(1, "1"));
|
|
@@ -127,8 +127,6 @@ module ShieldedMultiSigV2 {
|
|
|
127
127
|
return typeHash as Bytes<32>;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
// ─── Deposit ────────────────────────────────────────────────────
|
|
131
|
-
|
|
132
130
|
/**
|
|
133
131
|
* @description Receives a shielded coin into the multisig treasury.
|
|
134
132
|
*
|
|
@@ -149,8 +147,6 @@ module ShieldedMultiSigV2 {
|
|
|
149
147
|
receiveShielded(disclose(coin));
|
|
150
148
|
}
|
|
151
149
|
|
|
152
|
-
// ─── Execute ────────────────────────────────────────────────────
|
|
153
|
-
|
|
154
150
|
/**
|
|
155
151
|
* @description Executes a shielded send authorized by threshold signatures.
|
|
156
152
|
*
|
|
@@ -161,25 +157,29 @@ module ShieldedMultiSigV2 {
|
|
|
161
157
|
* separator. The digest is bound to the contract instance and the full recipient (kind and
|
|
162
158
|
* address), so a signature authorizes exactly one operation on one instance.
|
|
163
159
|
*
|
|
164
|
-
* Approvals are checked by `
|
|
165
|
-
* commitment from their public key and the instance salt
|
|
166
|
-
*
|
|
160
|
+
* Approvals are checked by `Secp256k1EcdsaMultisig`, which derives each
|
|
161
|
+
* signer's commitment from their public key and the instance salt and
|
|
162
|
+
* rejects duplicates. Constraints below are measured at `t = 2`.
|
|
167
163
|
*
|
|
168
|
-
* @
|
|
164
|
+
* @notice `to` must be a `ShieldedUser`. A contract-addressed coin would be
|
|
165
|
+
* unclaimable, making the transaction malformed.
|
|
166
|
+
*
|
|
167
|
+
* @constraints k=17, rows=98969 (zkir-v3)
|
|
169
168
|
*
|
|
170
169
|
* Requirements:
|
|
171
170
|
*
|
|
172
|
-
* -
|
|
173
|
-
* -
|
|
171
|
+
* - No two entries may be the same signer.
|
|
172
|
+
* - Every public key must hash to a registered signer commitment.
|
|
173
|
+
* - Every signature must be valid over the message hash and use the low-s
|
|
174
174
|
* encoding.
|
|
175
|
-
* -
|
|
175
|
+
* - `to.kind` must be `ShieldedUser`.
|
|
176
176
|
* - Coin value must be >= amount.
|
|
177
177
|
*
|
|
178
178
|
* @param {Proposal_Recipient} to - The recipient.
|
|
179
179
|
* @param {Uint<128>} amount - The amount to send.
|
|
180
180
|
* @param {QualifiedShieldedCoinInfo} coin - The coin to spend (from operator's pool).
|
|
181
|
-
* @param {Vector<
|
|
182
|
-
* @param {Vector<
|
|
181
|
+
* @param {Vector<t, Secp256k1Point>} pubkeys - Public keys of approving signers.
|
|
182
|
+
* @param {Vector<t, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the operation.
|
|
183
183
|
*
|
|
184
184
|
* @returns {ShieldedSendResult} The send result including any change.
|
|
185
185
|
*/
|
|
@@ -187,8 +187,8 @@ module ShieldedMultiSigV2 {
|
|
|
187
187
|
to: Proposal_Recipient,
|
|
188
188
|
amount: Uint<128>,
|
|
189
189
|
coin: QualifiedShieldedCoinInfo,
|
|
190
|
-
pubkeys: Vector<
|
|
191
|
-
signatures: Vector<
|
|
190
|
+
pubkeys: Vector<t, Secp256k1Point>,
|
|
191
|
+
signatures: Vector<t, Secp256k1EcdsaSignature>
|
|
192
192
|
): ShieldedSendResult {
|
|
193
193
|
// Increment nonce
|
|
194
194
|
const currentNonce = _nonce;
|
|
@@ -208,18 +208,21 @@ module ShieldedMultiSigV2 {
|
|
|
208
208
|
EvmAbi_uint128Word(amount)
|
|
209
209
|
]));
|
|
210
210
|
|
|
211
|
-
|
|
211
|
+
Secp256k1EcdsaMultisig_assertApprovals(msgHash, pubkeys, signatures);
|
|
212
212
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
213
|
+
assert(
|
|
214
|
+
to.kind == Proposal_RecipientKind.ShieldedUser,
|
|
215
|
+
"ShieldedMultiSigV2: recipient must be a coin public key"
|
|
216
|
+
);
|
|
217
|
+
const recipient = left<ZswapCoinPublicKey, ContractAddress>(
|
|
218
|
+
ZswapCoinPublicKey { bytes: to.address }
|
|
219
|
+
);
|
|
220
|
+
return Treasury__send(coin, recipient, amount);
|
|
216
221
|
}
|
|
217
222
|
|
|
218
|
-
// ─── Commitments ────────────────────────────────────────────────
|
|
219
|
-
|
|
220
223
|
/**
|
|
221
224
|
* @description Computes a signer commitment from a secp256k1 public key,
|
|
222
|
-
* as `persistentHash(pkX, pkY, salt, "
|
|
225
|
+
* as `persistentHash(pkX, pkY, salt, "Secp256k1EcdsaMultisig:signer")`.
|
|
223
226
|
*
|
|
224
227
|
* Pure, so the deployer can derive constructor commitments off-chain.
|
|
225
228
|
*
|
|
@@ -236,11 +239,9 @@ module ShieldedMultiSigV2 {
|
|
|
236
239
|
pk: Secp256k1Point,
|
|
237
240
|
salt: Bytes<32>
|
|
238
241
|
): Bytes<32> {
|
|
239
|
-
return
|
|
242
|
+
return Secp256k1EcdsaMultisig_calculateSignerId(pk, salt);
|
|
240
243
|
}
|
|
241
244
|
|
|
242
|
-
// ─── View ───────────────────────────────────────────────────────
|
|
243
|
-
|
|
244
245
|
/**
|
|
245
246
|
* @description Returns the nonce the next `execute` digest will bind to.
|
|
246
247
|
*
|
|
@@ -260,7 +261,7 @@ module ShieldedMultiSigV2 {
|
|
|
260
261
|
* @returns {Uint<8>} The signer count.
|
|
261
262
|
*/
|
|
262
263
|
export circuit getSignerCount(): Uint<8> {
|
|
263
|
-
return
|
|
264
|
+
return Secp256k1EcdsaMultisig_getSignerCount();
|
|
264
265
|
}
|
|
265
266
|
|
|
266
267
|
/**
|
|
@@ -271,7 +272,7 @@ module ShieldedMultiSigV2 {
|
|
|
271
272
|
* @returns {Uint<8>} The threshold.
|
|
272
273
|
*/
|
|
273
274
|
export circuit getThreshold(): Uint<8> {
|
|
274
|
-
return
|
|
275
|
+
return Secp256k1EcdsaMultisig_getThreshold();
|
|
275
276
|
}
|
|
276
277
|
|
|
277
278
|
/**
|
|
@@ -283,6 +284,6 @@ module ShieldedMultiSigV2 {
|
|
|
283
284
|
* @returns {Boolean} True if registered.
|
|
284
285
|
*/
|
|
285
286
|
export circuit isSigner(commitment: Bytes<32>): Boolean {
|
|
286
|
-
return
|
|
287
|
+
return Secp256k1EcdsaMultisig_isSigner(commitment);
|
|
287
288
|
}
|
|
288
289
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openzeppelin/compact-contracts",
|
|
3
|
-
"version": "0.4.0-alpha.
|
|
3
|
+
"version": "0.4.0-alpha.6",
|
|
4
4
|
"description": "OpenZeppelin Compact contract library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openzeppelin",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"@noble/curves": "^2.2.0",
|
|
66
66
|
"@noble/hashes": "^2.4.0",
|
|
67
67
|
"@openzeppelin/compact-deployer": "^0.3.1",
|
|
68
|
-
"@openzeppelin/compact-simulator": "^0.4.
|
|
68
|
+
"@openzeppelin/compact-simulator": "^0.4.1",
|
|
69
69
|
"@tsconfig/node24": "^24.0.5",
|
|
70
70
|
"@types/node": "26.6.2",
|
|
71
71
|
"@vitest/coverage-v8": "^5.0.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.4.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (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
|
package/token/MultiToken.compact
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.4.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (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=
|
|
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.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (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()`,
|
|
55
|
-
*
|
|
56
|
-
*
|
|
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
|
|
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=
|
|
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
|
-
|
|
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
|
|
293
|
-
* `
|
|
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=
|
|
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.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (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=
|
|
233
|
+
* @constraints k=14, rows=10497
|
|
234
234
|
*
|
|
235
235
|
* Requirements:
|
|
236
236
|
*
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (token/examples/ZOwnableNativeShieldedTokenExample.compact)
|
|
3
|
+
|
|
4
|
+
pragma language_version >= 0.26.0;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @title ZOwnableNativeShieldedTokenExample
|
|
8
|
+
* @description Deployable reference contract for the
|
|
9
|
+
* `ZOwnableNativeShieldedToken` preset: a native shielded token that only a
|
|
10
|
+
* single shielded owner mints and burns. Holders transfer coins through
|
|
11
|
+
* Zswap directly.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import CompactStandardLibrary;
|
|
15
|
+
|
|
16
|
+
import "../presets/ZOwnableNativeShieldedToken" prefix ZOwnableNativeShieldedToken_;
|
|
17
|
+
|
|
18
|
+
export { ZswapCoinPublicKey, ContractAddress, Either, Maybe, ShieldedCoinInfo };
|
|
19
|
+
|
|
20
|
+
// Surface the preset's state unprefixed so `ledger()` readers use the keys the
|
|
21
|
+
// modules declare.
|
|
22
|
+
import {
|
|
23
|
+
_ownerCommitment,
|
|
24
|
+
_counter,
|
|
25
|
+
_instanceSalt,
|
|
26
|
+
_ownableIsInitialized,
|
|
27
|
+
_domain,
|
|
28
|
+
_name,
|
|
29
|
+
_symbol,
|
|
30
|
+
_decimals,
|
|
31
|
+
_isInitialized,
|
|
32
|
+
_totalMinted,
|
|
33
|
+
_totalBurned,
|
|
34
|
+
} from "../presets/ZOwnableNativeShieldedToken";
|
|
35
|
+
export {
|
|
36
|
+
_ownerCommitment,
|
|
37
|
+
_counter,
|
|
38
|
+
_instanceSalt,
|
|
39
|
+
_ownableIsInitialized,
|
|
40
|
+
_domain,
|
|
41
|
+
_name,
|
|
42
|
+
_symbol,
|
|
43
|
+
_decimals,
|
|
44
|
+
_isInitialized,
|
|
45
|
+
_totalMinted,
|
|
46
|
+
_totalBurned,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @description Deploys the token with its owner, domain and metadata.
|
|
51
|
+
*
|
|
52
|
+
* @warning `ownerId` must be `_computeOwnerId(pk, secretNonce)` for the coin
|
|
53
|
+
* public key the owner's wallet will supply as `ownPublicKey()`. The circuit
|
|
54
|
+
* cannot check this at deploy; any other key leaves the contract with no
|
|
55
|
+
* usable owner and no recovery.
|
|
56
|
+
*
|
|
57
|
+
* @param {Bytes<32>} ownerId - `_computeOwnerId(pk, secretNonce)` of the owner.
|
|
58
|
+
* @param {Bytes<32>} instanceSalt - Random per-deployment salt for the owner commitment.
|
|
59
|
+
* @param {Bytes<32>} tokenDomain - Domain of this contract's token color.
|
|
60
|
+
*/
|
|
61
|
+
constructor(
|
|
62
|
+
ownerId: Bytes<32>,
|
|
63
|
+
instanceSalt: Bytes<32>,
|
|
64
|
+
tokenDomain: Bytes<32>,
|
|
65
|
+
name_: Opaque<"string">,
|
|
66
|
+
symbol_: Opaque<"string">,
|
|
67
|
+
decimals_: Uint<8>,
|
|
68
|
+
) {
|
|
69
|
+
ZOwnableNativeShieldedToken_initialize(
|
|
70
|
+
ownerId,
|
|
71
|
+
instanceSalt,
|
|
72
|
+
tokenDomain,
|
|
73
|
+
name_,
|
|
74
|
+
symbol_,
|
|
75
|
+
decimals_,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export circuit mint(recipient: ZswapCoinPublicKey, amount: Uint<64>, nonce: Bytes<32>): ShieldedCoinInfo {
|
|
80
|
+
return ZOwnableNativeShieldedToken_mint(recipient, amount, nonce);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export circuit burn(coin: ShieldedCoinInfo, amount: Uint<64>, refundTo: ZswapCoinPublicKey): Maybe<ShieldedCoinInfo> {
|
|
84
|
+
return ZOwnableNativeShieldedToken_burn(coin, amount, refundTo);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export circuit transferOwnership(newOwnerId: Bytes<32>): [] {
|
|
88
|
+
ZOwnableNativeShieldedToken_transferOwnership(newOwnerId);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export circuit renounceOwnership(): [] {
|
|
92
|
+
ZOwnableNativeShieldedToken_renounceOwnership();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export circuit owner(): Bytes<32> {
|
|
96
|
+
return ZOwnableNativeShieldedToken_owner();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export pure circuit _computeOwnerId(pk: Either<ZswapCoinPublicKey, ContractAddress>, nonce: Bytes<32>): Bytes<32> {
|
|
100
|
+
return ZOwnableNativeShieldedToken__computeOwnerId(pk, nonce);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export circuit totalMinted(): Uint<128> {
|
|
104
|
+
return ZOwnableNativeShieldedToken_totalMinted();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export circuit tokenColor(): Bytes<32> {
|
|
108
|
+
return ZOwnableNativeShieldedToken_tokenColor();
|
|
109
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
|
-
// OpenZeppelin Compact Contracts v0.4.0-alpha.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (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.
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.4.0-alpha.6 (token/extensions/NativeShieldedTokenDerivedNonce.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.26.0;
|
|
5
5
|
|