@openzeppelin/wizard 0.3.0 → 0.4.1
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/dist/add-pausable.d.ts +1 -0
- package/dist/add-pausable.d.ts.map +1 -1
- package/dist/add-pausable.js +9 -5
- package/dist/add-pausable.js.map +1 -1
- package/dist/contract.d.ts +13 -9
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +5 -5
- package/dist/contract.js.map +1 -1
- package/dist/environments/hardhat/package-lock.json +1488 -7247
- package/dist/environments/hardhat/package.json +4 -22
- package/dist/environments/hardhat/upgradeable/package-lock.json +1674 -7722
- package/dist/environments/hardhat/upgradeable/package.json +5 -22
- package/dist/erc1155.js +24 -15
- package/dist/erc1155.js.map +1 -1
- package/dist/erc20.d.ts +0 -1
- package/dist/erc20.d.ts.map +1 -1
- package/dist/erc20.js +45 -62
- package/dist/erc20.js.map +1 -1
- package/dist/erc721.js +54 -53
- package/dist/erc721.js.map +1 -1
- package/dist/generate/erc20.d.ts.map +1 -1
- package/dist/generate/erc20.js +0 -1
- package/dist/generate/erc20.js.map +1 -1
- package/dist/generate/governor.js +1 -1
- package/dist/generate/governor.js.map +1 -1
- package/dist/governor.d.ts +2 -2
- package/dist/governor.d.ts.map +1 -1
- package/dist/governor.js +104 -98
- package/dist/governor.js.map +1 -1
- package/dist/infer-transpiled.d.ts +3 -0
- package/dist/infer-transpiled.d.ts.map +1 -0
- package/dist/infer-transpiled.js +9 -0
- package/dist/infer-transpiled.js.map +1 -0
- package/dist/options.d.ts +3 -4
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +14 -11
- package/dist/options.js.map +1 -1
- package/dist/print-versioned.d.ts.map +1 -1
- package/dist/print-versioned.js +6 -1
- package/dist/print-versioned.js.map +1 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +17 -9
- package/dist/print.js.map +1 -1
- package/dist/scripts/prepare.js +0 -1
- package/dist/scripts/prepare.js.map +1 -1
- package/dist/set-access-control.d.ts +2 -2
- package/dist/set-access-control.d.ts.map +1 -1
- package/dist/set-access-control.js +36 -8
- package/dist/set-access-control.js.map +1 -1
- package/dist/set-upgradeable.d.ts.map +1 -1
- package/dist/set-upgradeable.js +5 -4
- package/dist/set-upgradeable.js.map +1 -1
- package/dist/solidity-version.json +1 -1
- package/dist/zip-foundry.d.ts +5 -0
- package/dist/zip-foundry.d.ts.map +1 -0
- package/dist/zip-foundry.js +224 -0
- package/dist/zip-foundry.js.map +1 -0
- package/dist/zip-hardhat.d.ts.map +1 -1
- package/dist/zip-hardhat.js +36 -11
- package/dist/zip-hardhat.js.map +1 -1
- package/package.json +3 -4
- package/src/add-pausable.ts +7 -3
- package/src/contract.ts +17 -15
- package/src/environments/hardhat/package-lock.json +1488 -7247
- package/src/environments/hardhat/package.json +4 -22
- package/src/environments/hardhat/upgradeable/package-lock.json +1674 -7722
- package/src/environments/hardhat/upgradeable/package.json +5 -22
- package/src/erc1155.ts +30 -23
- package/src/erc20.ts +46 -67
- package/src/erc721.ts +64 -66
- package/src/generate/erc20.ts +0 -1
- package/src/generate/governor.ts +1 -1
- package/src/governor.ts +110 -109
- package/src/infer-transpiled.ts +5 -0
- package/src/options.ts +18 -16
- package/src/print-versioned.ts +6 -2
- package/src/print.ts +17 -13
- package/src/scripts/prepare.ts +0 -2
- package/src/set-access-control.ts +36 -8
- package/src/set-upgradeable.ts +5 -4
- package/src/solidity-version.json +1 -1
- package/src/zip-foundry.ts +259 -0
- package/src/zip-hardhat.ts +39 -11
- package/CHANGELOG.md +0 -30
- package/dist/zip.d.ts +0 -4
- package/dist/zip.d.ts.map +0 -1
- package/dist/zip.js +0 -48
- package/dist/zip.js.map +0 -1
- package/src/.DS_Store +0 -0
- package/src/environments/.DS_Store +0 -0
- package/src/environments/hardhat/.DS_Store +0 -0
- 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
|
|
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
|
-
|
|
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'
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
90
|
-
|
|
91
|
-
addVotes(c
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
);
|
|
110
|
-
c.addOverride(
|
|
111
|
-
c.addOverride(
|
|
112
|
-
c.addOverride(
|
|
113
|
-
c.addOverride(
|
|
114
|
-
c.addOverride(
|
|
115
|
-
c.addOverride(
|
|
116
|
-
c.addOverride(
|
|
117
|
-
c.addOverride(
|
|
118
|
-
c.addOverride(
|
|
119
|
-
c.addOverride(
|
|
120
|
-
c.addOverride(
|
|
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(
|
|
137
|
-
c.addOverride(
|
|
138
|
-
c.addOverride(
|
|
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
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
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
|
-
|
|
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:
|
|
224
|
+
type: {
|
|
225
|
+
name: 'IVotes',
|
|
226
|
+
transpiled: false,
|
|
227
|
+
},
|
|
242
228
|
name: tokenArg,
|
|
243
229
|
});
|
|
244
230
|
|
|
245
231
|
c.addParent({
|
|
246
|
-
name:
|
|
247
|
-
path: `@openzeppelin/contracts/governance/extensions
|
|
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(
|
|
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
|
-
|
|
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:
|
|
303
|
-
|
|
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:
|
|
307
|
-
|
|
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,
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
c.addOverride(
|
|
349
|
-
c.addOverride(
|
|
350
|
-
c.addOverride(
|
|
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
|
|
357
|
-
if (
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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: '
|
|
448
|
+
kind: 'internal',
|
|
448
449
|
},
|
|
449
450
|
state: {
|
|
450
451
|
args: [
|
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:
|
|
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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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?: (
|
|
28
|
+
transformImport?: (parent: ParentContract) => ParentContract;
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
export interface Helpers extends Required<Options> {
|
|
28
32
|
upgradeable: boolean;
|
|
29
|
-
transformName: (name:
|
|
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
|
|
35
|
-
const transformName = (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 =
|
|
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
|
}
|
package/src/print-versioned.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
138
|
-
|
|
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
|
-
|
|
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
|
|
package/src/scripts/prepare.ts
CHANGED
|
@@ -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';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ContractBuilder, BaseFunction } from './contract';
|
|
2
2
|
import { supportsInterface } from './common-functions';
|
|
3
3
|
|
|
4
|
-
export const accessOptions = [false, 'ownable', 'roles'] as const;
|
|
4
|
+
export const accessOptions = [false, 'ownable', 'roles', 'managed'] as const;
|
|
5
5
|
|
|
6
6
|
export type Access = typeof accessOptions[number];
|
|
7
7
|
|
|
@@ -11,14 +11,32 @@ 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.
|
|
24
|
+
c.addConstructorArgument({
|
|
25
|
+
type: 'address',
|
|
26
|
+
name: 'defaultAdmin'
|
|
27
|
+
});
|
|
28
|
+
c.addConstructorCode('_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);');
|
|
29
|
+
}
|
|
30
|
+
c.addOverride(parents.AccessControl, supportsInterface);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
case 'managed': {
|
|
34
|
+
if (c.addParent(parents.AccessManaged, [ {lit: 'initialAuthority'} ])) {
|
|
35
|
+
c.addConstructorArgument({
|
|
36
|
+
type: 'address',
|
|
37
|
+
name: 'initialAuthority'
|
|
38
|
+
});
|
|
20
39
|
}
|
|
21
|
-
c.addOverride(parents.AccessControl.name, supportsInterface);
|
|
22
40
|
break;
|
|
23
41
|
}
|
|
24
42
|
}
|
|
@@ -27,7 +45,7 @@ export function setAccessControl(c: ContractBuilder, access: Access) {
|
|
|
27
45
|
/**
|
|
28
46
|
* Enables access control for the contract and restricts the given function with access control.
|
|
29
47
|
*/
|
|
30
|
-
export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, access: Access,
|
|
48
|
+
export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, access: Access, roleIdPrefix: string, roleOwner: string | undefined) {
|
|
31
49
|
if (access === false) {
|
|
32
50
|
access = 'ownable';
|
|
33
51
|
}
|
|
@@ -40,13 +58,19 @@ export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, acces
|
|
|
40
58
|
break;
|
|
41
59
|
}
|
|
42
60
|
case 'roles': {
|
|
43
|
-
const roleId =
|
|
44
|
-
|
|
45
|
-
|
|
61
|
+
const roleId = roleIdPrefix + '_ROLE';
|
|
62
|
+
const addedConstant = c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`);
|
|
63
|
+
if (roleOwner && addedConstant) {
|
|
64
|
+
c.addConstructorArgument({type: 'address', name: roleOwner});
|
|
65
|
+
c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
|
|
46
66
|
}
|
|
47
67
|
c.addModifier(`onlyRole(${roleId})`, fn);
|
|
48
68
|
break;
|
|
49
69
|
}
|
|
70
|
+
case 'managed': {
|
|
71
|
+
c.addModifier('restricted', fn);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
50
74
|
}
|
|
51
75
|
}
|
|
52
76
|
|
|
@@ -59,4 +83,8 @@ const parents = {
|
|
|
59
83
|
name: 'AccessControl',
|
|
60
84
|
path: '@openzeppelin/contracts/access/AccessControl.sol',
|
|
61
85
|
},
|
|
86
|
+
AccessManaged: {
|
|
87
|
+
name: 'AccessManaged',
|
|
88
|
+
path: '@openzeppelin/contracts/access/manager/AccessManaged.sol',
|
|
89
|
+
},
|
|
62
90
|
};
|
package/src/set-upgradeable.ts
CHANGED
|
@@ -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
|
-
|
|
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.
|
|
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.
|
|
1
|
+
"0.8.20"
|