@openzeppelin/compact-contracts 0.4.0-alpha.3 → 0.4.0-alpha.4
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/Ecdsa.compact +1 -1
- package/crypto/Eip712.compact +1 -1
- package/crypto/ElGamal.compact +1 -1
- package/multisig/EcdsaSignerManager.compact +1 -1
- package/multisig/ForwarderPrivate.compact +1 -1
- package/multisig/ForwarderShielded.compact +1 -1
- package/multisig/ForwarderUnshielded.compact +1 -1
- package/multisig/ProposalManager.compact +1 -1
- package/multisig/ShieldedTreasury.compact +1 -1
- package/multisig/ShieldedTreasuryStateless.compact +1 -1
- package/multisig/Signer.compact +1 -1
- package/multisig/UnshieldedTreasury.compact +1 -1
- package/multisig/examples/ForwarderPrivateExample.compact +1 -1
- package/multisig/examples/ForwarderShieldedExample.compact +1 -1
- package/multisig/examples/ForwarderUnshieldedExample.compact +1 -1
- package/multisig/examples/NativeShieldedTokenIssuerExample.compact +25 -5
- package/multisig/examples/ShieldedMultiSigV2Example.compact +1 -1
- package/multisig/presets/NativeShieldedTokenIssuer.compact +253 -115
- package/multisig/presets/ShieldedMultiSigV2.compact +1 -1
- package/package.json +5 -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 +1 -1
- package/token/FungibleToken.compact +1 -1
- package/token/MultiToken.compact +1 -1
- package/token/NativeShieldedToken.compact +1 -1
- package/token/NativeShieldedTokenCore.compact +1 -1
- package/token/NativeShieldedTokenFamily.compact +1 -1
- package/token/NonFungibleToken.compact +1 -1
- package/token/extensions/ConfidentialFungibleTokenPublicSupply.compact +1 -1
- package/token/extensions/NativeShieldedTokenDerivedNonce.compact +1 -1
- package/utils/EvmAbi.compact +1 -1
- package/utils/Utils.compact +1 -1
package/access/Ownable.compact
CHANGED
package/crypto/EcdhMask.compact
CHANGED
package/crypto/Ecdsa.compact
CHANGED
package/crypto/Eip712.compact
CHANGED
package/crypto/ElGamal.compact
CHANGED
package/multisig/Signer.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.4 (multisig/examples/ForwarderPrivateExample.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.4 (multisig/examples/ForwarderShieldedExample.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.4 (multisig/examples/ForwarderUnshieldedExample.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.4 (multisig/examples/NativeShieldedTokenIssuerExample.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
@@ -7,10 +7,12 @@ pragma language_version >= 0.26.0;
|
|
|
7
7
|
* @title NativeShieldedTokenIssuerExample
|
|
8
8
|
* @description Deployable reference contract for the `NativeShieldedTokenIssuer`
|
|
9
9
|
* preset: a native shielded token whose supply enters only through an
|
|
10
|
-
* ECDSA-authorized mint
|
|
10
|
+
* ECDSA-authorized mint, to a holder (`mint`) or to the contract itself
|
|
11
|
+
* (`mintToSelf`), and leaves only through an ECDSA-authorized burn, of a
|
|
12
|
+
* holder's coin (`burn`) or of one the contract holds (`burnFromSelf`).
|
|
11
13
|
*
|
|
12
14
|
* The token is non-transferable by construction. There is no transfer circuit,
|
|
13
|
-
* so a holder's only exit is to
|
|
15
|
+
* so a holder's only exit is to pay the coin into a `burn` tx.
|
|
14
16
|
*/
|
|
15
17
|
|
|
16
18
|
import CompactStandardLibrary;
|
|
@@ -94,20 +96,38 @@ export pure circuit _calculateSignerId(
|
|
|
94
96
|
|
|
95
97
|
export circuit mint(
|
|
96
98
|
amount: Uint<64>,
|
|
97
|
-
recipient:
|
|
99
|
+
recipient: ZswapCoinPublicKey,
|
|
98
100
|
pubkeys: Vector<2, Secp256k1Point>,
|
|
99
101
|
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
100
102
|
): ShieldedCoinInfo {
|
|
101
103
|
return NativeShieldedTokenIssuer_mint(amount, recipient, pubkeys, signatures);
|
|
102
104
|
}
|
|
103
105
|
|
|
106
|
+
export circuit mintToSelf(
|
|
107
|
+
amount: Uint<64>,
|
|
108
|
+
pubkeys: Vector<2, Secp256k1Point>,
|
|
109
|
+
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
110
|
+
): ShieldedCoinInfo {
|
|
111
|
+
return NativeShieldedTokenIssuer_mintToSelf(amount, pubkeys, signatures);
|
|
112
|
+
}
|
|
113
|
+
|
|
104
114
|
export circuit burn(
|
|
115
|
+
coin: ShieldedCoinInfo,
|
|
116
|
+
amount: Uint<64>,
|
|
117
|
+
refundTo: ZswapCoinPublicKey,
|
|
118
|
+
pubkeys: Vector<2, Secp256k1Point>,
|
|
119
|
+
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
120
|
+
): Maybe<ShieldedCoinInfo> {
|
|
121
|
+
return NativeShieldedTokenIssuer_burn(coin, amount, refundTo, pubkeys, signatures);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export circuit burnFromSelf(
|
|
105
125
|
coin: QualifiedShieldedCoinInfo,
|
|
106
126
|
amount: Uint<64>,
|
|
107
127
|
pubkeys: Vector<2, Secp256k1Point>,
|
|
108
128
|
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
109
129
|
): Maybe<ShieldedCoinInfo> {
|
|
110
|
-
return
|
|
130
|
+
return NativeShieldedTokenIssuer_burnFromSelf(coin, amount, pubkeys, signatures);
|
|
111
131
|
}
|
|
112
132
|
|
|
113
133
|
export circuit getNonce(): Uint<64> {
|
|
@@ -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.4 (multisig/examples/ShieldedMultiSigV2Example.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.4 (multisig/presets/NativeShieldedTokenIssuer.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.26.0;
|
|
5
5
|
|
|
@@ -7,8 +7,10 @@ pragma language_version >= 0.26.0;
|
|
|
7
7
|
* @module NativeShieldedTokenIssuer
|
|
8
8
|
* @description
|
|
9
9
|
* A 2-of-3 ECDSA multisig that mints and burns one native shielded token,
|
|
10
|
-
* for tokenized deposits. Value enters only through `mint`
|
|
11
|
-
*
|
|
10
|
+
* for tokenized deposits. Value enters only through `mint` (to a holder's
|
|
11
|
+
* coin public key) or `mintToSelf` (a coin this contract holds) and leaves
|
|
12
|
+
* only through `burn` (a holder's coin, paid into the tx) or `burnFromSelf`
|
|
13
|
+
* (a coin this contract holds); each is a single tx carrying two registered
|
|
12
14
|
* signers' approvals, so no single party creates or destroys tokens.
|
|
13
15
|
*
|
|
14
16
|
* Composes `EcdsaSignerManager` (signer commitments, approval checks),
|
|
@@ -23,8 +25,9 @@ pragma language_version >= 0.26.0;
|
|
|
23
25
|
* - `DS`: `_domainSeparator`, the EIP-712 domain separator fixed at
|
|
24
26
|
* construction.
|
|
25
27
|
* - `self`: `kernel.self().bytes`, this contract's address.
|
|
26
|
-
* - `opNonce`: the `_counter` value read at the start of
|
|
27
|
-
*
|
|
28
|
+
* - `opNonce`: the `_counter` value read at the start of every operation
|
|
29
|
+
* (`mint`, `mintToSelf`, `burn`, `burnFromSelf`). It is the signature
|
|
30
|
+
* replay counter and is separate from the
|
|
28
31
|
* `NativeShieldedTokenDerivedNonce` counter that feeds coin nonces.
|
|
29
32
|
* - `cm`: a signer commitment, the registry key.
|
|
30
33
|
* - `color`: `tokenType(_domain, self)`, this token's coin color.
|
|
@@ -37,15 +40,19 @@ pragma language_version >= 0.26.0;
|
|
|
37
40
|
* and a 32-byte address does not fit `address`. `self` inside each struct
|
|
38
41
|
* separates deployments instead.
|
|
39
42
|
* - Mint digest: `keccak(0x1901 ‖ DS ‖ keccak([MINT_TYPEHASH, self,
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* `recipientWord` its active arm and `isContract = !canonRecipient.is_left`.
|
|
43
|
+
* recipient.bytes, uint64Word(opNonce), uint64Word(amount)]))`.
|
|
44
|
+
* - MintToSelf digest: `keccak(0x1901 ‖ DS ‖ keccak([MINT_TO_SELF_TYPEHASH,
|
|
45
|
+
* self, uint64Word(opNonce), uint64Word(amount)]))`.
|
|
44
46
|
* - Burn digest: `keccak(0x1901 ‖ DS ‖ keccak([BURN_TYPEHASH, self,
|
|
45
|
-
* uint64Word(opNonce), uint64Word(amount)]))`.
|
|
47
|
+
* refundTo.bytes, uint64Word(opNonce), uint64Word(amount)]))`.
|
|
48
|
+
* - BurnFromSelf digest: `keccak(0x1901 ‖ DS ‖ keccak([
|
|
49
|
+
* BURN_FROM_SELF_TYPEHASH, self, uint64Word(opNonce), uint64Word(amount)]))`.
|
|
46
50
|
* - Type hashes: `MINT_TYPEHASH = keccak("Mint(bytes32 contractAddress,
|
|
47
|
-
* bytes32 recipient,
|
|
48
|
-
* `
|
|
51
|
+
* bytes32 recipient,uint256 nonce,uint256 amount)")`,
|
|
52
|
+
* `MINT_TO_SELF_TYPEHASH = keccak("MintToSelf(bytes32 contractAddress,
|
|
53
|
+
* uint256 nonce,uint256 amount)")`, `BURN_TYPEHASH = keccak("Burn(bytes32 contractAddress,bytes32 refundTo,
|
|
54
|
+
* uint256 nonce,uint256 amount)")` and `BURN_FROM_SELF_TYPEHASH =
|
|
55
|
+
* keccak("BurnFromSelf(bytes32 contractAddress,uint256 nonce,
|
|
49
56
|
* uint256 amount)")`, written as literal words.
|
|
50
57
|
* - Signer commitment: `cm = H<SignerCommitmentInput>({ pkX, pkY, salt,
|
|
51
58
|
* domain: pad(32, "multisig:signer:") })`, `pkX` / `pkY` the affine
|
|
@@ -57,7 +64,8 @@ pragma language_version >= 0.26.0;
|
|
|
57
64
|
* Digest integers are big-endian ABI words (`utils/EvmAbi`), so an EVM
|
|
58
65
|
* signer's typed-data encoder reproduces them.
|
|
59
66
|
* `contracts/src/multisig/test/EcdsaTestUtils.ts` pins the digests
|
|
60
|
-
* through ethers (`mintMsgHash`, `burnMsgHash
|
|
67
|
+
* through ethers (`mintMsgHash`, `mintToSelfMsgHash`, `burnMsgHash`,
|
|
68
|
+
* `burnFromSelfMsgHash`).
|
|
61
69
|
*
|
|
62
70
|
* @notice Implementing contracts register the signer set from their
|
|
63
71
|
* constructor by calling this module's `initialize`, and MUST NOT import
|
|
@@ -68,8 +76,8 @@ pragma language_version >= 0.26.0;
|
|
|
68
76
|
*
|
|
69
77
|
* @dev Compatibility:
|
|
70
78
|
* The wire format the custodian's signer implements is the EIP-712 domain
|
|
71
|
-
* (`NativeShieldedTokenIssuer`, version `1`, salt), the `Mint` /
|
|
72
|
-
* type strings, the `multisig:signer:` commitment domain (generic prefix,
|
|
79
|
+
* (`NativeShieldedTokenIssuer`, version `1`, salt), the `Mint` /
|
|
80
|
+
* `MintToSelf` / `Burn` / `BurnFromSelf` type strings, the `multisig:signer:` commitment domain (generic prefix,
|
|
73
81
|
* owned by `EcdsaSignerManager`), the `cm` preimage struct, and the
|
|
74
82
|
* `Vector<2>` / `Vector<3>` shapes. Changing any of them breaks every
|
|
75
83
|
* existing signer setup. The test suite pins them through
|
|
@@ -77,22 +85,30 @@ pragma language_version >= 0.26.0;
|
|
|
77
85
|
*
|
|
78
86
|
* @notice Privacy:
|
|
79
87
|
* - Public, per tx:
|
|
80
|
-
* - Entry point:
|
|
88
|
+
* - Entry point: which of the four operations ran.
|
|
81
89
|
* - Approvers: the two signer commitments (`disclose(commitment)` in
|
|
82
90
|
* `Signer_assertSigner`), so WHICH two of the three signers approved.
|
|
83
91
|
* - Mint: `amount`, as the `shieldedMints` effect under the token domain,
|
|
84
92
|
* and the coin commitment as a spend claim. Recipient and nonce are not
|
|
85
93
|
* published. The nonce is `evolveNonce` of the public
|
|
86
94
|
* `_derivedNonceCounter`, so a candidate recipient can be tested
|
|
87
|
-
* against the commitment.
|
|
88
|
-
*
|
|
89
|
-
* output.
|
|
90
|
-
* - Burn: the
|
|
91
|
-
* partial burn, the
|
|
92
|
-
* `
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
95
|
+
* against the commitment.
|
|
96
|
+
* - MintToSelf: as `mint`, plus the same commitment as a receive claim and
|
|
97
|
+
* the contract named in the Zswap output.
|
|
98
|
+
* - Burn: the holder's coin commitment as a receive claim, the burn-output
|
|
99
|
+
* commitment and, on a partial burn, the refund commitment. `amount`,
|
|
100
|
+
* `coin.value` and `refundTo` stay hidden only while `coin` carries a
|
|
101
|
+
* nonce the observer does not know. A coin passed straight from `mint`
|
|
102
|
+
* has a derived nonce, so the receive claim links the burn to its mint
|
|
103
|
+
* and exposes all three by trial: `coin.value` from the mint, `amount`
|
|
104
|
+
* over `[0, value]` against the burn output, `refundTo` against the
|
|
105
|
+
* refund commitment.
|
|
106
|
+
* - BurnFromSelf: the spent coin's nullifier, the burn-output commitment
|
|
107
|
+
* and, on a partial burn, the change commitment as both spend and
|
|
108
|
+
* receive claim. `amount`, the coin's value and `mt_index` are not
|
|
109
|
+
* published, but every held coin has a derived nonce, so its nullifier
|
|
110
|
+
* links the burn to its mint and `amount` is recoverable by trial over
|
|
111
|
+
* `[0, value]`.
|
|
96
112
|
* - Public, as state:
|
|
97
113
|
* - Cells: `_counter`, `_domainSeparator`, `_derivedNonceCounter`,
|
|
98
114
|
* `_signers`, `_signerCount`, `_threshold`, `_instanceSalt`, `_domain`,
|
|
@@ -102,37 +118,38 @@ pragma language_version >= 0.26.0;
|
|
|
102
118
|
* - Private:
|
|
103
119
|
* - Signer material: public keys and signatures are verified in-circuit,
|
|
104
120
|
* never disclosed.
|
|
105
|
-
* - Operation data: burn amounts
|
|
106
|
-
* test above.
|
|
121
|
+
* - Operation data: `burn` amounts and `refundTo`, for a coin whose nonce
|
|
122
|
+
* is secret. Mint recipients, up to the commitment test above.
|
|
107
123
|
* - Signer identity: keys sit behind `cm` with a public salt, so an observer
|
|
108
124
|
* holding a candidate key can test membership; one without cannot
|
|
109
125
|
* correlate a signer across deployments.
|
|
110
126
|
* - Counterparty: a mint recipient learns nothing beyond the coin handed over
|
|
111
127
|
* out of band; every observer learns the amount of every mint and can
|
|
112
128
|
* test a candidate recipient against the commitment.
|
|
113
|
-
* - Auditability: mint amounts are public
|
|
129
|
+
* - Auditability: mint amounts are public; `burnFromSelf` amounts are
|
|
130
|
+
* recoverable by trial, `burn` amounts only for a linkable coin. No
|
|
114
131
|
* on-chain total is kept. `NativeShieldedTokenPublicSupply` adds one and
|
|
115
132
|
* makes burn amounts public.
|
|
116
133
|
*
|
|
117
134
|
* @notice Security:
|
|
118
135
|
* - Digest binding: each struct binds its type hash, `self`, `opNonce` and
|
|
119
|
-
* `amount` (`mint` also
|
|
136
|
+
* `amount` (`mint` also `recipient`, `burn` also `refundTo`) under `DS`,
|
|
137
|
+
* so a
|
|
120
138
|
* signature authorizes one operation on one instance at one nonce, and is
|
|
121
|
-
* neither replayable as
|
|
139
|
+
* neither replayable as another operation, nor under another domain,
|
|
122
140
|
* nor redirectable. Removing the `self` word removes cross-instance
|
|
123
|
-
* replay protection, since `DS` cannot carry the address.
|
|
141
|
+
* replay protection, since `DS` cannot carry the address. `Burn` does not
|
|
142
|
+
* bind `coin`: the payer picks it, so a signature moved to another coin
|
|
143
|
+
* burns only the payer's own value and refunds the bound `refundTo`.
|
|
124
144
|
* - Low-s: verification goes through `Ecdsa_secp256k1EcdsaVerifyLowS`, so a
|
|
125
145
|
* high-s encoding is an invalid signature.
|
|
126
146
|
* - Distinct signers: `assertApprovals` asserts both entries and rejects a
|
|
127
147
|
* repeated commitment, so two distinct registered signers are always
|
|
128
148
|
* required. The threshold `2` is the ceiling `EcdsaSignerManager` accepts.
|
|
129
|
-
* - Canonical recipient: `Utils_canonicalize` zeroes the unused `Either` arm
|
|
130
|
-
* before hashing and minting, so a recipient with both arms populated
|
|
131
|
-
* cannot yield two digests for one destination.
|
|
132
149
|
* - Immutable signer set: no signer reconfiguration circuit is exported, so
|
|
133
150
|
* the three commitments and the threshold are fixed. Losing two of the
|
|
134
151
|
* three keys freezes the contract.
|
|
135
|
-
* - Griefing: the derived-nonce
|
|
152
|
+
* - Griefing: the derived-nonce mints are the only mint paths and both are
|
|
136
153
|
* threshold-gated, so `NativeShieldedTokenDerivedNonce`'s
|
|
137
154
|
* collision-griefing precondition (a caller-nonce mint at another trust
|
|
138
155
|
* level) is absent.
|
|
@@ -140,24 +157,24 @@ pragma language_version >= 0.26.0;
|
|
|
140
157
|
* neither counter advances and the sender pays no fee.
|
|
141
158
|
*
|
|
142
159
|
* @notice Concurrency:
|
|
143
|
-
* - Replay counter: `mint`
|
|
144
|
-
* The read is pinned, so any two of them in one block
|
|
145
|
-
*
|
|
146
|
-
* next nonce.
|
|
147
|
-
* - Derived-nonce counter:
|
|
148
|
-
* the `_counter` conflict already covers
|
|
149
|
-
* - `getNonce`: submitted as a tx it pins `_counter` and conflicts with
|
|
150
|
-
* same-block
|
|
160
|
+
* - Replay counter: `mint`, `mintToSelf`, `burn` and `burnFromSelf` read
|
|
161
|
+
* `_counter` into the digest. The read is pinned, so any two of them in one block
|
|
162
|
+
* conflict: at most one operation lands per block, and the losing signer
|
|
163
|
+
* pair re-signs at the next nonce.
|
|
164
|
+
* - Derived-nonce counter: both mints also pin it (`evolveNonce` consumes
|
|
165
|
+
* it); the `_counter` conflict already covers those pairs.
|
|
166
|
+
* - `getNonce`: submitted as a tx it pins `_counter` and conflicts with any
|
|
167
|
+
* same-block operation.
|
|
151
168
|
* - Views: metadata, `tokenColor` and the signer views read only state
|
|
152
169
|
* written by `initialize`, so they commute with everything.
|
|
153
170
|
*
|
|
154
171
|
* @notice Scope:
|
|
155
172
|
* Mint and burn only. No send, transfer or execute circuit exists, so
|
|
156
|
-
* contract-held coins
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
* No supply accounting.
|
|
173
|
+
* contract-held coins (from `mintToSelf` or `burnFromSelf` change) leave only
|
|
174
|
+
* through `burnFromSelf`, supplied by the operator as
|
|
175
|
+
* `QualifiedShieldedCoinInfo`. Coins minted to users are ordinary
|
|
176
|
+
* Zswap coins the contract neither tracks nor restricts; a holder redeems by
|
|
177
|
+
* paying the coin into a `burn` tx. No supply accounting.
|
|
161
178
|
*
|
|
162
179
|
* @notice Client-side duties:
|
|
163
180
|
* - Before deploy: pick a random `instanceSalt`, derive each `cm` with
|
|
@@ -165,28 +182,35 @@ pragma language_version >= 0.26.0;
|
|
|
165
182
|
* - Per operation: read `getNonce()`, rebuild the digest as
|
|
166
183
|
* `EcdsaTestUtils.ts` does, collect two low-s signatures off-chain, submit
|
|
167
184
|
* keys and signatures in matching `Vector<2>` positions.
|
|
168
|
-
* -
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* -
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
185
|
+
* - `mint`: hand the returned `ShieldedCoinInfo` to the recipient out of
|
|
186
|
+
* band; contract-initiated mints create no ciphertext, so a wallet cannot
|
|
187
|
+
* find the coin by scanning.
|
|
188
|
+
* - `mintToSelf`: persist the returned coin as a contract holding, as for
|
|
189
|
+
* `burnFromSelf` change.
|
|
190
|
+
* - `burn`: the holder's wallet funds `coin` into the tx; hand the returned
|
|
191
|
+
* refund coin to `refundTo` out of band. For an unlinkable burn the holder
|
|
192
|
+
* re-nonces the coin first (a wallet self-transfer yields a fresh secret
|
|
193
|
+
* nonce); the minted coin as-is is valid but linkable. The contract cannot
|
|
194
|
+
* enforce this.
|
|
195
|
+
* - `burnFromSelf` coin tracking: keep contract-held coins off-chain,
|
|
196
|
+
* recovering each coin's `mt_index` from the indexer's `ZswapOutput` /
|
|
197
|
+
* ledger events to build the `QualifiedShieldedCoinInfo` it takes.
|
|
198
|
+
* - `burnFromSelf` change coin: persist the one it returns. It replaces the
|
|
199
|
+
* spent coin as the contract's holding and is not otherwise recoverable.
|
|
176
200
|
*
|
|
177
201
|
* @notice Scalability:
|
|
178
|
-
* - Throughput: one
|
|
202
|
+
* - Throughput: one operation per block (see Concurrency).
|
|
179
203
|
* - State: constant-size, two counters and a three-entry signer set. Nothing
|
|
180
204
|
* grows per operation.
|
|
181
|
-
* - Amounts:
|
|
182
|
-
* `Uint<64>` by
|
|
205
|
+
* - Amounts: both mints cap at `Uint<64>` by `mintShieldedToken`; both burns
|
|
206
|
+
* take `Uint<64>` by their signatures and widen into the module's
|
|
183
207
|
* `Uint<128>`.
|
|
184
208
|
*
|
|
185
209
|
* @dev Composition:
|
|
186
210
|
* - Recipient privacy: pass a caller-supplied secret random nonce to
|
|
187
|
-
* `NST__mint` instead of `NSTDerivedNonce__deriveNonce()`.
|
|
188
|
-
* - Deposits:
|
|
189
|
-
*
|
|
211
|
+
* `NST__mint` / `NST__mintToSelf` instead of `NSTDerivedNonce__deriveNonce()`.
|
|
212
|
+
* - Deposits: no deposit-and-hold path; `burn` receives and spends the
|
|
213
|
+
* holder's coin in one call.
|
|
190
214
|
*
|
|
191
215
|
* @notice Requires ZKIR v3: `keccak256` is unavailable on the v2 backend.
|
|
192
216
|
*/
|
|
@@ -195,7 +219,6 @@ module NativeShieldedTokenIssuer {
|
|
|
195
219
|
|
|
196
220
|
import "../EcdsaSignerManager" prefix EcdsaSignerManager_;
|
|
197
221
|
import "../../crypto/Eip712" prefix Eip712_;
|
|
198
|
-
import "../../utils/Utils" prefix Utils_;
|
|
199
222
|
import "../../utils/EvmAbi" prefix EvmAbi_;
|
|
200
223
|
import "../../token/NativeShieldedToken" prefix NST_;
|
|
201
224
|
import "../../token/extensions/NativeShieldedTokenDerivedNonce" prefix NSTDerivedNonce_;
|
|
@@ -212,10 +235,11 @@ module NativeShieldedTokenIssuer {
|
|
|
212
235
|
export { _derivedNonceCounter };
|
|
213
236
|
|
|
214
237
|
/**
|
|
215
|
-
* @description Signature replay counter.
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
238
|
+
* @description Signature replay counter. Every operation (`mint`,
|
|
239
|
+
* `mintToSelf`, `burn`, `burnFromSelf`) reads it into its digest and
|
|
240
|
+
* increments it; `getNonce` returns the value
|
|
241
|
+
* the next digest binds to. The read is pinned, so at most one operation
|
|
242
|
+
* lands per block.
|
|
219
243
|
*/
|
|
220
244
|
export ledger _counter: Counter;
|
|
221
245
|
|
|
@@ -277,19 +301,39 @@ module NativeShieldedTokenIssuer {
|
|
|
277
301
|
|
|
278
302
|
/**
|
|
279
303
|
* @description `keccak256` of the `Mint` type string:
|
|
280
|
-
* `Mint(bytes32 contractAddress,bytes32 recipient,
|
|
304
|
+
* `Mint(bytes32 contractAddress,bytes32 recipient,uint256 nonce,uint256 amount)`
|
|
281
305
|
*
|
|
282
|
-
* @dev Written as a literal word; see `
|
|
306
|
+
* @dev Written as a literal word; see `BURN_FROM_SELF_TYPEHASH`. The spec checks this
|
|
283
307
|
* word against the type string above.
|
|
284
308
|
*
|
|
285
309
|
* @returns {Bytes<32>} The `Mint` type hash.
|
|
286
310
|
*/
|
|
287
311
|
pure circuit MINT_TYPEHASH(): Bytes<32> {
|
|
288
312
|
const typeHash: Vector<32, Uint<8>> = [
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
313
|
+
0x65, 0x2d, 0x4d, 0xad, 0x8f, 0xb2, 0x6c, 0x5c,
|
|
314
|
+
0x50, 0xc9, 0x87, 0xd4, 0x19, 0xdc, 0x93, 0x53,
|
|
315
|
+
0x14, 0xa0, 0x1e, 0xd4, 0x5d, 0xb1, 0x59, 0xf2,
|
|
316
|
+
0x30, 0xad, 0xc1, 0xa7, 0xe9, 0x02, 0x91, 0x1c
|
|
317
|
+
];
|
|
318
|
+
|
|
319
|
+
return typeHash as Bytes<32>;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @description `keccak256` of the `MintToSelf` type string:
|
|
324
|
+
* `MintToSelf(bytes32 contractAddress,uint256 nonce,uint256 amount)`
|
|
325
|
+
*
|
|
326
|
+
* @dev Written as a literal word; see `BURN_FROM_SELF_TYPEHASH`. The spec
|
|
327
|
+
* checks this word against the type string above.
|
|
328
|
+
*
|
|
329
|
+
* @returns {Bytes<32>} The `MintToSelf` type hash.
|
|
330
|
+
*/
|
|
331
|
+
pure circuit MINT_TO_SELF_TYPEHASH(): Bytes<32> {
|
|
332
|
+
const typeHash: Vector<32, Uint<8>> = [
|
|
333
|
+
0xf8, 0xb3, 0x1e, 0x4e, 0x0f, 0x2d, 0x10, 0x33,
|
|
334
|
+
0x82, 0xb4, 0xb3, 0x72, 0xac, 0x65, 0xa7, 0xad,
|
|
335
|
+
0xcd, 0x03, 0x89, 0x39, 0x8d, 0x24, 0x6c, 0x5e,
|
|
336
|
+
0xc2, 0xc9, 0x09, 0x38, 0x53, 0xdb, 0x49, 0x91
|
|
293
337
|
];
|
|
294
338
|
|
|
295
339
|
return typeHash as Bytes<32>;
|
|
@@ -297,21 +341,41 @@ module NativeShieldedTokenIssuer {
|
|
|
297
341
|
|
|
298
342
|
/**
|
|
299
343
|
* @description `keccak256` of the `Burn` type string:
|
|
300
|
-
* `Burn(bytes32 contractAddress,uint256 nonce,uint256 amount)`
|
|
344
|
+
* `Burn(bytes32 contractAddress,bytes32 refundTo,uint256 nonce,uint256 amount)`
|
|
345
|
+
*
|
|
346
|
+
* @dev Written as a literal word; see `BURN_FROM_SELF_TYPEHASH`. The spec
|
|
347
|
+
* checks this word against the type string above.
|
|
348
|
+
*
|
|
349
|
+
* @returns {Bytes<32>} The `Burn` type hash.
|
|
350
|
+
*/
|
|
351
|
+
pure circuit BURN_TYPEHASH(): Bytes<32> {
|
|
352
|
+
const typeHash: Vector<32, Uint<8>> = [
|
|
353
|
+
0x96, 0x8e, 0x03, 0xa5, 0xba, 0x91, 0xc8, 0xdd,
|
|
354
|
+
0x27, 0x56, 0x79, 0x5a, 0xc6, 0x57, 0x52, 0x13,
|
|
355
|
+
0x06, 0xe0, 0xd9, 0x7c, 0xe8, 0x1e, 0xbf, 0x9b,
|
|
356
|
+
0x68, 0x24, 0x45, 0xa2, 0x86, 0xfc, 0xeb, 0xef
|
|
357
|
+
];
|
|
358
|
+
|
|
359
|
+
return typeHash as Bytes<32>;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* @description `keccak256` of the `BurnFromSelf` type string:
|
|
364
|
+
* `BurnFromSelf(bytes32 contractAddress,uint256 nonce,uint256 amount)`
|
|
301
365
|
*
|
|
302
366
|
* @dev Written as a literal word. `compactc` emits a full keccak
|
|
303
367
|
* permutation even for a constant argument, so hashing the type string
|
|
304
368
|
* in-circuit would add ~4.2k rows to every operation. The spec checks this
|
|
305
369
|
* word against the type string above.
|
|
306
370
|
*
|
|
307
|
-
* @returns {Bytes<32>} The `
|
|
371
|
+
* @returns {Bytes<32>} The `BurnFromSelf` type hash.
|
|
308
372
|
*/
|
|
309
|
-
pure circuit
|
|
373
|
+
pure circuit BURN_FROM_SELF_TYPEHASH(): Bytes<32> {
|
|
310
374
|
const typeHash: Vector<32, Uint<8>> = [
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
375
|
+
0x08, 0xba, 0x21, 0x80, 0x7e, 0x7f, 0x75, 0x47,
|
|
376
|
+
0xa2, 0x70, 0x1d, 0x8c, 0x53, 0x06, 0x39, 0x7d,
|
|
377
|
+
0x97, 0xad, 0xfd, 0x3e, 0xa6, 0xf6, 0xa2, 0x8c,
|
|
378
|
+
0x10, 0x0c, 0xbd, 0x64, 0x9c, 0x7f, 0x5d, 0x94
|
|
315
379
|
];
|
|
316
380
|
|
|
317
381
|
return typeHash as Bytes<32>;
|
|
@@ -348,7 +412,7 @@ module NativeShieldedTokenIssuer {
|
|
|
348
412
|
* @notice The returned coin info is the only copy available to the
|
|
349
413
|
* recipient; deliver it out of band.
|
|
350
414
|
*
|
|
351
|
-
* @constraints k=17, rows=
|
|
415
|
+
* @constraints k=17, rows=89815 (zkir-v3)
|
|
352
416
|
*
|
|
353
417
|
* Requirements:
|
|
354
418
|
*
|
|
@@ -357,61 +421,135 @@ module NativeShieldedTokenIssuer {
|
|
|
357
421
|
* - Signers must not be duplicates.
|
|
358
422
|
* - Threshold must be met.
|
|
359
423
|
* - `recipient` is not zero.
|
|
360
|
-
* - A contract `recipient` is this contract's own address.
|
|
361
424
|
*
|
|
362
425
|
* @param {Uint<64>} amount - The token amount to mint.
|
|
363
|
-
* @param {
|
|
426
|
+
* @param {ZswapCoinPublicKey} recipient - The coin public key to receive the minted tokens.
|
|
364
427
|
* @param {Vector<2, Secp256k1Point>} pubkeys - Public keys of approving signers.
|
|
365
428
|
* @param {Vector<2, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the mint hash.
|
|
366
429
|
* @returns {ShieldedCoinInfo} The minted coin (nonce, color, value).
|
|
367
430
|
*/
|
|
368
431
|
export circuit mint(
|
|
369
432
|
amount: Uint<64>,
|
|
370
|
-
recipient:
|
|
433
|
+
recipient: ZswapCoinPublicKey,
|
|
371
434
|
pubkeys: Vector<2, Secp256k1Point>,
|
|
372
435
|
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
373
436
|
): ShieldedCoinInfo {
|
|
374
437
|
const opNonce = _counter;
|
|
375
438
|
_counter.increment(1);
|
|
376
439
|
|
|
377
|
-
|
|
378
|
-
|
|
440
|
+
const msgHash = Eip712_hashTypedData(_domainSeparator, keccak256<Vector<5, Bytes<32>>>([
|
|
441
|
+
MINT_TYPEHASH(),
|
|
442
|
+
// Binds the digest to this deployment. The domain cannot carry the
|
|
443
|
+
// address, so removing this word removes cross-instance replay
|
|
444
|
+
// protection.
|
|
445
|
+
kernel.self().bytes,
|
|
446
|
+
recipient.bytes,
|
|
447
|
+
EvmAbi_uint64Word(opNonce),
|
|
448
|
+
EvmAbi_uint64Word(amount)
|
|
449
|
+
]));
|
|
450
|
+
|
|
451
|
+
EcdsaSignerManager_assertApprovals(msgHash, pubkeys, signatures);
|
|
379
452
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
const recipientWord = canonRecipient.is_left
|
|
383
|
-
? canonRecipient.left.bytes
|
|
384
|
-
: canonRecipient.right.bytes;
|
|
453
|
+
return NST__mint(recipient, amount, NSTDerivedNonce__deriveNonce());
|
|
454
|
+
}
|
|
385
455
|
|
|
386
|
-
|
|
387
|
-
|
|
456
|
+
/**
|
|
457
|
+
* @description Mints a new shielded coin of this contract's token to the
|
|
458
|
+
* contract itself, claimed in the same call, authorized by threshold
|
|
459
|
+
* signatures.
|
|
460
|
+
*
|
|
461
|
+
* @notice The returned coin info is the contract's only record of the
|
|
462
|
+
* holding; persist it for `burnFromSelf`.
|
|
463
|
+
*
|
|
464
|
+
* @constraints k=17, rows=91259 (zkir-v3)
|
|
465
|
+
*
|
|
466
|
+
* Requirements:
|
|
467
|
+
*
|
|
468
|
+
* - Both public keys must hash to registered signer commitments.
|
|
469
|
+
* - Both signatures must be valid over the mint-to-self message hash.
|
|
470
|
+
* - Signers must not be duplicates.
|
|
471
|
+
* - Threshold must be met.
|
|
472
|
+
*
|
|
473
|
+
* @param {Uint<64>} amount - The token amount to mint.
|
|
474
|
+
* @param {Vector<2, Secp256k1Point>} pubkeys - Public keys of approving signers.
|
|
475
|
+
* @param {Vector<2, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the mint-to-self hash.
|
|
476
|
+
* @returns {ShieldedCoinInfo} The minted coin (nonce, color, value).
|
|
477
|
+
*/
|
|
478
|
+
export circuit mintToSelf(
|
|
479
|
+
amount: Uint<64>,
|
|
480
|
+
pubkeys: Vector<2, Secp256k1Point>,
|
|
481
|
+
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
482
|
+
): ShieldedCoinInfo {
|
|
483
|
+
const opNonce = _counter;
|
|
484
|
+
_counter.increment(1);
|
|
485
|
+
|
|
486
|
+
const msgHash = Eip712_hashTypedData(_domainSeparator, keccak256<Vector<4, Bytes<32>>>([
|
|
487
|
+
MINT_TO_SELF_TYPEHASH(),
|
|
488
|
+
// Binds the digest to this deployment. The domain cannot carry the
|
|
489
|
+
// address, so removing this word removes cross-instance replay
|
|
490
|
+
// protection.
|
|
491
|
+
kernel.self().bytes,
|
|
492
|
+
EvmAbi_uint64Word(opNonce),
|
|
493
|
+
EvmAbi_uint64Word(amount)
|
|
494
|
+
]));
|
|
495
|
+
|
|
496
|
+
EcdsaSignerManager_assertApprovals(msgHash, pubkeys, signatures);
|
|
497
|
+
|
|
498
|
+
return NST__mintToSelf(amount, NSTDerivedNonce__deriveNonce());
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* @description Burns `amount` from a holder's coin, authorized by threshold
|
|
503
|
+
* signatures. The holder's transaction pays `coin` in; the contract
|
|
504
|
+
* receives it and burns it in the same call. Any change goes to `refundTo`.
|
|
505
|
+
*
|
|
506
|
+
* @notice The returned refund coin info is the only copy available to
|
|
507
|
+
* `refundTo`; deliver it out of band.
|
|
508
|
+
*
|
|
509
|
+
* @constraints k=17, rows=118642 (zkir-v3)
|
|
510
|
+
*
|
|
511
|
+
* Requirements:
|
|
512
|
+
*
|
|
513
|
+
* - Both public keys must hash to registered signer commitments.
|
|
514
|
+
* - Both signatures must be valid over the burn message hash.
|
|
515
|
+
* - Signers must not be duplicates.
|
|
516
|
+
* - Threshold must be met.
|
|
517
|
+
* - `coin.color` is this contract's token color.
|
|
518
|
+
* - `amount` is less than or equal to `coin.value`.
|
|
519
|
+
* - `refundTo` is not zero.
|
|
520
|
+
*
|
|
521
|
+
* @param {ShieldedCoinInfo} coin - The holder's coin to burn from.
|
|
522
|
+
* @param {Uint<64>} amount - The token amount to burn.
|
|
523
|
+
* @param {ZswapCoinPublicKey} refundTo - Receives `coin.value - amount`.
|
|
524
|
+
* @param {Vector<2, Secp256k1Point>} pubkeys - Public keys of approving signers.
|
|
525
|
+
* @param {Vector<2, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the burn hash.
|
|
526
|
+
* @returns {Maybe<ShieldedCoinInfo>} The refund coin created for `refundTo`,
|
|
527
|
+
* or `none` if the coin was burned in full.
|
|
528
|
+
*/
|
|
529
|
+
export circuit burn(
|
|
530
|
+
coin: ShieldedCoinInfo,
|
|
531
|
+
amount: Uint<64>,
|
|
532
|
+
refundTo: ZswapCoinPublicKey,
|
|
533
|
+
pubkeys: Vector<2, Secp256k1Point>,
|
|
534
|
+
signatures: Vector<2, Secp256k1EcdsaSignature>
|
|
535
|
+
): Maybe<ShieldedCoinInfo> {
|
|
536
|
+
const opNonce = _counter;
|
|
537
|
+
_counter.increment(1);
|
|
538
|
+
|
|
539
|
+
const msgHash = Eip712_hashTypedData(_domainSeparator, keccak256<Vector<5, Bytes<32>>>([
|
|
540
|
+
BURN_TYPEHASH(),
|
|
388
541
|
// Binds the digest to this deployment. The domain cannot carry the
|
|
389
542
|
// address, so removing this word removes cross-instance replay
|
|
390
543
|
// protection.
|
|
391
544
|
kernel.self().bytes,
|
|
392
|
-
|
|
393
|
-
EvmAbi_boolWord(!canonRecipient.is_left),
|
|
545
|
+
refundTo.bytes,
|
|
394
546
|
EvmAbi_uint64Word(opNonce),
|
|
395
547
|
EvmAbi_uint64Word(amount)
|
|
396
548
|
]));
|
|
397
549
|
|
|
398
550
|
EcdsaSignerManager_assertApprovals(msgHash, pubkeys, signatures);
|
|
399
551
|
|
|
400
|
-
|
|
401
|
-
// this contract, since a mint to any other contract leaves an unclaimed
|
|
402
|
-
// output.
|
|
403
|
-
// The recipient is public (it is already in the signed digest), so the
|
|
404
|
-
// arm may gate which mint runs.
|
|
405
|
-
const target = disclose(canonRecipient);
|
|
406
|
-
const self = kernel.self();
|
|
407
|
-
assert(target.is_left || target.right == self,
|
|
408
|
-
"NativeShieldedToken: recipient contract must be self");
|
|
409
|
-
const nonce = NSTDerivedNonce__deriveNonce();
|
|
410
|
-
if (target.is_left) {
|
|
411
|
-
return NST__mint(target.left, amount, nonce);
|
|
412
|
-
} else {
|
|
413
|
-
return NST__mintToSelf(amount, nonce);
|
|
414
|
-
}
|
|
552
|
+
return NST__burn(coin, amount, refundTo);
|
|
415
553
|
}
|
|
416
554
|
|
|
417
555
|
/**
|
|
@@ -428,7 +566,7 @@ module NativeShieldedTokenIssuer {
|
|
|
428
566
|
* Requirements:
|
|
429
567
|
*
|
|
430
568
|
* - Both public keys must hash to registered signer commitments.
|
|
431
|
-
* - Both signatures must be valid over the burn message hash.
|
|
569
|
+
* - Both signatures must be valid over the burn-from-self message hash.
|
|
432
570
|
* - Signers must not be duplicates.
|
|
433
571
|
* - Threshold must be met.
|
|
434
572
|
* - `coin.color` is this contract's token color.
|
|
@@ -437,11 +575,11 @@ module NativeShieldedTokenIssuer {
|
|
|
437
575
|
* @param {QualifiedShieldedCoinInfo} coin - The contract-held coin to burn from.
|
|
438
576
|
* @param {Uint<64>} amount - The token amount to burn.
|
|
439
577
|
* @param {Vector<2, Secp256k1Point>} pubkeys - Public keys of approving signers.
|
|
440
|
-
* @param {Vector<2, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the burn hash.
|
|
578
|
+
* @param {Vector<2, Secp256k1EcdsaSignature>} signatures - ECDSA signatures over the burn-from-self hash.
|
|
441
579
|
* @returns {Maybe<ShieldedCoinInfo>} The change coin retained by the
|
|
442
580
|
* contract, or `none` if the coin was burned in full.
|
|
443
581
|
*/
|
|
444
|
-
export circuit
|
|
582
|
+
export circuit burnFromSelf(
|
|
445
583
|
coin: QualifiedShieldedCoinInfo,
|
|
446
584
|
amount: Uint<64>,
|
|
447
585
|
pubkeys: Vector<2, Secp256k1Point>,
|
|
@@ -451,7 +589,7 @@ module NativeShieldedTokenIssuer {
|
|
|
451
589
|
_counter.increment(1);
|
|
452
590
|
|
|
453
591
|
const msgHash = Eip712_hashTypedData(_domainSeparator, keccak256<Vector<4, Bytes<32>>>([
|
|
454
|
-
|
|
592
|
+
BURN_FROM_SELF_TYPEHASH(),
|
|
455
593
|
// Binds the digest to this deployment. The domain cannot carry the
|
|
456
594
|
// address, so removing this word removes cross-instance replay
|
|
457
595
|
// protection.
|
|
@@ -466,7 +604,7 @@ module NativeShieldedTokenIssuer {
|
|
|
466
604
|
}
|
|
467
605
|
|
|
468
606
|
/**
|
|
469
|
-
* @description Returns the counter the next
|
|
607
|
+
* @description Returns the counter the next operation's digest will bind to.
|
|
470
608
|
*
|
|
471
609
|
* @constraints k=6, rows=34 (zkir-v3)
|
|
472
610
|
*
|
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.4",
|
|
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.
|
|
66
|
+
"@noble/hashes": "^2.4.0",
|
|
67
|
+
"@openzeppelin/compact-deployer": "^0.3.1",
|
|
67
68
|
"@openzeppelin/compact-simulator": "^0.4.0",
|
|
68
69
|
"@tsconfig/node24": "^24.0.5",
|
|
69
|
-
"@types/node": "26.
|
|
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",
|
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.4 (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.4 (token/extensions/NativeShieldedTokenDerivedNonce.compact)
|
|
3
3
|
|
|
4
4
|
pragma language_version >= 0.26.0;
|
|
5
5
|
|
package/utils/EvmAbi.compact
CHANGED
package/utils/Utils.compact
CHANGED