@openzeppelin/wizard 0.3.0 → 0.4.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.
Files changed (92) hide show
  1. package/dist/add-pausable.d.ts +1 -0
  2. package/dist/add-pausable.d.ts.map +1 -1
  3. package/dist/add-pausable.js +9 -5
  4. package/dist/add-pausable.js.map +1 -1
  5. package/dist/contract.d.ts +13 -9
  6. package/dist/contract.d.ts.map +1 -1
  7. package/dist/contract.js +5 -5
  8. package/dist/contract.js.map +1 -1
  9. package/dist/environments/hardhat/package-lock.json +1488 -7247
  10. package/dist/environments/hardhat/package.json +4 -22
  11. package/dist/environments/hardhat/upgradeable/package-lock.json +1668 -7725
  12. package/dist/environments/hardhat/upgradeable/package.json +5 -22
  13. package/dist/erc1155.js +24 -15
  14. package/dist/erc1155.js.map +1 -1
  15. package/dist/erc20.d.ts +0 -1
  16. package/dist/erc20.d.ts.map +1 -1
  17. package/dist/erc20.js +45 -62
  18. package/dist/erc20.js.map +1 -1
  19. package/dist/erc721.js +54 -53
  20. package/dist/erc721.js.map +1 -1
  21. package/dist/generate/erc20.d.ts.map +1 -1
  22. package/dist/generate/erc20.js +0 -1
  23. package/dist/generate/erc20.js.map +1 -1
  24. package/dist/generate/governor.js +1 -1
  25. package/dist/generate/governor.js.map +1 -1
  26. package/dist/governor.d.ts +2 -2
  27. package/dist/governor.d.ts.map +1 -1
  28. package/dist/governor.js +104 -98
  29. package/dist/governor.js.map +1 -1
  30. package/dist/infer-transpiled.d.ts +3 -0
  31. package/dist/infer-transpiled.d.ts.map +1 -0
  32. package/dist/infer-transpiled.js +9 -0
  33. package/dist/infer-transpiled.js.map +1 -0
  34. package/dist/options.d.ts +3 -4
  35. package/dist/options.d.ts.map +1 -1
  36. package/dist/options.js +14 -11
  37. package/dist/options.js.map +1 -1
  38. package/dist/print-versioned.d.ts.map +1 -1
  39. package/dist/print-versioned.js +6 -1
  40. package/dist/print-versioned.js.map +1 -1
  41. package/dist/print.d.ts.map +1 -1
  42. package/dist/print.js +17 -9
  43. package/dist/print.js.map +1 -1
  44. package/dist/scripts/prepare.js +0 -1
  45. package/dist/scripts/prepare.js.map +1 -1
  46. package/dist/set-access-control.d.ts +1 -1
  47. package/dist/set-access-control.d.ts.map +1 -1
  48. package/dist/set-access-control.js +18 -7
  49. package/dist/set-access-control.js.map +1 -1
  50. package/dist/set-upgradeable.d.ts.map +1 -1
  51. package/dist/set-upgradeable.js +5 -4
  52. package/dist/set-upgradeable.js.map +1 -1
  53. package/dist/solidity-version.json +1 -1
  54. package/dist/zip-foundry.d.ts +5 -0
  55. package/dist/zip-foundry.d.ts.map +1 -0
  56. package/dist/zip-foundry.js +224 -0
  57. package/dist/zip-foundry.js.map +1 -0
  58. package/dist/zip-hardhat.d.ts.map +1 -1
  59. package/dist/zip-hardhat.js +36 -11
  60. package/dist/zip-hardhat.js.map +1 -1
  61. package/package.json +3 -4
  62. package/src/add-pausable.ts +7 -3
  63. package/src/contract.ts +17 -15
  64. package/src/environments/hardhat/package-lock.json +1488 -7247
  65. package/src/environments/hardhat/package.json +4 -22
  66. package/src/environments/hardhat/upgradeable/package-lock.json +1668 -7725
  67. package/src/environments/hardhat/upgradeable/package.json +5 -22
  68. package/src/erc1155.ts +30 -23
  69. package/src/erc20.ts +46 -67
  70. package/src/erc721.ts +64 -66
  71. package/src/generate/erc20.ts +0 -1
  72. package/src/generate/governor.ts +1 -1
  73. package/src/governor.ts +110 -109
  74. package/src/infer-transpiled.ts +5 -0
  75. package/src/options.ts +18 -16
  76. package/src/print-versioned.ts +6 -2
  77. package/src/print.ts +17 -13
  78. package/src/scripts/prepare.ts +0 -2
  79. package/src/set-access-control.ts +18 -7
  80. package/src/set-upgradeable.ts +5 -4
  81. package/src/solidity-version.json +1 -1
  82. package/src/zip-foundry.ts +259 -0
  83. package/src/zip-hardhat.ts +39 -11
  84. package/CHANGELOG.md +0 -30
  85. package/dist/zip.d.ts +0 -4
  86. package/dist/zip.d.ts.map +0 -1
  87. package/dist/zip.js +0 -48
  88. package/dist/zip.js.map +0 -1
  89. package/src/.DS_Store +0 -0
  90. package/src/environments/.DS_Store +0 -0
  91. package/src/environments/hardhat/.DS_Store +0 -0
  92. package/src/zip.ts +0 -53
