@openzeppelin/wizard 0.1.0 → 0.1.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.
Files changed (110) hide show
  1. package/README.md +26 -1
  2. package/dist/add-pausable.d.ts.map +1 -1
  3. package/dist/add-pausable.js +2 -2
  4. package/dist/add-pausable.js.map +1 -1
  5. package/dist/api.d.ts +8 -0
  6. package/dist/api.d.ts.map +1 -1
  7. package/dist/api.js +15 -5
  8. package/dist/api.js.map +1 -1
  9. package/dist/build-generic.d.ts +4 -0
  10. package/dist/build-generic.d.ts.map +1 -1
  11. package/dist/build-generic.js +3 -0
  12. package/dist/build-generic.js.map +1 -1
  13. package/dist/common-options.js +2 -2
  14. package/dist/common-options.js.map +1 -1
  15. package/dist/custom.d.ts +11 -0
  16. package/dist/custom.d.ts.map +1 -0
  17. package/dist/custom.js +47 -0
  18. package/dist/custom.js.map +1 -0
  19. package/dist/custom.test.d.ts +2 -0
  20. package/dist/custom.test.d.ts.map +1 -0
  21. package/dist/custom.test.js +70 -0
  22. package/dist/custom.test.js.map +1 -0
  23. package/dist/erc1155.d.ts +2 -0
  24. package/dist/erc1155.d.ts.map +1 -1
  25. package/dist/erc1155.js +16 -7
  26. package/dist/erc1155.js.map +1 -1
  27. package/dist/erc1155.test.js +11 -0
  28. package/dist/erc1155.test.js.map +1 -1
  29. package/dist/erc20.d.ts +1 -0
  30. package/dist/erc20.d.ts.map +1 -1
  31. package/dist/erc20.js +8 -3
  32. package/dist/erc20.js.map +1 -1
  33. package/dist/erc20.test.js +7 -0
  34. package/dist/erc20.test.js.map +1 -1
  35. package/dist/erc721.d.ts +1 -0
  36. package/dist/erc721.d.ts.map +1 -1
  37. package/dist/erc721.js +7 -2
  38. package/dist/erc721.js.map +1 -1
  39. package/dist/erc721.test.js +6 -0
  40. package/dist/erc721.test.js.map +1 -1
  41. package/dist/generate/custom.d.ts +3 -0
  42. package/dist/generate/custom.d.ts.map +1 -0
  43. package/dist/generate/custom.js +20 -0
  44. package/dist/generate/custom.js.map +1 -0
  45. package/dist/generate/erc1155.d.ts.map +1 -1
  46. package/dist/generate/erc1155.js +1 -0
  47. package/dist/generate/erc1155.js.map +1 -1
  48. package/dist/generate/sources.d.ts.map +1 -1
  49. package/dist/generate/sources.js +5 -1
  50. package/dist/generate/sources.js.map +1 -1
  51. package/dist/governor.d.ts +1 -0
  52. package/dist/governor.d.ts.map +1 -1
  53. package/dist/governor.js +7 -1
  54. package/dist/governor.js.map +1 -1
  55. package/dist/governor.test.js +4 -0
  56. package/dist/governor.test.js.map +1 -1
  57. package/dist/index.d.ts +1 -1
  58. package/dist/index.d.ts.map +1 -1
  59. package/dist/index.js +2 -1
  60. package/dist/index.js.map +1 -1
  61. package/dist/kind.js +1 -0
  62. package/dist/kind.js.map +1 -1
  63. package/dist/print.d.ts.map +1 -1
  64. package/dist/print.js +16 -12
  65. package/dist/print.js.map +1 -1
  66. package/dist/set-access-control.d.ts +9 -2
  67. package/dist/set-access-control.d.ts.map +1 -1
  68. package/dist/set-access-control.js +27 -6
  69. package/dist/set-access-control.js.map +1 -1
  70. package/dist/set-upgradeable.d.ts.map +1 -1
  71. package/dist/set-upgradeable.js +1 -1
  72. package/dist/set-upgradeable.js.map +1 -1
  73. package/dist/test.js +30 -1
  74. package/dist/test.js.map +1 -1
  75. package/package.json +3 -3
  76. package/src/add-pausable.ts +3 -3
  77. package/src/api.ts +25 -8
  78. package/src/build-generic.ts +5 -0
  79. package/src/common-options.ts +2 -2
  80. package/src/custom.test.ts +80 -0
  81. package/src/custom.test.ts.md +154 -0
  82. package/src/custom.test.ts.snap +0 -0
  83. package/src/custom.ts +55 -0
  84. package/src/erc1155.test.ts +13 -0
  85. package/src/erc1155.test.ts.md +16 -0
  86. package/src/erc1155.test.ts.snap +0 -0
  87. package/src/erc1155.ts +17 -7
  88. package/src/erc20.test.ts +8 -0
  89. package/src/erc20.ts +8 -4
  90. package/src/erc721.test.ts +7 -0
  91. package/src/erc721.ts +7 -3
  92. package/src/generate/custom.ts +19 -0
  93. package/src/generate/erc1155.ts +1 -0
  94. package/src/generate/sources.ts +6 -1
  95. package/src/governor.test.ts +5 -0
  96. package/src/governor.ts +6 -1
  97. package/src/index.ts +1 -1
  98. package/src/kind.ts +1 -0
  99. package/src/print.ts +17 -12
  100. package/src/set-access-control.ts +27 -4
  101. package/src/set-upgradeable.ts +2 -2
  102. package/src/test.ts +34 -2
  103. package/dist/general.d.ts +0 -8
  104. package/dist/general.d.ts.map +0 -1
  105. package/dist/general.js +0 -22
  106. package/dist/general.js.map +0 -1
  107. package/dist/general.test.d.ts +0 -2
  108. package/dist/general.test.d.ts.map +0 -1
  109. package/dist/general.test.js +0 -42
  110. package/dist/general.test.js.map +0 -1
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
- access: commonDefaults.access,
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
- addSetUri(c, access);
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
- setAccessControl(c, functions.mint, access, 'MINTER');
102
- setAccessControl(c, functions.mintBatch, access, 'MINTER');
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
- setAccessControl(c, functions.setURI, access, 'URI_SETTER');
118
+ requireAccessControl(c, functions.setURI, access, 'URI_SETTER');
109
119
  c.addFunctionCode('_setURI(newuri);', functions.setURI);
