@openzeppelin/upgrades-core 1.29.0 → 1.30.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.
Files changed (161) hide show
  1. package/dist/call-optional-signature.d.ts +3 -0
  2. package/dist/call-optional-signature.d.ts.map +1 -0
  3. package/dist/call-optional-signature.js +24 -0
  4. package/dist/call-optional-signature.js.map +1 -0
  5. package/dist/cli/validate/build-info-file.d.ts +4 -0
  6. package/dist/cli/validate/build-info-file.d.ts.map +1 -1
  7. package/dist/cli/validate/build-info-file.js +5 -2
  8. package/dist/cli/validate/build-info-file.js.map +1 -1
  9. package/dist/cli/validate/build-info-file.test.js +4 -1
  10. package/dist/cli/validate/build-info-file.test.js.map +1 -1
  11. package/dist/cli/validate/upgradeability-assessment.js +2 -6
  12. package/dist/cli/validate/upgradeability-assessment.js.map +1 -1
  13. package/dist/cli/validate/validations.d.ts.map +1 -1
  14. package/dist/cli/validate/validations.js +5 -4
  15. package/dist/cli/validate/validations.js.map +1 -1
  16. package/dist/impl-address.d.ts.map +1 -1
  17. package/dist/impl-address.js +9 -16
  18. package/dist/impl-address.js.map +1 -1
  19. package/dist/index.d.ts +3 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +7 -1
  22. package/dist/index.js.map +1 -1
  23. package/dist/levenshtein.d.ts +6 -0
  24. package/dist/levenshtein.d.ts.map +1 -1
  25. package/dist/levenshtein.js.map +1 -1
  26. package/dist/solc-api.d.ts +14 -0
  27. package/dist/solc-api.d.ts.map +1 -1
  28. package/dist/standalone.d.ts +4 -1
  29. package/dist/standalone.d.ts.map +1 -1
  30. package/dist/standalone.js +6 -3
  31. package/dist/standalone.js.map +1 -1
  32. package/dist/standalone.test.js +17 -0
  33. package/dist/standalone.test.js.map +1 -1
  34. package/dist/storage/compare.d.ts +2 -1
  35. package/dist/storage/compare.d.ts.map +1 -1
  36. package/dist/storage/compare.js +25 -2
  37. package/dist/storage/compare.js.map +1 -1
  38. package/dist/storage/extract.d.ts +15 -3
  39. package/dist/storage/extract.d.ts.map +1 -1
  40. package/dist/storage/extract.js +48 -21
  41. package/dist/storage/extract.js.map +1 -1
  42. package/dist/storage/index.d.ts.map +1 -1
  43. package/dist/storage/index.js +15 -1
  44. package/dist/storage/index.js.map +1 -1
  45. package/dist/storage/layout.d.ts +1 -0
  46. package/dist/storage/layout.d.ts.map +1 -1
  47. package/dist/storage/layout.js.map +1 -1
  48. package/dist/storage/namespace.d.ts +35 -0
  49. package/dist/storage/namespace.d.ts.map +1 -0
  50. package/dist/storage/namespace.js +219 -0
  51. package/dist/storage/namespace.js.map +1 -0
  52. package/dist/storage/report.js +6 -0
  53. package/dist/storage/report.js.map +1 -1
  54. package/dist/storage-namespaced-conflicts-layout.test.d.ts +2 -0
  55. package/dist/storage-namespaced-conflicts-layout.test.d.ts.map +1 -0
  56. package/dist/storage-namespaced-conflicts-layout.test.js +69 -0
  57. package/dist/storage-namespaced-conflicts-layout.test.js.map +1 -0
  58. package/dist/storage-namespaced-conflicts.test.d.ts +2 -0
  59. package/dist/storage-namespaced-conflicts.test.d.ts.map +1 -0
  60. package/dist/storage-namespaced-conflicts.test.js +45 -0
  61. package/dist/storage-namespaced-conflicts.test.js.map +1 -0
  62. package/dist/storage-namespaced-layout.test.d.ts +2 -0
  63. package/dist/storage-namespaced-layout.test.d.ts.map +1 -0
  64. package/dist/storage-namespaced-layout.test.js +59 -0
  65. package/dist/storage-namespaced-layout.test.js.map +1 -0
  66. package/dist/storage-namespaced-outside-contract.test.d.ts +2 -0
  67. package/dist/storage-namespaced-outside-contract.test.d.ts.map +1 -0
  68. package/dist/storage-namespaced-outside-contract.test.js +22 -0
  69. package/dist/storage-namespaced-outside-contract.test.js.map +1 -0
  70. package/dist/storage-namespaced-solc-versions.test.d.ts +2 -0
  71. package/dist/storage-namespaced-solc-versions.test.d.ts.map +1 -0
  72. package/dist/storage-namespaced-solc-versions.test.js +42 -0
  73. package/dist/storage-namespaced-solc-versions.test.js.map +1 -0
  74. package/dist/storage-namespaced-udvt.test.d.ts +2 -0
  75. package/dist/storage-namespaced-udvt.test.d.ts.map +1 -0
  76. package/dist/storage-namespaced-udvt.test.js +130 -0
  77. package/dist/storage-namespaced-udvt.test.js.map +1 -0
  78. package/dist/storage-namespaced.test.d.ts +2 -0
  79. package/dist/storage-namespaced.test.d.ts.map +1 -0
  80. package/dist/storage-namespaced.test.js +132 -0
  81. package/dist/storage-namespaced.test.js.map +1 -0
  82. package/dist/upgrade-interface-version.d.ts +3 -0
  83. package/dist/upgrade-interface-version.d.ts.map +1 -0
  84. package/dist/upgrade-interface-version.js +25 -0
  85. package/dist/upgrade-interface-version.js.map +1 -0
  86. package/dist/upgrade-interface-version.test.d.ts +2 -0
  87. package/dist/upgrade-interface-version.test.d.ts.map +1 -0
  88. package/dist/upgrade-interface-version.test.js +32 -0
  89. package/dist/upgrade-interface-version.test.js.map +1 -0
  90. package/dist/utils/annotations.d.ts +4 -0
  91. package/dist/utils/annotations.d.ts.map +1 -1
  92. package/dist/utils/annotations.js +9 -1
  93. package/dist/utils/annotations.js.map +1 -1
  94. package/dist/utils/make-namespaced.d.ts +20 -0
  95. package/dist/utils/make-namespaced.d.ts.map +1 -0
  96. package/dist/utils/make-namespaced.js +131 -0
  97. package/dist/utils/make-namespaced.js.map +1 -0
  98. package/dist/utils/make-namespaced.test.d.ts +2 -0
  99. package/dist/utils/make-namespaced.test.d.ts.map +1 -0
  100. package/dist/utils/make-namespaced.test.js +59 -0
  101. package/dist/utils/make-namespaced.test.js.map +1 -0
  102. package/dist/utils/stabilize-layout.d.ts +11 -0
  103. package/dist/utils/stabilize-layout.d.ts.map +1 -1
  104. package/dist/utils/stabilize-layout.js +5 -0
  105. package/dist/utils/stabilize-layout.js.map +1 -1
  106. package/dist/validate/query.d.ts.map +1 -1
  107. package/dist/validate/query.js +4 -2
  108. package/dist/validate/query.js.map +1 -1
  109. package/dist/validate/run.d.ts +18 -2
  110. package/dist/validate/run.d.ts.map +1 -1
  111. package/dist/validate/run.js +80 -2
  112. package/dist/validate/run.js.map +1 -1
  113. package/package.json +3 -3
  114. package/src/call-optional-signature.ts +20 -0
  115. package/src/cli/validate/build-info-file.test.ts +4 -1
  116. package/src/cli/validate/build-info-file.ts +12 -2
  117. package/src/cli/validate/upgradeability-assessment.ts +1 -6
  118. package/src/cli/validate/validations.ts +6 -5
  119. package/src/impl-address.ts +9 -20
  120. package/src/index.ts +4 -0
  121. package/src/levenshtein.ts +7 -0
  122. package/src/solc-api.ts +14 -0
  123. package/src/standalone.test.ts +26 -0
  124. package/src/standalone.ts +6 -2
  125. package/src/storage/compare.ts +34 -2
  126. package/src/storage/extract.ts +68 -20
  127. package/src/storage/index.ts +22 -1
  128. package/src/storage/layout.ts +1 -0
  129. package/src/storage/namespace.ts +267 -0
  130. package/src/storage/report.ts +8 -0
  131. package/src/storage-0.8.test.ts.md +4 -0
  132. package/src/storage-0.8.test.ts.snap +0 -0
  133. package/src/storage-memory-0.5.test.ts.md +2 -0
  134. package/src/storage-memory-0.5.test.ts.snap +0 -0
  135. package/src/storage-namespaced-conflicts-layout.test.ts +96 -0
  136. package/src/storage-namespaced-conflicts-layout.test.ts.md +53 -0
  137. package/src/storage-namespaced-conflicts-layout.test.ts.snap +0 -0
  138. package/src/storage-namespaced-conflicts.test.ts +54 -0
  139. package/src/storage-namespaced-conflicts.test.ts.md +53 -0
  140. package/src/storage-namespaced-conflicts.test.ts.snap +0 -0
  141. package/src/storage-namespaced-layout.test.ts +77 -0
  142. package/src/storage-namespaced-layout.test.ts.md +67 -0
  143. package/src/storage-namespaced-layout.test.ts.snap +0 -0
  144. package/src/storage-namespaced-outside-contract.test.ts +24 -0
  145. package/src/storage-namespaced-solc-versions.test.ts +59 -0
  146. package/src/storage-namespaced-udvt.test.ts +160 -0
  147. package/src/storage-namespaced.test.ts +146 -0
  148. package/src/storage-namespaced.test.ts.md +89 -0
  149. package/src/storage-namespaced.test.ts.snap +0 -0
  150. package/src/storage.test.ts.md +2 -0
  151. package/src/storage.test.ts.snap +0 -0
  152. package/src/upgrade-interface-version.test.ts +37 -0
  153. package/src/upgrade-interface-version.ts +27 -0
  154. package/src/utils/annotations.ts +8 -0
  155. package/src/utils/make-namespaced.test.ts +74 -0
  156. package/src/utils/make-namespaced.test.ts.md +154 -0
  157. package/src/utils/make-namespaced.test.ts.snap +0 -0
  158. package/src/utils/make-namespaced.ts +154 -0
  159. package/src/utils/stabilize-layout.ts +5 -0
  160. package/src/validate/query.ts +4 -2
  161. package/src/validate/run.ts +108 -2