package/src/governor.ts CHANGED
@@ -11,7 +11,7 @@ import { durationToBlocks } from "./utils/duration";
11
11
 
12
12
  export const defaults: Required<GovernorOptions> = {
13
13
  name: 'MyGovernor',
14
- delay: '1 block',
14
+ delay: '1 day',
15
15
  period: '1 week',
16
16
 
17
17
  votes: 'erc20votes',
@@ -22,7 +22,7 @@ export const defaults: Required<GovernorOptions> = {
22
22
  quorumMode: 'percent',
23
23
  quorumPercent: 4,
24
24
  quorumAbsolute: '',
25
- bravo: false,
25
+ storage: false,
26
26
  settings: true,
27
27
 
28
28
  access: commonDefaults.access,
@@ -30,7 +30,7 @@ export const defaults: Required<GovernorOptions> = {
30
30
  info: commonDefaults.info
31
31
  } as const;
32
32
 
33
- export const votesOptions = ['erc20votes', 'erc721votes', 'comp'] as const;
33
+ export const votesOptions = ['erc20votes', 'erc721votes'] as const;
34
34
  export type VotesOptions = typeof votesOptions[number];
35
35
 
36
36
  export const timelockOptions = [false, 'openzeppelin', 'compound'] as const;
@@ -52,7 +52,7 @@ export interface GovernorOptions extends CommonOptions {
52
52
  quorumAbsolute?: string;
53
53
  votes?: VotesOptions;
54
54
  timelock?: TimelockOptions;
55
- bravo?: boolean;
55
+ storage?: boolean;
56
56
  settings?: boolean;
57
57
  }
58
58
 
@@ -70,7 +70,7 @@ function withDefaults(opts: GovernorOptions): Required<GovernorOptions> {
70
70
  quorumAbsolute: opts.quorumAbsolute ?? defaults.quorumAbsolute,
71
71
  proposalThreshold: opts.proposalThreshold || defaults.proposalThreshold,
72
72
  settings: opts.settings ?? defaults.settings,
73
- bravo: opts.bravo ?? defaults.bravo,
73
+ storage: opts.storage ?? defaults.storage,
74
74
  quorumMode: opts.quorumMode ?? defaults.quorumMode,
75
75
  votes: opts.votes ?? defaults.votes,
76
76
  timelock: opts.timelock ?? defaults.timelock
@@ -86,9 +86,9 @@ export function buildGovernor(opts: GovernorOptions): Contract {
86
86
 
87
87
  addBase(c, allOpts);
88
88
  addSettings(c, allOpts);
89
- addCounting(c, allOpts);
90
- addBravo(c, allOpts);
91
- addVotes(c, allOpts);
89
+ addCounting(c);
90
+ addStorage(c, allOpts);
91
+ addVotes(c);
92
92
  addQuorum(c, allOpts);
93
93
  addTimelock(c, allOpts);
94
94
 
@@ -100,42 +100,43 @@ export function buildGovernor(opts: GovernorOptions): Contract {
100
100
  }
101
101
 
102
102
  function addBase(c: ContractBuilder, { name }: GovernorOptions) {
103
- c.addParent(
104
- {
105
- name: 'Governor',
106
- path: '@openzeppelin/contracts/governance/Governor.sol',
107
- },
108
- [name],
109
- );
110
- c.addOverride('IGovernor', functions.votingDelay);
111
- c.addOverride('IGovernor', functions.votingPeriod);
112
- c.addOverride('IGovernor', functions.quorum);
113
- c.addOverride('Governor', functions.state);
114
- c.addOverride('Governor', functions.propose);
115
- c.addOverride('Governor', functions.proposalThreshold);
116
- c.addOverride('Governor', functions._execute);
117
- c.addOverride('Governor', functions._cancel);
118
- c.addOverride('Governor', functions._executor);
119
- c.addOverride('Governor', supportsInterface);
120
- c.addOverride('Governor', functions.cancel);
103
+ const Governor = {
104
+ name: 'Governor',
105
+ path: '@openzeppelin/contracts/governance/Governor.sol',
106
+ };
107
+ c.addParent(Governor, [name]);
108
+ c.addOverride(Governor, functions.votingDelay);
109
+ c.addOverride(Governor, functions.votingPeriod);
110
+ c.addOverride(Governor, functions.quorum);
111
+ c.addOverride(Governor, functions.state);
112
+ c.addOverride(Governor, functions.propose);
113
+ c.addOverride(Governor, functions.proposalNeedsQueuing);
114
+ c.addOverride(Governor, functions.proposalThreshold);
115
+ c.addOverride(Governor, functions._propose);
116
+ c.addOverride(Governor, functions._queueOperations);
117
+ c.addOverride(Governor, functions._executeOperations);
118
+ c.addOverride(Governor, functions._cancel);
119
+ c.addOverride(Governor, functions._executor);
120
+ c.addOverride(Governor, supportsInterface);
121
121
  }
122
122
 
123
123
  function addSettings(c: ContractBuilder, allOpts: Required<GovernorOptions>) {
124
124
  if (allOpts.settings) {
125
+ const GovernorSettings = {
126
+ name: 'GovernorSettings',
127
+ path: '@openzeppelin/contracts/governance/extensions/GovernorSettings.sol',
128
+ };
125
129
  c.addParent(
126
- {
127
- name: 'GovernorSettings',
128
- path: '@openzeppelin/contracts/governance/extensions/GovernorSettings.sol',
129
- },
130
+ GovernorSettings,
130
131
  [
131
132
  { value: getVotingDelay(allOpts), note: allOpts.delay },
132
133
  { value: getVotingPeriod(allOpts), note: allOpts.period },
133
134
  { lit: getProposalThreshold(allOpts) },
134
135
  ],
135
136
  );
136
- c.addOverride('GovernorSettings', functions.votingDelay, 'view');
137
- c.addOverride('GovernorSettings', functions.votingPeriod, 'view');
138
- c.addOverride('GovernorSettings', functions.proposalThreshold, 'view');
137
+ c.addOverride(GovernorSettings, functions.votingDelay, 'view');
138
+ c.addOverride(GovernorSettings, functions.votingPeriod, 'view');
139
+ c.addOverride(GovernorSettings, functions.proposalThreshold, 'view');
139
140
  } else {
140
141
  setVotingParameters(c, allOpts);
141
142
  setProposalThreshold(c, allOpts);
@@ -209,42 +210,27 @@ function setProposalThreshold(c: ContractBuilder, opts: Required<GovernorOptions
209
210
  }
210
211
  }
211
212
 
212
- function addCounting(c: ContractBuilder, { bravo }: GovernorOptions) {
213
- if (!bravo) {
214
- c.addParent({
215
- name: 'GovernorCountingSimple',
216
- path: '@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol',
217
- });
218
- }
213
+ function addCounting(c: ContractBuilder) {
214
+ c.addParent({
215
+ name: 'GovernorCountingSimple',
216
+ path: '@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol',
217
+ });
219
218
  }
220
219
 
221
- const votesModules = {
222
- erc20votes: {
223
- tokenType: 'IVotes',
224
- parentName: 'GovernorVotes',
225
- },
226
- erc721votes: {
227
- tokenType: 'IVotes',
228
- parentName: 'GovernorVotes',
229
- },
230
- comp: {
231
- tokenType: 'ERC20VotesComp',
232
- parentName: 'GovernorVotesComp',
233
- },
234
- } as const;
235
-
236
- function addVotes(c: ContractBuilder, { votes }: Required<GovernorOptions>) {
220
+ function addVotes(c: ContractBuilder) {
237
221
  const tokenArg = '_token';
238
- const { tokenType, parentName } = votesModules[votes];
239
222
 
240
223
  c.addConstructorArgument({
241
- type: tokenType,
224
+ type: {
225
+ name: 'IVotes',
226
+ transpiled: false,
227
+ },
242
228
  name: tokenArg,
243
229
  });
244
230
 
245
231
  c.addParent({
246
- name: parentName,
247
- path: `@openzeppelin/contracts/governance/extensions/${parentName}.sol`,
232
+ name: 'GovernorVotes',
233
+ path: `@openzeppelin/contracts/governance/extensions/GovernorVotes.sol`,
248
234
  }, [{ lit: tokenArg }]);
249
235
  }
250
236
 
@@ -252,12 +238,6 @@ export const numberPattern = /^(?!$)(\d*)(?:\.(\d+))?(?:e(\d+))?$/;
252
238
 
253
239
  function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
254
240
  if (opts.quorumMode === 'percent') {
255
- if (opts.votes !== 'erc20votes' && opts.votes !== 'erc721votes') {
256
- throw new OptionsError({
257
- quorumPercent: 'Percent-based quorum is only available for ERC20Votes or ERC721Votes',
258
- });
259
- }
260
-
261
241
  if (opts.quorumPercent > 100) {
262
242
  throw new OptionsError({
263
243
  quorumPercent: 'Invalid percentage',
@@ -266,18 +246,20 @@ function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
266
246
 
267
247
  let { quorumFractionNumerator, quorumFractionDenominator } = getQuorumFractionComponents(opts.quorumPercent);
268
248
 
249
+ const GovernorVotesQuorumFraction = {
250
+ name: 'GovernorVotesQuorumFraction',
251
+ path: '@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol',
252
+ };
253
+
269
254
  if (quorumFractionDenominator !== undefined) {
270
- c.addOverride('GovernorVotesQuorumFraction', functions.quorumDenominator);
255
+ c.addOverride(GovernorVotesQuorumFraction, functions.quorumDenominator);
271
256
  c.setFunctionBody([
272
257
  `return ${quorumFractionDenominator};`
273
258
  ], functions.quorumDenominator, 'pure');
274
259
  }
275
260
 
276
- c.addParent({
277
- name: 'GovernorVotesQuorumFraction',
278
- path: '@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol',
279
- }, [quorumFractionNumerator]);
280
- c.addOverride('GovernorVotesQuorumFraction', functions.quorum);
261
+ c.addParent(GovernorVotesQuorumFraction, [quorumFractionNumerator]);
262
+ c.addOverride(GovernorVotesQuorumFraction, functions.quorum);
281
263
  }
282
264
 
283
265
  else if (opts.quorumMode === 'absolute') {
@@ -299,12 +281,23 @@ function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
299
281
 
300
282
  const timelockModules = {
301
283
  openzeppelin: {
302
- timelockType: 'TimelockController',
303
- parentName: 'GovernorTimelockControl',
284
+ timelockType: {
285
+ name: 'TimelockController',
286
+ },
287
+ timelockParent: {
288
+ name: 'GovernorTimelockControl',
289
+ path: `@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol`,
290
+ }
304
291
  },
305
292
  compound: {
306
- timelockType: 'ICompoundTimelock',
307
- parentName: 'GovernorTimelockCompound',
293
+ timelockType: {
294
+ name: 'ICompoundTimelock',
295
+ transpiled: false,
296
+ },
297
+ timelockParent: {
298
+ name: 'GovernorTimelockCompound',
299
+ path: `@openzeppelin/contracts/governance/extensions/GovernorTimelockCompound.sol`,
300
+ }
308
301
  },
309
302
  } as const;
310
303
 
@@ -334,42 +327,30 @@ function addTimelock(c: ContractBuilder, { timelock }: Required<GovernorOptions>
334
327
  }
335
328
 
336
329
  const timelockArg = '_timelock';
337
- const { timelockType, parentName } = timelockModules[timelock];
330
+ const { timelockType, timelockParent } = timelockModules[timelock];
338
331
 
339
332
  c.addConstructorArgument({
340
333
  type: timelockType,
341
334
  name: timelockArg,
342
335
  });
343
336
 
344
- c.addParent({
345
- name: parentName,
346
- path: `@openzeppelin/contracts/governance/extensions/${parentName}.sol`,
347
- }, [{ lit: timelockArg }]);
348
- c.addOverride('IGovernor', functions.propose);
349
- c.addOverride(parentName, functions._execute);
350
- c.addOverride(parentName, functions._cancel);
351
- c.addOverride(parentName, functions._executor);
352
- c.addOverride(parentName, functions.state);
353
- c.addOverride(parentName, supportsInterface);
337
+ c.addParent(timelockParent, [{ lit: timelockArg }]);
338
+ c.addOverride(timelockParent, functions._queueOperations);
339
+ c.addOverride(timelockParent, functions._executeOperations);
340
+ c.addOverride(timelockParent, functions._cancel);
341
+ c.addOverride(timelockParent, functions._executor);
342
+ c.addOverride(timelockParent, functions.state);
343
+ c.addOverride(timelockParent, functions.proposalNeedsQueuing);
354
344
  }
355
345
 
356
- function addBravo(c: ContractBuilder, { bravo, timelock }: GovernorOptions) {
357
- if (bravo) {
358
- if (timelock === false) {
359
- throw new OptionsError({
360
- timelock: 'GovernorBravo compatibility requires a timelock',
361
- });
362
- }
363
-
364
- c.addParent({
365
- name: 'GovernorCompatibilityBravo',
366
- path: '@openzeppelin/contracts/governance/compatibility/GovernorCompatibilityBravo.sol',
367
- });
368
- c.addOverride('IGovernor', functions.state);
369
- c.addOverride('IGovernor', functions.cancel);
370
- c.addOverride('GovernorCompatibilityBravo', functions.cancel);
371
- c.addOverride('GovernorCompatibilityBravo', functions.propose);
372
- c.addOverride('IERC165', supportsInterface);
346
+ function addStorage(c: ContractBuilder, { storage }: GovernorOptions) {
347
+ if (storage) {
348
+ const GovernorStorage = {
349
+ name: 'GovernorStorage',
350
+ path: '@openzeppelin/contracts/governance/extensions/GovernorStorage.sol',
351
+ };
352
+ c.addParent(GovernorStorage);
353
+ c.addOverride(GovernorStorage, functions._propose);
373
354
  }
374
355
  }
375
356
 
@@ -392,6 +373,14 @@ const functions = defineFunctions({
392
373
  kind: 'public',
393
374
  mutability: 'pure',
394
375
  },
376
+ proposalNeedsQueuing: {
377
+ args: [
378
+ { name: 'proposalId', type: 'uint256' },
379
+ ],
380
+ returns: ['bool'],
381
+ kind: 'public',
382
+ mutability: 'view',
383
+ },
395
384
  quorum: {
396
385
  args: [
397
386
  { name: 'blockNumber', type: 'uint256' },
@@ -416,7 +405,18 @@ const functions = defineFunctions({
416
405
  returns: ['uint256'],
417
406
  kind: 'public',
418
407
  },
419
- _execute: {
408
+ _propose: {
409
+ args: [
410
+ { name: 'targets', type: 'address[] memory' },
411
+ { name: 'values', type: 'uint256[] memory' },
412
+ { name: 'calldatas', type: 'bytes[] memory' },
413
+ { name: 'description', type: 'string memory' },
414
+ { name: 'proposer', type: 'address' },
415
+ ],
416
+ returns: ['uint256'],
417
+ kind: 'internal',
418
+ },
419
+ _queueOperations: {
420
420
  args: [
421
421
  { name: 'proposalId', type: 'uint256' },
422
422
  { name: 'targets', type: 'address[] memory' },
@@ -425,18 +425,19 @@ const functions = defineFunctions({
425
425
  { name: 'descriptionHash', type: 'bytes32' },
426
426
  ],
427
427
  kind: 'internal',
428
+ returns: ['uint48'],
428
429
  },
429
- _cancel: {
430
+ _executeOperations: {
430
431
  args: [
432
+ { name: 'proposalId', type: 'uint256' },
431
433
  { name: 'targets', type: 'address[] memory' },
432
434
  { name: 'values', type: 'uint256[] memory' },
433
435
  { name: 'calldatas', type: 'bytes[] memory' },
434
436
  { name: 'descriptionHash', type: 'bytes32' },
435
437
  ],
436
- returns: ['uint256'],
437
438
  kind: 'internal',
438
439
  },
439
- cancel: {
440
+ _cancel: {
440
441
  args: [
441
442
  { name: 'targets', type: 'address[] memory' },
442
443
  { name: 'values', type: 'uint256[] memory' },
@@ -444,7 +445,7 @@ const functions = defineFunctions({
444
445
  { name: 'descriptionHash', type: 'bytes32' },
445
446
  ],
446
447
  returns: ['uint256'],
447
- kind: 'public',
448
+ kind: 'internal',
448
449
  },
449
450
  state: {
450
451
  args: [
@@ -0,0 +1,5 @@
1
+ import type { ReferencedContract } from "./contract";
2
+
3
+ export function inferTranspiled(c: ReferencedContract): boolean {
4
+ return c.transpiled ?? !/^I[A-Z]/.test(c.name);
5
+ }
package/src/options.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import path from 'path';
2
2
 
3
- import type { Contract } from './contract';
3
+ import type { Contract, ReferencedContract, ParentContract } from './contract';
4
+ import { inferTranspiled } from './infer-transpiled';
4
5
 
5
6
  const upgradeableName = (n: string) => {
6
7
  if (n === 'Initializable') {
@@ -10,36 +11,37 @@ const upgradeableName = (n: string) => {
10
11
  }
11
12
  }
12
13
 
13
- const upgradeableImport = (p: string) => {
14
- const { dir, ext, name } = path.parse(p);
14
+ const upgradeableImport = (p: ParentContract): ParentContract => {
15
+ const { dir, ext, name } = path.parse(p.path);
15
16
  // Use path.posix to get forward slashes
16
- return path.posix.format({
17
- ext,
18
- dir: dir.replace(/^@openzeppelin\/contracts/, '@openzeppelin/contracts-upgradeable'),
19
- name: upgradeableName(name),
20
- });
17
+ return {
18
+ ...p,
19
+ path: path.posix.format({
20
+ ext,
21
+ dir: dir.replace(/^@openzeppelin\/contracts/, '@openzeppelin/contracts-upgradeable'),
22
+ name: upgradeableName(name),
23
+ }),
24
+ }
21
25
  };
22
26
 
23
27
  export interface Options {
24
- transformImport?: (path: string) => string;
28
+ transformImport?: (parent: ParentContract) => ParentContract;
25
29
  }
26
30
 
27
31
  export interface Helpers extends Required<Options> {
28
32
  upgradeable: boolean;
29
- transformName: (name: string) => string;
30
- transformVariable: (code: string) => string;
33
+ transformName: (name: ReferencedContract) => string;
31
34
  }
32
35
 
33
36
  export function withHelpers(contract: Contract, opts: Options = {}): Helpers {
34
- const upgradeable = contract.upgradeable;
35
- const transformName = (n: string) => upgradeable ? upgradeableName(n) : n;
37
+ const contractUpgradeable = contract.upgradeable;
38
+ const transformName = (n: ReferencedContract) => contractUpgradeable && inferTranspiled(n) ? upgradeableName(n.name) : n.name;
36
39
  return {
37
- upgradeable,
40
+ upgradeable: contractUpgradeable,
38
41
  transformName,
39
42
  transformImport: p1 => {
40
- const p2 = upgradeable ? upgradeableImport(p1) : p1;
43
+ const p2 = contractUpgradeable && inferTranspiled(p1) ? upgradeableImport(p1) : p1;
41
44
  return opts.transformImport?.(p2) ?? p2;
42
45
  },
43
- transformVariable: v => v.replace(/[A-Z]\w*(?=\.|$)/, transformName),
44
46
  };
45
47
  }
@@ -4,8 +4,12 @@ import { printContract } from "./print";
4
4
 
5
5
  export function printContractVersioned(contract: Contract): string {
6
6
  return printContract(contract, {
7
- transformImport: p =>
8
- p.replace(/^@openzeppelin\/contracts(-upgradeable)?/, `$&@${contracts.version}`),
7
+ transformImport: p => {
8
+ return {
9
+ ...p,
10
+ path: p.path.replace(/^@openzeppelin\/contracts(-upgradeable)?/, `$&@${contracts.version}`),
11
+ }
12
+ }
9
13
  });
10
14
  }
11
15
 
package/src/print.ts CHANGED
@@ -6,6 +6,7 @@ import { Options, Helpers, withHelpers } from './options';
6
6
  import { formatLines, spaceBetween, Lines } from './utils/format-lines';
7
7
  import { mapValues } from './utils/map-values';
8
8
  import SOLIDITY_VERSION from './solidity-version.json';
9
+ import { inferTranspiled } from './infer-transpiled';
9
10
 
10
11
  export function printContract(contract: Contract, opts?: Options): string {
11
12
  const helpers = withHelpers(contract, opts);
@@ -24,15 +25,14 @@ export function printContract(contract: Contract, opts?: Options): string {
24
25
  `pragma solidity ^${SOLIDITY_VERSION};`,
25
26
  ],
26
27
 
27
- contract.imports.map(p => `import "${helpers.transformImport(p)}";`),
28
+ contract.imports.map(p => `import "${helpers.transformImport(p).path}";`),
28
29
 
29
30
  [
30
31
  ...printNatspecTags(contract.natspecTags),
31
32
  [`contract ${contract.name}`, ...printInheritance(contract, helpers), '{'].join(' '),
32
33
 
33
34
  spaceBetween(
34
- printUsingFor(contract, helpers),
35
- contract.variables.map(helpers.transformVariable),
35
+ contract.variables,
36
36
  printConstructor(contract, helpers),
37
37
  ...fns.code,
38
38
  ...fns.modifiers,
@@ -48,18 +48,12 @@ export function printContract(contract: Contract, opts?: Options): string {
48
48
 
49
49
  function printInheritance(contract: Contract, { transformName }: Helpers): [] | [string] {
50
50
  if (contract.parents.length > 0) {
51
- return ['is ' + contract.parents.map(p => transformName(p.contract.name)).join(', ')];
51
+ return ['is ' + contract.parents.map(p => transformName(p.contract)).join(', ')];
52
52
  } else {
53
53
  return [];
54
54
  }
55
55
  }
56
56
 
57
- function printUsingFor(contract: Contract, { transformName }: Helpers): string[] {
58
- return contract.using.map(
59
- u => `using ${transformName(u.library.name)} for ${transformName(u.usingFor)};`,
60
- );
61
- }
62
-
63
57
  function printConstructor(contract: Contract, helpers: Helpers): Lines[] {
64
58
  const hasParentParams = contract.parents.some(p => p.params.length > 0);
65
59
  const hasConstructorCode = contract.constructorCode.length > 0;
@@ -134,8 +128,9 @@ function sortedFunctions(contract: Contract): SortedFunctions {
134
128
  }
135
129
 
136
130
  function printParentConstructor({ contract, params }: Parent, helpers: Helpers): [] | [string] {
137
- const fn = helpers.upgradeable ? `__${contract.name}_init` : contract.name;
138
- if (helpers.upgradeable || params.length > 0) {
131
+ const useTranspiled = helpers.upgradeable && inferTranspiled(contract);
132
+ const fn = useTranspiled ? `__${contract.name}_init` : contract.name;
133
+ if (useTranspiled || params.length > 0) {
139
134
  return [
140
135
  fn + '(' + params.map(printValue).join(', ') + ')',
141
136
  ];
@@ -231,7 +226,16 @@ function printFunction2(kindedName: string, args: string[], modifiers: string[],
231
226
  }
232
227
 
233
228
  function printArgument(arg: FunctionArgument, { transformName }: Helpers): string {
234
- const type = /^[A-Z]/.test(arg.type) ? transformName(arg.type) : arg.type;
229
+ let type: string;
230
+ if (typeof arg.type === 'string') {
231
+ if (/^[A-Z]/.test(arg.type)) {
232
+ `Type ${arg.type} is not a primitive type. Define it as a ContractReference`;
233
+ }
234
+ type = arg.type;
235
+ } else {
236
+ type = transformName(arg.type);
237
+ }
238
+
235
239
  return [type, arg.name].join(' ');
236
240
  }
237
241
 
@@ -2,10 +2,8 @@ import { promises as fs } from 'fs';
2
2
  import path from 'path';
3
3
  import hre from 'hardhat';
4
4
  import type { BuildInfo } from 'hardhat/types';
5
- import type { SourceUnit } from 'solidity-ast';
6
5
  import { findAll } from 'solidity-ast/utils';
7
6
  import { rimraf } from 'rimraf';
8
- import { promisify } from 'util';
9
7
  import { version } from "@openzeppelin/contracts/package.json";
10
8
 
11
9
  import type { OpenZeppelinContracts } from '../../openzeppelin-contracts';
@@ -11,14 +11,23 @@ export type Access = typeof accessOptions[number];
11
11
  export function setAccessControl(c: ContractBuilder, access: Access) {
12
12
  switch (access) {
13
13
  case 'ownable': {
14
- c.addParent(parents.Ownable);
14
+ if (c.addParent(parents.Ownable, [ {lit: 'initialOwner'} ])) {
15
+ c.addConstructorArgument({
16
+ type: 'address',
17
+ name: 'initialOwner'
18
+ });
19
+ }
15
20
  break;
16
21
  }
17
22
  case 'roles': {
18
23
  if (c.addParent(parents.AccessControl)) {
19
- c.addConstructorCode('_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);');
24
+ c.addConstructorArgument({
25
+ type: 'address',
26
+ name: 'defaultAdmin'
27
+ });
28
+ c.addConstructorCode('_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);');
20
29
  }
21
- c.addOverride(parents.AccessControl.name, supportsInterface);
30
+ c.addOverride(parents.AccessControl, supportsInterface);
22
31
  break;
23
32
  }
24
33
  }
@@ -27,7 +36,7 @@ export function setAccessControl(c: ContractBuilder, access: Access) {
27
36
  /**
28
37
  * Enables access control for the contract and restricts the given function with access control.
29
38
  */
30
- export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, access: Access, role: string) {
39
+ export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, access: Access, roleIdPrefix: string, roleOwner: string | undefined) {
31
40
  if (access === false) {
32
41
  access = 'ownable';
33
42
  }
@@ -40,9 +49,11 @@ export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, acces
40
49
  break;
41
50
  }
42
51
  case 'roles': {
43
- const roleId = role + '_ROLE';
44
- if (c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`)) {
45
- c.addConstructorCode(`_grantRole(${roleId}, msg.sender);`);
52
+ const roleId = roleIdPrefix + '_ROLE';
53
+ const addedConstant = c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`);
54
+ if (roleOwner && addedConstant) {
55
+ c.addConstructorArgument({type: 'address', name: roleOwner});
56
+ c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
46
57
  }
47
58
  c.addModifier(`onlyRole(${roleId})`, fn);
48
59
  break;
@@ -22,12 +22,13 @@ export function setUpgradeable(c: ContractBuilder, upgradeable: Upgradeable, acc
22
22
  case 'transparent': break;
23
23
 
24
24
  case 'uups': {
25
- requireAccessControl(c, functions._authorizeUpgrade, access, 'UPGRADER');
26
- c.addParent({
25
+ requireAccessControl(c, functions._authorizeUpgrade, access, 'UPGRADER', 'upgrader');
26
+ const UUPSUpgradeable = {
27
27
  name: 'UUPSUpgradeable',
28
28
  path: '@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol',
29
- });
30
- c.addOverride('UUPSUpgradeable', functions._authorizeUpgrade);
29
+ };
30
+ c.addParent(UUPSUpgradeable);
31
+ c.addOverride(UUPSUpgradeable, functions._authorizeUpgrade);
31
32
  c.setFunctionBody([], functions._authorizeUpgrade);
32
33
  break;
33
34
  }
@@ -1 +1 @@
1
- "0.8.9"
1
+ "0.8.20"