@openzeppelin/wizard 0.5.1 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/dist/add-pausable.d.ts +1 -1
  2. package/dist/add-pausable.d.ts.map +1 -1
  3. package/dist/add-pausable.js.map +1 -1
  4. package/dist/api.d.ts +6 -6
  5. package/dist/api.d.ts.map +1 -1
  6. package/dist/api.js +7 -7
  7. package/dist/api.js.map +1 -1
  8. package/dist/build-generic.d.ts +7 -7
  9. package/dist/build-generic.d.ts.map +1 -1
  10. package/dist/build-generic.js +2 -1
  11. package/dist/build-generic.js.map +1 -1
  12. package/dist/common-functions.d.ts.map +1 -1
  13. package/dist/common-functions.js +1 -3
  14. package/dist/common-functions.js.map +1 -1
  15. package/dist/common-options.d.ts +3 -3
  16. package/dist/contract.d.ts +1 -1
  17. package/dist/contract.d.ts.map +1 -1
  18. package/dist/contract.js +10 -6
  19. package/dist/contract.js.map +1 -1
  20. package/dist/custom.d.ts +2 -2
  21. package/dist/custom.d.ts.map +1 -1
  22. package/dist/custom.js.map +1 -1
  23. package/dist/environments/hardhat/package-lock.json +368 -246
  24. package/dist/environments/hardhat/upgradeable/package-lock.json +824 -1506
  25. package/dist/erc1155.d.ts +2 -2
  26. package/dist/erc1155.d.ts.map +1 -1
  27. package/dist/erc1155.js +2 -4
  28. package/dist/erc1155.js.map +1 -1
  29. package/dist/erc20.d.ts +9 -3
  30. package/dist/erc20.d.ts.map +1 -1
  31. package/dist/erc20.js +132 -11
  32. package/dist/erc20.js.map +1 -1
  33. package/dist/erc721.d.ts +3 -3
  34. package/dist/erc721.d.ts.map +1 -1
  35. package/dist/erc721.js +6 -7
  36. package/dist/erc721.js.map +1 -1
  37. package/dist/error.js +1 -1
  38. package/dist/error.js.map +1 -1
  39. package/dist/generate/alternatives.d.ts.map +1 -1
  40. package/dist/generate/alternatives.js.map +1 -1
  41. package/dist/generate/erc20.d.ts +1 -1
  42. package/dist/generate/erc20.d.ts.map +1 -1
  43. package/dist/generate/erc20.js +9 -1
  44. package/dist/generate/erc20.js.map +1 -1
  45. package/dist/generate/erc721.js.map +1 -1
  46. package/dist/generate/governor.d.ts +1 -1
  47. package/dist/generate/governor.d.ts.map +1 -1
  48. package/dist/generate/governor.js.map +1 -1
  49. package/dist/generate/sources.d.ts +1 -1
  50. package/dist/generate/sources.d.ts.map +1 -1
  51. package/dist/generate/sources.js +1 -5
  52. package/dist/generate/sources.js.map +1 -1
  53. package/dist/generate/stablecoin.d.ts.map +1 -1
  54. package/dist/generate/stablecoin.js +32 -15
  55. package/dist/generate/stablecoin.js.map +1 -1
  56. package/dist/get-imports.d.ts +4 -4
  57. package/dist/get-imports.js +4 -4
  58. package/dist/governor.d.ts +5 -5
  59. package/dist/governor.d.ts.map +1 -1
  60. package/dist/governor.js +19 -27
  61. package/dist/governor.js.map +1 -1
  62. package/dist/index.d.ts +1 -1
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +2 -1
  65. package/dist/index.js.map +1 -1
  66. package/dist/infer-transpiled.d.ts +1 -1
  67. package/dist/options.d.ts.map +1 -1
  68. package/dist/options.js.map +1 -1
  69. package/dist/print-versioned.d.ts +1 -1
  70. package/dist/print-versioned.js +1 -1
  71. package/dist/print-versioned.js.map +1 -1
  72. package/dist/print.d.ts +1 -1
  73. package/dist/print.d.ts.map +1 -1
  74. package/dist/print.js +10 -15
  75. package/dist/print.js.map +1 -1
  76. package/dist/scripts/prepare.js +4 -2
  77. package/dist/scripts/prepare.js.map +1 -1
  78. package/dist/set-access-control.d.ts +1 -1
  79. package/dist/set-access-control.d.ts.map +1 -1
  80. package/dist/set-access-control.js +3 -3
  81. package/dist/set-access-control.js.map +1 -1
  82. package/dist/set-clock-mode.d.ts +2 -2
  83. package/dist/set-clock-mode.d.ts.map +1 -1
  84. package/dist/set-clock-mode.js +1 -1
  85. package/dist/set-info.d.ts +1 -1
  86. package/dist/set-info.d.ts.map +1 -1
  87. package/dist/set-upgradeable.d.ts +2 -2
  88. package/dist/set-upgradeable.d.ts.map +1 -1
  89. package/dist/set-upgradeable.js +3 -4
  90. package/dist/set-upgradeable.js.map +1 -1
  91. package/dist/stablecoin.d.ts +3 -3
  92. package/dist/stablecoin.d.ts.map +1 -1
  93. package/dist/stablecoin.js +8 -18
  94. package/dist/stablecoin.js.map +1 -1
  95. package/dist/test.js +1 -1
  96. package/dist/test.js.map +1 -1
  97. package/dist/utils/define-functions.d.ts.map +1 -1
  98. package/dist/utils/define-functions.js +1 -4
  99. package/dist/utils/define-functions.js.map +1 -1
  100. package/dist/utils/format-lines.d.ts.map +1 -1
  101. package/dist/utils/format-lines.js.map +1 -1
  102. package/dist/utils/map-values.d.ts.map +1 -1
  103. package/dist/utils/map-values.js +1 -0
  104. package/dist/utils/map-values.js.map +1 -1
  105. package/dist/utils/to-identifier.d.ts.map +1 -1
  106. package/dist/utils/to-identifier.js +3 -2
  107. package/dist/utils/to-identifier.js.map +1 -1
  108. package/dist/zip-foundry.d.ts +3 -3
  109. package/dist/zip-foundry.d.ts.map +1 -1
  110. package/dist/zip-foundry.js +23 -76
  111. package/dist/zip-foundry.js.map +1 -1
  112. package/dist/zip-hardhat.d.ts +3 -3
  113. package/dist/zip-hardhat.d.ts.map +1 -1
  114. package/dist/zip-hardhat.js +13 -15
  115. package/dist/zip-hardhat.js.map +1 -1
  116. package/package.json +3 -2
  117. package/src/add-pausable.ts +2 -1
  118. package/src/api.ts +55 -25
  119. package/src/build-generic.ts +21 -14
  120. package/src/common-functions.ts +1 -3
  121. package/src/common-options.ts +4 -4
  122. package/src/contract.ts +21 -19
  123. package/src/custom.ts +4 -3
  124. package/src/environments/hardhat/package-lock.json +368 -246
  125. package/src/environments/hardhat/upgradeable/package-lock.json +824 -1506
  126. package/src/erc1155.ts +8 -7
  127. package/src/erc20.ts +188 -23
  128. package/src/erc721.ts +16 -13
  129. package/src/error.ts +1 -1
  130. package/src/generate/alternatives.ts +2 -8
  131. package/src/generate/erc20.ts +10 -3
  132. package/src/generate/erc721.ts +1 -1
  133. package/src/generate/governor.ts +2 -1
  134. package/src/generate/sources.ts +11 -8
  135. package/src/generate/stablecoin.ts +35 -16
  136. package/src/get-imports.ts +5 -5
  137. package/src/governor.ts +56 -58
  138. package/src/index.ts +2 -2
  139. package/src/infer-transpiled.ts +2 -2
  140. package/src/kind.ts +0 -1
  141. package/src/options.ts +4 -3
  142. package/src/print-versioned.ts +4 -6
  143. package/src/print.ts +43 -45
  144. package/src/scripts/prepare.ts +10 -6
  145. package/src/set-access-control.ts +15 -9
  146. package/src/set-clock-mode.ts +5 -5
  147. package/src/set-info.ts +3 -3
  148. package/src/set-upgradeable.ts +6 -6
  149. package/src/stablecoin.ts +23 -27
  150. package/src/test.ts +6 -5
  151. package/src/utils/define-functions.ts +3 -12
  152. package/src/utils/duration.ts +2 -2
  153. package/src/utils/format-lines.ts +1 -5
  154. package/src/utils/map-values.ts +2 -4
  155. package/src/utils/to-identifier.ts +3 -2
  156. package/src/zip-foundry.ts +40 -102
  157. package/src/zip-hardhat.ts +24 -30
