@openzeppelin/wizard 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/add-pausable.d.ts +1 -1
- package/dist/add-pausable.d.ts.map +1 -1
- package/dist/add-pausable.js.map +1 -1
- package/dist/api.d.ts +6 -6
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +7 -7
- package/dist/api.js.map +1 -1
- package/dist/build-generic.d.ts +7 -7
- package/dist/build-generic.d.ts.map +1 -1
- package/dist/build-generic.js +2 -1
- package/dist/build-generic.js.map +1 -1
- package/dist/common-functions.d.ts.map +1 -1
- package/dist/common-functions.js +1 -3
- package/dist/common-functions.js.map +1 -1
- package/dist/common-options.d.ts +3 -3
- package/dist/contract.d.ts +1 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +10 -6
- package/dist/contract.js.map +1 -1
- package/dist/custom.d.ts +2 -2
- package/dist/custom.d.ts.map +1 -1
- package/dist/custom.js.map +1 -1
- package/dist/environments/hardhat/package-lock.json +368 -246
- package/dist/environments/hardhat/upgradeable/package-lock.json +824 -1506
- package/dist/erc1155.d.ts +2 -2
- package/dist/erc1155.d.ts.map +1 -1
- package/dist/erc1155.js +2 -4
- package/dist/erc1155.js.map +1 -1
- package/dist/erc20.d.ts +9 -3
- package/dist/erc20.d.ts.map +1 -1
- package/dist/erc20.js +132 -11
- package/dist/erc20.js.map +1 -1
- package/dist/erc721.d.ts +3 -3
- package/dist/erc721.d.ts.map +1 -1
- package/dist/erc721.js +6 -7
- package/dist/erc721.js.map +1 -1
- package/dist/error.js +1 -1
- package/dist/error.js.map +1 -1
- package/dist/generate/alternatives.d.ts.map +1 -1
- package/dist/generate/alternatives.js.map +1 -1
- package/dist/generate/erc20.d.ts +1 -1
- package/dist/generate/erc20.d.ts.map +1 -1
- package/dist/generate/erc20.js +9 -1
- package/dist/generate/erc20.js.map +1 -1
- package/dist/generate/erc721.js.map +1 -1
- package/dist/generate/governor.d.ts +1 -1
- package/dist/generate/governor.d.ts.map +1 -1
- package/dist/generate/governor.js.map +1 -1
- package/dist/generate/sources.d.ts +1 -1
- package/dist/generate/sources.d.ts.map +1 -1
- package/dist/generate/sources.js +1 -5
- package/dist/generate/sources.js.map +1 -1
- package/dist/generate/stablecoin.d.ts.map +1 -1
- package/dist/generate/stablecoin.js +32 -15
- package/dist/generate/stablecoin.js.map +1 -1
- package/dist/get-imports.d.ts +4 -4
- package/dist/get-imports.js +4 -4
- package/dist/governor.d.ts +5 -5
- package/dist/governor.d.ts.map +1 -1
- package/dist/governor.js +19 -27
- package/dist/governor.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/infer-transpiled.d.ts +1 -1
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js.map +1 -1
- package/dist/print-versioned.d.ts +1 -1
- package/dist/print-versioned.js +1 -1
- package/dist/print-versioned.js.map +1 -1
- package/dist/print.d.ts +1 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +10 -15
- package/dist/print.js.map +1 -1
- package/dist/scripts/prepare.js +4 -2
- 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 +3 -3
- package/dist/set-access-control.js.map +1 -1
- package/dist/set-clock-mode.d.ts +2 -2
- package/dist/set-clock-mode.d.ts.map +1 -1
- package/dist/set-clock-mode.js +1 -1
- package/dist/set-info.d.ts +1 -1
- package/dist/set-info.d.ts.map +1 -1
- package/dist/set-upgradeable.d.ts +2 -2
- package/dist/set-upgradeable.d.ts.map +1 -1
- package/dist/set-upgradeable.js +3 -4
- package/dist/set-upgradeable.js.map +1 -1
- package/dist/stablecoin.d.ts +3 -3
- package/dist/stablecoin.d.ts.map +1 -1
- package/dist/stablecoin.js +8 -18
- package/dist/stablecoin.js.map +1 -1
- package/dist/test.js +1 -1
- package/dist/test.js.map +1 -1
- package/dist/utils/define-functions.d.ts.map +1 -1
- package/dist/utils/define-functions.js +1 -4
- package/dist/utils/define-functions.js.map +1 -1
- package/dist/utils/format-lines.d.ts.map +1 -1
- package/dist/utils/format-lines.js.map +1 -1
- package/dist/utils/map-values.d.ts.map +1 -1
- package/dist/utils/map-values.js +1 -0
- package/dist/utils/map-values.js.map +1 -1
- package/dist/utils/to-identifier.d.ts.map +1 -1
- package/dist/utils/to-identifier.js +3 -2
- package/dist/utils/to-identifier.js.map +1 -1
- package/dist/zip-foundry.d.ts +3 -3
- package/dist/zip-foundry.d.ts.map +1 -1
- package/dist/zip-foundry.js +23 -76
- package/dist/zip-foundry.js.map +1 -1
- package/dist/zip-hardhat.d.ts +3 -3
- package/dist/zip-hardhat.d.ts.map +1 -1
- package/dist/zip-hardhat.js +13 -15
- package/dist/zip-hardhat.js.map +1 -1
- package/package.json +3 -2
- package/src/add-pausable.ts +2 -1
- package/src/api.ts +55 -25
- package/src/build-generic.ts +21 -14
- package/src/common-functions.ts +1 -3
- package/src/common-options.ts +4 -4
- package/src/contract.ts +21 -19
- package/src/custom.ts +4 -3
- package/src/environments/hardhat/package-lock.json +368 -246
- package/src/environments/hardhat/upgradeable/package-lock.json +824 -1506
- package/src/erc1155.ts +8 -7
- package/src/erc20.ts +188 -23
- package/src/erc721.ts +16 -13
- package/src/error.ts +1 -1
- package/src/generate/alternatives.ts +2 -8
- package/src/generate/erc20.ts +10 -3
- package/src/generate/erc721.ts +1 -1
- package/src/generate/governor.ts +2 -1
- package/src/generate/sources.ts +11 -8
- package/src/generate/stablecoin.ts +35 -16
- package/src/get-imports.ts +5 -5
- package/src/governor.ts +56 -58
- package/src/index.ts +2 -2
- package/src/infer-transpiled.ts +2 -2
- package/src/kind.ts +0 -1
- package/src/options.ts +4 -3
- package/src/print-versioned.ts +4 -6
- package/src/print.ts +43 -45
- package/src/scripts/prepare.ts +10 -6
- package/src/set-access-control.ts +15 -9
- package/src/set-clock-mode.ts +5 -5
- package/src/set-info.ts +3 -3
- package/src/set-upgradeable.ts +6 -6
- package/src/stablecoin.ts +23 -27
- package/src/test.ts +6 -5
- package/src/utils/define-functions.ts +3 -12
- package/src/utils/duration.ts +2 -2
- package/src/utils/format-lines.ts +1 -5
- package/src/utils/map-values.ts +2 -4
- package/src/utils/to-identifier.ts +3 -2
- package/src/zip-foundry.ts +40 -102
- package/src/zip-hardhat.ts +24 -30
package/src/governor.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { supportsInterface } from
|
|
2
|
-
import { CommonOptions
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
1
|
+
import { supportsInterface } from './common-functions';
|
|
2
|
+
import type { CommonOptions } from './common-options';
|
|
3
|
+
import { withCommonDefaults, defaults as commonDefaults } from './common-options';
|
|
4
|
+
import type { Contract } from './contract';
|
|
5
|
+
import { ContractBuilder } from './contract';
|
|
6
|
+
import { OptionsError } from './error';
|
|
7
|
+
import { setAccessControl } from './set-access-control';
|
|
8
|
+
import { printContract } from './print';
|
|
9
|
+
import { setInfo } from './set-info';
|
|
10
|
+
import { setUpgradeable } from './set-upgradeable';
|
|
9
11
|
import { defineFunctions } from './utils/define-functions';
|
|
10
|
-
import { durationToBlocks, durationToTimestamp } from
|
|
11
|
-
import { clockModeDefault, type ClockMode } from
|
|
12
|
+
import { durationToBlocks, durationToTimestamp } from './utils/duration';
|
|
13
|
+
import { clockModeDefault, type ClockMode } from './set-clock-mode';
|
|
12
14
|
|
|
13
15
|
export const defaults: Required<GovernorOptions> = {
|
|
14
16
|
name: 'MyGovernor',
|
|
@@ -26,17 +28,17 @@ export const defaults: Required<GovernorOptions> = {
|
|
|
26
28
|
quorumAbsolute: '',
|
|
27
29
|
storage: false,
|
|
28
30
|
settings: true,
|
|
29
|
-
|
|
31
|
+
|
|
30
32
|
access: commonDefaults.access,
|
|
31
33
|
upgradeable: commonDefaults.upgradeable,
|
|
32
|
-
info: commonDefaults.info
|
|
34
|
+
info: commonDefaults.info,
|
|
33
35
|
} as const;
|
|
34
36
|
|
|
35
37
|
export const votesOptions = ['erc20votes', 'erc721votes'] as const;
|
|
36
|
-
export type VotesOptions = typeof votesOptions[number];
|
|
38
|
+
export type VotesOptions = (typeof votesOptions)[number];
|
|
37
39
|
|
|
38
40
|
export const timelockOptions = [false, 'openzeppelin', 'compound'] as const;
|
|
39
|
-
export type TimelockOptions = typeof timelockOptions[number];
|
|
41
|
+
export type TimelockOptions = (typeof timelockOptions)[number];
|
|
40
42
|
|
|
41
43
|
export function printGovernor(opts: GovernorOptions = defaults): string {
|
|
42
44
|
return printContract(buildGovernor(opts));
|
|
@@ -77,7 +79,7 @@ function withDefaults(opts: GovernorOptions): Required<GovernorOptions> {
|
|
|
77
79
|
quorumMode: opts.quorumMode ?? defaults.quorumMode,
|
|
78
80
|
votes: opts.votes ?? defaults.votes,
|
|
79
81
|
clockMode: opts.clockMode ?? defaults.clockMode,
|
|
80
|
-
timelock: opts.timelock ?? defaults.timelock
|
|
82
|
+
timelock: opts.timelock ?? defaults.timelock,
|
|
81
83
|
};
|
|
82
84
|
}
|
|
83
85
|
|
|
@@ -130,14 +132,11 @@ function addSettings(c: ContractBuilder, allOpts: Required<GovernorOptions>) {
|
|
|
130
132
|
name: 'GovernorSettings',
|
|
131
133
|
path: '@openzeppelin/contracts/governance/extensions/GovernorSettings.sol',
|
|
132
134
|
};
|
|
133
|
-
c.addParent(
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
{ lit: getProposalThreshold(allOpts) },
|
|
139
|
-
],
|
|
140
|
-
);
|
|
135
|
+
c.addParent(GovernorSettings, [
|
|
136
|
+
getVotingDelay(allOpts),
|
|
137
|
+
getVotingPeriod(allOpts),
|
|
138
|
+
{ lit: getProposalThreshold(allOpts) },
|
|
139
|
+
]);
|
|
141
140
|
c.addOverride(GovernorSettings, functions.votingDelay, 'view');
|
|
142
141
|
c.addOverride(GovernorSettings, functions.votingPeriod, 'view');
|
|
143
142
|
c.addOverride(GovernorSettings, functions.proposalThreshold, 'view');
|
|
@@ -147,7 +146,7 @@ function addSettings(c: ContractBuilder, allOpts: Required<GovernorOptions>) {
|
|
|
147
146
|
}
|
|
148
147
|
}
|
|
149
148
|
|
|
150
|
-
function getVotingDelay(opts: Required<GovernorOptions>): { lit: string } | { note: string
|
|
149
|
+
function getVotingDelay(opts: Required<GovernorOptions>): { lit: string } | { note: string; value: number } {
|
|
151
150
|
try {
|
|
152
151
|
if (opts.clockMode === 'timestamp') {
|
|
153
152
|
return {
|
|
@@ -156,7 +155,7 @@ function getVotingDelay(opts: Required<GovernorOptions>): { lit: string } | { no
|
|
|
156
155
|
} else {
|
|
157
156
|
return {
|
|
158
157
|
value: durationToBlocks(opts.delay, opts.blockTime),
|
|
159
|
-
note: opts.delay
|
|
158
|
+
note: opts.delay,
|
|
160
159
|
};
|
|
161
160
|
}
|
|
162
161
|
} catch (e) {
|
|
@@ -170,7 +169,7 @@ function getVotingDelay(opts: Required<GovernorOptions>): { lit: string } | { no
|
|
|
170
169
|
}
|
|
171
170
|
}
|
|
172
171
|
|
|
173
|
-
function getVotingPeriod(opts: Required<GovernorOptions>): { lit: string } | { note: string
|
|
172
|
+
function getVotingPeriod(opts: Required<GovernorOptions>): { lit: string } | { note: string; value: number } {
|
|
174
173
|
try {
|
|
175
174
|
if (opts.clockMode === 'timestamp') {
|
|
176
175
|
return {
|
|
@@ -179,7 +178,7 @@ function getVotingPeriod(opts: Required<GovernorOptions>): { lit: string } | { n
|
|
|
179
178
|
} else {
|
|
180
179
|
return {
|
|
181
180
|
value: durationToBlocks(opts.period, opts.blockTime),
|
|
182
|
-
note: opts.period
|
|
181
|
+
note: opts.period,
|
|
183
182
|
};
|
|
184
183
|
}
|
|
185
184
|
} catch (e) {
|
|
@@ -263,10 +262,13 @@ function addVotes(c: ContractBuilder) {
|
|
|
263
262
|
name: tokenArg,
|
|
264
263
|
});
|
|
265
264
|
|
|
266
|
-
c.addParent(
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
265
|
+
c.addParent(
|
|
266
|
+
{
|
|
267
|
+
name: 'GovernorVotes',
|
|
268
|
+
path: `@openzeppelin/contracts/governance/extensions/GovernorVotes.sol`,
|
|
269
|
+
},
|
|
270
|
+
[{ lit: tokenArg }],
|
|
271
|
+
);
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
export const numberPattern = /^(?!$)(\d*)(?:\.(\d+))?(?:e(\d+))?$/;
|
|
@@ -279,7 +281,7 @@ function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
|
|
|
279
281
|
});
|
|
280
282
|
}
|
|
281
283
|
|
|
282
|
-
|
|
284
|
+
const { quorumFractionNumerator, quorumFractionDenominator } = getQuorumFractionComponents(opts.quorumPercent);
|
|
283
285
|
|
|
284
286
|
const GovernorVotesQuorumFraction = {
|
|
285
287
|
name: 'GovernorVotesQuorumFraction',
|
|
@@ -288,29 +290,24 @@ function addQuorum(c: ContractBuilder, opts: Required<GovernorOptions>) {
|
|
|
288
290
|
|
|
289
291
|
if (quorumFractionDenominator !== undefined) {
|
|
290
292
|
c.addOverride(GovernorVotesQuorumFraction, functions.quorumDenominator);
|
|
291
|
-
c.setFunctionBody([
|
|
292
|
-
`return ${quorumFractionDenominator};`
|
|
293
|
-
], functions.quorumDenominator, 'pure');
|
|
293
|
+
c.setFunctionBody([`return ${quorumFractionDenominator};`], functions.quorumDenominator, 'pure');
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
c.addParent(GovernorVotesQuorumFraction, [quorumFractionNumerator]);
|
|
297
297
|
c.addOverride(GovernorVotesQuorumFraction, functions.quorum);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
else if (opts.quorumMode === 'absolute') {
|
|
298
|
+
} else if (opts.quorumMode === 'absolute') {
|
|
301
299
|
if (!numberPattern.test(opts.quorumAbsolute)) {
|
|
302
300
|
throw new OptionsError({
|
|
303
301
|
quorumAbsolute: 'Not a valid number',
|
|
304
302
|
});
|
|
305
303
|
}
|
|
306
304
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
305
|
+
const returnStatement =
|
|
306
|
+
opts.decimals === 0 || opts.votes === 'erc721votes'
|
|
307
|
+
? `return ${opts.quorumAbsolute};`
|
|
308
|
+
: `return ${opts.quorumAbsolute}e${opts.decimals};`;
|
|
310
309
|
|
|
311
|
-
c.setFunctionBody([
|
|
312
|
-
returnStatement,
|
|
313
|
-
], functions.quorum, 'pure');
|
|
310
|
+
c.setFunctionBody([returnStatement], functions.quorum, 'pure');
|
|
314
311
|
}
|
|
315
312
|
}
|
|
316
313
|
|
|
@@ -323,7 +320,7 @@ const timelockModules = {
|
|
|
323
320
|
timelockParent: {
|
|
324
321
|
name: 'GovernorTimelockControl',
|
|
325
322
|
path: `@openzeppelin/contracts/governance/extensions/GovernorTimelockControl.sol`,
|
|
326
|
-
}
|
|
323
|
+
},
|
|
327
324
|
},
|
|
328
325
|
compound: {
|
|
329
326
|
timelockType: {
|
|
@@ -334,20 +331,27 @@ const timelockModules = {
|
|
|
334
331
|
timelockParent: {
|
|
335
332
|
name: 'GovernorTimelockCompound',
|
|
336
333
|
path: `@openzeppelin/contracts/governance/extensions/GovernorTimelockCompound.sol`,
|
|
337
|
-
}
|
|
334
|
+
},
|
|
338
335
|
},
|
|
339
336
|
} as const;
|
|
340
337
|
|
|
341
|
-
function getQuorumFractionComponents(quorumPercent: number): {
|
|
338
|
+
function getQuorumFractionComponents(quorumPercent: number): {
|
|
339
|
+
quorumFractionNumerator: number;
|
|
340
|
+
quorumFractionDenominator: string | undefined;
|
|
341
|
+
} {
|
|
342
342
|
let quorumFractionNumerator = quorumPercent;
|
|
343
343
|
let quorumFractionDenominator = undefined;
|
|
344
344
|
|
|
345
|
-
const quorumPercentSegments = quorumPercent.toString().split(
|
|
345
|
+
const quorumPercentSegments = quorumPercent.toString().split('.');
|
|
346
346
|
if (quorumPercentSegments.length > 2) {
|
|
347
347
|
throw new OptionsError({
|
|
348
348
|
quorumPercent: 'Invalid percentage',
|
|
349
349
|
});
|
|
350
|
-
} else if (
|
|
350
|
+
} else if (
|
|
351
|
+
quorumPercentSegments.length == 2 &&
|
|
352
|
+
quorumPercentSegments[0] !== undefined &&
|
|
353
|
+
quorumPercentSegments[1] !== undefined
|
|
354
|
+
) {
|
|
351
355
|
quorumFractionNumerator = parseInt(quorumPercentSegments[0].concat(quorumPercentSegments[1]));
|
|
352
356
|
const decimals = quorumPercentSegments[1].length;
|
|
353
357
|
quorumFractionDenominator = '100';
|
|
@@ -412,17 +416,13 @@ const functions = defineFunctions({
|
|
|
412
416
|
mutability: 'pure',
|
|
413
417
|
},
|
|
414
418
|
proposalNeedsQueuing: {
|
|
415
|
-
args: [
|
|
416
|
-
{ name: 'proposalId', type: 'uint256' },
|
|
417
|
-
],
|
|
419
|
+
args: [{ name: 'proposalId', type: 'uint256' }],
|
|
418
420
|
returns: ['bool'],
|
|
419
421
|
kind: 'public',
|
|
420
422
|
mutability: 'view',
|
|
421
423
|
},
|
|
422
424
|
quorum: {
|
|
423
|
-
args: [
|
|
424
|
-
{ name: 'blockNumber', type: 'uint256' },
|
|
425
|
-
],
|
|
425
|
+
args: [{ name: 'blockNumber', type: 'uint256' }],
|
|
426
426
|
returns: ['uint256'],
|
|
427
427
|
kind: 'public',
|
|
428
428
|
mutability: 'view',
|
|
@@ -486,9 +486,7 @@ const functions = defineFunctions({
|
|
|
486
486
|
kind: 'internal',
|
|
487
487
|
},
|
|
488
488
|
state: {
|
|
489
|
-
args: [
|
|
490
|
-
{ name: 'proposalId', type: 'uint256' },
|
|
491
|
-
],
|
|
489
|
+
args: [{ name: 'proposalId', type: 'uint256' }],
|
|
492
490
|
returns: ['ProposalState'],
|
|
493
491
|
kind: 'public',
|
|
494
492
|
mutability: 'view',
|
package/src/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ export type { Access } from './set-access-control';
|
|
|
10
10
|
export type { Upgradeable } from './set-upgradeable';
|
|
11
11
|
export type { Info } from './set-info';
|
|
12
12
|
|
|
13
|
-
export { premintPattern } from './erc20';
|
|
13
|
+
export { premintPattern, chainIdPattern } from './erc20';
|
|
14
14
|
export { defaults as infoDefaults } from './set-info';
|
|
15
15
|
|
|
16
16
|
export type { OptionsErrorMessages } from './error';
|
|
@@ -21,4 +21,4 @@ export { sanitizeKind } from './kind';
|
|
|
21
21
|
|
|
22
22
|
export { erc20, erc721, erc1155, stablecoin, realWorldAsset, governor, custom } from './api';
|
|
23
23
|
|
|
24
|
-
export { compatibleContractsSemver } from './utils/version';
|
|
24
|
+
export { compatibleContractsSemver } from './utils/version';
|
package/src/infer-transpiled.ts
CHANGED
package/src/kind.ts
CHANGED
package/src/options.ts
CHANGED
|
@@ -9,7 +9,7 @@ const upgradeableName = (n: string) => {
|
|
|
9
9
|
} else {
|
|
10
10
|
return n.replace(/(Upgradeable)?(?=\.|$)/, 'Upgradeable');
|
|
11
11
|
}
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
|
|
14
14
|
const upgradeableImport = (p: ImportContract): ImportContract => {
|
|
15
15
|
const { dir, ext, name } = path.parse(p.path);
|
|
@@ -22,7 +22,7 @@ const upgradeableImport = (p: ImportContract): ImportContract => {
|
|
|
22
22
|
dir: dir.replace(/^@openzeppelin\/contracts/, '@openzeppelin/contracts-upgradeable'),
|
|
23
23
|
name: upgradeableName(name), // Solidity file name
|
|
24
24
|
}),
|
|
25
|
-
}
|
|
25
|
+
};
|
|
26
26
|
};
|
|
27
27
|
|
|
28
28
|
export interface Options {
|
|
@@ -36,7 +36,8 @@ export interface Helpers extends Required<Options> {
|
|
|
36
36
|
|
|
37
37
|
export function withHelpers(contract: Contract, opts: Options = {}): Helpers {
|
|
38
38
|
const contractUpgradeable = contract.upgradeable;
|
|
39
|
-
const transformName = (n: ReferencedContract) =>
|
|
39
|
+
const transformName = (n: ReferencedContract) =>
|
|
40
|
+
contractUpgradeable && inferTranspiled(n) ? upgradeableName(n.name) : n.name;
|
|
40
41
|
return {
|
|
41
42
|
upgradeable: contractUpgradeable,
|
|
42
43
|
transformName,
|
package/src/print-versioned.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import contracts from '../openzeppelin-contracts';
|
|
2
|
-
import type { Contract } from
|
|
3
|
-
import { printContract } from
|
|
2
|
+
import type { Contract } from './contract';
|
|
3
|
+
import { printContract } from './print';
|
|
4
4
|
|
|
5
5
|
export function printContractVersioned(contract: Contract): string {
|
|
6
6
|
return printContract(contract, {
|
|
@@ -8,9 +8,7 @@ export function printContractVersioned(contract: Contract): string {
|
|
|
8
8
|
return {
|
|
9
9
|
...p,
|
|
10
10
|
path: p.path.replace(/^@openzeppelin\/contracts(-upgradeable)?/, `$&@${contracts.version}`),
|
|
11
|
-
}
|
|
12
|
-
}
|
|
11
|
+
};
|
|
12
|
+
},
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
package/src/print.ts
CHANGED
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import type {
|
|
2
|
+
Contract,
|
|
3
|
+
Parent,
|
|
4
|
+
ContractFunction,
|
|
5
|
+
FunctionArgument,
|
|
6
|
+
Value,
|
|
7
|
+
NatspecTag,
|
|
8
|
+
ImportContract,
|
|
9
|
+
} from './contract';
|
|
10
|
+
import type { Options, Helpers } from './options';
|
|
11
|
+
import { withHelpers } from './options';
|
|
12
|
+
|
|
13
|
+
import type { Lines } from './utils/format-lines';
|
|
14
|
+
import { formatLines, spaceBetween } from './utils/format-lines';
|
|
5
15
|
import { mapValues } from './utils/map-values';
|
|
6
16
|
import SOLIDITY_VERSION from './solidity-version.json';
|
|
7
17
|
import { inferTranspiled } from './infer-transpiled';
|
|
@@ -10,10 +20,7 @@ import { compatibleContractsSemver } from './utils/version';
|
|
|
10
20
|
export function printContract(contract: Contract, opts?: Options): string {
|
|
11
21
|
const helpers = withHelpers(contract, opts);
|
|
12
22
|
|
|
13
|
-
const fns = mapValues(
|
|
14
|
-
sortedFunctions(contract),
|
|
15
|
-
fns => fns.map(fn => printFunction(fn, helpers)),
|
|
16
|
-
);
|
|
23
|
+
const fns = mapValues(sortedFunctions(contract), fns => fns.map(fn => printFunction(fn, helpers)));
|
|
17
24
|
|
|
18
25
|
const hasOverrides = fns.override.some(l => l.length > 0);
|
|
19
26
|
|
|
@@ -59,31 +66,21 @@ function printConstructor(contract: Contract, helpers: Helpers): Lines[] {
|
|
|
59
66
|
const hasConstructorCode = contract.constructorCode.length > 0;
|
|
60
67
|
const parentsWithInitializers = contract.parents.filter(hasInitializer);
|
|
61
68
|
if (hasParentParams || hasConstructorCode || (helpers.upgradeable && parentsWithInitializers.length > 0)) {
|
|
62
|
-
const parents = parentsWithInitializers
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
const args = contract.constructorArgs.map(a => printArgument(a, helpers));
|
|
69
|
+
const parents = parentsWithInitializers.flatMap(p => printParentConstructor(p, helpers));
|
|
70
|
+
const modifiers = helpers.upgradeable ? ['public initializer'] : parents;
|
|
71
|
+
const args = contract.constructorArgs.map(a => printArgument(a, helpers));
|
|
66
72
|
const body = helpers.upgradeable
|
|
67
73
|
? spaceBetween(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
74
|
+
parents.map(p => p + ';'),
|
|
75
|
+
contract.constructorCode,
|
|
76
|
+
)
|
|
71
77
|
: contract.constructorCode;
|
|
72
78
|
const head = helpers.upgradeable ? 'function initialize' : 'constructor';
|
|
73
|
-
const constructor = printFunction2(
|
|
74
|
-
[],
|
|
75
|
-
head,
|
|
76
|
-
args,
|
|
77
|
-
modifiers,
|
|
78
|
-
body,
|
|
79
|
-
);
|
|
79
|
+
const constructor = printFunction2([], head, args, modifiers, body);
|
|
80
80
|
if (!helpers.upgradeable) {
|
|
81
81
|
return constructor;
|
|
82
82
|
} else {
|
|
83
|
-
return spaceBetween(
|
|
84
|
-
DISABLE_INITIALIZERS,
|
|
85
|
-
constructor,
|
|
86
|
-
);
|
|
83
|
+
return spaceBetween(DISABLE_INITIALIZERS, constructor);
|
|
87
84
|
}
|
|
88
85
|
} else if (!helpers.upgradeable) {
|
|
89
86
|
return [];
|
|
@@ -92,14 +89,11 @@ function printConstructor(contract: Contract, helpers: Helpers): Lines[] {
|
|
|
92
89
|
}
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
const DISABLE_INITIALIZERS =
|
|
96
|
-
[
|
|
92
|
+
const DISABLE_INITIALIZERS = [
|
|
97
93
|
'/// @custom:oz-upgrades-unsafe-allow constructor',
|
|
98
94
|
'constructor() {',
|
|
99
|
-
[
|
|
100
|
-
|
|
101
|
-
],
|
|
102
|
-
'}'
|
|
95
|
+
['_disableInitializers();'],
|
|
96
|
+
'}',
|
|
103
97
|
];
|
|
104
98
|
|
|
105
99
|
function hasInitializer(parent: Parent) {
|
|
@@ -132,9 +126,7 @@ function printParentConstructor({ contract, params }: Parent, helpers: Helpers):
|
|
|
132
126
|
const useTranspiled = helpers.upgradeable && inferTranspiled(contract);
|
|
133
127
|
const fn = useTranspiled ? `__${contract.name}_init` : contract.name;
|
|
134
128
|
if (useTranspiled || params.length > 0) {
|
|
135
|
-
return [
|
|
136
|
-
fn + '(' + params.map(printValue).join(', ') + ')',
|
|
137
|
-
];
|
|
129
|
+
return [fn + '(' + params.map(printValue).join(', ') + ')'];
|
|
138
130
|
} else {
|
|
139
131
|
return [];
|
|
140
132
|
}
|
|
@@ -164,13 +156,12 @@ function printFunction(fn: ContractFunction, helpers: Helpers): Lines[] {
|
|
|
164
156
|
const { transformName } = helpers;
|
|
165
157
|
|
|
166
158
|
if (fn.override.size <= 1 && fn.modifiers.length === 0 && fn.code.length === 0 && !fn.final) {
|
|
167
|
-
return []
|
|
159
|
+
return [];
|
|
168
160
|
}
|
|
169
|
-
|
|
170
|
-
const modifiers: string[] = [fn.kind, ...fn.modifiers];
|
|
161
|
+
const modifiers: string[] = [fn.kind];
|
|
171
162
|
|
|
172
163
|
if (fn.mutability !== 'nonpayable') {
|
|
173
|
-
modifiers.
|
|
164
|
+
modifiers.push(fn.mutability);
|
|
174
165
|
}
|
|
175
166
|
|
|
176
167
|
if (fn.override.size === 1) {
|
|
@@ -179,6 +170,8 @@ function printFunction(fn: ContractFunction, helpers: Helpers): Lines[] {
|
|
|
179
170
|
modifiers.push(`override(${[...fn.override].map(transformName).join(', ')})`);
|
|
180
171
|
}
|
|
181
172
|
|
|
173
|
+
modifiers.push(...fn.modifiers);
|
|
174
|
+
|
|
182
175
|
if (fn.returns?.length) {
|
|
183
176
|
modifiers.push(`returns (${fn.returns.join(', ')})`);
|
|
184
177
|
}
|
|
@@ -205,12 +198,16 @@ function printFunction(fn: ContractFunction, helpers: Helpers): Lines[] {
|
|
|
205
198
|
|
|
206
199
|
// generic for functions and constructors
|
|
207
200
|
// kindedName = 'function foo' or 'constructor'
|
|
208
|
-
function printFunction2(
|
|
209
|
-
|
|
201
|
+
function printFunction2(
|
|
202
|
+
comments: string[],
|
|
203
|
+
kindedName: string,
|
|
204
|
+
args: string[],
|
|
205
|
+
modifiers: string[],
|
|
206
|
+
code: Lines[],
|
|
207
|
+
): Lines[] {
|
|
208
|
+
const fn: Lines[] = [...comments];
|
|
210
209
|
|
|
211
|
-
const headingLength = [kindedName, ...args, ...modifiers]
|
|
212
|
-
.map(s => s.length)
|
|
213
|
-
.reduce((a, b) => a + b);
|
|
210
|
+
const headingLength = [kindedName, ...args, ...modifiers].map(s => s.length).reduce((a, b) => a + b);
|
|
214
211
|
|
|
215
212
|
const braces = code.length > 0 ? '{' : '{}';
|
|
216
213
|
|
|
@@ -231,6 +228,7 @@ function printArgument(arg: FunctionArgument, { transformName }: Helpers): strin
|
|
|
231
228
|
let type: string;
|
|
232
229
|
if (typeof arg.type === 'string') {
|
|
233
230
|
if (/^[A-Z]/.test(arg.type)) {
|
|
231
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
234
232
|
`Type ${arg.type} is not a primitive type. Define it as a ContractReference`;
|
|
235
233
|
}
|
|
236
234
|
type = arg.type;
|
|
@@ -260,4 +258,4 @@ function printImports(imports: ImportContract[], helpers: Helpers): string[] {
|
|
|
260
258
|
});
|
|
261
259
|
|
|
262
260
|
return lines;
|
|
263
|
-
}
|
|
261
|
+
}
|
package/src/scripts/prepare.ts
CHANGED
|
@@ -4,7 +4,7 @@ import hre from 'hardhat';
|
|
|
4
4
|
import type { BuildInfo } from 'hardhat/types';
|
|
5
5
|
import { findAll } from 'solidity-ast/utils';
|
|
6
6
|
import { rimraf } from 'rimraf';
|
|
7
|
-
import { version } from
|
|
7
|
+
import { version } from '@openzeppelin/contracts/package.json';
|
|
8
8
|
|
|
9
9
|
import type { OpenZeppelinContracts } from '../../openzeppelin-contracts';
|
|
10
10
|
import { writeGeneratedSources } from '../generate/sources';
|
|
@@ -21,12 +21,13 @@ async function main() {
|
|
|
21
21
|
const sources: Record<string, string> = {};
|
|
22
22
|
|
|
23
23
|
for (const buildInfoPath of await hre.artifacts.getBuildInfoPaths()) {
|
|
24
|
-
const buildInfo: BuildInfo = JSON.parse(
|
|
25
|
-
await fs.readFile(buildInfoPath, 'utf8'),
|
|
26
|
-
);
|
|
24
|
+
const buildInfo: BuildInfo = JSON.parse(await fs.readFile(buildInfoPath, 'utf8'));
|
|
27
25
|
|
|
28
26
|
for (const [sourceFile, { ast }] of Object.entries(buildInfo.output.sources)) {
|
|
29
|
-
if (
|
|
27
|
+
if (
|
|
28
|
+
sourceFile.startsWith('@openzeppelin/contracts') ||
|
|
29
|
+
sourceFile.startsWith('@openzeppelin/community-contracts')
|
|
30
|
+
) {
|
|
30
31
|
const sourceDependencies = (dependencies[sourceFile] ??= new Set());
|
|
31
32
|
for (const imp of findAll('ImportDirective', ast)) {
|
|
32
33
|
sourceDependencies.add(imp.absolutePath);
|
|
@@ -35,7 +36,10 @@ async function main() {
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
for (const [sourceFile, { content }] of Object.entries(buildInfo.input.sources)) {
|
|
38
|
-
if (
|
|
39
|
+
if (
|
|
40
|
+
sourceFile.startsWith('@openzeppelin/contracts') ||
|
|
41
|
+
sourceFile.startsWith('@openzeppelin/community-contracts')
|
|
42
|
+
) {
|
|
39
43
|
sources[sourceFile] = content;
|
|
40
44
|
}
|
|
41
45
|
}
|
|
@@ -3,7 +3,7 @@ import { supportsInterface } from './common-functions';
|
|
|
3
3
|
|
|
4
4
|
export const accessOptions = [false, 'ownable', 'roles', 'managed'] as const;
|
|
5
5
|
|
|
6
|
-
export type Access = typeof accessOptions[number];
|
|
6
|
+
export type Access = (typeof accessOptions)[number];
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Sets access control for the contract by adding inheritance.
|
|
@@ -11,10 +11,10 @@ export type Access = typeof accessOptions[number];
|
|
|
11
11
|
export function setAccessControl(c: ContractBuilder, access: Access) {
|
|
12
12
|
switch (access) {
|
|
13
13
|
case 'ownable': {
|
|
14
|
-
if (c.addParent(parents.Ownable, [
|
|
14
|
+
if (c.addParent(parents.Ownable, [{ lit: 'initialOwner' }])) {
|
|
15
15
|
c.addConstructorArgument({
|
|
16
16
|
type: 'address',
|
|
17
|
-
name: 'initialOwner'
|
|
17
|
+
name: 'initialOwner',
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
break;
|
|
@@ -23,7 +23,7 @@ export function setAccessControl(c: ContractBuilder, access: Access) {
|
|
|
23
23
|
if (c.addParent(parents.AccessControl)) {
|
|
24
24
|
c.addConstructorArgument({
|
|
25
25
|
type: 'address',
|
|
26
|
-
name: 'defaultAdmin'
|
|
26
|
+
name: 'defaultAdmin',
|
|
27
27
|
});
|
|
28
28
|
c.addConstructorCode('_grantRole(DEFAULT_ADMIN_ROLE, defaultAdmin);');
|
|
29
29
|
}
|
|
@@ -31,10 +31,10 @@ export function setAccessControl(c: ContractBuilder, access: Access) {
|
|
|
31
31
|
break;
|
|
32
32
|
}
|
|
33
33
|
case 'managed': {
|
|
34
|
-
if (c.addParent(parents.AccessManaged, [
|
|
34
|
+
if (c.addParent(parents.AccessManaged, [{ lit: 'initialAuthority' }])) {
|
|
35
35
|
c.addConstructorArgument({
|
|
36
36
|
type: 'address',
|
|
37
|
-
name: 'initialAuthority'
|
|
37
|
+
name: 'initialAuthority',
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
40
|
break;
|
|
@@ -45,11 +45,17 @@ export function setAccessControl(c: ContractBuilder, access: Access) {
|
|
|
45
45
|
/**
|
|
46
46
|
* Enables access control for the contract and restricts the given function with access control.
|
|
47
47
|
*/
|
|
48
|
-
export function requireAccessControl(
|
|
48
|
+
export function requireAccessControl(
|
|
49
|
+
c: ContractBuilder,
|
|
50
|
+
fn: BaseFunction,
|
|
51
|
+
access: Access,
|
|
52
|
+
roleIdPrefix: string,
|
|
53
|
+
roleOwner: string | undefined,
|
|
54
|
+
) {
|
|
49
55
|
if (access === false) {
|
|
50
56
|
access = 'ownable';
|
|
51
57
|
}
|
|
52
|
-
|
|
58
|
+
|
|
53
59
|
setAccessControl(c, access);
|
|
54
60
|
|
|
55
61
|
switch (access) {
|
|
@@ -61,7 +67,7 @@ export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, acces
|
|
|
61
67
|
const roleId = roleIdPrefix + '_ROLE';
|
|
62
68
|
const addedConstant = c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`);
|
|
63
69
|
if (roleOwner && addedConstant) {
|
|
64
|
-
c.addConstructorArgument({type: 'address', name: roleOwner});
|
|
70
|
+
c.addConstructorArgument({ type: 'address', name: roleOwner });
|
|
65
71
|
c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
|
|
66
72
|
}
|
|
67
73
|
c.addModifier(`onlyRole(${roleId})`, fn);
|
package/src/set-clock-mode.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ContractBuilder, ReferencedContract } from
|
|
2
|
-
import { defineFunctions } from
|
|
1
|
+
import type { ContractBuilder, ReferencedContract } from './contract';
|
|
2
|
+
import { defineFunctions } from './utils/define-functions';
|
|
3
3
|
|
|
4
4
|
export const clockModeOptions = ['blocknumber', 'timestamp'] as const;
|
|
5
5
|
export const clockModeDefault = 'blocknumber' as const;
|
|
6
|
-
export type ClockMode = typeof clockModeOptions[number];
|
|
6
|
+
export type ClockMode = (typeof clockModeOptions)[number];
|
|
7
7
|
|
|
8
8
|
const functions = defineFunctions({
|
|
9
9
|
clock: {
|
|
@@ -18,7 +18,7 @@ const functions = defineFunctions({
|
|
|
18
18
|
args: [],
|
|
19
19
|
returns: ['string memory'],
|
|
20
20
|
mutability: 'pure' as const,
|
|
21
|
-
}
|
|
21
|
+
},
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
export function setClockMode(c: ContractBuilder, parent: ReferencedContract, votes: ClockMode) {
|
|
@@ -30,4 +30,4 @@ export function setClockMode(c: ContractBuilder, parent: ReferencedContract, vot
|
|
|
30
30
|
c.addOverride(parent, functions.CLOCK_MODE);
|
|
31
31
|
c.setFunctionBody(['return "mode=timestamp";'], functions.CLOCK_MODE);
|
|
32
32
|
}
|
|
33
|
-
}
|
|
33
|
+
}
|
package/src/set-info.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ContractBuilder } from
|
|
1
|
+
import type { ContractBuilder } from './contract';
|
|
2
2
|
|
|
3
3
|
export const TAG_SECURITY_CONTACT = `@custom:security-contact`;
|
|
4
4
|
|
|
@@ -9,11 +9,11 @@ export const defaults: Info = { license: 'MIT' };
|
|
|
9
9
|
export type Info = {
|
|
10
10
|
securityContact?: string;
|
|
11
11
|
license?: string;
|
|
12
|
-
}
|
|
12
|
+
};
|
|
13
13
|
|
|
14
14
|
export function setInfo(c: ContractBuilder, info: Info) {
|
|
15
15
|
const { securityContact, license } = info;
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
if (securityContact) {
|
|
18
18
|
c.addNatspecTag(TAG_SECURITY_CONTACT, securityContact);
|
|
19
19
|
}
|