@@ -0,0 +1,146 @@
1
+ import _test, { TestFn } from 'ava';
2
+ import { ContractDefinition } from 'solidity-ast';
3
+ import { findAll, astDereferencer } from 'solidity-ast/utils';
4
+ import { artifacts } from 'hardhat';
5
+
6
+ import { SolcOutput } from './solc-api';
7
+ import { getStorageUpgradeErrors } from './storage';
8
+ import { StorageLayout } from './storage/layout';
9
+ import { extractStorageLayout } from './storage/extract';
10
+ import { stabilizeStorageLayout } from './utils/stabilize-layout';
11
+
12
+ interface Context {
13
+ extractStorageLayout: (contract: string) => ReturnType<typeof extractStorageLayout>;
14
+ }
15
+
16
+ const test = _test as TestFn<Context>;
17
+
18
+ test.before(async t => {
19
+ const buildInfo = await artifacts.getBuildInfo('contracts/test/Namespaced.sol:Example');
20
+ if (buildInfo === undefined) {
21
+ throw new Error('Build info not found');
22
+ }
23
+ const solcOutput: SolcOutput = buildInfo.output;
24
+ const contracts: Record<string, ContractDefinition> = {};
25
+ const storageLayouts: Record<string, StorageLayout> = {};
26
+ for (const def of findAll('ContractDefinition', solcOutput.sources['contracts/test/Namespaced.sol'].ast)) {
27
+ contracts[def.name] = def;
28
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
29
+ storageLayouts[def.name] = solcOutput.contracts['contracts/test/Namespaced.sol'][def.name].storageLayout!;
30
+ }
31
+ const deref = astDereferencer(solcOutput);
32
+ t.context.extractStorageLayout = name =>
33
+ extractStorageLayout(contracts[name], dummyDecodeSrc, deref, storageLayouts[name]);
34
+ });
35
+
36
+ const dummyDecodeSrc = () => 'file.sol:1';
37
+
38
+ test('layout', t => {
39
+ const layout = t.context.extractStorageLayout('Example');
40
+ t.snapshot(stabilizeStorageLayout(layout));
41
+ });
42
+
43
+ test('multiple namespaces', t => {
44
+ const layout = t.context.extractStorageLayout('MultipleNamespaces');
45
+ t.snapshot(stabilizeStorageLayout(layout));
46
+ });
47
+
48
+ test('namespaced upgrade ok', t => {
49
+ const v1 = t.context.extractStorageLayout('Example');
50
+ const v2 = t.context.extractStorageLayout('ExampleV2_Ok');
51
+ const comparison = getStorageUpgradeErrors(v1, v2);
52
+ t.deepEqual(comparison, []);
53
+ });
54
+
55
+ test('namespaced upgrade bad', t => {
56
+ const v1 = t.context.extractStorageLayout('Example');
57
+ const v2 = t.context.extractStorageLayout('ExampleV2_Bad');
58
+ const comparison = getStorageUpgradeErrors(v1, v2);
59
+ t.like(comparison, {
60
+ length: 1,
61
+ 0: {
62
+ kind: 'delete',
63
+ original: {
64
+ contract: 'Example',
65
+ label: 'x',
66
+ type: {
67
+ id: 't_uint256',
68
+ },
69
+ },
70
+ },
71
+ });
72
+ });
73
+
74
+ test('recursive struct outer ok', t => {
75
+ const v1 = t.context.extractStorageLayout('RecursiveStruct');
76
+ const v2 = t.context.extractStorageLayout('RecursiveStructV2_Outer_Ok');
77
+ const comparison = getStorageUpgradeErrors(v1, v2);
78
+ t.deepEqual(comparison, []);
79
+ });
80
+
81
+ test('recursive struct bad', t => {
82
+ const v1 = t.context.extractStorageLayout('RecursiveStruct');
83
+ const v2 = t.context.extractStorageLayout('RecursiveStructV2_Bad');
84
+ const comparison = getStorageUpgradeErrors(v1, v2);
85
+ t.like(comparison, {
86
+ length: 1,
87
+ 0: {
88
+ kind: 'typechange',
89
+ change: {
90
+ kind: 'struct members',
91
+ ops: {
92
+ length: 1,
93
+ 0: { kind: 'append' },
94
+ },
95
+ },
96
+ original: { label: 's' },
97
+ updated: { label: 's' },
98
+ },
99
+ });
100
+ });
101
+
102
+ test('multiple namespaces and regular variables ok', t => {
103
+ const v1 = t.context.extractStorageLayout('MultipleNamespacesAndRegularVariables');
104
+ const v2 = t.context.extractStorageLayout('MultipleNamespacesAndRegularVariablesV2_Ok');
105
+ const comparison = getStorageUpgradeErrors(v1, v2);
106
+ t.deepEqual(comparison, []);
107
+ });
108
+
109
+ test('multiple namespaces and regular variables bad', t => {
110
+ const v1 = t.context.extractStorageLayout('MultipleNamespacesAndRegularVariables');
111
+ const v2 = t.context.extractStorageLayout('MultipleNamespacesAndRegularVariablesV2_Bad');
112
+ const comparison = getStorageUpgradeErrors(v1, v2);
113
+ t.like(comparison, {
114
+ length: 5,
115
+ 0: {
116
+ kind: 'insert',
117
+ updated: {
118
+ label: 'c',
119
+ },
120
+ },
121
+ 1: {
122
+ kind: 'layoutchange',
123
+ updated: {
124
+ label: 'a', // layout available for regular variable outside of namespace
125
+ },
126
+ },
127
+ 2: {
128
+ kind: 'layoutchange',
129
+ updated: {
130
+ label: 'b', // layout available for regular variable outside of namespace
131
+ },
132
+ },
133
+ 3: {
134
+ kind: 'insert',
135
+ updated: {
136
+ label: 'c',
137
+ },
138
+ },
139
+ 4: {
140
+ kind: 'insert',
141
+ updated: {
142
+ label: 'c',
143
+ },
144
+ },
145
+ });
146
+ });
@@ -0,0 +1,89 @@
1
+ # Snapshot report for `src/storage-namespaced.test.ts`
2
+
3
+ The actual snapshot is saved in `storage-namespaced.test.ts.snap`.
4
+
5
+ Generated by [AVA](https://avajs.dev).
6
+
7
+ ## layout
8
+
9
+ > Snapshot 1
10
+
11
+ {
12
+ namespaces: [
13
+ [
14
+ 'erc7201:example.main',
15
+ [
16
+ {
17
+ contract: 'Example',
18
+ label: 'x',
19
+ src: 'file.sol:1',
20
+ type: 't_uint256',
21
+ },
22
+ {
23
+ contract: 'Example',
24
+ label: 'y',
25
+ src: 'file.sol:1',
26
+ type: 't_uint256',
27
+ },
28
+ ],
29
+ ],
30
+ ],
31
+ storage: [],
32
+ types: [
33
+ [
34
+ 't_uint256',
35
+ {
36
+ label: 'uint256',
37
+ members: undefined,
38
+ },
39
+ ],
40
+ ],
41
+ }
42
+
43
+ ## multiple namespaces
44
+
45
+ > Snapshot 1
46
+
47
+ {
48
+ namespaces: [
49
+ [
50
+ 'erc7201:one',
51
+ [
52
+ {
53
+ contract: 'MultipleNamespaces',
54
+ label: 'a',
55
+ src: 'file.sol:1',
56
+ type: 't_uint256',
57
+ },
58
+ ],
59
+ ],
60
+ [
61
+ 'erc7201:two',
62
+ [
63
+ {
64
+ contract: 'MultipleNamespaces',
65
+ label: 'a',
66
+ src: 'file.sol:1',
67
+ type: 't_uint128',
68
+ },
69
+ ],
70
+ ],
71
+ ],
72
+ storage: [],
73
+ types: [
74
+ [
75
+ 't_uint256',
76
+ {
77
+ label: 'uint256',
78
+ members: undefined,
79
+ },
80
+ ],
81
+ [
82
+ 't_uint128',
83
+ {
84
+ label: 'uint128',
85
+ members: undefined,
86
+ },
87
+ ],
88
+ ],
89
+ }
@@ -9,6 +9,7 @@ Generated by [AVA](https://avajs.dev).
9
9
  > Snapshot 1
10
10
 
11
11
  {
12
+ namespaces: [],
12
13
  storage: [
13
14
  {
14
15
  contract: 'Storage1',
@@ -92,6 +93,7 @@ Generated by [AVA](https://avajs.dev).
92
93
  > Snapshot 1
93
94
 
94
95
  {
96
+ namespaces: [],
95
97
  storage: [
96
98
  {
97
99
  contract: 'Storage2',
Binary file
@@ -0,0 +1,37 @@
1
+ import test from 'ava';
2
+ import { EthereumProvider } from './provider';
3
+ import { getUpgradeInterfaceVersion } from './upgrade-interface-version';
4
+
5
+ const hash = '0x1234';
6
+
7
+ function makeProviderReturning(result: unknown): EthereumProvider {
8
+ return { send: (_method: string, _params: unknown[]) => Promise.resolve(result) } as EthereumProvider;
9
+ }
10
+
11
+ function makeProviderError(msg: string): EthereumProvider {
12
+ return {
13
+ send: (_method: string, _params: unknown[]) => {
14
+ throw new Error(msg);
15
+ },
16
+ } as EthereumProvider;
17
+ }
18
+
19
+ test('getUpgradeInterfaceVersion returns version', async t => {
20
+ // abi encoding of '5.0.0'
21
+ const provider = makeProviderReturning(
22
+ '0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005352e302e30000000000000000000000000000000000000000000000000000000',
23
+ );
24
+ t.is(await getUpgradeInterfaceVersion(provider, hash), '5.0.0');
25
+ });
26
+
27
+ test('getUpgradeInterfaceVersion throws unrelated error', async t => {
28
+ const provider = makeProviderError('unrelated error');
29
+ await t.throwsAsync(() => getUpgradeInterfaceVersion(provider, hash), { message: 'unrelated error' });
30
+ });
31
+
32
+ test('getUpgradeInterfaceVersion returns undefined for invalid selector', async t => {
33
+ const provider = makeProviderError(
34
+ `Transaction reverted: function selector was not recognized and there's no fallback function`,
35
+ );
36
+ t.is(await getUpgradeInterfaceVersion(provider, hash), undefined);
37
+ });
@@ -0,0 +1,27 @@
1
+ import { callOptionalSignature } from './call-optional-signature';
2
+ import { EthereumProvider } from './provider';
3
+
4
+ export async function getUpgradeInterfaceVersion(
5
+ provider: EthereumProvider,
6
+ address: string,
7
+ ): Promise<string | undefined> {
8
+ const encodedVersion = await callOptionalSignature(provider, address, 'UPGRADE_INTERFACE_VERSION()');
9
+ if (encodedVersion !== undefined) {
10
+ // Encoded string
11
+ const buf = Buffer.from(encodedVersion.replace(/^0x/, ''), 'hex');
12
+
13
+ // The first 32 bytes represent the offset, which should be 32 for a string
14
+ const offset = parseInt(buf.slice(0, 32).toString('hex'), 16);
15
+ if (offset !== 32) {
16
+ throw new Error(`Unexpected type for UPGRADE_INTERFACE_VERSION at address ${address}. Expected a string`);
17
+ }
18
+
19
+ // The next 32 bytes represent the length of the string
20
+ const length = parseInt(buf.slice(32, 64).toString('hex'), 16);
21
+
22
+ // The rest is the string itself
23
+ return buf.slice(64, 64 + length).toString('utf8');
24
+ } else {
25
+ return undefined;
26
+ }
27
+ }
@@ -1,6 +1,14 @@
1
1
  import { execall } from './execall';
2
2
  import { Node } from 'solidity-ast/node';
3
3
 
4
+ /**
5
+ * Whether the given doc string has an annotation tag.
6
+ */
7
+ export function hasAnnotationTag(doc: string, tag: string): boolean {
8
+ const regex = new RegExp(`^\\s*(@custom:${tag})(\\s|$)`, 'm');
9
+ return regex.test(doc);
10
+ }
11
+
4
12
  /**
5
13
  * Get args from the doc string matching the given tag.
6
14
  *
@@ -0,0 +1,74 @@
1
+ import test, { ExecutionContext } from 'ava';
2
+ import { artifacts, run } from 'hardhat';
3
+ import {
4
+ TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD,
5
+ TASK_COMPILE_SOLIDITY_RUN_SOLC,
6
+ TASK_COMPILE_SOLIDITY_RUN_SOLCJS,
7
+ } from 'hardhat/builtin-tasks/task-names';
8
+
9
+ import { makeNamespacedInput } from './make-namespaced';
10
+ import { SolcBuild } from 'hardhat/types/builtin-tasks';
11
+ import { SolcInput, SolcOutput } from '../solc-api';
12
+ import { BuildInfo } from 'hardhat/types';
13
+
14
+ test('make namespaced input', async t => {
15
+ const origBuildInfo = await artifacts.getBuildInfo('contracts/test/NamespacedToModify.sol:Example');
16
+ await testMakeNamespaced(origBuildInfo, t, '0.8.20');
17
+ });
18
+
19
+ test('make namespaced input - solc 0.7', async t => {
20
+ // 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
+ const origBuildInfo = await artifacts.getBuildInfo('contracts/test/NamespacedToModify07.sol:HasFunction');
22
+ await testMakeNamespaced(origBuildInfo, t, '0.7.6');
23
+ });
24
+
25
+ async function testMakeNamespaced(
26
+ origBuildInfo: BuildInfo | undefined,
27
+ t: ExecutionContext<unknown>,
28
+ solcVersion: string,
29
+ ) {
30
+ if (origBuildInfo === undefined) {
31
+ throw new Error('Build info not found');
32
+ }
33
+
34
+ // Inefficient, but we want to test that we don't actually modify the original input object
35
+ const origInput = JSON.parse(JSON.stringify(origBuildInfo.input));
36
+
37
+ const modifiedInput = makeNamespacedInput(origBuildInfo.input, origBuildInfo.output);
38
+ normalizeStateVariableNames(modifiedInput);
39
+ t.snapshot(modifiedInput);
40
+
41
+ t.deepEqual(origBuildInfo.input, origInput);
42
+ t.notDeepEqual(modifiedInput, origInput);
43
+
44
+ // Run hardhat compile on the modified input and make sure it has no errors
45
+ const modifiedOutput = await hardhatCompile(modifiedInput, solcVersion);
46
+ t.is(modifiedOutput.errors, undefined);
47
+ }
48
+
49
+ function normalizeStateVariableNames(input: SolcInput): void {
50
+ for (const source of Object.values(input.sources)) {
51
+ if (source.content !== undefined) {
52
+ source.content = source.content.replace(/\$MainStorage_\d{1,6};/g, '$MainStorage_random;');
53
+ }
54
+ }
55
+ }
56
+
57
+ async function hardhatCompile(input: SolcInput, solcVersion: string): Promise<SolcOutput> {
58
+ const solcBuild: SolcBuild = await run(TASK_COMPILE_SOLIDITY_GET_SOLC_BUILD, {
59
+ quiet: true,
60
+ solcVersion,
61
+ });
62
+
63
+ if (solcBuild.isSolcJs) {
64
+ return await run(TASK_COMPILE_SOLIDITY_RUN_SOLCJS, {
65
+ input,
66
+ solcJsPath: solcBuild.compilerPath,
67
+ });
68
+ } else {
69
+ return await run(TASK_COMPILE_SOLIDITY_RUN_SOLC, {
70
+ input,
71
+ solcPath: solcBuild.compilerPath,
72
+ });
73
+ }
74
+ }
@@ -0,0 +1,154 @@
1
+ # Snapshot report for `src/utils/make-namespaced.test.ts`
2
+
3
+ The actual snapshot is saved in `make-namespaced.test.ts.snap`.
4
+
5
+ Generated by [AVA](https://avajs.dev).
6
+
7
+ ## make namespaced input
8
+
9
+ > Snapshot 1
10
+
11
+ {
12
+ language: 'Solidity',
13
+ settings: {
14
+ optimizer: {
15
+ enabled: true,
16
+ runs: 200,
17
+ },
18
+ outputSelection: {
19
+ '*': {
20
+ '': [
21
+ 'ast',
22
+ ],
23
+ '*': [
24
+ 'storageLayout',
25
+ ],
26
+ },
27
+ },
28
+ },
29
+ sources: {
30
+ 'contracts/test/NamespacedToModify.sol': {
31
+ content: `// SPDX-License-Identifier: MIT␊
32
+ pragma solidity ^0.8.20;␊
33
+ ␊
34
+ contract Example {␊
35
+ /// @custom:storage-location erc7201:example.main␊
36
+ struct MainStorage {␊
37
+ uint256 x;␊
38
+ uint256 y;␊
39
+ } MainStorage $MainStorage_random;␊
40
+ ␊
41
+ ␊
42
+ ␊
43
+ ␊
44
+ ␊
45
+ ␊
46
+ ␊
47
+ ␊
48
+ ␊
49
+ struct MyStruct { uint b; }␊
50
+ ␊
51
+ // keccak256(abi.encode(uint256(keccak256("example.main")) - 1)) & ~bytes32(uint256(0xff));␊
52
+ ␊
53
+ ␊
54
+ ␊
55
+ ␊
56
+ ␊
57
+ ␊
58
+ /// @notice standlone natspec␊
59
+ ␊
60
+ ␊
61
+ ␊
62
+ ␊
63
+ // standalone doc␊
64
+ ␊
65
+ /**␊
66
+ * standlone doc block␊
67
+ */␊
68
+ ␊
69
+ ␊
70
+ ␊
71
+ ␊
72
+ ␊
73
+ ␊
74
+ }␊
75
+ ␊
76
+ contract HasFunction {␊
77
+ ␊
78
+ ␊
79
+ }␊
80
+ ␊
81
+ contract UsingFunction is HasFunction {␊
82
+ ␊
83
+ }␊
84
+ ␊
85
+ uint256 constant FreeFunctionUsingSelector = 0;␊
86
+ ␊
87
+ uint256 constant CONSTANT_USING_SELECTOR = 0;␊
88
+ ␊
89
+ library Lib {␊
90
+ ␊
91
+ ␊
92
+ ␊
93
+ }␊
94
+ ␊
95
+ contract Consumer {␊
96
+ ␊
97
+ ␊
98
+ ␊
99
+ ␊
100
+ ␊
101
+ }␊
102
+ ␊
103
+ uint256 constant plusTwo = 0;␊
104
+ ␊
105
+ ␊
106
+ ␊
107
+ contract UsingForDirectives {␊
108
+ ␊
109
+ ␊
110
+ ␊
111
+ }`,
112
+ },
113
+ },
114
+ }
115
+
116
+ ## make namespaced input - solc 0.7
117
+
118
+ > Snapshot 1
119
+
120
+ {
121
+ language: 'Solidity',
122
+ settings: {
123
+ optimizer: {
124
+ enabled: true,
125
+ runs: 200,
126
+ },
127
+ outputSelection: {
128
+ '*': {
129
+ '': [
130
+ 'ast',
131
+ ],
132
+ '*': [
133
+ 'storageLayout',
134
+ ],
135
+ },
136
+ },
137
+ },
138
+ sources: {
139
+ 'contracts/test/NamespacedToModify07.sol': {
140
+ content: `// SPDX-License-Identifier: MIT␊
141
+ pragma solidity 0.7.6;␊
142
+ ␊
143
+ contract HasFunction {␊
144
+ ␊
145
+ ␊
146
+ }␊
147
+ ␊
148
+ contract UsingFunction is HasFunction {␊
149
+ ␊
150
+ }␊
151
+ `,
152
+ },
153
+ },
154
+ }