slotdiff 0.1.0-alpha.1 → 0.2.0-alpha.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 +16 -9
- package/README.md +196 -105
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +22 -0
- package/dist/bin.js.map +1 -0
- package/dist/build-info.d.ts +45 -0
- package/dist/build-info.d.ts.map +1 -0
- package/dist/build-info.js +319 -0
- package/dist/build-info.js.map +1 -0
- package/dist/cli.d.ts +25 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +363 -0
- package/dist/cli.js.map +1 -0
- package/dist/erc7201.d.ts +72 -0
- package/dist/erc7201.d.ts.map +1 -0
- package/dist/erc7201.js +340 -0
- package/dist/erc7201.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +8 -0
- package/dist/errors.js.map +1 -1
- package/dist/explorer.js +2 -2
- package/dist/explorer.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/reconstruct.d.ts +51 -3
- package/dist/reconstruct.d.ts.map +1 -1
- package/dist/reconstruct.js +37 -8
- package/dist/reconstruct.js.map +1 -1
- package/dist/report.d.ts +26 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +109 -0
- package/dist/report.js.map +1 -0
- package/dist/resolve.d.ts +11 -0
- package/dist/resolve.d.ts.map +1 -1
- package/dist/resolve.js +11 -1
- package/dist/resolve.js.map +1 -1
- package/package.json +6 -3
- package/src/bin.ts +25 -0
- package/src/build-info.ts +405 -0
- package/src/cli.ts +423 -0
- package/src/erc7201.ts +412 -0
- package/src/errors.ts +9 -0
- package/src/explorer.ts +2 -2
- package/src/index.ts +18 -1
- package/src/reconstruct.ts +111 -10
- package/src/report.ts +155 -0
- package/src/resolve.ts +17 -2
package/dist/erc7201.js
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ERC-7201 namespaces by the slot the code really uses.
|
|
3
|
+
*
|
|
4
|
+
* OpenZeppelin matches namespaces by their `@custom:storage-location
|
|
5
|
+
* erc7201:<id>` annotation and never checks the `bytes32` slot the code assigns
|
|
6
|
+
* (`assembly { $.slot := LOCATION }`). The two can disagree. A changed
|
|
7
|
+
* constant behind an unchanged annotation moves the storage while the layout
|
|
8
|
+
* check passes; a corrected annotation over an unchanged constant leaves the
|
|
9
|
+
* storage in place while the check reports a deleted namespace. Reading the
|
|
10
|
+
* slot from the AST catches the first and fixes the second.
|
|
11
|
+
*/
|
|
12
|
+
// Not exported from the package index; the package has no exports map, and
|
|
13
|
+
// all exist since 1.46.0, the lowest version slotdiff accepts.
|
|
14
|
+
import { getStorageLocationAnnotation } from "@openzeppelin/upgrades-core/dist/storage/namespace.js";
|
|
15
|
+
import { calculateERC7201StorageLocation } from "@openzeppelin/upgrades-core/dist/utils/erc7201.js";
|
|
16
|
+
import { resolveBaseSlot } from "@openzeppelin/upgrades-core/dist/utils/erc7201-builtin.js";
|
|
17
|
+
import { normalizeUint256Literal, toBytes32Hex, } from "@openzeppelin/upgrades-core/dist/utils/integer-literals.js";
|
|
18
|
+
/**
|
|
19
|
+
* How each of `namespaces` (`erc7201:<id>` keys of `contract`'s layout,
|
|
20
|
+
* `source.sol:Name`) is assigned in `output`. Only structs declared in the
|
|
21
|
+
* contract or its bases count, as for OpenZeppelin: a sibling contract in the
|
|
22
|
+
* same build (a V1 next to its V2, a test copy) may declare the same id.
|
|
23
|
+
*/
|
|
24
|
+
export function namespaceSlots(output, contract, namespaces) {
|
|
25
|
+
const colon = contract.lastIndexOf(":");
|
|
26
|
+
// Most derived first, as solc lists them: the order virtual calls resolve in.
|
|
27
|
+
let linearized = [];
|
|
28
|
+
walk(output.sources?.[contract.slice(0, colon)]?.ast, (node) => {
|
|
29
|
+
if (node.nodeType === "ContractDefinition" && node.name === contract.slice(colon + 1)) {
|
|
30
|
+
linearized = node.linearizedBaseContracts;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
const bases = new Set(linearized);
|
|
34
|
+
// Only code the contract can run counts: its bases (minus the functions they
|
|
35
|
+
// override), libraries and free functions, not a sibling contract (a test
|
|
36
|
+
// harness) in the same files.
|
|
37
|
+
const byId = new Map();
|
|
38
|
+
const touched = new Set();
|
|
39
|
+
const overridden = new Set();
|
|
40
|
+
for (const source of Object.values(output.sources ?? {})) {
|
|
41
|
+
walk(source.ast, (node) => {
|
|
42
|
+
if (typeof node.id === "number")
|
|
43
|
+
byId.set(node.id, node);
|
|
44
|
+
// Any Solidity use of a local after its declaration, so a local is read
|
|
45
|
+
// only when nothing but assembly reads it.
|
|
46
|
+
if (node.nodeType === "Identifier")
|
|
47
|
+
touched.add(node.referencedDeclaration);
|
|
48
|
+
if (node.nodeType === "FunctionDefinition" && bases.has(node.scope)) {
|
|
49
|
+
for (const base of (node.baseFunctions ?? []))
|
|
50
|
+
overridden.add(base);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
const assemblies = [];
|
|
55
|
+
for (const source of Object.values(output.sources ?? {})) {
|
|
56
|
+
walk(source.ast, (node) => {
|
|
57
|
+
const sibling = node.nodeType === "ContractDefinition" &&
|
|
58
|
+
node.contractKind !== "library" &&
|
|
59
|
+
!bases.has(node.id);
|
|
60
|
+
if (sibling || overridden.has(node.id))
|
|
61
|
+
return false;
|
|
62
|
+
if (node.nodeType === "InlineAssembly")
|
|
63
|
+
assemblies.push(node);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const ctx = { byId, linearized, bases, touched };
|
|
67
|
+
// Struct id → every slot value assigned to a pointer of that struct (undefined: unreadable).
|
|
68
|
+
const assigned = new Map();
|
|
69
|
+
for (const assembly of assemblies) {
|
|
70
|
+
const refs = (assembly.externalReferences ?? []);
|
|
71
|
+
const declarationAt = (src) => refs.find((r) => r.src === src)?.declaration ?? -1;
|
|
72
|
+
walk(assembly.AST, (node) => {
|
|
73
|
+
if (node.nodeType !== "YulAssignment")
|
|
74
|
+
return;
|
|
75
|
+
for (const target of node.variableNames) {
|
|
76
|
+
if (typeof target.name !== "string")
|
|
77
|
+
continue;
|
|
78
|
+
if (!target.name.endsWith(".slot")) {
|
|
79
|
+
touched.add(declarationAt(target.src));
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const pointer = byId.get(declarationAt(target.src));
|
|
83
|
+
const struct = pointer?.typeName?.referencedDeclaration;
|
|
84
|
+
if (typeof struct !== "number")
|
|
85
|
+
continue;
|
|
86
|
+
const value = node.value;
|
|
87
|
+
const slot = value.nodeType === "YulLiteral"
|
|
88
|
+
? value.kind === "number"
|
|
89
|
+
? normalize(value.value)
|
|
90
|
+
: undefined
|
|
91
|
+
: resolveDecl(ctx, byId.get(declarationAt(value.src)));
|
|
92
|
+
assigned.set(struct, [...(assigned.get(struct) ?? []), slot]);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return namespaces.map((namespace) => {
|
|
97
|
+
const expected = calculateERC7201StorageLocation(namespace.slice("erc7201:".length));
|
|
98
|
+
const slots = [...byId.values()]
|
|
99
|
+
.filter((n) => n.nodeType === "StructDefinition" &&
|
|
100
|
+
bases.has(n.scope) &&
|
|
101
|
+
getStorageLocationAnnotation(n) === namespace)
|
|
102
|
+
.flatMap((n) => assigned.get(n.id) ?? []);
|
|
103
|
+
const known = [...new Set(slots.filter((s) => s !== undefined))];
|
|
104
|
+
if (known.length > 1)
|
|
105
|
+
return { namespace, expected, status: "conflict" };
|
|
106
|
+
if (known.length === 0 || slots.includes(undefined)) {
|
|
107
|
+
return { namespace, expected, status: "unread" };
|
|
108
|
+
}
|
|
109
|
+
const actual = known[0];
|
|
110
|
+
return actual === expected
|
|
111
|
+
? { namespace, expected, actual, status: "match" }
|
|
112
|
+
: { namespace, expected, actual, status: "mismatch" };
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Checks ERC-7201 namespaces by the slot the code uses, not the annotation
|
|
117
|
+
* OpenZeppelin goes by. An old and a new namespace are the same storage when
|
|
118
|
+
* the code uses the same slot (under the same annotation first), failing that
|
|
119
|
+
* when they share an annotation, and failing that when the new annotation
|
|
120
|
+
* names the slot where the old data is.
|
|
121
|
+
* Pass `layout` to `diffLayouts` in place of `old.layout`.
|
|
122
|
+
*/
|
|
123
|
+
export function checkNamespaces(old, next) {
|
|
124
|
+
const unpaired = new Set(old.namespaces);
|
|
125
|
+
const pairs = next.namespaces.map((n) => ({ next: n }));
|
|
126
|
+
const sameSlot = (o, n) => o.actual !== undefined && n.actual !== undefined && same(o.actual, n.actual);
|
|
127
|
+
const rules = [
|
|
128
|
+
(o, n) => sameSlot(o, n) && o.namespace === n.namespace,
|
|
129
|
+
sameSlot,
|
|
130
|
+
(o, n) => o.namespace === n.namespace,
|
|
131
|
+
(o, n) => o.actual !== undefined && same(o.actual, n.expected),
|
|
132
|
+
];
|
|
133
|
+
// Rule by rule over every namespace, so a weaker rule never takes a pair from a stronger one.
|
|
134
|
+
for (const rule of rules) {
|
|
135
|
+
for (const pair of pairs) {
|
|
136
|
+
const o = pair.old ?? [...unpaired].find((o) => rule(o, pair.next));
|
|
137
|
+
if (o !== undefined && unpaired.delete(o))
|
|
138
|
+
pair.old = o;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const o of unpaired)
|
|
142
|
+
pairs.push({ old: o });
|
|
143
|
+
for (const pair of pairs)
|
|
144
|
+
pair.problem = problemOf(pair);
|
|
145
|
+
// Renamed all at once, so two namespaces can swap names.
|
|
146
|
+
const renames = new Map(pairs.flatMap((p) => p.old !== undefined && p.next !== undefined ? [[p.old.namespace, p.next.namespace]] : []));
|
|
147
|
+
const oldNames = Object.keys(old.layout.namespaces ?? {});
|
|
148
|
+
const renamed = oldNames.map((name) => renames.get(name) ?? name);
|
|
149
|
+
// On a clash (an old namespace that stays keeps the name another would take)
|
|
150
|
+
// nothing is renamed: OpenZeppelin then reports the moved one as deleted.
|
|
151
|
+
const layout = new Set(renamed).size < renamed.length || renamed.every((to, i) => to === oldNames[i])
|
|
152
|
+
? old.layout
|
|
153
|
+
: {
|
|
154
|
+
...old.layout,
|
|
155
|
+
namespaces: Object.fromEntries(oldNames.map((name, i) => [renamed[i], old.layout.namespaces[name]])),
|
|
156
|
+
};
|
|
157
|
+
const problems = pairs.map((p) => p.problem);
|
|
158
|
+
return {
|
|
159
|
+
layout,
|
|
160
|
+
pairs,
|
|
161
|
+
result: problems.some((p) => p !== undefined && p !== "unread")
|
|
162
|
+
? "fail"
|
|
163
|
+
: problems.includes("unread")
|
|
164
|
+
? "unread"
|
|
165
|
+
: "pass",
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
function problemOf({ old, next }) {
|
|
169
|
+
if (next?.status === "conflict")
|
|
170
|
+
return "conflict";
|
|
171
|
+
if (old?.actual !== undefined && next?.actual !== undefined && !same(old.actual, next.actual)) {
|
|
172
|
+
return "moved";
|
|
173
|
+
}
|
|
174
|
+
if (next?.status === "mismatch")
|
|
175
|
+
return "mismatch";
|
|
176
|
+
if ((old !== undefined && old.actual === undefined) || next?.status === "unread") {
|
|
177
|
+
return "unread";
|
|
178
|
+
}
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
function same(a, b) {
|
|
182
|
+
return BigInt(a) === BigInt(b);
|
|
183
|
+
}
|
|
184
|
+
// Visits every node; a visitor returning false skips the node's children.
|
|
185
|
+
function walk(node, visit) {
|
|
186
|
+
if (Array.isArray(node)) {
|
|
187
|
+
for (const child of node)
|
|
188
|
+
walk(child, visit);
|
|
189
|
+
}
|
|
190
|
+
else if (typeof node === "object" && node !== null) {
|
|
191
|
+
if (visit(node) === false)
|
|
192
|
+
return;
|
|
193
|
+
for (const child of Object.values(node))
|
|
194
|
+
walk(child, visit);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The value of a constant, an immutable set where it is declared, or a local
|
|
199
|
+
* that only assembly reads. A state variable's initial value is not read: it
|
|
200
|
+
* lives in the implementation's storage, not the proxy's.
|
|
201
|
+
*/
|
|
202
|
+
function resolveDecl(ctx, decl, depth = 0) {
|
|
203
|
+
if (decl === undefined)
|
|
204
|
+
return undefined;
|
|
205
|
+
if (decl.stateVariable === true) {
|
|
206
|
+
if (decl.mutability !== "constant" && decl.mutability !== "immutable")
|
|
207
|
+
return undefined;
|
|
208
|
+
return resolveExpr(ctx, decl.value, depth);
|
|
209
|
+
}
|
|
210
|
+
if (ctx.touched.has(decl.id))
|
|
211
|
+
return undefined;
|
|
212
|
+
return resolveExpr(ctx, initialValue(ctx.byId, decl), depth);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* The value of an expression: a reference to a constant or local, a call to a
|
|
216
|
+
* no-argument function that returns one (OpenZeppelin's Initializable reads
|
|
217
|
+
* its slot from `_initializableStorageSlot()`), the ERC-7201 formula, a
|
|
218
|
+
* number literal or `erc7201("id")`.
|
|
219
|
+
*/
|
|
220
|
+
function resolveExpr(ctx, e, depth) {
|
|
221
|
+
if (e === undefined || depth > 8)
|
|
222
|
+
return undefined;
|
|
223
|
+
if (e.nodeType === "Identifier") {
|
|
224
|
+
return resolveDecl(ctx, ctx.byId.get(e.referencedDeclaration), depth + 1);
|
|
225
|
+
}
|
|
226
|
+
if (e.nodeType === "FunctionCall" && e.kind === "functionCall") {
|
|
227
|
+
const callee = e.expression;
|
|
228
|
+
const fn = ctx.byId.get(callee.referencedDeclaration);
|
|
229
|
+
if (callee.nodeType !== "Identifier" || fn?.nodeType !== "FunctionDefinition")
|
|
230
|
+
return undefined;
|
|
231
|
+
if (e.arguments.length > 0)
|
|
232
|
+
return undefined;
|
|
233
|
+
return resolveExpr(ctx, returned(override(ctx, fn)), depth + 1);
|
|
234
|
+
}
|
|
235
|
+
const id = formulaId(e);
|
|
236
|
+
if (id !== undefined)
|
|
237
|
+
return calculateERC7201StorageLocation(id);
|
|
238
|
+
// OpenZeppelin would read any other literal, such as `hex"..."`, as a number.
|
|
239
|
+
if (e.nodeType === "Literal" && e.kind !== "number")
|
|
240
|
+
return undefined;
|
|
241
|
+
try {
|
|
242
|
+
return resolveBaseSlot(e);
|
|
243
|
+
}
|
|
244
|
+
catch {
|
|
245
|
+
return undefined;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* The implementation an internal call to `fn` reaches: the most derived
|
|
250
|
+
* override of a virtual function in the bases, or `fn` itself (a free or
|
|
251
|
+
* library function, which nothing overrides).
|
|
252
|
+
*/
|
|
253
|
+
function override(ctx, fn) {
|
|
254
|
+
if (fn.virtual !== true || !ctx.bases.has(fn.scope))
|
|
255
|
+
return fn;
|
|
256
|
+
for (const contract of ctx.linearized) {
|
|
257
|
+
for (const node of ctx.byId.values()) {
|
|
258
|
+
if (node.nodeType === "FunctionDefinition" &&
|
|
259
|
+
node.scope === contract &&
|
|
260
|
+
node.name === fn.name &&
|
|
261
|
+
node.parameters.parameters.length === 0 &&
|
|
262
|
+
node.body) {
|
|
263
|
+
return node;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return fn;
|
|
268
|
+
}
|
|
269
|
+
// The expression of a function whose body is a single `return <expression>;`
|
|
270
|
+
// and that has no modifier, which could skip it.
|
|
271
|
+
function returned(fn) {
|
|
272
|
+
if (fn.modifiers?.length)
|
|
273
|
+
return undefined;
|
|
274
|
+
const statements = fn.body?.statements;
|
|
275
|
+
return statements?.length === 1 && statements[0].nodeType === "Return"
|
|
276
|
+
? statements[0].expression
|
|
277
|
+
: undefined;
|
|
278
|
+
}
|
|
279
|
+
// A local variable's value is on the statement that declares it.
|
|
280
|
+
function initialValue(byId, decl) {
|
|
281
|
+
for (const node of byId.values()) {
|
|
282
|
+
if (node.nodeType !== "VariableDeclarationStatement")
|
|
283
|
+
continue;
|
|
284
|
+
const declarations = node.declarations;
|
|
285
|
+
if (declarations.length === 1 && declarations[0]?.id === decl.id)
|
|
286
|
+
return node.initialValue;
|
|
287
|
+
}
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* The id in the ERC-7201 formula written out in Solidity,
|
|
292
|
+
* `keccak256(abi.encode(uint256(keccak256("id")) - 1)) & ~bytes32(uint256(0xff))`,
|
|
293
|
+
* with an optional `bytes("id")`. Anything else is not recognized.
|
|
294
|
+
*/
|
|
295
|
+
function formulaId(e) {
|
|
296
|
+
if (e.nodeType !== "BinaryOperation" || e.operator !== "&")
|
|
297
|
+
return undefined;
|
|
298
|
+
const mask = e.rightExpression;
|
|
299
|
+
const masked = arg(arg(mask.nodeType === "UnaryOperation" ? mask.subExpression : undefined, "bytes32"), "uint256");
|
|
300
|
+
if (masked?.nodeType !== "Literal" || normalize(masked.value) !== toBytes32Hex(0xffn)) {
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
303
|
+
const minus = arg(arg(e.leftExpression, "keccak256"), "abi.encode");
|
|
304
|
+
if (minus?.nodeType !== "BinaryOperation" || minus.operator !== "-")
|
|
305
|
+
return undefined;
|
|
306
|
+
const one = minus.rightExpression;
|
|
307
|
+
if (one.nodeType !== "Literal" || one.value !== "1")
|
|
308
|
+
return undefined;
|
|
309
|
+
let id = arg(arg(minus.leftExpression, "uint256"), "keccak256");
|
|
310
|
+
if (id?.nodeType === "FunctionCall")
|
|
311
|
+
id = arg(id, "bytes");
|
|
312
|
+
return id?.nodeType === "Literal" && id.kind === "string" ? id.value : undefined;
|
|
313
|
+
}
|
|
314
|
+
// The single argument of a call to `name` (a function, `abi.encode`, or a type conversion).
|
|
315
|
+
function arg(call, name) {
|
|
316
|
+
if (call?.nodeType !== "FunctionCall")
|
|
317
|
+
return undefined;
|
|
318
|
+
const callee = call.expression;
|
|
319
|
+
const calleeName = callee.nodeType === "Identifier"
|
|
320
|
+
? callee.name
|
|
321
|
+
: callee.nodeType === "MemberAccess"
|
|
322
|
+
? `${callee.expression.name}.${callee.memberName}`
|
|
323
|
+
: callee.nodeType === "ElementaryTypeNameExpression"
|
|
324
|
+
? callee.typeName.name
|
|
325
|
+
: undefined;
|
|
326
|
+
const args = call.arguments;
|
|
327
|
+
return calleeName === name && args.length === 1 ? args[0] : undefined;
|
|
328
|
+
}
|
|
329
|
+
// A number literal as a slot, or undefined when it is not one.
|
|
330
|
+
function normalize(value) {
|
|
331
|
+
if (typeof value !== "string")
|
|
332
|
+
return undefined;
|
|
333
|
+
try {
|
|
334
|
+
return normalizeUint256Literal(value);
|
|
335
|
+
}
|
|
336
|
+
catch {
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
//# sourceMappingURL=erc7201.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erc7201.js","sourceRoot":"","sources":["../src/erc7201.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -15,4 +15,9 @@ export declare class LayoutUnavailableError extends Error {
|
|
|
15
15
|
export declare class LayoutIntegrityError extends Error {
|
|
16
16
|
constructor(message: string);
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* A network error's code (ECONNREFUSED, ENOTFOUND), never its message: fetch
|
|
20
|
+
* quotes the URL in some messages, and URLs carry API keys.
|
|
21
|
+
*/
|
|
22
|
+
export declare function errorCode(e: unknown): string;
|
|
18
23
|
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;gBACnC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAG5C"}
|
package/dist/errors.js
CHANGED
|
@@ -21,4 +21,12 @@ export class LayoutIntegrityError extends Error {
|
|
|
21
21
|
this.name = "LayoutIntegrityError";
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* A network error's code (ECONNREFUSED, ENOTFOUND), never its message: fetch
|
|
26
|
+
* quotes the URL in some messages, and URLs carry API keys.
|
|
27
|
+
*/
|
|
28
|
+
export function errorCode(e) {
|
|
29
|
+
const code = e.cause?.code;
|
|
30
|
+
return typeof code === "string" ? code : "network error";
|
|
31
|
+
}
|
|
24
32
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,CAAU;IAClC,MAAM,IAAI,GAAI,CAAoC,CAAC,KAAK,EAAE,IAAI,CAAC;IAC/D,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC;AAC3D,CAAC"}
|
package/dist/explorer.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* rebuilding from them means guessing; the bytecode proof would reject a wrong
|
|
7
7
|
* guess, but refusing up front gives a clearer error.
|
|
8
8
|
*/
|
|
9
|
-
import { LayoutUnavailableError } from "./errors.js";
|
|
9
|
+
import { errorCode, LayoutUnavailableError } from "./errors.js";
|
|
10
10
|
export const ETHERSCAN_V2_API_URL = "https://api.etherscan.io/v2/api";
|
|
11
11
|
const RATE_LIMIT = /rate limit/i;
|
|
12
12
|
// Key problems are the user's to fix and must surface; anything else the
|
|
@@ -43,7 +43,7 @@ async function requestWithRetry(url, fetchImpl) {
|
|
|
43
43
|
}
|
|
44
44
|
catch (e) {
|
|
45
45
|
// Messages never include the URL, which carries the API key.
|
|
46
|
-
throw new LayoutUnavailableError(`Explorer unreachable
|
|
46
|
+
throw new LayoutUnavailableError(`Explorer unreachable (${errorCode(e)}).`);
|
|
47
47
|
}
|
|
48
48
|
if (res.status === 429 && retry) {
|
|
49
49
|
await backoff(attempt);
|
package/dist/explorer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"explorer.js","sourceRoot":"","sources":["../src/explorer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAEhE,MAAM,CAAC,MAAM,oBAAoB,GAAG,iCAAiC,CAAC;AAgCtE,MAAM,UAAU,GAAG,aAAa,CAAC;AACjC,yEAAyE;AACzE,4EAA4E;AAC5E,MAAM,SAAS,GAAG,WAAW,CAAC;AAC9B,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAsB;IACrD,OAAO,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAAe,EACf,OAAe,EACf,MAAsB,EACtB,YAAuB,KAAK;IAE5B,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,sBAAsB,CAC9B,4CAA4C,OAAO,sCAAsC,OAAO,GAAG,CACpG,CAAC;IACJ,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,oBAAoB,CAAC,CAAC;IAC3D,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IACjD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC3C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAChD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,MAAM;QAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAEjE,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,SAAS,CAAC,CAAC;IAChE,OAAO,oBAAoB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,SAAoB;IAC/D,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,OAAO,GAAG,YAAY,CAAC;QACrC,IAAI,GAAmC,CAAC;QACxC,IAAI,CAAC;YACH,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,6DAA6D;YAC7D,MAAM,IAAI,sBAAsB,CAAC,yBAAyB,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;YAChC,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,IAAI,sBAAsB,CAAC,qCAAqC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,IAAsB,CAAC;QAC3B,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqB,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,sBAAsB,CAAC,gDAAgD,CAAC,CAAC;QACrF,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,IAAI,sBAAsB,CAAC,2CAA2C,CAAC,CAAC;QAChF,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChF,MAAM,KAAK,GAAY,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBAChD,MAAM,IAAI,sBAAsB,CAAC,+CAA+C,CAAC,CAAC;YACpF,CAAC;YACD,OAAO,KAAwB,CAAC;QAClC,CAAC;QAED,MAAM,MAAM,GACV,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC,CAAC;QACpF,6EAA6E;QAC7E,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,MAAM,IAAI,sBAAsB,CAAC,4CAA4C,MAAM,EAAE,CAAC,CAAC;QACzF,CAAC;QACD,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,EAAE,CAAC,CAAC;QACxF,MAAM,IAAI,sBAAsB,CAAC,8BAA8B,MAAM,EAAE,CAAC,CAAC;IAC3E,CAAC;AACH,CAAC;AAED,SAAS,OAAO,CAAC,OAAe;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,0BAA0B;AAC1B,MAAM,UAAU,oBAAoB,CAAC,KAAsB,EAAE,OAAe;IAC1E,MAAM,GAAG,GAAG,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC;IACnC,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;QACf,MAAM,IAAI,sBAAsB,CAAC,YAAY,OAAO,mCAAmC,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC;IACpD,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,sBAAsB,CAC9B,YAAY,OAAO,uBAAuB,eAAe,gCAAgC,CAC1F,CAAC;IACJ,CAAC;IAED,IACE,CAAC,2EAA2E,CAAC,IAAI,CAC/E,eAAe,CAChB,EACD,CAAC;QACD,MAAM,IAAI,sBAAsB,CAC9B,YAAY,OAAO,8CAA8C,eAAe,IAAI,CACrF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,sBAAsB,CAC9B,YAAY,OAAO,qEAAqE;YACtF,wDAAwD,CAC3D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK;QACL,eAAe,EAAE,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;QACzC,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,EAAE;KACvC,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,4CAA4C;AAC5C,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACjF,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,SAAS,GAAG,MAAoD,CAAC;IACvE,IAAI,SAAS,CAAC,QAAQ,KAAK,UAAU,IAAI,OAAO,SAAS,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACjG,OAAO,SAAsB,CAAC;AAChC,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ export { parseRecord, verifyRecord, type LayoutRecord } from "./record.js";
|
|
|
4
4
|
export { readProxy, readImplementation, readCode, readChainId, type EthProvider, type ProxyState, } from "./chain.js";
|
|
5
5
|
export { fetchVerifiedSource, ETHERSCAN_V2_API_URL, type ExplorerConfig, type VerifiedSource, } from "./explorer.js";
|
|
6
6
|
export { getSolc, type SolcOptions, type SolcRunner } from "./solc.js";
|
|
7
|
-
export {
|
|
7
|
+
export { findBuildInfo, type BuildInfoOptions, type BuildInfoContract } from "./build-info.js";
|
|
8
|
+
export { checkNamespaces, type NamespaceCheck, type NamespacePair, type NamespaceSlot, } from "./erc7201.js";
|
|
9
|
+
export { layoutFromSource, analyzeSource, SAFETY_ERROR_KINDS, type SourceAnalysis, type SafetyOptions, type SafetyReport, type SafetyError, type SafetyErrorKind, type ProxyKind, } from "./reconstruct.js";
|
|
8
10
|
export { compareDeployedBytecode, isProvingMatch, type DeployedBytecodeMatch, type ProvingMatch, type ImmutableReferences, } from "./bytecode.js";
|
|
9
11
|
export { LayoutIntegrityError, LayoutUnavailableError } from "./errors.js";
|
|
10
12
|
export type { SolcInput, StorageLayout } from "@openzeppelin/upgrades-core";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,QAAQ,EACR,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,QAAQ,EACR,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EACL,eAAe,EACf,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,SAAS,GACf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,cAAc,EACd,KAAK,qBAAqB,EAC1B,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,9 @@ export { parseRecord, verifyRecord } from "./record.js";
|
|
|
4
4
|
export { readProxy, readImplementation, readCode, readChainId, } from "./chain.js";
|
|
5
5
|
export { fetchVerifiedSource, ETHERSCAN_V2_API_URL, } from "./explorer.js";
|
|
6
6
|
export { getSolc } from "./solc.js";
|
|
7
|
-
export {
|
|
7
|
+
export { findBuildInfo } from "./build-info.js";
|
|
8
|
+
export { checkNamespaces, } from "./erc7201.js";
|
|
9
|
+
export { layoutFromSource, analyzeSource, SAFETY_ERROR_KINDS, } from "./reconstruct.js";
|
|
8
10
|
export { compareDeployedBytecode, isProvingMatch, } from "./bytecode.js";
|
|
9
11
|
export { LayoutIntegrityError, LayoutUnavailableError } from "./errors.js";
|
|
10
12
|
//# 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,gBAAgB,
|
|
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,gBAAgB,EAChB,aAAa,EACb,kBAAkB,GAOnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,cAAc,GAIf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/reconstruct.d.ts
CHANGED
|
@@ -6,16 +6,17 @@
|
|
|
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 SolcInput, type StorageLayout } from "@openzeppelin/upgrades-core";
|
|
9
|
+
import { type ProxyDeployment, type SolcInput, type StorageLayout } from "@openzeppelin/upgrades-core";
|
|
10
|
+
import { type ValidationError } from "@openzeppelin/upgrades-core/dist/validate/run.js";
|
|
10
11
|
import { type ProvingMatch } from "./bytecode.js";
|
|
12
|
+
import { type NamespaceSlot } from "./erc7201.js";
|
|
11
13
|
import type { VerifiedSource } from "./explorer.js";
|
|
12
14
|
import type { SolcRunner } from "./solc.js";
|
|
13
|
-
export interface ReconstructedLayout {
|
|
15
|
+
export interface ReconstructedLayout extends SourceAnalysis {
|
|
14
16
|
/** Fully qualified name, `source.sol:Contract`. */
|
|
15
17
|
contract: string;
|
|
16
18
|
compiler: string;
|
|
17
19
|
bytecodeMatch: ProvingMatch;
|
|
18
|
-
layout: StorageLayout;
|
|
19
20
|
}
|
|
20
21
|
export declare function reconstructLayout(source: VerifiedSource, solc: SolcRunner, onchainCode: string): Promise<ReconstructedLayout>;
|
|
21
22
|
/**
|
|
@@ -24,4 +25,51 @@ export declare function reconstructLayout(source: VerifiedSource, solc: SolcRunn
|
|
|
24
25
|
* project's own build-info.
|
|
25
26
|
*/
|
|
26
27
|
export declare function layoutFromSource(input: SolcInput, solc: SolcRunner, contract: string): Promise<StorageLayout>;
|
|
28
|
+
export type ProxyKind = ProxyDeployment["kind"];
|
|
29
|
+
/**
|
|
30
|
+
* OpenZeppelin's safety error kinds, without the deprecated struct-definition
|
|
31
|
+
* and enum-definition, which the check never reports.
|
|
32
|
+
*/
|
|
33
|
+
export type SafetyErrorKind = Exclude<ValidationError["kind"], "struct-definition" | "enum-definition">;
|
|
34
|
+
export declare const SAFETY_ERROR_KINDS: readonly SafetyErrorKind[];
|
|
35
|
+
export interface SafetyError {
|
|
36
|
+
/** OpenZeppelin's error kind, such as `constructor`. */
|
|
37
|
+
kind: SafetyErrorKind;
|
|
38
|
+
/** Where, as `file.sol:line`. */
|
|
39
|
+
src: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SafetyOptions {
|
|
42
|
+
/**
|
|
43
|
+
* The proxy being upgraded; only `uups` requires an `upgradeToAndCall`.
|
|
44
|
+
* Required: the new contract's own `kind` would let a UUPS implementation
|
|
45
|
+
* that lost its upgrade function pass.
|
|
46
|
+
*/
|
|
47
|
+
kind: ProxyKind;
|
|
48
|
+
/** Error kinds to accept anyway (OZ's `unsafeAllow`). Prefer NatSpec exceptions in the source. */
|
|
49
|
+
unsafeAllow?: SafetyErrorKind[];
|
|
50
|
+
}
|
|
51
|
+
export interface SafetyReport {
|
|
52
|
+
ok: boolean;
|
|
53
|
+
errors: SafetyError[];
|
|
54
|
+
/** OpenZeppelin's description of each error. */
|
|
55
|
+
explain(): string;
|
|
56
|
+
}
|
|
57
|
+
export interface SourceAnalysis {
|
|
58
|
+
layout: StorageLayout;
|
|
59
|
+
/** `uups` when the contract has `upgradeTo` or `upgradeToAndCall`, else `transparent`. */
|
|
60
|
+
kind: Exclude<ProxyKind, "beacon">;
|
|
61
|
+
/**
|
|
62
|
+
* The slot each ERC-7201 namespace really uses, read from the code
|
|
63
|
+
* (`$.slot := LOCATION`); OpenZeppelin trusts the annotation alone.
|
|
64
|
+
*/
|
|
65
|
+
namespaces: NamespaceSlot[];
|
|
66
|
+
/**
|
|
67
|
+
* OpenZeppelin's safety check (constructors, `selfdestruct`,
|
|
68
|
+
* `delegatecall`, initial values, immutables, initializers), honoring
|
|
69
|
+
* `@custom:oz-upgrades-unsafe-allow` in the source.
|
|
70
|
+
*/
|
|
71
|
+
safety(options: SafetyOptions): SafetyReport;
|
|
72
|
+
}
|
|
73
|
+
/** `layoutFromSource` plus OpenZeppelin's safety check, from one compile. */
|
|
74
|
+
export declare function analyzeSource(input: SolcInput, solc: SolcRunner, contract: string): Promise<SourceAnalysis>;
|
|
27
75
|
//# 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,EAUL,KAAK,eAAe,EACpB,KAAK,SAAS,EAEd,KAAK,aAAa,EAGnB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,kDAAkD,CAAC;AACpG,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;AAoBD,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,UAAU,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAiB9B;AAED;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,CAExB;AAED,MAAM,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;AAEhD;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,CACnC,eAAe,CAAC,MAAM,CAAC,EACvB,mBAAmB,GAAG,iBAAiB,CACxC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,SAAS,eAAe,EAExD,CAAC;AAEF,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,gDAAgD;IAChD,OAAO,IAAI,MAAM,CAAC;CACnB;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,6EAA6E;AAC7E,wBAAsB,aAAa,CACjC,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,cAAc,CAAC,CAGzB"}
|
package/dist/reconstruct.js
CHANGED
|
@@ -6,8 +6,11 @@
|
|
|
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 { getStorageLayout, isNamespaceSupported, makeNamespacedInput, solcInputOutputDecoder, trySanitizeNatSpec, validate, } from "@openzeppelin/upgrades-core";
|
|
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";
|
|
10
12
|
import { compareDeployedBytecode, isProvingMatch } from "./bytecode.js";
|
|
13
|
+
import { namespaceSlots } from "./erc7201.js";
|
|
11
14
|
import { LayoutIntegrityError } from "./errors.js";
|
|
12
15
|
// validate() reads evm.bytecode for every contract, so codegen is requested
|
|
13
16
|
// for all of them. A verified input holds only the target's dependency graph.
|
|
@@ -33,7 +36,7 @@ export async function reconstructLayout(source, solc, onchainCode) {
|
|
|
33
36
|
contract,
|
|
34
37
|
compiler: source.solcLongVersion,
|
|
35
38
|
bytecodeMatch,
|
|
36
|
-
|
|
39
|
+
...(await analyze(input, output, solc, contract)),
|
|
37
40
|
};
|
|
38
41
|
}
|
|
39
42
|
/**
|
|
@@ -42,11 +45,36 @@ export async function reconstructLayout(source, solc, onchainCode) {
|
|
|
42
45
|
* project's own build-info.
|
|
43
46
|
*/
|
|
44
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
|
+
export async function analyzeSource(input, solc, contract) {
|
|
45
53
|
const selected = withOutputSelection(input, FULL_SELECTION);
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
return analyze(selected, await compileOrThrow(solc, selected, "source"), solc, contract);
|
|
55
|
+
}
|
|
56
|
+
async function analyze(input, output, solc, contract) {
|
|
57
|
+
const { data, version } = await validateContract(input, output, solc, contract);
|
|
58
|
+
const layout = getStorageLayout(data, version);
|
|
59
|
+
return {
|
|
60
|
+
layout,
|
|
61
|
+
// Typed as any ProxyKind, but only ever uups or transparent.
|
|
62
|
+
kind: inferProxyKind(data, version),
|
|
63
|
+
namespaces: namespaceSlots(output, contract, Object.keys(layout.namespaces ?? {})),
|
|
64
|
+
safety({ kind, unsafeAllow = [] }) {
|
|
65
|
+
// A copy: OpenZeppelin appends to the array it is given.
|
|
66
|
+
const opts = { kind, unsafeAllow: [...unsafeAllow] };
|
|
67
|
+
// The deprecated kinds are never reported, so every error has a SafetyErrorKind.
|
|
68
|
+
const errors = getErrors(data, version, opts);
|
|
69
|
+
return {
|
|
70
|
+
ok: errors.length === 0,
|
|
71
|
+
errors,
|
|
72
|
+
explain: () => new UpgradeableContractErrorReport(errors).explain(),
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
};
|
|
48
76
|
}
|
|
49
|
-
async function
|
|
77
|
+
async function validateContract(input, output, solc, contract) {
|
|
50
78
|
const solcVersion = solc.longVersion.split("+")[0];
|
|
51
79
|
let namespacedOutput;
|
|
52
80
|
if (isNamespaceSupported(solcVersion)) {
|
|
@@ -57,12 +85,13 @@ async function extractLayout(input, output, solc, contract) {
|
|
|
57
85
|
const runData = validate(output, solcInputOutputDecoder(input, output), solcVersion, input, namespacedOutput);
|
|
58
86
|
const version = runData[contract]?.version;
|
|
59
87
|
if (version === undefined) {
|
|
60
|
-
throw new LayoutIntegrityError(`${contract} compiled to no bytecode
|
|
88
|
+
throw new LayoutIntegrityError(`${contract} compiled to no bytecode (an abstract contract or interface?); ` +
|
|
89
|
+
`cannot derive its layout.`);
|
|
61
90
|
}
|
|
62
91
|
// OZ looks the contract up by bytecode version and takes the first match, so
|
|
63
92
|
// two contracts with identical code (possible without a source hash) could
|
|
64
|
-
// swap layouts. Listing the target first makes
|
|
65
|
-
return
|
|
93
|
+
// swap layouts or safety errors. Listing the target first makes every lookup land on it.
|
|
94
|
+
return { data: { [contract]: runData[contract], ...runData }, version };
|
|
66
95
|
}
|
|
67
96
|
/**
|
|
68
97
|
* Finds the compiled contract that matches the deployed code. The verified
|