@openzeppelin/wizard 0.6.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,10 +9,10 @@
9
9
  "author": "",
10
10
  "license": "ISC",
11
11
  "devDependencies": {
12
- "@openzeppelin/contracts": "^5.0.0",
13
- "@openzeppelin/contracts-upgradeable": "^5.0.0",
12
+ "@openzeppelin/contracts": "^5.4.0",
13
+ "@openzeppelin/contracts-upgradeable": "^5.4.0",
14
14
  "@openzeppelin/hardhat-upgrades": "^3.0.0",
15
- "@nomicfoundation/hardhat-toolbox": "^5.0.0",
15
+ "@nomicfoundation/hardhat-toolbox": "^6.1.0",
16
16
  "hardhat": "^2.16.1"
17
17
  }
18
18
  }
package/src/erc20.ts CHANGED
@@ -5,7 +5,6 @@ import { addPauseFunctions } from './add-pausable';
5
5
  import { defineFunctions } from './utils/define-functions';
6
6
  import type { CommonOptions } from './common-options';
7
7
  import { withCommonDefaults, defaults as commonDefaults } from './common-options';
8
- import type { Upgradeable } from './set-upgradeable';
9
8
  import { setUpgradeable } from './set-upgradeable';
10
9
  import { setInfo } from './set-info';
11
10
  import { printContract } from './print';
@@ -90,7 +89,7 @@ export function buildERC20(opts: ERC20Options): ContractBuilder {
90
89
  addBase(c, allOpts.name, allOpts.symbol);
91
90
 
92
91
  if (allOpts.crossChainBridging) {
93
- addCrossChainBridging(c, allOpts.crossChainBridging, allOpts.upgradeable, access);
92
+ addCrossChainBridging(c, allOpts.crossChainBridging, access);
94
93
  }
95
94
 
96
95
  if (allOpts.premint) {
@@ -305,26 +304,15 @@ function addFlashMint(c: ContractBuilder) {
305
304
  });
306
305
  }
307
306
 
