@openzeppelin/wizard 0.1.0 → 0.2.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/README.md +28 -1
- package/dist/add-pausable.d.ts.map +1 -1
- package/dist/add-pausable.js +2 -2
- package/dist/add-pausable.js.map +1 -1
- package/dist/api.d.ts +8 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +15 -5
- package/dist/api.js.map +1 -1
- package/dist/build-generic.d.ts +4 -0
- package/dist/build-generic.d.ts.map +1 -1
- package/dist/build-generic.js +3 -0
- package/dist/build-generic.js.map +1 -1
- package/dist/common-options.js +2 -2
- package/dist/common-options.js.map +1 -1
- package/dist/custom.d.ts +11 -0
- package/dist/custom.d.ts.map +1 -0
- package/dist/custom.js +47 -0
- package/dist/custom.js.map +1 -0
- package/dist/environments/hardhat/package-lock.json +14913 -0
- package/dist/environments/hardhat/package.json +34 -0
- package/dist/environments/hardhat/upgradeable/package-lock.json +15333 -0
- package/dist/environments/hardhat/upgradeable/package.json +35 -0
- package/dist/erc1155.d.ts +2 -0
- package/dist/erc1155.d.ts.map +1 -1
- package/dist/erc1155.js +16 -7
- package/dist/erc1155.js.map +1 -1
- package/dist/erc20.d.ts +1 -0
- package/dist/erc20.d.ts.map +1 -1
- package/dist/erc20.js +8 -3
- package/dist/erc20.js.map +1 -1
- package/dist/erc721.d.ts +1 -0
- package/dist/erc721.d.ts.map +1 -1
- package/dist/erc721.js +9 -2
- package/dist/erc721.js.map +1 -1
- package/dist/generate/custom.d.ts +3 -0
- package/dist/generate/custom.d.ts.map +1 -0
- package/dist/generate/custom.js +20 -0
- package/dist/generate/custom.js.map +1 -0
- package/dist/generate/erc1155.d.ts.map +1 -1
- package/dist/generate/erc1155.js +1 -0
- package/dist/generate/erc1155.js.map +1 -1
- package/dist/generate/sources.d.ts.map +1 -1
- package/dist/generate/sources.js +5 -1
- package/dist/generate/sources.js.map +1 -1
- package/dist/governor.d.ts +1 -0
- package/dist/governor.d.ts.map +1 -1
- package/dist/governor.js +8 -2
- 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/kind.js +1 -0
- package/dist/kind.js.map +1 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +21 -14
- package/dist/print.js.map +1 -1
- package/dist/set-access-control.d.ts +9 -2
- package/dist/set-access-control.d.ts.map +1 -1
- package/dist/set-access-control.js +27 -6
- package/dist/set-access-control.js.map +1 -1
- package/dist/set-upgradeable.d.ts.map +1 -1
- package/dist/set-upgradeable.js +1 -1
- package/dist/set-upgradeable.js.map +1 -1
- package/dist/solidity-version.json +1 -0
- package/dist/test.js +30 -1
- package/dist/test.js.map +1 -1
- package/dist/utils/format-lines.d.ts +1 -0
- package/dist/utils/format-lines.d.ts.map +1 -1
- package/dist/utils/format-lines.js +9 -5
- package/dist/utils/format-lines.js.map +1 -1
- package/dist/zip-hardhat.d.ts +5 -0
- package/dist/zip-hardhat.d.ts.map +1 -0
- package/dist/zip-hardhat.js +187 -0
- package/dist/zip-hardhat.js.map +1 -0
- package/dist/zip.js +1 -1
- package/dist/zip.js.map +1 -1
- package/package.json +8 -6
- package/src/add-pausable.ts +3 -3
- package/src/api.ts +25 -8
- package/src/build-generic.ts +5 -0
- package/src/common-options.ts +2 -2
- package/src/custom.ts +55 -0
- package/src/environments/hardhat/package-lock.json +14913 -0
- package/src/environments/hardhat/package.json +34 -0
- package/src/environments/hardhat/upgradeable/package-lock.json +15333 -0
- package/src/environments/hardhat/upgradeable/package.json +35 -0
- package/src/erc1155.ts +17 -7
- package/src/erc20.ts +8 -4
- package/src/erc721.ts +9 -3
- package/src/generate/custom.ts +19 -0
- package/src/generate/erc1155.ts +1 -0
- package/src/generate/sources.ts +6 -1
- package/src/governor.ts +7 -2
- package/src/index.ts +1 -1
- package/src/kind.ts +1 -0
- package/src/print.ts +18 -14
- package/src/set-access-control.ts +27 -4
- package/src/set-upgradeable.ts +2 -2
- package/src/solidity-version.json +1 -0
- package/src/test.ts +34 -2
- package/src/utils/format-lines.ts +8 -3
- package/src/zip-hardhat.ts +186 -0
- package/src/zip.ts +1 -1
- package/dist/contract.test.d.ts +0 -2
- package/dist/contract.test.d.ts.map +0 -1
- package/dist/contract.test.js +0 -147
- package/dist/contract.test.js.map +0 -1
- package/dist/erc1155.test.d.ts +0 -2
- package/dist/erc1155.test.d.ts.map +0 -1
- package/dist/erc1155.test.js +0 -80
- package/dist/erc1155.test.js.map +0 -1
- package/dist/erc20.test.d.ts +0 -2
- package/dist/erc20.test.d.ts.map +0 -1
- package/dist/erc20.test.js +0 -126
- package/dist/erc20.test.js.map +0 -1
- package/dist/erc721.test.d.ts +0 -2
- package/dist/erc721.test.d.ts.map +0 -1
- package/dist/erc721.test.js +0 -106
- package/dist/erc721.test.js.map +0 -1
- package/dist/general.d.ts +0 -8
- package/dist/general.d.ts.map +0 -1
- package/dist/general.js +0 -22
- package/dist/general.js.map +0 -1
- package/dist/general.test.d.ts +0 -2
- package/dist/general.test.d.ts.map +0 -1
- package/dist/general.test.js +0 -42
- package/dist/general.test.js.map +0 -1
- package/dist/governor.test.d.ts +0 -2
- package/dist/governor.test.d.ts.map +0 -1
- package/dist/governor.test.js +0 -104
- package/dist/governor.test.js.map +0 -1
- package/dist/utils/to-identifier.test.d.ts +0 -2
- package/dist/utils/to-identifier.test.d.ts.map +0 -1
- package/dist/utils/to-identifier.test.js +0 -21
- package/dist/utils/to-identifier.test.js.map +0 -1
- package/dist/zip.test.d.ts +0 -2
- package/dist/zip.test.d.ts.map +0 -1
- package/dist/zip.test.js +0 -37
- package/dist/zip.test.js.map +0 -1
- package/src/contract.test.ts +0 -164
- package/src/contract.test.ts.md +0 -272
- package/src/contract.test.ts.snap +0 -0
- package/src/erc1155.test.ts +0 -90
- package/src/erc1155.test.ts.md +0 -416
- package/src/erc1155.test.ts.snap +0 -0
- package/src/erc20.test.ts +0 -144
- package/src/erc20.test.ts.md +0 -571
- package/src/erc20.test.ts.snap +0 -0
- package/src/erc721.test.ts +0 -122
- package/src/erc721.test.ts.md +0 -517
- package/src/erc721.test.ts.snap +0 -0
- package/src/governor.test.ts +0 -120
- package/src/governor.test.ts.md +0 -1419
- package/src/governor.test.ts.snap +0 -0
- package/src/utils/to-identifier.test.ts +0 -20
- package/src/zip.test.ts +0 -35
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hardhat-sample",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "hardhat test"
|
|
8
|
+
},
|
|
9
|
+
"author": "",
|
|
10
|
+
"license": "ISC",
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@openzeppelin/contracts-upgradeable": "^4.8.0",
|
|
13
|
+
"@openzeppelin/hardhat-upgrades": "^1.21.0",
|
|
14
|
+
"@ethersproject/abi": "^5.7.0",
|
|
15
|
+
"@ethersproject/providers": "^5.7.2",
|
|
16
|
+
"@nomicfoundation/hardhat-chai-matchers": "^1.0.4",
|
|
17
|
+
"@nomicfoundation/hardhat-network-helpers": "^1.0.6",
|
|
18
|
+
"@nomicfoundation/hardhat-toolbox": "^2.0.0",
|
|
19
|
+
"@nomiclabs/hardhat-ethers": "^2.2.0",
|
|
20
|
+
"@nomiclabs/hardhat-etherscan": "^3.1.1",
|
|
21
|
+
"@typechain/ethers-v5": "^10.1.1",
|
|
22
|
+
"@typechain/hardhat": "^6.1.4",
|
|
23
|
+
"@types/chai": "^4.3.3",
|
|
24
|
+
"@types/mocha": "^9.1.1",
|
|
25
|
+
"@types/node": "^18.11.6",
|
|
26
|
+
"chai": "^4.3.6",
|
|
27
|
+
"ethers": "^5.7.2",
|
|
28
|
+
"hardhat": "^2.12.0",
|
|
29
|
+
"hardhat-gas-reporter": "^1.0.9",
|
|
30
|
+
"solidity-coverage": "^0.8.2",
|
|
31
|
+
"ts-node": "^10.9.1",
|
|
32
|
+
"typechain": "^8.1.1",
|
|
33
|
+
"typescript": "^4.8.4"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/erc1155.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Contract, ContractBuilder } from './contract';
|
|
2
|
-
import { Access, setAccessControl } from './set-access-control';
|
|
2
|
+
import { Access, setAccessControl, requireAccessControl } from './set-access-control';
|
|
3
3
|
import { addPausable } from './add-pausable';
|
|
4
4
|
import { supportsInterface } from './common-functions';
|
|
5
5
|
import { defineFunctions } from './utils/define-functions';
|
|
@@ -15,6 +15,7 @@ export interface ERC1155Options extends CommonOptions {
|
|
|
15
15
|
pausable?: boolean;
|
|
16
16
|
mintable?: boolean;
|
|
17
17
|
supply?: boolean;
|
|
18
|
+
updatableUri?: boolean;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export const defaults: Required<ERC1155Options> = {
|
|
@@ -24,7 +25,8 @@ export const defaults: Required<ERC1155Options> = {
|
|
|
24
25
|
pausable: false,
|
|
25
26
|
mintable: false,
|
|
26
27
|
supply: false,
|
|
27
|
-
|
|
28
|
+
updatableUri: true,
|
|
29
|
+
access: false,
|
|
28
30
|
upgradeable: commonDefaults.upgradeable,
|
|
29
31
|
info: commonDefaults.info
|
|
30
32
|
} as const;
|
|
@@ -37,6 +39,7 @@ function withDefaults(opts: ERC1155Options): Required<ERC1155Options> {
|
|
|
37
39
|
pausable: opts.pausable ?? defaults.pausable,
|
|
38
40
|
mintable: opts.mintable ?? defaults.mintable,
|
|
39
41
|
supply: opts.supply ?? defaults.supply,
|
|
42
|
+
updatableUri: opts.updatableUri ?? defaults.updatableUri,
|
|
40
43
|
};
|
|
41
44
|
}
|
|
42
45
|
|
|
@@ -44,6 +47,10 @@ export function printERC1155(opts: ERC1155Options = defaults): string {
|
|
|
44
47
|
return printContract(buildERC1155(opts));
|
|
45
48
|
}
|
|
46
49
|
|
|
50
|
+
export function isAccessControlRequired(opts: Partial<ERC1155Options>): boolean {
|
|
51
|
+
return opts.mintable || opts.pausable || opts.updatableUri !== false || opts.upgradeable === 'uups';
|
|
52
|
+
}
|
|
53
|
+
|
|
47
54
|
export function buildERC1155(opts: ERC1155Options): Contract {
|
|
48
55
|
const allOpts = withDefaults(opts);
|
|
49
56
|
|
|
@@ -52,7 +59,10 @@ export function buildERC1155(opts: ERC1155Options): Contract {
|
|
|
52
59
|
const { access, upgradeable, info } = allOpts;
|
|
53
60
|
|
|
54
61
|
addBase(c, allOpts.uri);
|
|
55
|
-
|
|
62
|
+
|
|
63
|
+
if (allOpts.updatableUri) {
|
|
64
|
+
addSetUri(c, access);
|
|
65
|
+
}
|
|
56
66
|
|
|
57
67
|
if (allOpts.pausable) {
|
|
58
68
|
addPausable(c, access, [functions._beforeTokenTransfer]);
|
|
@@ -70,8 +80,8 @@ export function buildERC1155(opts: ERC1155Options): Contract {
|
|
|
70
80
|
addSupply(c);
|
|
71
81
|
}
|
|
72
82
|
|
|
83
|
+
setAccessControl(c, access);
|
|
73
84
|
setUpgradeable(c, upgradeable, access);
|
|
74
|
-
|
|
75
85
|
setInfo(c, info);
|
|
76
86
|
|
|
77
87
|
return c;
|
|
@@ -98,14 +108,14 @@ function addBurnable(c: ContractBuilder) {
|
|
|
98
108
|
}
|
|
99
109
|
|
|
100
110
|
function addMintable(c: ContractBuilder, access: Access) {
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
requireAccessControl(c, functions.mint, access, 'MINTER');
|
|
112
|
+
requireAccessControl(c, functions.mintBatch, access, 'MINTER');
|
|
103
113
|
c.addFunctionCode('_mint(account, id, amount, data);', functions.mint);
|
|
104
114
|
c.addFunctionCode('_mintBatch(to, ids, amounts, data);', functions.mintBatch);
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
function addSetUri(c: ContractBuilder, access: Access) {
|
|
108
|
-
|
|
118
|
+
requireAccessControl(c, functions.setURI, access, 'URI_SETTER');
|
|
109
119
|
c.addFunctionCode('_setURI(newuri);', functions.setURI);
|
|
110
120
|
}
|
|
111
121
|
|
package/src/erc20.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Contract, ContractBuilder } from './contract';
|
|
2
|
-
import { Access, setAccessControl } from './set-access-control';
|
|
2
|
+
import { Access, setAccessControl, requireAccessControl } from './set-access-control';
|
|
3
3
|
import { addPausable } from './add-pausable';
|
|
4
4
|
import { defineFunctions } from './utils/define-functions';
|
|
5
5
|
import { CommonOptions, withCommonDefaults, defaults as commonDefaults } from './common-options';
|
|
@@ -55,6 +55,10 @@ export function printERC20(opts: ERC20Options = defaults): string {
|
|
|
55
55
|
return printContract(buildERC20(opts));
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
export function isAccessControlRequired(opts: Partial<ERC20Options>): boolean {
|
|
59
|
+
return opts.mintable || opts.pausable || opts.snapshots || opts.upgradeable === 'uups';
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
export function buildERC20(opts: ERC20Options): Contract {
|
|
59
63
|
const allOpts = withDefaults(opts);
|
|
60
64
|
|
|
@@ -97,8 +101,8 @@ export function buildERC20(opts: ERC20Options): Contract {
|
|
|
97
101
|
addFlashMint(c);
|
|
98
102
|
}
|
|
99
103
|
|
|
104
|
+
setAccessControl(c, access);
|
|
100
105
|
setUpgradeable(c, upgradeable, access);
|
|
101
|
-
|
|
102
106
|
setInfo(c, info);
|
|
103
107
|
|
|
104
108
|
return c;
|
|
@@ -134,7 +138,7 @@ function addSnapshot(c: ContractBuilder, access: Access) {
|
|
|
134
138
|
|
|
135
139
|
c.addOverride('ERC20Snapshot', functions._beforeTokenTransfer);
|
|
136
140
|
|
|
137
|
-
|
|
141
|
+
requireAccessControl(c, functions.snapshot, access, 'SNAPSHOT');
|
|
138
142
|
c.addFunctionCode('_snapshot();', functions.snapshot);
|
|
139
143
|
}
|
|
140
144
|
|
|
@@ -158,7 +162,7 @@ function addPremint(c: ContractBuilder, amount: string) {
|
|
|
158
162
|
}
|
|
159
163
|
|
|
160
164
|
function addMintable(c: ContractBuilder, access: Access) {
|
|
161
|
-
|
|
165
|
+
requireAccessControl(c, functions.mint, access, 'MINTER');
|
|
162
166
|
c.addFunctionCode('_mint(to, amount);', functions.mint);
|
|
163
167
|
}
|
|
164
168
|
|
package/src/erc721.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Contract, ContractBuilder } from './contract';
|
|
2
|
-
import { Access, setAccessControl } from './set-access-control';
|
|
2
|
+
import { Access, setAccessControl, requireAccessControl } from './set-access-control';
|
|
3
3
|
import { addPausable } from './add-pausable';
|
|
4
4
|
import { supportsInterface } from './common-functions';
|
|
5
5
|
import { defineFunctions } from './utils/define-functions';
|
|
@@ -56,6 +56,10 @@ export function printERC721(opts: ERC721Options = defaults): string {
|
|
|
56
56
|
return printContract(buildERC721(opts));
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
export function isAccessControlRequired(opts: Partial<ERC721Options>): boolean {
|
|
60
|
+
return opts.mintable || opts.pausable || opts.upgradeable === 'uups';
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
export function buildERC721(opts: ERC721Options): Contract {
|
|
60
64
|
const allOpts = withDefaults(opts);
|
|
61
65
|
|
|
@@ -93,8 +97,8 @@ export function buildERC721(opts: ERC721Options): Contract {
|
|
|
93
97
|
addVotes(c, allOpts.name);
|
|
94
98
|
}
|
|
95
99
|
|
|
100
|
+
setAccessControl(c, access);
|
|
96
101
|
setUpgradeable(c, upgradeable, access);
|
|
97
|
-
|
|
98
102
|
setInfo(c, info);
|
|
99
103
|
|
|
100
104
|
return c;
|
|
@@ -150,7 +154,7 @@ function addBurnable(c: ContractBuilder) {
|
|
|
150
154
|
|
|
151
155
|
function addMintable(c: ContractBuilder, access: Access, incremental = false, uriStorage = false) {
|
|
152
156
|
const fn = getMintFunction(incremental, uriStorage);
|
|
153
|
-
|
|
157
|
+
requireAccessControl(c, fn, access, 'MINTER');
|
|
154
158
|
|
|
155
159
|
if (incremental) {
|
|
156
160
|
c.addUsing({
|
|
@@ -193,6 +197,7 @@ const functions = defineFunctions({
|
|
|
193
197
|
{ name: 'from', type: 'address' },
|
|
194
198
|
{ name: 'to', type: 'address' },
|
|
195
199
|
{ name: 'tokenId', type: 'uint256' },
|
|
200
|
+
{ name: 'batchSize', type: 'uint256' },
|
|
196
201
|
],
|
|
197
202
|
},
|
|
198
203
|
|
|
@@ -202,6 +207,7 @@ const functions = defineFunctions({
|
|
|
202
207
|
{ name: 'from', type: 'address' },
|
|
203
208
|
{ name: 'to', type: 'address' },
|
|
204
209
|
{ name: 'tokenId', type: 'uint256' },
|
|
210
|
+
{ name: 'batchSize', type: 'uint256' },
|
|
205
211
|
],
|
|
206
212
|
},
|
|
207
213
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { CustomOptions } from '../custom';
|
|
2
|
+
import { accessOptions } from '../set-access-control';
|
|
3
|
+
import { infoOptions } from '../set-info';
|
|
4
|
+
import { upgradeableOptions } from '../set-upgradeable';
|
|
5
|
+
import { generateAlternatives } from './alternatives';
|
|
6
|
+
|
|
7
|
+
const booleans = [true, false];
|
|
8
|
+
|
|
9
|
+
const blueprint = {
|
|
10
|
+
name: ['MyContract'],
|
|
11
|
+
pausable: booleans,
|
|
12
|
+
access: accessOptions,
|
|
13
|
+
upgradeable: upgradeableOptions,
|
|
14
|
+
info: infoOptions,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function* generateCustomOptions(): Generator<Required<CustomOptions>> {
|
|
18
|
+
yield* generateAlternatives(blueprint);
|
|
19
|
+
}
|
package/src/generate/erc1155.ts
CHANGED
package/src/generate/sources.ts
CHANGED
|
@@ -5,9 +5,10 @@ import crypto from 'crypto';
|
|
|
5
5
|
import { generateERC20Options } from './erc20';
|
|
6
6
|
import { generateERC721Options } from './erc721';
|
|
7
7
|
import { generateERC1155Options } from './erc1155';
|
|
8
|
+
import { generateGovernorOptions } from './governor';
|
|
9
|
+
import { generateCustomOptions } from './custom';
|
|
8
10
|
import { buildGeneric, GenericOptions } from '../build-generic';
|
|
9
11
|
import { printContract } from '../print';
|
|
10
|
-
import { generateGovernorOptions } from './governor';
|
|
11
12
|
import { OptionsError } from '../error';
|
|
12
13
|
import { findCover } from '../utils/find-cover';
|
|
13
14
|
import type { Contract } from '../contract';
|
|
@@ -30,6 +31,10 @@ export function* generateOptions(): Generator<GenericOptions> {
|
|
|
30
31
|
for (const kindOpts of generateGovernorOptions()) {
|
|
31
32
|
yield { kind: 'Governor', ...kindOpts };
|
|
32
33
|
}
|
|
34
|
+
|
|
35
|
+
for (const kindOpts of generateCustomOptions()) {
|
|
36
|
+
yield { kind: 'Custom', ...kindOpts };
|
|
37
|
+
}
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
interface GeneratedContract {
|
package/src/governor.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { supportsInterface } from "./common-functions";
|
|
|
2
2
|
import { CommonOptions, withCommonDefaults, defaults as commonDefaults } from "./common-options";
|
|
3
3
|
import { ContractBuilder, Contract } from "./contract";
|
|
4
4
|
import { OptionsError } from "./error";
|
|
5
|
+
import { setAccessControl } from "./set-access-control";
|
|
5
6
|
import { printContract } from "./print";
|
|
6
7
|
import { setInfo } from "./set-info";
|
|
7
8
|
import { setUpgradeable } from "./set-upgradeable";
|
|
@@ -15,7 +16,7 @@ export const defaults: Required<GovernorOptions> = {
|
|
|
15
16
|
|
|
16
17
|
votes: 'erc20votes',
|
|
17
18
|
timelock: 'openzeppelin',
|
|
18
|
-
blockTime:
|
|
19
|
+
blockTime: 12,
|
|
19
20
|
decimals: 18,
|
|
20
21
|
proposalThreshold: '0',
|
|
21
22
|
quorumMode: 'percent',
|
|
@@ -55,6 +56,10 @@ export interface GovernorOptions extends CommonOptions {
|
|
|
55
56
|
settings?: boolean;
|
|
56
57
|
}
|
|
57
58
|
|
|
59
|
+
export function isAccessControlRequired(opts: Partial<GovernorOptions>): boolean {
|
|
60
|
+
return opts.upgradeable === 'uups';
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
function withDefaults(opts: GovernorOptions): Required<GovernorOptions> {
|
|
59
64
|
return {
|
|
60
65
|
...opts,
|
|
@@ -87,8 +92,8 @@ export function buildGovernor(opts: GovernorOptions): Contract {
|
|
|
87
92
|
addQuorum(c, allOpts);
|
|
88
93
|
addTimelock(c, allOpts);
|
|
89
94
|
|
|
95
|
+
setAccessControl(c, allOpts.access);
|
|
90
96
|
setUpgradeable(c, allOpts.upgradeable, allOpts.access);
|
|
91
|
-
|
|
92
97
|
setInfo(c, allOpts.info);
|
|
93
98
|
|
|
94
99
|
return c;
|
package/src/index.ts
CHANGED
package/src/kind.ts
CHANGED
package/src/print.ts
CHANGED
|
@@ -5,8 +5,7 @@ import { Options, Helpers, withHelpers } from './options';
|
|
|
5
5
|
|
|
6
6
|
import { formatLines, spaceBetween, Lines } from './utils/format-lines';
|
|
7
7
|
import { mapValues } from './utils/map-values';
|
|
8
|
-
|
|
9
|
-
const SOLIDITY_VERSION = '0.8.4';
|
|
8
|
+
import SOLIDITY_VERSION from './solidity-version.json';
|
|
10
9
|
|
|
11
10
|
export function printContract(contract: Contract, opts?: Options): string {
|
|
12
11
|
const helpers = withHelpers(contract, opts);
|
|
@@ -64,9 +63,9 @@ function printUsingFor(contract: Contract, { transformName }: Helpers): string[]
|
|
|
64
63
|
function printConstructor(contract: Contract, helpers: Helpers): Lines[] {
|
|
65
64
|
const hasParentParams = contract.parents.some(p => p.params.length > 0);
|
|
66
65
|
const hasConstructorCode = contract.constructorCode.length > 0;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
const parentsWithInitializers = contract.parents.filter(hasInitializer);
|
|
67
|
+
if (hasParentParams || hasConstructorCode || (helpers.upgradeable && parentsWithInitializers.length > 0)) {
|
|
68
|
+
const parents = parentsWithInitializers
|
|
70
69
|
.flatMap(p => printParentConstructor(p, helpers));
|
|
71
70
|
const modifiers = helpers.upgradeable ? ['initializer public'] : parents;
|
|
72
71
|
const args = contract.constructorArgs.map(a => printArgument(a, helpers));
|
|
@@ -87,22 +86,27 @@ function printConstructor(contract: Contract, helpers: Helpers): Lines[] {
|
|
|
87
86
|
return constructor;
|
|
88
87
|
} else {
|
|
89
88
|
return spaceBetween(
|
|
90
|
-
|
|
91
|
-
'/// @custom:oz-upgrades-unsafe-allow constructor',
|
|
92
|
-
'constructor() {',
|
|
93
|
-
[
|
|
94
|
-
'_disableInitializers();'
|
|
95
|
-
],
|
|
96
|
-
'}'
|
|
97
|
-
],
|
|
89
|
+
DISABLE_INITIALIZERS,
|
|
98
90
|
constructor,
|
|
99
91
|
);
|
|
100
92
|
}
|
|
101
|
-
} else {
|
|
93
|
+
} else if (!helpers.upgradeable) {
|
|
102
94
|
return [];
|
|
95
|
+
} else {
|
|
96
|
+
return DISABLE_INITIALIZERS;
|
|
103
97
|
}
|
|
104
98
|
}
|
|
105
99
|
|
|
100
|
+
const DISABLE_INITIALIZERS =
|
|
101
|
+
[
|
|
102
|
+
'/// @custom:oz-upgrades-unsafe-allow constructor',
|
|
103
|
+
'constructor() {',
|
|
104
|
+
[
|
|
105
|
+
'_disableInitializers();'
|
|
106
|
+
],
|
|
107
|
+
'}'
|
|
108
|
+
];
|
|
109
|
+
|
|
106
110
|
function hasInitializer(parent: Parent) {
|
|
107
111
|
// CAUTION
|
|
108
112
|
// This list is validated by compilation of SafetyCheck.sol.
|
|
@@ -1,23 +1,46 @@
|
|
|
1
1
|
import type { ContractBuilder, BaseFunction } from './contract';
|
|
2
2
|
import { supportsInterface } from './common-functions';
|
|
3
3
|
|
|
4
|
-
export const accessOptions = ['ownable', 'roles'] as const;
|
|
4
|
+
export const accessOptions = [false, 'ownable', 'roles'] as const;
|
|
5
5
|
|
|
6
6
|
export type Access = typeof accessOptions[number];
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Sets access control for the contract by adding inheritance.
|
|
10
|
+
*/
|
|
11
|
+
export function setAccessControl(c: ContractBuilder, access: Access) {
|
|
9
12
|
switch (access) {
|
|
10
13
|
case 'ownable': {
|
|
11
14
|
c.addParent(parents.Ownable);
|
|
12
|
-
c.addModifier('onlyOwner', fn);
|
|
13
15
|
break;
|
|
14
16
|
}
|
|
15
17
|
case 'roles': {
|
|
16
|
-
const roleId = role + '_ROLE';
|
|
17
18
|
if (c.addParent(parents.AccessControl)) {
|
|
18
19
|
c.addConstructorCode('_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);');
|
|
19
20
|
}
|
|
20
21
|
c.addOverride(parents.AccessControl.name, supportsInterface);
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Enables access control for the contract and restricts the given function with access control.
|
|
29
|
+
*/
|
|
30
|
+
export function requireAccessControl(c: ContractBuilder, fn: BaseFunction, access: Access, role: string) {
|
|
31
|
+
if (access === false) {
|
|
32
|
+
access = 'ownable';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
setAccessControl(c, access);
|
|
36
|
+
|
|
37
|
+
switch (access) {
|
|
38
|
+
case 'ownable': {
|
|
39
|
+
c.addModifier('onlyOwner', fn);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
case 'roles': {
|
|
43
|
+
const roleId = role + '_ROLE';
|
|
21
44
|
if (c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`)) {
|
|
22
45
|
c.addConstructorCode(`_grantRole(${roleId}, msg.sender);`);
|
|
23
46
|
}
|
package/src/set-upgradeable.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ContractBuilder } from './contract';
|
|
2
|
-
import { Access,
|
|
2
|
+
import { Access, requireAccessControl } from './set-access-control';
|
|
3
3
|
import { defineFunctions } from './utils/define-functions';
|
|
4
4
|
|
|
5
5
|
export const upgradeableOptions = [false, 'transparent', 'uups'] as const;
|
|
@@ -22,7 +22,7 @@ export function setUpgradeable(c: ContractBuilder, upgradeable: Upgradeable, acc
|
|
|
22
22
|
case 'transparent': break;
|
|
23
23
|
|
|
24
24
|
case 'uups': {
|
|
25
|
-
|
|
25
|
+
requireAccessControl(c, functions._authorizeUpgrade, access, 'UPGRADER');
|
|
26
26
|
c.addParent({
|
|
27
27
|
name: 'UUPSUpgradeable',
|
|
28
28
|
path: '@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"0.8.9"
|
package/src/test.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import hre from 'hardhat';
|
|
3
|
-
import { promisify } from 'util';
|
|
4
3
|
import path from 'path';
|
|
5
4
|
|
|
6
|
-
import { writeGeneratedSources } from './generate/sources';
|
|
5
|
+
import { generateSources, writeGeneratedSources } from './generate/sources';
|
|
6
|
+
import type { GenericOptions } from './build-generic';
|
|
7
|
+
import { custom, erc1155, erc20, erc721, governor } from './api';
|
|
7
8
|
|
|
8
9
|
test('result compiles', async t => {
|
|
9
10
|
const generatedSourcesPath = path.join(hre.config.paths.sources, 'generated');
|
|
@@ -19,3 +20,34 @@ test('result compiles', async t => {
|
|
|
19
20
|
await hre.run('compile');
|
|
20
21
|
t.pass();
|
|
21
22
|
});
|
|
23
|
+
|
|
24
|
+
function isAccessControlRequired(opts: GenericOptions) {
|
|
25
|
+
switch(opts.kind) {
|
|
26
|
+
case 'ERC20':
|
|
27
|
+
return erc20.isAccessControlRequired(opts);
|
|
28
|
+
case 'ERC721':
|
|
29
|
+
return erc721.isAccessControlRequired(opts);
|
|
30
|
+
case 'ERC1155':
|
|
31
|
+
return erc1155.isAccessControlRequired(opts);
|
|
32
|
+
case 'Governor':
|
|
33
|
+
return governor.isAccessControlRequired(opts);
|
|
34
|
+
case 'Custom':
|
|
35
|
+
return custom.isAccessControlRequired(opts);
|
|
36
|
+
default:
|
|
37
|
+
throw new Error("No such kind");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
test('is access control required', async t => {
|
|
42
|
+
for (const contract of generateSources('all')) {
|
|
43
|
+
const regexOwnable = /import.*Ownable(Upgradeable)?.sol.*/gm;
|
|
44
|
+
|
|
45
|
+
if (!contract.options.access) {
|
|
46
|
+
if (isAccessControlRequired(contract.options)) {
|
|
47
|
+
t.regex(contract.source, regexOwnable, JSON.stringify(contract.options));
|
|
48
|
+
} else {
|
|
49
|
+
t.notRegex(contract.source, regexOwnable, JSON.stringify(contract.options));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
});
|
|
@@ -5,20 +5,25 @@ export type Lines = string | typeof whitespace | Lines[];
|
|
|
5
5
|
const whitespace = Symbol('whitespace');
|
|
6
6
|
|
|
7
7
|
export function formatLines(...lines: Lines[]): string {
|
|
8
|
-
return
|
|
8
|
+
return formatLinesWithSpaces(4, ...lines);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function formatLinesWithSpaces(spacesPerIndent: number, ...lines: Lines[]): string {
|
|
12
|
+
return [...indentEach(0, lines, spacesPerIndent)].join('\n') + '\n';
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
function* indentEach(
|
|
12
16
|
indent: number,
|
|
13
17
|
lines: Lines[],
|
|
18
|
+
spacesPerIndent: number,
|
|
14
19
|
): Generator<string | typeof whitespace> {
|
|
15
20
|
for (const line of lines) {
|
|
16
21
|
if (line === whitespace) {
|
|
17
22
|
yield '';
|
|
18
23
|
} else if (Array.isArray(line)) {
|
|
19
|
-
yield* indentEach(indent + 1, line);
|
|
24
|
+
yield* indentEach(indent + 1, line, spacesPerIndent);
|
|
20
25
|
} else {
|
|
21
|
-
yield '
|
|
26
|
+
yield ' '.repeat(indent * spacesPerIndent) + line;
|
|
22
27
|
}
|
|
23
28
|
}
|
|
24
29
|
}
|