package/src/erc1155.ts CHANGED
@@ -1,9 +1,12 @@
1
- import { Contract, ContractBuilder } from './contract';
2
- import { Access, setAccessControl, requireAccessControl } from './set-access-control';
1
+ import type { Contract } from './contract';
2
+ import { ContractBuilder } from './contract';
3
+ import type { Access } from './set-access-control';
4
+ import { setAccessControl, requireAccessControl } from './set-access-control';
3
5
  import { addPauseFunctions } from './add-pausable';
4
6
  import { supportsInterface } from './common-functions';
5
7
  import { defineFunctions } from './utils/define-functions';
6
- import { CommonOptions, withCommonDefaults, defaults as commonDefaults } from './common-options';
8
+ import type { CommonOptions } from './common-options';
9
+ import { withCommonDefaults, defaults as commonDefaults } from './common-options';
7
10
  import { setUpgradeable } from './set-upgradeable';
8
11
  import { setInfo } from './set-info';
9
12
  import { printContract } from './print';
@@ -28,7 +31,7 @@ export const defaults: Required<ERC1155Options> = {
28
31
  updatableUri: true,
29
32
  access: commonDefaults.access,
30
33
  upgradeable: commonDefaults.upgradeable,
31
- info: commonDefaults.info
34
+ info: commonDefaults.info,
32
35
  } as const;
