@openzeppelin/wizard 0.10.5 → 0.10.7
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/common-options.js +1 -1
- package/dist/common-options.js.map +1 -1
- package/dist/contract.d.ts +1 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js +1 -1
- package/dist/contract.js.map +1 -1
- package/dist/environments/hardhat/package-lock.json +4 -4
- package/dist/environments/hardhat/package.json +1 -1
- package/dist/environments/hardhat/upgradeable/package-lock.json +9 -9
- package/dist/environments/hardhat/upgradeable/package.json +2 -2
- package/dist/erc20.d.ts +10 -2
- package/dist/erc20.d.ts.map +1 -1
- package/dist/erc20.js +125 -50
- package/dist/erc20.js.map +1 -1
- package/dist/generate/erc20.d.ts.map +1 -1
- package/dist/generate/erc20.js +25 -6
- package/dist/generate/erc20.js.map +1 -1
- package/dist/generate/stablecoin.d.ts.map +1 -1
- package/dist/generate/stablecoin.js +2 -0
- package/dist/generate/stablecoin.js.map +1 -1
- package/dist/index.d.ts +23 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -21
- package/dist/index.js.map +1 -1
- package/dist/options.d.ts +3 -0
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js.map +1 -1
- package/dist/print.d.ts.map +1 -1
- package/dist/print.js +38 -26
- package/dist/print.js.map +1 -1
- package/dist/stablecoin.d.ts.map +1 -1
- package/dist/stablecoin.js +1 -1
- package/dist/stablecoin.js.map +1 -1
- package/dist/utils/convert-strings.d.ts +21 -2
- package/dist/utils/convert-strings.d.ts.map +1 -1
- package/dist/utils/convert-strings.js +28 -4
- package/dist/utils/convert-strings.js.map +1 -1
- package/dist/utils/version.d.ts +1 -1
- package/dist/utils/version.js +1 -1
- package/openzeppelin-contracts-version.json +1 -1
- package/package.json +5 -5
- package/src/common-options.ts +1 -1
- package/src/contract.ts +2 -2
- package/src/environments/hardhat/package-lock.json +4 -4
- package/src/environments/hardhat/package.json +1 -1
- package/src/environments/hardhat/upgradeable/package-lock.json +9 -9
- package/src/environments/hardhat/upgradeable/package.json +2 -2
- package/src/erc20.ts +163 -51
- package/src/generate/erc20.ts +27 -6
- package/src/generate/stablecoin.ts +2 -0
- package/src/index.ts +30 -18
- package/src/options.ts +3 -1
- package/src/print.ts +47 -26
- package/src/stablecoin.ts +2 -1
- package/src/utils/convert-strings.ts +28 -4
- package/src/utils/version.ts +1 -1
package/src/common-options.ts
CHANGED
package/src/contract.ts
CHANGED
|
@@ -100,9 +100,9 @@ export class ContractBuilder implements Contract {
|
|
|
100
100
|
|
|
101
101
|
readonly variableOrErrorMap: Map<string, VariableOrErrorDefinition> = new Map<string, VariableOrErrorDefinition>();
|
|
102
102
|
private parentMap: Map<string, Parent> = new Map<string, Parent>();
|
|
103
|
+
private functionMap: Map<string, ContractFunction> = new Map<string, ContractFunction>();
|
|
103
104
|
private libraryMap: Map<string, Library> = new Map<string, Library>();
|
|
104
|
-
private
|
|
105
|
-
private structMap: Map<string, ContractStruct> = new Map();
|
|
105
|
+
private structMap: Map<string, ContractStruct> = new Map<string, ContractStruct>();
|
|
106
106
|
|
|
107
107
|
constructor(name: string) {
|
|
108
108
|
this.name = toIdentifier(name, true);
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@nomicfoundation/hardhat-toolbox": "^6.1.0",
|
|
13
|
-
"@openzeppelin/contracts": "^5.
|
|
13
|
+
"@openzeppelin/contracts": "^5.6.0",
|
|
14
14
|
"hardhat": "^2.22.0"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
@@ -1219,9 +1219,9 @@
|
|
|
1219
1219
|
}
|
|
1220
1220
|
},
|
|
1221
1221
|
"node_modules/@openzeppelin/contracts": {
|
|
1222
|
-
"version": "5.
|
|
1223
|
-
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.
|
|
1224
|
-
"integrity": "sha512-
|
|
1222
|
+
"version": "5.6.0",
|
|
1223
|
+
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.6.0.tgz",
|
|
1224
|
+
"integrity": "sha512-eZJSS8+RbWzX/7oDJPi+lYzfeuWwHXSsw336Yff35pTkmLEwRWKde2PQMW2objjMi1C1hNn9QiHjGktEJPSSWQ==",
|
|
1225
1225
|
"dev": true,
|
|
1226
1226
|
"license": "MIT"
|
|
1227
1227
|
},
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@nomicfoundation/hardhat-toolbox": "^6.1.0",
|
|
13
|
-
"@openzeppelin/contracts": "^5.
|
|
14
|
-
"@openzeppelin/contracts-upgradeable": "^5.
|
|
13
|
+
"@openzeppelin/contracts": "^5.6.0",
|
|
14
|
+
"@openzeppelin/contracts-upgradeable": "^5.6.0",
|
|
15
15
|
"@openzeppelin/hardhat-upgrades": "^3.0.0",
|
|
16
16
|
"hardhat": "^2.22.0"
|
|
17
17
|
}
|
|
@@ -1924,20 +1924,20 @@
|
|
|
1924
1924
|
}
|
|
1925
1925
|
},
|
|
1926
1926
|
"node_modules/@openzeppelin/contracts": {
|
|
1927
|
-
"version": "5.
|
|
1928
|
-
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.
|
|
1929
|
-
"integrity": "sha512-
|
|
1927
|
+
"version": "5.6.0",
|
|
1928
|
+
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.6.0.tgz",
|
|
1929
|
+
"integrity": "sha512-eZJSS8+RbWzX/7oDJPi+lYzfeuWwHXSsw336Yff35pTkmLEwRWKde2PQMW2objjMi1C1hNn9QiHjGktEJPSSWQ==",
|
|
1930
1930
|
"dev": true,
|
|
1931
1931
|
"license": "MIT"
|
|
1932
1932
|
},
|
|
1933
1933
|
"node_modules/@openzeppelin/contracts-upgradeable": {
|
|
1934
|
-
"version": "5.
|
|
1935
|
-
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.
|
|
1936
|
-
"integrity": "sha512-
|
|
1934
|
+
"version": "5.6.0",
|
|
1935
|
+
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.6.0.tgz",
|
|
1936
|
+
"integrity": "sha512-pJ4Qb4EGjemdvP/pbBZ+etXDB5PQJJf1tbIBDQqfQZMK3Lk8UuNCK+cWDluHZ28UfwH2WAwJLftyhJid4w63QA==",
|
|
1937
1937
|
"dev": true,
|
|
1938
1938
|
"license": "MIT",
|
|
1939
1939
|
"peerDependencies": {
|
|
1940
|
-
"@openzeppelin/contracts": "5.
|
|
1940
|
+
"@openzeppelin/contracts": "5.6.0"
|
|
1941
1941
|
}
|
|
1942
1942
|
},
|
|
1943
1943
|
"node_modules/@openzeppelin/defender-sdk-base-client": {
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"@nomicfoundation/hardhat-toolbox": "^6.1.0",
|
|
13
|
-
"@openzeppelin/contracts": "^5.
|
|
14
|
-
"@openzeppelin/contracts-upgradeable": "^5.
|
|
13
|
+
"@openzeppelin/contracts": "^5.6.0",
|
|
14
|
+
"@openzeppelin/contracts-upgradeable": "^5.6.0",
|
|
15
15
|
"@openzeppelin/hardhat-upgrades": "^3.0.0",
|
|
16
16
|
"hardhat": "^2.22.0"
|
|
17
17
|
}
|
package/src/erc20.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { OptionsError } from './error';
|
|
|
16
16
|
import { toUint256, UINT256_MAX } from './utils/convert-strings';
|
|
17
17
|
import { setNamespacedStorage, toStorageStructInstantiation } from './set-namespaced-storage';
|
|
18
18
|
|
|
19
|
-
export const crossChainBridgingOptions = [false, 'custom', 'superchain'] as const;
|
|
19
|
+
export const crossChainBridgingOptions = [false, 'custom', 'erc7786native', 'superchain'] as const;
|
|
20
20
|
export type CrossChainBridging = (typeof crossChainBridgingOptions)[number];
|
|
21
21
|
|
|
22
22
|
export interface ERC20Options extends CommonOptions {
|
|
@@ -36,6 +36,7 @@ export interface ERC20Options extends CommonOptions {
|
|
|
36
36
|
votes?: boolean | ClockMode;
|
|
37
37
|
flashmint?: boolean;
|
|
38
38
|
crossChainBridging?: CrossChainBridging;
|
|
39
|
+
crossChainLinkAllowOverride?: boolean;
|
|
39
40
|
namespacePrefix?: string;
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -53,6 +54,7 @@ export const defaults: Required<ERC20Options> = {
|
|
|
53
54
|
votes: false,
|
|
54
55
|
flashmint: false,
|
|
55
56
|
crossChainBridging: false,
|
|
57
|
+
crossChainLinkAllowOverride: false,
|
|
56
58
|
namespacePrefix: 'myProject',
|
|
57
59
|
} as const;
|
|
58
60
|
|
|
@@ -70,6 +72,7 @@ export function withDefaults(opts: ERC20Options): Required<ERC20Options> {
|
|
|
70
72
|
votes: opts.votes ?? defaults.votes,
|
|
71
73
|
flashmint: opts.flashmint ?? defaults.flashmint,
|
|
72
74
|
crossChainBridging: opts.crossChainBridging ?? defaults.crossChainBridging,
|
|
75
|
+
crossChainLinkAllowOverride: opts.crossChainLinkAllowOverride ?? defaults.crossChainLinkAllowOverride,
|
|
73
76
|
namespacePrefix: opts.namespacePrefix ?? defaults.namespacePrefix,
|
|
74
77
|
};
|
|
75
78
|
}
|
|
@@ -79,7 +82,13 @@ export function printERC20(opts: ERC20Options = defaults): string {
|
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
export function isAccessControlRequired(opts: Partial<ERC20Options>): boolean {
|
|
82
|
-
return
|
|
85
|
+
return (
|
|
86
|
+
opts.mintable ||
|
|
87
|
+
opts.pausable ||
|
|
88
|
+
opts.upgradeable === 'uups' ||
|
|
89
|
+
opts.crossChainBridging === 'custom' ||
|
|
90
|
+
opts.crossChainBridging === 'erc7786native'
|
|
91
|
+
);
|
|
83
92
|
}
|
|
84
93
|
|
|
85
94
|
export function buildERC20(opts: ERC20Options): ContractBuilder {
|
|
@@ -92,7 +101,14 @@ export function buildERC20(opts: ERC20Options): ContractBuilder {
|
|
|
92
101
|
addBase(c, allOpts.name, allOpts.symbol);
|
|
93
102
|
|
|
94
103
|
if (allOpts.crossChainBridging) {
|
|
95
|
-
addCrossChainBridging(
|
|
104
|
+
addCrossChainBridging(
|
|
105
|
+
c,
|
|
106
|
+
allOpts.crossChainBridging,
|
|
107
|
+
allOpts.crossChainLinkAllowOverride,
|
|
108
|
+
access,
|
|
109
|
+
upgradeable,
|
|
110
|
+
allOpts.namespacePrefix,
|
|
111
|
+
);
|
|
96
112
|
}
|
|
97
113
|
|
|
98
114
|
if (allOpts.premint) {
|
|
@@ -115,14 +131,13 @@ export function buildERC20(opts: ERC20Options): ContractBuilder {
|
|
|
115
131
|
addCallback(c);
|
|
116
132
|
}
|
|
117
133
|
|
|
118
|
-
|
|
119
|
-
if (allOpts.permit || allOpts.votes) {
|
|
134
|
+
if (allOpts.permit) {
|
|
120
135
|
addPermit(c, allOpts.name);
|
|
121
136
|
}
|
|
122
137
|
|
|
123
138
|
if (allOpts.votes) {
|
|
124
139
|
const clockMode = allOpts.votes === true ? clockModeDefault : allOpts.votes;
|
|
125
|
-
addVotes(c, clockMode);
|
|
140
|
+
addVotes(c, allOpts.name, clockMode);
|
|
126
141
|
}
|
|
127
142
|
|
|
128
143
|
if (allOpts.flashmint) {
|
|
@@ -173,7 +188,7 @@ export function isValidChainId(str: string): boolean {
|
|
|
173
188
|
return chainIdPattern.test(str);
|
|
174
189
|
}
|
|
175
190
|
|
|
176
|
-
function scaleByPowerOfTen(base: bigint, exponent: number): bigint {
|
|
191
|
+
export function scaleByPowerOfTen(base: bigint, exponent: number): bigint {
|
|
177
192
|
if (exponent < 0) {
|
|
178
193
|
return base / BigInt(10) ** BigInt(-exponent);
|
|
179
194
|
} else {
|
|
@@ -181,55 +196,74 @@ function scaleByPowerOfTen(base: bigint, exponent: number): bigint {
|
|
|
181
196
|
}
|
|
182
197
|
}
|
|
183
198
|
|
|
199
|
+
export interface PremintCalculation {
|
|
200
|
+
units: string;
|
|
201
|
+
exp: string;
|
|
202
|
+
decimalPlace: number;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function calculatePremint(amount: string): PremintCalculation | undefined {
|
|
206
|
+
const m = amount.match(premintPattern);
|
|
207
|
+
if (!m) {
|
|
208
|
+
throw new OptionsError({
|
|
209
|
+
premint: 'Not a valid number',
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
const integer = m[1]?.replace(/^0+/, '') ?? '';
|
|
214
|
+
const decimals = m[2]?.replace(/0+$/, '') ?? '';
|
|
215
|
+
const exponent = Number(m[3] ?? 0);
|
|
216
|
+
|
|
217
|
+
if (Number(integer + decimals) > 0) {
|
|
218
|
+
const decimalPlace = decimals.length - exponent;
|
|
219
|
+
const zeroes = new Array(Math.max(0, -decimalPlace)).fill('0').join('');
|
|
220
|
+
const units = integer + decimals + zeroes;
|
|
221
|
+
const exp = decimalPlace <= 0 ? 'decimals()' : `(decimals() - ${decimalPlace})`;
|
|
222
|
+
|
|
223
|
+
return { units, exp, decimalPlace };
|
|
224
|
+
} else {
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
184
229
|
function addPremint(
|
|
185
230
|
c: ContractBuilder,
|
|
186
231
|
amount: string,
|
|
187
232
|
premintChainId: string,
|
|
188
233
|
crossChainBridging: CrossChainBridging,
|
|
189
234
|
) {
|
|
190
|
-
const
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const exponent = Number(m[3] ?? 0);
|
|
195
|
-
|
|
196
|
-
if (Number(integer + decimals) > 0) {
|
|
197
|
-
const decimalPlace = decimals.length - exponent;
|
|
198
|
-
const zeroes = new Array(Math.max(0, -decimalPlace)).fill('0').join('');
|
|
199
|
-
const units = integer + decimals + zeroes;
|
|
200
|
-
const exp = decimalPlace <= 0 ? 'decimals()' : `(decimals() - ${decimalPlace})`;
|
|
235
|
+
const premintCalculation = calculatePremint(amount);
|
|
236
|
+
if (premintCalculation === undefined) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
201
239
|
|
|
202
|
-
|
|
203
|
-
checkPotentialPremintOverflow(validatedBaseUnits, decimalPlace);
|
|
240
|
+
const { units, exp, decimalPlace } = premintCalculation;
|
|
204
241
|
|
|
205
|
-
|
|
242
|
+
const validatedBaseUnits = toUint256(units, 'premint');
|
|
243
|
+
checkPotentialPremintOverflow(validatedBaseUnits, decimalPlace);
|
|
206
244
|
|
|
207
|
-
|
|
245
|
+
c.addConstructorArgument({ type: 'address', name: 'recipient' });
|
|
208
246
|
|
|
209
|
-
|
|
210
|
-
if (premintChainId === '') {
|
|
211
|
-
throw new OptionsError({
|
|
212
|
-
premintChainId: 'Chain ID is required when using Premint with Cross-Chain Bridging',
|
|
213
|
-
});
|
|
214
|
-
}
|
|
247
|
+
const mintLine = `_mint(recipient, ${units} * 10 ** ${exp});`;
|
|
215
248
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
249
|
+
if (crossChainBridging) {
|
|
250
|
+
if (premintChainId === '') {
|
|
251
|
+
throw new OptionsError({
|
|
252
|
+
premintChainId: 'Chain ID is required when using Premint with Cross-Chain Bridging',
|
|
253
|
+
});
|
|
254
|
+
}
|
|
221
255
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
c.addConstructorCode(mintLine);
|
|
227
|
-
}
|
|
256
|
+
if (!isValidChainId(premintChainId)) {
|
|
257
|
+
throw new OptionsError({
|
|
258
|
+
premintChainId: 'Not a valid chain ID',
|
|
259
|
+
});
|
|
228
260
|
}
|
|
261
|
+
|
|
262
|
+
c.addConstructorCode(`if (block.chainid == ${premintChainId}) {`);
|
|
263
|
+
c.addConstructorCode(` ${mintLine}`);
|
|
264
|
+
c.addConstructorCode(`}`);
|
|
229
265
|
} else {
|
|
230
|
-
|
|
231
|
-
premint: 'Not a valid number',
|
|
232
|
-
});
|
|
266
|
+
c.addConstructorCode(mintLine);
|
|
233
267
|
}
|
|
234
268
|
}
|
|
235
269
|
|
|
@@ -274,9 +308,14 @@ function addPermit(c: ContractBuilder, name: string) {
|
|
|
274
308
|
c.addOverride(ERC20Permit, functions.nonces);
|
|
275
309
|
}
|
|
276
310
|
|
|
277
|
-
function addVotes(c: ContractBuilder, clockMode: ClockMode) {
|
|
311
|
+
function addVotes(c: ContractBuilder, name: string, clockMode: ClockMode) {
|
|
278
312
|
if (!c.parents.some(p => p.contract.name === 'ERC20Permit')) {
|
|
279
|
-
|
|
313
|
+
// ERC20Permit initializes the EIP712 domain separator. If ERC20Permit is not a parent, we need to do it here.
|
|
314
|
+
const EIP712 = {
|
|
315
|
+
name: 'EIP712',
|
|
316
|
+
path: '@openzeppelin/contracts/utils/cryptography/EIP712.sol',
|
|
317
|
+
};
|
|
318
|
+
c.addParent(EIP712, [name, '1']);
|
|
280
319
|
}
|
|
281
320
|
|
|
282
321
|
const ERC20Votes = {
|
|
@@ -308,6 +347,40 @@ function addFlashMint(c: ContractBuilder) {
|
|
|
308
347
|
}
|
|
309
348
|
|
|
310
349
|
function addCrossChainBridging(
|
|
350
|
+
c: ContractBuilder,
|
|
351
|
+
crossChainBridging: 'custom' | 'erc7786native' | 'superchain',
|
|
352
|
+
crossChainLinkAllowOverride: boolean,
|
|
353
|
+
access: Access,
|
|
354
|
+
upgradeable: Upgradeable,
|
|
355
|
+
namespacePrefix: string,
|
|
356
|
+
) {
|
|
357
|
+
if (crossChainBridging === 'erc7786native') {
|
|
358
|
+
addERC20Crosschain(c, crossChainLinkAllowOverride, access);
|
|
359
|
+
} else {
|
|
360
|
+
addERC20Bridgeable(c, crossChainBridging, access, upgradeable, namespacePrefix);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function addERC20Crosschain(c: ContractBuilder, crossChainLinkAllowOverride: boolean, access: Access) {
|
|
365
|
+
c.addParent({
|
|
366
|
+
name: 'ERC20Crosschain',
|
|
367
|
+
path: '@openzeppelin/contracts/token/ERC20/extensions/ERC20Crosschain.sol',
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
c.addConstructionOnly(
|
|
371
|
+
{
|
|
372
|
+
name: 'CrosschainLinked',
|
|
373
|
+
path: '@openzeppelin/contracts/crosschain/CrosschainLinked.sol',
|
|
374
|
+
},
|
|
375
|
+
[{ lit: 'links' }],
|
|
376
|
+
);
|
|
377
|
+
c.addConstructorArgument({ type: 'CrosschainLinked.Link[] memory', name: 'links' });
|
|
378
|
+
|
|
379
|
+
requireAccessControl(c, functions.setLink, access, 'CROSSCHAIN_LINKER', 'crosschainLinker');
|
|
380
|
+
c.addFunctionCode(`_setLink(gateway, counterpart, ${crossChainLinkAllowOverride});`, functions.setLink);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
function addERC20Bridgeable(
|
|
311
384
|
c: ContractBuilder,
|
|
312
385
|
crossChainBridging: 'custom' | 'superchain',
|
|
313
386
|
access: Access,
|
|
@@ -339,31 +412,57 @@ function addCrossChainBridging(
|
|
|
339
412
|
}
|
|
340
413
|
|
|
341
414
|
function addCustomBridging(c: ContractBuilder, access: Access, upgradeable: Upgradeable, namespacePrefix: string) {
|
|
415
|
+
if (access === false) {
|
|
416
|
+
access = 'ownable';
|
|
417
|
+
}
|
|
418
|
+
|
|
342
419
|
switch (access) {
|
|
343
|
-
case false:
|
|
344
420
|
case 'ownable': {
|
|
345
421
|
if (!upgradeable) {
|
|
422
|
+
const LINES_CHECK_AND_SET_TOKEN_BRIDGE = [
|
|
423
|
+
`require(tokenBridge_ != address(0), "Invalid tokenBridge_ address");`,
|
|
424
|
+
`tokenBridge = tokenBridge_;`,
|
|
425
|
+
];
|
|
426
|
+
|
|
427
|
+
// Add variable and constructor logic using state variable
|
|
346
428
|
const addedBridge = c.addStateVariable(`address public tokenBridge;`, false);
|
|
347
429
|
if (addedBridge) {
|
|
348
430
|
c.addConstructorArgument({ type: 'address', name: 'tokenBridge_' });
|
|
349
|
-
|
|
350
|
-
|
|
431
|
+
LINES_CHECK_AND_SET_TOKEN_BRIDGE.forEach(line => {
|
|
432
|
+
c.addConstructorCode(line);
|
|
433
|
+
});
|
|
351
434
|
}
|
|
352
435
|
c.setFunctionBody([`if (caller != tokenBridge) revert Unauthorized();`], functions._checkTokenBridge, 'view');
|
|
436
|
+
|
|
437
|
+
// Add bridge setter
|
|
438
|
+
requireAccessControl(c, functions.setTokenBridge, access, 'TOKEN_BRIDGE_SETTER', 'tokenBridgeSetter');
|
|
439
|
+
LINES_CHECK_AND_SET_TOKEN_BRIDGE.forEach(line => {
|
|
440
|
+
c.addFunctionCode(line, functions.setTokenBridge);
|
|
441
|
+
});
|
|
353
442
|
} else {
|
|
443
|
+
const LINES_CHECK_AND_SET_TOKEN_BRIDGE = [
|
|
444
|
+
`require(tokenBridge_ != address(0), "Invalid tokenBridge_ address");`,
|
|
445
|
+
toStorageStructInstantiation(c.name),
|
|
446
|
+
'$.tokenBridge = tokenBridge_;',
|
|
447
|
+
];
|
|
448
|
+
|
|
449
|
+
// Add variable and constructor logic using namespaced storage
|
|
354
450
|
setNamespacedStorage(c, ['address tokenBridge;'], namespacePrefix);
|
|
355
451
|
|
|
356
452
|
c.addConstructorArgument({ type: 'address', name: 'tokenBridge_' });
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
c.addConstructorCode(`$.tokenBridge = tokenBridge_;`);
|
|
453
|
+
LINES_CHECK_AND_SET_TOKEN_BRIDGE.forEach(line => {
|
|
454
|
+
c.addConstructorCode(line);
|
|
455
|
+
});
|
|
361
456
|
|
|
362
457
|
c.setFunctionBody(
|
|
363
458
|
[toStorageStructInstantiation(c.name), `if (caller != $.tokenBridge) revert Unauthorized();`],
|
|
364
459
|
functions._checkTokenBridge,
|
|
365
460
|
'view',
|
|
366
461
|
);
|
|
462
|
+
|
|
463
|
+
// Add bridge setter
|
|
464
|
+
requireAccessControl(c, functions.setTokenBridge, access, 'TOKEN_BRIDGE_SETTER', 'tokenBridgeSetter');
|
|
465
|
+
c.setFunctionBody(LINES_CHECK_AND_SET_TOKEN_BRIDGE, functions.setTokenBridge);
|
|
367
466
|
}
|
|
368
467
|
break;
|
|
369
468
|
}
|
|
@@ -483,4 +582,17 @@ export const functions = defineFunctions({
|
|
|
483
582
|
kind: 'internal' as const,
|
|
484
583
|
args: [{ name: 'caller', type: 'address' }],
|
|
485
584
|
},
|
|
585
|
+
|
|
586
|
+
setTokenBridge: {
|
|
587
|
+
kind: 'public' as const,
|
|
588
|
+
args: [{ name: 'tokenBridge_', type: 'address' }],
|
|
589
|
+
},
|
|
590
|
+
|
|
591
|
+
setLink: {
|
|
592
|
+
kind: 'public' as const,
|
|
593
|
+
args: [
|
|
594
|
+
{ name: 'gateway', type: 'address' },
|
|
595
|
+
{ name: 'counterpart', type: 'bytes memory' },
|
|
596
|
+
],
|
|
597
|
+
},
|
|
486
598
|
});
|
package/src/generate/erc20.ts
CHANGED
|
@@ -7,27 +7,48 @@ import { generateAlternatives } from './alternatives';
|
|
|
7
7
|
|
|
8
8
|
const booleans = [true, false];
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const blueprintWithoutBasicFeatures = {
|
|
11
11
|
name: ['MyToken'],
|
|
12
12
|
symbol: ['MTK'],
|
|
13
|
-
burnable: booleans,
|
|
14
13
|
pausable: booleans,
|
|
15
14
|
mintable: booleans,
|
|
16
|
-
callback: booleans,
|
|
17
|
-
permit: booleans,
|
|
18
15
|
votes: [...booleans, ...clockModeOptions] as const,
|
|
19
|
-
flashmint: booleans,
|
|
20
16
|
premint: ['1'],
|
|
21
17
|
premintChainId: ['10'],
|
|
22
18
|
crossChainBridging: crossChainBridgingOptions,
|
|
19
|
+
crossChainLinkAllowOverride: [false],
|
|
23
20
|
access: accessOptions,
|
|
24
21
|
upgradeable: upgradeableOptions,
|
|
25
22
|
namespacePrefix: ['myProject'],
|
|
26
23
|
info: infoOptions,
|
|
27
24
|
};
|
|
28
25
|
|
|
26
|
+
// Basic features that do not depend on other features like access control
|
|
27
|
+
const basicFeatures = {
|
|
28
|
+
OFF: {
|
|
29
|
+
burnable: [false],
|
|
30
|
+
callback: [false],
|
|
31
|
+
permit: [false],
|
|
32
|
+
flashmint: [false],
|
|
33
|
+
},
|
|
34
|
+
ON: {
|
|
35
|
+
burnable: [true],
|
|
36
|
+
callback: [true],
|
|
37
|
+
permit: [true],
|
|
38
|
+
flashmint: [true],
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
29
42
|
export function* generateERC20Options(): Generator<Required<ERC20Options>> {
|
|
30
|
-
|
|
43
|
+
// Separate generation steps with basic features OFF and ON to avoid having too many combinations
|
|
44
|
+
for (const opts of generateAlternatives({ ...blueprintWithoutBasicFeatures, ...basicFeatures.OFF })) {
|
|
45
|
+
// crossChainBridging does not currently support upgradeable
|
|
46
|
+
if (!(opts.crossChainBridging && opts.upgradeable)) {
|
|
47
|
+
yield opts;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
for (const opts of generateAlternatives({ ...blueprintWithoutBasicFeatures, ...basicFeatures.ON })) {
|
|
31
52
|
// crossChainBridging does not currently support upgradeable
|
|
32
53
|
if (!(opts.crossChainBridging && opts.upgradeable)) {
|
|
33
54
|
yield opts;
|
|
@@ -19,6 +19,7 @@ const erc20Basic = {
|
|
|
19
19
|
premint: ['1'],
|
|
20
20
|
premintChainId: [''],
|
|
21
21
|
crossChainBridging: [false] as const,
|
|
22
|
+
crossChainLinkAllowOverride: [false] as const,
|
|
22
23
|
access: [false] as const,
|
|
23
24
|
info: [{}] as const,
|
|
24
25
|
namespacePrefix: ['myProject'],
|
|
@@ -37,6 +38,7 @@ const erc20Full = {
|
|
|
37
38
|
premint: ['1'],
|
|
38
39
|
premintChainId: ['10'],
|
|
39
40
|
crossChainBridging: crossChainBridgingOptions,
|
|
41
|
+
crossChainLinkAllowOverride: [true] as const,
|
|
40
42
|
access: accessOptions,
|
|
41
43
|
info: infoOptions,
|
|
42
44
|
namespacePrefix: ['myProject'],
|
package/src/index.ts
CHANGED
|
@@ -1,21 +1,37 @@
|
|
|
1
|
+
// ===== Public API =====
|
|
2
|
+
|
|
3
|
+
export { erc20, erc721, erc1155, stablecoin, realWorldAsset, account, governor, custom } from './api';
|
|
4
|
+
export type { WizardContractAPI, AccessControlAPI } from './api';
|
|
5
|
+
|
|
6
|
+
export type { ERC20Options } from './erc20';
|
|
7
|
+
export type { ERC721Options } from './erc721';
|
|
8
|
+
export type { ERC1155Options } from './erc1155';
|
|
9
|
+
export type { StablecoinOptions } from './stablecoin';
|
|
10
|
+
export type { AccountOptions } from './account';
|
|
11
|
+
export type { GovernorOptions } from './governor';
|
|
12
|
+
export type { CustomOptions } from './custom';
|
|
13
|
+
|
|
14
|
+
// ===== Internal API - Intended for use by other Wizard packages only =====
|
|
15
|
+
|
|
1
16
|
export type { GenericOptions, KindedOptions } from './build-generic';
|
|
2
17
|
export { buildGeneric } from './build-generic';
|
|
3
18
|
|
|
4
19
|
export { generateAlternatives } from './generate/alternatives';
|
|
5
20
|
|
|
6
|
-
export type { Contract, BaseFunction, Value, ReferencedContract } from './contract';
|
|
21
|
+
export type { Contract, BaseFunction, Value, ReferencedContract, FunctionArgument } from './contract';
|
|
7
22
|
export { ContractBuilder } from './contract';
|
|
8
23
|
|
|
9
24
|
export { printContract } from './print';
|
|
10
25
|
|
|
11
26
|
export type { Access } from './set-access-control';
|
|
27
|
+
export { accessOptions, setAccessControl, requireAccessControl } from './set-access-control';
|
|
28
|
+
export { addPausable } from './add-pausable';
|
|
12
29
|
export type { Upgradeable } from './set-upgradeable';
|
|
13
30
|
export type { Info } from './set-info';
|
|
14
31
|
|
|
15
32
|
export { premintPattern, chainIdPattern } from './erc20';
|
|
16
|
-
export { defaults as infoDefaults,
|
|
17
|
-
export {
|
|
18
|
-
export { addPausable } from './add-pausable';
|
|
33
|
+
export { defaults as infoDefaults, setInfo, infoOptions } from './set-info';
|
|
34
|
+
export { supportsInterface } from './common-functions';
|
|
19
35
|
|
|
20
36
|
export type { OptionsErrorMessages } from './error';
|
|
21
37
|
export { OptionsError } from './error';
|
|
@@ -23,21 +39,17 @@ export { OptionsError } from './error';
|
|
|
23
39
|
export type { Kind } from './kind';
|
|
24
40
|
export { sanitizeKind } from './kind';
|
|
25
41
|
|
|
26
|
-
export { erc20, erc721, erc1155, stablecoin, realWorldAsset, account, governor, custom } from './api';
|
|
27
|
-
export type { WizardContractAPI, AccessControlAPI } from './api';
|
|
28
|
-
|
|
29
42
|
export { compatibleContractsSemver } from './utils/version';
|
|
30
|
-
export { findCover } from './utils/find-cover';
|
|
31
|
-
export { defineFunctions } from './utils/define-functions';
|
|
32
43
|
|
|
44
|
+
export { defineFunctions } from './utils/define-functions';
|
|
33
45
|
export type { CommonOptions } from './common-options';
|
|
34
46
|
export { withCommonDefaults, defaults as commonDefaults } from './common-options';
|
|
35
|
-
export {
|
|
36
|
-
|
|
37
|
-
export
|
|
38
|
-
export type {
|
|
39
|
-
export type {
|
|
40
|
-
export
|
|
41
|
-
export
|
|
42
|
-
export type {
|
|
43
|
-
export
|
|
47
|
+
export type { ClockMode } from './set-clock-mode';
|
|
48
|
+
export { clockModeDefault, setClockMode, clockModeOptions } from './set-clock-mode';
|
|
49
|
+
export { toBigInt } from './utils/convert-strings';
|
|
50
|
+
export type { Options } from './options';
|
|
51
|
+
export type { Lines } from './utils/format-lines';
|
|
52
|
+
export { formatLinesWithSpaces, spaceBetween } from './utils/format-lines';
|
|
53
|
+
export { findCover } from './utils/find-cover';
|
|
54
|
+
export type { PremintCalculation } from './erc20';
|
|
55
|
+
export { calculatePremint as calculateERC20Premint, scaleByPowerOfTen } from './erc20';
|
package/src/options.ts
CHANGED
|
@@ -29,8 +29,10 @@ export interface Options {
|
|
|
29
29
|
transformImport?: (parent: ImportContract) => ImportContract;
|
|
30
30
|
/**
|
|
31
31
|
* Add additional libraries to the compatibility banner printed at the top of the contract.
|
|
32
|
+
*
|
|
33
|
+
* If `alwaysKeepOzPrefix` is true, the library name will always keep the "OpenZeppelin " prefix, even if there are multiple libraries from OpenZeppelin being imported.
|
|
32
34
|
*/
|
|
33
|
-
additionalCompatibleLibraries?: { name: string; path: string; version: string }[];
|
|
35
|
+
additionalCompatibleLibraries?: { name: string; path: string; version: string; alwaysKeepOzPrefix?: boolean }[];
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
export interface Helpers extends Required<Options> {
|