@openzeppelin/compact-contracts 0.1.0 → 0.2.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 CHANGED
@@ -199,7 +199,6 @@ make sure to check out the [contribution guide](CONTRIBUTING.md) in advance.
199
199
  >
200
200
  > - [Node.js](https://nodejs.org/)
201
201
  > - [Yarn](https://yarnpkg.com/getting-started/install)
202
- > - [Turbo](https://turborepo.com/docs/getting-started/installation)
203
202
  > - [Compact](https://docs.midnight.network/blog/compact-developer-tools)
204
203
 
205
204
  ### Set up the project
@@ -215,20 +214,20 @@ git clone git@github.com:OpenZeppelin/compact-contracts.git
215
214
  ```bash
216
215
  nvm install && \
217
216
  yarn && \
218
- turbo compact
217
+ yarn compact
219
218
  ```
220
219
 
221
220
  ### Run tests
222
221
 
223
222
  ```bash
224
- turbo test
223
+ yarn test
225
224
  ```
226
225
 
227
226
  ### Check/apply Biome formatter
228
227
 
229
228
  ```bash
230
- turbo fmt-and-lint
231
- turbo fmt-and-lint:fix
229
+ yarn fmt-and-lint
230
+ yarn fmt-and-lint:fix
232
231
  ```
233
232
 
234
233
  ### Advanced
@@ -236,8 +235,8 @@ turbo fmt-and-lint:fix
236
235
  #### Targeted compilation
237
236
 
238
237
  ```bash
239
- turbo compact:access
240
- turbo compact:archive
238
+ yarn compact:access
239
+ yarn compact:archive
241
240
  ...
242
241
  ```
243
242
 
@@ -246,11 +245,11 @@ turbo compact:archive
246
245
  ZK key generation is slow and usually unnecessary during development.
247
246
 
248
247
  ```bash
249
- # Individual module compilation (recommended for development)
250
- turbo compact:token --filter=@openzeppelin/compact-contracts -- --skip-zk
251
-
252
248
  # Full compilation with skip-zk (use environment variable)
253
- SKIP_ZK=true turbo compact
249
+ SKIP_ZK=true yarn compact
250
+
251
+ # Access compilation with skip-zk (this compiles security first as a dependency)
252
+ SKIP_ZK=true yarn compact:access
254
253
  ```
255
254
 
256
255
  #### Clean environment
@@ -258,13 +257,13 @@ SKIP_ZK=true turbo compact
258
257
  ```bash
259
258
  # WARNING!
260
259
  # These are destructive commands
261
- turbo clean
260
+ yarn clean
262
261
  rm -rf .turbo/
263
262
  ```
264
263
 
265
264
  ### Troubleshooting
266
265
 
267
- - **Issues with turbo's cache?** Try cleaning: `turbo clean && rm -rf .turbo/`
266
+ - **Issues with turbo's cache?** Try cleaning: `yarn clean && rm -rf .turbo/`
268
267
  - **Node version issues?** Use `nvm use` to switch to the correct version
269
268
 
270
269
  ## Security
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (access/AccessControl.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (access/AccessControl.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (access/Ownable.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (access/Ownable.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -85,9 +85,15 @@ pragma language_version >= 0.21.0;
85
85
  */
86
86
  module Ownable {
87
87
  import CompactStandardLibrary;
88
- import "../security/Initializable" prefix Initializable_;
89
88
  import "../utils/Utils" prefix Utils_;
90
89
 
90
+ /**
91
+ * @description Initialization flag, tracked per-module to avoid the compiler's
92
+ * shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the
93
+ * Initializable module for rationale.
94
+ */
95
+ export ledger _isInitialized: Boolean;
96
+
91
97
  export ledger _owner: Either<Bytes<32>, ContractAddress>;
92
98
 
93
99
  /**
@@ -117,11 +123,38 @@ module Ownable {
117
123
  * @returns {[]} Empty tuple.
118
124
  */
119
125
  export circuit initialize(initialOwner: Either<Bytes<32>, ContractAddress>): [] {
120
- Initializable_initialize();
126
+ assertNotInitialized();
127
+ _isInitialized = true;
121
128
  assert(!_isTargetZero(initialOwner), "Ownable: invalid initial owner");
122
129
  _transferOwnership(initialOwner);
123
130
  }
124
131
 
132
+ /**
133
+ * @description Asserts that the contract has been initialized, throwing an error if not.
134
+ *
135
+ * Requirements:
136
+ *
137
+ * - Contract must be initialized.
138
+ *
139
+ * @return {[]} - Empty tuple.
140
+ */
141
+ circuit assertInitialized(): [] {
142
+ assert(_isInitialized, "Ownable: contract not initialized");
143
+ }
144
+
145
+ /**
146
+ * @description Asserts that the contract has not been initialized, throwing an error if it has.
147
+ *
148
+ * Requirements:
149
+ *
150
+ * - Contract must not be initialized.
151
+ *
152
+ * @return {[]} - Empty tuple.
153
+ */
154
+ circuit assertNotInitialized(): [] {
155
+ assert(!_isInitialized, "Ownable: contract already initialized");
156
+ }
157
+
125
158
  /**
126
159
  * @description Returns the current contract owner.
127
160
  *
@@ -134,7 +167,7 @@ module Ownable {
134
167
  * @returns {Either<Bytes<32>, ContractAddress>} - The contract owner.
135
168
  */
136
169
  export circuit owner(): Either<Bytes<32>, ContractAddress> {
137
- Initializable_assertInitialized();
170
+ assertInitialized();
138
171
  return _owner;
139
172
  }
140
173
 
@@ -158,7 +191,7 @@ module Ownable {
158
191
  * @returns {[]} Empty tuple.
159
192
  */
160
193
  export circuit transferOwnership(newOwner: Either<Bytes<32>, ContractAddress>): [] {
161
- Initializable_assertInitialized();
194
+ assertInitialized();
162
195
  const isContractAddr = !newOwner.is_left;
163
196
  assert(!isContractAddr, "Ownable: unsafe ownership transfer");
164
197
  _unsafeTransferOwnership(newOwner);
@@ -184,7 +217,7 @@ module Ownable {
184
217
  * @returns {[]} Empty tuple.
185
218
  */
186
219
  export circuit _unsafeTransferOwnership(newOwner: Either<Bytes<32>, ContractAddress>): [] {
187
- Initializable_assertInitialized();
220
+ assertInitialized();
188
221
  assertOnlyOwner();
189
222
  assert(!_isTargetZero(newOwner), "Ownable: invalid new owner");
190
223
  _unsafeUncheckedTransferOwnership(newOwner);
@@ -205,7 +238,7 @@ module Ownable {
205
238
  * @returns {[]} Empty tuple.
206
239
  */
207
240
  export circuit renounceOwnership(): [] {
208
- Initializable_assertInitialized();
241
+ assertInitialized();
209
242
  assertOnlyOwner();
210
243
 
211
244
  // We use `left` here because `assertOnlyOwner` would return a misleading
@@ -233,7 +266,7 @@ module Ownable {
233
266
  * @returns {[]} Empty tuple.
234
267
  */
235
268
  export circuit assertOnlyOwner(): [] {
236
- Initializable_assertInitialized();
269
+ assertInitialized();
237
270
  if (_owner.is_left) {
238
271
  assert(_computeAccountId() == _owner.left, "Ownable: caller is not the owner");
239
272
  } else {
@@ -260,7 +293,7 @@ module Ownable {
260
293
  * @returns {[]} Empty tuple.
261
294
  */
262
295
  export circuit _transferOwnership(newOwner: Either<Bytes<32>, ContractAddress>): [] {
263
- Initializable_assertInitialized();
296
+ assertInitialized();
264
297
  const isContractAddr = !newOwner.is_left;
265
298
  assert(!isContractAddr, "Ownable: unsafe ownership transfer");
266
299
  _unsafeUncheckedTransferOwnership(newOwner);
@@ -286,7 +319,7 @@ module Ownable {
286
319
  export circuit _unsafeUncheckedTransferOwnership(
287
320
  newOwner: Either<Bytes<32>, ContractAddress>
288
321
  ): [] {
289
- Initializable_assertInitialized();
322
+ assertInitialized();
290
323
  const canonAcct = Utils_canonicalize<Bytes<32>, ContractAddress>(newOwner);
291
324
  _owner = disclose(canonAcct);
292
325
  }
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (access/ShieldedAccessControl.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (access/ShieldedAccessControl.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -168,7 +168,6 @@ pragma language_version >= 0.21.0;
168
168
  module ShieldedAccessControl {
169
169
  import CompactStandardLibrary;
170
170
  import "../utils/Utils" prefix Utils_;
171
- import "../security/Initializable" prefix Initializable_;
172
171
 
173
172
  export enum UpdateType {
174
173
  Grant,
@@ -181,6 +180,13 @@ module ShieldedAccessControl {
181
180
  export new type AccountIdentifier = Bytes<32>;
182
181
  export new type RoleNullifier = Bytes<32>;
183
182
 
183
+ /**
184
+ * @description Initialization flag, tracked per-module to avoid the compiler's
185
+ * shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the
186
+ * Initializable module for rationale.
187
+ */
188
+ export ledger _isInitialized: Boolean;
189
+
184
190
  /**
185
191
  * @ledger _operatorRoles
186
192
  * @description A Merkle tree of role commitments stored as SHA256(role | accountId | instanceSalt | commitmentDomain)
@@ -259,11 +265,38 @@ module ShieldedAccessControl {
259
265
  */
260
266
  export circuit initialize(instanceSalt: Bytes<32>): [] {
261
267
  assert(instanceSalt != default<Bytes<32>>, "ShieldedAccessControl: Instance salt must not be 0");
262
- Initializable_initialize();
268
+ assertNotInitialized();
269
+ _isInitialized = true;
263
270
 
264
271
  _instanceSalt = disclose(instanceSalt);
265
272
  }
266
273
 
274
+ /**
275
+ * @description Asserts that the contract has been initialized, throwing an error if not.
276
+ *
277
+ * Requirements:
278
+ *
279
+ * - Contract must be initialized.
280
+ *
281
+ * @return {[]} - Empty tuple.
282
+ */
283
+ circuit assertInitialized(): [] {
284
+ assert(_isInitialized, "ShieldedAccessControl: contract not initialized");
285
+ }
286
+
287
+ /**
288
+ * @description Asserts that the contract has not been initialized, throwing an error if it has.
289
+ *
290
+ * Requirements:
291
+ *
292
+ * - Contract must not be initialized.
293
+ *
294
+ * @return {[]} - Empty tuple.
295
+ */
296
+ circuit assertNotInitialized(): [] {
297
+ assert(!_isInitialized, "ShieldedAccessControl: contract already initialized");
298
+ }
299
+
267
300
  /**
268
301
  * @description The default admin role for all roles. Only accounts with this role will be able to grant or revoke other roles
269
302
  * unless custom admin roles are created.
@@ -295,7 +328,7 @@ module ShieldedAccessControl {
295
328
  * @return {[]} - Empty tuple.
296
329
  */
297
330
  export circuit assertOnlyRole(role: RoleIdentifier): [] {
298
- Initializable_assertInitialized();
331
+ assertInitialized();
299
332
  assert(_uncheckedCanProveRole(role), "ShieldedAccessControl: unauthorized account");
300
333
  }
301
334
 
@@ -320,7 +353,7 @@ module ShieldedAccessControl {
320
353
  * @return {Boolean} - A boolean determining if a caller successfully proved ownership of `role`
321
354
  */
322
355
  export circuit canProveRole(role: RoleIdentifier): Boolean {
323
- Initializable_assertInitialized();
356
+ assertInitialized();
324
357
  return _uncheckedCanProveRole(role);
325
358
  }
326
359
 
@@ -417,7 +450,7 @@ module ShieldedAccessControl {
417
450
  * @return {[]} - Empty tuple.
418
451
  */
419
452
  export circuit _grantRole(role: RoleIdentifier, accountId: AccountIdentifier): [] {
420
- Initializable_assertInitialized();
453
+ assertInitialized();
421
454
  _updateRole(role, accountId, UpdateType.Grant);
422
455
  }
423
456
 
@@ -449,7 +482,7 @@ module ShieldedAccessControl {
449
482
  * @return {[]} - Empty tuple.
450
483
  */
451
484
  export circuit renounceRole(role: RoleIdentifier, accountIdConfirmation: AccountIdentifier): [] {
452
- Initializable_assertInitialized();
485
+ assertInitialized();
453
486
 
454
487
  assert(accountIdConfirmation == _computeAccountId(),
455
488
  "ShieldedAccessControl: bad confirmation"
@@ -515,7 +548,7 @@ module ShieldedAccessControl {
515
548
  * @return {[]} - Empty tuple.
516
549
  */
517
550
  export circuit _revokeRole(role: RoleIdentifier, accountId: AccountIdentifier): [] {
518
- Initializable_assertInitialized();
551
+ assertInitialized();
519
552
  _updateRole(role, accountId, UpdateType.Revoke);
520
553
  }
521
554
 
@@ -599,7 +632,7 @@ module ShieldedAccessControl {
599
632
  * @return {[]} - Empty tuple.
600
633
  */
601
634
  export circuit _setRoleAdmin(role: RoleIdentifier, adminId: RoleIdentifier): [] {
602
- Initializable_assertInitialized();
635
+ assertInitialized();
603
636
  _adminRoles.insert(disclose(role), disclose(adminId));
604
637
  }
605
638
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (access/ZOwnablePK.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (access/ZOwnablePK.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -45,7 +45,13 @@ pragma language_version >= 0.21.0;
45
45
  */
46
46
  module ZOwnablePK {
47
47
  import CompactStandardLibrary;
48
- import "../security/Initializable" prefix Initializable_;
48
+
49
+ /**
50
+ * @description Initialization flag, tracked per-module to avoid the compiler's
51
+ * shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the
52
+ * Initializable module for rationale.
53
+ */
54
+ export ledger _isInitialized: Boolean;
49
55
 
50
56
  /**
51
57
  * @ledger _ownerCommitment
@@ -56,6 +62,7 @@ module ZOwnablePK {
56
62
  * A commitment of `default<Bytes<32>>` (i.e., zero) indicates the contract is unowned.
57
63
  */
58
64
  export ledger _ownerCommitment: Bytes<32>;
65
+
59
66
  /**
60
67
  * @ledger _counter
61
68
  * @description Internal transfer counter used to prevent commitment reuse.
@@ -64,6 +71,7 @@ module ZOwnablePK {
64
71
  * `instanceSalt` to compute unique owner commitments over time.
65
72
  */
66
73
  export ledger _counter: Counter;
74
+
67
75
  /**
68
76
  * @sealed @ledger _instanceSalt
69
77
  * @description A per-instance value provided at initialization used to namespace
@@ -104,13 +112,40 @@ module ZOwnablePK {
104
112
  * @returns {[]} Empty tuple.
105
113
  */
106
114
  export circuit initialize(ownerId: Bytes<32>, instanceSalt: Bytes<32>): [] {
107
- Initializable_initialize();
115
+ assertNotInitialized();
116
+ _isInitialized = true;
108
117
 
109
118
  assert(ownerId != default<Bytes<32>>, "ZOwnablePK: invalid id");
110
119
  _instanceSalt = disclose(instanceSalt);
111
120
  _transferOwnership(ownerId);
112
121
  }
113
122
 
123
+ /**
124
+ * @description Asserts that the contract has been initialized, throwing an error if not.
125
+ *
126
+ * Requirements:
127
+ *
128
+ * - Contract must be initialized.
129
+ *
130
+ * @return {[]} - Empty tuple.
131
+ */
132
+ circuit assertInitialized(): [] {
133
+ assert(_isInitialized, "ZOwnablePK: contract not initialized");
134
+ }
135
+
136
+ /**
137
+ * @description Asserts that the contract has not been initialized, throwing an error if it has.
138
+ *
139
+ * Requirements:
140
+ *
141
+ * - Contract must not be initialized.
142
+ *
143
+ * @return {[]} - Empty tuple.
144
+ */
145
+ circuit assertNotInitialized(): [] {
146
+ assert(!_isInitialized, "ZOwnablePK: contract already initialized");
147
+ }
148
+
114
149
  /**
115
150
  * @description Returns the current commitment representing the contract owner.
116
151
  * The full commitment is: `SHA256(SHA256(pk, nonce), instanceSalt, counter, domain)`.
@@ -124,7 +159,7 @@ module ZOwnablePK {
124
159
  * @returns {Bytes<32>} The current owner's commitment.
125
160
  */
126
161
  export circuit owner(): Bytes<32> {
127
- Initializable_assertInitialized();
162
+ assertInitialized();
128
163
  return _ownerCommitment;
129
164
  }
130
165
 
@@ -144,7 +179,7 @@ module ZOwnablePK {
144
179
  * @returns {[]} Empty tuple.
145
180
  */
146
181
  export circuit transferOwnership(newOwnerId: Bytes<32>): [] {
147
- Initializable_assertInitialized();
182
+ assertInitialized();
148
183
 
149
184
  assertOnlyOwner();
150
185
  assert(newOwnerId != default<Bytes<32>>, "ZOwnablePK: invalid id");
@@ -166,7 +201,7 @@ module ZOwnablePK {
166
201
  * @returns {[]} Empty tuple.
167
202
  */
168
203
  export circuit renounceOwnership(): [] {
169
- Initializable_assertInitialized();
204
+ assertInitialized();
170
205
 
171
206
  assertOnlyOwner();
172
207
  _ownerCommitment.resetToDefault();
@@ -188,7 +223,7 @@ module ZOwnablePK {
188
223
  * @returns {[]} Empty tuple.
189
224
  */
190
225
  export circuit assertOnlyOwner(): [] {
191
- Initializable_assertInitialized();
226
+ assertInitialized();
192
227
 
193
228
  const nonce = wit_secretNonce();
194
229
  const callerAsEither =
@@ -234,7 +269,7 @@ module ZOwnablePK {
234
269
  * @returns {Bytes<32>} The commitment derived from `id` and `counter`.
235
270
  */
236
271
  export circuit _computeOwnerCommitment(id: Bytes<32>, counter: Uint<64>,): Bytes<32> {
237
- Initializable_assertInitialized();
272
+ assertInitialized();
238
273
  return persistentHash<Vector<4, Bytes<32>>>(
239
274
  [id, _instanceSalt, counter as Field as Bytes<32>, pad(32, "ZOwnablePK:shield:")]
240
275
  );
@@ -296,7 +331,7 @@ module ZOwnablePK {
296
331
  * @returns {[]} Empty tuple.
297
332
  */
298
333
  export circuit _transferOwnership(newOwnerId: Bytes<32>): [] {
299
- Initializable_assertInitialized();
334
+ assertInitialized();
300
335
 
301
336
  _counter.increment(1);
302
337
  _ownerCommitment = disclose(_computeOwnerCommitment(newOwnerId, _counter));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/compact-contracts",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "OpenZeppelin Compact contract library",
5
5
  "keywords": [
6
6
  "openzeppelin",
@@ -33,6 +33,8 @@
33
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
34
  "test": "SKIP_ZK=true yarn run compact && vitest run",
35
35
  "test:coverage": "SKIP_ZK=true yarn run compact && vitest run --coverage",
36
+ "compact:integration": "SKIP_ZK=true compact compile test/integration/_mocks/SharedInitCollision.compact artifacts/SharedInitCollision && SKIP_ZK=true compact compile test/integration/_mocks/ComposedTokens.compact artifacts/ComposedTokens",
37
+ "test:integration": "yarn run compact:integration && vitest run --config vitest.integration.config.ts",
36
38
  "types": "tsc -p tsconfig.json --noEmit",
37
39
  "clean": "git clean -fXd"
38
40
  },
@@ -45,10 +47,10 @@
45
47
  "devDependencies": {
46
48
  "@openzeppelin/compact-simulator": "^0.0.1",
47
49
  "@tsconfig/node24": "^24.0.4",
48
- "@types/node": "25.7.0",
49
- "@vitest/coverage-v8": "^4.1.7",
50
+ "@types/node": "25.9.1",
51
+ "@vitest/coverage-v8": "^4.1.8",
50
52
  "ts-node": "^10.9.2",
51
- "typescript": "^5.9.3",
52
- "vitest": "^4.1.7"
53
+ "typescript": "^6.0.3",
54
+ "vitest": "^4.1.8"
53
55
  }
54
56
  }
@@ -1,11 +1,27 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (security/Initializable.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (security/Initializable.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
6
6
  /**
7
7
  * @module Initializable
8
8
  * @description Initializable provides a simple mechanism that mimics the functionality of a constructor.
9
+ *
10
+ * @notice ⚠️ TECHNICAL WARNING: only use this module at the top contract layer, and
11
+ * import it into at most one module per contract.
12
+ *
13
+ * The Compact compiler deduplicates a shared transitive dependency's ledger state
14
+ * inconsistently depending on directory layout
15
+ * (https://github.com/LFDT-Minokawa/compact/issues/270, reproduced on compiler
16
+ * 0.29.0–0.31.0). When two modules in the SAME directory both import this module,
17
+ * their `_isInitialized` flags collapse into a SINGLE shared ledger slot: calling
18
+ * `initialize()` on one marks the other as initialized, and the other can never be
19
+ * initialized independently. Modules in different directories get separate slots.
20
+ * The result is unpredictable and a security hazard for composed contracts.
21
+ *
22
+ * For this reason the OpenZeppelin modules no longer use this module: each tracks
23
+ * its own `_isInitialized` ledger flag inline. This module is kept for direct,
24
+ * single-import use and can be reintroduced across modules once #270 is resolved.
9
25
  */
10
26
  module Initializable {
11
27
  import CompactStandardLibrary;
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (security/Pausable.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (security/Pausable.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (token/FungibleToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (token/FungibleToken.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -64,9 +64,15 @@ pragma language_version >= 0.21.0;
64
64
  */
65
65
  module FungibleToken {
66
66
  import CompactStandardLibrary;
67
- import "../security/Initializable" prefix Initializable_;
68
67
  import "../utils/Utils" prefix Utils_;
69
68
 
69
+ /**
70
+ * @description Initialization flag, tracked per-module to avoid the compiler's
71
+ * shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the
72
+ * Initializable module for rationale.
73
+ */
74
+ export ledger _isInitialized: Boolean;
75
+
70
76
  /**
71
77
  * @description Mapping from account addresses to their token balances.
72
78
  * @type {Either<Bytes<32>, ContractAddress>} account - The account address.
@@ -75,6 +81,7 @@ module FungibleToken {
75
81
  * @type {Map<Either<Bytes<32>, ContractAddress>, Uint<128>>} _balances
76
82
  */
77
83
  export ledger _balances: Map<Either<Bytes<32>, ContractAddress>, Uint<128>>;
84
+
78
85
  /**
79
86
  * @description Mapping from owner accounts to spender accounts and their allowances.
80
87
  * @type {Either<Bytes<32>, ContractAddress>} account - The owner account address.
@@ -134,12 +141,39 @@ module FungibleToken {
134
141
  symbol_: Opaque<"string">,
135
142
  decimals_: Uint<8>
136
143
  ): [] {
137
- Initializable_initialize();
144
+ assertNotInitialized();
145
+ _isInitialized = true;
138
146
  _name = disclose(name_);
139
147
  _symbol = disclose(symbol_);
140
148
  _decimals = disclose(decimals_);
141
149
  }
142
150
 
151
+ /**
152
+ * @description Asserts that the contract has been initialized, throwing an error if not.
153
+ *
154
+ * Requirements:
155
+ *
156
+ * - Contract must be initialized.
157
+ *
158
+ * @return {[]} - Empty tuple.
159
+ */
160
+ circuit assertInitialized(): [] {
161
+ assert(_isInitialized, "FungibleToken: contract not initialized");
162
+ }
163
+
164
+ /**
165
+ * @description Asserts that the contract has not been initialized, throwing an error if it has.
166
+ *
167
+ * Requirements:
168
+ *
169
+ * - Contract must not be initialized.
170
+ *
171
+ * @return {[]} - Empty tuple.
172
+ */
173
+ circuit assertNotInitialized(): [] {
174
+ assert(!_isInitialized, "FungibleToken: contract already initialized");
175
+ }
176
+
143
177
  /**
144
178
  * @description Returns the token name.
145
179
  *
@@ -152,7 +186,7 @@ module FungibleToken {
152
186
  * @return {Opaque<"string">} - The token name.
153
187
  */
154
188
  export circuit name(): Opaque<"string"> {
155
- Initializable_assertInitialized();
189
+ assertInitialized();
156
190
  return _name;
157
191
  }
158
192
 
@@ -168,7 +202,7 @@ module FungibleToken {
168
202
  * @return {Opaque<"string">} - The token name.
169
203
  */
170
204
  export circuit symbol(): Opaque<"string"> {
171
- Initializable_assertInitialized();
205
+ assertInitialized();
172
206
  return _symbol;
173
207
  }
174
208
 
@@ -184,7 +218,7 @@ module FungibleToken {
184
218
  * @return {Uint<8>} - The account's token balance.
185
219
  */
186
220
  export circuit decimals(): Uint<8> {
187
- Initializable_assertInitialized();
221
+ assertInitialized();
188
222
  return _decimals;
189
223
  }
190
224
 
@@ -200,7 +234,7 @@ module FungibleToken {
200
234
  * @return {Uint<128>} - The total supply of tokens.
201
235
  */
202
236
  export circuit totalSupply(): Uint<128> {
203
- Initializable_assertInitialized();
237
+ assertInitialized();
204
238
  return _totalSupply;
205
239
  }
206
240
 
@@ -219,7 +253,7 @@ module FungibleToken {
219
253
  * @return {Uint<128>} - The account's token balance.
220
254
  */
221
255
  export circuit balanceOf(account: Either<Bytes<32>, ContractAddress>): Uint<128> {
222
- Initializable_assertInitialized();
256
+ assertInitialized();
223
257
  const canonAcct = Utils_canonicalize<Bytes<32>, ContractAddress>(account);
224
258
 
225
259
  if (!_balances.member(disclose(canonAcct))) {
@@ -253,7 +287,7 @@ module FungibleToken {
253
287
  to: Either<Bytes<32>, ContractAddress>,
254
288
  value: Uint<128>
255
289
  ): Boolean {
256
- Initializable_assertInitialized();
290
+ assertInitialized();
257
291
  const isContractAddr = !to.is_left;
258
292
  assert(!isContractAddr, "FungibleToken: unsafe transfer");
259
293
 
@@ -283,7 +317,7 @@ module FungibleToken {
283
317
  to: Either<Bytes<32>, ContractAddress>,
284
318
  value: Uint<128>
285
319
  ): Boolean {
286
- Initializable_assertInitialized();
320
+ assertInitialized();
287
321
  const owner = left<Bytes<32>, ContractAddress>(_computeAccountId());
288
322
  _unsafeUncheckedTransfer(owner, to, value);
289
323
  return true;
@@ -309,7 +343,7 @@ module FungibleToken {
309
343
  owner: Either<Bytes<32>, ContractAddress>,
310
344
  spender: Either<Bytes<32>, ContractAddress>
311
345
  ): Uint<128> {
312
- Initializable_assertInitialized();
346
+ assertInitialized();
313
347
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
314
348
  const canonSpender = Utils_canonicalize<Bytes<32>, ContractAddress>(spender);
315
349
 
@@ -337,7 +371,7 @@ module FungibleToken {
337
371
  export circuit approve(spender: Either<Bytes<32>, ContractAddress>,
338
372
  value: Uint<128>
339
373
  ): Boolean {
340
- Initializable_assertInitialized();
374
+ assertInitialized();
341
375
 
342
376
  const owner = left<Bytes<32>, ContractAddress>(_computeAccountId());
343
377
  _approve(owner, spender, value);
@@ -373,7 +407,7 @@ module FungibleToken {
373
407
  to: Either<Bytes<32>, ContractAddress>,
374
408
  value: Uint<128>
375
409
  ): Boolean {
376
- Initializable_assertInitialized();
410
+ assertInitialized();
377
411
  const isContractAddr = !to.is_left;
378
412
  assert(!isContractAddr, "FungibleToken: unsafe transfer");
379
413
  return _unsafeTransferFrom(fromAddress, to, value);
@@ -406,7 +440,7 @@ module FungibleToken {
406
440
  to: Either<Bytes<32>, ContractAddress>,
407
441
  value: Uint<128>
408
442
  ): Boolean {
409
- Initializable_assertInitialized();
443
+ assertInitialized();
410
444
 
411
445
  const spender = left<Bytes<32>, ContractAddress>(_computeAccountId());
412
446
  _spendAllowance(fromAddress, spender, value);
@@ -443,7 +477,7 @@ module FungibleToken {
443
477
  to: Either<Bytes<32>, ContractAddress>,
444
478
  value: Uint<128>
445
479
  ): [] {
446
- Initializable_assertInitialized();
480
+ assertInitialized();
447
481
  const isContractAddr = !to.is_left;
448
482
  assert(!isContractAddr, "FungibleToken: unsafe transfer");
449
483
  _unsafeUncheckedTransfer(fromAddress, to, value);
@@ -474,7 +508,7 @@ module FungibleToken {
474
508
  to: Either<Bytes<32>, ContractAddress>,
475
509
  value: Uint<128>
476
510
  ): [] {
477
- Initializable_assertInitialized();
511
+ assertInitialized();
478
512
  assert(!_isTargetZero(fromAddress), "FungibleToken: invalid sender");
479
513
  assert(!_isTargetZero(to), "FungibleToken: invalid receiver");
480
514
 
@@ -501,7 +535,7 @@ module FungibleToken {
501
535
  to: Either<Bytes<32>, ContractAddress>,
502
536
  value: Uint<128>
503
537
  ): [] {
504
- Initializable_assertInitialized();
538
+ assertInitialized();
505
539
  const canonFrom = Utils_canonicalize<Bytes<32>, ContractAddress>(fromAddress);
506
540
  const canonTo = Utils_canonicalize<Bytes<32>, ContractAddress>(to);
507
541
 
@@ -547,7 +581,7 @@ module FungibleToken {
547
581
  * @return {[]} - Empty tuple.
548
582
  */
549
583
  export circuit _mint(account: Either<Bytes<32>, ContractAddress>, value: Uint<128>): [] {
550
- Initializable_assertInitialized();
584
+ assertInitialized();
551
585
  const isContractAddr = !account.is_left;
552
586
  assert(!isContractAddr, "FungibleToken: unsafe transfer");
553
587
  _unsafeMint(account, value);
@@ -575,7 +609,7 @@ module FungibleToken {
575
609
  account: Either<Bytes<32>, ContractAddress>,
576
610
  value: Uint<128>
577
611
  ): [] {
578
- Initializable_assertInitialized();
612
+ assertInitialized();
579
613
  assert(!_isTargetZero(account), "FungibleToken: invalid receiver");
580
614
  _update(ZERO(), account, value);
581
615
  }
@@ -597,7 +631,7 @@ module FungibleToken {
597
631
  * @return {[]} - Empty tuple.
598
632
  */
599
633
  export circuit _burn(account: Either<Bytes<32>, ContractAddress>, value: Uint<128>): [] {
600
- Initializable_assertInitialized();
634
+ assertInitialized();
601
635
  assert(!_isTargetZero(account), "FungibleToken: invalid sender");
602
636
  _update(account, ZERO(), value);
603
637
  }
@@ -625,7 +659,7 @@ module FungibleToken {
625
659
  spender: Either<Bytes<32>, ContractAddress>,
626
660
  value: Uint<128>
627
661
  ): [] {
628
- Initializable_assertInitialized();
662
+ assertInitialized();
629
663
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
630
664
  const canonSpender = Utils_canonicalize<Bytes<32>, ContractAddress>(spender);
631
665
 
@@ -663,7 +697,7 @@ module FungibleToken {
663
697
  spender: Either<Bytes<32>, ContractAddress>,
664
698
  value: Uint<128>
665
699
  ): [] {
666
- Initializable_assertInitialized();
700
+ assertInitialized();
667
701
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
668
702
  const canonSpender = Utils_canonicalize<Bytes<32>, ContractAddress>(spender);
669
703
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (token/MultiToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (token/MultiToken.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -124,9 +124,15 @@ pragma language_version >= 0.21.0;
124
124
  */
125
125
  module MultiToken {
126
126
  import CompactStandardLibrary;
127
- import "../security/Initializable" prefix Initializable_;
128
127
  import "../utils/Utils" prefix Utils_;
129
128
 
129
+ /**
130
+ * @description Initialization flag, tracked per-module to avoid the compiler's
131
+ * shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the
132
+ * Initializable module for rationale.
133
+ */
134
+ export ledger _isInitialized: Boolean;
135
+
130
136
  /**
131
137
  * @description Mapping from token ID to account balances.
132
138
  * @type {Uint<128>} id - The token identifier.
@@ -199,10 +205,37 @@ module MultiToken {
199
205
  * @return {[]} - Empty tuple.
200
206
  */
201
207
  export circuit initialize(uri_: Opaque<"string">): [] {
202
- Initializable_initialize();
208
+ assertNotInitialized();
209
+ _isInitialized = true;
203
210
  _setURI(uri_);
204
211
  }
205
212
 
213
+ /**
214
+ * @description Asserts that the contract has been initialized, throwing an error if not.
215
+ *
216
+ * Requirements:
217
+ *
218
+ * - Contract must be initialized.
219
+ *
220
+ * @return {[]} - Empty tuple.
221
+ */
222
+ circuit assertInitialized(): [] {
223
+ assert(_isInitialized, "MultiToken: contract not initialized");
224
+ }
225
+
226
+ /**
227
+ * @description Asserts that the contract has not been initialized, throwing an error if it has.
228
+ *
229
+ * Requirements:
230
+ *
231
+ * - Contract must not be initialized.
232
+ *
233
+ * @return {[]} - Empty tuple.
234
+ */
235
+ circuit assertNotInitialized(): [] {
236
+ assert(!_isInitialized, "MultiToken: contract already initialized");
237
+ }
238
+
206
239
  /**
207
240
  * @description This implementation returns the same URI for *all* token types. It relies
208
241
  * on the token type ID substitution mechanism defined in the EIP:
@@ -220,7 +253,7 @@ module MultiToken {
220
253
  * @return {Opaque<"string">} - The base URI for all tokens.
221
254
  */
222
255
  export circuit uri(id: Uint<128>): Opaque<"string"> {
223
- Initializable_assertInitialized();
256
+ assertInitialized();
224
257
  return _uri;
225
258
  }
226
259
 
@@ -241,7 +274,7 @@ module MultiToken {
241
274
  account: Either<Bytes<32>, ContractAddress>,
242
275
  id: Uint<128>
243
276
  ): Uint<128> {
244
- Initializable_assertInitialized();
277
+ assertInitialized();
245
278
  const canonAcct = Utils_canonicalize<Bytes<32>, ContractAddress>(account);
246
279
 
247
280
  if (!_balances.member(disclose(id)) || !_balances.lookup(id).member(disclose(canonAcct))) {
@@ -273,7 +306,7 @@ module MultiToken {
273
306
  operator: Either<Bytes<32>, ContractAddress>,
274
307
  approved: Boolean
275
308
  ): [] {
276
- Initializable_assertInitialized();
309
+ assertInitialized();
277
310
  const caller = left<Bytes<32>, ContractAddress>(_computeAccountId());
278
311
  _setApprovalForAll(caller, operator, approved);
279
312
  }
@@ -295,7 +328,7 @@ module MultiToken {
295
328
  account: Either<Bytes<32>, ContractAddress>,
296
329
  operator: Either<Bytes<32>, ContractAddress>
297
330
  ): Boolean {
298
- Initializable_assertInitialized();
331
+ assertInitialized();
299
332
  const canonAcct = Utils_canonicalize<Bytes<32>, ContractAddress>(account);
300
333
  const canonOp = Utils_canonicalize<Bytes<32>, ContractAddress>(operator);
301
334
 
@@ -404,7 +437,7 @@ module MultiToken {
404
437
  id: Uint<128>,
405
438
  value: Uint<128>
406
439
  ): [] {
407
- Initializable_assertInitialized();
440
+ assertInitialized();
408
441
  const canonFrom = Utils_canonicalize<Bytes<32>, ContractAddress>(fromAddress);
409
442
  const canonTo = Utils_canonicalize<Bytes<32>, ContractAddress>(to);
410
443
 
@@ -464,7 +497,7 @@ module MultiToken {
464
497
  id: Uint<128>,
465
498
  value: Uint<128>
466
499
  ): [] {
467
- Initializable_assertInitialized();
500
+ assertInitialized();
468
501
 
469
502
  const caller = left<Bytes<32>, ContractAddress>(_computeAccountId());
470
503
  const canonFrom = Utils_canonicalize<Bytes<32>, ContractAddress>(fromAddress);
@@ -505,7 +538,7 @@ module MultiToken {
505
538
  id: Uint<128>,
506
539
  value: Uint<128>
507
540
  ): [] {
508
- Initializable_assertInitialized();
541
+ assertInitialized();
509
542
 
510
543
  assert(!_isTargetZero(fromAddress), "MultiToken: invalid sender");
511
544
  assert(!_isTargetZero(to), "MultiToken: invalid receiver");
@@ -536,7 +569,7 @@ module MultiToken {
536
569
  * @return {[]} - Empty tuple.
537
570
  */
538
571
  export circuit _setURI(newURI: Opaque<"string">): [] {
539
- Initializable_assertInitialized();
572
+ assertInitialized();
540
573
  _uri = disclose(newURI);
541
574
  }
542
575
 
@@ -593,7 +626,7 @@ module MultiToken {
593
626
  id: Uint<128>,
594
627
  value: Uint<128>
595
628
  ): [] {
596
- Initializable_assertInitialized();
629
+ assertInitialized();
597
630
  assert(!_isTargetZero(to), "MultiToken: invalid receiver");
598
631
  _update(ZERO(), to, id, value);
599
632
  }
@@ -618,7 +651,7 @@ module MultiToken {
618
651
  id: Uint<128>,
619
652
  value: Uint<128>
620
653
  ): [] {
621
- Initializable_assertInitialized();
654
+ assertInitialized();
622
655
  assert(!_isTargetZero(fromAddress), "MultiToken: invalid sender");
623
656
  _update(fromAddress, ZERO(), id, value);
624
657
  }
@@ -649,7 +682,7 @@ module MultiToken {
649
682
  operator: Either<Bytes<32>, ContractAddress>,
650
683
  approved: Boolean
651
684
  ): [] {
652
- Initializable_assertInitialized();
685
+ assertInitialized();
653
686
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
654
687
  assert(!_isTargetZero(canonOwner), "MultiToken: invalid owner");
655
688
 
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (token/NonFungibleToken.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (token/NonFungibleToken.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5
 
@@ -83,13 +83,19 @@ pragma language_version >= 0.21.0;
83
83
 
84
84
  module NonFungibleToken {
85
85
  import CompactStandardLibrary;
86
- import "../security/Initializable" prefix Initializable_;
87
86
  import "../utils/Utils" prefix Utils_;
88
87
 
89
88
  /// Public state
90
89
  export sealed ledger _name: Opaque<"string">;
91
90
  export sealed ledger _symbol: Opaque<"string">;
92
91
 
92
+ /**
93
+ * @description Initialization flag, tracked per-module to avoid the compiler's
94
+ * shared transitive-dependency state bug (LFDT-Minokawa/compact#270). See the
95
+ * Initializable module for rationale.
96
+ */
97
+ export ledger _isInitialized: Boolean;
98
+
93
99
  /**
94
100
  * @description Mapping from token IDs to their owner addresses.
95
101
  * @type {Uint<128>} tokenId - The unique identifier for a token.
@@ -177,11 +183,38 @@ module NonFungibleToken {
177
183
  * @return {[]} - Empty tuple.
178
184
  */
179
185
  export circuit initialize(name_: Opaque<"string">, symbol_: Opaque<"string">): [] {
180
- Initializable_initialize();
186
+ assertNotInitialized();
187
+ _isInitialized = true;
181
188
  _name = disclose(name_);
182
189
  _symbol = disclose(symbol_);
183
190
  }
184
191
 
192
+ /**
193
+ * @description Asserts that the contract has been initialized, throwing an error if not.
194
+ *
195
+ * Requirements:
196
+ *
197
+ * - Contract must be initialized.
198
+ *
199
+ * @return {[]} - Empty tuple.
200
+ */
201
+ circuit assertInitialized(): [] {
202
+ assert(_isInitialized, "NonFungibleToken: contract not initialized");
203
+ }
204
+
205
+ /**
206
+ * @description Asserts that the contract has not been initialized, throwing an error if it has.
207
+ *
208
+ * Requirements:
209
+ *
210
+ * - Contract must not be initialized.
211
+ *
212
+ * @return {[]} - Empty tuple.
213
+ */
214
+ circuit assertNotInitialized(): [] {
215
+ assert(!_isInitialized, "NonFungibleToken: contract already initialized");
216
+ }
217
+
185
218
  /**
186
219
  * @description Returns the number of tokens in `owner`'s account.
187
220
  *
@@ -195,7 +228,7 @@ module NonFungibleToken {
195
228
  * @return {Uint<128>} - The number of tokens in `owner`'s account.
196
229
  */
197
230
  export circuit balanceOf(owner: Either<Bytes<32>, ContractAddress>): Uint<128> {
198
- Initializable_assertInitialized();
231
+ assertInitialized();
199
232
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
200
233
 
201
234
  if (!_balances.member(disclose(canonOwner))) {
@@ -219,7 +252,7 @@ module NonFungibleToken {
219
252
  * @return {Either<Bytes<32>, ContractAddress>} - The account that owns the token.
220
253
  */
221
254
  export circuit ownerOf(tokenId: Uint<128>): Either<Bytes<32>, ContractAddress> {
222
- Initializable_assertInitialized();
255
+ assertInitialized();
223
256
  return _requireOwned(tokenId);
224
257
  }
225
258
 
@@ -235,7 +268,7 @@ module NonFungibleToken {
235
268
  * @return {Opaque<"string">} - The token name.
236
269
  */
237
270
  export circuit name(): Opaque<"string"> {
238
- Initializable_assertInitialized();
271
+ assertInitialized();
239
272
  return _name;
240
273
  }
241
274
 
@@ -251,7 +284,7 @@ module NonFungibleToken {
251
284
  * @return {Opaque<"string">} - The token symbol.
252
285
  */
253
286
  export circuit symbol(): Opaque<"string"> {
254
- Initializable_assertInitialized();
287
+ assertInitialized();
255
288
  return _symbol;
256
289
  }
257
290
 
@@ -275,7 +308,7 @@ module NonFungibleToken {
275
308
  * @return {Opaque<"string">} - the token id's URI.
276
309
  */
277
310
  export circuit tokenURI(tokenId: Uint<128>): Opaque<"string"> {
278
- Initializable_assertInitialized();
311
+ assertInitialized();
279
312
  _requireOwned(tokenId);
280
313
 
281
314
  if (!_tokenURIs.member(disclose(tokenId))) {
@@ -302,7 +335,7 @@ module NonFungibleToken {
302
335
  * @return {[]} - Empty tuple.
303
336
  */
304
337
  export circuit _setTokenURI(tokenId: Uint<128>, tokenURI: Opaque<"string">): [] {
305
- Initializable_assertInitialized();
338
+ assertInitialized();
306
339
  _requireOwned(tokenId);
307
340
 
308
341
  return _tokenURIs.insert(disclose(tokenId), disclose(tokenURI));
@@ -330,7 +363,7 @@ module NonFungibleToken {
330
363
  * @return {[]} - Empty tuple.
331
364
  */
332
365
  export circuit approve(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>): [] {
333
- Initializable_assertInitialized();
366
+ assertInitialized();
334
367
  const auth = left<Bytes<32>, ContractAddress>(_computeAccountId());
335
368
  _approve(to, tokenId, auth);
336
369
  }
@@ -349,7 +382,7 @@ module NonFungibleToken {
349
382
  * @return {Either<Bytes<32>, ContractAddress>} - The account approved to manage the token
350
383
  */
351
384
  export circuit getApproved(tokenId: Uint<128>): Either<Bytes<32>, ContractAddress> {
352
- Initializable_assertInitialized();
385
+ assertInitialized();
353
386
  _requireOwned(tokenId);
354
387
 
355
388
  return _getApproved(tokenId);
@@ -377,7 +410,7 @@ module NonFungibleToken {
377
410
  operator: Either<Bytes<32>, ContractAddress>,
378
411
  approved: Boolean
379
412
  ): [] {
380
- Initializable_assertInitialized();
413
+ assertInitialized();
381
414
  const owner = left<Bytes<32>, ContractAddress>(_computeAccountId());
382
415
  _setApprovalForAll(owner, operator, approved);
383
416
  }
@@ -399,7 +432,7 @@ module NonFungibleToken {
399
432
  owner: Either<Bytes<32>, ContractAddress>,
400
433
  operator: Either<Bytes<32>, ContractAddress>
401
434
  ): Boolean {
402
- Initializable_assertInitialized();
435
+ assertInitialized();
403
436
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
404
437
  const canonOp = Utils_canonicalize<Bytes<32>, ContractAddress>(operator);
405
438
 
@@ -439,7 +472,7 @@ module NonFungibleToken {
439
472
  to: Either<Bytes<32>, ContractAddress>,
440
473
  tokenId: Uint<128>
441
474
  ): [] {
442
- Initializable_assertInitialized();
475
+ assertInitialized();
443
476
  const isContractAddr = !to.is_left;
444
477
  assert(!isContractAddr, "NonFungibleToken: unsafe transfer");
445
478
 
@@ -476,7 +509,7 @@ module NonFungibleToken {
476
509
  to: Either<Bytes<32>, ContractAddress>,
477
510
  tokenId: Uint<128>
478
511
  ): [] {
479
- Initializable_assertInitialized();
512
+ assertInitialized();
480
513
  assert(!_isTargetZero(to), "NonFungibleToken: invalid receiver");
481
514
  // Setting an "auth" argument enables the `_isAuthorized` check which verifies that the token exists
482
515
  // (fromAddress != 0). Therefore, it is not needed to verify that the return value is not 0 here.
@@ -500,7 +533,7 @@ module NonFungibleToken {
500
533
  * @return {Either<Bytes<32>, ContractAddress>} - The owner of the token
501
534
  */
502
535
  export circuit _ownerOf(tokenId: Uint<128>): Either<Bytes<32>, ContractAddress> {
503
- Initializable_assertInitialized();
536
+ assertInitialized();
504
537
  if (!_owners.member(disclose(tokenId))) {
505
538
  return ZERO();
506
539
  }
@@ -521,7 +554,7 @@ module NonFungibleToken {
521
554
  * @return {Either<Bytes<32>, ContractAddress>} - An account approved to spend `tokenId`
522
555
  */
523
556
  export circuit _getApproved(tokenId: Uint<128>): Either<Bytes<32>, ContractAddress> {
524
- Initializable_assertInitialized();
557
+ assertInitialized();
525
558
  if (!_tokenApprovals.member(disclose(tokenId))) {
526
559
  return ZERO();
527
560
  }
@@ -551,7 +584,7 @@ module NonFungibleToken {
551
584
  spender: Either<Bytes<32>, ContractAddress>,
552
585
  tokenId: Uint<128>
553
586
  ): Boolean {
554
- Initializable_assertInitialized();
587
+ assertInitialized();
555
588
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
556
589
  const canonSpender = Utils_canonicalize<Bytes<32>, ContractAddress>(spender);
557
590
 
@@ -584,7 +617,7 @@ module NonFungibleToken {
584
617
  spender: Either<Bytes<32>, ContractAddress>,
585
618
  tokenId: Uint<128>
586
619
  ): [] {
587
- Initializable_assertInitialized();
620
+ assertInitialized();
588
621
  if (!_isAuthorized(owner, spender, tokenId)) {
589
622
  assert(!_isTargetZero(owner), "NonFungibleToken: nonexistent token");
590
623
  assert(false, "NonFungibleToken: insufficient approval");
@@ -610,7 +643,7 @@ module NonFungibleToken {
610
643
  tokenId: Uint<128>,
611
644
  auth: Either<Bytes<32>, ContractAddress>
612
645
  ): Either<Bytes<32>, ContractAddress> {
613
- Initializable_assertInitialized();
646
+ assertInitialized();
614
647
  const canonTo = Utils_canonicalize<Bytes<32>, ContractAddress>(to);
615
648
  const canonAuth = Utils_canonicalize<Bytes<32>, ContractAddress>(auth);
616
649
  const fromAddress = _ownerOf(tokenId);
@@ -659,7 +692,7 @@ module NonFungibleToken {
659
692
  * @return {[]} - Empty tuple.
660
693
  */
661
694
  export circuit _mint(to: Either<Bytes<32>, ContractAddress>, tokenId: Uint<128>): [] {
662
- Initializable_assertInitialized();
695
+ assertInitialized();
663
696
  const isContractAddr = !to.is_left;
664
697
  assert(!isContractAddr, "NonFungibleToken: unsafe transfer");
665
698
 
@@ -689,7 +722,7 @@ module NonFungibleToken {
689
722
  to: Either<Bytes<32>, ContractAddress>,
690
723
  tokenId: Uint<128>
691
724
  ): [] {
692
- Initializable_assertInitialized();
725
+ assertInitialized();
693
726
  assert(!_isTargetZero(to), "NonFungibleToken: invalid receiver");
694
727
 
695
728
  const previousOwner = _update(to, tokenId, ZERO());
@@ -713,7 +746,7 @@ module NonFungibleToken {
713
746
  * @return {[]} - Empty tuple.
714
747
  */
715
748
  export circuit _burn(tokenId: Uint<128>): [] {
716
- Initializable_assertInitialized();
749
+ assertInitialized();
717
750
  const previousOwner = _update(ZERO(), tokenId, ZERO());
718
751
  assert(!_isTargetZero(previousOwner), "NonFungibleToken: invalid sender");
719
752
  _tokenURIs.remove(disclose(tokenId));
@@ -746,7 +779,7 @@ module NonFungibleToken {
746
779
  to: Either<Bytes<32>, ContractAddress>,
747
780
  tokenId: Uint<128>
748
781
  ): [] {
749
- Initializable_assertInitialized();
782
+ assertInitialized();
750
783
  const isContractAddr = !to.is_left;
751
784
  assert(!isContractAddr, "NonFungibleToken: unsafe transfer");
752
785
 
@@ -780,7 +813,7 @@ module NonFungibleToken {
780
813
  to: Either<Bytes<32>, ContractAddress>,
781
814
  tokenId: Uint<128>
782
815
  ): [] {
783
- Initializable_assertInitialized();
816
+ assertInitialized();
784
817
  assert(!_isTargetZero(to), "NonFungibleToken: invalid receiver");
785
818
 
786
819
  const previousOwner = _update(to, tokenId, ZERO());
@@ -812,7 +845,7 @@ module NonFungibleToken {
812
845
  tokenId: Uint<128>,
813
846
  auth: Either<Bytes<32>, ContractAddress>
814
847
  ): [] {
815
- Initializable_assertInitialized();
848
+ assertInitialized();
816
849
  // Canonicalize + normalize `to`
817
850
  const canonTo = Utils_canonicalize<Bytes<32>, ContractAddress>(to);
818
851
  const normalizedTo = _isTargetZero(canonTo) ? ZERO() : canonTo;
@@ -853,7 +886,7 @@ module NonFungibleToken {
853
886
  operator: Either<Bytes<32>, ContractAddress>,
854
887
  approved: Boolean
855
888
  ): [] {
856
- Initializable_assertInitialized();
889
+ assertInitialized();
857
890
  const canonOwner = Utils_canonicalize<Bytes<32>, ContractAddress>(owner);
858
891
  assert(!_isTargetZero(canonOwner), "NonFungibleToken: invalid owner");
859
892
 
@@ -885,7 +918,7 @@ module NonFungibleToken {
885
918
  * @return {Either<Bytes<32>, ContractAddress>} - The owner of `tokenId`
886
919
  */
887
920
  export circuit _requireOwned(tokenId: Uint<128>): Either<Bytes<32>, ContractAddress> {
888
- Initializable_assertInitialized();
921
+ assertInitialized();
889
922
  const owner = _ownerOf(tokenId);
890
923
 
891
924
  assert(!_isTargetZero(owner), "NonFungibleToken: nonexistent token");
@@ -1,5 +1,5 @@
1
1
  // SPDX-License-Identifier: MIT
2
- // OpenZeppelin Compact Contracts v0.1.0 (utils/Utils.compact)
2
+ // OpenZeppelin Compact Contracts v0.2.0 (utils/Utils.compact)
3
3
 
4
4
  pragma language_version >= 0.21.0;
5
5