@openzeppelin/compact-contracts 0.1.0
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 +278 -0
- package/access/AccessControl.compact +479 -0
- package/access/Ownable.compact +353 -0
- package/access/ShieldedAccessControl.compact +784 -0
- package/access/ZOwnablePK.compact +304 -0
- package/package.json +54 -0
- package/security/Initializable.compact +60 -0
- package/security/Pausable.compact +89 -0
- package/token/FungibleToken.compact +742 -0
- package/token/MultiToken.compact +728 -0
- package/token/NonFungibleToken.compact +954 -0
- package/utils/Utils.compact +98 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.1.0 (access/ZOwnablePK.compact)
|
|
3
|
+
|
|
4
|
+
pragma language_version >= 0.21.0;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module ZOwnablePK
|
|
8
|
+
* @description A shielded, public key-derived Ownable module.
|
|
9
|
+
*
|
|
10
|
+
* `ZOwnablePK` provides a privacy-preserving access control mechanism
|
|
11
|
+
* for contracts with a single administrative user. Unlike traditional
|
|
12
|
+
* `Ownable` implementations that store or expose the owner's public key
|
|
13
|
+
* on-chain, this module stores only a commitment to a hashed identifier
|
|
14
|
+
* derived from the owner's public key and a secret nonce.
|
|
15
|
+
* For the strongest security guarantees, use an Air-Gapped Public Key.
|
|
16
|
+
*
|
|
17
|
+
* @notice This module explicitly supports commitments derived from public keys;
|
|
18
|
+
* however, it may be possible to use contract addresses when contract-to-contract
|
|
19
|
+
* calls become available. This will be revisited when it's known if/how witnesses
|
|
20
|
+
* are used from a contract address context.
|
|
21
|
+
*
|
|
22
|
+
* @dev Features:
|
|
23
|
+
* - Obfuscated owner identity: The owner's public key is never revealed on-chain.
|
|
24
|
+
* - Stateless verification: The contract never needs access to the full public key.
|
|
25
|
+
* - Built-in support for transfer and renounce functionality.
|
|
26
|
+
* - Instance-specific salts to prevent cross-contract correlation.
|
|
27
|
+
* - Deterministic hashing with `persistentHash` to support zero-knowledge verification.
|
|
28
|
+
*
|
|
29
|
+
* @dev Commitment structure:
|
|
30
|
+
* ```
|
|
31
|
+
* id = SHA256(pk, secretNonce)
|
|
32
|
+
* commitment = SHA256(id, instanceSalt, counter, "ZOwnablePK:shield:")
|
|
33
|
+
* ```
|
|
34
|
+
* The commitment changes on each transfer due to the incrementing `counter`,
|
|
35
|
+
* providing unlinkability across ownership changes.
|
|
36
|
+
*
|
|
37
|
+
* @dev Security Considerations:
|
|
38
|
+
* - The `secretNonce` must be kept private. Loss of the nonce prevents the
|
|
39
|
+
* owner from proving ownership or transferring it.
|
|
40
|
+
* - Ownership validation is entirely circuit-based using witness-provided values.
|
|
41
|
+
* - The `_instanceSalt` is immutable and used to differentiate deployments.
|
|
42
|
+
*
|
|
43
|
+
* @notice Best used for single-admin contracts with privacy requirements.
|
|
44
|
+
* It is not designed for multi-owner or role-based access control.
|
|
45
|
+
*/
|
|
46
|
+
module ZOwnablePK {
|
|
47
|
+
import CompactStandardLibrary;
|
|
48
|
+
import "../security/Initializable" prefix Initializable_;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @ledger _ownerCommitment
|
|
52
|
+
* @description Stores the current hashed commitment representing the owner.
|
|
53
|
+
* This commitment is derived from the public identifier (e.g., `SHA256(pk, nonce)`),
|
|
54
|
+
* the `instanceSalt`, the transfer `counter`, and a domain separator.
|
|
55
|
+
*
|
|
56
|
+
* A commitment of `default<Bytes<32>>` (i.e., zero) indicates the contract is unowned.
|
|
57
|
+
*/
|
|
58
|
+
export ledger _ownerCommitment: Bytes<32>;
|
|
59
|
+
/**
|
|
60
|
+
* @ledger _counter
|
|
61
|
+
* @description Internal transfer counter used to prevent commitment reuse.
|
|
62
|
+
*
|
|
63
|
+
* Increments by 1 on every successful ownership transfer. Combined with `id` and
|
|
64
|
+
* `instanceSalt` to compute unique owner commitments over time.
|
|
65
|
+
*/
|
|
66
|
+
export ledger _counter: Counter;
|
|
67
|
+
/**
|
|
68
|
+
* @sealed @ledger _instanceSalt
|
|
69
|
+
* @description A per-instance value provided at initialization used to namespace
|
|
70
|
+
* commitments for this contract instance.
|
|
71
|
+
*
|
|
72
|
+
* This salt prevents commitment collisions across contracts that might otherwise use
|
|
73
|
+
* the same owner identifiers or domain parameters. It is immutable after initialization.
|
|
74
|
+
*/
|
|
75
|
+
export sealed ledger _instanceSalt: Bytes<32>;
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @witness wit_secretNonce
|
|
79
|
+
* @description A private per-user nonce used in deriving the shielded owner identifier.
|
|
80
|
+
*
|
|
81
|
+
* Combined with the user's public key as `SHA256(pk, nonce)` to produce an obfuscated,
|
|
82
|
+
* unlinkable identity commitment. Users are encouraged to rotate this value on ownership changes.
|
|
83
|
+
*/
|
|
84
|
+
export witness wit_secretNonce(): Bytes<32>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @description Initializes the contract by setting the initial owner via `ownerId`
|
|
88
|
+
* and storing the `instanceSalt` that acts as a privacy additive for preventing
|
|
89
|
+
* duplicate commitments among other contracts implementing ZOwnablePK.
|
|
90
|
+
*
|
|
91
|
+
* @warning The `ownerId` must be calculated prior to contract deployment using the SHA256 hashing algorithm.
|
|
92
|
+
* Using any other algorithm will result in a permanent loss of contract access.
|
|
93
|
+
*
|
|
94
|
+
* @circuitInfo k=14, rows=14933
|
|
95
|
+
*
|
|
96
|
+
* Requirements:
|
|
97
|
+
*
|
|
98
|
+
* - Contract is not initialized.
|
|
99
|
+
* - `ownerId` is not zero.
|
|
100
|
+
*
|
|
101
|
+
* @param {Bytes<32>} ownerId - The owner's unique identifier SHA256(pk, nonce).
|
|
102
|
+
* @param {Bytes<32>} instanceSalt - Contract salt to prevent duplicate commitments if
|
|
103
|
+
* users reuse their PK and secretNonce witness (not recommended).
|
|
104
|
+
* @returns {[]} Empty tuple.
|
|
105
|
+
*/
|
|
106
|
+
export circuit initialize(ownerId: Bytes<32>, instanceSalt: Bytes<32>): [] {
|
|
107
|
+
Initializable_initialize();
|
|
108
|
+
|
|
109
|
+
assert(ownerId != default<Bytes<32>>, "ZOwnablePK: invalid id");
|
|
110
|
+
_instanceSalt = disclose(instanceSalt);
|
|
111
|
+
_transferOwnership(ownerId);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* @description Returns the current commitment representing the contract owner.
|
|
116
|
+
* The full commitment is: `SHA256(SHA256(pk, nonce), instanceSalt, counter, domain)`.
|
|
117
|
+
*
|
|
118
|
+
* @circuitInfo k=10, rows=57
|
|
119
|
+
*
|
|
120
|
+
* Requirements:
|
|
121
|
+
*
|
|
122
|
+
* - Contract is initialized.
|
|
123
|
+
*
|
|
124
|
+
* @returns {Bytes<32>} The current owner's commitment.
|
|
125
|
+
*/
|
|
126
|
+
export circuit owner(): Bytes<32> {
|
|
127
|
+
Initializable_assertInitialized();
|
|
128
|
+
return _ownerCommitment;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @description Transfers ownership to `newOwnerId`.
|
|
133
|
+
* `newOwnerId` must be precalculated and given to the current owner off chain.
|
|
134
|
+
*
|
|
135
|
+
* @circuitInfo k=16, rows=39240
|
|
136
|
+
*
|
|
137
|
+
* Requirements:
|
|
138
|
+
*
|
|
139
|
+
* - Contract is initialized.
|
|
140
|
+
* - Caller is the current owner.
|
|
141
|
+
* - `newOwnerId` is not an empty array.
|
|
142
|
+
*
|
|
143
|
+
* @param {Bytes<32>} newOwnerId - The new owner's unique identifier (`SHA256(pk, nonce)`).
|
|
144
|
+
* @returns {[]} Empty tuple.
|
|
145
|
+
*/
|
|
146
|
+
export circuit transferOwnership(newOwnerId: Bytes<32>): [] {
|
|
147
|
+
Initializable_assertInitialized();
|
|
148
|
+
|
|
149
|
+
assertOnlyOwner();
|
|
150
|
+
assert(newOwnerId != default<Bytes<32>>, "ZOwnablePK: invalid id");
|
|
151
|
+
_transferOwnership(newOwnerId);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* @description Leaves the contract without an owner.
|
|
156
|
+
* It will not be possible to call `assertOnlyOwner` circuits anymore.
|
|
157
|
+
* Can only be called by the current owner.
|
|
158
|
+
*
|
|
159
|
+
* @circuitInfo k=15, rows=24442
|
|
160
|
+
*
|
|
161
|
+
* Requirements:
|
|
162
|
+
*
|
|
163
|
+
* - Contract is initialized.
|
|
164
|
+
* - Caller is the current owner.
|
|
165
|
+
*
|
|
166
|
+
* @returns {[]} Empty tuple.
|
|
167
|
+
*/
|
|
168
|
+
export circuit renounceOwnership(): [] {
|
|
169
|
+
Initializable_assertInitialized();
|
|
170
|
+
|
|
171
|
+
assertOnlyOwner();
|
|
172
|
+
_ownerCommitment.resetToDefault();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @description Throws if called by any account whose id hash `SHA256(pk, nonce)` does not match
|
|
177
|
+
* the stored owner commitment.
|
|
178
|
+
* Use this to only allow the owner to call specific circuits.
|
|
179
|
+
*
|
|
180
|
+
* @circuitInfo k=15, rows=24437
|
|
181
|
+
*
|
|
182
|
+
* Requirements:
|
|
183
|
+
*
|
|
184
|
+
* - Contract is initialized.
|
|
185
|
+
* - Caller's id (`SHA256(pk, nonce)`) when used in `_computeOwnerCommitment` equals
|
|
186
|
+
* the stored `_ownerCommitment`, thus verifying themselves as the owner.
|
|
187
|
+
*
|
|
188
|
+
* @returns {[]} Empty tuple.
|
|
189
|
+
*/
|
|
190
|
+
export circuit assertOnlyOwner(): [] {
|
|
191
|
+
Initializable_assertInitialized();
|
|
192
|
+
|
|
193
|
+
const nonce = wit_secretNonce();
|
|
194
|
+
const callerAsEither =
|
|
195
|
+
Either<ZswapCoinPublicKey, ContractAddress> { is_left: true,
|
|
196
|
+
left: ownPublicKey(),
|
|
197
|
+
right: ContractAddress { bytes: pad(32, "") } };
|
|
198
|
+
const id = _computeOwnerId(callerAsEither, nonce);
|
|
199
|
+
assert(_ownerCommitment == _computeOwnerCommitment(id, _counter),
|
|
200
|
+
"ZOwnablePK: caller is not the owner"
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @description Computes the owner commitment from the given `id` and `counter`.
|
|
206
|
+
*
|
|
207
|
+
* ## Owner ID (`id`)
|
|
208
|
+
* The `id` is expected to be computed off-chain as:
|
|
209
|
+
* `id = SHA256(pk, nonce)`
|
|
210
|
+
*
|
|
211
|
+
* - `pk`: The owner's public key.
|
|
212
|
+
* - `nonce`: A secret nonce scoped to the instance, ideally rotated with each transfer.
|
|
213
|
+
*
|
|
214
|
+
* ## Commitment Derivation
|
|
215
|
+
* `commitment = SHA256(id, instanceSalt, counter, domain)`
|
|
216
|
+
*
|
|
217
|
+
* - `id`: See above.
|
|
218
|
+
* - `instanceSalt`: A unique per-deployment salt, stored during initialization.
|
|
219
|
+
* This prevents commitment collisions across deployments.
|
|
220
|
+
* - `counter`: Incremented with each ownership transfer, ensuring uniqueness
|
|
221
|
+
* even with repeated `id` values. Cast to `Field` then `Bytes<32>` for hashing.
|
|
222
|
+
* - `domain`: Domain separator `"ZOwnablePK:shield:"` (padded to 32 bytes) to prevent
|
|
223
|
+
* hash collisions when extending the module or using similar commitment schemes.
|
|
224
|
+
*
|
|
225
|
+
* @circuitInfo k=14, rows=14853
|
|
226
|
+
*
|
|
227
|
+
* Requirements:
|
|
228
|
+
*
|
|
229
|
+
* - Contract is initialized.
|
|
230
|
+
*
|
|
231
|
+
* @param {Bytes<32>} id - The unique identifier of the owner calculated by `SHA256(pk, nonce)`.
|
|
232
|
+
* @param {Uint<64>} counter - The current counter or round. This increments by `1`
|
|
233
|
+
* after every transfer to prevent duplicate commitments given the same `id`.
|
|
234
|
+
* @returns {Bytes<32>} The commitment derived from `id` and `counter`.
|
|
235
|
+
*/
|
|
236
|
+
export circuit _computeOwnerCommitment(id: Bytes<32>, counter: Uint<64>,): Bytes<32> {
|
|
237
|
+
Initializable_assertInitialized();
|
|
238
|
+
return persistentHash<Vector<4, Bytes<32>>>(
|
|
239
|
+
[id, _instanceSalt, counter as Field as Bytes<32>, pad(32, "ZOwnablePK:shield:")]
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* @description Computes the unique identifier (`id`) of the owner from their
|
|
245
|
+
* public key and a secret nonce.
|
|
246
|
+
*
|
|
247
|
+
* ## ID Derivation
|
|
248
|
+
* `id = SHA256(pk, nonce)`
|
|
249
|
+
*
|
|
250
|
+
* - `pk`: The public key of the caller. This is passed explicitly to allow
|
|
251
|
+
* for off-chain derivation, testing, or scenarios where the caller is
|
|
252
|
+
* different from the subject of the computation.
|
|
253
|
+
* We recommend using an Air-Gapped Public Key.
|
|
254
|
+
* - `nonce`: A secret nonce tied to the identity. The generation strategy is
|
|
255
|
+
* left to the user, offering different security/convenience trade-offs.
|
|
256
|
+
*
|
|
257
|
+
* The result is a 32-byte commitment that uniquely identifies the owner.
|
|
258
|
+
* This value is later used in owner commitment hashing,
|
|
259
|
+
* and acts as a privacy-preserving alternative to a raw public key.
|
|
260
|
+
*
|
|
261
|
+
* @notice This module allows ownership to be tied to an identity commitment derived
|
|
262
|
+
* from a public key and secret nonce.
|
|
263
|
+
* While typically used with user public keys, this mechanism may also
|
|
264
|
+
* support contract addresses as identifiers in future contract-to-contract
|
|
265
|
+
* interactions. Both are treated as 32-byte values (`Bytes<32>`).
|
|
266
|
+
*
|
|
267
|
+
* Requirements:
|
|
268
|
+
*
|
|
269
|
+
* - `pk` is not a ContractAddress.
|
|
270
|
+
*
|
|
271
|
+
* @param {Either<ZswapCoinPublicKey, ContractAddress>} pk - The public key of the identity being committed.
|
|
272
|
+
* @param {Bytes<32>} nonce - A private nonce to scope the commitment.
|
|
273
|
+
* @returns {Bytes<32>} The computed owner ID.
|
|
274
|
+
*/
|
|
275
|
+
export pure circuit _computeOwnerId(
|
|
276
|
+
pk: Either<ZswapCoinPublicKey, ContractAddress>,
|
|
277
|
+
nonce: Bytes<32>
|
|
278
|
+
): Bytes<32> {
|
|
279
|
+
assert(pk.is_left, "ZOwnablePK: contract address owners are not yet supported");
|
|
280
|
+
|
|
281
|
+
return persistentHash<Vector<2, Bytes<32>>>([pk.left.bytes, nonce]);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @description Transfers ownership to owner id `newOwnerId` without
|
|
286
|
+
* enforcing permission checks on the caller.
|
|
287
|
+
*
|
|
288
|
+
* @circuitInfo k=14, rows=14823
|
|
289
|
+
*
|
|
290
|
+
* Requirements:
|
|
291
|
+
*
|
|
292
|
+
* - Contract is initialized.
|
|
293
|
+
*
|
|
294
|
+
* @param {Bytes<32>} newOwnerId - The unique identifier of the new owner
|
|
295
|
+
* calculated by `SHA256(pk, nonce)`.
|
|
296
|
+
* @returns {[]} Empty tuple.
|
|
297
|
+
*/
|
|
298
|
+
export circuit _transferOwnership(newOwnerId: Bytes<32>): [] {
|
|
299
|
+
Initializable_assertInitialized();
|
|
300
|
+
|
|
301
|
+
_counter.increment(1);
|
|
302
|
+
_ownerCommitment = disclose(_computeOwnerCommitment(newOwnerId, _counter));
|
|
303
|
+
}
|
|
304
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openzeppelin/compact-contracts",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenZeppelin Compact contract library",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"openzeppelin",
|
|
7
|
+
"compact",
|
|
8
|
+
"midnight",
|
|
9
|
+
"contracts",
|
|
10
|
+
"security"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/OpenZeppelin/compact-contracts.git"
|
|
15
|
+
},
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"author": "OpenZeppelin Community <maintainers@openzeppelin.org>",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/OpenZeppelin/compact-contracts/issues"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://docs.openzeppelin.com/contracts-compact/",
|
|
22
|
+
"type": "module",
|
|
23
|
+
"imports": {
|
|
24
|
+
"#test-utils/address.js": "./test-utils/address.js"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"compact": "compact-compiler --exclude '*/archive/*'",
|
|
28
|
+
"compact:access": "compact-compiler --dir access",
|
|
29
|
+
"compact:archive": "compact-compiler --dir archive",
|
|
30
|
+
"compact:security": "compact-compiler --dir security",
|
|
31
|
+
"compact:token": "compact-compiler --dir token",
|
|
32
|
+
"compact:utils": "compact-compiler --dir utils",
|
|
33
|
+
"build": "compact-builder --hierarchical --out dist --clean-dist --exclude '*/archive/*' --exclude 'Mock*' --exclude '*.mock.compact' --copy package.json --copy ../README.md && find dist -type d -empty -delete",
|
|
34
|
+
"test": "SKIP_ZK=true yarn run compact && vitest run",
|
|
35
|
+
"test:coverage": "SKIP_ZK=true yarn run compact && vitest run --coverage",
|
|
36
|
+
"types": "tsc -p tsconfig.json --noEmit",
|
|
37
|
+
"clean": "git clean -fXd"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@openzeppelin/compact-cli": "^0.0.2"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@openzeppelin/compact-simulator": "^0.0.1",
|
|
47
|
+
"@tsconfig/node24": "^24.0.4",
|
|
48
|
+
"@types/node": "25.7.0",
|
|
49
|
+
"@vitest/coverage-v8": "^4.1.7",
|
|
50
|
+
"ts-node": "^10.9.2",
|
|
51
|
+
"typescript": "^5.9.3",
|
|
52
|
+
"vitest": "^4.1.7"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.1.0 (security/Initializable.compact)
|
|
3
|
+
|
|
4
|
+
pragma language_version >= 0.21.0;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module Initializable
|
|
8
|
+
* @description Initializable provides a simple mechanism that mimics the functionality of a constructor.
|
|
9
|
+
*/
|
|
10
|
+
module Initializable {
|
|
11
|
+
import CompactStandardLibrary;
|
|
12
|
+
|
|
13
|
+
export ledger _isInitialized: Boolean;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @description Initializes the state thus ensuring the calling circuit can only be called once.
|
|
17
|
+
*
|
|
18
|
+
* @circuitInfo k=10, rows=38
|
|
19
|
+
*
|
|
20
|
+
* Requirements:
|
|
21
|
+
*
|
|
22
|
+
* - Contract must not be initialized.
|
|
23
|
+
*
|
|
24
|
+
* @return {[]} - Empty tuple.
|
|
25
|
+
*/
|
|
26
|
+
export circuit initialize(): [] {
|
|
27
|
+
assertNotInitialized();
|
|
28
|
+
_isInitialized = true;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @description Asserts that the contract has been initialized, throwing an error if not.
|
|
33
|
+
*
|
|
34
|
+
* @circuitInfo k=10, rows=31
|
|
35
|
+
*
|
|
36
|
+
* Requirements:
|
|
37
|
+
*
|
|
38
|
+
* - Contract must be initialized.
|
|
39
|
+
*
|
|
40
|
+
* @return {[]} - Empty tuple.
|
|
41
|
+
*/
|
|
42
|
+
export circuit assertInitialized(): [] {
|
|
43
|
+
assert(_isInitialized, "Initializable: contract not initialized");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @description Asserts that the contract has not been initialized, throwing an error if it has.
|
|
48
|
+
*
|
|
49
|
+
* @circuitInfo k=10, rows=35
|
|
50
|
+
*
|
|
51
|
+
* Requirements:
|
|
52
|
+
*
|
|
53
|
+
* - Contract must not be initialized.
|
|
54
|
+
*
|
|
55
|
+
* @return {[]} - Empty tuple.
|
|
56
|
+
*/
|
|
57
|
+
export circuit assertNotInitialized(): [] {
|
|
58
|
+
assert(!_isInitialized, "Initializable: contract already initialized");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// OpenZeppelin Compact Contracts v0.1.0 (security/Pausable.compact)
|
|
3
|
+
|
|
4
|
+
pragma language_version >= 0.21.0;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module Pausable
|
|
8
|
+
* @description Pausable allows the implementing contract to implement
|
|
9
|
+
* an emergency stop mechanism. Only circuits that call `assertPaused`
|
|
10
|
+
* or `assertNotPaused` will be affected by this mechanism.
|
|
11
|
+
*/
|
|
12
|
+
module Pausable {
|
|
13
|
+
import CompactStandardLibrary;
|
|
14
|
+
|
|
15
|
+
export ledger _isPaused: Boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @description Returns true if the contract is paused, and false otherwise.
|
|
19
|
+
*
|
|
20
|
+
* @circuitInfo k=10, rows=32
|
|
21
|
+
*
|
|
22
|
+
* @return {Boolean} True if paused.
|
|
23
|
+
*/
|
|
24
|
+
export circuit isPaused(): Boolean {
|
|
25
|
+
return _isPaused;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @description Makes a circuit only callable when the contract is paused.
|
|
30
|
+
*
|
|
31
|
+
* @circuitInfo k=10, rows=31
|
|
32
|
+
*
|
|
33
|
+
* Requirements:
|
|
34
|
+
*
|
|
35
|
+
* - Contract must be paused.
|
|
36
|
+
*
|
|
37
|
+
* @return {[]} - Empty tuple.
|
|
38
|
+
*/
|
|
39
|
+
export circuit assertPaused(): [] {
|
|
40
|
+
assert(_isPaused, "Pausable: not paused");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @description Makes a circuit only callable when the contract is not paused.
|
|
45
|
+
*
|
|
46
|
+
* @circuitInfo k=10, rows=35
|
|
47
|
+
*
|
|
48
|
+
* Requirements:
|
|
49
|
+
*
|
|
50
|
+
* - Contract must not be paused.
|
|
51
|
+
*
|
|
52
|
+
* @return {[]} - Empty tuple.
|
|
53
|
+
*/
|
|
54
|
+
export circuit assertNotPaused(): [] {
|
|
55
|
+
assert(!_isPaused, "Pausable: paused");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @description Triggers a stopped state.
|
|
60
|
+
*
|
|
61
|
+
* @circuitInfo k=10, rows=38
|
|
62
|
+
*
|
|
63
|
+
* Requirements:
|
|
64
|
+
*
|
|
65
|
+
* - Contract must not be paused.
|
|
66
|
+
*
|
|
67
|
+
* @return {[]} - Empty tuple.
|
|
68
|
+
*/
|
|
69
|
+
export circuit _pause(): [] {
|
|
70
|
+
assertNotPaused();
|
|
71
|
+
_isPaused = true;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @description Lifts the pause on the contract.
|
|
76
|
+
*
|
|
77
|
+
* @circuitInfo k=10, rows=34
|
|
78
|
+
*
|
|
79
|
+
* Requirements:
|
|
80
|
+
*
|
|
81
|
+
* - Contract must be paused.
|
|
82
|
+
*
|
|
83
|
+
* @return {[]} - Empty tuple.
|
|
84
|
+
*/
|
|
85
|
+
export circuit _unpause(): [] {
|
|
86
|
+
assertPaused();
|
|
87
|
+
_isPaused = false;
|
|
88
|
+
}
|
|
89
|
+
}
|