@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/set-upgradeable.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { ContractBuilder } from './contract';
|
|
2
|
-
import { Access
|
|
2
|
+
import type { Access } from './set-access-control';
|
|
3
|
+
import { requireAccessControl } from './set-access-control';
|
|
3
4
|
import { defineFunctions } from './utils/define-functions';
|
|
4
5
|
|
|
5
6
|
export const upgradeableOptions = [false, 'transparent', 'uups'] as const;
|
|
6
7
|
|
|
7
|
-
export type Upgradeable = typeof upgradeableOptions[number];
|
|
8
|
+
export type Upgradeable = (typeof upgradeableOptions)[number];
|
|
8
9
|
|
|
9
10
|
export function setUpgradeable(c: ContractBuilder, upgradeable: Upgradeable, access: Access) {
|
|
10
11
|
if (upgradeable === false) {
|
|
@@ -19,7 +20,8 @@ export function setUpgradeable(c: ContractBuilder, upgradeable: Upgradeable, acc
|
|
|
19
20
|
});
|
|
20
21
|
|
|
21
22
|
switch (upgradeable) {
|
|
22
|
-
case 'transparent':
|
|
23
|
+
case 'transparent':
|
|
24
|
+
break;
|
|
23
25
|
|
|
24
26
|
case 'uups': {
|
|
25
27
|
requireAccessControl(c, functions._authorizeUpgrade, access, 'UPGRADER', 'upgrader');
|
|
@@ -42,9 +44,7 @@ export function setUpgradeable(c: ContractBuilder, upgradeable: Upgradeable, acc
|
|
|
42
44
|
|
|
43
45
|
const functions = defineFunctions({
|
|
44
46
|
_authorizeUpgrade: {
|
|
45
|
-
args: [
|
|
46
|
-
{ name: 'newImplementation', type: 'address' },
|
|
47
|
-
],
|
|
47
|
+
args: [{ name: 'newImplementation', type: 'address' }],
|
|
48
48
|
kind: 'internal',
|
|
49
49
|
},
|
|
50
50
|
});
|
package/src/stablecoin.ts
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import { Contract, ContractBuilder } from './contract';
|
|
2
|
-
import { Access
|
|
1
|
+
import type { Contract, ContractBuilder } from './contract';
|
|
2
|
+
import type { Access } from './set-access-control';
|
|
3
|
+
import { setAccessControl, requireAccessControl } from './set-access-control';
|
|
3
4
|
import { defineFunctions } from './utils/define-functions';
|
|
4
5
|
import { printContract } from './print';
|
|
5
|
-
import {
|
|
6
|
+
import type { ERC20Options } from './erc20';
|
|
7
|
+
import {
|
|
8
|
+
buildERC20,
|
|
9
|
+
defaults as erc20defaults,
|
|
10
|
+
withDefaults as withERC20Defaults,
|
|
11
|
+
functions as erc20functions,
|
|
12
|
+
} from './erc20';
|
|
6
13
|
|
|
7
14
|
export interface StablecoinOptions extends ERC20Options {
|
|
8
|
-
limitations?: false |
|
|
15
|
+
limitations?: false | 'allowlist' | 'blocklist';
|
|
9
16
|
custodian?: boolean;
|
|
10
17
|
}
|
|
11
18
|
|
|
@@ -65,7 +72,7 @@ function addLimitations(c: ContractBuilder, access: Access, mode: boolean | 'all
|
|
|
65
72
|
c.addOverride(ERC20Limitation, functions._update);
|
|
66
73
|
c.addOverride(ERC20Limitation, functions._approve);
|
|
67
74
|
|
|
68
|
-
const [addFn, removeFn] = type
|
|
75
|
+
const [addFn, removeFn] = type
|
|
69
76
|
? [functions.allowUser, functions.disallowUser]
|
|
70
77
|
: [functions.blockUser, functions.unblockUser];
|
|
71
78
|
|
|
@@ -89,7 +96,7 @@ function addCustodian(c: ContractBuilder, access: Access) {
|
|
|
89
96
|
if (access === false) {
|
|
90
97
|
access = 'ownable';
|
|
91
98
|
}
|
|
92
|
-
|
|
99
|
+
|
|
93
100
|
setAccessControl(c, access);
|
|
94
101
|
|
|
95
102
|
switch (access) {
|
|
@@ -102,7 +109,7 @@ function addCustodian(c: ContractBuilder, access: Access) {
|
|
|
102
109
|
const roleId = 'CUSTODIAN_ROLE';
|
|
103
110
|
const addedConstant = c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`);
|
|
104
111
|
if (roleOwner && addedConstant) {
|
|
105
|
-
c.addConstructorArgument({type: 'address', name: roleOwner});
|
|
112
|
+
c.addConstructorArgument({ type: 'address', name: roleOwner });
|
|
106
113
|
c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
|
|
107
114
|
}
|
|
108
115
|
c.setFunctionBody([`return hasRole(CUSTODIAN_ROLE, user);`], functions._isCustodian);
|
|
@@ -115,8 +122,8 @@ function addCustodian(c: ContractBuilder, access: Access) {
|
|
|
115
122
|
});
|
|
116
123
|
const logic = [
|
|
117
124
|
`(bool immediate,) = AuthorityUtils.canCallWithDelay(authority(), user, address(this), bytes4(_msgData()[0:4]));`,
|
|
118
|
-
`return immediate
|
|
119
|
-
]
|
|
125
|
+
`return immediate;`,
|
|
126
|
+
];
|
|
120
127
|
c.setFunctionBody(logic, functions._isCustodian);
|
|
121
128
|
break;
|
|
122
129
|
}
|
|
@@ -128,40 +135,29 @@ const functions = {
|
|
|
128
135
|
...defineFunctions({
|
|
129
136
|
_isCustodian: {
|
|
130
137
|
kind: 'internal' as const,
|
|
131
|
-
args: [
|
|
132
|
-
{ name: 'user', type: 'address' },
|
|
133
|
-
],
|
|
138
|
+
args: [{ name: 'user', type: 'address' }],
|
|
134
139
|
returns: ['bool'],
|
|
135
|
-
mutability: 'view' as const
|
|
140
|
+
mutability: 'view' as const,
|
|
136
141
|
},
|
|
137
142
|
|
|
138
143
|
allowUser: {
|
|
139
144
|
kind: 'public' as const,
|
|
140
|
-
args: [
|
|
141
|
-
{ name: 'user', type: 'address' }
|
|
142
|
-
],
|
|
145
|
+
args: [{ name: 'user', type: 'address' }],
|
|
143
146
|
},
|
|
144
147
|
|
|
145
148
|
disallowUser: {
|
|
146
149
|
kind: 'public' as const,
|
|
147
|
-
args: [
|
|
148
|
-
{ name: 'user', type: 'address' }
|
|
149
|
-
],
|
|
150
|
+
args: [{ name: 'user', type: 'address' }],
|
|
150
151
|
},
|
|
151
152
|
|
|
152
153
|
blockUser: {
|
|
153
154
|
kind: 'public' as const,
|
|
154
|
-
args: [
|
|
155
|
-
{ name: 'user', type: 'address' }
|
|
156
|
-
],
|
|
155
|
+
args: [{ name: 'user', type: 'address' }],
|
|
157
156
|
},
|
|
158
157
|
|
|
159
158
|
unblockUser: {
|
|
160
159
|
kind: 'public' as const,
|
|
161
|
-
args: [
|
|
162
|
-
{ name: 'user', type: 'address' }
|
|
163
|
-
],
|
|
160
|
+
args: [{ name: 'user', type: 'address' }],
|
|
164
161
|
},
|
|
165
|
-
})
|
|
162
|
+
}),
|
|
166
163
|
};
|
|
167
|
-
|
package/src/test.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
|
-
import
|
|
2
|
+
import type { TestFn, ExecutionContext } from 'ava';
|
|
3
|
+
import _test from 'ava';
|
|
3
4
|
import hre from 'hardhat';
|
|
4
5
|
import path from 'path';
|
|
5
6
|
|
|
@@ -8,7 +9,7 @@ import type { GenericOptions, KindedOptions } from './build-generic';
|
|
|
8
9
|
import { custom, erc1155, stablecoin, erc20, erc721, governor } from './api';
|
|
9
10
|
|
|
10
11
|
interface Context {
|
|
11
|
-
generatedSourcesPath: string
|
|
12
|
+
generatedSourcesPath: string;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
const test = _test as TestFn<Context>;
|
|
@@ -54,7 +55,7 @@ async function testCompile(t: ExecutionContext<Context>, kind: keyof KindedOptio
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
function isAccessControlRequired(opts: GenericOptions) {
|
|
57
|
-
switch(opts.kind) {
|
|
58
|
+
switch (opts.kind) {
|
|
58
59
|
case 'ERC20':
|
|
59
60
|
return erc20.isAccessControlRequired(opts);
|
|
60
61
|
case 'ERC721':
|
|
@@ -70,7 +71,7 @@ function isAccessControlRequired(opts: GenericOptions) {
|
|
|
70
71
|
case 'Custom':
|
|
71
72
|
return custom.isAccessControlRequired(opts);
|
|
72
73
|
default:
|
|
73
|
-
throw new Error(
|
|
74
|
+
throw new Error('No such kind');
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -86,4 +87,4 @@ test('is access control required', async t => {
|
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
|
-
});
|
|
90
|
+
});
|
|
@@ -2,17 +2,8 @@ import type { BaseFunction } from '../contract';
|
|
|
2
2
|
|
|
3
3
|
type ImplicitNameFunction = Omit<BaseFunction, 'name'>;
|
|
4
4
|
|
|
5
|
-
export function defineFunctions<F extends string>(
|
|
6
|
-
fns: Record<F, ImplicitNameFunction>,
|
|
7
|
-
): Record<F, BaseFunction>;
|
|
5
|
+
export function defineFunctions<F extends string>(fns: Record<F, ImplicitNameFunction>): Record<F, BaseFunction>;
|
|
8
6
|
|
|
9
|
-
export function defineFunctions(
|
|
10
|
-
fns
|
|
11
|
-
): Record<string, BaseFunction> {
|
|
12
|
-
return Object.fromEntries(
|
|
13
|
-
Object.entries(fns).map(([name, fn]) => [
|
|
14
|
-
name,
|
|
15
|
-
Object.assign({ name }, fn),
|
|
16
|
-
]),
|
|
17
|
-
);
|
|
7
|
+
export function defineFunctions(fns: Record<string, ImplicitNameFunction>): Record<string, BaseFunction> {
|
|
8
|
+
return Object.fromEntries(Object.entries(fns).map(([name, fn]) => [name, Object.assign({ name }, fn)]));
|
|
18
9
|
}
|
package/src/utils/duration.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const durationUnits = ['block', 'second', 'minute', 'hour', 'day', 'week', 'month', 'year'] as const;
|
|
2
|
-
type DurationUnit = typeof durationUnits[number];
|
|
2
|
+
type DurationUnit = (typeof durationUnits)[number];
|
|
3
3
|
export const durationPattern = new RegExp(`^(\\d+(?:\\.\\d+)?) +(${durationUnits.join('|')})s?$`);
|
|
4
4
|
|
|
5
5
|
const second = 1;
|
|
@@ -49,4 +49,4 @@ export function durationToTimestamp(duration: string): string {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
return `${value} ${unit}s`;
|
|
52
|
-
}
|
|
52
|
+
}
|
|
@@ -10,11 +10,7 @@ export function formatLinesWithSpaces(spacesPerIndent: number, ...lines: Lines[]
|
|
|
10
10
|
return [...indentEach(0, lines, spacesPerIndent)].join('\n') + '\n';
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
function* indentEach(
|
|
14
|
-
indent: number,
|
|
15
|
-
lines: Lines[],
|
|
16
|
-
spacesPerIndent: number,
|
|
17
|
-
): Generator<string | typeof whitespace> {
|
|
13
|
+
function* indentEach(indent: number, lines: Lines[], spacesPerIndent: number): Generator<string | typeof whitespace> {
|
|
18
14
|
for (const line of lines) {
|
|
19
15
|
if (line === whitespace) {
|
|
20
16
|
yield '';
|
package/src/utils/map-values.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
fn: (val: V) => W,
|
|
4
|
-
): Record<K, W> {
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2
|
+
export function mapValues<K extends keyof any, V, W>(obj: Record<K, V>, fn: (val: V) => W): Record<K, W> {
|
|
5
3
|
const res = {} as Record<K, W>;
|
|
6
4
|
for (const key in obj) {
|
|
7
5
|
res[key] = fn(obj[key]);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
export function toIdentifier(str: string, capitalize = false): string {
|
|
2
2
|
return str
|
|
3
|
-
.normalize('NFD')
|
|
3
|
+
.normalize('NFD')
|
|
4
|
+
.replace(/[\u0300-\u036f]/g, '') // remove accents
|
|
4
5
|
.replace(/^[^a-zA-Z$_]+/, '')
|
|
5
|
-
.replace(/^(.)/, c => capitalize ? c.toUpperCase() : c)
|
|
6
|
+
.replace(/^(.)/, c => (capitalize ? c.toUpperCase() : c))
|
|
6
7
|
.replace(/[^\w$]+(.?)/g, (_, c) => c.toUpperCase());
|
|
7
8
|
}
|
package/src/zip-foundry.ts
CHANGED
|
@@ -1,32 +1,21 @@
|
|
|
1
|
-
import JSZip from
|
|
2
|
-
import type { GenericOptions } from
|
|
3
|
-
import type { Contract } from
|
|
4
|
-
import { printContract } from
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import type { GenericOptions } from './build-generic';
|
|
3
|
+
import type { Contract } from './contract';
|
|
4
|
+
import { printContract } from './print';
|
|
5
5
|
import SOLIDITY_VERSION from './solidity-version.json';
|
|
6
6
|
import contracts from '../openzeppelin-contracts';
|
|
7
|
-
import {
|
|
7
|
+
import type { Lines } from './utils/format-lines';
|
|
8
|
+
import { formatLinesWithSpaces, spaceBetween } from './utils/format-lines';
|
|
8
9
|
|
|
9
10
|
function getHeader(c: Contract) {
|
|
10
|
-
return [
|
|
11
|
-
`// SPDX-License-Identifier: ${c.license}`,
|
|
12
|
-
`pragma solidity ^${SOLIDITY_VERSION};`
|
|
13
|
-
];
|
|
11
|
+
return [`// SPDX-License-Identifier: ${c.license}`, `pragma solidity ^${SOLIDITY_VERSION};`];
|
|
14
12
|
}
|
|
15
13
|
|
|
16
14
|
const test = (c: Contract, opts?: GenericOptions) => {
|
|
17
|
-
return formatLinesWithSpaces(
|
|
18
|
-
2,
|
|
19
|
-
...spaceBetween(
|
|
20
|
-
getHeader(c),
|
|
21
|
-
getImports(c),
|
|
22
|
-
getTestCase(c),
|
|
23
|
-
),
|
|
24
|
-
);
|
|
15
|
+
return formatLinesWithSpaces(2, ...spaceBetween(getHeader(c), getImports(c), getTestCase(c)));
|
|
25
16
|
|
|
26
17
|
function getImports(c: Contract) {
|
|
27
|
-
const result = [
|
|
28
|
-
'import {Test} from "forge-std/Test.sol";',
|
|
29
|
-
];
|
|
18
|
+
const result = ['import {Test} from "forge-std/Test.sol";'];
|
|
30
19
|
if (c.upgradeable) {
|
|
31
20
|
result.push('import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";');
|
|
32
21
|
}
|
|
@@ -39,15 +28,8 @@ const test = (c: Contract, opts?: GenericOptions) => {
|
|
|
39
28
|
return [
|
|
40
29
|
`contract ${c.name}Test is Test {`,
|
|
41
30
|
spaceBetween(
|
|
42
|
-
[
|
|
43
|
-
|
|
44
|
-
],
|
|
45
|
-
[
|
|
46
|
-
'function setUp() public {',
|
|
47
|
-
getAddressVariables(c, args),
|
|
48
|
-
getDeploymentCode(c, args),
|
|
49
|
-
'}',
|
|
50
|
-
],
|
|
31
|
+
[`${c.name} public instance;`],
|
|
32
|
+
['function setUp() public {', getAddressVariables(c, args), getDeploymentCode(c, args), '}'],
|
|
51
33
|
getContractSpecificTestFunction(),
|
|
52
34
|
),
|
|
53
35
|
'}',
|
|
@@ -59,29 +41,20 @@ const test = (c: Contract, opts?: GenericOptions) => {
|
|
|
59
41
|
if (opts?.upgradeable === 'transparent') {
|
|
60
42
|
return [
|
|
61
43
|
`address proxy = Upgrades.deployTransparentProxy(`,
|
|
62
|
-
[
|
|
63
|
-
`"${c.name}.sol",`,
|
|
64
|
-
`initialOwner,`,
|
|
65
|
-
`abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`
|
|
66
|
-
],
|
|
44
|
+
[`"${c.name}.sol",`, `initialOwner,`, `abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`],
|
|
67
45
|
');',
|
|
68
46
|
`instance = ${c.name}(proxy);`,
|
|
69
47
|
];
|
|
70
48
|
} else {
|
|
71
49
|
return [
|
|
72
50
|
`address proxy = Upgrades.deployUUPSProxy(`,
|
|
73
|
-
[
|
|
74
|
-
`"${c.name}.sol",`,
|
|
75
|
-
`abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`
|
|
76
|
-
],
|
|
51
|
+
[`"${c.name}.sol",`, `abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`],
|
|
77
52
|
');',
|
|
78
53
|
`instance = ${c.name}(proxy);`,
|
|
79
54
|
];
|
|
80
55
|
}
|
|
81
56
|
} else {
|
|
82
|
-
return [
|
|
83
|
-
`instance = new ${c.name}(${args.join(', ')});`,
|
|
84
|
-
];
|
|
57
|
+
return [`instance = new ${c.name}(${args.join(', ')});`];
|
|
85
58
|
}
|
|
86
59
|
}
|
|
87
60
|
|
|
@@ -102,32 +75,14 @@ const test = (c: Contract, opts?: GenericOptions) => {
|
|
|
102
75
|
switch (opts.kind) {
|
|
103
76
|
case 'ERC20':
|
|
104
77
|
case 'ERC721':
|
|
105
|
-
return [
|
|
106
|
-
'function testName() public view {',
|
|
107
|
-
[
|
|
108
|
-
`assertEq(instance.name(), "${opts.name}");`
|
|
109
|
-
],
|
|
110
|
-
'}',
|
|
111
|
-
];
|
|
78
|
+
return ['function testName() public view {', [`assertEq(instance.name(), "${opts.name}");`], '}'];
|
|
112
79
|
|
|
113
80
|
case 'ERC1155':
|
|
114
|
-
return [
|
|
115
|
-
'function testUri() public view {',
|
|
116
|
-
[
|
|
117
|
-
`assertEq(instance.uri(0), "${opts.uri}");`
|
|
118
|
-
],
|
|
119
|
-
'}',
|
|
120
|
-
];
|
|
81
|
+
return ['function testUri() public view {', [`assertEq(instance.uri(0), "${opts.uri}");`], '}'];
|
|
121
82
|
|
|
122
83
|
case 'Governor':
|
|
123
84
|
case 'Custom':
|
|
124
|
-
return [
|
|
125
|
-
'function testSomething() public {',
|
|
126
|
-
[
|
|
127
|
-
'// Add your test here',
|
|
128
|
-
],
|
|
129
|
-
'}',
|
|
130
|
-
]
|
|
85
|
+
return ['function testSomething() public {', ['// Add your test here'], '}'];
|
|
131
86
|
|
|
132
87
|
default:
|
|
133
88
|
throw new Error('Unknown ERC');
|
|
@@ -148,20 +103,10 @@ function getAddressArgs(c: Contract): string[] {
|
|
|
148
103
|
}
|
|
149
104
|
|
|
150
105
|
const script = (c: Contract, opts?: GenericOptions) => {
|
|
151
|
-
return formatLinesWithSpaces(
|
|
152
|
-
2,
|
|
153
|
-
...spaceBetween(
|
|
154
|
-
getHeader(c),
|
|
155
|
-
getImports(c),
|
|
156
|
-
getScript(c),
|
|
157
|
-
),
|
|
158
|
-
);
|
|
106
|
+
return formatLinesWithSpaces(2, ...spaceBetween(getHeader(c), getImports(c), getScript(c)));
|
|
159
107
|
|
|
160
108
|
function getImports(c: Contract) {
|
|
161
|
-
const result = [
|
|
162
|
-
'import {Script} from "forge-std/Script.sol";',
|
|
163
|
-
'import {console} from "forge-std/console.sol";',
|
|
164
|
-
];
|
|
109
|
+
const result = ['import {Script} from "forge-std/Script.sol";', 'import {console} from "forge-std/console.sol";'];
|
|
165
110
|
if (c.upgradeable) {
|
|
166
111
|
result.push('import {Upgrades} from "openzeppelin-foundry-upgrades/Upgrades.sol";');
|
|
167
112
|
}
|
|
@@ -181,14 +126,8 @@ const script = (c: Contract, opts?: GenericOptions) => {
|
|
|
181
126
|
return [
|
|
182
127
|
`contract ${c.name}Script is Script {`,
|
|
183
128
|
spaceBetween(
|
|
184
|
-
[
|
|
185
|
-
|
|
186
|
-
],
|
|
187
|
-
[
|
|
188
|
-
'function run() public {',
|
|
189
|
-
args.length > 0 ? addTodoAndCommentOut(deploymentLines) : deploymentLines,
|
|
190
|
-
'}',
|
|
191
|
-
],
|
|
129
|
+
['function setUp() public {}'],
|
|
130
|
+
['function run() public {', args.length > 0 ? addTodoAndCommentOut(deploymentLines) : deploymentLines, '}'],
|
|
192
131
|
),
|
|
193
132
|
'}',
|
|
194
133
|
];
|
|
@@ -199,29 +138,20 @@ const script = (c: Contract, opts?: GenericOptions) => {
|
|
|
199
138
|
if (opts?.upgradeable === 'transparent') {
|
|
200
139
|
return [
|
|
201
140
|
`address proxy = Upgrades.deployTransparentProxy(`,
|
|
202
|
-
[
|
|
203
|
-
`"${c.name}.sol",`,
|
|
204
|
-
`initialOwner,`,
|
|
205
|
-
`abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`
|
|
206
|
-
],
|
|
141
|
+
[`"${c.name}.sol",`, `initialOwner,`, `abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`],
|
|
207
142
|
');',
|
|
208
143
|
`${c.name} instance = ${c.name}(proxy);`,
|
|
209
144
|
];
|
|
210
145
|
} else {
|
|
211
146
|
return [
|
|
212
147
|
`address proxy = Upgrades.deployUUPSProxy(`,
|
|
213
|
-
[
|
|
214
|
-
`"${c.name}.sol",`,
|
|
215
|
-
`abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`
|
|
216
|
-
],
|
|
148
|
+
[`"${c.name}.sol",`, `abi.encodeCall(${c.name}.initialize, (${args.join(', ')}))`],
|
|
217
149
|
');',
|
|
218
150
|
`${c.name} instance = ${c.name}(proxy);`,
|
|
219
151
|
];
|
|
220
152
|
}
|
|
221
153
|
} else {
|
|
222
|
-
return [
|
|
223
|
-
`${c.name} instance = new ${c.name}(${args.join(', ')});`,
|
|
224
|
-
];
|
|
154
|
+
return [`${c.name} instance = new ${c.name}(${args.join(', ')});`];
|
|
225
155
|
}
|
|
226
156
|
}
|
|
227
157
|
|
|
@@ -274,14 +204,18 @@ then
|
|
|
274
204
|
# Initialize sample Foundry project
|
|
275
205
|
forge init --force --no-commit --quiet
|
|
276
206
|
|
|
277
|
-
${
|
|
207
|
+
${
|
|
208
|
+
c.upgradeable
|
|
209
|
+
? `\
|
|
278
210
|
# Install OpenZeppelin Contracts and Upgrades
|
|
279
211
|
forge install OpenZeppelin/openzeppelin-contracts-upgradeable@v${contracts.version} --no-commit --quiet
|
|
280
212
|
forge install OpenZeppelin/openzeppelin-foundry-upgrades --no-commit --quiet\
|
|
281
|
-
`
|
|
213
|
+
`
|
|
214
|
+
: `\
|
|
282
215
|
# Install OpenZeppelin Contracts
|
|
283
216
|
forge install OpenZeppelin/openzeppelin-contracts@v${contracts.version} --no-commit --quiet\
|
|
284
|
-
`
|
|
217
|
+
`
|
|
218
|
+
}
|
|
285
219
|
|
|
286
220
|
# Remove unneeded Foundry template files
|
|
287
221
|
rm src/Counter.sol
|
|
@@ -297,7 +231,9 @@ ${c.upgradeable ? `\
|
|
|
297
231
|
then
|
|
298
232
|
echo "" >> remappings.txt
|
|
299
233
|
fi
|
|
300
|
-
${
|
|
234
|
+
${
|
|
235
|
+
c.upgradeable
|
|
236
|
+
? `\
|
|
301
237
|
echo "@openzeppelin/contracts/=lib/openzeppelin-contracts-upgradeable/lib/openzeppelin-contracts/contracts/" >> remappings.txt
|
|
302
238
|
echo "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" >> remappings.txt
|
|
303
239
|
|
|
@@ -307,9 +243,11 @@ ${c.upgradeable ? `\
|
|
|
307
243
|
echo "ast = true" >> foundry.toml
|
|
308
244
|
echo "build_info = true" >> foundry.toml
|
|
309
245
|
echo "extra_output = [\\"storageLayout\\"]" >> foundry.toml\
|
|
310
|
-
`
|
|
246
|
+
`
|
|
247
|
+
: `\
|
|
311
248
|
echo "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/" >> remappings.txt\
|
|
312
|
-
`
|
|
249
|
+
`
|
|
250
|
+
}
|
|
313
251
|
|
|
314
252
|
# Perform initial git commit
|
|
315
253
|
git add .
|
|
@@ -350,7 +288,7 @@ You can simulate a deployment by running the script:
|
|
|
350
288
|
forge script script/${c.name}.s.sol${c.upgradeable ? ' --force' : ''}
|
|
351
289
|
\`\`\`
|
|
352
290
|
|
|
353
|
-
See [Solidity scripting guide](https://book.getfoundry.sh/
|
|
291
|
+
See [Solidity scripting guide](https://book.getfoundry.sh/guides/scripting-with-solidity) for more information.
|
|
354
292
|
`;
|
|
355
293
|
|
|
356
294
|
export async function zipFoundry(c: Contract, opts?: GenericOptions) {
|
|
@@ -363,4 +301,4 @@ export async function zipFoundry(c: Contract, opts?: GenericOptions) {
|
|
|
363
301
|
zip.file('README.md', readme(c));
|
|
364
302
|
|
|
365
303
|
return zip;
|
|
366
|
-
}
|
|
304
|
+
}
|
package/src/zip-hardhat.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import JSZip from
|
|
2
|
-
import type { GenericOptions } from
|
|
3
|
-
import type { Contract } from
|
|
4
|
-
import { printContract } from
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import type { GenericOptions } from './build-generic';
|
|
3
|
+
import type { Contract } from './contract';
|
|
4
|
+
import { printContract } from './print';
|
|
5
5
|
import SOLIDITY_VERSION from './solidity-version.json';
|
|
6
|
-
import {
|
|
6
|
+
import type { Lines } from './utils/format-lines';
|
|
7
|
+
import { formatLinesWithSpaces, spaceBetween } from './utils/format-lines';
|
|
7
8
|
|
|
8
9
|
const hardhatConfig = (upgradeable: boolean) => `\
|
|
9
10
|
import { HardhatUserConfig } from "hardhat/config";
|
|
@@ -52,13 +53,7 @@ artifacts
|
|
|
52
53
|
`;
|
|
53
54
|
|
|
54
55
|
const test = (c: Contract, opts?: GenericOptions) => {
|
|
55
|
-
return formatLinesWithSpaces(
|
|
56
|
-
2,
|
|
57
|
-
...spaceBetween(
|
|
58
|
-
getImports(c),
|
|
59
|
-
getTestCase(c),
|
|
60
|
-
),
|
|
61
|
-
);
|
|
56
|
+
return formatLinesWithSpaces(2, ...spaceBetween(getImports(c), getTestCase(c)));
|
|
62
57
|
|
|
63
58
|
function getTestCase(c: Contract) {
|
|
64
59
|
const args = getAddressArgs(c);
|
|
@@ -67,27 +62,19 @@ const test = (c: Contract, opts?: GenericOptions) => {
|
|
|
67
62
|
[
|
|
68
63
|
'it("Test contract", async function () {',
|
|
69
64
|
spaceBetween(
|
|
70
|
-
[
|
|
71
|
-
`const ContractFactory = await ethers.getContractFactory("${c.name}");`,
|
|
72
|
-
],
|
|
65
|
+
[`const ContractFactory = await ethers.getContractFactory("${c.name}");`],
|
|
73
66
|
getAddressVariables(args),
|
|
74
|
-
[
|
|
75
|
-
`const instance = await ${getDeploymentCall(c, args)};`,
|
|
76
|
-
'await instance.waitForDeployment();'
|
|
77
|
-
],
|
|
67
|
+
[`const instance = await ${getDeploymentCall(c, args)};`, 'await instance.waitForDeployment();'],
|
|
78
68
|
getExpects(),
|
|
79
69
|
),
|
|
80
|
-
'});'
|
|
70
|
+
'});',
|
|
81
71
|
],
|
|
82
72
|
'});',
|
|
83
73
|
];
|
|
84
74
|
}
|
|
85
75
|
|
|
86
76
|
function getImports(c: Contract) {
|
|
87
|
-
return [
|
|
88
|
-
'import { expect } from "chai";',
|
|
89
|
-
`import { ${getHardhatPlugins(c).join(', ')} } from "hardhat";`,
|
|
90
|
-
];
|
|
77
|
+
return ['import { expect } from "chai";', `import { ${getHardhatPlugins(c).join(', ')} } from "hardhat";`];
|
|
91
78
|
}
|
|
92
79
|
|
|
93
80
|
function getExpects(): Lines[] {
|
|
@@ -131,7 +118,9 @@ function getAddressArgs(c: Contract): string[] {
|
|
|
131
118
|
}
|
|
132
119
|
|
|
133
120
|
function getDeploymentCall(c: Contract, args: string[]): string {
|
|
134
|
-
return c.upgradeable
|
|
121
|
+
return c.upgradeable
|
|
122
|
+
? `upgrades.deployProxy(ContractFactory, [${args.join(', ')}])`
|
|
123
|
+
: `ContractFactory.deploy(${args.join(', ')})`;
|
|
135
124
|
}
|
|
136
125
|
|
|
137
126
|
const script = (c: Contract) => {
|
|
@@ -155,7 +144,8 @@ main().catch((error) => {
|
|
|
155
144
|
console.error(error);
|
|
156
145
|
process.exitCode = 1;
|
|
157
146
|
});
|
|
158
|
-
|
|
147
|
+
`;
|
|
148
|
+
};
|
|
159
149
|
|
|
160
150
|
const readme = `\
|
|
161
151
|
# Sample Hardhat Project
|
|
@@ -184,7 +174,7 @@ npx hardhat run --network <network-name> scripts/deploy.ts
|
|
|
184
174
|
`;
|
|
185
175
|
|
|
186
176
|
function getHardhatPlugins(c: Contract) {
|
|
187
|
-
|
|
177
|
+
const plugins = ['ethers'];
|
|
188
178
|
if (c.upgradeable) {
|
|
189
179
|
plugins.push('upgrades');
|
|
190
180
|
}
|
|
@@ -194,10 +184,14 @@ function getHardhatPlugins(c: Contract) {
|
|
|
194
184
|
export async function zipHardhat(c: Contract, opts?: GenericOptions) {
|
|
195
185
|
const zip = new JSZip();
|
|
196
186
|
|
|
197
|
-
const { default: packageJson } = c.upgradeable
|
|
187
|
+
const { default: packageJson } = c.upgradeable
|
|
188
|
+
? await import('./environments/hardhat/upgradeable/package.json')
|
|
189
|
+
: await import('./environments/hardhat/package.json');
|
|
198
190
|
packageJson.license = c.license;
|
|
199
191
|
|
|
200
|
-
const { default: packageLock } = c.upgradeable
|
|
192
|
+
const { default: packageLock } = c.upgradeable
|
|
193
|
+
? await import('./environments/hardhat/upgradeable/package-lock.json')
|
|
194
|
+
: await import('./environments/hardhat/package-lock.json');
|
|
201
195
|
packageLock.packages[''].license = c.license;
|
|
202
196
|
|
|
203
197
|
zip.file(`contracts/${c.name}.sol`, printContract(c));
|
|
@@ -211,4 +205,4 @@ export async function zipHardhat(c: Contract, opts?: GenericOptions) {
|
|
|
211
205
|
zip.file('tsconfig.json', tsConfig);
|
|
212
206
|
|
|
213
207
|
return zip;
|
|
214
|
-
}
|
|
208
|
+
}
|