33
36
 
34
37
  function withDefaults(opts: ERC1155Options): Required<ERC1155Options> {
@@ -150,9 +153,7 @@ const functions = defineFunctions({
150
153
 
151
154
  setURI: {
152
155
  kind: 'public' as const,
153
- args: [
154
- { name: 'newuri', type: 'string memory' },
155
- ],
156
+ args: [{ name: 'newuri', type: 'string memory' }],
156
157
  },
157
158
 
158
159
  mint: {
package/src/erc20.ts CHANGED
@@ -1,12 +1,21 @@
1
- import { Contract, ContractBuilder } from './contract';
2
- import { Access, setAccessControl, requireAccessControl } from './set-access-control';
1
+ import { ContractBuilder } from './contract';
2
+ import type { Access } from './set-access-control';
3
+ import { setAccessControl, requireAccessControl } from './set-access-control';
3
4
  import { addPauseFunctions } from './add-pausable';
4
5
  import { defineFunctions } from './utils/define-functions';
5
- import { CommonOptions, withCommonDefaults, defaults as commonDefaults } from './common-options';
6
+ import type { CommonOptions } from './common-options';
7
+ import { withCommonDefaults, defaults as commonDefaults } from './common-options';
8
+ import type { Upgradeable } from './set-upgradeable';
6
9
  import { setUpgradeable } from './set-upgradeable';
7
10
  import { setInfo } from './set-info';
8
11
  import { printContract } from './print';
9
- import { ClockMode, clockModeDefault, setClockMode } from './set-clock-mode';
12
+ import type { ClockMode } from './set-clock-mode';
13
+ import { clockModeDefault, setClockMode } from './set-clock-mode';
14
+ import { supportsInterface } from './common-functions';
15
+ import { OptionsError } from './error';
16
+
17
+ export const crossChainBridgingOptions = [false, 'custom', 'superchain'] as const;
18
+ export type CrossChainBridging = (typeof crossChainBridgingOptions)[number];
10
19
 
11
20
  export interface ERC20Options extends CommonOptions {
12
21
  name: string;
@@ -14,6 +23,7 @@ export interface ERC20Options extends CommonOptions {
14
23
  burnable?: boolean;
15
24
  pausable?: boolean;
16
25
  premint?: string;
26
+ premintChainId?: string;
17
27
  mintable?: boolean;
18
28
  permit?: boolean;
19
29
  /**
@@ -22,6 +32,7 @@ export interface ERC20Options extends CommonOptions {
22
32
  */
23
33
  votes?: boolean | ClockMode;
24
34
  flashmint?: boolean;
35
+ crossChainBridging?: CrossChainBridging;
25
36
  }
26
37
 
27
38
  export const defaults: Required<ERC20Options> = {
@@ -30,10 +41,12 @@ export const defaults: Required<ERC20Options> = {
30
41
  burnable: false,
31
42
  pausable: false,
32
43
  premint: '0',
44
+ premintChainId: '',
33
45
  mintable: false,
34
46
  permit: true,
35
47
  votes: false,
36
48
  flashmint: false,
49
+ crossChainBridging: false,
37
50
  access: commonDefaults.access,
38
51
  upgradeable: commonDefaults.upgradeable,
39
52
  info: commonDefaults.info,
@@ -46,10 +59,12 @@ export function withDefaults(opts: ERC20Options): Required<ERC20Options> {
46
59
  burnable: opts.burnable ?? defaults.burnable,
47
60
  pausable: opts.pausable ?? defaults.pausable,
48
61
  premint: opts.premint || defaults.premint,
62
+ premintChainId: opts.premintChainId || defaults.premintChainId,
49
63
  mintable: opts.mintable ?? defaults.mintable,
50
64
  permit: opts.permit ?? defaults.permit,
51
65
  votes: opts.votes ?? defaults.votes,
52
66
  flashmint: opts.flashmint ?? defaults.flashmint,
67
+ crossChainBridging: opts.crossChainBridging ?? defaults.crossChainBridging,
53
68
  };
54
69
  }
55
70
 
@@ -70,6 +85,14 @@ export function buildERC20(opts: ERC20Options): ContractBuilder {
70
85
 
71
86
  addBase(c, allOpts.name, allOpts.symbol);
72
87
 
88
+ if (allOpts.crossChainBridging) {
89
+ addCrossChainBridging(c, allOpts.crossChainBridging, allOpts.upgradeable, access);
90
+ }
91
+
92
+ if (allOpts.premint) {
93
+ addPremint(c, allOpts.premint, allOpts.premintChainId, allOpts.crossChainBridging);
94
+ }
95
+
73
96
  if (allOpts.burnable) {
74
97
  addBurnable(c);
75
98
  }
@@ -78,10 +101,6 @@ export function buildERC20(opts: ERC20Options): ContractBuilder {
78
101
  addPausableExtension(c, access);
79
102
  }
80
103
 
81
- if (allOpts.premint) {
82
- addPremint(c, allOpts.premint);
83
- }
84
-
85
104
  if (allOpts.mintable) {
86
105
  addMintable(c, access);
87
106
  }
@@ -112,10 +131,7 @@ function addBase(c: ContractBuilder, name: string, symbol: string) {
112
131
  name: 'ERC20',
113
132
  path: '@openzeppelin/contracts/token/ERC20/ERC20.sol',
114
133
  };
115
- c.addParent(
116
- ERC20,
117
- [name, symbol],
118
- );
134
+ c.addParent(ERC20, [name, symbol]);
119
135
 
120
136
  c.addOverride(ERC20, functions._update);
121
137
  c.addOverride(ERC20, functions._approve); // allows override from stablecoin
@@ -141,7 +157,18 @@ function addBurnable(c: ContractBuilder) {
141
157
 
142
158
  export const premintPattern = /^(\d*)(?:\.(\d+))?(?:e(\d+))?$/;
143
159
 
144
- function addPremint(c: ContractBuilder, amount: string) {
160
+ export const chainIdPattern = /^(?!$)[1-9]\d*$/;
161
+
162
+ export function isValidChainId(str: string): boolean {
163
+ return chainIdPattern.test(str);
164
+ }
165
+
166
+ function addPremint(
167
+ c: ContractBuilder,
168
+ amount: string,
169
+ premintChainId: string,
170
+ crossChainBridging: CrossChainBridging,
171
+ ) {
145
172
  const m = amount.match(premintPattern);
146
173
  if (m) {
147
174
  const integer = m[1]?.replace(/^0+/, '') ?? '';
@@ -153,9 +180,35 @@ function addPremint(c: ContractBuilder, amount: string) {
153
180
  const zeroes = new Array(Math.max(0, -decimalPlace)).fill('0').join('');
154
181
  const units = integer + decimals + zeroes;
155
182
  const exp = decimalPlace <= 0 ? 'decimals()' : `(decimals() - ${decimalPlace})`;
156
- c.addConstructorArgument({type: 'address', name: 'recipient'});
157
- c.addConstructorCode(`_mint(recipient, ${units} * 10 ** ${exp});`);
183
+
184
+ c.addConstructorArgument({ type: 'address', name: 'recipient' });
185
+
186
+ const mintLine = `_mint(recipient, ${units} * 10 ** ${exp});`;
187
+
188
+ if (crossChainBridging) {
189
+ if (premintChainId === '') {
190
+ throw new OptionsError({
191
+ premintChainId: 'Chain ID is required when using Premint with Cross-Chain Bridging',
192
+ });
193
+ }
194
+
195
+ if (!isValidChainId(premintChainId)) {
196
+ throw new OptionsError({
197
+ premintChainId: 'Not a valid chain ID',
198
+ });
199
+ }
200
+
201
+ c.addConstructorCode(`if (block.chainid == ${premintChainId}) {`);
202
+ c.addConstructorCode(` ${mintLine}`);
203
+ c.addConstructorCode(`}`);
204
+ } else {
205
+ c.addConstructorCode(mintLine);
206
+ }
158
207
  }
208
+ } else {
209
+ throw new OptionsError({
210
+ premint: 'Not a valid number',
211
+ });
159
212
  }
160
213
  }
161
214
 
@@ -171,7 +224,6 @@ function addPermit(c: ContractBuilder, name: string) {
171
224
  };
172
225
  c.addParent(ERC20Permit, [name]);
173
226
  c.addOverride(ERC20Permit, functions.nonces);
174
-
175
227
  }
176
228
 
177
229
  function addVotes(c: ContractBuilder, clockMode: ClockMode) {
@@ -190,9 +242,12 @@ function addVotes(c: ContractBuilder, clockMode: ClockMode) {
190
242
  name: 'Nonces',
191
243
  path: '@openzeppelin/contracts/utils/Nonces.sol',
192
244
  });
193
- c.addOverride({
194
- name: 'Nonces',
195
- }, functions.nonces);
245
+ c.addOverride(
246
+ {
247
+ name: 'Nonces',
248
+ },
249
+ functions.nonces,
250
+ );
196
251
 
197
252
  setClockMode(c, ERC20Votes, clockMode);
198
253
  }
@@ -204,6 +259,113 @@ function addFlashMint(c: ContractBuilder) {
204
259
  });
205
260
  }
206
261
 
262
+ function addCrossChainBridging(
263
+ c: ContractBuilder,
264
+ crossChainBridging: 'custom' | 'superchain',
265
+ upgradeable: Upgradeable,
266
+ access: Access,
267
+ ) {
268
+ const ERC20Bridgeable = {
269
+ name: 'ERC20Bridgeable',
270
+ path: `@openzeppelin/community-contracts/contracts/token/ERC20/extensions/ERC20Bridgeable.sol`,
271
+ };
272
+
273
+ c.addParent(ERC20Bridgeable);
274
+ c.addOverride(ERC20Bridgeable, supportsInterface);
275
+
276
+ if (upgradeable) {
277
+ throw new OptionsError({
278
+ crossChainBridging: 'Upgradeability is not currently supported with Cross-Chain Bridging',
279
+ });
280
+ }
281
+
282
+ c.addOverride(ERC20Bridgeable, functions._checkTokenBridge);
283
+ switch (crossChainBridging) {
284
+ case 'custom':
285
+ addCustomBridging(c, access);
286
+ break;
287
+ case 'superchain':
288
+ addSuperchainERC20(c);
289
+ break;
290
+ default: {
291
+ const _: never = crossChainBridging;
292
+ throw new Error('Unknown value for `crossChainBridging`');
293
+ }
294
+ }
295
+ c.addVariable('error Unauthorized();');
296
+ }
297
+
298
+ function addCustomBridging(c: ContractBuilder, access: Access) {
299
+ switch (access) {
300
+ case false:
301
+ case 'ownable': {
302
+ const addedBridgeImmutable = c.addVariable(`address public immutable TOKEN_BRIDGE;`);
303
+ if (addedBridgeImmutable) {
304
+ c.addConstructorArgument({ type: 'address', name: 'tokenBridge' });
305
+ c.addConstructorCode(`require(tokenBridge != address(0), "Invalid TOKEN_BRIDGE address");`);
306
+ c.addConstructorCode(`TOKEN_BRIDGE = tokenBridge;`);
307
+ }
308
+ c.setFunctionBody([`if (caller != TOKEN_BRIDGE) revert Unauthorized();`], functions._checkTokenBridge, 'view');
309
+ break;
310
+ }
311
+ case 'roles': {
312
+ setAccessControl(c, access);
313
+ const roleOwner = 'tokenBridge';
314
+ const roleId = 'TOKEN_BRIDGE_ROLE';
315
+ const addedRoleConstant = c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`);
316
+ if (addedRoleConstant) {
317
+ c.addConstructorArgument({ type: 'address', name: roleOwner });
318
+ c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
319
+ }
320
+ c.setFunctionBody(
321
+ [`if (!hasRole(${roleId}, caller)) revert Unauthorized();`],
322
+ functions._checkTokenBridge,
323
+ 'view',
324
+ );
325
+ break;
326
+ }
327
+ case 'managed': {
328
+ setAccessControl(c, access);
329
+ c.addImportOnly({
330
+ name: 'AuthorityUtils',
331
+ path: `@openzeppelin/contracts/access/manager/AuthorityUtils.sol`,
332
+ });
333
+ c.setFunctionBody(
334
+ [
335
+ `(bool immediate,) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), bytes4(_msgData()[0:4]));`,
336
+ `if (!immediate) revert Unauthorized();`,
337
+ ],
338
+ functions._checkTokenBridge,
339
+ 'view',
340
+ );
341
+ break;
342
+ }
343
+ default: {
344
+ const _: never = access;
345
+ throw new Error('Unknown value for `access`');
346
+ }
347
+ }
348
+ }
349
+
350
+ function addSuperchainERC20(c: ContractBuilder) {
351
+ c.addVariable('address internal constant SUPERCHAIN_TOKEN_BRIDGE = 0x4200000000000000000000000000000000000028;');
352
+ c.setFunctionBody(
353
+ ['if (caller != SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized();'],
354
+ functions._checkTokenBridge,
355
+ 'pure',
356
+ );
357
+ c.setFunctionComments(
358
+ [
359
+ '/**',
360
+ ' * @dev Checks if the caller is the predeployed SuperchainTokenBridge. Reverts otherwise.',
361
+ ' *',
362
+ ' * IMPORTANT: The predeployed SuperchainTokenBridge is only available on chains in the Superchain.',
363
+ ' */',
364
+ ],
365
+ functions._checkTokenBridge,
366
+ );
367
+ }
368
+
207
369
  export const functions = defineFunctions({
208
370
  _update: {
209
371
  kind: 'internal' as const,
@@ -249,10 +411,13 @@ export const functions = defineFunctions({
249
411
 
250
412
  nonces: {
251
413
  kind: 'public' as const,
252
- args: [
253
- { name: 'owner', type: 'address' },
254
- ],
414
+ args: [{ name: 'owner', type: 'address' }],
255
415
  returns: ['uint256'],
256
416
  mutability: 'view' as const,
257
- }
417
+ },
418
+
419
+ _checkTokenBridge: {
420
+ kind: 'internal' as const,
421
+ args: [{ name: 'caller', type: 'address' }],
422
+ },
258
423
  });
package/src/erc721.ts CHANGED
@@ -1,13 +1,17 @@
1
- import { Contract, ContractBuilder } from './contract';
2
- import { Access, setAccessControl, requireAccessControl } from './set-access-control';
1
+ import type { BaseFunction, Contract } from './contract';
2
+ import { ContractBuilder } from './contract';
3
+ import type { Access } from './set-access-control';
4
+ import { setAccessControl, requireAccessControl } from './set-access-control';
3
5
  import { addPauseFunctions } from './add-pausable';
4
6
  import { supportsInterface } from './common-functions';
5
7
  import { defineFunctions } from './utils/define-functions';
6
- import { CommonOptions, withCommonDefaults, defaults as commonDefaults } from './common-options';
8
+ import type { CommonOptions } from './common-options';
9
+ import { withCommonDefaults, defaults as commonDefaults } from './common-options';
7
10
  import { setUpgradeable } from './set-upgradeable';
8
11
  import { setInfo } from './set-info';
9
12
  import { printContract } from './print';
10
- import { ClockMode, clockModeDefault, setClockMode } from './set-clock-mode';
13
+ import type { ClockMode } from './set-clock-mode';
14
+ import { clockModeDefault, setClockMode } from './set-clock-mode';
11
15
 
12
16
  export interface ERC721Options extends CommonOptions {
13
17
  name: string;
@@ -185,6 +189,8 @@ function addMintable(c: ContractBuilder, access: Access, incremental = false, ur
185
189
  if (uriStorage) {
186
190
  c.addFunctionCode('_setTokenURI(tokenId, uri);', fn);
187
191
  }
192
+
193
+ if (incremental) c.addFunctionCode('return tokenId;', fn);
188
194
  }
189
195
 
190
196
  function addVotes(c: ContractBuilder, name: string, clockMode: ClockMode) {
@@ -192,7 +198,7 @@ function addVotes(c: ContractBuilder, name: string, clockMode: ClockMode) {
192
198
  name: 'EIP712',
193
199
  path: '@openzeppelin/contracts/utils/cryptography/EIP712.sol',
194
200
  };
195
- c.addParent(EIP712, [name, "1"]);
201
+ c.addParent(EIP712, [name, '1']);
196
202
 
197
203
  const ERC721Votes = {
198
204
  name: 'ERC721Votes',
@@ -219,9 +225,7 @@ const functions = defineFunctions({
219
225
 
220
226
  tokenURI: {
221
227
  kind: 'public' as const,
222
- args: [
223
- { name: 'tokenId', type: 'uint256' },
224
- ],
228
+ args: [{ name: 'tokenId', type: 'uint256' }],
225
229
  returns: ['string memory'],
226
230
  mutability: 'view' as const,
227
231
  },
@@ -242,13 +246,12 @@ const functions = defineFunctions({
242
246
  },
243
247
  });
244
248
 
245
- function getMintFunction(incremental: boolean, uriStorage: boolean) {
246
- const fn = {
249
+ function getMintFunction(incremental: boolean, uriStorage: boolean): BaseFunction {
250
+ const fn: BaseFunction = {
247
251
  name: 'safeMint',
248
252
  kind: 'public' as const,
249
- args: [
250
- { name: 'to', type: 'address' },
251
- ],
253
+ args: [{ name: 'to', type: 'address' }],
254
+ returns: incremental ? ['uint256'] : undefined,
252
255
  };
253
256
 
254
257
  if (!incremental) {
package/src/error.ts CHANGED
@@ -2,6 +2,6 @@ export type OptionsErrorMessages = { [prop in string]?: string };
2
2
 
3
3
  export class OptionsError extends Error {
4
4
  constructor(readonly messages: OptionsErrorMessages) {
5
- super("Invalid options for Governor");
5
+ super('Invalid options');
6
6
  }
7
7
  }
@@ -1,14 +1,10 @@
1
- import { mapValues } from "../utils/map-values";
2
-
3
1
  type Blueprint = Record<string, readonly unknown[]>;
4
2
 
5
3
  type Alternatives<B extends Blueprint> = {
6
4
  [k in keyof B]: B[k][number];
7
5
  };
8
6
 
9
- export function* generateAlternatives<B extends Blueprint>(
10
- blueprint: B,
11
- ): Generator<Alternatives<B>> {
7
+ export function* generateAlternatives<B extends Blueprint>(blueprint: B): Generator<Alternatives<B>> {
12
8
  const entries = Object.entries(blueprint).map(([key, values]) => ({
13
9
  key,
14
10
  values,
@@ -17,9 +13,7 @@ export function* generateAlternatives<B extends Blueprint>(
17
13
  }));
18
14
 
19
15
  for (; !done(); advance()) {
20
- yield Object.fromEntries(
21
- entries.map(e => [e.key, e.values[e.current % e.limit]]),
22
- ) as Alternatives<B>;
16
+ yield Object.fromEntries(entries.map(e => [e.key, e.values[e.current % e.limit]])) as Alternatives<B>;
23
17
  }
24
18
 
25
19
  function done() {
@@ -1,4 +1,4 @@
1
- import type { ERC20Options } from '../erc20';
1
+ import { crossChainBridgingOptions, type ERC20Options } from '../erc20';
2
2
  import { accessOptions } from '../set-access-control';
3
3
  import { clockModeOptions } from '../set-clock-mode';
4
4
  import { infoOptions } from '../set-info';
@@ -14,14 +14,21 @@ const blueprint = {
14
14
  pausable: booleans,
15
15
  mintable: booleans,
16
16
  permit: booleans,
17
- votes: [ ...booleans, ...clockModeOptions ] as const,
17
+ votes: [...booleans, ...clockModeOptions] as const,
18
18
  flashmint: booleans,
19
19
  premint: ['1'],
20
+ premintChainId: ['10'],
21
+ crossChainBridging: crossChainBridgingOptions,
20
22
  access: accessOptions,
21
23
  upgradeable: upgradeableOptions,
22
24
  info: infoOptions,
23
25
  };
24
26
 
25
27
  export function* generateERC20Options(): Generator<Required<ERC20Options>> {
26
- yield* generateAlternatives(blueprint);
28
+ for (const opts of generateAlternatives(blueprint)) {
29
+ // crossChainBridging does not currently support upgradeable
30
+ if (!(opts.crossChainBridging && opts.upgradeable)) {
31
+ yield opts;
32
+ }
33
+ }
27
34
  }
@@ -20,7 +20,7 @@ const blueprint = {
20
20
  access: accessOptions,
21
21
  upgradeable: upgradeableOptions,
22
22
  info: infoOptions,
23
- votes: [ ...booleans, ...clockModeOptions ] as const,
23
+ votes: [...booleans, ...clockModeOptions] as const,
24
24
  };
25
25
 
26
26
  export function* generateERC721Options(): Generator<Required<ERC721Options>> {
@@ -1,4 +1,5 @@
1
- import { defaults, GovernorOptions, timelockOptions, votesOptions } from '../governor';
1
+ import type { GovernorOptions } from '../governor';
2
+ import { defaults, timelockOptions, votesOptions } from '../governor';
2
3
  import { accessOptions } from '../set-access-control';
3
4
  import { clockModeOptions } from '../set-clock-mode';
4
5
  import { infoOptions } from '../set-info';
@@ -8,7 +8,8 @@ import { generateERC1155Options } from './erc1155';
8
8
  import { generateStablecoinOptions } from './stablecoin';
9
9
  import { generateGovernorOptions } from './governor';
10
10
  import { generateCustomOptions } from './custom';
11
- import { buildGeneric, GenericOptions, KindedOptions } from '../build-generic';
11
+ import type { GenericOptions, KindedOptions } from '../build-generic';
12
+ import { buildGeneric } from '../build-generic';
12
13
  import { printContract } from '../print';
13
14
  import { OptionsError } from '../error';
14
15
  import { findCover } from '../utils/find-cover';
@@ -76,11 +77,7 @@ function generateContractSubset(subset: Subset, kind?: Kind): GeneratedContract[
76
77
  const contracts = [];
77
78
 
78
79
  for (const options of generateOptions(kind)) {
79
- const id = crypto
80
- .createHash('sha1')
81
- .update(JSON.stringify(options))
82
- .digest()
83
- .toString('hex');
80
+ const id = crypto.createHash('sha1').update(JSON.stringify(options)).digest().toString('hex');
84
81
 
85
82
  try {
86
83
  const contract = buildGeneric(options);
@@ -99,8 +96,14 @@ function generateContractSubset(subset: Subset, kind?: Kind): GeneratedContract[
99
96
  } else {
100
97
  const getParents = (c: GeneratedContract) => c.contract.parents.map(p => p.contract.path);
101
98
  return [
102
- ...findCover(contracts.filter(c => c.options.upgradeable), getParents),
103
- ...findCover(contracts.filter(c => !c.options.upgradeable), getParents),
99
+ ...findCover(
100
+ contracts.filter(c => c.options.upgradeable),
101
+ getParents,
102
+ ),
103
+ ...findCover(
104
+ contracts.filter(c => !c.options.upgradeable),
105
+ getParents,
106
+ ),
104
107
  ];
105
108
  }
106
109
  }
@@ -1,31 +1,50 @@
1
- import type { StablecoinOptions } from '../stablecoin';
1
+ import { crossChainBridgingOptions } from '../erc20';
2
2
  import { accessOptions } from '../set-access-control';
3
- import { clockModeOptions } from '../set-clock-mode';
4
3
  import { infoOptions } from '../set-info';
5
- import { upgradeableOptions } from '../set-upgradeable';
4
+ import type { StablecoinOptions } from '../stablecoin';
6
5
  import { generateAlternatives } from './alternatives';
7
6
 
8
7
  const booleans = [true, false];
9
8
 
10
- const blueprint = {
9
+ const erc20Basic = {
11
10
  name: ['MyStablecoin'],
12
11
  symbol: ['MST'],
13
- burnable: booleans,
14
- pausable: booleans,
15
- mintable: booleans,
16
- permit: booleans,
17
- limitations: [false, 'allowlist', 'blocklist'] as const,
18
- votes: [ ...booleans, ...clockModeOptions ] as const,
19
- flashmint: booleans,
12
+ burnable: [false] as const,
13
+ pausable: [false] as const,
14
+ mintable: [false] as const,
15
+ permit: [false] as const,
16
+ votes: [false] as const,
17
+ flashmint: [false] as const,
20
18
  premint: ['1'],
21
- custodian: booleans,
19
+ premintChainId: [''],
20
+ crossChainBridging: [false] as const,
21
+ access: [false] as const,
22
+ info: [{}] as const,
23
+ };
24
+
25
+ const erc20Full = {
26
+ name: ['MyStablecoin'],
27
+ symbol: ['MST'],
28
+ burnable: [true] as const,
29
+ pausable: [true] as const,
30
+ mintable: [true] as const,
31
+ permit: [true] as const,
32
+ votes: ['timestamp'] as const,
33
+ flashmint: [true] as const,
34
+ premint: ['1'],
35
+ premintChainId: ['10'],
36
+ crossChainBridging: crossChainBridgingOptions,
22
37
  access: accessOptions,
23
- upgradeable: upgradeableOptions,
24
38
  info: infoOptions,
25
39
  };
26
40
 
41
+ const stablecoinExtensions = {
42
+ limitations: [false, 'allowlist', 'blocklist'] as const,
43
+ custodian: booleans,
44
+ upgradeable: [false] as const,
45
+ };
46
+
27
47
  export function* generateStablecoinOptions(): Generator<Required<StablecoinOptions>> {
28
- for (const opts of generateAlternatives(blueprint)) {
29
- yield { ...opts, upgradeable: false };
30
- }
48
+ yield* generateAlternatives({ ...erc20Basic, ...stablecoinExtensions });
49
+ yield* generateAlternatives({ ...erc20Full, ...stablecoinExtensions });
31
50
  }
@@ -11,10 +11,10 @@ export interface SolcInputSources {
11
11
  }
12
12
 
13
13
  /**
14
- * Gets the source code for all imports of a contract, including all transitive dependencies,
15
- * in a format compatible with the Solidity compiler input's `sources` field.
16
- *
17
- * Does not include the contract itself (use `printContract` for that if needed).
14
+ * Gets the source code for all imports of a contract, including all transitive dependencies,
15
+ * in a format compatible with the Solidity compiler input's `sources` field.
16
+ *
17
+ * Does not include the contract itself (use `printContract` for that if needed).
18
18
  *
19
19
  * @param c The contract to get imports for.
20
20
  * @returns A record of import paths to `content` that contains the source code for each contract.
@@ -42,4 +42,4 @@ export function getImports(c: Contract): SolcInputSources {
42
42
  }
43
43
 
44
44
  return result;
45
- }
45
+ }