@openzeppelin/upgrades-core 1.45.0 → 1.46.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.
Files changed (34) hide show
  1. package/dist/storage/extract.d.ts.map +1 -1
  2. package/dist/storage/extract.js +21 -7
  3. package/dist/storage/extract.js.map +1 -1
  4. package/dist/storage/namespace.d.ts.map +1 -1
  5. package/dist/storage/namespace.js +18 -11
  6. package/dist/storage/namespace.js.map +1 -1
  7. package/dist/storage-erc7201-builtin.test.d.ts +2 -0
  8. package/dist/storage-erc7201-builtin.test.d.ts.map +1 -0
  9. package/dist/storage-erc7201-builtin.test.js +105 -0
  10. package/dist/storage-erc7201-builtin.test.js.map +1 -0
  11. package/dist/utils/erc7201-builtin.d.ts +24 -0
  12. package/dist/utils/erc7201-builtin.d.ts.map +1 -0
  13. package/dist/utils/erc7201-builtin.js +83 -0
  14. package/dist/utils/erc7201-builtin.js.map +1 -0
  15. package/dist/utils/erc7201.d.ts.map +1 -1
  16. package/dist/utils/erc7201.js +5 -3
  17. package/dist/utils/erc7201.js.map +1 -1
  18. package/dist/utils/erc7201.test.js +10 -0
  19. package/dist/utils/erc7201.test.js.map +1 -1
  20. package/dist/utils/integer-literals.d.ts +19 -6
  21. package/dist/utils/integer-literals.d.ts.map +1 -1
  22. package/dist/utils/integer-literals.js +28 -10
  23. package/dist/utils/integer-literals.js.map +1 -1
  24. package/dist/utils/integer-literals.test.js +12 -0
  25. package/dist/utils/integer-literals.test.js.map +1 -1
  26. package/package.json +3 -3
  27. package/src/storage/extract.ts +28 -12
  28. package/src/storage/namespace.ts +21 -11
  29. package/src/storage-erc7201-builtin.test.ts +127 -0
  30. package/src/utils/erc7201-builtin.ts +91 -0
  31. package/src/utils/erc7201.test.ts +12 -0
  32. package/src/utils/erc7201.ts +6 -4
  33. package/src/utils/integer-literals.test.ts +15 -1
  34. package/src/utils/integer-literals.ts +29 -10