308
- function addCrossChainBridging(
309
- c: ContractBuilder,
310
- crossChainBridging: 'custom' | 'superchain',
311
- upgradeable: Upgradeable,
312
- access: Access,
313
- ) {
307
+ function addCrossChainBridging(c: ContractBuilder, crossChainBridging: 'custom' | 'superchain', access: Access) {
314
308
  const ERC20Bridgeable = {
315
309
  name: 'ERC20Bridgeable',
316
- path: `@openzeppelin/community-contracts/token/ERC20/extensions/ERC20Bridgeable.sol`,
310
+ path: `@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Bridgeable.sol`,
317
311
  };
318
312
 
319
313
  c.addParent(ERC20Bridgeable);
320
314
  c.addOverride(ERC20Bridgeable, supportsInterface);
321
315
 
322
- if (upgradeable) {
323
- throw new OptionsError({
324
- crossChainBridging: 'Upgradeability is not currently supported with Cross-Chain Bridging',
325
- });
326
- }
327
-
328
316
  c.addOverride(ERC20Bridgeable, functions._checkTokenBridge);
329
317
  switch (crossChainBridging) {
330
318
  case 'custom':
@@ -345,13 +333,13 @@ function addCustomBridging(c: ContractBuilder, access: Access) {
345
333
  switch (access) {
346
334
  case false:
347
335
  case 'ownable': {
348
- const addedBridgeImmutable = c.addVariable(`address public immutable TOKEN_BRIDGE;`);
336
+ const addedBridgeImmutable = c.addVariable(`address public tokenBridge;`);
349
337
  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;`);
338
+ c.addConstructorArgument({ type: 'address', name: 'tokenBridge_' });
339
+ c.addConstructorCode(`require(tokenBridge_ != address(0), "Invalid tokenBridge_ address");`);
340
+ c.addConstructorCode(`tokenBridge = tokenBridge_;`);
353
341
  }
354
- c.setFunctionBody([`if (caller != TOKEN_BRIDGE) revert Unauthorized();`], functions._checkTokenBridge, 'view');
342
+ c.setFunctionBody([`if (caller != tokenBridge) revert Unauthorized();`], functions._checkTokenBridge, 'view');
355
343
  break;
356
344
  }
357
345
  case 'roles': {
package/src/print.ts CHANGED
@@ -17,6 +17,8 @@ import SOLIDITY_VERSION from './solidity-version.json';
17
17
  import { inferTranspiled } from './infer-transpiled';
18
18
  import { compatibleContractsSemver } from './utils/version';
19
19
  import { stringifyUnicodeSafe } from './utils/sanitize';
20
+ import { importsCommunityContracts } from './utils/imports-libraries';
21
+ import { getCommunityContractsGitCommit } from './utils/community-contracts-git-commit';
20
22
 
21
23
  export function printContract(contract: Contract, opts?: Options): string {
22
24
  const helpers = withHelpers(contract, opts);
@@ -29,7 +31,7 @@ export function printContract(contract: Contract, opts?: Options): string {
29
31
  ...spaceBetween(
30
32
  [
31
33
  `// SPDX-License-Identifier: ${contract.license}`,
32
- `// Compatible with OpenZeppelin Contracts ${compatibleContractsSemver}`,
34
+ printCompatibleLibraryVersions(contract),
33
35
  `pragma solidity ^${SOLIDITY_VERSION};`,
34
36
  ],
35
37
 
@@ -54,6 +56,19 @@ export function printContract(contract: Contract, opts?: Options): string {
54
56
  );
55
57
  }
56
58
 
59
+ function printCompatibleLibraryVersions(contract: Contract): string {
60
+ let result = `// Compatible with OpenZeppelin Contracts ${compatibleContractsSemver}`;
61
+ if (importsCommunityContracts(contract)) {
62
+ try {
63
+ const commit = getCommunityContractsGitCommit();
64
+ result += ` and Community Contracts commit ${commit}`;
65
+ } catch (e) {
66
+ console.error(e);
67
+ }
68
+ }
69
+ return result;
70
+ }
71
+
57
72
  function printInheritance(contract: Contract, { transformName }: Helpers): [] | [string] {
58
73
  if (contract.parents.length > 0) {
59
74
  return ['is ' + contract.parents.map(p => transformName(p.contract)).join(', ')];
@@ -0,0 +1,38 @@
1
+ import { devDependencies } from '../../package.json';
2
+
3
+ /**
4
+ * @returns The git commit hash of the @openzeppelin/community-contracts package dependency.
5
+ * @throws Error if the @openzeppelin/community-contracts package dependency is not found in devDependencies.
6
+ */
7
+ export function getCommunityContractsGitCommit(): string {
8
+ const communityContractsVersion = devDependencies['@openzeppelin/community-contracts'];
9
+ if (!communityContractsVersion) {
10
+ throw new Error('@openzeppelin/community-contracts not found in devDependencies');
11
+ }
12
+ return extractGitCommitHash('@openzeppelin/community-contracts', communityContractsVersion);
13
+ }
14
+
15
+ /**
16
+ * Extracts the git commit hash from a package dependency version string.
17
+ * The expected format is `git+<url>#<commit-hash>`.
18
+ *
19
+ * @param dependencyName The name of the package dependency.
20
+ * @param dependencyVersion The version string of the package dependency.
21
+ * @returns The git commit hash, normalized to lowercase.
22
+ * @throws Error if the version string or commit hash is not in the expected format.
23
+ */
24
+ export function extractGitCommitHash(dependencyName: string, dependencyVersion: string): string {
25
+ const split = dependencyVersion.split('#');
26
+ if (!dependencyVersion.startsWith('git+') || split.length !== 2) {
27
+ throw new Error(
28
+ `Expected package dependency for ${dependencyName} in format git+<url>#<commit-hash>, but got ${dependencyVersion}`,
29
+ );
30
+ }
31
+ const hash = split[1]!;
32
+ if (!/^[a-fA-F0-9]{7,40}$/.test(hash)) {
33
+ throw new Error(
34
+ `Expected git commit hash for package dependency ${dependencyName} to have between 7 and 40 hex chars, but got ${hash}`,
35
+ );
36
+ }
37
+ return hash.toLowerCase();
38
+ }
@@ -0,0 +1,5 @@
1
+ import type { Contract } from '../contract';
2
+
3
+ export function importsCommunityContracts(contract: Contract) {
4
+ return contract.imports.some(i => i.path.startsWith('@openzeppelin/community-contracts/'));
5
+ }
@@ -1,4 +1,4 @@
1
1
  /**
2
2
  * Semantic version string representing of the minimum compatible version of Contracts to display in output.
3
3
  */
4
- export const compatibleContractsSemver = '^5.0.0';
4
+ export const compatibleContractsSemver = '^5.4.0';