@openzeppelin/wizard 0.2.3 → 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 +1717 -7286
  10. package/dist/environments/hardhat/package.json +4 -22
  11. package/dist/environments/hardhat/upgradeable/package-lock.json +2091 -7495
  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 -52
  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 +110 -91
  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 +2 -4
  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 +4 -5
  62. package/src/add-pausable.ts +7 -3
  63. package/src/contract.ts +17 -15
  64. package/src/environments/hardhat/package-lock.json +1717 -7286
  65. package/src/environments/hardhat/package.json +4 -22
  66. package/src/environments/hardhat/upgradeable/package-lock.json +2091 -7495
  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 -65
  71. package/src/generate/erc20.ts +0 -1
  72. package/src/generate/governor.ts +1 -1
  73. package/src/governor.ts +116 -102
  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 +1 -5
  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 -26
  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,41 +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);
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);
120
121
  }
121
122
 
122
123
  function addSettings(c: ContractBuilder, allOpts: Required<GovernorOptions>) {
123
124
  if (allOpts.settings) {
125
+ const GovernorSettings = {
126
+ name: 'GovernorSettings',
127
+ path: '@openzeppelin/contracts/governance/extensions/GovernorSettings.sol',
128
+ };
124
129
  c.addParent(
125
- {
126
- name: 'GovernorSettings',
127
- path: '@openzeppelin/contracts/governance/extensions/GovernorSettings.sol',
128
- },
130
+ GovernorSettings,
129
131
  [
130
132
  { value: getVotingDelay(allOpts), note: allOpts.delay },
131
133
  { value: getVotingPeriod(allOpts), note: allOpts.period },
132
134
  { lit: getProposalThreshold(allOpts) },
133
135
  ],
134
136
  );
135
- c.addOverride('GovernorSettings', functions.votingDelay, 'view');
136
- c.addOverride('GovernorSettings', functions.votingPeriod, 'view');
137
- 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');
138
140
  } else {
139
141
  setVotingParameters(c, allOpts);
140
142
  setProposalThreshold(c, allOpts);
@@ -208,42 +210,27 @@ function setProposalThreshold(c: ContractBuilder, opts: Required<GovernorOptions
208
210
  }
209
211
  }
210
212
 
211
- function addCounting(c: ContractBuilder, { bravo }: GovernorOptions) {
212
- if (!bravo) {
213
- c.addParent({
214
- name: 'GovernorCountingSimple',
215
- path: '@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol',
216
- });
217
- }
213
+ function addCounting(c: ContractBuilder) {
214
+ c.addParent({
215
+ name: 'GovernorCountingSimple',
216
+ path: '@openzeppelin/contracts/governance/extensions/GovernorCountingSimple.sol',
217
+ });
218
218
  }
219
219
 
220
- const votesModules = {
221
- erc20votes: {
222
- tokenType: 'IVotes',
223
- parentName: 'GovernorVotes',
224
- },
225
- erc721votes: {
226
- tokenType: 'IVotes',
227
- parentName: 'GovernorVotes',
228
- },
229
- comp: {
230
- tokenType: 'ERC20VotesComp',
231
- parentName: 'GovernorVotesComp',
232
- },
233
- } as const;
234
-
235
- function addVotes(c: ContractBuilder, { votes }: Required<GovernorOptions>) {
220
+ function addVotes(c: ContractBuilder) {
236
221
  const tokenArg = '_token';
237
- const { tokenType, parentName } = votesModules[votes];
238
222
 
239
223
  c.addConstructorArgument({
240
- type: tokenType,
224
+ type: {
225
+ name: 'IVotes',
226
+ transpiled: false,
227
+ },
241
228
  name: tokenArg,
242
229
  });
243
230
 
244
231
  c.addParent({
245
- name: parentName,
246
- path: `@openzeppelin/contracts/governance/extensions/${parentName}.sol`,
232
+ name: 'GovernorVotes',
233
+ path: `@openzeppelin/contracts/governance/extensions/GovernorVotes.sol`,
247
234
  }, [{ lit: tokenArg }]);
248
235
  }
249
236
 
@@ -251,12 +238,6 @@ export const numberPattern = /^(?!$)(\d*)(?:\.(\d+))?(?:e(\d+))?$/;
251
238
 
252
239
  function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
253
240
  if (opts.quorumMode === 'percent') {
254
- if (opts.votes !== 'erc20votes' && opts.votes !== 'erc721votes') {
255
- throw new OptionsError({
256
- quorumPercent: 'Percent-based quorum is only available for ERC20Votes or ERC721Votes',
257
- });
258
- }
259
-
260
241
  if (opts.quorumPercent > 100) {
261
242
  throw new OptionsError({
262
243
  quorumPercent: 'Invalid percentage',
@@ -265,18 +246,20 @@ function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
265
246
 
266
247
  let { quorumFractionNumerator, quorumFractionDenominator } = getQuorumFractionComponents(opts.quorumPercent);
267
248
 
249
+ const GovernorVotesQuorumFraction = {
250
+ name: 'GovernorVotesQuorumFraction',
251
+ path: '@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol',
252
+ };
253
+
268
254
  if (quorumFractionDenominator !== undefined) {
269
- c.addOverride('GovernorVotesQuorumFraction', functions.quorumDenominator);
255
+ c.addOverride(GovernorVotesQuorumFraction, functions.quorumDenominator);
270
256
  c.setFunctionBody([
271
257
  `return ${quorumFractionDenominator};`
272
258
  ], functions.quorumDenominator, 'pure');
273
259
  }
274
260
 
275
- c.addParent({
276
- name: 'GovernorVotesQuorumFraction',
277
- path: '@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol',
278
- }, [quorumFractionNumerator]);
279
- c.addOverride('GovernorVotesQuorumFraction', functions.quorum);
261
+ c.addParent(GovernorVotesQuorumFraction, [quorumFractionNumerator]);
262
+ c.addOverride(GovernorVotesQuorumFraction, functions.quorum);
280
263
  }
281
264
 
282
265
  else if (opts.quorumMode === 'absolute') {
@@ -298,12 +281,23 @@ function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
298
281
 
299
282
  const timelockModules = {
300
283
  openzeppelin: {
301
- timelockType: 'TimelockController',
302
- parentName: 'GovernorTimelockControl',
284
+ timelockType: {
285
+ name: 'TimelockController',
286
+ },
287
+ timelockParent: {
288
+ name: 'GovernorTimelockControl',
289
+ path: `@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol`,
290
+ }
303
291
  },
304
292
  compound: {
305
- timelockType: 'ICompoundTimelock',
306
- 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
+ }
307
301
  },
308
302
  } as const;
309
303
 
@@ -333,40 +327,30 @@ function addTimelock(c: ContractBuilder, { timelock }: Required<GovernorOptions>
333
327
  }
334
328
 
335
329
  const timelockArg = '_timelock';
336
- const { timelockType, parentName } = timelockModules[timelock];
330
+ const { timelockType, timelockParent } = timelockModules[timelock];
337
331
 
338
332
  c.addConstructorArgument({
339
333
  type: timelockType,
340
334
  name: timelockArg,
341
335
  });
342
336
 
343
- c.addParent({
344
- name: parentName,
345
- path: `@openzeppelin/contracts/governance/extensions/${parentName}.sol`,
346
- }, [{ lit: timelockArg }]);
347
- c.addOverride('IGovernor', functions.propose);
348
- c.addOverride(parentName, functions._execute);
349
- c.addOverride(parentName, functions._cancel);
350
- c.addOverride(parentName, functions._executor);
351
- c.addOverride(parentName, functions.state);
352
- 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);
353
344
  }
354
345
 
355
- function addBravo(c: ContractBuilder, { bravo, timelock }: GovernorOptions) {
356
- if (bravo) {
357
- if (timelock === false) {
358
- throw new OptionsError({
359
- timelock: 'GovernorBravo compatibility requires a timelock',
360
- });
361
- }
362
-
363
- c.addParent({
364
- name: 'GovernorCompatibilityBravo',
365
- path: '@openzeppelin/contracts/governance/compatibility/GovernorCompatibilityBravo.sol',
366
- });
367
- c.addOverride('IGovernor', functions.state);
368
- c.addOverride('GovernorCompatibilityBravo', functions.propose);
369
- 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);
370
354
  }
371
355
  }
372
356
 
@@ -389,6 +373,14 @@ const functions = defineFunctions({
389
373
  kind: 'public',
390
374
  mutability: 'pure',
391
375
  },
376
+ proposalNeedsQueuing: {
377
+ args: [
378
+ { name: 'proposalId', type: 'uint256' },
379
+ ],
380
+ returns: ['bool'],
381
+ kind: 'public',
382
+ mutability: 'view',
383
+ },
392
384
  quorum: {
393
385
  args: [
394
386
  { name: 'blockNumber', type: 'uint256' },
@@ -413,7 +405,29 @@ const functions = defineFunctions({
413
405
  returns: ['uint256'],
414
406
  kind: 'public',
415
407
  },
416
- _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
+ args: [
421
+ { name: 'proposalId', type: 'uint256' },
422
+ { name: 'targets', type: 'address[] memory' },
423
+ { name: 'values', type: 'uint256[] memory' },
424
+ { name: 'calldatas', type: 'bytes[] memory' },
425
+ { name: 'descriptionHash', type: 'bytes32' },
426
+ ],
427
+ kind: 'internal',
428
+ returns: ['uint48'],
429
+ },
430
+ _executeOperations: {
417
431
  args: [
418
432
  { name: 'proposalId', type: 'uint256' },
419
433
  { name: 'targets', type: 'address[] memory' },
@@ -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,14 +2,10 @@ 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
- import _rimraf from 'rimraf';
8
- import { promisify } from 'util';
6
+ import { rimraf } from 'rimraf';
9
7
  import { version } from "@openzeppelin/contracts/package.json";
10
8
 
11
- const rimraf = promisify(_rimraf);
12
-
13
9
  import type { OpenZeppelinContracts } from '../../openzeppelin-contracts';
14
10
  import { writeGeneratedSources } from '../generate/sources';
15
11
  import { mapValues } from '../utils/map-values';
@@ -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"