@openzeppelin/wizard 0.5.2 → 0.5.4
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 +10 -3
- package/dist/erc20.d.ts.map +1 -1
- package/dist/erc20.js +175 -14
- 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.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 +10 -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 +34 -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 +6 -12
- 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/convert-strings.d.ts +11 -0
- package/dist/utils/convert-strings.d.ts.map +1 -0
- package/dist/utils/convert-strings.js +30 -0
- package/dist/utils/convert-strings.js.map +1 -0
- 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 +2 -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 +234 -23
- package/src/erc721.ts +8 -4
- package/src/error.ts +1 -1
- package/src/generate/alternatives.ts +2 -8
- package/src/generate/erc20.ts +11 -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 +37 -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 +40 -43
- 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/convert-strings.ts +27 -0
- 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/erc1155.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { Contract
|
|
2
|
-
import {
|
|
1
|
+
import type { Contract } from './contract';
|
|
2
|
+
import { ContractBuilder } from './contract';
|
|
3
|
+
import type { Access } from './set-access-control';
|
|
4
|
+
import { setAccessControl, requireAccessControl } from './set-access-control';
|
|
3
5
|
import { addPauseFunctions } from './add-pausable';
|
|
4
6
|
import { supportsInterface } from './common-functions';
|
|
5
7
|
import { defineFunctions } from './utils/define-functions';
|
|
6
|
-
import { CommonOptions
|
|
8
|
+
import type { CommonOptions } from './common-options';
|
|
9
|
+
import { withCommonDefaults, defaults as commonDefaults } from './common-options';
|
|
7
10
|
import { setUpgradeable } from './set-upgradeable';
|
|
8
11
|
import { setInfo } from './set-info';
|
|
9
12
|
import { printContract } from './print';
|
|
@@ -28,7 +31,7 @@ export const defaults: Required<ERC1155Options> = {
|
|
|
28
31
|
updatableUri: true,
|
|
29
32
|
access: commonDefaults.access,
|
|
30
33
|
upgradeable: commonDefaults.upgradeable,
|
|
31
|
-
info: commonDefaults.info
|
|
34
|
+
info: commonDefaults.info,
|
|
32
35
|
} as const;
|
|
33
36
|
|
|
34
37
|
function withDefaults(opts: ERC1155Options): Required<ERC1155Options> {
|
|
@@ -150,9 +153,7 @@ const functions = defineFunctions({
|
|
|
150
153
|
|
|
151
154
|
setURI: {
|
|
152
155
|
kind: 'public' as const,
|
|
153
|
-
args: [
|
|
154
|
-
{ name: 'newuri', type: 'string memory' },
|
|
155
|
-
],
|
|
156
|
+
args: [{ name: 'newuri', type: 'string memory' }],
|
|
156
157
|
},
|
|
157
158
|
|
|
158
159
|
mint: {
|
package/src/erc20.ts
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Access
|
|
1
|
+
import { ContractBuilder } from './contract';
|
|
2
|
+
import type { Access } from './set-access-control';
|
|
3
|
+
import { setAccessControl, requireAccessControl } from './set-access-control';
|
|
3
4
|
import { addPauseFunctions } from './add-pausable';
|
|
4
5
|
import { defineFunctions } from './utils/define-functions';
|
|
5
|
-
import { CommonOptions
|
|
6
|
+
import type { CommonOptions } from './common-options';
|
|
7
|
+
import { withCommonDefaults, defaults as commonDefaults } from './common-options';
|
|
8
|
+
import type { Upgradeable } from './set-upgradeable';
|
|
6
9
|
import { setUpgradeable } from './set-upgradeable';
|
|
7
10
|
import { setInfo } from './set-info';
|
|
8
11
|
import { printContract } from './print';
|
|
9
|
-
import { ClockMode
|
|
12
|
+
import type { ClockMode } from './set-clock-mode';
|
|
13
|
+
import { clockModeDefault, setClockMode } from './set-clock-mode';
|
|
14
|
+
import { supportsInterface } from './common-functions';
|
|
15
|
+
import { OptionsError } from './error';
|
|
16
|
+
import { toUint256, UINT256_MAX } from './utils/convert-strings';
|
|
17
|
+
|
|
18
|
+
export const crossChainBridgingOptions = [false, 'custom', 'superchain'] as const;
|
|
19
|
+
export type CrossChainBridging = (typeof crossChainBridgingOptions)[number];
|
|
10
20
|
|
|
11
21
|
export interface ERC20Options extends CommonOptions {
|
|
12
22
|
name: string;
|
|
@@ -14,7 +24,9 @@ export interface ERC20Options extends CommonOptions {
|
|
|
14
24
|
burnable?: boolean;
|
|
15
25
|
pausable?: boolean;
|
|
16
26
|
premint?: string;
|
|
27
|
+
premintChainId?: string;
|
|
17
28
|
mintable?: boolean;
|
|
29
|
+
callback?: boolean;
|
|
18
30
|
permit?: boolean;
|
|
19
31
|
/**
|
|
20
32
|
* Whether to keep track of historical balances for voting in on-chain governance, and optionally specify the clock mode.
|
|
@@ -22,6 +34,7 @@ export interface ERC20Options extends CommonOptions {
|
|
|
22
34
|
*/
|
|
23
35
|
votes?: boolean | ClockMode;
|
|
24
36
|
flashmint?: boolean;
|
|
37
|
+
crossChainBridging?: CrossChainBridging;
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
export const defaults: Required<ERC20Options> = {
|
|
@@ -30,10 +43,13 @@ export const defaults: Required<ERC20Options> = {
|
|
|
30
43
|
burnable: false,
|
|
31
44
|
pausable: false,
|
|
32
45
|
premint: '0',
|
|
46
|
+
premintChainId: '',
|
|
33
47
|
mintable: false,
|
|
48
|
+
callback: false,
|
|
34
49
|
permit: true,
|
|
35
50
|
votes: false,
|
|
36
51
|
flashmint: false,
|
|
52
|
+
crossChainBridging: false,
|
|
37
53
|
access: commonDefaults.access,
|
|
38
54
|
upgradeable: commonDefaults.upgradeable,
|
|
39
55
|
info: commonDefaults.info,
|
|
@@ -46,10 +62,13 @@ export function withDefaults(opts: ERC20Options): Required<ERC20Options> {
|
|
|
46
62
|
burnable: opts.burnable ?? defaults.burnable,
|
|
47
63
|
pausable: opts.pausable ?? defaults.pausable,
|
|
48
64
|
premint: opts.premint || defaults.premint,
|
|
65
|
+
premintChainId: opts.premintChainId || defaults.premintChainId,
|
|
49
66
|
mintable: opts.mintable ?? defaults.mintable,
|
|
67
|
+
callback: opts.callback ?? defaults.callback,
|
|
50
68
|
permit: opts.permit ?? defaults.permit,
|
|
51
69
|
votes: opts.votes ?? defaults.votes,
|
|
52
70
|
flashmint: opts.flashmint ?? defaults.flashmint,
|
|
71
|
+
crossChainBridging: opts.crossChainBridging ?? defaults.crossChainBridging,
|
|
53
72
|
};
|
|
54
73
|
}
|
|
55
74
|
|
|
@@ -70,6 +89,14 @@ export function buildERC20(opts: ERC20Options): ContractBuilder {
|
|
|
70
89
|
|
|
71
90
|
addBase(c, allOpts.name, allOpts.symbol);
|
|
72
91
|
|
|
92
|
+
if (allOpts.crossChainBridging) {
|
|
93
|
+
addCrossChainBridging(c, allOpts.crossChainBridging, allOpts.upgradeable, access);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (allOpts.premint) {
|
|
97
|
+
addPremint(c, allOpts.premint, allOpts.premintChainId, allOpts.crossChainBridging);
|
|
98
|
+
}
|
|
99
|
+
|
|
73
100
|
if (allOpts.burnable) {
|
|
74
101
|
addBurnable(c);
|
|
75
102
|
}
|
|
@@ -78,14 +105,14 @@ export function buildERC20(opts: ERC20Options): ContractBuilder {
|
|
|
78
105
|
addPausableExtension(c, access);
|
|
79
106
|
}
|
|
80
107
|
|
|
81
|
-
if (allOpts.premint) {
|
|
82
|
-
addPremint(c, allOpts.premint);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
108
|
if (allOpts.mintable) {
|
|
86
109
|
addMintable(c, access);
|
|
87
110
|
}
|
|
88
111
|
|
|
112
|
+
if (allOpts.callback) {
|
|
113
|
+
addCallback(c);
|
|
114
|
+
}
|
|
115
|
+
|
|
89
116
|
// Note: Votes requires Permit
|
|
90
117
|
if (allOpts.permit || allOpts.votes) {
|
|
91
118
|
addPermit(c, allOpts.name);
|
|
@@ -112,10 +139,7 @@ function addBase(c: ContractBuilder, name: string, symbol: string) {
|
|
|
112
139
|
name: 'ERC20',
|
|
113
140
|
path: '@openzeppelin/contracts/token/ERC20/ERC20.sol',
|
|
114
141
|
};
|
|
115
|
-
c.addParent(
|
|
116
|
-
ERC20,
|
|
117
|
-
[name, symbol],
|
|
118
|
-
);
|
|
142
|
+
c.addParent(ERC20, [name, symbol]);
|
|
119
143
|
|
|
120
144
|
c.addOverride(ERC20, functions._update);
|
|
121
145
|
c.addOverride(ERC20, functions._approve); // allows override from stablecoin
|
|
@@ -141,7 +165,26 @@ function addBurnable(c: ContractBuilder) {
|
|
|
141
165
|
|
|
142
166
|
export const premintPattern = /^(\d*)(?:\.(\d+))?(?:e(\d+))?$/;
|
|
143
167
|
|
|
144
|
-
|
|
168
|
+
export const chainIdPattern = /^(?!$)[1-9]\d*$/;
|
|
169
|
+
|
|
170
|
+
export function isValidChainId(str: string): boolean {
|
|
171
|
+
return chainIdPattern.test(str);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function scaleByPowerOfTen(base: bigint, exponent: number): bigint {
|
|
175
|
+
if (exponent < 0) {
|
|
176
|
+
return base / BigInt(10) ** BigInt(-exponent);
|
|
177
|
+
} else {
|
|
178
|
+
return base * BigInt(10) ** BigInt(exponent);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function addPremint(
|
|
183
|
+
c: ContractBuilder,
|
|
184
|
+
amount: string,
|
|
185
|
+
premintChainId: string,
|
|
186
|
+
crossChainBridging: CrossChainBridging,
|
|
187
|
+
) {
|
|
145
188
|
const m = amount.match(premintPattern);
|
|
146
189
|
if (m) {
|
|
147
190
|
const integer = m[1]?.replace(/^0+/, '') ?? '';
|
|
@@ -153,9 +196,56 @@ function addPremint(c: ContractBuilder, amount: string) {
|
|
|
153
196
|
const zeroes = new Array(Math.max(0, -decimalPlace)).fill('0').join('');
|
|
154
197
|
const units = integer + decimals + zeroes;
|
|
155
198
|
const exp = decimalPlace <= 0 ? 'decimals()' : `(decimals() - ${decimalPlace})`;
|
|
156
|
-
|
|
157
|
-
|
|
199
|
+
|
|
200
|
+
const validatedBaseUnits = toUint256(units, 'premint');
|
|
201
|
+
checkPotentialPremintOverflow(validatedBaseUnits, decimalPlace);
|
|
202
|
+
|
|
203
|
+
c.addConstructorArgument({ type: 'address', name: 'recipient' });
|
|
204
|
+
|
|
205
|
+
const mintLine = `_mint(recipient, ${units} * 10 ** ${exp});`;
|
|
206
|
+
|
|
207
|
+
if (crossChainBridging) {
|
|
208
|
+
if (premintChainId === '') {
|
|
209
|
+
throw new OptionsError({
|
|
210
|
+
premintChainId: 'Chain ID is required when using Premint with Cross-Chain Bridging',
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (!isValidChainId(premintChainId)) {
|
|
215
|
+
throw new OptionsError({
|
|
216
|
+
premintChainId: 'Not a valid chain ID',
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
c.addConstructorCode(`if (block.chainid == ${premintChainId}) {`);
|
|
221
|
+
c.addConstructorCode(` ${mintLine}`);
|
|
222
|
+
c.addConstructorCode(`}`);
|
|
223
|
+
} else {
|
|
224
|
+
c.addConstructorCode(mintLine);
|
|
225
|
+
}
|
|
158
226
|
}
|
|
227
|
+
} else {
|
|
228
|
+
throw new OptionsError({
|
|
229
|
+
premint: 'Not a valid number',
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Check for potential premint overflow assuming the user's contract has decimals() = 18
|
|
236
|
+
*
|
|
237
|
+
* @param baseUnits The base units of the token, before applying power of 10
|
|
238
|
+
* @param decimalPlace If positive, the number of assumed decimal places in the least significant digits of `validatedBaseUnits`. Ignored if <= 0.
|
|
239
|
+
* @throws OptionsError if the calculated value would overflow uint256
|
|
240
|
+
*/
|
|
241
|
+
function checkPotentialPremintOverflow(baseUnits: bigint, decimalPlace: number) {
|
|
242
|
+
const assumedExp = decimalPlace <= 0 ? 18 : 18 - decimalPlace;
|
|
243
|
+
const calculatedValue = scaleByPowerOfTen(baseUnits, assumedExp);
|
|
244
|
+
|
|
245
|
+
if (calculatedValue > UINT256_MAX) {
|
|
246
|
+
throw new OptionsError({
|
|
247
|
+
premint: 'Amount would overflow uint256 after applying decimals',
|
|
248
|
+
});
|
|
159
249
|
}
|
|
160
250
|
}
|
|
161
251
|
|
|
@@ -164,6 +254,15 @@ function addMintable(c: ContractBuilder, access: Access) {
|
|
|
164
254
|
c.addFunctionCode('_mint(to, amount);', functions.mint);
|
|
165
255
|
}
|
|
166
256
|
|
|
257
|
+
function addCallback(c: ContractBuilder) {
|
|
258
|
+
const ERC1363 = {
|
|
259
|
+
name: 'ERC1363',
|
|
260
|
+
path: '@openzeppelin/contracts/token/ERC20/extensions/ERC1363.sol',
|
|
261
|
+
};
|
|
262
|
+
c.addParent(ERC1363);
|
|
263
|
+
c.addOverride(ERC1363, supportsInterface);
|
|
264
|
+
}
|
|
265
|
+
|
|
167
266
|
function addPermit(c: ContractBuilder, name: string) {
|
|
168
267
|
const ERC20Permit = {
|
|
169
268
|
name: 'ERC20Permit',
|
|
@@ -171,7 +270,6 @@ function addPermit(c: ContractBuilder, name: string) {
|
|
|
171
270
|
};
|
|
172
271
|
c.addParent(ERC20Permit, [name]);
|
|
173
272
|
c.addOverride(ERC20Permit, functions.nonces);
|
|
174
|
-
|
|
175
273
|
}
|
|
176
274
|
|
|
177
275
|
function addVotes(c: ContractBuilder, clockMode: ClockMode) {
|
|
@@ -190,9 +288,12 @@ function addVotes(c: ContractBuilder, clockMode: ClockMode) {
|
|
|
190
288
|
name: 'Nonces',
|
|
191
289
|
path: '@openzeppelin/contracts/utils/Nonces.sol',
|
|
192
290
|
});
|
|
193
|
-
c.addOverride(
|
|
194
|
-
|
|
195
|
-
|
|
291
|
+
c.addOverride(
|
|
292
|
+
{
|
|
293
|
+
name: 'Nonces',
|
|
294
|
+
},
|
|
295
|
+
functions.nonces,
|
|
296
|
+
);
|
|
196
297
|
|
|
197
298
|
setClockMode(c, ERC20Votes, clockMode);
|
|
198
299
|
}
|
|
@@ -204,6 +305,113 @@ function addFlashMint(c: ContractBuilder) {
|
|
|
204
305
|
});
|
|
205
306
|
}
|
|
206
307
|
|
|
308
|
+
function addCrossChainBridging(
|
|
309
|
+
c: ContractBuilder,
|
|
310
|
+
crossChainBridging: 'custom' | 'superchain',
|
|
311
|
+
upgradeable: Upgradeable,
|
|
312
|
+
access: Access,
|
|
313
|
+
) {
|
|
314
|
+
const ERC20Bridgeable = {
|
|
315
|
+
name: 'ERC20Bridgeable',
|
|
316
|
+
path: `@openzeppelin/community-contracts/contracts/token/ERC20/extensions/ERC20Bridgeable.sol`,
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
c.addParent(ERC20Bridgeable);
|
|
320
|
+
c.addOverride(ERC20Bridgeable, supportsInterface);
|
|
321
|
+
|
|
322
|
+
if (upgradeable) {
|
|
323
|
+
throw new OptionsError({
|
|
324
|
+
crossChainBridging: 'Upgradeability is not currently supported with Cross-Chain Bridging',
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
c.addOverride(ERC20Bridgeable, functions._checkTokenBridge);
|
|
329
|
+
switch (crossChainBridging) {
|
|
330
|
+
case 'custom':
|
|
331
|
+
addCustomBridging(c, access);
|
|
332
|
+
break;
|
|
333
|
+
case 'superchain':
|
|
334
|
+
addSuperchainERC20(c);
|
|
335
|
+
break;
|
|
336
|
+
default: {
|
|
337
|
+
const _: never = crossChainBridging;
|
|
338
|
+
throw new Error('Unknown value for `crossChainBridging`');
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
c.addVariable('error Unauthorized();');
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function addCustomBridging(c: ContractBuilder, access: Access) {
|
|
345
|
+
switch (access) {
|
|
346
|
+
case false:
|
|
347
|
+
case 'ownable': {
|
|
348
|
+
const addedBridgeImmutable = c.addVariable(`address public immutable TOKEN_BRIDGE;`);
|
|
349
|
+
if (addedBridgeImmutable) {
|
|
350
|
+
c.addConstructorArgument({ type: 'address', name: 'tokenBridge' });
|
|
351
|
+
c.addConstructorCode(`require(tokenBridge != address(0), "Invalid TOKEN_BRIDGE address");`);
|
|
352
|
+
c.addConstructorCode(`TOKEN_BRIDGE = tokenBridge;`);
|
|
353
|
+
}
|
|
354
|
+
c.setFunctionBody([`if (caller != TOKEN_BRIDGE) revert Unauthorized();`], functions._checkTokenBridge, 'view');
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case 'roles': {
|
|
358
|
+
setAccessControl(c, access);
|
|
359
|
+
const roleOwner = 'tokenBridge';
|
|
360
|
+
const roleId = 'TOKEN_BRIDGE_ROLE';
|
|
361
|
+
const addedRoleConstant = c.addVariable(`bytes32 public constant ${roleId} = keccak256("${roleId}");`);
|
|
362
|
+
if (addedRoleConstant) {
|
|
363
|
+
c.addConstructorArgument({ type: 'address', name: roleOwner });
|
|
364
|
+
c.addConstructorCode(`_grantRole(${roleId}, ${roleOwner});`);
|
|
365
|
+
}
|
|
366
|
+
c.setFunctionBody(
|
|
367
|
+
[`if (!hasRole(${roleId}, caller)) revert Unauthorized();`],
|
|
368
|
+
functions._checkTokenBridge,
|
|
369
|
+
'view',
|
|
370
|
+
);
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
case 'managed': {
|
|
374
|
+
setAccessControl(c, access);
|
|
375
|
+
c.addImportOnly({
|
|
376
|
+
name: 'AuthorityUtils',
|
|
377
|
+
path: `@openzeppelin/contracts/access/manager/AuthorityUtils.sol`,
|
|
378
|
+
});
|
|
379
|
+
c.setFunctionBody(
|
|
380
|
+
[
|
|
381
|
+
`(bool immediate,) = AuthorityUtils.canCallWithDelay(authority(), caller, address(this), bytes4(_msgData()[0:4]));`,
|
|
382
|
+
`if (!immediate) revert Unauthorized();`,
|
|
383
|
+
],
|
|
384
|
+
functions._checkTokenBridge,
|
|
385
|
+
'view',
|
|
386
|
+
);
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
389
|
+
default: {
|
|
390
|
+
const _: never = access;
|
|
391
|
+
throw new Error('Unknown value for `access`');
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function addSuperchainERC20(c: ContractBuilder) {
|
|
397
|
+
c.addVariable('address internal constant SUPERCHAIN_TOKEN_BRIDGE = 0x4200000000000000000000000000000000000028;');
|
|
398
|
+
c.setFunctionBody(
|
|
399
|
+
['if (caller != SUPERCHAIN_TOKEN_BRIDGE) revert Unauthorized();'],
|
|
400
|
+
functions._checkTokenBridge,
|
|
401
|
+
'pure',
|
|
402
|
+
);
|
|
403
|
+
c.setFunctionComments(
|
|
404
|
+
[
|
|
405
|
+
'/**',
|
|
406
|
+
' * @dev Checks if the caller is the predeployed SuperchainTokenBridge. Reverts otherwise.',
|
|
407
|
+
' *',
|
|
408
|
+
' * IMPORTANT: The predeployed SuperchainTokenBridge is only available on chains in the Superchain.',
|
|
409
|
+
' */',
|
|
410
|
+
],
|
|
411
|
+
functions._checkTokenBridge,
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
207
415
|
export const functions = defineFunctions({
|
|
208
416
|
_update: {
|
|
209
417
|
kind: 'internal' as const,
|
|
@@ -249,10 +457,13 @@ export const functions = defineFunctions({
|
|
|
249
457
|
|
|
250
458
|
nonces: {
|
|
251
459
|
kind: 'public' as const,
|
|
252
|
-
args: [
|
|
253
|
-
{ name: 'owner', type: 'address' },
|
|
254
|
-
],
|
|
460
|
+
args: [{ name: 'owner', type: 'address' }],
|
|
255
461
|
returns: ['uint256'],
|
|
256
462
|
mutability: 'view' as const,
|
|
257
|
-
}
|
|
463
|
+
},
|
|
464
|
+
|
|
465
|
+
_checkTokenBridge: {
|
|
466
|
+
kind: 'internal' as const,
|
|
467
|
+
args: [{ name: 'caller', type: 'address' }],
|
|
468
|
+
},
|
|
258
469
|
});
|
package/src/erc721.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { BaseFunction, Contract
|
|
2
|
-
import {
|
|
1
|
+
import type { BaseFunction, Contract } from './contract';
|
|
2
|
+
import { ContractBuilder } from './contract';
|
|
3
|
+
import type { Access } from './set-access-control';
|
|
4
|
+
import { setAccessControl, requireAccessControl } from './set-access-control';
|
|
3
5
|
import { addPauseFunctions } from './add-pausable';
|
|
4
6
|
import { supportsInterface } from './common-functions';
|
|
5
7
|
import { defineFunctions } from './utils/define-functions';
|
|
6
|
-
import { CommonOptions
|
|
8
|
+
import type { CommonOptions } from './common-options';
|
|
9
|
+
import { withCommonDefaults, defaults as commonDefaults } from './common-options';
|
|
7
10
|
import { setUpgradeable } from './set-upgradeable';
|
|
8
11
|
import { setInfo } from './set-info';
|
|
9
12
|
import { printContract } from './print';
|
|
10
|
-
import { ClockMode
|
|
13
|
+
import type { ClockMode } from './set-clock-mode';
|
|
14
|
+
import { clockModeDefault, setClockMode } from './set-clock-mode';
|
|
11
15
|
|
|
12
16
|
export interface ERC721Options extends CommonOptions {
|
|
13
17
|
name: string;
|
package/src/error.ts
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import { mapValues } from "../utils/map-values";
|
|
2
|
-
|
|
3
1
|
type Blueprint = Record<string, readonly unknown[]>;
|
|
4
2
|
|
|
5
3
|
type Alternatives<B extends Blueprint> = {
|
|
6
4
|
[k in keyof B]: B[k][number];
|
|
7
5
|
};
|
|
8
6
|
|
|
9
|
-
export function* generateAlternatives<B extends Blueprint>(
|
|
10
|
-
blueprint: B,
|
|
11
|
-
): Generator<Alternatives<B>> {
|
|
7
|
+
export function* generateAlternatives<B extends Blueprint>(blueprint: B): Generator<Alternatives<B>> {
|
|
12
8
|
const entries = Object.entries(blueprint).map(([key, values]) => ({
|
|
13
9
|
key,
|
|
14
10
|
values,
|
|
@@ -17,9 +13,7 @@ export function* generateAlternatives<B extends Blueprint>(
|
|
|
17
13
|
}));
|
|
18
14
|
|
|
19
15
|
for (; !done(); advance()) {
|
|
20
|
-
yield Object.fromEntries(
|
|
21
|
-
entries.map(e => [e.key, e.values[e.current % e.limit]]),
|
|
22
|
-
) as Alternatives<B>;
|
|
16
|
+
yield Object.fromEntries(entries.map(e => [e.key, e.values[e.current % e.limit]])) as Alternatives<B>;
|
|
23
17
|
}
|
|
24
18
|
|
|
25
19
|
function done() {
|
package/src/generate/erc20.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { crossChainBridgingOptions, type ERC20Options } from '../erc20';
|
|
2
2
|
import { accessOptions } from '../set-access-control';
|
|
3
3
|
import { clockModeOptions } from '../set-clock-mode';
|
|
4
4
|
import { infoOptions } from '../set-info';
|
|
@@ -13,15 +13,23 @@ const blueprint = {
|
|
|
13
13
|
burnable: booleans,
|
|
14
14
|
pausable: booleans,
|
|
15
15
|
mintable: booleans,
|
|
16
|
+
callback: booleans,
|
|
16
17
|
permit: booleans,
|
|
17
|
-
votes: [
|
|
18
|
+
votes: [...booleans, ...clockModeOptions] as const,
|
|
18
19
|
flashmint: booleans,
|
|
19
20
|
premint: ['1'],
|
|
21
|
+
premintChainId: ['10'],
|
|
22
|
+
crossChainBridging: crossChainBridgingOptions,
|
|
20
23
|
access: accessOptions,
|
|
21
24
|
upgradeable: upgradeableOptions,
|
|
22
25
|
info: infoOptions,
|
|
23
26
|
};
|
|
24
27
|
|
|
25
28
|
export function* generateERC20Options(): Generator<Required<ERC20Options>> {
|
|
26
|
-
|
|
29
|
+
for (const opts of generateAlternatives(blueprint)) {
|
|
30
|
+
// crossChainBridging does not currently support upgradeable
|
|
31
|
+
if (!(opts.crossChainBridging && opts.upgradeable)) {
|
|
32
|
+
yield opts;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
27
35
|
}
|
package/src/generate/erc721.ts
CHANGED
|
@@ -20,7 +20,7 @@ const blueprint = {
|
|
|
20
20
|
access: accessOptions,
|
|
21
21
|
upgradeable: upgradeableOptions,
|
|
22
22
|
info: infoOptions,
|
|
23
|
-
votes: [
|
|
23
|
+
votes: [...booleans, ...clockModeOptions] as const,
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
export function* generateERC721Options(): Generator<Required<ERC721Options>> {
|
package/src/generate/governor.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { GovernorOptions } from '../governor';
|
|
2
|
+
import { defaults, timelockOptions, votesOptions } from '../governor';
|
|
2
3
|
import { accessOptions } from '../set-access-control';
|
|
3
4
|
import { clockModeOptions } from '../set-clock-mode';
|
|
4
5
|
import { infoOptions } from '../set-info';
|
package/src/generate/sources.ts
CHANGED
|
@@ -8,7 +8,8 @@ import { generateERC1155Options } from './erc1155';
|
|
|
8
8
|
import { generateStablecoinOptions } from './stablecoin';
|
|
9
9
|
import { generateGovernorOptions } from './governor';
|
|
10
10
|
import { generateCustomOptions } from './custom';
|
|
11
|
-
import {
|
|
11
|
+
import type { GenericOptions, KindedOptions } from '../build-generic';
|
|
12
|
+
import { buildGeneric } from '../build-generic';
|
|
12
13
|
import { printContract } from '../print';
|
|
13
14
|
import { OptionsError } from '../error';
|
|
14
15
|
import { findCover } from '../utils/find-cover';
|
|
@@ -76,11 +77,7 @@ function generateContractSubset(subset: Subset, kind?: Kind): GeneratedContract[
|
|
|
76
77
|
const contracts = [];
|
|
77
78
|
|
|
78
79
|
for (const options of generateOptions(kind)) {
|
|
79
|
-
const id = crypto
|
|
80
|
-
.createHash('sha1')
|
|
81
|
-
.update(JSON.stringify(options))
|
|
82
|
-
.digest()
|
|
83
|
-
.toString('hex');
|
|
80
|
+
const id = crypto.createHash('sha1').update(JSON.stringify(options)).digest().toString('hex');
|
|
84
81
|
|
|
85
82
|
try {
|
|
86
83
|
const contract = buildGeneric(options);
|
|
@@ -99,8 +96,14 @@ function generateContractSubset(subset: Subset, kind?: Kind): GeneratedContract[
|
|
|
99
96
|
} else {
|
|
100
97
|
const getParents = (c: GeneratedContract) => c.contract.parents.map(p => p.contract.path);
|
|
101
98
|
return [
|
|
102
|
-
...findCover(
|
|
103
|
-
|
|
99
|
+
...findCover(
|
|
100
|
+
contracts.filter(c => c.options.upgradeable),
|
|
101
|
+
getParents,
|
|
102
|
+
),
|
|
103
|
+
...findCover(
|
|
104
|
+
contracts.filter(c => !c.options.upgradeable),
|
|
105
|
+
getParents,
|
|
106
|
+
),
|
|
104
107
|
];
|
|
105
108
|
}
|
|
106
109
|
}
|
|
@@ -1,31 +1,52 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { crossChainBridgingOptions } from '../erc20';
|
|
2
2
|
import { accessOptions } from '../set-access-control';
|
|
3
|
-
import { clockModeOptions } from '../set-clock-mode';
|
|
4
3
|
import { infoOptions } from '../set-info';
|
|
5
|
-
import {
|
|
4
|
+
import type { StablecoinOptions } from '../stablecoin';
|
|
6
5
|
import { generateAlternatives } from './alternatives';
|
|
7
6
|
|
|
8
7
|
const booleans = [true, false];
|
|
9
8
|
|
|
10
|
-
const
|
|
9
|
+
const erc20Basic = {
|
|
11
10
|
name: ['MyStablecoin'],
|
|
12
11
|
symbol: ['MST'],
|
|
13
|
-
burnable:
|
|
14
|
-
pausable:
|
|
15
|
-
mintable:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
votes: [
|
|
19
|
-
flashmint:
|
|
12
|
+
burnable: [false] as const,
|
|
13
|
+
pausable: [false] as const,
|
|
14
|
+
mintable: [false] as const,
|
|
15
|
+
callback: [false] as const,
|
|
16
|
+
permit: [false] as const,
|
|
17
|
+
votes: [false] as const,
|
|
18
|
+
flashmint: [false] as const,
|
|
20
19
|
premint: ['1'],
|
|
21
|
-
|
|
20
|
+
premintChainId: [''],
|
|
21
|
+
crossChainBridging: [false] as const,
|
|
22
|
+
access: [false] as const,
|
|
23
|
+
info: [{}] as const,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const erc20Full = {
|
|
27
|
+
name: ['MyStablecoin'],
|
|
28
|
+
symbol: ['MST'],
|
|
29
|
+
burnable: [true] as const,
|
|
30
|
+
pausable: [true] as const,
|
|
31
|
+
mintable: [true] as const,
|
|
32
|
+
callback: [true] as const,
|
|
33
|
+
permit: [true] as const,
|
|
34
|
+
votes: ['timestamp'] as const,
|
|
35
|
+
flashmint: [true] as const,
|
|
36
|
+
premint: ['1'],
|
|
37
|
+
premintChainId: ['10'],
|
|
38
|
+
crossChainBridging: crossChainBridgingOptions,
|
|
22
39
|
access: accessOptions,
|
|
23
|
-
upgradeable: upgradeableOptions,
|
|
24
40
|
info: infoOptions,
|
|
25
41
|
};
|
|
26
42
|
|
|
43
|
+
const stablecoinExtensions = {
|
|
44
|
+
limitations: [false, 'allowlist', 'blocklist'] as const,
|
|
45
|
+
custodian: booleans,
|
|
46
|
+
upgradeable: [false] as const,
|
|
47
|
+
};
|
|
48
|
+
|
|
27
49
|
export function* generateStablecoinOptions(): Generator<Required<StablecoinOptions>> {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
50
|
+
yield* generateAlternatives({ ...erc20Basic, ...stablecoinExtensions });
|
|
51
|
+
yield* generateAlternatives({ ...erc20Full, ...stablecoinExtensions });
|
|
31
52
|
}
|
package/src/get-imports.ts
CHANGED
|
@@ -11,10 +11,10 @@ export interface SolcInputSources {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
* Gets the source code for all imports of a contract, including all transitive dependencies,
|
|
15
|
-
* in a format compatible with the Solidity compiler input's `sources` field.
|
|
16
|
-
*
|
|
17
|
-
* Does not include the contract itself (use `printContract` for that if needed).
|
|
14
|
+
* Gets the source code for all imports of a contract, including all transitive dependencies,
|
|
15
|
+
* in a format compatible with the Solidity compiler input's `sources` field.
|
|
16
|
+
*
|
|
17
|
+
* Does not include the contract itself (use `printContract` for that if needed).
|
|
18
18
|
*
|
|
19
19
|
* @param c The contract to get imports for.
|
|
20
20
|
* @returns A record of import paths to `content` that contains the source code for each contract.
|
|
@@ -42,4 +42,4 @@ export function getImports(c: Contract): SolcInputSources {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
return result;
|
|
45
|
-
}
|
|
45
|
+
}
|