@openzeppelin/upgrades-core 1.34.4 → 1.35.0

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.35.0 (2024-07-31)
4
+
5
+ - Fix Hardhat compile error when public variables are used to implement interface functions. ([#1055](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1055))
6
+ - Remove non-struct NatSpec from Hardhat compilation step for namespaced storage layout validations. ([#1051](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1051))
7
+
3
8
  ## 1.34.4 (2024-07-22)
4
9
 
5
10
  - Fix Hardhat compile error when return parameter names are documented as param. ([#1050](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1050))
@@ -13,7 +13,8 @@ import { SolcInput, SolcOutput } from '../solc-api';
13
13
  *
14
14
  * @param input The original solc input.
15
15
  * @param output The original solc output.
16
+ * @param solcVersion The version of the solc compiler that was originally used to compile the input.
16
17
  * @returns The modified solc input with storage layout that includes namespaced type information.
17
18
  */
18
- export declare function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcInput;
19
+ export declare function makeNamespacedInput(input: SolcInput, output: SolcOutput, solcVersion?: string): SolcInput;
19
20
  //# sourceMappingURL=make-namespaced.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"make-namespaced.d.ts","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYpD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAwHnF"}
1
+ {"version":3,"file":"make-namespaced.d.ts","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYpD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAgIzG"}
@@ -24,9 +24,10 @@ const OUTPUT_SELECTION = {
24
24
  *
25
25
  * @param input The original solc input.
26
26
  * @param output The original solc output.
27
+ * @param solcVersion The version of the solc compiler that was originally used to compile the input.
27
28
  * @returns The modified solc input with storage layout that includes namespaced type information.
28
29
  */
29
- function makeNamespacedInput(input, output) {
30
+ function makeNamespacedInput(input, output, solcVersion) {
30
31
  const modifiedSources = {};
31
32
  for (const [sourcePath] of Object.entries(input.sources)) {
32
33
  const source = input.sources[sourcePath];
@@ -40,6 +41,11 @@ function makeNamespacedInput(input, output) {
40
41
  switch (node.nodeType) {
41
42
  case 'ContractDefinition': {
42
43
  const contractDef = node;
44
+ // Mark contracts as abstract, since state variables are converted to dummy enums
45
+ // which would not generate public getters for inherited interface functions
46
+ if (contractDef.contractKind === 'contract' && !contractDef.abstract) {
47
+ modifications.push(makeInsertBefore(contractDef, 'abstract '));
48
+ }
43
49
  // Remove any calls to parent constructors from the inheritance list
44
50
  const inherits = contractDef.baseContracts;
45
51
  for (const inherit of inherits) {
@@ -131,10 +137,59 @@ function makeNamespacedInput(input, output) {
131
137
  }
132
138
  }
133
139
  }
134
- modifiedSources[sourcePath] = { ...source, content: getModifiedSource(orig, modifications) };
140
+ const modifiedSource = tryRemoveNonStructNatSpec(getModifiedSource(orig, modifications), solcVersion);
141
+ modifiedSources[sourcePath] = { ...source, content: modifiedSource };
135
142
  }
136
143
  return { ...input, sources: modifiedSources, settings: { ...input.settings, outputSelection: OUTPUT_SELECTION } };
137
144
  }
145
+ /**
146
+ * If Slang is supported for the current platform and we have the compiler version available,
147
+ * use Slang to parse and remove all NatSpec comments that do not precede a struct definition and return the modified content.
148
+ *
149
+ * Otherwise, return the original content.
150
+ */
151
+ function tryRemoveNonStructNatSpec(origContent, solcVersion) {
152
+ const natSpecRemovals = [];
153
+ if (solcVersion !== undefined && tryRequire('@nomicfoundation/slang')) {
154
+ /* eslint-disable @typescript-eslint/no-var-requires */
155
+ const { Language } = require('@nomicfoundation/slang/language');
156
+ const { NonterminalKind, TerminalKind } = require('@nomicfoundation/slang/kinds');
157
+ const { TerminalNode } = require('@nomicfoundation/slang/cst');
158
+ const { isTrivia } = require('./slang/trivia');
159
+ /* eslint-enable @typescript-eslint/no-var-requires */
160
+ const language = new Language(solcVersion);
161
+ const parseOutput = language.parse(NonterminalKind.SourceUnit, origContent);
162
+ const cursor = parseOutput.createTreeCursor();
163
+ while (cursor.goToNextTerminalWithKinds([TerminalKind.MultiLineNatSpecComment, TerminalKind.SingleLineNatSpecComment])) {
164
+ // Lookahead to determine if the next non-trivia node is the struct keyword.
165
+ // If so, this NatSpec is part of the struct definition and should not be removed.
166
+ const lookaheadCursor = cursor.clone();
167
+ while (lookaheadCursor.goToNextTerminal() && isTrivia(lookaheadCursor.node())) {
168
+ // skip over trivia nodes
169
+ }
170
+ if (lookaheadCursor.node().kind === TerminalKind.StructKeyword) {
171
+ continue;
172
+ }
173
+ const triviaNode = cursor.node();
174
+ (0, assert_1.assert)(triviaNode instanceof TerminalNode);
175
+ natSpecRemovals.push(makeDeleteRange(cursor.textRange.start.utf8, cursor.textRange.end.utf8));
176
+ }
177
+ return getModifiedSource(Buffer.from(origContent, 'utf8'), natSpecRemovals);
178
+ }
179
+ else {
180
+ return origContent;
181
+ }
182
+ }
183
+ function tryRequire(id) {
184
+ try {
185
+ require(id);
186
+ return true;
187
+ }
188
+ catch (e) {
189
+ // do nothing
190
+ }
191
+ return false;
192
+ }
138
193
  function toDummyEnumWithName(name) {
139
194
  return `enum ${name} { dummy }`;
140
195
  }
@@ -177,6 +232,10 @@ function makeReplace(node, orig, text) {
177
232
  const { start, end } = makeDelete(node, orig);
178
233
  return { start, end, text };
179
234
  }
235
+ function makeInsertBefore(node, text) {
236
+ const { start } = getPositions(node);
237
+ return { start: start, end: start, text };
238
+ }
180
239
  function makeInsertAfter(node, text) {
181
240
  const { end } = getPositions(node);
182
241
  return { start: end, end, text };
@@ -193,7 +252,10 @@ function makeDelete(node, orig) {
193
252
  end += 1;
194
253
  }
195
254
  }
196
- return { start: positions.start, end };
255
+ return makeDeleteRange(positions.start, end);
256
+ }
257
+ function makeDeleteRange(start, end) {
258
+ return { start, end };
197
259
  }
198
260
  function getModifiedSource(orig, modifications) {
199
261
  let result = '';
@@ -1 +1 @@
1
- {"version":3,"file":"make-namespaced.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"make-namespaced.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.ts"],"names":[],"mappings":"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"}
@@ -11,18 +11,22 @@ const make_namespaced_1 = require("./make-namespaced");
11
11
  const origBuildInfo = await hardhat_1.artifacts.getBuildInfo('contracts/test/NamespacedToModifyImported.sol:Example');
12
12
  await testMakeNamespaced(origBuildInfo, t, '0.8.20');
13
13
  });
14
+ (0, ava_1.default)('make namespaced input - keep all natspec', async (t) => {
15
+ const origBuildInfo = await hardhat_1.artifacts.getBuildInfo('contracts/test/NamespacedToModifyImported.sol:Example');
16
+ await testMakeNamespaced(origBuildInfo, t, '0.8.20', true);
17
+ });
14
18
  (0, ava_1.default)('make namespaced input - solc 0.7', async (t) => {
15
19
  // The nameNamespacedInput function must work for different solc versions, since it is called before we check whether namespaces are used with solc >= 0.8.20
16
20
  const origBuildInfo = await hardhat_1.artifacts.getBuildInfo('contracts/test/NamespacedToModify07.sol:HasFunction');
17
21
  await testMakeNamespaced(origBuildInfo, t, '0.7.6');
18
22
  });
19
- async function testMakeNamespaced(origBuildInfo, t, solcVersion) {
23
+ async function testMakeNamespaced(origBuildInfo, t, solcVersion, keepAllNatSpec = false) {
20
24
  if (origBuildInfo === undefined) {
21
25
  throw new Error('Build info not found');
22
26
  }
23
27
  // Inefficient, but we want to test that we don't actually modify the original input object
24
28
  const origInput = JSON.parse(JSON.stringify(origBuildInfo.input));
25
- const modifiedInput = (0, make_namespaced_1.makeNamespacedInput)(origBuildInfo.input, origBuildInfo.output);
29
+ const modifiedInput = (0, make_namespaced_1.makeNamespacedInput)(origBuildInfo.input, origBuildInfo.output, keepAllNatSpec ? undefined : origBuildInfo.solcVersion);
26
30
  // Run hardhat compile on the modified input and make sure it has no errors
27
31
  const modifiedOutput = await hardhatCompile(modifiedInput, solcVersion);
28
32
  t.is(modifiedOutput.errors, undefined, JSON.stringify(modifiedInput.sources, null, 2));
@@ -37,6 +41,7 @@ function normalizeIdentifiers(input) {
37
41
  source.content = source.content
38
42
  .replace(/\$MainStorage_\d{1,6}/g, '$MainStorage_random')
39
43
  .replace(/\$SecondaryStorage_\d{1,6}/g, '$SecondaryStorage_random')
44
+ .replace(/\$StorageWithComment_\d{1,6}/g, '$StorageWithComment_random')
40
45
  .replace(/\$astId_\d+_\d{1,6}/g, '$astId_id_random');
41
46
  }
42
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"make-namespaced.test.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAA6C;AAC7C,qCAAyC;AACzC,iEAI0C;AAE1C,uDAAwD;AAKxD,IAAA,aAAI,EAAC,uBAAuB,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACtC,MAAM,aAAa,GAAG,MAAM,mBAAS,CAAC,YAAY,CAAC,uDAAuD,CAAC,CAAC;IAC5G,MAAM,kBAAkB,CAAC,aAAa,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,kCAAkC,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;IACjD,6JAA6J;IAC7J,MAAM,aAAa,GAAG,MAAM,mBAAS,CAAC,YAAY,CAAC,qDAAqD,CAAC,CAAC;IAC1G,MAAM,kBAAkB,CAAC,aAAa,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,kBAAkB,CAC/B,aAAoC,EACpC,CAA4B,EAC5B,WAAmB;IAEnB,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC1C,CAAC;IAED,2FAA2F;IAC3F,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IAElE,MAAM,aAAa,GAAG,IAAA,qCAAmB,EAAC,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAErF,2EAA2E;IAC3E,MAAM,cAAc,GAAG,MAAM,cAAc,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IACxE,CAAC,CAAC,EAAE,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvF,oBAAoB,CAAC,aAAa,CAAC,CAAC;IACpC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IAE1B,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC,CAAC,YAAY,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,oBAAoB,CAAC,KAAgB;IAC5C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QAClD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO;iBAC5B,OAAO,CAAC,wBAAwB,EAAE,qBAAqB,CAAC;iBACxD,OAAO,CAAC,6BAA6B,EAAE,0BAA0B,CAAC;iBAClE,OAAO,CAAC,sBAAsB,EAAE,kBAAkB,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,KAAgB,EAAE,WAAmB;IACjE,MAAM,SAAS,GAAc,MAAM,IAAA,aAAG,EAAC,iDAAoC,EAAE;QAC3E,KAAK,EAAE,IAAI;QACX,WAAW;KACZ,CAAC,CAAC;IAEH,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvB,OAAO,MAAM,IAAA,aAAG,EAAC,6CAAgC,EAAE;YACjD,KAAK;YACL,UAAU,EAAE,SAAS,CAAC,YAAY;SACnC,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,MAAM,IAAA,aAAG,EAAC,2CAA8B,EAAE;YAC/C,KAAK;YACL,QAAQ,EAAE,SAAS,CAAC,YAAY;SACjC,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"make-namespaced.test.js","sourceRoot":"","sources":["../../src/utils/make-namespaced.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { Node } from '@nomicfoundation/slang/cst';
2
+ /**
3
+ * Returns true if the node is a trivia terminal (whitespace or comment or NatSpec)
4
+ *
5
+ * CAUTION: This must be imported dynamically.
6
+ * Only import this file if Slang is supported on the current platform, otherwise an error will be thrown on import.
7
+ */
8
+ export declare function isTrivia(node: Node): boolean;
9
+ //# sourceMappingURL=trivia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trivia.d.ts","sourceRoot":"","sources":["../../../src/utils/slang/trivia.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAgB,MAAM,4BAA4B,CAAC;AAEhE;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,WAElC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTrivia = isTrivia;
4
+ const kinds_1 = require("@nomicfoundation/slang/kinds");
5
+ const cst_1 = require("@nomicfoundation/slang/cst");
6
+ /**
7
+ * Returns true if the node is a trivia terminal (whitespace or comment or NatSpec)
8
+ *
9
+ * CAUTION: This must be imported dynamically.
10
+ * Only import this file if Slang is supported on the current platform, otherwise an error will be thrown on import.
11
+ */
12
+ function isTrivia(node) {
13
+ return node instanceof cst_1.TerminalNode && isTriviaKind(node.kind);
14
+ }
15
+ function isTriviaKind(kind) {
16
+ return (kind === kinds_1.TerminalKind.EndOfLine ||
17
+ kind === kinds_1.TerminalKind.MultiLineComment ||
18
+ kind === kinds_1.TerminalKind.MultiLineNatSpecComment ||
19
+ kind === kinds_1.TerminalKind.SingleLineComment ||
20
+ kind === kinds_1.TerminalKind.SingleLineNatSpecComment ||
21
+ kind === kinds_1.TerminalKind.Whitespace);
22
+ }
23
+ //# sourceMappingURL=trivia.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trivia.js","sourceRoot":"","sources":["../../../src/utils/slang/trivia.ts"],"names":[],"mappings":";;AASA,4BAEC;AAXD,wDAA4D;AAC5D,oDAAgE;AAEhE;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,IAAU;IACjC,OAAO,IAAI,YAAY,kBAAY,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,YAAY,CAAC,IAAkB;IACtC,OAAO,CACL,IAAI,KAAK,oBAAY,CAAC,SAAS;QAC/B,IAAI,KAAK,oBAAY,CAAC,gBAAgB;QACtC,IAAI,KAAK,oBAAY,CAAC,uBAAuB;QAC7C,IAAI,KAAK,oBAAY,CAAC,iBAAiB;QACvC,IAAI,KAAK,oBAAY,CAAC,wBAAwB;QAC9C,IAAI,KAAK,oBAAY,CAAC,UAAU,CACjC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/upgrades-core",
3
- "version": "1.34.4",
3
+ "version": "1.35.0",
4
4
  "description": "",
5
5
  "repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/core",
6
6
  "license": "MIT",
@@ -61,6 +61,7 @@
61
61
  "typescript": "^5.0.0"
62
62
  },
63
63
  "dependencies": {
64
+ "@nomicfoundation/slang": "^0.15.1",
64
65
  "cbor": "^9.0.0",
65
66
  "chalk": "^4.1.0",
66
67
  "compare-versions": "^6.0.0",
@@ -16,6 +16,11 @@ test('make namespaced input', async t => {
16
16
  await testMakeNamespaced(origBuildInfo, t, '0.8.20');
17
17
  });
18
18
 
19
+ test('make namespaced input - keep all natspec', async t => {
20
+ const origBuildInfo = await artifacts.getBuildInfo('contracts/test/NamespacedToModifyImported.sol:Example');
21
+ await testMakeNamespaced(origBuildInfo, t, '0.8.20', true);
22
+ });
23
+
19
24
  test('make namespaced input - solc 0.7', async t => {
20
25
  // The nameNamespacedInput function must work for different solc versions, since it is called before we check whether namespaces are used with solc >= 0.8.20
21
26
  const origBuildInfo = await artifacts.getBuildInfo('contracts/test/NamespacedToModify07.sol:HasFunction');
@@ -26,6 +31,7 @@ async function testMakeNamespaced(
26
31
  origBuildInfo: BuildInfo | undefined,
27
32
  t: ExecutionContext<unknown>,
28
33
  solcVersion: string,
34
+ keepAllNatSpec = false,
29
35
  ) {
30
36
  if (origBuildInfo === undefined) {
31
37
  throw new Error('Build info not found');
@@ -34,7 +40,11 @@ async function testMakeNamespaced(
34
40
  // Inefficient, but we want to test that we don't actually modify the original input object
35
41
  const origInput = JSON.parse(JSON.stringify(origBuildInfo.input));
36
42
 
37
- const modifiedInput = makeNamespacedInput(origBuildInfo.input, origBuildInfo.output);
43
+ const modifiedInput = makeNamespacedInput(
44
+ origBuildInfo.input,
45
+ origBuildInfo.output,
46
+ keepAllNatSpec ? undefined : origBuildInfo.solcVersion,
47
+ );
38
48
 
39
49
  // Run hardhat compile on the modified input and make sure it has no errors
40
50
  const modifiedOutput = await hardhatCompile(modifiedInput, solcVersion);
@@ -53,6 +63,7 @@ function normalizeIdentifiers(input: SolcInput): void {
53
63
  source.content = source.content
54
64
  .replace(/\$MainStorage_\d{1,6}/g, '$MainStorage_random')
55
65
  .replace(/\$SecondaryStorage_\d{1,6}/g, '$SecondaryStorage_random')
66
+ .replace(/\$StorageWithComment_\d{1,6}/g, '$StorageWithComment_random')
56
67
  .replace(/\$astId_\d+_\d{1,6}/g, '$astId_id_random');
57
68
  }
58
69
  }
@@ -32,7 +32,7 @@ Generated by [AVA](https://avajs.dev).
32
32
  content: `// SPDX-License-Identifier: MIT␊
33
33
  pragma solidity ^0.8.20;␊
34
34
  ␊
35
- contract Example {␊
35
+ abstract contract Example {␊
36
36
  /// @custom:storage-location erc7201:example.main␊
37
37
  struct MainStorage {␊
38
38
  uint256 x;␊
@@ -44,6 +44,251 @@ Generated by [AVA](https://avajs.dev).
44
44
  uint256 a;␊
45
45
  uint256 b;␊
46
46
  } SecondaryStorage $SecondaryStorage_random;␊
47
+ ␊
48
+ /// @custom:storage-location erc7201:example.with.following.comment␊
49
+ // some comment␊
50
+ struct StorageWithComment {␊
51
+ uint256 a;␊
52
+ uint256 b;␊
53
+ } StorageWithComment $StorageWithComment_random;␊
54
+ ␊
55
+ ␊
56
+ function foo() public {}␊
57
+ ␊
58
+ ␊
59
+ function foo1(uint a) public {}␊
60
+ ␊
61
+ ␊
62
+ function foo2(uint a) internal {}␊
63
+ struct MyStruct { uint b; }␊
64
+ ␊
65
+ // keccak256(abi.encode(uint256(keccak256("example.main")) - 1)) & ~bytes32(uint256(0xff));␊
66
+ bytes32 private constant MAIN_STORAGE_LOCATION =␊
67
+ 0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500;␊
68
+ ␊
69
+ function _getMainStorage() private pure returns (bool $) {}␊
70
+ ␊
71
+ function _getXTimesY() internal view returns (bool) {}␊
72
+ ␊
73
+ ␊
74
+ ␊
75
+ ␊
76
+ enum $astId_id_random { dummy }␊
77
+ ␊
78
+ // standalone doc␊
79
+ ␊
80
+ ␊
81
+ ␊
82
+ ␊
83
+ function foo3() public {}␊
84
+ ␊
85
+ ␊
86
+ function foo4() public {}␊
87
+ ␊
88
+ ␊
89
+ enum $astId_id_random { dummy }␊
90
+ ␊
91
+ enum $astId_id_random { dummy }␊
92
+ enum $astId_id_random { dummy }␊
93
+ enum $astId_id_random { dummy }␊
94
+ enum $astId_id_random { dummy }␊
95
+ enum $astId_id_random { dummy }␊
96
+ }␊
97
+ ␊
98
+ abstract contract HasFunction {␊
99
+ ␊
100
+ function foo() pure public returns (bool) {}␊
101
+ }␊
102
+ ␊
103
+ abstract contract UsingFunction is HasFunction {␊
104
+ enum $astId_id_random { dummy }␊
105
+ }␊
106
+ ␊
107
+ function FreeFunctionUsingSelector() pure returns (bool) {}␊
108
+ ␊
109
+ bytes4 constant CONSTANT_USING_SELECTOR = HasFunction.foo.selector;␊
110
+ ␊
111
+ library Lib {␊
112
+ function usingSelector() pure public returns (bool) {}␊
113
+ ␊
114
+ function plusOne(uint x) pure public returns (bool) {}␊
115
+ }␊
116
+ ␊
117
+ abstract contract Consumer {␊
118
+ enum $astId_id_random { dummy }␊
119
+ ␊
120
+ function usingFreeFunction() pure public returns (bool) {}␊
121
+ ␊
122
+ function usingConstant() pure public returns (bool) {}␊
123
+ ␊
124
+ function usingLibraryFunction() pure public returns (bool) {}␊
125
+ }␊
126
+ ␊
127
+ abstract contract HasConstantWithSelector {␊
128
+ bytes4 constant CONTRACT_CONSTANT_USING_SELECTOR = HasFunction.foo.selector;␊
129
+ }␊
130
+ ␊
131
+ function plusTwo(uint x) pure returns (bool) {}␊
132
+ ␊
133
+ ␊
134
+ ␊
135
+ ␊
136
+ function plusThree(uint x) pure returns (bool) {}␊
137
+ ␊
138
+ ␊
139
+ ␊
140
+ ␊
141
+ function plusThree(uint x, uint y) pure returns (bool) {}␊
142
+ ␊
143
+ function originallyNoDocumentation() pure {}␊
144
+ ␊
145
+ ␊
146
+ enum $astId_id_random { dummy }␊
147
+ ␊
148
+ abstract contract UsingForDirectives {␊
149
+ enum $astId_id_random { dummy }␊
150
+ ␊
151
+ function usingFor(uint x) pure public returns (bool) {}␊
152
+ }␊
153
+ ␊
154
+ ␊
155
+ enum FreeEnum { MyEnum }␊
156
+ ␊
157
+ ␊
158
+ enum CustomErrorOutsideContract { dummy }␊
159
+ ␊
160
+ int8 constant MAX_SIZE_C = 2;␊
161
+ ␊
162
+ abstract contract StructArrayUsesConstant {␊
163
+ uint16 private constant MAX_SIZE = 10;␊
164
+ ␊
165
+ struct NotNamespaced {␊
166
+ uint16 a;␊
167
+ uint256[MAX_SIZE] b;␊
168
+ uint256[MAX_SIZE_C] c;␊
169
+ }␊
170
+ ␊
171
+ /// @custom:storage-location erc7201:uses.constant␊
172
+ struct MainStorage {␊
173
+ uint256 x;␊
174
+ uint256[MAX_SIZE] y;␊
175
+ uint256[MAX_SIZE_C] c;␊
176
+ } MainStorage $MainStorage_random;␊
177
+ }␊
178
+ ␊
179
+ address constant MY_ADDRESS = address(0);␊
180
+ uint constant CONVERTED_ADDRESS = uint160(MY_ADDRESS);␊
181
+ ␊
182
+ interface IDummy {␊
183
+ }␊
184
+ ␊
185
+ abstract contract UsesAddress {␊
186
+ IDummy public constant MY_CONTRACT = IDummy(MY_ADDRESS);␊
187
+ }␊
188
+ ␊
189
+ abstract contract HasFunctionWithRequiredReturn {␊
190
+ struct S { uint x; }␊
191
+ function foo(S calldata s) internal pure returns (bool) {}␊
192
+ }␊
193
+ ␊
194
+ ␊
195
+ function hasMultipleReturns() pure returns (bool, bool) {}␊
196
+ ␊
197
+ ␊
198
+ function hasMultipleNamedReturns() pure returns (bool a, bool b) {}␊
199
+ ␊
200
+ ␊
201
+ function hasReturnsDocumentedAsParams() pure returns (bool a, bool b) {}␊
202
+ ␊
203
+ abstract contract HasNatSpecWithMultipleReturns {␊
204
+ ␊
205
+ function hasMultipleReturnsInContract() public pure returns (bool, bool) {}␊
206
+ ␊
207
+ ␊
208
+ function hasMultipleNamedReturnsInContract() public pure returns (bool a, bool b) {}␊
209
+ ␊
210
+ ␊
211
+ function hasReturnsDocumentedAsParamsInContract() public pure returns (bool a, bool b) {}␊
212
+ }␊
213
+ ␊
214
+ interface IHasExternalViewFunction {␊
215
+ function foo() external view returns (bool);␊
216
+ }␊
217
+ ␊
218
+ abstract contract HasExternalViewFunction is IHasExternalViewFunction {␊
219
+ // This generates a getter function that conforms to the interface␊
220
+ enum $astId_id_random { dummy }␊
221
+ ␊
222
+ // References a selector in an interface␊
223
+ bytes4 constant USING_INTERFACE_FUNCTION_SELECTOR = IHasExternalViewFunction.foo.selector;␊
224
+ ␊
225
+ // References a getter generated for a public variable␊
226
+ enum $astId_id_random { dummy }␊
227
+ }␊
228
+ ␊
229
+ abstract contract DeploysContractToImmutable {␊
230
+ enum $astId_id_random { dummy }␊
231
+ }`,
232
+ },
233
+ 'contracts/test/NamespacedToModifyImported.sol': {
234
+ content: `// SPDX-License-Identifier: MIT␊
235
+ pragma solidity ^0.8.20;␊
236
+ ␊
237
+ import {CONSTANT_USING_SELECTOR, plusTwo, plusThree, CustomErrorOutsideContract} from "./NamespacedToModify.sol";␊
238
+ ␊
239
+ abstract contract Example {}␊
240
+ `,
241
+ },
242
+ },
243
+ }
244
+
245
+ ## make namespaced input - keep all natspec
246
+
247
+ > Snapshot 1
248
+
249
+ {
250
+ language: 'Solidity',
251
+ settings: {
252
+ evmVersion: 'paris',
253
+ optimizer: {
254
+ enabled: true,
255
+ runs: 200,
256
+ },
257
+ outputSelection: {
258
+ '*': {
259
+ '': [
260
+ 'ast',
261
+ ],
262
+ '*': [
263
+ 'storageLayout',
264
+ ],
265
+ },
266
+ },
267
+ },
268
+ sources: {
269
+ 'contracts/test/NamespacedToModify.sol': {
270
+ content: `// SPDX-License-Identifier: MIT␊
271
+ pragma solidity ^0.8.20;␊
272
+ ␊
273
+ abstract contract Example {␊
274
+ /// @custom:storage-location erc7201:example.main␊
275
+ struct MainStorage {␊
276
+ uint256 x;␊
277
+ uint256 y;␊
278
+ } MainStorage $MainStorage_random;␊
279
+ ␊
280
+ /// @custom:storage-location erc7201:example.secondary␊
281
+ struct SecondaryStorage {␊
282
+ uint256 a;␊
283
+ uint256 b;␊
284
+ } SecondaryStorage $SecondaryStorage_random;␊
285
+ ␊
286
+ /// @custom:storage-location erc7201:example.with.following.comment␊
287
+ // some comment␊
288
+ struct StorageWithComment {␊
289
+ uint256 a;␊
290
+ uint256 b;␊
291
+ } StorageWithComment $StorageWithComment_random;␊
47
292
  ␊
48
293
  /// @notice some natspec␊
49
294
  function foo() public {}␊
@@ -98,12 +343,12 @@ Generated by [AVA](https://avajs.dev).
98
343
  enum $astId_id_random { dummy }␊
99
344
  }␊
100
345
  ␊
101
- contract HasFunction {␊
346
+ abstract contract HasFunction {␊
102
347
  ␊
103
348
  function foo() pure public returns (bool) {}␊
104
349
  }␊
105
350
  ␊
106
- contract UsingFunction is HasFunction {␊
351
+ abstract contract UsingFunction is HasFunction {␊
107
352
  enum $astId_id_random { dummy }␊
108
353
  }␊
109
354
  ␊
@@ -117,7 +362,7 @@ Generated by [AVA](https://avajs.dev).
117
362
  function plusOne(uint x) pure public returns (bool) {}␊
118
363
  }␊
119
364
  ␊
120
- contract Consumer {␊
365
+ abstract contract Consumer {␊
121
366
  enum $astId_id_random { dummy }␊
122
367
  ␊
123
368
  function usingFreeFunction() pure public returns (bool) {}␊
@@ -127,7 +372,7 @@ Generated by [AVA](https://avajs.dev).
127
372
  function usingLibraryFunction() pure public returns (bool) {}␊
128
373
  }␊
129
374
  ␊
130
- contract HasConstantWithSelector {␊
375
+ abstract contract HasConstantWithSelector {␊
131
376
  bytes4 constant CONTRACT_CONSTANT_USING_SELECTOR = HasFunction.foo.selector;␊
132
377
  }␊
133
378
  ␊
@@ -159,7 +404,7 @@ Generated by [AVA](https://avajs.dev).
159
404
  */␊
160
405
  enum $astId_id_random { dummy }␊
161
406
  ␊
162
- contract UsingForDirectives {␊
407
+ abstract contract UsingForDirectives {␊
163
408
  enum $astId_id_random { dummy }␊
164
409
  ␊
165
410
  function usingFor(uint x) pure public returns (bool) {}␊
@@ -185,7 +430,7 @@ Generated by [AVA](https://avajs.dev).
185
430
  ␊
186
431
  int8 constant MAX_SIZE_C = 2;␊
187
432
  ␊
188
- contract StructArrayUsesConstant {␊
433
+ abstract contract StructArrayUsesConstant {␊
189
434
  uint16 private constant MAX_SIZE = 10;␊
190
435
  ␊
191
436
  struct NotNamespaced {␊
@@ -208,11 +453,11 @@ Generated by [AVA](https://avajs.dev).
208
453
  interface IDummy {␊
209
454
  }␊
210
455
  ␊
211
- contract UsesAddress {␊
456
+ abstract contract UsesAddress {␊
212
457
  IDummy public constant MY_CONTRACT = IDummy(MY_ADDRESS);␊
213
458
  }␊
214
459
  ␊
215
- contract HasFunctionWithRequiredReturn {␊
460
+ abstract contract HasFunctionWithRequiredReturn {␊
216
461
  struct S { uint x; }␊
217
462
  function foo(S calldata s) internal pure returns (bool) {}␊
218
463
  }␊
@@ -235,7 +480,7 @@ Generated by [AVA](https://avajs.dev).
235
480
  */␊
236
481
  function hasReturnsDocumentedAsParams() pure returns (bool a, bool b) {}␊
237
482
  ␊
238
- contract HasNatSpecWithMultipleReturns {␊
483
+ abstract contract HasNatSpecWithMultipleReturns {␊
239
484
  /**␊
240
485
  * @return uint 1␊
241
486
  * @return uint 2␊
@@ -254,7 +499,25 @@ Generated by [AVA](https://avajs.dev).
254
499
  */␊
255
500
  function hasReturnsDocumentedAsParamsInContract() public pure returns (bool a, bool b) {}␊
256
501
  }␊
257
- `,
502
+ ␊
503
+ interface IHasExternalViewFunction {␊
504
+ function foo() external view returns (bool);␊
505
+ }␊
506
+ ␊
507
+ abstract contract HasExternalViewFunction is IHasExternalViewFunction {␊
508
+ // This generates a getter function that conforms to the interface␊
509
+ enum $astId_id_random { dummy }␊
510
+ ␊
511
+ // References a selector in an interface␊
512
+ bytes4 constant USING_INTERFACE_FUNCTION_SELECTOR = IHasExternalViewFunction.foo.selector;␊
513
+ ␊
514
+ // References a getter generated for a public variable␊
515
+ enum $astId_id_random { dummy }␊
516
+ }␊
517
+ ␊
518
+ abstract contract DeploysContractToImmutable {␊
519
+ enum $astId_id_random { dummy }␊
520
+ }`,
258
521
  },
259
522
  'contracts/test/NamespacedToModifyImported.sol': {
260
523
  content: `// SPDX-License-Identifier: MIT␊
@@ -262,7 +525,7 @@ Generated by [AVA](https://avajs.dev).
262
525
  ␊
263
526
  import {CONSTANT_USING_SELECTOR, plusTwo, plusThree, CustomErrorOutsideContract} from "./NamespacedToModify.sol";␊
264
527
  ␊
265
- contract Example {}␊
528
+ abstract contract Example {}␊
266
529
  `,
267
530
  },
268
531
  },
@@ -295,12 +558,12 @@ Generated by [AVA](https://avajs.dev).
295
558
  content: `// SPDX-License-Identifier: MIT␊
296
559
  pragma solidity 0.7.6;␊
297
560
  ␊
298
- contract HasFunction {␊
561
+ abstract contract HasFunction {␊
299
562
  ␊
300
563
  function foo() pure public returns (bool) {}␊
301
564
  }␊
302
565
  ␊
303
- contract UsingFunction is HasFunction {␊
566
+ abstract contract UsingFunction is HasFunction {␊
304
567
  enum $astId_id_random { dummy }␊
305
568
  }␊
306
569
  `,
@@ -26,9 +26,10 @@ const OUTPUT_SELECTION = {
26
26
  *
27
27
  * @param input The original solc input.
28
28
  * @param output The original solc output.
29
+ * @param solcVersion The version of the solc compiler that was originally used to compile the input.
29
30
  * @returns The modified solc input with storage layout that includes namespaced type information.
30
31
  */
31
- export function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcInput {
32
+ export function makeNamespacedInput(input: SolcInput, output: SolcOutput, solcVersion?: string): SolcInput {
32
33
  const modifiedSources: Record<string, { content?: string }> = {};
33
34
 
34
35
  for (const [sourcePath] of Object.entries(input.sources)) {
@@ -48,6 +49,12 @@ export function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcI
48
49
  case 'ContractDefinition': {
49
50
  const contractDef = node;
50
51
 
52
+ // Mark contracts as abstract, since state variables are converted to dummy enums
53
+ // which would not generate public getters for inherited interface functions
54
+ if (contractDef.contractKind === 'contract' && !contractDef.abstract) {
55
+ modifications.push(makeInsertBefore(contractDef, 'abstract '));
56
+ }
57
+
51
58
  // Remove any calls to parent constructors from the inheritance list
52
59
  const inherits = contractDef.baseContracts;
53
60
  for (const inherit of inherits) {
@@ -144,12 +151,68 @@ export function makeNamespacedInput(input: SolcInput, output: SolcOutput): SolcI
144
151
  }
145
152
  }
146
153
 
147
- modifiedSources[sourcePath] = { ...source, content: getModifiedSource(orig, modifications) };
154
+ const modifiedSource = tryRemoveNonStructNatSpec(getModifiedSource(orig, modifications), solcVersion);
155
+
156
+ modifiedSources[sourcePath] = { ...source, content: modifiedSource };
148
157
  }
149
158
 
150
159
  return { ...input, sources: modifiedSources, settings: { ...input.settings, outputSelection: OUTPUT_SELECTION } };
151
160
  }
152
161
 
162
+ /**
163
+ * If Slang is supported for the current platform and we have the compiler version available,
164
+ * use Slang to parse and remove all NatSpec comments that do not precede a struct definition and return the modified content.
165
+ *
166
+ * Otherwise, return the original content.
167
+ */
168
+ function tryRemoveNonStructNatSpec(origContent: string, solcVersion: string | undefined): string {
169
+ const natSpecRemovals: Modification[] = [];
170
+
171
+ if (solcVersion !== undefined && tryRequire('@nomicfoundation/slang')) {
172
+ /* eslint-disable @typescript-eslint/no-var-requires */
173
+ const { Language } = require('@nomicfoundation/slang/language');
174
+ const { NonterminalKind, TerminalKind } = require('@nomicfoundation/slang/kinds');
175
+ const { TerminalNode } = require('@nomicfoundation/slang/cst');
176
+ const { isTrivia } = require('./slang/trivia');
177
+ /* eslint-enable @typescript-eslint/no-var-requires */
178
+
179
+ const language = new Language(solcVersion);
180
+ const parseOutput = language.parse(NonterminalKind.SourceUnit, origContent);
181
+ const cursor = parseOutput.createTreeCursor();
182
+
183
+ while (
184
+ cursor.goToNextTerminalWithKinds([TerminalKind.MultiLineNatSpecComment, TerminalKind.SingleLineNatSpecComment])
185
+ ) {
186
+ // Lookahead to determine if the next non-trivia node is the struct keyword.
187
+ // If so, this NatSpec is part of the struct definition and should not be removed.
188
+ const lookaheadCursor = cursor.clone();
189
+ while (lookaheadCursor.goToNextTerminal() && isTrivia(lookaheadCursor.node())) {
190
+ // skip over trivia nodes
191
+ }
192
+ if (lookaheadCursor.node().kind === TerminalKind.StructKeyword) {
193
+ continue;
194
+ }
195
+
196
+ const triviaNode = cursor.node();
197
+ assert(triviaNode instanceof TerminalNode);
198
+ natSpecRemovals.push(makeDeleteRange(cursor.textRange.start.utf8, cursor.textRange.end.utf8));
199
+ }
200
+ return getModifiedSource(Buffer.from(origContent, 'utf8'), natSpecRemovals);
201
+ } else {
202
+ return origContent;
203
+ }
204
+ }
205
+
206
+ function tryRequire(id: string) {
207
+ try {
208
+ require(id);
209
+ return true;
210
+ } catch (e: any) {
211
+ // do nothing
212
+ }
213
+ return false;
214
+ }
215
+
153
216
  interface Modification {
154
217
  start: number;
155
218
  end: number;
@@ -210,6 +273,11 @@ function makeReplace(node: Node, orig: Buffer, text: string): Modification {
210
273
  return { start, end, text };
211
274
  }
212
275
 
276
+ function makeInsertBefore(node: Node, text: string): Modification {
277
+ const { start } = getPositions(node);
278
+ return { start: start, end: start, text };
279
+ }
280
+
213
281
  function makeInsertAfter(node: Node, text: string): Modification {
214
282
  const { end } = getPositions(node);
215
283
  return { start: end, end, text };
@@ -227,7 +295,11 @@ function makeDelete(node: Node, orig: Buffer): Modification {
227
295
  end += 1;
228
296
  }
229
297
  }
230
- return { start: positions.start, end };
298
+ return makeDeleteRange(positions.start, end);
299
+ }
300
+
301
+ function makeDeleteRange(start: number, end: number): Modification {
302
+ return { start, end };
231
303
  }
232
304
 
233
305
  function getModifiedSource(orig: Buffer, modifications: Modification[]): string {
@@ -0,0 +1,23 @@
1
+ import { TerminalKind } from '@nomicfoundation/slang/kinds';
2
+ import { Node, TerminalNode } from '@nomicfoundation/slang/cst';
3
+
4
+ /**
5
+ * Returns true if the node is a trivia terminal (whitespace or comment or NatSpec)
6
+ *
7
+ * CAUTION: This must be imported dynamically.
8
+ * Only import this file if Slang is supported on the current platform, otherwise an error will be thrown on import.
9
+ */
10
+ export function isTrivia(node: Node) {
11
+ return node instanceof TerminalNode && isTriviaKind(node.kind);
12
+ }
13
+
14
+ function isTriviaKind(kind: TerminalKind) {
15
+ return (
16
+ kind === TerminalKind.EndOfLine ||
17
+ kind === TerminalKind.MultiLineComment ||
18
+ kind === TerminalKind.MultiLineNatSpecComment ||
19
+ kind === TerminalKind.SingleLineComment ||
20
+ kind === TerminalKind.SingleLineNatSpecComment ||
21
+ kind === TerminalKind.Whitespace
22
+ );
23
+ }