slotdiff 0.2.0-alpha.1 → 0.3.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.
- package/CHANGELOG.md +41 -0
- package/README.md +55 -38
- package/dist/build-info.d.ts.map +1 -1
- package/dist/build-info.js +9 -3
- package/dist/build-info.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +59 -33
- package/dist/cli.js.map +1 -1
- package/dist/erc7201.d.ts +27 -11
- package/dist/erc7201.d.ts.map +1 -1
- package/dist/erc7201.js +182 -13
- package/dist/erc7201.js.map +1 -1
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +20 -0
- package/dist/errors.js.map +1 -1
- package/dist/explorer.d.ts.map +1 -1
- package/dist/explorer.js +28 -9
- package/dist/explorer.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/reconstruct.d.ts +30 -15
- package/dist/reconstruct.d.ts.map +1 -1
- package/dist/reconstruct.js +140 -32
- package/dist/reconstruct.js.map +1 -1
- package/dist/record.d.ts +13 -0
- package/dist/record.d.ts.map +1 -1
- package/dist/record.js +8 -0
- package/dist/record.js.map +1 -1
- package/dist/report.d.ts +4 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +37 -8
- package/dist/report.js.map +1 -1
- package/dist/resolve.d.ts +6 -1
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +6 -1
- package/dist/resolve.js.map +1 -1
- package/dist/solc.js +20 -4
- package/dist/solc.js.map +1 -1
- package/dist/upgrade.d.ts +48 -0
- package/dist/upgrade.d.ts.map +1 -0
- package/dist/upgrade.js +36 -0
- package/dist/upgrade.js.map +1 -0
- package/package.json +5 -5
- package/src/build-info.ts +9 -3
- package/src/cli.ts +69 -33
- package/src/erc7201.ts +217 -26
- package/src/errors.ts +22 -0
- package/src/explorer.ts +39 -10
- package/src/index.ts +11 -3
- package/src/reconstruct.ts +206 -57
- package/src/record.ts +18 -0
- package/src/report.ts +44 -13
- package/src/resolve.ts +12 -2
- package/src/solc.ts +20 -4
- package/src/upgrade.ts +91 -0
package/dist/index.js
CHANGED
|
@@ -6,7 +6,8 @@ export { fetchVerifiedSource, ETHERSCAN_V2_API_URL, } from "./explorer.js";
|
|
|
6
6
|
export { getSolc } from "./solc.js";
|
|
7
7
|
export { findBuildInfo } from "./build-info.js";
|
|
8
8
|
export { checkNamespaces, } from "./erc7201.js";
|
|
9
|
-
export {
|
|
9
|
+
export { checkUpgrade, } from "./upgrade.js";
|
|
10
|
+
export { analyzeSource, analyzeBuild, SAFETY_ERROR_KINDS, } from "./reconstruct.js";
|
|
10
11
|
export { compareDeployedBytecode, isProvingMatch, } from "./bytecode.js";
|
|
11
|
-
export { LayoutIntegrityError, LayoutUnavailableError } from "./errors.js";
|
|
12
|
+
export { IncompleteBuildError, LayoutIntegrityError, LayoutUnavailableError } from "./errors.js";
|
|
12
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAuC,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,eAAe,GAKhB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,QAAQ,EACR,WAAW,GAGZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GAGrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAqC,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,aAAa,EAAiD,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EACL,eAAe,GAIhB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAuC,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,eAAe,GAKhB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,QAAQ,EACR,WAAW,GAGZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,GAGrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAqC,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,aAAa,EAAiD,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EACL,eAAe,GAIhB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,YAAY,GAIb,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,aAAa,EACb,YAAY,EAGZ,kBAAkB,GAOnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,cAAc,GAIf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/reconstruct.d.ts
CHANGED
|
@@ -6,8 +6,7 @@
|
|
|
6
6
|
* the local build (full compile, namespaced second pass, `validate()`,
|
|
7
7
|
* `getStorageLayout`), so both sides of a comparison are extracted identically.
|
|
8
8
|
*/
|
|
9
|
-
import { type ProxyDeployment, type SolcInput, type StorageLayout } from "@openzeppelin/upgrades-core";
|
|
10
|
-
import { type ValidationError } from "@openzeppelin/upgrades-core/dist/validate/run.js";
|
|
9
|
+
import { type ProxyDeployment, type SolcInput, type SolcOutput, type StorageLayout } from "@openzeppelin/upgrades-core";
|
|
11
10
|
import { type ProvingMatch } from "./bytecode.js";
|
|
12
11
|
import { type NamespaceSlot } from "./erc7201.js";
|
|
13
12
|
import type { VerifiedSource } from "./explorer.js";
|
|
@@ -19,19 +18,15 @@ export interface ReconstructedLayout extends SourceAnalysis {
|
|
|
19
18
|
bytecodeMatch: ProvingMatch;
|
|
20
19
|
}
|
|
21
20
|
export declare function reconstructLayout(source: VerifiedSource, solc: SolcRunner, onchainCode: string): Promise<ReconstructedLayout>;
|
|
22
|
-
/**
|
|
23
|
-
* The layout of `contract` (`source.sol:Name`) in `input`, with no bytecode
|
|
24
|
-
* proof. Only for sources whose provenance is already known, such as a
|
|
25
|
-
* project's own build-info.
|
|
26
|
-
*/
|
|
27
|
-
export declare function layoutFromSource(input: SolcInput, solc: SolcRunner, contract: string): Promise<StorageLayout>;
|
|
28
21
|
export type ProxyKind = ProxyDeployment["kind"];
|
|
29
22
|
/**
|
|
30
23
|
* OpenZeppelin's safety error kinds, without the deprecated struct-definition
|
|
31
|
-
* and enum-definition, which the check never reports.
|
|
24
|
+
* and enum-definition, which the check never reports. Listed here, not taken
|
|
25
|
+
* from OpenZeppelin, so its releases cannot change this API unseen; a test
|
|
26
|
+
* compares the two.
|
|
32
27
|
*/
|
|
33
|
-
export
|
|
34
|
-
export
|
|
28
|
+
export declare const SAFETY_ERROR_KINDS: readonly ["state-variable-assignment", "state-variable-immutable", "external-library-linking", "constructor", "delegatecall", "selfdestruct", "missing-public-upgradeto", "internal-function-storage", "missing-initializer", "missing-initializer-call", "duplicate-initializer-call", "incorrect-initializer-order"];
|
|
29
|
+
export type SafetyErrorKind = (typeof SAFETY_ERROR_KINDS)[number];
|
|
35
30
|
export interface SafetyError {
|
|
36
31
|
/** OpenZeppelin's error kind, such as `constructor`. */
|
|
37
32
|
kind: SafetyErrorKind;
|
|
@@ -51,8 +46,8 @@ export interface SafetyOptions {
|
|
|
51
46
|
export interface SafetyReport {
|
|
52
47
|
ok: boolean;
|
|
53
48
|
errors: SafetyError[];
|
|
54
|
-
/** OpenZeppelin's description of each error. */
|
|
55
|
-
explain(): string;
|
|
49
|
+
/** OpenZeppelin's description of each error; `color` (default true) adds terminal colors. */
|
|
50
|
+
explain(color?: boolean): string;
|
|
56
51
|
}
|
|
57
52
|
export interface SourceAnalysis {
|
|
58
53
|
layout: StorageLayout;
|
|
@@ -70,6 +65,26 @@ export interface SourceAnalysis {
|
|
|
70
65
|
*/
|
|
71
66
|
safety(options: SafetyOptions): SafetyReport;
|
|
72
67
|
}
|
|
73
|
-
/**
|
|
74
|
-
|
|
68
|
+
/**
|
|
69
|
+
* The layout of `contract` (`source.sol:Name`) in `input`, its ERC-7201 slots
|
|
70
|
+
* and OpenZeppelin's safety check, from one compile. No bytecode proof: only
|
|
71
|
+
* for sources whose provenance is already known, such as a project's own build info.
|
|
72
|
+
*/
|
|
73
|
+
export declare function analyzeSource(input: SolcInput, solc: BuildCompiler, contract: string): Promise<SourceAnalysis>;
|
|
74
|
+
/** The compiler for OpenZeppelin's namespaced pass: a `SolcRunner`, or a build tool's. */
|
|
75
|
+
export type BuildCompiler = Pick<SolcRunner, "longVersion" | "compile">;
|
|
76
|
+
export interface BuildAnalysis {
|
|
77
|
+
/** The analysis of one contract in the build, `source.sol:Name`. */
|
|
78
|
+
contract(contract: string): SourceAnalysis;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* `analyzeSource` for a build you already compiled, such as a build tool's,
|
|
82
|
+
* without compiling it again: one namespaced pass and one validation serve
|
|
83
|
+
* every contract in it. `output` must hold every source's `ast` and, for each
|
|
84
|
+
* contract, its `metadata`, `storageLayout` (an interface or library may lack
|
|
85
|
+
* it) and `evm.bytecode` (`object`, `linkReferences`); without them it throws
|
|
86
|
+
* `IncompleteBuildError`. The metadata proves `output` was compiled from
|
|
87
|
+
* `input`'s sources by `compiler`'s version (not with its settings).
|
|
88
|
+
*/
|
|
89
|
+
export declare function analyzeBuild(input: SolcInput, output: SolcOutput, compiler: BuildCompiler): Promise<BuildAnalysis>;
|
|
75
90
|
//# sourceMappingURL=reconstruct.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconstruct.d.ts","sourceRoot":"","sources":["../src/reconstruct.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"reconstruct.d.ts","sourceRoot":"","sources":["../src/reconstruct.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAWL,KAAK,eAAe,EACpB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,aAAa,EAEnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAA2C,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IACzD,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,YAAY,CAAC;CAC7B;AAqBD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAiB9B;AAED,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAIhD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,wTAarB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAElE,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,IAAI,EAAE,eAAe,CAAC;IACtB,iCAAiC;IACjC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,IAAI,EAAE,SAAS,CAAC;IAChB,kGAAkG;IAClG,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,6FAA6F;IAC7F,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,aAAa,CAAC;IACtB,0FAA0F;IAC1F,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnC;;;OAGG;IACH,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B;;;;OAIG;IACH,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC,CAIzB;AAED,0FAA0F;AAC1F,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;AAExE,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAAC;CAC5C;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,aAAa,GACtB,OAAO,CAAC,aAAa,CAAC,CAIxB"}
|
package/dist/reconstruct.js
CHANGED
|
@@ -6,12 +6,10 @@
|
|
|
6
6
|
* the local build (full compile, namespaced second pass, `validate()`,
|
|
7
7
|
* `getStorageLayout`), so both sides of a comparison are extracted identically.
|
|
8
8
|
*/
|
|
9
|
-
import { getErrors, getStorageLayout, inferProxyKind, isNamespaceSupported, makeNamespacedInput, solcInputOutputDecoder, trySanitizeNatSpec, UpgradeableContractErrorReport, validate, } from "@openzeppelin/upgrades-core";
|
|
10
|
-
// Not exported from the package index; the package has no exports map.
|
|
11
|
-
import { errorKinds } from "@openzeppelin/upgrades-core/dist/validate/run.js";
|
|
9
|
+
import { getErrors, getStorageLayout, hashBytecode, inferProxyKind, isNamespaceSupported, makeNamespacedInput, solcInputOutputDecoder, trySanitizeNatSpec, UpgradeableContractErrorReport, validate, } from "@openzeppelin/upgrades-core";
|
|
12
10
|
import { compareDeployedBytecode, isProvingMatch } from "./bytecode.js";
|
|
13
11
|
import { namespaceSlots } from "./erc7201.js";
|
|
14
|
-
import { LayoutIntegrityError } from "./errors.js";
|
|
12
|
+
import { IncompleteBuildError, LayoutIntegrityError, printable } from "./errors.js";
|
|
15
13
|
// validate() reads evm.bytecode for every contract, so codegen is requested
|
|
16
14
|
// for all of them. A verified input holds only the target's dependency graph.
|
|
17
15
|
const FULL_SELECTION = {
|
|
@@ -22,6 +20,7 @@ const FULL_SELECTION = {
|
|
|
22
20
|
"evm.bytecode.linkReferences",
|
|
23
21
|
"evm.deployedBytecode.object",
|
|
24
22
|
"evm.deployedBytecode.immutableReferences",
|
|
23
|
+
"metadata",
|
|
25
24
|
],
|
|
26
25
|
"": ["ast"],
|
|
27
26
|
},
|
|
@@ -36,32 +35,150 @@ export async function reconstructLayout(source, solc, onchainCode) {
|
|
|
36
35
|
contract,
|
|
37
36
|
compiler: source.solcLongVersion,
|
|
38
37
|
bytecodeMatch,
|
|
39
|
-
...(await
|
|
38
|
+
...(await analyzeBuild(input, output, solc)).contract(contract),
|
|
40
39
|
};
|
|
41
40
|
}
|
|
42
41
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
42
|
+
* OpenZeppelin's safety error kinds, without the deprecated struct-definition
|
|
43
|
+
* and enum-definition, which the check never reports. Listed here, not taken
|
|
44
|
+
* from OpenZeppelin, so its releases cannot change this API unseen; a test
|
|
45
|
+
* compares the two.
|
|
46
|
+
*/
|
|
47
|
+
export const SAFETY_ERROR_KINDS = [
|
|
48
|
+
"state-variable-assignment",
|
|
49
|
+
"state-variable-immutable",
|
|
50
|
+
"external-library-linking",
|
|
51
|
+
"constructor",
|
|
52
|
+
"delegatecall",
|
|
53
|
+
"selfdestruct",
|
|
54
|
+
"missing-public-upgradeto",
|
|
55
|
+
"internal-function-storage",
|
|
56
|
+
"missing-initializer",
|
|
57
|
+
"missing-initializer-call",
|
|
58
|
+
"duplicate-initializer-call",
|
|
59
|
+
"incorrect-initializer-order",
|
|
60
|
+
];
|
|
61
|
+
/**
|
|
62
|
+
* The layout of `contract` (`source.sol:Name`) in `input`, its ERC-7201 slots
|
|
63
|
+
* and OpenZeppelin's safety check, from one compile. No bytecode proof: only
|
|
64
|
+
* for sources whose provenance is already known, such as a project's own build info.
|
|
46
65
|
*/
|
|
47
|
-
export async function layoutFromSource(input, solc, contract) {
|
|
48
|
-
return (await analyzeSource(input, solc, contract)).layout;
|
|
49
|
-
}
|
|
50
|
-
export const SAFETY_ERROR_KINDS = errorKinds.filter((k) => k !== "struct-definition" && k !== "enum-definition");
|
|
51
|
-
/** `layoutFromSource` plus OpenZeppelin's safety check, from one compile. */
|
|
52
66
|
export async function analyzeSource(input, solc, contract) {
|
|
53
67
|
const selected = withOutputSelection(input, FULL_SELECTION);
|
|
54
|
-
|
|
68
|
+
const output = await compileOrThrow(solc, selected, "source");
|
|
69
|
+
return (await analyzeBuild(selected, output, solc)).contract(contract);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* `analyzeSource` for a build you already compiled, such as a build tool's,
|
|
73
|
+
* without compiling it again: one namespaced pass and one validation serve
|
|
74
|
+
* every contract in it. `output` must hold every source's `ast` and, for each
|
|
75
|
+
* contract, its `metadata`, `storageLayout` (an interface or library may lack
|
|
76
|
+
* it) and `evm.bytecode` (`object`, `linkReferences`); without them it throws
|
|
77
|
+
* `IncompleteBuildError`. The metadata proves `output` was compiled from
|
|
78
|
+
* `input`'s sources by `compiler`'s version (not with its settings).
|
|
79
|
+
*/
|
|
80
|
+
export async function analyzeBuild(input, output, compiler) {
|
|
81
|
+
checkBuild(input, output, compiler.longVersion);
|
|
82
|
+
const runData = await validateBuild(input, output, compiler);
|
|
83
|
+
return { contract: (contract) => analyzeContract(runData, output, contract) };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The analysis reads layouts from `output` and edits `input` at the offsets in
|
|
87
|
+
* `output`'s ASTs, so the two must be one build, complete: an output from other
|
|
88
|
+
* sources could pass a changed layout, and one without an AST would leave every
|
|
89
|
+
* namespace unassigned, compared by annotation alone. Anything else is refused.
|
|
90
|
+
*/
|
|
91
|
+
function checkBuild(input, output, longVersion) {
|
|
92
|
+
if (output.sources === undefined && Object.hasOwn(output, "_format")) {
|
|
93
|
+
throw new Error("The compiler output is wrapped in a build info file; pass its output field " +
|
|
94
|
+
"(Hardhat 3 writes { _format, output } to <id>.output.json).");
|
|
95
|
+
}
|
|
96
|
+
const paths = Object.keys(input.sources);
|
|
97
|
+
const outputPaths = Object.keys(output.sources ?? {});
|
|
98
|
+
if (paths.length !== outputPaths.length ||
|
|
99
|
+
paths.some((path) => !Object.hasOwn(output.sources, path))) {
|
|
100
|
+
throw new Error("The compiler output does not hold the same sources as the input.");
|
|
101
|
+
}
|
|
102
|
+
for (const path of paths) {
|
|
103
|
+
if (typeof input.sources[path].content !== "string") {
|
|
104
|
+
throw new Error(`The compiler input has no content for ${path}.`);
|
|
105
|
+
}
|
|
106
|
+
const ast = output.sources[path].ast;
|
|
107
|
+
if (ast === undefined) {
|
|
108
|
+
throw new IncompleteBuildError(`The compiler output has no ast for ${path}; it needs every source's ast.`);
|
|
109
|
+
}
|
|
110
|
+
for (const node of ast.nodes ?? []) {
|
|
111
|
+
if (node.nodeType !== "ContractDefinition")
|
|
112
|
+
continue;
|
|
113
|
+
const name = `${path}:${String(node.name)}`;
|
|
114
|
+
const c = output.contracts?.[path]?.[String(node.name)];
|
|
115
|
+
if (c === undefined)
|
|
116
|
+
throw new IncompleteBuildError(`The compiler output has no contract output for ${name}.`);
|
|
117
|
+
// Neither can hold state, and some tools (Foundry) leave their layout out.
|
|
118
|
+
const stateless = node.contractKind === "interface" || node.contractKind === "library";
|
|
119
|
+
if (typeof c.metadata !== "string" ||
|
|
120
|
+
(c.storageLayout === undefined && !stateless) ||
|
|
121
|
+
typeof c.evm?.bytecode?.object !== "string" ||
|
|
122
|
+
typeof c.evm.bytecode.linkReferences !== "object") {
|
|
123
|
+
throw new IncompleteBuildError(`The compiler output for ${name} lacks metadata, storageLayout or evm.bytecode ` +
|
|
124
|
+
`(object, linkReferences); compile with them in outputSelection.`);
|
|
125
|
+
}
|
|
126
|
+
proveSameBuild(input, path, name, c.metadata, longVersion);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function proveSameBuild(input, path, name, metadata, longVersion) {
|
|
131
|
+
let parsed;
|
|
132
|
+
try {
|
|
133
|
+
parsed = JSON.parse(metadata);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
throw new LayoutIntegrityError(`The metadata for ${name} is not JSON.`);
|
|
137
|
+
}
|
|
138
|
+
const [version, commit] = String(parsed.compiler?.version).split("+");
|
|
139
|
+
const [wanted, wantedCommit] = longVersion.split("+");
|
|
140
|
+
if (version !== wanted ||
|
|
141
|
+
(commit !== undefined && wantedCommit !== undefined && commit !== wantedCommit)) {
|
|
142
|
+
throw new LayoutIntegrityError(`${name} was compiled by solc ${String(parsed.compiler?.version)}, not ${longVersion}.`);
|
|
143
|
+
}
|
|
144
|
+
// Its own source at least: metadata that lists none would prove nothing.
|
|
145
|
+
const sources = { [path]: {}, ...parsed.sources };
|
|
146
|
+
for (const [source, { keccak256 }] of Object.entries(sources)) {
|
|
147
|
+
const content = input.sources[source]?.content;
|
|
148
|
+
const hash = content === undefined ? undefined : "0x" + hashBytecode(Buffer.from(content).toString("hex"));
|
|
149
|
+
if (hash !== keccak256) {
|
|
150
|
+
throw new LayoutIntegrityError(`The compiler output for ${name} was not compiled from this input (${source} differs).`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
55
153
|
}
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
154
|
+
function analyzeContract(runData, output, contract) {
|
|
155
|
+
const colon = contract.lastIndexOf(":");
|
|
156
|
+
if (output.contracts?.[contract.slice(0, colon)]?.[contract.slice(colon + 1)] === undefined) {
|
|
157
|
+
throw new Error(`${contract} is not in the compiler input. Name it as source.sol:Contract, with the ` +
|
|
158
|
+
`source path exactly as the input has it (Hardhat 3 starts it with project/).`);
|
|
159
|
+
}
|
|
160
|
+
const version = runData[contract]?.version;
|
|
161
|
+
if (version === undefined) {
|
|
162
|
+
throw new LayoutIntegrityError(`${contract} compiled to no bytecode (an abstract contract or interface?); ` +
|
|
163
|
+
`cannot derive its layout.`);
|
|
164
|
+
}
|
|
165
|
+
// OZ looks the contract up by bytecode version and takes the first match, so
|
|
166
|
+
// two contracts with identical code (possible without a source hash) could
|
|
167
|
+
// swap layouts or safety errors. Listing the target first makes every lookup land on it.
|
|
168
|
+
const data = { [contract]: runData[contract], ...runData };
|
|
169
|
+
// A copy: OpenZeppelin's layout points into the run data that every call shares.
|
|
170
|
+
const layout = structuredClone(getStorageLayout(data, version));
|
|
59
171
|
return {
|
|
60
172
|
layout,
|
|
61
173
|
// Typed as any ProxyKind, but only ever uups or transparent.
|
|
62
174
|
kind: inferProxyKind(data, version),
|
|
63
175
|
namespaces: namespaceSlots(output, contract, Object.keys(layout.namespaces ?? {})),
|
|
64
176
|
safety({ kind, unsafeAllow = [] }) {
|
|
177
|
+
// OpenZeppelin ignores a kind it does not know, so a typo would accept nothing silently.
|
|
178
|
+
const unknown = unsafeAllow.find((k) => !SAFETY_ERROR_KINDS.includes(k));
|
|
179
|
+
if (unknown !== undefined) {
|
|
180
|
+
throw new Error(`Unknown unsafeAllow error kind "${String(unknown)}". Known: ${SAFETY_ERROR_KINDS.join(", ")}.`);
|
|
181
|
+
}
|
|
65
182
|
// A copy: OpenZeppelin appends to the array it is given.
|
|
66
183
|
const opts = { kind, unsafeAllow: [...unsafeAllow] };
|
|
67
184
|
// The deprecated kinds are never reported, so every error has a SafetyErrorKind.
|
|
@@ -69,29 +186,20 @@ async function analyze(input, output, solc, contract) {
|
|
|
69
186
|
return {
|
|
70
187
|
ok: errors.length === 0,
|
|
71
188
|
errors,
|
|
72
|
-
explain: () => new UpgradeableContractErrorReport(errors).explain(),
|
|
189
|
+
explain: (color) => new UpgradeableContractErrorReport(errors).explain(color),
|
|
73
190
|
};
|
|
74
191
|
},
|
|
75
192
|
};
|
|
76
193
|
}
|
|
77
|
-
async function
|
|
78
|
-
const solcVersion =
|
|
194
|
+
async function validateBuild(input, output, compiler) {
|
|
195
|
+
const solcVersion = compiler.longVersion.split("+")[0];
|
|
79
196
|
let namespacedOutput;
|
|
80
197
|
if (isNamespaceSupported(solcVersion)) {
|
|
81
198
|
let namespacedInput = makeNamespacedInput(input, output, solcVersion);
|
|
82
199
|
namespacedInput = await trySanitizeNatSpec(namespacedInput, solcVersion);
|
|
83
|
-
namespacedOutput = await compileOrThrow(
|
|
200
|
+
namespacedOutput = await compileOrThrow(compiler, withOutputSelection(namespacedInput, LAYOUT_SELECTION), "namespaced pass");
|
|
84
201
|
}
|
|
85
|
-
|
|
86
|
-
const version = runData[contract]?.version;
|
|
87
|
-
if (version === undefined) {
|
|
88
|
-
throw new LayoutIntegrityError(`${contract} compiled to no bytecode (an abstract contract or interface?); ` +
|
|
89
|
-
`cannot derive its layout.`);
|
|
90
|
-
}
|
|
91
|
-
// OZ looks the contract up by bytecode version and takes the first match, so
|
|
92
|
-
// two contracts with identical code (possible without a source hash) could
|
|
93
|
-
// swap layouts or safety errors. Listing the target first makes every lookup land on it.
|
|
94
|
-
return { data: { [contract]: runData[contract], ...runData }, version };
|
|
202
|
+
return validate(output, solcInputOutputDecoder(input, output), solcVersion, input, namespacedOutput);
|
|
95
203
|
}
|
|
96
204
|
/**
|
|
97
205
|
* Finds the compiled contract that matches the deployed code. The verified
|
|
@@ -150,7 +258,7 @@ async function compileOrThrow(solc, input, what) {
|
|
|
150
258
|
const output = await solc.compile(input);
|
|
151
259
|
const errors = (output.errors ?? []).filter((e) => e.severity === "error");
|
|
152
260
|
if (errors.length > 0) {
|
|
153
|
-
throw new LayoutIntegrityError(`solc ${solc.longVersion} failed to compile the ${what}: ${errors[0].formattedMessage}`);
|
|
261
|
+
throw new LayoutIntegrityError(`solc ${solc.longVersion} failed to compile the ${what}: ${printable(String(errors[0].formattedMessage))}`);
|
|
154
262
|
}
|
|
155
263
|
return output;
|
|
156
264
|
}
|
package/dist/reconstruct.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconstruct.js","sourceRoot":"","sources":["../src/reconstruct.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EACL,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,8BAA8B,EAC9B,QAAQ,
|
|
1
|
+
{"version":3,"file":"reconstruct.js","sourceRoot":"","sources":["../src/reconstruct.ts"],"names":[],"mappings":"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"}
|
package/dist/record.d.ts
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
import type { StorageLayout } from "@openzeppelin/upgrades-core";
|
|
11
11
|
import { type ProvingMatch } from "./bytecode.js";
|
|
12
12
|
import { type EthProvider } from "./chain.js";
|
|
13
|
+
import { type NamespaceSlot } from "./erc7201.js";
|
|
14
|
+
import type { SourceAnalysis } from "./reconstruct.js";
|
|
13
15
|
/**
|
|
14
16
|
* Deployed code never changes, so a record cannot go stale for its chain and
|
|
15
17
|
* address. `codeSha256` binds it to the exact runtime code it was proven
|
|
@@ -30,6 +32,17 @@ export interface LayoutRecord {
|
|
|
30
32
|
source: "explorer" | "local-compile";
|
|
31
33
|
recordedAt: string;
|
|
32
34
|
layout: StorageLayout;
|
|
35
|
+
/**
|
|
36
|
+
* The proxy kind this code implies: `uups` when it has `upgradeTo` or
|
|
37
|
+
* `upgradeToAndCall`, else `transparent`. Pass `beacon` to the safety check
|
|
38
|
+
* instead when a beacon serves it. Absent in older records.
|
|
39
|
+
*/
|
|
40
|
+
kind?: SourceAnalysis["kind"];
|
|
41
|
+
/**
|
|
42
|
+
* The slot each ERC-7201 namespace in `layout` really uses. Without it,
|
|
43
|
+
* `checkNamespaces` reports the record's namespaces as unread.
|
|
44
|
+
*/
|
|
45
|
+
namespaces?: NamespaceSlot[];
|
|
33
46
|
}
|
|
34
47
|
/**
|
|
35
48
|
* Checks a loaded record without touching the chain: its format, its shape,
|
package/dist/record.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAqC,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAkB,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,EAAqC,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,CAAC,CAAC;IACV,iBAAiB;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,YAAY,CAAC;IAC5B,+FAA+F;IAC/F,MAAM,EAAE,UAAU,GAAG,eAAe,CAAC;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,IAAI,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;CAC9B;AAKD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,CA+C1E;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,GACb,OAAO,CAAC,YAAY,CAAC,CA0BvB"}
|
package/dist/record.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { isProvingMatch } from "./bytecode.js";
|
|
11
11
|
import { codeSha256, readChainId, readCode } from "./chain.js";
|
|
12
|
+
import { slotsMisfit } from "./erc7201.js";
|
|
12
13
|
import { LayoutIntegrityError, LayoutUnavailableError } from "./errors.js";
|
|
13
14
|
const ADDRESS = /^0x[0-9a-f]{40}$/;
|
|
14
15
|
const SHA256 = /^[0-9a-f]{64}$/;
|
|
@@ -51,6 +52,13 @@ export function parseRecord(value, address) {
|
|
|
51
52
|
r.layout.types === null) {
|
|
52
53
|
throw malformed("layout");
|
|
53
54
|
}
|
|
55
|
+
if (r.kind !== undefined && r.kind !== "uups" && r.kind !== "transparent") {
|
|
56
|
+
throw malformed("kind");
|
|
57
|
+
}
|
|
58
|
+
if (slotsMisfit(r.layout, undefined) !== undefined)
|
|
59
|
+
throw malformed("layout");
|
|
60
|
+
if (slotsMisfit(r.layout, r.namespaces) !== undefined)
|
|
61
|
+
throw malformed("namespaces");
|
|
54
62
|
if (typeof r.bytecodeMatch !== "string" || !isProvingMatch(r.bytecodeMatch)) {
|
|
55
63
|
throw new LayoutIntegrityError(`The layout record for ${who} rests on a "${String(r.bytecodeMatch)}" match, which does ` +
|
|
56
64
|
`not prove a storage layout.`);
|
package/dist/record.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,cAAc,EAAqB,MAAM,eAAe,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAoB,MAAM,YAAY,CAAC;AACjF,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../src/record.ts"],"names":[],"mappings":"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"}
|
package/dist/report.d.ts
CHANGED
|
@@ -17,10 +17,13 @@ export interface Check {
|
|
|
17
17
|
}
|
|
18
18
|
/** One line per check, names aligned, details indented under their check. */
|
|
19
19
|
export declare function checkLines(checks: Check[], paint?: Paint): string[];
|
|
20
|
+
/** How many namespaces are compared by annotation alone because no code assigns them. */
|
|
21
|
+
export declare function unassignedCount(pairs: NamespacePair[]): number;
|
|
20
22
|
/**
|
|
21
23
|
* A grid for each namespace whose slot is in question on either side: the
|
|
22
24
|
* annotation, the slot it implies and the slot the code uses, for old and new,
|
|
23
|
-
* with a sentence saying what that means. Namespaces that line up
|
|
25
|
+
* with a sentence saying what that means. Namespaces that line up, or that no
|
|
26
|
+
* code assigns on either side, are left out.
|
|
24
27
|
*/
|
|
25
28
|
export declare function namespaceLines(pairs: NamespacePair[], paint?: Paint): string[];
|
|
26
29
|
//# sourceMappingURL=report.d.ts.map
|
package/dist/report.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,cAAc,CAAC;AAEjE,+DAA+D;AAC/D,MAAM,MAAM,KAAK,GAAG,CAClB,MAAM,EAAE,UAAU,CAAC,cAAc,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAC3D,IAAI,EAAE,MAAM,KACT,MAAM,CAAC;AAEZ,eAAO,MAAM,KAAK,EAAE,KAAyB,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,GAAE,KAAa,GAAG,MAAM,EAAE,CAM1E;AAED
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,cAAc,CAAC;AAEjE,+DAA+D;AAC/D,MAAM,MAAM,KAAK,GAAG,CAClB,MAAM,EAAE,UAAU,CAAC,cAAc,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAC3D,IAAI,EAAE,MAAM,KACT,MAAM,CAAC;AAEZ,eAAO,MAAM,KAAK,EAAE,KAAyB,CAAC;AAE9C,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,mFAAmF;IACnF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,KAAK,GAAE,KAAa,GAAG,MAAM,EAAE,CAM1E;AAYD,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,CAG9D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,KAAK,GAAE,KAAa,GAAG,MAAM,EAAE,CAwCrF"}
|
package/dist/report.js
CHANGED
|
@@ -14,16 +14,28 @@ export function checkLines(checks, paint = plain) {
|
|
|
14
14
|
...(c.details?.split("\n").map((line) => ` ${line}`) ?? []),
|
|
15
15
|
]);
|
|
16
16
|
}
|
|
17
|
+
// A pair with nothing in question: no problem, and each side matches its
|
|
18
|
+
// annotation or is not assigned at all, except data the new code stops assigning.
|
|
19
|
+
// A side that is absent is not a problem here; OpenZeppelin reports a deleted namespace.
|
|
20
|
+
function quiet({ old, next, problem }) {
|
|
21
|
+
const plain = (s) => s === undefined || s.status === "match" || s.status === "unused";
|
|
22
|
+
const dropped = old?.actual !== undefined && next?.status === "unused";
|
|
23
|
+
return problem === undefined && plain(old) && plain(next) && !dropped;
|
|
24
|
+
}
|
|
25
|
+
/** How many namespaces are compared by annotation alone because no code assigns them. */
|
|
26
|
+
export function unassignedCount(pairs) {
|
|
27
|
+
return pairs.filter((p) => quiet(p) && [p.old, p.next].some((s) => s?.status === "unused"))
|
|
28
|
+
.length;
|
|
29
|
+
}
|
|
17
30
|
/**
|
|
18
31
|
* A grid for each namespace whose slot is in question on either side: the
|
|
19
32
|
* annotation, the slot it implies and the slot the code uses, for old and new,
|
|
20
|
-
* with a sentence saying what that means. Namespaces that line up
|
|
33
|
+
* with a sentence saying what that means. Namespaces that line up, or that no
|
|
34
|
+
* code assigns on either side, are left out.
|
|
21
35
|
*/
|
|
22
36
|
export function namespaceLines(pairs, paint = plain) {
|
|
23
37
|
const blocks = pairs
|
|
24
|
-
|
|
25
|
-
.filter((p) => p.problem !== undefined ||
|
|
26
|
-
[p.old, p.next].some((s) => s !== undefined && s.status !== "match"))
|
|
38
|
+
.filter((p) => !quiet(p))
|
|
27
39
|
.map((p) => {
|
|
28
40
|
const fmt = formatter([p.old, p.next]);
|
|
29
41
|
return {
|
|
@@ -65,14 +77,21 @@ function row(side, s, fmt) {
|
|
|
65
77
|
side,
|
|
66
78
|
id: s.namespace.slice("erc7201:".length),
|
|
67
79
|
implied: fmt(s.expected),
|
|
68
|
-
inCode: s.status === "conflict"
|
|
80
|
+
inCode: s.status === "conflict"
|
|
81
|
+
? "several"
|
|
82
|
+
: s.status === "unused"
|
|
83
|
+
? "none"
|
|
84
|
+
: s.actual !== undefined
|
|
85
|
+
? fmt(s.actual)
|
|
86
|
+
: "not read",
|
|
69
87
|
mark: {
|
|
70
88
|
match: "✓",
|
|
71
89
|
mismatch: "✗ annotation does not match code",
|
|
72
90
|
conflict: "✗ code uses more than one slot",
|
|
91
|
+
unused: "· not assigned in code",
|
|
73
92
|
unread: "? slot in code not read",
|
|
74
93
|
}[s.status],
|
|
75
|
-
tone: { match: "green", mismatch: "red", conflict: "red", unread: "yellow" }[s.status],
|
|
94
|
+
tone: { match: "green", mismatch: "red", conflict: "red", unused: "dim", unread: "yellow" }[s.status],
|
|
76
95
|
};
|
|
77
96
|
}
|
|
78
97
|
function meaning({ old, next, problem }, fmt) {
|
|
@@ -83,11 +102,21 @@ function meaning({ old, next, problem }, fmt) {
|
|
|
83
102
|
return (`The new code moves this namespace from ${fmt(old.actual)} to ${fmt(next.actual)}: ` +
|
|
84
103
|
"its data would be left behind. Keep the slot the deployed code uses, under an annotation that matches it.");
|
|
85
104
|
case "mismatch":
|
|
86
|
-
return old === undefined
|
|
105
|
+
return old === undefined || old.status === "unused"
|
|
87
106
|
? "The new code keeps this namespace in a different slot than its annotation says. Fix one of the two before deploying."
|
|
88
107
|
: "The storage did not move, but the new annotation does not match its code. Fix it before deploying.";
|
|
108
|
+
case "dropped":
|
|
109
|
+
return (`The new code stops assigning this namespace while its data is at ${fmt(old.actual)}, ` +
|
|
110
|
+
`not at ${fmt(old.expected)} where its annotation points: a later version that follows ` +
|
|
111
|
+
"the annotation would miss it. Correct the annotation to match the data first.");
|
|
89
112
|
case "unread":
|
|
90
|
-
return
|
|
113
|
+
return old !== undefined && old.actual === undefined && old.status !== "unused"
|
|
114
|
+
? "The old slot is not known (not read from its code, or missing from an older record), so this namespace could not be checked."
|
|
115
|
+
: "The slot in the new code could not be read (set from a value slotdiff does not evaluate), so this namespace could not be checked.";
|
|
116
|
+
}
|
|
117
|
+
// The only unused case shown without a problem: the new code stops assigning old data.
|
|
118
|
+
if (next?.status === "unused" && old?.actual !== undefined) {
|
|
119
|
+
return `The new code no longer assigns this namespace; its data stays at ${fmt(old.actual)}.`;
|
|
91
120
|
}
|
|
92
121
|
return next !== undefined
|
|
93
122
|
? "Same slot in code on both sides: the storage did not move. Compared as one namespace."
|
package/dist/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,CAAC,MAAM,KAAK,GAAU,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;AAY9C,MAAM,IAAI,GAAgC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAC9E,MAAM,IAAI,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAW,CAAC;AAErE,6EAA6E;AAC7E,MAAM,UAAU,UAAU,CAAC,MAAe,EAAE,QAAe,KAAK;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC3B,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE;QAChG,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;KAC/D,CAAC,CAAC;AACL,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
|
package/dist/resolve.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ import type { StorageLayout } from "@openzeppelin/upgrades-core";
|
|
|
11
11
|
import { type DeployedBytecodeMatch, type ImmutableReferences } from "./bytecode.js";
|
|
12
12
|
import { type EthProvider } from "./chain.js";
|
|
13
13
|
import { type ExplorerConfig } from "./explorer.js";
|
|
14
|
-
import { type ReconstructedLayout } from "./reconstruct.js";
|
|
14
|
+
import { type ProxyKind, type ReconstructedLayout } from "./reconstruct.js";
|
|
15
15
|
import { type LayoutRecord } from "./record.js";
|
|
16
16
|
import { type SolcOptions } from "./solc.js";
|
|
17
17
|
export interface ResolveOptions {
|
|
@@ -39,6 +39,8 @@ export interface ProxyLayout {
|
|
|
39
39
|
implementation: string;
|
|
40
40
|
/** Set for a beacon proxy. */
|
|
41
41
|
beacon?: string;
|
|
42
|
+
/** The proxy's kind, for `checkUpgrade`: `beacon` behind a beacon, else the record's. */
|
|
43
|
+
kind: ProxyKind;
|
|
42
44
|
record: LayoutRecord;
|
|
43
45
|
}
|
|
44
46
|
/** `resolveLayout` for whatever implementation `proxy` runs right now (ERC-1967 or beacon). */
|
|
@@ -50,6 +52,9 @@ export interface LocalBuild {
|
|
|
50
52
|
layout: StorageLayout;
|
|
51
53
|
deployedBytecode: string;
|
|
52
54
|
immutableReferences?: ImmutableReferences;
|
|
55
|
+
/** From `analyzeSource`, so the record carries them (see `LayoutRecord`). */
|
|
56
|
+
kind?: LayoutRecord["kind"];
|
|
57
|
+
namespaces?: LayoutRecord["namespaces"];
|
|
53
58
|
}
|
|
54
59
|
export interface LocalBuildResult {
|
|
55
60
|
bytecodeMatch: DeployedBytecodeMatch;
|