110
120
  }
111
121
 
package/src/erc20.test.ts CHANGED
@@ -141,4 +141,12 @@ testAPIEquivalence('erc20 API full upgradeable', {
141
141
 
142
142
  test('erc20 API assert defaults', async t => {
143
143
  t.is(erc20.print(erc20.defaults), erc20.print());
144
+ });
145
+
146
+ test('erc20 API isAccessControlRequired', async t => {
147
+ t.is(erc20.isAccessControlRequired({ mintable: true }), true);
148
+ t.is(erc20.isAccessControlRequired({ pausable: true }), true);
149
+ t.is(erc20.isAccessControlRequired({ snapshots: true }), true);
150
+ t.is(erc20.isAccessControlRequired({ upgradeable: 'uups' }), true);
151
+ t.is(erc20.isAccessControlRequired({ upgradeable: 'transparent' }), false);
144
152
  });
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
- setAccessControl(c, functions.snapshot, access, 'SNAPSHOT');
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
- setAccessControl(c, functions.mint, access, 'MINTER');
165
+ requireAccessControl(c, functions.mint, access, 'MINTER');
162
166
  c.addFunctionCode('_mint(to, amount);', functions.mint);
163
167
  }
164
168
 
@@ -119,4 +119,11 @@ testAPIEquivalence('API full upgradeable', {
119
119
 
120
120
  test('API assert defaults', async t => {
121
121
  t.is(erc721.print(erc721.defaults), erc721.print());
122
+ });
123
+
124
+ test('API isAccessControlRequired', async t => {
125
+ t.is(erc721.isAccessControlRequired({ mintable: true }), true);
126
+ t.is(erc721.isAccessControlRequired({ pausable: true }), true);
127
+ t.is(erc721.isAccessControlRequired({ upgradeable: 'uups' }), true);
128
+ t.is(erc721.isAccessControlRequired({ upgradeable: 'transparent' }), false);
122
129
  });
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
- setAccessControl(c, fn, access, 'MINTER');
157
+ requireAccessControl(c, fn, access, 'MINTER');
154
158
 
155
159
  if (incremental) {
156
160
  c.addUsing({
@@ -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
+ }
@@ -13,6 +13,7 @@ const blueprint = {
13
13
  pausable: booleans,
14
14
  mintable: booleans,
15
15
  supply: booleans,
16
+ updatableUri: booleans,
16
17
  access: accessOptions,
17
18
  upgradeable: upgradeableOptions,
18
19
  info: infoOptions,
@@ -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 {
@@ -117,4 +117,9 @@ testAPIEquivalence('API basic upgradeable', { name: 'CustomGovernor', delay: '2
117
117
 
118
118
  test('API assert defaults', async t => {
119
119
  t.is(governor.print(governor.defaults), governor.print());
120
+ });
121
+
122
+ test('API isAccessControlRequired', async t => {
123
+ t.is(governor.isAccessControlRequired({ upgradeable: 'uups' }), true);
124
+ t.is(governor.isAccessControlRequired({}), false);
120
125
  });
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";
@@ -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
@@ -20,4 +20,4 @@ export { OptionsError } from './error';
20
20
  export type { Kind } from './kind';
21
21
  export { sanitizeKind } from './kind';
22
22
 
23
- export { erc20, erc721, erc1155, governor } from './api';
23
+ export { erc20, erc721, erc1155, governor, custom } from './api';
package/src/kind.ts CHANGED
@@ -18,6 +18,7 @@ function isKind<T>(value: Kind | T): value is Kind {
18
18
  case 'ERC1155':
19
19
  case 'ERC721':
20
20
  case 'Governor':
21
+ case 'Custom':
21
22
  return true;
22
23
 
23
24
  default: {
package/src/print.ts CHANGED
@@ -64,9 +64,9 @@ function printUsingFor(contract: Contract, { transformName }: Helpers): string[]
64
64
  function printConstructor(contract: Contract, helpers: Helpers): Lines[] {
65
65
  const hasParentParams = contract.parents.some(p => p.params.length > 0);
66
66
  const hasConstructorCode = contract.constructorCode.length > 0;
67
- if (hasParentParams || hasConstructorCode) {
68
- const parents = contract.parents
69
- .filter(hasInitializer)
67
+ const parentsWithInitializers = contract.parents.filter(hasInitializer);
68
+ if (hasParentParams || hasConstructorCode || (helpers.upgradeable && parentsWithInitializers.length > 0)) {
69
+ const parents = parentsWithInitializers
70
70
  .flatMap(p => printParentConstructor(p, helpers));
71
71
  const modifiers = helpers.upgradeable ? ['initializer public'] : parents;
72
72
  const args = contract.constructorArgs.map(a => printArgument(a, helpers));
@@ -87,22 +87,27 @@ function printConstructor(contract: Contract, helpers: Helpers): Lines[] {
87
87
  return constructor;
88
88
  } else {
89
89
  return spaceBetween(
90
- [
91
- '/// @custom:oz-upgrades-unsafe-allow constructor',
92
- 'constructor() {',
93
- [
94
- '_disableInitializers();'
95
- ],
96
- '}'
97
- ],
90
+ DISABLE_INITIALIZERS,
98
91
  constructor,
99
92
  );
100
93
  }
101
- } else {
94
+ } else if (!helpers.upgradeable) {
102
95
  return [];
96
+ } else {
97
+ return DISABLE_INITIALIZERS;
103
98
  }
104
99
  }
105
100
 
101
+ const DISABLE_INITIALIZERS =
102
+ [
103
+ '/// @custom:oz-upgrades-unsafe-allow constructor',
104
+ 'constructor() {',
105
+ [
106
+ '_disableInitializers();'
107
+ ],
108
+ '}'
109
+ ];
110
+
106
111
  function hasInitializer(parent: Parent) {
107
112
  // CAUTION
108
113
  // 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
- export function setAccessControl(c: ContractBuilder, fn: BaseFunction, access: Access, role: string) {
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
  }
@@ -1,5 +1,5 @@
1
1
  import type { ContractBuilder } from './contract';
2
- import { Access, setAccessControl } from './set-access-control';
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
- setAccessControl(c, functions._authorizeUpgrade, access, 'UPGRADER');
25
+ requireAccessControl(c, functions._authorizeUpgrade, access, 'UPGRADER');
26
26
  c.addParent({
27
27
  name: 'UUPSUpgradeable',
28
28
  path: '@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol',
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
+ });
package/dist/general.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import { Contract } from './contract';
2
- import { CommonOptions } from './common-options';
3
- export interface GeneralOptions extends CommonOptions {
4
- name: string;
5
- pausable?: boolean;
6
- }
7
- export declare function buildGeneral(opts: GeneralOptions): Contract;
8
- //# sourceMappingURL=general.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,aAAa,EAAsB,MAAM,kBAAkB,CAAC;AAMrE,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,CAc3D"}
package/dist/general.js DELETED
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildGeneral = void 0;
4
- const contract_1 = require("./contract");
5
- const common_options_1 = require("./common-options");
6
- const set_upgradeable_1 = require("./set-upgradeable");
7
- const set_info_1 = require("./set-info");
8
- const set_access_control_1 = require("./set-access-control");
9
- const add_pausable_1 = require("./add-pausable");
10
- function buildGeneral(opts) {
11
- const c = new contract_1.ContractBuilder(opts.name);
12
- const { access, upgradeable, info } = (0, common_options_1.withCommonDefaults)(opts);
13
- if (opts.pausable) {
14
- (0, add_pausable_1.addPausable)(c, access, []);
15
- }
16
- (0, set_access_control_1.setAccessControlForContract)(c, access);
17
- (0, set_upgradeable_1.setUpgradeable)(c, upgradeable, access);
18
- (0, set_info_1.setInfo)(c, info);
19
- return c;
20
- }
21
- exports.buildGeneral = buildGeneral;
22
- //# sourceMappingURL=general.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":";;;AAAA,yCAAuD;AACvD,qDAAqE;AACrE,uDAAmD;AACnD,yCAAqC;AACrC,6DAAmE;AACnE,iDAA6C;AAO7C,SAAgB,YAAY,CAAC,IAAoB;IAC/C,MAAM,CAAC,GAAG,IAAI,0BAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEzC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,IAAA,mCAAkB,EAAC,IAAI,CAAC,CAAC;IAE/D,IAAI,IAAI,CAAC,QAAQ,EAAE;QACjB,IAAA,0BAAW,EAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;KAC5B;IAED,IAAA,gDAA2B,EAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACvC,IAAA,gCAAc,EAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IACvC,IAAA,kBAAO,EAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAEjB,OAAO,CAAC,CAAC;AACX,CAAC;AAdD,oCAcC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=general.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"general.test.d.ts","sourceRoot":"","sources":["../src/general.test.ts"],"names":[],"mappings":""}
@@ -1,42 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const ava_1 = __importDefault(require("ava"));
7
- const general_1 = require("./general");
8
- const print_1 = require("./print");
9
- function testGeneral(title, opts) {
10
- (0, ava_1.default)(title, t => {
11
- const c = (0, general_1.buildGeneral)({
12
- name: 'MyContract',
13
- ...opts,
14
- });
15
- t.snapshot((0, print_1.printContract)(c));
16
- });
17
- }
18
- testGeneral('general', {});
19
- testGeneral('pausable', {
20
- pausable: true,
21
- });
22
- testGeneral('upgradeable transparent', {
23
- upgradeable: 'transparent',
24
- });
25
- testGeneral('upgradeable uups', {
26
- upgradeable: 'uups',
27
- });
28
- testGeneral('access control disabled', {
29
- access: false,
30
- });
31
- testGeneral('access control ownable', {
32
- access: 'ownable',
33
- });
34
- testGeneral('access control roles', {
35
- access: 'roles',
36
- });
37
- testGeneral('upgradeable uups with access control disabled', {
38
- // API should override access to true since it is required for UUPS
39
- access: false,
40
- upgradeable: 'uups',
41
- });
42
- //# sourceMappingURL=general.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"general.test.js","sourceRoot":"","sources":["../src/general.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAGvB,uCAAyD;AACzD,mCAAwC;AAExC,SAAS,WAAW,CAAC,KAAa,EAAE,IAA6B;IAC/D,IAAA,aAAI,EAAC,KAAK,EAAE,CAAC,CAAC,EAAE;QACd,MAAM,CAAC,GAAG,IAAA,sBAAY,EAAC;YACrB,IAAI,EAAE,YAAY;YAClB,GAAG,IAAI;SACR,CAAC,CAAC;QACH,CAAC,CAAC,QAAQ,CAAC,IAAA,qBAAa,EAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AAE3B,WAAW,CAAC,UAAU,EAAE;IACtB,QAAQ,EAAE,IAAI;CACf,CAAC,CAAC;AAEH,WAAW,CAAC,yBAAyB,EAAE;IACrC,WAAW,EAAE,aAAa;CAC3B,CAAC,CAAC;AAEH,WAAW,CAAC,kBAAkB,EAAE;IAC9B,WAAW,EAAE,MAAM;CACpB,CAAC,CAAC;AAEH,WAAW,CAAC,yBAAyB,EAAE;IACrC,MAAM,EAAE,KAAK;CACd,CAAC,CAAC;AAEH,WAAW,CAAC,wBAAwB,EAAE;IACpC,MAAM,EAAE,SAAS;CAClB,CAAC,CAAC;AAEH,WAAW,CAAC,sBAAsB,EAAE;IAClC,MAAM,EAAE,OAAO;CAChB,CAAC,CAAC;AAEH,WAAW,CAAC,+CAA+C,EAAE;IAC3D,mEAAmE;IACnE,MAAM,EAAE,KAAK;IACb,WAAW,EAAE,MAAM;CACpB,CAAC,CAAC"}