@@ -1 +1 @@
1
- {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/storage/extract.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EAEd,mBAAmB,EACnB,QAAQ,EACT,MAAM,cAAc,CAAC;AACtB,OAAO,EAAuB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,YAAY,EAA6B,UAAU,EAAE,MAAM,UAAU,CAAC;AAE9F,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAS5C,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAErE;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,eAAe,CAAC;IACvB,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,kBAAkB,EAC/B,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,eAAe,EACtB,aAAa,CAAC,EAAE,aAAa,EAC7B,iBAAiB,CAAC,EAAE,kBAAkB,GACrC,aAAa,CAmEf;AAuCD,KAAK,cAAc,CACjB,CAAC,SAAS,cAAc,GAAG,gBAAgB,EAC3C,CAAC,SAAS,KAAK,GAAG,UAAU,IAC1B,CAAC,SAAS,cAAc,GAAG,UAAU,EAAE,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAE9F,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,GAAG,gBAAgB,EAAE,OAAO,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAClH,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,GAAG,gBAAgB,EAAE,CAAC,SAAS,KAAK,GAAG,UAAU,EACtG,OAAO,EAAE,CAAC,EACV,aAAa,EAAE;KAAG,CAAC,IAAI,CAAC,GAAG,IAAI;CAAE,GAChC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAmCxB,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,QAkClH"}
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/storage/extract.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EAEd,mBAAmB,EACnB,QAAQ,EACT,MAAM,cAAc,CAAC;AACtB,OAAO,EAAuB,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,YAAY,EAA6B,UAAU,EAAE,MAAM,UAAU,CAAC;AAE9F,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAU5C,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAErE;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,eAAe,CAAC;IACvB,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,kBAAkB,EAC/B,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,eAAe,EACtB,aAAa,CAAC,EAAE,aAAa,EAC7B,iBAAiB,CAAC,EAAE,kBAAkB,GACrC,aAAa,CAmEf;AAsDD,KAAK,cAAc,CACjB,CAAC,SAAS,cAAc,GAAG,gBAAgB,EAC3C,CAAC,SAAS,KAAK,GAAG,UAAU,IAC1B,CAAC,SAAS,cAAc,GAAG,UAAU,EAAE,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AAE9F,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,GAAG,gBAAgB,EAAE,OAAO,EAAE,CAAC,GAAG,cAAc,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAClH,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,GAAG,gBAAgB,EAAE,CAAC,SAAS,KAAK,GAAG,UAAU,EACtG,OAAO,EAAE,CAAC,EACV,aAAa,EAAE;KAAG,CAAC,IAAI,CAAC,GAAG,IAAI;CAAE,GAChC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAmCxB,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,eAAe,QAkClH"}
@@ -16,6 +16,7 @@ const pick_1 = require("../utils/pick");
16
16
  const execall_1 = require("../utils/execall");
17
17
  const namespace_1 = require("./namespace");
18
18
  const error_1 = require("../error");
19
+ const erc7201_builtin_1 = require("../utils/erc7201-builtin");
19
20
  const currentLayoutVersion = '1.2';
20
21
  function isCurrentLayoutVersion(layout) {
21
22
  return layout?.layoutVersion === currentLayoutVersion;
@@ -83,14 +84,27 @@ function extractStorageLayout(contractDef, decodeSrc, deref, storageLayout, name
83
84
  }
84
85
  function loadBaseSlot(contractDef, decodeSrc, layout) {
85
86
  if (contractDef.storageLayout !== undefined) {
86
- if (contractDef.storageLayout.baseSlotExpression.nodeType !== 'Literal') {
87
- const src = decodeSrc(contractDef.storageLayout.baseSlotExpression);
88
- // TODO when Slang supports Solidity 0.8.29, use it to parse the expression (of any node type) into a string, then just save it to `layout.baseSlot`.
89
- // Then when comparing layouts in `storage/index.ts`, it will only be used when detailed storage layout is not available, and the comparison
90
- // can be changed to a string comparison when `layout.baseSlot` not an integer literal.
91
- throw new error_1.UpgradesError(`${src}: Custom storage layout expression with node type ${contractDef.storageLayout.baseSlotExpression.nodeType} is not currently supported`, () => 'Please report this at https://zpl.in/upgrades/report and include the `layout at` expression from your contract.');
87
+ const baseSlotExpression = contractDef.storageLayout.baseSlotExpression;
88
+ if (baseSlotExpression.nodeType === 'Literal') {
89
+ layout.baseSlot = baseSlotExpression.value ?? undefined;
90
+ return;
92
91
  }
93
- layout.baseSlot = contractDef.storageLayout.baseSlotExpression.value ?? undefined;
92
+ // Solidity 0.8.35+ allows the `erc7201(string)` comptime builtin as a base slot, e.g.
93
+ // `layout at erc7201("example.main")`. Resolve it to its computed storage location.
94
+ const resolvedSlot = (0, erc7201_builtin_1.resolveBaseSlot)(baseSlotExpression);
95
+ if (resolvedSlot !== undefined) {
96
+ layout.baseSlot = resolvedSlot;
97
+ return;
98
+ }
99
+ const src = decodeSrc(baseSlotExpression);
100
+ // TODO if a base slot expression other than a numeric literal or an `erc7201(...)` builtin call
101
+ // needs to be supported, evaluate the right approach per expression — either resolve it to a
102
+ // computed value (like the erc7201 builtin) or compare its source text across upgrades. A
103
+ // source-text approach could use Slang to extract the expression's source span (Slang supports
104
+ // `StorageLayoutSpecifier` from 0.8.29) and store it as a string on `layout.baseSlot`, with the
105
+ // upgrade-time comparison in `storage/index.ts:validateBaseSlotUnchanged` falling back to a
106
+ // string compare when `layout.baseSlot` is not a numeric literal.
107
+ throw new error_1.UpgradesError(`${src}: Custom storage layout expression with node type ${baseSlotExpression.nodeType} is not currently supported`, () => 'Please report this at https://zpl.in/upgrades/report and include the `layout at` expression from your contract.');
94
108
  }
95
109
  }
96
110
  const findTypeNames = (0, utils_1.findAll)([
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/storage/extract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/storage/extract.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../src/storage/namespace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,aAAa,EAA6B,MAAM,UAAU,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAkC,MAAM,WAAW,CAAC;AAO/E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,kBAAkB,EAC/B,iBAAiB,CAAC,EAAE,kBAAkB,QAiCvC;AA2ID;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,IAAI,sBAStD;AAwGD,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,WAEvD"}
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../src/storage/namespace.ts"],"names":[],"mappings":"AAGA,OAAO,EAAe,aAAa,EAA6B,MAAM,UAAU,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAkC,MAAM,WAAW,CAAC;AAO/E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,kBAAkB,EAC/B,iBAAiB,CAAC,EAAE,kBAAkB,QAiCvC;AAqJD;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,IAAI,sBAStD;AAwGD,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,WAEvD"}
@@ -36,8 +36,8 @@ const annotations_1 = require("../utils/annotations");
36
36
  const extract_1 = require("./extract");
37
37
  const error_1 = require("../error");
38
38
  const versions = __importStar(require("compare-versions"));
39
- const integer_literals_1 = require("../utils/integer-literals");
40
39
  const erc7201_1 = require("../utils/erc7201");
40
+ const erc7201_builtin_1 = require("../utils/erc7201-builtin");
41
41
  const log_1 = require("../utils/log");
42
42
  /**
43
43
  * Loads a contract's namespaces and namespaced type information into the storage layout.
@@ -144,20 +144,27 @@ function addContractNamespacesWithSrc(namespacesWithSrc, decodeSrc, layout, cont
144
144
  * @throws CustomLayoutClashWithNamespaceError if the custom layout clashes with the namespace.
145
145
  */
146
146
  function checkCustomLayoutClashWithNamespace(contractDef, storageLocation, contractName, src) {
147
- if (contractDef.storageLayout !== undefined && storageLocation.startsWith(erc7201_1.ERC7201_FORMULA_PREFIX)) {
148
- const namespaceId = storageLocation.substring(erc7201_1.ERC7201_FORMULA_PREFIX.length);
149
- const calculatedStorageLocation = (0, erc7201_1.calculateERC7201StorageLocation)(namespaceId);
150
- if (contractDef.storageLayout.baseSlotExpression.nodeType === 'Literal') {
151
- const baseSlotNormalized = (0, integer_literals_1.normalizeUint256Literal)(contractDef.storageLayout.baseSlotExpression.value); // TODO: when Solidity supports an erc7201 helper function, also check that for clash
152
- if (baseSlotNormalized === calculatedStorageLocation) {
153
- throw new CustomLayoutClashWithNamespaceError(storageLocation, contractName, src);
154
- }
155
- }
147
+ if (contractDef.storageLayout === undefined || !storageLocation.startsWith(erc7201_1.ERC7201_FORMULA_PREFIX)) {
148
+ return;
149
+ }
150
+ const namespaceId = storageLocation.substring(erc7201_1.ERC7201_FORMULA_PREFIX.length);
151
+ // Resolve the base slot (a numeric literal or an erc7201(...) builtin call) and compare it against
152
+ // the namespace's computed storage location. This covers `layout at erc7201("<id>")` using the same
153
+ // id as the namespace, since both resolve to the same hash.
154
+ const baseSlotNormalized = (0, erc7201_builtin_1.resolveBaseSlot)(contractDef.storageLayout.baseSlotExpression);
155
+ if (baseSlotNormalized !== undefined && baseSlotNormalized === (0, erc7201_1.calculateERC7201StorageLocation)(namespaceId)) {
156
+ throw new CustomLayoutClashWithNamespaceError(storageLocation, contractName, src);
156
157
  }
157
158
  }
158
159
  function warnIfCustomLayoutAndNamespacesFound(namespacesWithSrc, decodeSrc, origContractDef) {
159
- // TODO: when Solidity supports an erc7201 helper function, only give this warning if the custom storage layout is not using the erc7201 helper function
160
160
  if (Object.entries(namespacesWithSrc).length > 0 && origContractDef.storageLayout !== undefined) {
161
+ // The warning is meant for users who pick an arbitrary literal slot that could land inside a
162
+ // namespace's range. When the base slot uses the erc7201 comptime builtin, it relies on the
163
+ // same collision resistance that namespaces rely on against each other, so suppress the warning;
164
+ // the tool likewise does not warn when multiple namespaces coexist.
165
+ if ((0, erc7201_builtin_1.getErc7201BuiltinNamespaceId)(origContractDef.storageLayout.baseSlotExpression) !== undefined) {
166
+ return;
167
+ }
161
168
  const contractName = origContractDef.canonicalName ?? origContractDef.name;
162
169
  (0, log_1.logWarning)(`${decodeSrc(origContractDef.storageLayout)}: Ensure custom storage layout does not overlap with namespaced storage layout.`, [
163
170
  `Contract \`${contractName}\` has both custom storage layout and namespaces.`,
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../src/storage/namespace.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../src/storage/namespace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=storage-erc7201-builtin.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-erc7201-builtin.test.d.ts","sourceRoot":"","sources":["../src/storage-erc7201-builtin.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ava_1 = __importDefault(require("ava"));
7
+ const utils_1 = require("solidity-ast/utils");
8
+ const hardhat_1 = require("hardhat");
9
+ const storage_1 = require("./storage");
10
+ const extract_1 = require("./storage/extract");
11
+ const test = ava_1.default;
12
+ const SOURCE = 'contracts/test/Erc7201Builtin.sol';
13
+ test.before(async (t) => {
14
+ const buildInfo = await hardhat_1.artifacts.getBuildInfo(`${SOURCE}:Erc7201Builtin`);
15
+ if (buildInfo === undefined) {
16
+ throw new Error('Build info not found');
17
+ }
18
+ const solcOutput = buildInfo.output;
19
+ const contracts = {};
20
+ const storageLayouts = {};
21
+ for (const def of (0, utils_1.findAll)('ContractDefinition', solcOutput.sources[SOURCE].ast)) {
22
+ contracts[def.name] = def;
23
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
24
+ storageLayouts[def.name] = solcOutput.contracts[SOURCE][def.name].storageLayout;
25
+ }
26
+ const deref = (0, utils_1.astDereferencer)(solcOutput);
27
+ t.context.extractStorageLayout = name => (0, extract_1.extractStorageLayout)(contracts[name], dummyDecodeSrc, deref, storageLayouts[name]);
28
+ t.context.extractStorageLayoutFallback = name => (0, extract_1.extractStorageLayout)(contracts[name], dummyDecodeSrc, deref, undefined);
29
+ });
30
+ const dummyDecodeSrc = () => 'file.sol:1';
31
+ test('erc7201 builtin base slot - extract', t => {
32
+ const layout = t.context.extractStorageLayout('Erc7201Builtin');
33
+ t.is(layout.baseSlot, '0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500');
34
+ t.is(layout.storage.length, 1);
35
+ t.is(layout.storage[0].label, 'a');
36
+ });
37
+ test('erc7201 builtin base slot - append - ok', t => {
38
+ const v1 = t.context.extractStorageLayout('Erc7201Builtin');
39
+ const v2 = t.context.extractStorageLayout('Erc7201Builtin_Append_Ok');
40
+ t.deepEqual((0, storage_1.getStorageUpgradeErrors)(v1, v2), []);
41
+ });
42
+ test('erc7201 builtin base slot - append - fallback - ok', t => {
43
+ const v1 = t.context.extractStorageLayoutFallback('Erc7201Builtin');
44
+ const v2 = t.context.extractStorageLayoutFallback('Erc7201Builtin_Append_Ok');
45
+ t.deepEqual((0, storage_1.getStorageUpgradeErrors)(v1, v2), []);
46
+ });
47
+ test('erc7201 builtin base slot - changed id - bad', t => {
48
+ const v1 = t.context.extractStorageLayout('Erc7201Builtin');
49
+ const v2 = t.context.extractStorageLayout('Erc7201Builtin_Changed_Id_Bad');
50
+ const comparison = (0, storage_1.getStorageUpgradeErrors)(v1, v2);
51
+ t.true(comparison.length > 0);
52
+ t.is(comparison[0].kind, 'layoutchange');
53
+ });
54
+ test('erc7201 builtin base slot - changed id - fallback - bad', t => {
55
+ const v1 = t.context.extractStorageLayoutFallback('Erc7201Builtin');
56
+ const v2 = t.context.extractStorageLayoutFallback('Erc7201Builtin_Changed_Id_Bad');
57
+ // Base slot differs between the two erc7201 ids, so the fallback base-slot check must fail.
58
+ t.throws(() => (0, storage_1.getStorageUpgradeErrors)(v1, v2), {
59
+ message: /Base slot for custom storage layout changed/,
60
+ });
61
+ });
62
+ test('erc7201 builtin and literal-equivalent base slots compare equal', t => {
63
+ const builtin = t.context.extractStorageLayout('Erc7201Builtin');
64
+ const literal = t.context.extractStorageLayout('Erc7201Builtin_Literal_Equivalent');
65
+ // Both resolve to the same base slot; the fallback (base-slot) check must treat them as unchanged.
66
+ const builtinFallback = t.context.extractStorageLayoutFallback('Erc7201Builtin');
67
+ const literalFallback = t.context.extractStorageLayoutFallback('Erc7201Builtin_Literal_Equivalent');
68
+ t.deepEqual((0, storage_1.getStorageUpgradeErrors)(builtin, literal), []);
69
+ t.deepEqual((0, storage_1.getStorageUpgradeErrors)(builtinFallback, literalFallback), []);
70
+ });
71
+ test('erc7201 builtin base slot clashes with namespace - error', t => {
72
+ t.throws(() => t.context.extractStorageLayout('Erc7201Builtin_Clash'), {
73
+ message: /Custom layout for contract Erc7201Builtin_Clash clashes with the storage location for namespace erc7201:example\.main/,
74
+ });
75
+ });
76
+ test('erc7201 builtin base slot different from namespace - no error and no warning', t => {
77
+ const warnings = captureWarnings(() => {
78
+ const layout = t.context.extractStorageLayout('Erc7201Builtin_NoClash_NoWarning');
79
+ t.truthy(layout.baseSlot);
80
+ });
81
+ t.deepEqual(warnings, []);
82
+ });
83
+ test('erc7201 builtin accepts a unicode string literal argument', t => {
84
+ const layout = t.context.extractStorageLayout('Erc7201Builtin_Unicode');
85
+ t.is(layout.baseSlot, '0x2d3e72b7d91644a80150e2643e65016def7067dc9568719707e7eca1a5dab800');
86
+ });
87
+ test('literal base slot with namespace - warning not suppressed', t => {
88
+ const warnings = captureWarnings(() => t.context.extractStorageLayout('Erc7201Builtin_LiteralBase_Warns'));
89
+ t.true(warnings.some(w => w.includes('custom storage layout')));
90
+ });
91
+ function captureWarnings(fn) {
92
+ const warnings = [];
93
+ const original = console.error;
94
+ console.error = (...args) => {
95
+ warnings.push(args.map(String).join(' '));
96
+ };
97
+ try {
98
+ fn();
99
+ }
100
+ finally {
101
+ console.error = original;
102
+ }
103
+ return warnings;
104
+ }
105
+ //# sourceMappingURL=storage-erc7201-builtin.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-erc7201-builtin.test.js","sourceRoot":"","sources":["../src/storage-erc7201-builtin.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { Expression } from 'solidity-ast';
2
+ /**
3
+ * Recognizes the Solidity 0.8.35+ `erc7201(string)` comptime builtin, which evaluates the ERC-7201
4
+ * storage location for a namespace id and can be used in a compile-time context such as a `layout at`
5
+ * specifier (e.g. `contract C layout at erc7201("example.main")`).
6
+ *
7
+ * The builtin compiles to an ordinary `FunctionCall` node, so it is matched by its shape rather than
8
+ * by a dedicated AST node type.
9
+ *
10
+ * @param node The expression to check.
11
+ * @returns The namespace id passed to the builtin (without the `erc7201:` prefix), or undefined if the
12
+ * expression is not a call to the `erc7201` builtin with a single string literal argument.
13
+ */
14
+ export declare function getErc7201BuiltinNamespaceId(node: Expression): string | undefined;
15
+ /**
16
+ * Resolves an expression to its base slot as a normalized uint256 hex string, for either a numeric
17
+ * literal or an `erc7201(...)` builtin call.
18
+ *
19
+ * @param node The expression to resolve.
20
+ * @returns The normalized base slot hex string, or undefined if the expression is neither a numeric
21
+ * literal nor a resolvable `erc7201(...)` builtin call.
22
+ */
23
+ export declare function resolveBaseSlot(node: Expression): string | undefined;
24
+ //# sourceMappingURL=erc7201-builtin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erc7201-builtin.d.ts","sourceRoot":"","sources":["../../src/utils/erc7201-builtin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAW,MAAM,cAAc,CAAC;AAKnD;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAmCjF;AAUD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAWpE"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getErc7201BuiltinNamespaceId = getErc7201BuiltinNamespaceId;
4
+ exports.resolveBaseSlot = resolveBaseSlot;
5
+ const erc7201_1 = require("./erc7201");
6
+ const integer_literals_1 = require("./integer-literals");
7
+ const error_1 = require("../error");
8
+ /**
9
+ * Recognizes the Solidity 0.8.35+ `erc7201(string)` comptime builtin, which evaluates the ERC-7201
10
+ * storage location for a namespace id and can be used in a compile-time context such as a `layout at`
11
+ * specifier (e.g. `contract C layout at erc7201("example.main")`).
12
+ *
13
+ * The builtin compiles to an ordinary `FunctionCall` node, so it is matched by its shape rather than
14
+ * by a dedicated AST node type.
15
+ *
16
+ * @param node The expression to check.
17
+ * @returns The namespace id passed to the builtin (without the `erc7201:` prefix), or undefined if the
18
+ * expression is not a call to the `erc7201` builtin with a single string literal argument.
19
+ */
20
+ function getErc7201BuiltinNamespaceId(node) {
21
+ // Check that this is a function call to an identifier named `erc7201`. Return undefined for
22
+ // anything else so the caller can fall through to other base-slot forms.
23
+ if (node.nodeType !== 'FunctionCall' || node.kind !== 'functionCall') {
24
+ return undefined;
25
+ }
26
+ const callee = node.expression;
27
+ if (callee.nodeType !== 'Identifier' || callee.name !== 'erc7201') {
28
+ return undefined;
29
+ }
30
+ // Beyond this point, the call is to `erc7201(...)`. Check its expected shape — one string-literal
31
+ // argument with no user-defined declaration shadowing the builtin — and throw if anything is off.
32
+ // Valid Solidity 0.8.35+ cannot produce these mismatches in a call to the builtin:
33
+ // - User-defined `erc7201` (`referencedDeclaration >= 0`): solc resolves the call to the builtin
34
+ // when both are in scope, so this shape doesn't reach a successful compile.
35
+ // - Wrong number of arguments: enforced by the builtin's signature.
36
+ // - Non-`Literal` argument or non-string literal `kind`: the builtin's signature requires a
37
+ // comptime-constant string literal. `hex"..."` is type `bytes` and wouldn't typecheck.
38
+ // We throw instead of returning undefined so a future solc emitting one of these surfaces loudly.
39
+ if (typeof callee.referencedDeclaration === 'number' && callee.referencedDeclaration >= 0) {
40
+ throw unexpectedErc7201BuiltinAst('callee resolves to a user-defined declaration');
41
+ }
42
+ if (node.arguments.length !== 1) {
43
+ throw unexpectedErc7201BuiltinAst(`expected 1 argument, got ${node.arguments.length}`);
44
+ }
45
+ const arg = node.arguments[0];
46
+ if (arg.nodeType !== 'Literal') {
47
+ throw unexpectedErc7201BuiltinAst(`argument is ${arg.nodeType}, expected Literal`);
48
+ }
49
+ if (arg.kind !== 'string' && arg.kind !== 'unicodeString') {
50
+ throw unexpectedErc7201BuiltinAst(`argument literal kind is ${arg.kind}, expected string or unicodeString`);
51
+ }
52
+ return getStringLiteralValue(arg);
53
+ }
54
+ function unexpectedErc7201BuiltinAst(detail) {
55
+ return new error_1.UpgradesError(`Unexpected AST for \`erc7201(...)\` builtin call: ${detail}`, () => 'Please report this at https://zpl.in/upgrades/report and include the `erc7201(...)` expression from your contract.');
56
+ }
57
+ /**
58
+ * Resolves an expression to its base slot as a normalized uint256 hex string, for either a numeric
59
+ * literal or an `erc7201(...)` builtin call.
60
+ *
61
+ * @param node The expression to resolve.
62
+ * @returns The normalized base slot hex string, or undefined if the expression is neither a numeric
63
+ * literal nor a resolvable `erc7201(...)` builtin call.
64
+ */
65
+ function resolveBaseSlot(node) {
66
+ if (node.nodeType === 'Literal') {
67
+ return (0, integer_literals_1.normalizeUint256Literal)(node.value);
68
+ }
69
+ const id = getErc7201BuiltinNamespaceId(node);
70
+ if (id !== undefined) {
71
+ return (0, erc7201_1.calculateERC7201StorageLocation)(id);
72
+ }
73
+ return undefined;
74
+ }
75
+ function getStringLiteralValue(literal) {
76
+ // solc populates `value` for `kind: 'string'`/`'unicodeString'` literals; throw defensively if
77
+ // a future solc ever produces a null/missing `value` for such a literal.
78
+ if (literal.value === undefined || literal.value === null) {
79
+ throw unexpectedErc7201BuiltinAst('string literal `value` is null or missing');
80
+ }
81
+ return literal.value;
82
+ }
83
+ //# sourceMappingURL=erc7201-builtin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"erc7201-builtin.js","sourceRoot":"","sources":["../../src/utils/erc7201-builtin.ts"],"names":[],"mappings":";;AAiBA,oEAmCC;AAkBD,0CAWC;AAhFD,uCAA4D;AAC5D,yDAA6D;AAC7D,oCAAyC;AAEzC;;;;;;;;;;;GAWG;AACH,SAAgB,4BAA4B,CAAC,IAAgB;IAC3D,4FAA4F;IAC5F,yEAAyE;IACzE,IAAI,IAAI,CAAC,QAAQ,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;QACrE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC;IAC/B,IAAI,MAAM,CAAC,QAAQ,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,kGAAkG;IAClG,kGAAkG;IAClG,mFAAmF;IACnF,mGAAmG;IACnG,gFAAgF;IAChF,sEAAsE;IACtE,8FAA8F;IAC9F,2FAA2F;IAC3F,kGAAkG;IAClG,IAAI,OAAO,MAAM,CAAC,qBAAqB,KAAK,QAAQ,IAAI,MAAM,CAAC,qBAAqB,IAAI,CAAC,EAAE,CAAC;QAC1F,MAAM,2BAA2B,CAAC,+CAA+C,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,2BAA2B,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IACzF,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,GAAG,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,2BAA2B,CAAC,eAAe,GAAG,CAAC,QAAQ,oBAAoB,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QAC1D,MAAM,2BAA2B,CAAC,4BAA4B,GAAG,CAAC,IAAI,oCAAoC,CAAC,CAAC;IAC9G,CAAC;IAED,OAAO,qBAAqB,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,2BAA2B,CAAC,MAAc;IACjD,OAAO,IAAI,qBAAa,CACtB,qDAAqD,MAAM,EAAE,EAC7D,GAAG,EAAE,CACH,oHAAoH,CACvH,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,eAAe,CAAC,IAAgB;IAC9C,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,IAAA,0CAAuB,EAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,EAAE,GAAG,4BAA4B,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,OAAO,IAAA,yCAA+B,EAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAgB;IAC7C,+FAA+F;IAC/F,yEAAyE;IACzE,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1D,MAAM,2BAA2B,CAAC,2CAA2C,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC;AACvB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"erc7201.d.ts","sourceRoot":"","sources":["../../src/utils/erc7201.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,aAAa,CAAC;AAEjD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAalE"}
1
+ {"version":3,"file":"erc7201.d.ts","sourceRoot":"","sources":["../../src/utils/erc7201.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,sBAAsB,aAAa,CAAC;AAEjD;;;;;;GAMG;AACH,wBAAgB,+BAA+B,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAalE"}
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ERC7201_FORMULA_PREFIX = void 0;
4
4
  exports.calculateERC7201StorageLocation = calculateERC7201StorageLocation;
5
5
  const ethereumjs_util_1 = require("ethereumjs-util");
6
+ const integer_literals_1 = require("./integer-literals");
6
7
  exports.ERC7201_FORMULA_PREFIX = 'erc7201:';
7
8
  /**
8
9
  * Returns the ERC-7201 storage location hash for a given namespace id using formula:
@@ -14,11 +15,12 @@ exports.ERC7201_FORMULA_PREFIX = 'erc7201:';
14
15
  function calculateERC7201StorageLocation(id) {
15
16
  const firstHash = (0, ethereumjs_util_1.keccak256)(Buffer.from(id));
16
17
  const minusOne = BigInt(`0x${firstHash.toString('hex')}`) - 1n;
17
- const minusOneBuffer = Buffer.from(minusOne.toString(16), 'hex');
18
+ // Pad to 64 hex chars so that `Buffer.from` doesn't silently truncate odd-length input;
19
+ // `abi.encode(uint256)` is always 32 bytes.
20
+ const minusOneBuffer = Buffer.from(minusOne.toString(16).padStart(64, '0'), 'hex');
18
21
  const secondHash = (0, ethereumjs_util_1.keccak256)(minusOneBuffer);
19
22
  const mask = BigInt('0xff');
20
23
  const masked = BigInt(`0x${secondHash.toString('hex')}`) & ~mask;
21
- const padded = masked.toString(16).padStart(64, '0');
22
- return `0x${padded}`;
24
+ return (0, integer_literals_1.toBytes32Hex)(masked);
23
25
  }
24
26
  //# sourceMappingURL=erc7201.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"erc7201.js","sourceRoot":"","sources":["../../src/utils/erc7201.ts"],"names":[],"mappings":";;;AAWA,0EAaC;AAxBD,qDAA4C;AAE/B,QAAA,sBAAsB,GAAG,UAAU,CAAC;AAEjD;;;;;;GAMG;AACH,SAAgB,+BAA+B,CAAC,EAAU;IACxD,MAAM,SAAS,GAAG,IAAA,2BAAS,EAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/D,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;IAEjE,MAAM,UAAU,GAAG,IAAA,2BAAS,EAAC,cAAc,CAAC,CAAC;IAE7C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;IAEjE,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAErD,OAAO,KAAK,MAAM,EAAE,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"erc7201.js","sourceRoot":"","sources":["../../src/utils/erc7201.ts"],"names":[],"mappings":";;;AAaA,0EAaC;AA1BD,qDAA4C;AAE5C,yDAAkD;AAErC,QAAA,sBAAsB,GAAG,UAAU,CAAC;AAEjD;;;;;;GAMG;AACH,SAAgB,+BAA+B,CAAC,EAAU;IACxD,MAAM,SAAS,GAAG,IAAA,2BAAS,EAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC;IAC/D,wFAAwF;IACxF,4CAA4C;IAC5C,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IAEnF,MAAM,UAAU,GAAG,IAAA,2BAAS,EAAC,cAAc,CAAC,CAAC;IAE7C,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;IAEjE,OAAO,IAAA,+BAAY,EAAC,MAAM,CAAC,CAAC;AAC9B,CAAC"}
@@ -8,4 +8,14 @@ const erc7201_1 = require("./erc7201");
8
8
  (0, ava_1.default)('calculateERC7201StorageLocation', t => {
9
9
  t.is((0, erc7201_1.calculateERC7201StorageLocation)('example.main'), '0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500');
10
10
  });
11
+ // `keccak256("ns2") - 1` is 63 hex chars (odd-length), which must be zero-padded to 32 bytes
12
+ // before hashing. Regression test for truncation of the intermediate buffer.
13
+ (0, ava_1.default)('calculateERC7201StorageLocation - odd-length intermediate hash', t => {
14
+ t.is((0, erc7201_1.calculateERC7201StorageLocation)('ns2'), '0xa61069020885c09e922542fb3fa98c8d50e6481fc1251ff86c3319a70f0f7d00');
15
+ });
16
+ // `keccak256("ns297") - 1` is 62 hex chars (i.e., its top byte is `0x00`). Without zero-padding,
17
+ // `Buffer.from('hex')` would interpret it as a 31-byte buffer rather than 32, producing the wrong hash.
18
+ (0, ava_1.default)('calculateERC7201StorageLocation - leading-zero-byte intermediate hash', t => {
19
+ t.is((0, erc7201_1.calculateERC7201StorageLocation)('ns297'), '0xe06f9faa11c8032ea604e1764972c1a5594987f1678d8fabf921c28d1a7a4c00');
20
+ });
11
21
  //# sourceMappingURL=erc7201.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"erc7201.test.js","sourceRoot":"","sources":["../../src/utils/erc7201.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAEvB,uCAA4D;AAE5D,IAAA,aAAI,EAAC,iCAAiC,EAAE,CAAC,CAAC,EAAE;IAC1C,CAAC,CAAC,EAAE,CACF,IAAA,yCAA+B,EAAC,cAAc,CAAC,EAC/C,oEAAoE,CACrE,CAAC;AACJ,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"erc7201.test.js","sourceRoot":"","sources":["../../src/utils/erc7201.test.ts"],"names":[],"mappings":";;;;;AAAA,8CAAuB;AAEvB,uCAA4D;AAE5D,IAAA,aAAI,EAAC,iCAAiC,EAAE,CAAC,CAAC,EAAE;IAC1C,CAAC,CAAC,EAAE,CACF,IAAA,yCAA+B,EAAC,cAAc,CAAC,EAC/C,oEAAoE,CACrE,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,6FAA6F;AAC7F,6EAA6E;AAC7E,IAAA,aAAI,EAAC,gEAAgE,EAAE,CAAC,CAAC,EAAE;IACzE,CAAC,CAAC,EAAE,CAAC,IAAA,yCAA+B,EAAC,KAAK,CAAC,EAAE,oEAAoE,CAAC,CAAC;AACrH,CAAC,CAAC,CAAC;AAEH,iGAAiG;AACjG,wGAAwG;AACxG,IAAA,aAAI,EAAC,uEAAuE,EAAE,CAAC,CAAC,EAAE;IAChF,CAAC,CAAC,EAAE,CAAC,IAAA,yCAA+B,EAAC,OAAO,CAAC,EAAE,oEAAoE,CAAC,CAAC;AACvH,CAAC,CAAC,CAAC"}
@@ -1,15 +1,28 @@
1
1
  /**
2
- * Converts a Solidity unsigned integer literal according to https://docs.soliditylang.org/en/latest/types.html#rational-literals
3
- * to a 64-byte padded hex string.
2
+ * Encodes a bigint as a 0x-prefixed, 64-char lowercase hex string — the canonical text encoding of
3
+ * a `bytes32` value, used throughout this package for storage slots and similar 256-bit identifiers.
4
+ * Throws if the value is outside the 0..2^256-1 range, since that almost certainly indicates a bug
5
+ * upstream (overflow, wrong hash, etc.) and would silently produce a string longer than 64 chars.
4
6
  *
5
- * Accepts decimal, hexadecimal, and scientific notation formats.
7
+ * @param value bigint value to encode
8
+ * @returns 0x-prefixed, 64-char lowercase hex string
9
+ */
10
+ export declare function toBytes32Hex(value: bigint): string;
11
+ /**
12
+ * Parses a Solidity unsigned integer literal source string (per
13
+ * https://docs.soliditylang.org/en/latest/types.html#rational-literals) and returns it in the
14
+ * canonical hex form produced by {@link toBytes32Hex}.
15
+ *
16
+ * Parsing is delegated to {@link BigNumber}, which accepts decimal (`1000`), hex (`0x1f`), and
17
+ * scientific notation (`1e18`). Underscore separators and uppercase digits, which BigNumber rejects
18
+ * but Solidity allows, are stripped/lowercased first. Non-integer results (e.g. `1.5e3`) are rejected.
6
19
  *
7
- * If the input is null or undefined, returns '0x0000000000000000000000000000000000000000000000000000000000000000'.
20
+ * If the input is null or undefined, returns the canonical hex form of zero.
8
21
  *
9
22
  * Assumes the input is a valid uint256-compatible literal for Solidity, and only performs minimal validation.
10
23
  *
11
- * @param literal Integer literal to convert
12
- * @returns Hex string with 0x prefix, padded to 64 bytes with leading zeroes
24
+ * @param literal Integer literal source string to parse
25
+ * @returns 0x-prefixed, 64-char lowercase hex string
13
26
  */
14
27
  export declare function normalizeUint256Literal(literal: string | null | undefined): string;
15
28
  //# sourceMappingURL=integer-literals.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"integer-literals.d.ts","sourceRoot":"","sources":["../../src/utils/integer-literals.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAalF"}
1
+ {"version":3,"file":"integer-literals.d.ts","sourceRoot":"","sources":["../../src/utils/integer-literals.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKlD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAWlF"}
@@ -3,32 +3,50 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.toBytes32Hex = toBytes32Hex;
6
7
  exports.normalizeUint256Literal = normalizeUint256Literal;
7
8
  const bignumber_js_1 = __importDefault(require("bignumber.js"));
9
+ const MAX_UINT256 = (1n << 256n) - 1n;
8
10
  /**
9
- * Converts a Solidity unsigned integer literal according to https://docs.soliditylang.org/en/latest/types.html#rational-literals
10
- * to a 64-byte padded hex string.
11
+ * Encodes a bigint as a 0x-prefixed, 64-char lowercase hex string — the canonical text encoding of
12
+ * a `bytes32` value, used throughout this package for storage slots and similar 256-bit identifiers.
13
+ * Throws if the value is outside the 0..2^256-1 range, since that almost certainly indicates a bug
14
+ * upstream (overflow, wrong hash, etc.) and would silently produce a string longer than 64 chars.
11
15
  *
12
- * Accepts decimal, hexadecimal, and scientific notation formats.
16
+ * @param value bigint value to encode
17
+ * @returns 0x-prefixed, 64-char lowercase hex string
18
+ */
19
+ function toBytes32Hex(value) {
20
+ if (value < 0n || value > MAX_UINT256) {
21
+ throw new Error(`Value out of uint256 range: ${value}`);
22
+ }
23
+ return `0x${value.toString(16).padStart(64, '0')}`;
24
+ }
25
+ /**
26
+ * Parses a Solidity unsigned integer literal source string (per
27
+ * https://docs.soliditylang.org/en/latest/types.html#rational-literals) and returns it in the
28
+ * canonical hex form produced by {@link toBytes32Hex}.
29
+ *
30
+ * Parsing is delegated to {@link BigNumber}, which accepts decimal (`1000`), hex (`0x1f`), and
31
+ * scientific notation (`1e18`). Underscore separators and uppercase digits, which BigNumber rejects
32
+ * but Solidity allows, are stripped/lowercased first. Non-integer results (e.g. `1.5e3`) are rejected.
13
33
  *
14
- * If the input is null or undefined, returns '0x0000000000000000000000000000000000000000000000000000000000000000'.
34
+ * If the input is null or undefined, returns the canonical hex form of zero.
15
35
  *
16
36
  * Assumes the input is a valid uint256-compatible literal for Solidity, and only performs minimal validation.
17
37
  *
18
- * @param literal Integer literal to convert
19
- * @returns Hex string with 0x prefix, padded to 64 bytes with leading zeroes
38
+ * @param literal Integer literal source string to parse
39
+ * @returns 0x-prefixed, 64-char lowercase hex string
20
40
  */
21
41
  function normalizeUint256Literal(literal) {
22
42
  if (!literal) {
23
- return '0x0000000000000000000000000000000000000000000000000000000000000000';
43
+ return toBytes32Hex(0n);
24
44
  }
25
45
  const lowercaseNoUnderscores = literal.replace(/_/g, '').toLowerCase();
26
46
  const parsed = new bignumber_js_1.default(lowercaseNoUnderscores);
27
47
  if (!parsed.isInteger()) {
28
48
  throw new Error(`Invalid integer literal: ${literal}`);
29
49
  }
30
- const calculatedValueAsHex = parsed.toString(16);
31
- const padded = calculatedValueAsHex.padStart(64, '0');
32
- return `0x${padded}`;
50
+ return toBytes32Hex(BigInt(parsed.toFixed()));
33
51
  }
34
52
  //# sourceMappingURL=integer-literals.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"integer-literals.js","sourceRoot":"","sources":["../../src/utils/integer-literals.ts"],"names":[],"mappings":";;;;;AAeA,0DAaC;AA5BD,gEAAqC;AAErC;;;;;;;;;;;;GAYG;AACH,SAAgB,uBAAuB,CAAC,OAAkC;IACxE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,oEAAoE,CAAC;IAC9E,CAAC;IACD,MAAM,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAEvE,MAAM,MAAM,GAAG,IAAI,sBAAS,CAAC,sBAAsB,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,oBAAoB,GAAG,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IACtD,OAAO,KAAK,MAAM,EAAE,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"integer-literals.js","sourceRoot":"","sources":["../../src/utils/integer-literals.ts"],"names":[],"mappings":";;;;;AAaA,oCAKC;AAkBD,0DAWC;AA/CD,gEAAqC;AAErC,MAAM,WAAW,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;AAEtC;;;;;;;;GAQG;AACH,SAAgB,YAAY,CAAC,KAAa;IACxC,IAAI,KAAK,GAAG,EAAE,IAAI,KAAK,GAAG,WAAW,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC;AACrD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,uBAAuB,CAAC,OAAkC;IACxE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,YAAY,CAAC,EAAE,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,sBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAEvE,MAAM,MAAM,GAAG,IAAI,sBAAS,CAAC,sBAAsB,CAAC,CAAC;IACrD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AAChD,CAAC"}
@@ -54,4 +54,16 @@ const ZEROES = '0x00000000000000000000000000000000000000000000000000000000000000
54
54
  (0, ava_1.default)('full hex with leading and trailing zeroes', t => {
55
55
  t.is((0, integer_literals_1.normalizeUint256Literal)('0x00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00'), '0x00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00');
56
56
  });
57
+ (0, ava_1.default)('rejects values above uint256 max', t => {
58
+ const tooLarge = '0x10000000000000000000000000000000000000000000000000000000000000000';
59
+ const error = t.throws(() => (0, integer_literals_1.normalizeUint256Literal)(tooLarge));
60
+ t.regex(error?.message ?? '', /uint256 range/);
61
+ });
62
+ (0, ava_1.default)('toBytes32Hex - boundaries', t => {
63
+ const MAX_HEX = '0x' + 'f'.repeat(64);
64
+ t.is((0, integer_literals_1.toBytes32Hex)(0n), '0x' + '0'.repeat(64));
65
+ t.is((0, integer_literals_1.toBytes32Hex)(BigInt(MAX_HEX)), MAX_HEX);
66
+ t.throws(() => (0, integer_literals_1.toBytes32Hex)(BigInt(MAX_HEX) + 1n), { message: /uint256 range/ });
67
+ t.throws(() => (0, integer_literals_1.toBytes32Hex)(-1n), { message: /uint256 range/ });
68
+ });
57
69
  //# sourceMappingURL=integer-literals.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"integer-literals.test.js","sourceRoot":"","sources":["../../src/utils/integer-literals.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integer-literals.test.js","sourceRoot":"","sources":["../../src/utils/integer-literals.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openzeppelin/upgrades-core",
3
- "version": "1.45.0",
3
+ "version": "1.46.0",
4
4
  "description": "",
5
5
  "repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades",
6
6
  "license": "MIT",
@@ -57,7 +57,7 @@
57
57
  "ava": "^6.0.0",
58
58
  "dotenv": "^16.0.0",
59
59
  "fgbg": "^0.1.4",
60
- "hardhat": "^2.19.1",
60
+ "hardhat": "^2.28.0",
61
61
  "rimraf": "^5.0.0",
62
62
  "typescript": "^5.0.0"
63
63
  },
@@ -72,6 +72,6 @@
72
72
  "minimist": "^1.2.7",
73
73
  "proper-lockfile": "^4.1.1",
74
74
  "solidity-ast": "^0.4.60",
75
- "minimatch": "^9.0.5"
75
+ "minimatch": "^10.2.5"
76
76
  }
77
77
  }
@@ -16,6 +16,7 @@ import { pick } from '../utils/pick';
16
16
  import { execall } from '../utils/execall';
17
17
  import { loadNamespaces } from './namespace';
18
18
  import { UpgradesError } from '../error';
19
+ import { resolveBaseSlot } from '../utils/erc7201-builtin';
19
20
 
20
21
  const currentLayoutVersion = '1.2';
21
22
 
@@ -106,19 +107,34 @@ export function extractStorageLayout(
106
107
 
107
108
  function loadBaseSlot(contractDef: ContractDefinition, decodeSrc: SrcDecoder, layout: StorageLayout) {
108
109
  if (contractDef.storageLayout !== undefined) {
109
- if (contractDef.storageLayout.baseSlotExpression.nodeType !== 'Literal') {
110
- const src = decodeSrc(contractDef.storageLayout.baseSlotExpression);
111
-
112
- // TODO when Slang supports Solidity 0.8.29, use it to parse the expression (of any node type) into a string, then just save it to `layout.baseSlot`.
113
- // Then when comparing layouts in `storage/index.ts`, it will only be used when detailed storage layout is not available, and the comparison
114
- // can be changed to a string comparison when `layout.baseSlot` not an integer literal.
115
- throw new UpgradesError(
116
- `${src}: Custom storage layout expression with node type ${contractDef.storageLayout.baseSlotExpression.nodeType} is not currently supported`,
117
- () =>
118
- 'Please report this at https://zpl.in/upgrades/report and include the `layout at` expression from your contract.',
119
- );
110
+ const baseSlotExpression = contractDef.storageLayout.baseSlotExpression;
111
+ if (baseSlotExpression.nodeType === 'Literal') {
112
+ layout.baseSlot = baseSlotExpression.value ?? undefined;
113
+ return;
120
114
  }
121
- layout.baseSlot = contractDef.storageLayout.baseSlotExpression.value ?? undefined;
115
+
116
+ // Solidity 0.8.35+ allows the `erc7201(string)` comptime builtin as a base slot, e.g.
117
+ // `layout at erc7201("example.main")`. Resolve it to its computed storage location.
118
+ const resolvedSlot = resolveBaseSlot(baseSlotExpression);
119
+ if (resolvedSlot !== undefined) {
120
+ layout.baseSlot = resolvedSlot;
121
+ return;
122
+ }
123
+
124
+ const src = decodeSrc(baseSlotExpression);
125
+
126
+ // TODO if a base slot expression other than a numeric literal or an `erc7201(...)` builtin call
127
+ // needs to be supported, evaluate the right approach per expression — either resolve it to a
128
+ // computed value (like the erc7201 builtin) or compare its source text across upgrades. A
129
+ // source-text approach could use Slang to extract the expression's source span (Slang supports
130
+ // `StorageLayoutSpecifier` from 0.8.29) and store it as a string on `layout.baseSlot`, with the
131
+ // upgrade-time comparison in `storage/index.ts:validateBaseSlotUnchanged` falling back to a
132
+ // string compare when `layout.baseSlot` is not a numeric literal.
133
+ throw new UpgradesError(
134
+ `${src}: Custom storage layout expression with node type ${baseSlotExpression.nodeType} is not currently supported`,
135
+ () =>
136
+ 'Please report this at https://zpl.in/upgrades/report and include the `layout at` expression from your contract.',
137
+ );
122
138
  }
123
139
  }
124
140
 
@@ -8,8 +8,8 @@ import { Node } from 'solidity-ast/node';
8
8
  import { CompilationContext, getTypeMembers, loadLayoutType } from './extract';
9
9
  import { UpgradesError } from '../error';
10
10
  import * as versions from 'compare-versions';
11
- import { normalizeUint256Literal } from '../utils/integer-literals';
12
11
  import { calculateERC7201StorageLocation, ERC7201_FORMULA_PREFIX } from '../utils/erc7201';
12
+ import { getErc7201BuiltinNamespaceId, resolveBaseSlot } from '../utils/erc7201-builtin';
13
13
  import { logWarning } from '../utils/log';
14
14
 
15
15
  /**
@@ -175,15 +175,18 @@ function checkCustomLayoutClashWithNamespace(
175
175
  contractName: string,
176
176
  src: string,
177
177
  ) {
178
- if (contractDef.storageLayout !== undefined && storageLocation.startsWith(ERC7201_FORMULA_PREFIX)) {
179
- const namespaceId = storageLocation.substring(ERC7201_FORMULA_PREFIX.length);
180
- const calculatedStorageLocation = calculateERC7201StorageLocation(namespaceId);
181
- if (contractDef.storageLayout.baseSlotExpression.nodeType === 'Literal') {
182
- const baseSlotNormalized = normalizeUint256Literal(contractDef.storageLayout.baseSlotExpression.value); // TODO: when Solidity supports an erc7201 helper function, also check that for clash
183
- if (baseSlotNormalized === calculatedStorageLocation) {
184
- throw new CustomLayoutClashWithNamespaceError(storageLocation, contractName, src);
185
- }
186
- }
178
+ if (contractDef.storageLayout === undefined || !storageLocation.startsWith(ERC7201_FORMULA_PREFIX)) {
179
+ return;
180
+ }
181
+
182
+ const namespaceId = storageLocation.substring(ERC7201_FORMULA_PREFIX.length);
183
+
184
+ // Resolve the base slot (a numeric literal or an erc7201(...) builtin call) and compare it against
185
+ // the namespace's computed storage location. This covers `layout at erc7201("<id>")` using the same
186
+ // id as the namespace, since both resolve to the same hash.
187
+ const baseSlotNormalized = resolveBaseSlot(contractDef.storageLayout.baseSlotExpression);
188
+ if (baseSlotNormalized !== undefined && baseSlotNormalized === calculateERC7201StorageLocation(namespaceId)) {
189
+ throw new CustomLayoutClashWithNamespaceError(storageLocation, contractName, src);
187
190
  }
188
191
  }
189
192
 
@@ -192,8 +195,15 @@ function warnIfCustomLayoutAndNamespacesFound(
192
195
  decodeSrc: SrcDecoder,
193
196
  origContractDef: ContractDefinition,
194
197
  ) {
195
- // TODO: when Solidity supports an erc7201 helper function, only give this warning if the custom storage layout is not using the erc7201 helper function
196
198
  if (Object.entries(namespacesWithSrc).length > 0 && origContractDef.storageLayout !== undefined) {
199
+ // The warning is meant for users who pick an arbitrary literal slot that could land inside a
200
+ // namespace's range. When the base slot uses the erc7201 comptime builtin, it relies on the
201
+ // same collision resistance that namespaces rely on against each other, so suppress the warning;
202
+ // the tool likewise does not warn when multiple namespaces coexist.
203
+ if (getErc7201BuiltinNamespaceId(origContractDef.storageLayout.baseSlotExpression) !== undefined) {
204
+ return;
205
+ }
206
+
197
207
  const contractName = origContractDef.canonicalName ?? origContractDef.name;
198
208
  logWarning(
199
209
  `${decodeSrc(origContractDef.storageLayout)}: Ensure custom storage layout does not overlap with namespaced storage layout.`,
@@ -0,0 +1,127 @@
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
+
11
+ interface Context {
12
+ extractStorageLayout: (contract: string) => ReturnType<typeof extractStorageLayout>;
13
+ extractStorageLayoutFallback: (contract: string) => ReturnType<typeof extractStorageLayout>;
14
+ }
15
+
16
+ const test = _test as TestFn<Context>;
17
+
18
+ const SOURCE = 'contracts/test/Erc7201Builtin.sol';
19
+
20
+ test.before(async t => {
21
+ const buildInfo = await artifacts.getBuildInfo(`${SOURCE}:Erc7201Builtin`);
22
+ if (buildInfo === undefined) {
23
+ throw new Error('Build info not found');
24
+ }
25
+ const solcOutput: SolcOutput = buildInfo.output;
26
+ const contracts: Record<string, ContractDefinition> = {};
27
+ const storageLayouts: Record<string, StorageLayout> = {};
28
+ for (const def of findAll('ContractDefinition', solcOutput.sources[SOURCE].ast)) {
29
+ contracts[def.name] = def;
30
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
31
+ storageLayouts[def.name] = solcOutput.contracts[SOURCE][def.name].storageLayout!;
32
+ }
33
+ const deref = astDereferencer(solcOutput);
34
+
35
+ t.context.extractStorageLayout = name =>
36
+ extractStorageLayout(contracts[name], dummyDecodeSrc, deref, storageLayouts[name]);
37
+
38
+ t.context.extractStorageLayoutFallback = name =>
39
+ extractStorageLayout(contracts[name], dummyDecodeSrc, deref, undefined);
40
+ });
41
+
42
+ const dummyDecodeSrc = () => 'file.sol:1';
43
+
44
+ test('erc7201 builtin base slot - extract', t => {
45
+ const layout = t.context.extractStorageLayout('Erc7201Builtin');
46
+ t.is(layout.baseSlot, '0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500');
47
+ t.is(layout.storage.length, 1);
48
+ t.is(layout.storage[0].label, 'a');
49
+ });
50
+
51
+ test('erc7201 builtin base slot - append - ok', t => {
52
+ const v1 = t.context.extractStorageLayout('Erc7201Builtin');
53
+ const v2 = t.context.extractStorageLayout('Erc7201Builtin_Append_Ok');
54
+ t.deepEqual(getStorageUpgradeErrors(v1, v2), []);
55
+ });
56
+
57
+ test('erc7201 builtin base slot - append - fallback - ok', t => {
58
+ const v1 = t.context.extractStorageLayoutFallback('Erc7201Builtin');
59
+ const v2 = t.context.extractStorageLayoutFallback('Erc7201Builtin_Append_Ok');
60
+ t.deepEqual(getStorageUpgradeErrors(v1, v2), []);
61
+ });
62
+
63
+ test('erc7201 builtin base slot - changed id - bad', t => {
64
+ const v1 = t.context.extractStorageLayout('Erc7201Builtin');
65
+ const v2 = t.context.extractStorageLayout('Erc7201Builtin_Changed_Id_Bad');
66
+ const comparison = getStorageUpgradeErrors(v1, v2);
67
+ t.true(comparison.length > 0);
68
+ t.is(comparison[0].kind, 'layoutchange');
69
+ });
70
+
71
+ test('erc7201 builtin base slot - changed id - fallback - bad', t => {
72
+ const v1 = t.context.extractStorageLayoutFallback('Erc7201Builtin');
73
+ const v2 = t.context.extractStorageLayoutFallback('Erc7201Builtin_Changed_Id_Bad');
74
+ // Base slot differs between the two erc7201 ids, so the fallback base-slot check must fail.
75
+ t.throws(() => getStorageUpgradeErrors(v1, v2), {
76
+ message: /Base slot for custom storage layout changed/,
77
+ });
78
+ });
79
+
80
+ test('erc7201 builtin and literal-equivalent base slots compare equal', t => {
81
+ const builtin = t.context.extractStorageLayout('Erc7201Builtin');
82
+ const literal = t.context.extractStorageLayout('Erc7201Builtin_Literal_Equivalent');
83
+ // Both resolve to the same base slot; the fallback (base-slot) check must treat them as unchanged.
84
+ const builtinFallback = t.context.extractStorageLayoutFallback('Erc7201Builtin');
85
+ const literalFallback = t.context.extractStorageLayoutFallback('Erc7201Builtin_Literal_Equivalent');
86
+ t.deepEqual(getStorageUpgradeErrors(builtin, literal), []);
87
+ t.deepEqual(getStorageUpgradeErrors(builtinFallback, literalFallback), []);
88
+ });
89
+
90
+ test('erc7201 builtin base slot clashes with namespace - error', t => {
91
+ t.throws(() => t.context.extractStorageLayout('Erc7201Builtin_Clash'), {
92
+ message:
93
+ /Custom layout for contract Erc7201Builtin_Clash clashes with the storage location for namespace erc7201:example\.main/,
94
+ });
95
+ });
96
+
97
+ test('erc7201 builtin base slot different from namespace - no error and no warning', t => {
98
+ const warnings = captureWarnings(() => {
99
+ const layout = t.context.extractStorageLayout('Erc7201Builtin_NoClash_NoWarning');
100
+ t.truthy(layout.baseSlot);
101
+ });
102
+ t.deepEqual(warnings, []);
103
+ });
104
+
105
+ test('erc7201 builtin accepts a unicode string literal argument', t => {
106
+ const layout = t.context.extractStorageLayout('Erc7201Builtin_Unicode');
107
+ t.is(layout.baseSlot, '0x2d3e72b7d91644a80150e2643e65016def7067dc9568719707e7eca1a5dab800');
108
+ });
109
+
110
+ test('literal base slot with namespace - warning not suppressed', t => {
111
+ const warnings = captureWarnings(() => t.context.extractStorageLayout('Erc7201Builtin_LiteralBase_Warns'));
112
+ t.true(warnings.some(w => w.includes('custom storage layout')));
113
+ });
114
+
115
+ function captureWarnings(fn: () => void): string[] {
116
+ const warnings: string[] = [];
117
+ const original = console.error;
118
+ console.error = (...args: unknown[]) => {
119
+ warnings.push(args.map(String).join(' '));
120
+ };
121
+ try {
122
+ fn();
123
+ } finally {
124
+ console.error = original;
125
+ }
126
+ return warnings;
127
+ }
@@ -0,0 +1,91 @@
1
+ import { Expression, Literal } from 'solidity-ast';
2
+ import { calculateERC7201StorageLocation } from './erc7201';
3
+ import { normalizeUint256Literal } from './integer-literals';
4
+ import { UpgradesError } from '../error';
5
+
6
+ /**
7
+ * Recognizes the Solidity 0.8.35+ `erc7201(string)` comptime builtin, which evaluates the ERC-7201
8
+ * storage location for a namespace id and can be used in a compile-time context such as a `layout at`
9
+ * specifier (e.g. `contract C layout at erc7201("example.main")`).
10
+ *
11
+ * The builtin compiles to an ordinary `FunctionCall` node, so it is matched by its shape rather than
12
+ * by a dedicated AST node type.
13
+ *
14
+ * @param node The expression to check.
15
+ * @returns The namespace id passed to the builtin (without the `erc7201:` prefix), or undefined if the
16
+ * expression is not a call to the `erc7201` builtin with a single string literal argument.
17
+ */
18
+ export function getErc7201BuiltinNamespaceId(node: Expression): string | undefined {
19
+ // Check that this is a function call to an identifier named `erc7201`. Return undefined for
20
+ // anything else so the caller can fall through to other base-slot forms.
21
+ if (node.nodeType !== 'FunctionCall' || node.kind !== 'functionCall') {
22
+ return undefined;
23
+ }
24
+ const callee = node.expression;
25
+ if (callee.nodeType !== 'Identifier' || callee.name !== 'erc7201') {
26
+ return undefined;
27
+ }
28
+
29
+ // Beyond this point, the call is to `erc7201(...)`. Check its expected shape — one string-literal
30
+ // argument with no user-defined declaration shadowing the builtin — and throw if anything is off.
31
+ // Valid Solidity 0.8.35+ cannot produce these mismatches in a call to the builtin:
32
+ // - User-defined `erc7201` (`referencedDeclaration >= 0`): solc resolves the call to the builtin
33
+ // when both are in scope, so this shape doesn't reach a successful compile.
34
+ // - Wrong number of arguments: enforced by the builtin's signature.
35
+ // - Non-`Literal` argument or non-string literal `kind`: the builtin's signature requires a
36
+ // comptime-constant string literal. `hex"..."` is type `bytes` and wouldn't typecheck.
37
+ // We throw instead of returning undefined so a future solc emitting one of these surfaces loudly.
38
+ if (typeof callee.referencedDeclaration === 'number' && callee.referencedDeclaration >= 0) {
39
+ throw unexpectedErc7201BuiltinAst('callee resolves to a user-defined declaration');
40
+ }
41
+ if (node.arguments.length !== 1) {
42
+ throw unexpectedErc7201BuiltinAst(`expected 1 argument, got ${node.arguments.length}`);
43
+ }
44
+ const arg = node.arguments[0];
45
+ if (arg.nodeType !== 'Literal') {
46
+ throw unexpectedErc7201BuiltinAst(`argument is ${arg.nodeType}, expected Literal`);
47
+ }
48
+ if (arg.kind !== 'string' && arg.kind !== 'unicodeString') {
49
+ throw unexpectedErc7201BuiltinAst(`argument literal kind is ${arg.kind}, expected string or unicodeString`);
50
+ }
51
+
52
+ return getStringLiteralValue(arg);
53
+ }
54
+
55
+ function unexpectedErc7201BuiltinAst(detail: string): UpgradesError {
56
+ return new UpgradesError(
57
+ `Unexpected AST for \`erc7201(...)\` builtin call: ${detail}`,
58
+ () =>
59
+ 'Please report this at https://zpl.in/upgrades/report and include the `erc7201(...)` expression from your contract.',
60
+ );
61
+ }
62
+
63
+ /**
64
+ * Resolves an expression to its base slot as a normalized uint256 hex string, for either a numeric
65
+ * literal or an `erc7201(...)` builtin call.
66
+ *
67
+ * @param node The expression to resolve.
68
+ * @returns The normalized base slot hex string, or undefined if the expression is neither a numeric
69
+ * literal nor a resolvable `erc7201(...)` builtin call.
70
+ */
71
+ export function resolveBaseSlot(node: Expression): string | undefined {
72
+ if (node.nodeType === 'Literal') {
73
+ return normalizeUint256Literal(node.value);
74
+ }
75
+
76
+ const id = getErc7201BuiltinNamespaceId(node);
77
+ if (id !== undefined) {
78
+ return calculateERC7201StorageLocation(id);
79
+ }
80
+
81
+ return undefined;
82
+ }
83
+
84
+ function getStringLiteralValue(literal: Literal): string {
85
+ // solc populates `value` for `kind: 'string'`/`'unicodeString'` literals; throw defensively if
86
+ // a future solc ever produces a null/missing `value` for such a literal.
87
+ if (literal.value === undefined || literal.value === null) {
88
+ throw unexpectedErc7201BuiltinAst('string literal `value` is null or missing');
89
+ }
90
+ return literal.value;
91
+ }
@@ -8,3 +8,15 @@ test('calculateERC7201StorageLocation', t => {
8
8
  '0x183a6125c38840424c4a85fa12bab2ab606c4b6d0e7cc73c0c06ba5300eab500',
9
9
  );
10
10
  });
11
+
12
+ // `keccak256("ns2") - 1` is 63 hex chars (odd-length), which must be zero-padded to 32 bytes
13
+ // before hashing. Regression test for truncation of the intermediate buffer.
14
+ test('calculateERC7201StorageLocation - odd-length intermediate hash', t => {
15
+ t.is(calculateERC7201StorageLocation('ns2'), '0xa61069020885c09e922542fb3fa98c8d50e6481fc1251ff86c3319a70f0f7d00');
16
+ });
17
+
18
+ // `keccak256("ns297") - 1` is 62 hex chars (i.e., its top byte is `0x00`). Without zero-padding,
19
+ // `Buffer.from('hex')` would interpret it as a 31-byte buffer rather than 32, producing the wrong hash.
20
+ test('calculateERC7201StorageLocation - leading-zero-byte intermediate hash', t => {
21
+ t.is(calculateERC7201StorageLocation('ns297'), '0xe06f9faa11c8032ea604e1764972c1a5594987f1678d8fabf921c28d1a7a4c00');
22
+ });
@@ -1,5 +1,7 @@
1
1
  import { keccak256 } from 'ethereumjs-util';
2
2
 
3
+ import { toBytes32Hex } from './integer-literals';
4
+
3
5
  export const ERC7201_FORMULA_PREFIX = 'erc7201:';
4
6
 
5
7
  /**
@@ -12,14 +14,14 @@ export const ERC7201_FORMULA_PREFIX = 'erc7201:';
12
14
  export function calculateERC7201StorageLocation(id: string): string {
13
15
  const firstHash = keccak256(Buffer.from(id));
14
16
  const minusOne = BigInt(`0x${firstHash.toString('hex')}`) - 1n;
15
- const minusOneBuffer = Buffer.from(minusOne.toString(16), 'hex');
17
+ // Pad to 64 hex chars so that `Buffer.from` doesn't silently truncate odd-length input;
18
+ // `abi.encode(uint256)` is always 32 bytes.
19
+ const minusOneBuffer = Buffer.from(minusOne.toString(16).padStart(64, '0'), 'hex');
16
20
 
17
21
  const secondHash = keccak256(minusOneBuffer);
18
22
 
19
23
  const mask = BigInt('0xff');
20
24
  const masked = BigInt(`0x${secondHash.toString('hex')}`) & ~mask;
21
25
 
22
- const padded = masked.toString(16).padStart(64, '0');
23
-
24
- return `0x${padded}`;
26
+ return toBytes32Hex(masked);
25
27
  }
@@ -1,6 +1,6 @@
1
1
  import test from 'ava';
2
2
 
3
- import { normalizeUint256Literal } from './integer-literals';
3
+ import { normalizeUint256Literal, toBytes32Hex } from './integer-literals';
4
4
 
5
5
  const ZEROES = '0x0000000000000000000000000000000000000000000000000000000000000000';
6
6
 
@@ -71,3 +71,17 @@ test('full hex with leading and trailing zeroes', t => {
71
71
  '0x00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00',
72
72
  );
73
73
  });
74
+
75
+ test('rejects values above uint256 max', t => {
76
+ const tooLarge = '0x10000000000000000000000000000000000000000000000000000000000000000';
77
+ const error = t.throws(() => normalizeUint256Literal(tooLarge));
78
+ t.regex(error?.message ?? '', /uint256 range/);
79
+ });
80
+
81
+ test('toBytes32Hex - boundaries', t => {
82
+ const MAX_HEX = '0x' + 'f'.repeat(64);
83
+ t.is(toBytes32Hex(0n), '0x' + '0'.repeat(64));
84
+ t.is(toBytes32Hex(BigInt(MAX_HEX)), MAX_HEX);
85
+ t.throws(() => toBytes32Hex(BigInt(MAX_HEX) + 1n), { message: /uint256 range/ });
86
+ t.throws(() => toBytes32Hex(-1n), { message: /uint256 range/ });
87
+ });
@@ -1,21 +1,42 @@
1
1
  import BigNumber from 'bignumber.js';
2
2
 
3
+ const MAX_UINT256 = (1n << 256n) - 1n;
4
+
5
+ /**
6
+ * Encodes a bigint as a 0x-prefixed, 64-char lowercase hex string — the canonical text encoding of
7
+ * a `bytes32` value, used throughout this package for storage slots and similar 256-bit identifiers.
8
+ * Throws if the value is outside the 0..2^256-1 range, since that almost certainly indicates a bug
9
+ * upstream (overflow, wrong hash, etc.) and would silently produce a string longer than 64 chars.
10
+ *
11
+ * @param value bigint value to encode
12
+ * @returns 0x-prefixed, 64-char lowercase hex string
13
+ */
14
+ export function toBytes32Hex(value: bigint): string {
15
+ if (value < 0n || value > MAX_UINT256) {
16
+ throw new Error(`Value out of uint256 range: ${value}`);
17
+ }
18
+ return `0x${value.toString(16).padStart(64, '0')}`;
19
+ }
20
+
3
21
  /**
4
- * Converts a Solidity unsigned integer literal according to https://docs.soliditylang.org/en/latest/types.html#rational-literals
5
- * to a 64-byte padded hex string.
22
+ * Parses a Solidity unsigned integer literal source string (per
23
+ * https://docs.soliditylang.org/en/latest/types.html#rational-literals) and returns it in the
24
+ * canonical hex form produced by {@link toBytes32Hex}.
6
25
  *
7
- * Accepts decimal, hexadecimal, and scientific notation formats.
26
+ * Parsing is delegated to {@link BigNumber}, which accepts decimal (`1000`), hex (`0x1f`), and
27
+ * scientific notation (`1e18`). Underscore separators and uppercase digits, which BigNumber rejects
28
+ * but Solidity allows, are stripped/lowercased first. Non-integer results (e.g. `1.5e3`) are rejected.
8
29
  *
9
- * If the input is null or undefined, returns '0x0000000000000000000000000000000000000000000000000000000000000000'.
30
+ * If the input is null or undefined, returns the canonical hex form of zero.
10
31
  *
11
32
  * Assumes the input is a valid uint256-compatible literal for Solidity, and only performs minimal validation.
12
33
  *
13
- * @param literal Integer literal to convert
14
- * @returns Hex string with 0x prefix, padded to 64 bytes with leading zeroes
34
+ * @param literal Integer literal source string to parse
35
+ * @returns 0x-prefixed, 64-char lowercase hex string
15
36
  */
16
37
  export function normalizeUint256Literal(literal: string | null | undefined): string {
17
38
  if (!literal) {
18
- return '0x0000000000000000000000000000000000000000000000000000000000000000';
39
+ return toBytes32Hex(0n);
19
40
  }
20
41
  const lowercaseNoUnderscores = literal.replace(/_/g, '').toLowerCase();
21
42
 
@@ -23,7 +44,5 @@ export function normalizeUint256Literal(literal: string | null | undefined): str
23
44
  if (!parsed.isInteger()) {
24
45
  throw new Error(`Invalid integer literal: ${literal}`);
25
46
  }
26
- const calculatedValueAsHex = parsed.toString(16);
27
- const padded = calculatedValueAsHex.padStart(64, '0');
28
- return `0x${padded}`;
47
+ return toBytes32Hex(BigInt(parsed.toFixed()));
29
48
  }