@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.
- 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 +1717 -7286
- package/dist/environments/hardhat/package.json +4 -22
- package/dist/environments/hardhat/upgradeable/package-lock.json +2091 -7495
- 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 -52
- 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 +110 -91
- 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 +2 -4
- package/dist/scripts/prepare.js.map +1 -1
- package/dist/set-access-control.d.ts +1 -1
- package/dist/set-access-control.d.ts.map +1 -1
- package/dist/set-access-control.js +18 -7
- 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 +4 -5
- package/src/add-pausable.ts +7 -3
- package/src/contract.ts +17 -15
- package/src/environments/hardhat/package-lock.json +1717 -7286
- package/src/environments/hardhat/package.json +4 -22
- package/src/environments/hardhat/upgradeable/package-lock.json +2091 -7495
- 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 -65
- package/src/generate/erc20.ts +0 -1
- package/src/generate/governor.ts +1 -1
- package/src/governor.ts +116 -102
- 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 +1 -5
- package/src/set-access-control.ts +18 -7
- 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 -26
- 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,41 +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(
|
|
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(
|
|
136
|
-
c.addOverride(
|
|
137
|
-
c.addOverride(
|
|
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
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
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
|
-
|
|
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:
|
|
224
|
+
type: {
|
|
225
|
+
name: 'IVotes',
|
|
226
|
+
transpiled: false,
|
|
227
|
+
},
|
|
241
228
|
name: tokenArg,
|
|
242
229
|
});
|
|
243
230
|
|
|
244
231
|
c.addParent({
|
|
245
|
-
name:
|
|
246
|
-
path: `@openzeppelin/contracts/governance/extensions
|
|
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(
|
|
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
|
-
|
|
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:
|
|
302
|
-
|
|
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:
|
|
306
|
-
|
|
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,
|
|
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
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
c.addOverride(
|
|
348
|
-
c.addOverride(
|
|
349
|
-
c.addOverride(
|
|
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
|
|
356
|
-
if (
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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
|
-
|
|
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' },
|
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,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
|
|
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.
|
|
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
|
|
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,
|
|
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 =
|
|
44
|
-
|
|
45
|
-
|
|
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;
|
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"
|