glamsterdam-compat-lab 0.2.2
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/CONTRIBUTING.md +59 -0
- package/LICENSE +21 -0
- package/README.md +187 -0
- package/ROADMAP.md +76 -0
- package/SECURITY.md +19 -0
- package/data/client-compat/clients.example.json +42 -0
- package/data/detectors/thresholds.ci.json +33 -0
- package/data/detectors/thresholds.json +33 -0
- package/data/detectors/thresholds.research.json +33 -0
- package/data/eips/glamsterdam.json +85 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +163 -0
- package/dist/cli.js.map +1 -0
- package/dist/detectors/balDetectors.d.ts +3 -0
- package/dist/detectors/balDetectors.js +26 -0
- package/dist/detectors/balDetectors.js.map +1 -0
- package/dist/detectors/contractSizeDetectors.d.ts +3 -0
- package/dist/detectors/contractSizeDetectors.js +37 -0
- package/dist/detectors/contractSizeDetectors.js.map +1 -0
- package/dist/detectors/epbsDetectors.d.ts +7 -0
- package/dist/detectors/epbsDetectors.js +33 -0
- package/dist/detectors/epbsDetectors.js.map +1 -0
- package/dist/detectors/gasRepricingDetectors.d.ts +4 -0
- package/dist/detectors/gasRepricingDetectors.js +135 -0
- package/dist/detectors/gasRepricingDetectors.js.map +1 -0
- package/dist/detectors/nativeEthTransferLogDetectors.d.ts +8 -0
- package/dist/detectors/nativeEthTransferLogDetectors.js +54 -0
- package/dist/detectors/nativeEthTransferLogDetectors.js.map +1 -0
- package/dist/detectors/stateCreationDetectors.d.ts +4 -0
- package/dist/detectors/stateCreationDetectors.js +46 -0
- package/dist/detectors/stateCreationDetectors.js.map +1 -0
- package/dist/detectors/thresholds.d.ts +34 -0
- package/dist/detectors/thresholds.js +45 -0
- package/dist/detectors/thresholds.js.map +1 -0
- package/dist/detectors/types.d.ts +15 -0
- package/dist/detectors/types.js +23 -0
- package/dist/detectors/types.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/registry/eipRegistry.d.ts +6 -0
- package/dist/registry/eipRegistry.js +30 -0
- package/dist/registry/eipRegistry.js.map +1 -0
- package/dist/registry/schemas.d.ts +76 -0
- package/dist/registry/schemas.js +34 -0
- package/dist/registry/schemas.js.map +1 -0
- package/dist/reports/jsonReporter.d.ts +2 -0
- package/dist/reports/jsonReporter.js +5 -0
- package/dist/reports/jsonReporter.js.map +1 -0
- package/dist/reports/markdownReporter.d.ts +2 -0
- package/dist/reports/markdownReporter.js +75 -0
- package/dist/reports/markdownReporter.js.map +1 -0
- package/dist/reports/reportTypes.d.ts +150 -0
- package/dist/reports/reportTypes.js +111 -0
- package/dist/reports/reportTypes.js.map +1 -0
- package/dist/scanners/bytecodeScanner.d.ts +11 -0
- package/dist/scanners/bytecodeScanner.js +107 -0
- package/dist/scanners/bytecodeScanner.js.map +1 -0
- package/dist/scanners/indexerScanner.d.ts +13 -0
- package/dist/scanners/indexerScanner.js +129 -0
- package/dist/scanners/indexerScanner.js.map +1 -0
- package/dist/scanners/rpcTraceScanner.d.ts +40 -0
- package/dist/scanners/rpcTraceScanner.js +121 -0
- package/dist/scanners/rpcTraceScanner.js.map +1 -0
- package/dist/scanners/traceScanner.d.ts +24 -0
- package/dist/scanners/traceScanner.js +272 -0
- package/dist/scanners/traceScanner.js.map +1 -0
- package/dist/scanners/validatorScanner.d.ts +40 -0
- package/dist/scanners/validatorScanner.js +210 -0
- package/dist/scanners/validatorScanner.js.map +1 -0
- package/dist/utils/bytecode.d.ts +11 -0
- package/dist/utils/bytecode.js +140 -0
- package/dist/utils/bytecode.js.map +1 -0
- package/dist/utils/files.d.ts +10 -0
- package/dist/utils/files.js +51 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/severity.d.ts +2 -0
- package/dist/utils/severity.js +13 -0
- package/dist/utils/severity.js.map +1 -0
- package/docs/fixtures.md +60 -0
- package/docs/release.md +132 -0
- package/examples/storage-heavy-bytecode.md +57 -0
- package/fixtures/bytecode/storage-heavy.hex +1 -0
- package/fixtures/indexers/balance-diff-indexer.json +15 -0
- package/fixtures/indexers/subgraph.yaml +24 -0
- package/fixtures/traces/besu-debug-structlogs.json +18 -0
- package/fixtures/traces/call-tracer-tree.json +27 -0
- package/fixtures/traces/drpc-call-tracer-real.json +373 -0
- package/fixtures/traces/erigon-action-trace.json +29 -0
- package/fixtures/traces/foundry-json-trace.json +19 -0
- package/fixtures/traces/geth-json-rpc-structlogs.json +16 -0
- package/fixtures/traces/hardhat-debug-trace.json +13 -0
- package/fixtures/traces/nethermind-debug-structlogs.json +17 -0
- package/fixtures/traces/storage-heavy-trace.json +25 -0
- package/fixtures/validator/operator-config.yaml +15 -0
- package/package.json +80 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
export const detectorThresholdsSchema = z.object({
|
|
7
|
+
schemaVersion: z.number().int().positive(),
|
|
8
|
+
profile: z.string().min(1).optional(),
|
|
9
|
+
lastUpdated: z.string().min(1),
|
|
10
|
+
notes: z.array(z.string()).default([]),
|
|
11
|
+
bytecode: z.object({
|
|
12
|
+
contractSize: z.object({
|
|
13
|
+
currentRuntimeLimitBytes: z.number().int().positive(),
|
|
14
|
+
nearCurrentLimitBytes: z.number().int().positive()
|
|
15
|
+
}),
|
|
16
|
+
stateAccountOpcodeExposure: z.object({
|
|
17
|
+
mediumSensitiveOpcodeCount: z.number().int().positive(),
|
|
18
|
+
lowSensitiveOpcodeCount: z.number().int().positive()
|
|
19
|
+
}),
|
|
20
|
+
storagePattern: z.object({
|
|
21
|
+
mediumStorageOpcodeCount: z.number().int().positive()
|
|
22
|
+
})
|
|
23
|
+
}),
|
|
24
|
+
trace: z.object({
|
|
25
|
+
stateHeavyExecution: z.object({
|
|
26
|
+
highStorageOps: z.number().int().positive(),
|
|
27
|
+
highSensitiveOpcodeCount: z.number().int().positive(),
|
|
28
|
+
mediumStorageOps: z.number().int().positive(),
|
|
29
|
+
mediumSensitiveOpcodeCount: z.number().int().positive()
|
|
30
|
+
}),
|
|
31
|
+
calldataHeavy: z.object({
|
|
32
|
+
mediumCalldataBytes: z.number().int().positive()
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
});
|
|
36
|
+
export function defaultThresholdsPath() {
|
|
37
|
+
return resolve(moduleDir, "../../data/detectors/thresholds.json");
|
|
38
|
+
}
|
|
39
|
+
export function loadDetectorThresholds(thresholdsPath = defaultThresholdsPath()) {
|
|
40
|
+
if (!existsSync(thresholdsPath)) {
|
|
41
|
+
throw new Error(`Detector thresholds not found: ${thresholdsPath}`);
|
|
42
|
+
}
|
|
43
|
+
return detectorThresholdsSchema.parse(JSON.parse(readFileSync(thresholdsPath, "utf8")));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=thresholds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thresholds.js","sourceRoot":"","sources":["../../src/detectors/thresholds.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;IAC1C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IACrC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC;QACjB,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC;YACrB,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YACrD,qBAAqB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;SACnD,CAAC;QACF,0BAA0B,EAAE,CAAC,CAAC,MAAM,CAAC;YACnC,0BAA0B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YACvD,uBAAuB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;SACrD,CAAC;QACF,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC;YACvB,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;SACtD,CAAC;KACH,CAAC;IACF,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;QACd,mBAAmB,EAAE,CAAC,CAAC,MAAM,CAAC;YAC5B,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YAC3C,wBAAwB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YACrD,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;YAC7C,0BAA0B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;SACxD,CAAC;QACF,aAAa,EAAE,CAAC,CAAC,MAAM,CAAC;YACtB,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;SACjD,CAAC;KACH,CAAC;CACH,CAAC,CAAC;AAIH,MAAM,UAAU,qBAAqB;IACnC,OAAO,OAAO,CAAC,SAAS,EAAE,sCAAsC,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,cAAc,GAAG,qBAAqB,EAAE;IAC7E,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,kCAAkC,cAAc,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { EipRegistry } from "../registry/schemas.js";
|
|
2
|
+
import type { CompatibilityFinding, ReportDomain } from "../reports/reportTypes.js";
|
|
3
|
+
import type { DetectorThresholds } from "./thresholds.js";
|
|
4
|
+
export type FindingInput = Omit<CompatibilityFinding, "relatedEips" | "evidence"> & {
|
|
5
|
+
relatedEips?: string[];
|
|
6
|
+
evidence?: unknown[] | unknown;
|
|
7
|
+
};
|
|
8
|
+
export interface DetectorContext {
|
|
9
|
+
registry: EipRegistry;
|
|
10
|
+
targetName: string;
|
|
11
|
+
thresholds: DetectorThresholds;
|
|
12
|
+
}
|
|
13
|
+
export declare function relatedEipsForDetector(registry: EipRegistry, detectorName: string, preferredIds?: string[]): string[];
|
|
14
|
+
export declare function makeFinding(input: FindingInput): CompatibilityFinding;
|
|
15
|
+
export declare function domains(...domains: ReportDomain[]): ReportDomain[];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export function relatedEipsForDetector(registry, detectorName, preferredIds = []) {
|
|
2
|
+
const registryIds = registry.eips
|
|
3
|
+
.filter((entry) => entry.detectors.includes(detectorName))
|
|
4
|
+
.map((entry) => entry.id);
|
|
5
|
+
const knownIds = new Set(registry.eips.map((entry) => entry.id));
|
|
6
|
+
return [...new Set([...preferredIds.filter((id) => knownIds.has(id)), ...registryIds])];
|
|
7
|
+
}
|
|
8
|
+
export function makeFinding(input) {
|
|
9
|
+
const evidence = input.evidence === undefined
|
|
10
|
+
? []
|
|
11
|
+
: Array.isArray(input.evidence)
|
|
12
|
+
? input.evidence
|
|
13
|
+
: [input.evidence];
|
|
14
|
+
return {
|
|
15
|
+
...input,
|
|
16
|
+
evidence,
|
|
17
|
+
relatedEips: input.relatedEips ?? []
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function domains(...domains) {
|
|
21
|
+
return domains;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/detectors/types.ts"],"names":[],"mappings":"AAeA,MAAM,UAAU,sBAAsB,CACpC,QAAqB,EACrB,YAAoB,EACpB,eAAyB,EAAE;IAE3B,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI;SAC9B,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;SACzD,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5B,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAmB;IAC7C,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,KAAK,SAAS;QAC3C,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC7B,CAAC,CAAC,KAAK,CAAC,QAAQ;YAChB,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEvB,OAAO;QACL,GAAG,KAAK;QACR,QAAQ;QACR,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAG,OAAuB;IAChD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { loadEipRegistry, defaultRegistryPath } from "./registry/eipRegistry.js";
|
|
2
|
+
export type { EipEntry, EipRegistry, EipStatus, EipDomain } from "./registry/schemas.js";
|
|
3
|
+
export { scanBytecode } from "./scanners/bytecodeScanner.js";
|
|
4
|
+
export { scanTrace, scanTraceFile, normalizeTrace } from "./scanners/traceScanner.js";
|
|
5
|
+
export { fetchAndScanTransactionTrace, fetchDebugTraceTransaction, normalizeTxHash, parseDebugTraceMode, scanFetchedTransactionTrace, scanTransactionTrace } from "./scanners/rpcTraceScanner.js";
|
|
6
|
+
export { writeFetchedTrace } from "./scanners/rpcTraceScanner.js";
|
|
7
|
+
export type { DebugTraceMode, FetchDebugTraceOptions, RpcFetch, ScannedTransactionTrace, ScanTransactionTraceOptions } from "./scanners/rpcTraceScanner.js";
|
|
8
|
+
export { scanIndexer, summarizeHandlers } from "./scanners/indexerScanner.js";
|
|
9
|
+
export { scanValidatorConfig, defaultClientMatrixPath } from "./scanners/validatorScanner.js";
|
|
10
|
+
export { loadDetectorThresholds, defaultThresholdsPath, detectorThresholdsSchema } from "./detectors/thresholds.js";
|
|
11
|
+
export type { DetectorThresholds } from "./detectors/thresholds.js";
|
|
12
|
+
export { compatibilityReportSchema, findingSchema, makeReport, summarizeFindings, validateCompatibilityReport, combineReports } from "./reports/reportTypes.js";
|
|
13
|
+
export type { CompatibilityFinding, CompatibilityReport, Confidence, ReportDomain, Severity, TargetKind } from "./reports/reportTypes.js";
|
|
14
|
+
export { renderJsonReport } from "./reports/jsonReporter.js";
|
|
15
|
+
export { renderMarkdownReport } from "./reports/markdownReporter.js";
|
|
16
|
+
export { normalizeBytecode, disassembleBytecode, countOpcodeNames, byteLength, opcodeCount } from "./utils/bytecode.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { loadEipRegistry, defaultRegistryPath } from "./registry/eipRegistry.js";
|
|
2
|
+
export { scanBytecode } from "./scanners/bytecodeScanner.js";
|
|
3
|
+
export { scanTrace, scanTraceFile, normalizeTrace } from "./scanners/traceScanner.js";
|
|
4
|
+
export { fetchAndScanTransactionTrace, fetchDebugTraceTransaction, normalizeTxHash, parseDebugTraceMode, scanFetchedTransactionTrace, scanTransactionTrace } from "./scanners/rpcTraceScanner.js";
|
|
5
|
+
export { writeFetchedTrace } from "./scanners/rpcTraceScanner.js";
|
|
6
|
+
export { scanIndexer, summarizeHandlers } from "./scanners/indexerScanner.js";
|
|
7
|
+
export { scanValidatorConfig, defaultClientMatrixPath } from "./scanners/validatorScanner.js";
|
|
8
|
+
export { loadDetectorThresholds, defaultThresholdsPath, detectorThresholdsSchema } from "./detectors/thresholds.js";
|
|
9
|
+
export { compatibilityReportSchema, findingSchema, makeReport, summarizeFindings, validateCompatibilityReport, combineReports } from "./reports/reportTypes.js";
|
|
10
|
+
export { renderJsonReport } from "./reports/jsonReporter.js";
|
|
11
|
+
export { renderMarkdownReport } from "./reports/markdownReporter.js";
|
|
12
|
+
export { normalizeBytecode, disassembleBytecode, countOpcodeNames, byteLength, opcodeCount } from "./utils/bytecode.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAGjF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,EAC1B,eAAe,EACf,mBAAmB,EACnB,2BAA2B,EAC3B,oBAAoB,EACrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAQlE,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAGpH,OAAO,EACL,yBAAyB,EACzB,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,cAAc,EACf,MAAM,0BAA0B,CAAC;AAUlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAErE,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,UAAU,EACV,WAAW,EACZ,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type EipEntry, type EipRegistry } from "./schemas.js";
|
|
2
|
+
export declare function defaultRegistryPath(): string;
|
|
3
|
+
export declare function loadEipRegistry(registryPath?: string): EipRegistry;
|
|
4
|
+
export declare function eipsForDetector(registry: EipRegistry, detectorName: string): EipEntry[];
|
|
5
|
+
export declare function findEip(registry: EipRegistry, id: string): EipEntry | undefined;
|
|
6
|
+
export declare function activeOrConsideredEipIds(registry: EipRegistry, ids: string[]): string[];
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, resolve } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { eipRegistrySchema } from "./schemas.js";
|
|
5
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
export function defaultRegistryPath() {
|
|
7
|
+
return resolve(moduleDir, "../../data/eips/glamsterdam.json");
|
|
8
|
+
}
|
|
9
|
+
export function loadEipRegistry(registryPath = defaultRegistryPath()) {
|
|
10
|
+
if (!existsSync(registryPath)) {
|
|
11
|
+
throw new Error(`EIP registry not found: ${registryPath}`);
|
|
12
|
+
}
|
|
13
|
+
const raw = readFileSync(registryPath, "utf8");
|
|
14
|
+
const parsed = JSON.parse(raw);
|
|
15
|
+
return eipRegistrySchema.parse(parsed);
|
|
16
|
+
}
|
|
17
|
+
export function eipsForDetector(registry, detectorName) {
|
|
18
|
+
return registry.eips.filter((entry) => entry.detectors.includes(detectorName));
|
|
19
|
+
}
|
|
20
|
+
export function findEip(registry, id) {
|
|
21
|
+
return registry.eips.find((entry) => entry.id === id);
|
|
22
|
+
}
|
|
23
|
+
export function activeOrConsideredEipIds(registry, ids) {
|
|
24
|
+
const usableStatuses = new Set(["scheduled", "considered"]);
|
|
25
|
+
return ids.filter((id) => {
|
|
26
|
+
const entry = findEip(registry, id);
|
|
27
|
+
return entry ? usableStatuses.has(entry.status) : false;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=eipRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eipRegistry.js","sourceRoot":"","sources":["../../src/registry/eipRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAmC,MAAM,cAAc,CAAC;AAElF,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,MAAM,UAAU,mBAAmB;IACjC,OAAO,OAAO,CAAC,SAAS,EAAE,kCAAkC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,YAAY,GAAG,mBAAmB,EAAE;IAClE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,QAAqB,EAAE,YAAoB;IACzE,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,QAAqB,EAAE,EAAU;IACvD,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,QAAqB,EAAE,GAAa;IAC3E,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;QACvB,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QACpC,OAAO,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const eipStatusSchema: z.ZodEnum<{
|
|
3
|
+
scheduled: "scheduled";
|
|
4
|
+
considered: "considered";
|
|
5
|
+
declined: "declined";
|
|
6
|
+
superseded: "superseded";
|
|
7
|
+
unknown: "unknown";
|
|
8
|
+
}>;
|
|
9
|
+
export declare const eipDomainSchema: z.ZodEnum<{
|
|
10
|
+
execution: "execution";
|
|
11
|
+
consensus: "consensus";
|
|
12
|
+
networking: "networking";
|
|
13
|
+
tooling: "tooling";
|
|
14
|
+
monitoring: "monitoring";
|
|
15
|
+
indexer: "indexer";
|
|
16
|
+
validator: "validator";
|
|
17
|
+
builder: "builder";
|
|
18
|
+
contracts: "contracts";
|
|
19
|
+
}>;
|
|
20
|
+
export declare const eipEntrySchema: z.ZodObject<{
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
name: z.ZodString;
|
|
23
|
+
status: z.ZodEnum<{
|
|
24
|
+
scheduled: "scheduled";
|
|
25
|
+
considered: "considered";
|
|
26
|
+
declined: "declined";
|
|
27
|
+
superseded: "superseded";
|
|
28
|
+
unknown: "unknown";
|
|
29
|
+
}>;
|
|
30
|
+
domain: z.ZodArray<z.ZodEnum<{
|
|
31
|
+
execution: "execution";
|
|
32
|
+
consensus: "consensus";
|
|
33
|
+
networking: "networking";
|
|
34
|
+
tooling: "tooling";
|
|
35
|
+
monitoring: "monitoring";
|
|
36
|
+
indexer: "indexer";
|
|
37
|
+
validator: "validator";
|
|
38
|
+
builder: "builder";
|
|
39
|
+
contracts: "contracts";
|
|
40
|
+
}>>;
|
|
41
|
+
detectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
42
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
export declare const eipRegistrySchema: z.ZodObject<{
|
|
45
|
+
fork: z.ZodString;
|
|
46
|
+
lastUpdated: z.ZodString;
|
|
47
|
+
sources: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
48
|
+
eips: z.ZodArray<z.ZodObject<{
|
|
49
|
+
id: z.ZodString;
|
|
50
|
+
name: z.ZodString;
|
|
51
|
+
status: z.ZodEnum<{
|
|
52
|
+
scheduled: "scheduled";
|
|
53
|
+
considered: "considered";
|
|
54
|
+
declined: "declined";
|
|
55
|
+
superseded: "superseded";
|
|
56
|
+
unknown: "unknown";
|
|
57
|
+
}>;
|
|
58
|
+
domain: z.ZodArray<z.ZodEnum<{
|
|
59
|
+
execution: "execution";
|
|
60
|
+
consensus: "consensus";
|
|
61
|
+
networking: "networking";
|
|
62
|
+
tooling: "tooling";
|
|
63
|
+
monitoring: "monitoring";
|
|
64
|
+
indexer: "indexer";
|
|
65
|
+
validator: "validator";
|
|
66
|
+
builder: "builder";
|
|
67
|
+
contracts: "contracts";
|
|
68
|
+
}>>;
|
|
69
|
+
detectors: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
70
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
71
|
+
}, z.core.$strip>>;
|
|
72
|
+
}, z.core.$strip>;
|
|
73
|
+
export type EipStatus = z.infer<typeof eipStatusSchema>;
|
|
74
|
+
export type EipDomain = z.infer<typeof eipDomainSchema>;
|
|
75
|
+
export type EipEntry = z.infer<typeof eipEntrySchema>;
|
|
76
|
+
export type EipRegistry = z.infer<typeof eipRegistrySchema>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const eipStatusSchema = z.enum([
|
|
3
|
+
"scheduled",
|
|
4
|
+
"considered",
|
|
5
|
+
"declined",
|
|
6
|
+
"superseded",
|
|
7
|
+
"unknown"
|
|
8
|
+
]);
|
|
9
|
+
export const eipDomainSchema = z.enum([
|
|
10
|
+
"execution",
|
|
11
|
+
"consensus",
|
|
12
|
+
"networking",
|
|
13
|
+
"tooling",
|
|
14
|
+
"monitoring",
|
|
15
|
+
"indexer",
|
|
16
|
+
"validator",
|
|
17
|
+
"builder",
|
|
18
|
+
"contracts"
|
|
19
|
+
]);
|
|
20
|
+
export const eipEntrySchema = z.object({
|
|
21
|
+
id: z.string().min(1),
|
|
22
|
+
name: z.string().min(1),
|
|
23
|
+
status: eipStatusSchema,
|
|
24
|
+
domain: z.array(eipDomainSchema).min(1),
|
|
25
|
+
detectors: z.array(z.string()).default([]),
|
|
26
|
+
notes: z.string().optional()
|
|
27
|
+
});
|
|
28
|
+
export const eipRegistrySchema = z.object({
|
|
29
|
+
fork: z.string().min(1),
|
|
30
|
+
lastUpdated: z.string().min(1),
|
|
31
|
+
sources: z.array(z.string().url()).default([]),
|
|
32
|
+
eips: z.array(eipEntrySchema)
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/registry/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC;IACpC,WAAW;IACX,YAAY;IACZ,UAAU;IACV,YAAY;IACZ,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,IAAI,CAAC;IACpC,WAAW;IACX,WAAW;IACX,YAAY;IACZ,SAAS;IACT,YAAY;IACZ,SAAS;IACT,WAAW;IACX,SAAS;IACT,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,MAAM,EAAE,eAAe;IACvB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACvC,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IAC9C,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC;CAC9B,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonReporter.js","sourceRoot":"","sources":["../../src/reports/jsonReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAA4B,MAAM,kBAAkB,CAAC;AAEvF,MAAM,UAAU,gBAAgB,CAAC,MAA2B;IAC1D,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;AACjF,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export function renderMarkdownReport(report) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
lines.push("# Glamsterdam Compatibility Report");
|
|
4
|
+
lines.push("");
|
|
5
|
+
lines.push(`Target: ${report.target.kind} ${report.target.name}`);
|
|
6
|
+
lines.push(`Tool version: ${report.toolVersion}`);
|
|
7
|
+
lines.push(`Fork registry: ${report.fork}`);
|
|
8
|
+
lines.push("");
|
|
9
|
+
lines.push("## Summary");
|
|
10
|
+
lines.push("");
|
|
11
|
+
lines.push(`Overall risk: ${formatInlineSeverity(report.summary.risk)}`);
|
|
12
|
+
lines.push(`Findings: ${report.summary.findingCount} total, ${report.summary.highCount} high, ${report.summary.mediumCount} medium, ${report.summary.lowCount} low, ${report.summary.unknownCount} unknown`);
|
|
13
|
+
lines.push("");
|
|
14
|
+
lines.push("## Findings");
|
|
15
|
+
lines.push("");
|
|
16
|
+
if (report.findings.length === 0) {
|
|
17
|
+
lines.push("No findings were produced by this scanner.");
|
|
18
|
+
lines.push("");
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
report.findings.forEach((finding, index) => {
|
|
22
|
+
lines.push(renderFinding(finding, index + 1));
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
lines.push("## Assumptions");
|
|
26
|
+
lines.push("");
|
|
27
|
+
pushList(lines, report.assumptions, "No explicit assumptions were recorded.");
|
|
28
|
+
lines.push("");
|
|
29
|
+
lines.push("## Limitations");
|
|
30
|
+
lines.push("");
|
|
31
|
+
pushList(lines, report.limitations, "No limitations were recorded.");
|
|
32
|
+
lines.push("");
|
|
33
|
+
return `${lines.join("\n")}\n`;
|
|
34
|
+
}
|
|
35
|
+
function renderFinding(finding, index) {
|
|
36
|
+
const lines = [];
|
|
37
|
+
lines.push(`### ${index}. ${finding.title}`);
|
|
38
|
+
lines.push("");
|
|
39
|
+
lines.push(`Severity: ${formatInlineSeverity(finding.severity)}`);
|
|
40
|
+
lines.push(`Confidence: ${finding.confidence}`);
|
|
41
|
+
lines.push(`Domains: ${finding.domain.join(", ")}`);
|
|
42
|
+
lines.push(`Related EIPs: ${finding.relatedEips.length > 0 ? finding.relatedEips.join(", ") : "none"}`);
|
|
43
|
+
lines.push("");
|
|
44
|
+
lines.push(finding.description);
|
|
45
|
+
lines.push("");
|
|
46
|
+
if (finding.evidence.length > 0) {
|
|
47
|
+
lines.push("Evidence:");
|
|
48
|
+
for (const item of finding.evidence) {
|
|
49
|
+
lines.push(`- ${formatEvidence(item)}`);
|
|
50
|
+
}
|
|
51
|
+
lines.push("");
|
|
52
|
+
}
|
|
53
|
+
lines.push(`Recommendation: ${finding.recommendation}`);
|
|
54
|
+
lines.push("");
|
|
55
|
+
return lines.join("\n");
|
|
56
|
+
}
|
|
57
|
+
function pushList(lines, items, emptyText) {
|
|
58
|
+
if (items.length === 0) {
|
|
59
|
+
lines.push(emptyText);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
for (const item of items) {
|
|
63
|
+
lines.push(`- ${item}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function formatEvidence(item) {
|
|
67
|
+
if (typeof item === "string") {
|
|
68
|
+
return item;
|
|
69
|
+
}
|
|
70
|
+
return JSON.stringify(item);
|
|
71
|
+
}
|
|
72
|
+
function formatInlineSeverity(value) {
|
|
73
|
+
return value.toUpperCase();
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=markdownReporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdownReporter.js","sourceRoot":"","sources":["../../src/reports/markdownReporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const TOOL_VERSION = "0.2.2";
|
|
3
|
+
export declare const severitySchema: z.ZodEnum<{
|
|
4
|
+
unknown: "unknown";
|
|
5
|
+
low: "low";
|
|
6
|
+
medium: "medium";
|
|
7
|
+
high: "high";
|
|
8
|
+
}>;
|
|
9
|
+
export declare const confidenceSchema: z.ZodEnum<{
|
|
10
|
+
low: "low";
|
|
11
|
+
medium: "medium";
|
|
12
|
+
high: "high";
|
|
13
|
+
}>;
|
|
14
|
+
export declare const reportDomainSchema: z.ZodEnum<{
|
|
15
|
+
execution: "execution";
|
|
16
|
+
consensus: "consensus";
|
|
17
|
+
networking: "networking";
|
|
18
|
+
tooling: "tooling";
|
|
19
|
+
monitoring: "monitoring";
|
|
20
|
+
indexer: "indexer";
|
|
21
|
+
validator: "validator";
|
|
22
|
+
builder: "builder";
|
|
23
|
+
contracts: "contracts";
|
|
24
|
+
}>;
|
|
25
|
+
export declare const targetKindSchema: z.ZodEnum<{
|
|
26
|
+
indexer: "indexer";
|
|
27
|
+
validator: "validator";
|
|
28
|
+
bytecode: "bytecode";
|
|
29
|
+
trace: "trace";
|
|
30
|
+
combined: "combined";
|
|
31
|
+
}>;
|
|
32
|
+
export declare const findingSchema: z.ZodObject<{
|
|
33
|
+
id: z.ZodString;
|
|
34
|
+
title: z.ZodString;
|
|
35
|
+
severity: z.ZodEnum<{
|
|
36
|
+
unknown: "unknown";
|
|
37
|
+
low: "low";
|
|
38
|
+
medium: "medium";
|
|
39
|
+
high: "high";
|
|
40
|
+
}>;
|
|
41
|
+
confidence: z.ZodEnum<{
|
|
42
|
+
low: "low";
|
|
43
|
+
medium: "medium";
|
|
44
|
+
high: "high";
|
|
45
|
+
}>;
|
|
46
|
+
domain: z.ZodArray<z.ZodEnum<{
|
|
47
|
+
execution: "execution";
|
|
48
|
+
consensus: "consensus";
|
|
49
|
+
networking: "networking";
|
|
50
|
+
tooling: "tooling";
|
|
51
|
+
monitoring: "monitoring";
|
|
52
|
+
indexer: "indexer";
|
|
53
|
+
validator: "validator";
|
|
54
|
+
builder: "builder";
|
|
55
|
+
contracts: "contracts";
|
|
56
|
+
}>>;
|
|
57
|
+
relatedEips: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
58
|
+
description: z.ZodString;
|
|
59
|
+
evidence: z.ZodDefault<z.ZodArray<z.ZodUnknown>>;
|
|
60
|
+
recommendation: z.ZodString;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export declare const reportSummarySchema: z.ZodObject<{
|
|
63
|
+
risk: z.ZodEnum<{
|
|
64
|
+
unknown: "unknown";
|
|
65
|
+
low: "low";
|
|
66
|
+
medium: "medium";
|
|
67
|
+
high: "high";
|
|
68
|
+
}>;
|
|
69
|
+
findingCount: z.ZodNumber;
|
|
70
|
+
highCount: z.ZodNumber;
|
|
71
|
+
mediumCount: z.ZodNumber;
|
|
72
|
+
lowCount: z.ZodNumber;
|
|
73
|
+
unknownCount: z.ZodNumber;
|
|
74
|
+
}, z.core.$strip>;
|
|
75
|
+
export declare const compatibilityReportSchema: z.ZodObject<{
|
|
76
|
+
toolVersion: z.ZodString;
|
|
77
|
+
fork: z.ZodString;
|
|
78
|
+
target: z.ZodObject<{
|
|
79
|
+
kind: z.ZodEnum<{
|
|
80
|
+
indexer: "indexer";
|
|
81
|
+
validator: "validator";
|
|
82
|
+
bytecode: "bytecode";
|
|
83
|
+
trace: "trace";
|
|
84
|
+
combined: "combined";
|
|
85
|
+
}>;
|
|
86
|
+
name: z.ZodString;
|
|
87
|
+
}, z.core.$strip>;
|
|
88
|
+
summary: z.ZodObject<{
|
|
89
|
+
risk: z.ZodEnum<{
|
|
90
|
+
unknown: "unknown";
|
|
91
|
+
low: "low";
|
|
92
|
+
medium: "medium";
|
|
93
|
+
high: "high";
|
|
94
|
+
}>;
|
|
95
|
+
findingCount: z.ZodNumber;
|
|
96
|
+
highCount: z.ZodNumber;
|
|
97
|
+
mediumCount: z.ZodNumber;
|
|
98
|
+
lowCount: z.ZodNumber;
|
|
99
|
+
unknownCount: z.ZodNumber;
|
|
100
|
+
}, z.core.$strip>;
|
|
101
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
102
|
+
id: z.ZodString;
|
|
103
|
+
title: z.ZodString;
|
|
104
|
+
severity: z.ZodEnum<{
|
|
105
|
+
unknown: "unknown";
|
|
106
|
+
low: "low";
|
|
107
|
+
medium: "medium";
|
|
108
|
+
high: "high";
|
|
109
|
+
}>;
|
|
110
|
+
confidence: z.ZodEnum<{
|
|
111
|
+
low: "low";
|
|
112
|
+
medium: "medium";
|
|
113
|
+
high: "high";
|
|
114
|
+
}>;
|
|
115
|
+
domain: z.ZodArray<z.ZodEnum<{
|
|
116
|
+
execution: "execution";
|
|
117
|
+
consensus: "consensus";
|
|
118
|
+
networking: "networking";
|
|
119
|
+
tooling: "tooling";
|
|
120
|
+
monitoring: "monitoring";
|
|
121
|
+
indexer: "indexer";
|
|
122
|
+
validator: "validator";
|
|
123
|
+
builder: "builder";
|
|
124
|
+
contracts: "contracts";
|
|
125
|
+
}>>;
|
|
126
|
+
relatedEips: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
127
|
+
description: z.ZodString;
|
|
128
|
+
evidence: z.ZodDefault<z.ZodArray<z.ZodUnknown>>;
|
|
129
|
+
recommendation: z.ZodString;
|
|
130
|
+
}, z.core.$strip>>;
|
|
131
|
+
assumptions: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
132
|
+
limitations: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
133
|
+
}, z.core.$strip>;
|
|
134
|
+
export type Severity = z.infer<typeof severitySchema>;
|
|
135
|
+
export type Confidence = z.infer<typeof confidenceSchema>;
|
|
136
|
+
export type ReportDomain = z.infer<typeof reportDomainSchema>;
|
|
137
|
+
export type TargetKind = z.infer<typeof targetKindSchema>;
|
|
138
|
+
export type CompatibilityFinding = z.infer<typeof findingSchema>;
|
|
139
|
+
export type CompatibilityReport = z.infer<typeof compatibilityReportSchema>;
|
|
140
|
+
export interface MakeReportInput {
|
|
141
|
+
fork?: string;
|
|
142
|
+
target: CompatibilityReport["target"];
|
|
143
|
+
findings: CompatibilityFinding[];
|
|
144
|
+
assumptions?: string[];
|
|
145
|
+
limitations?: string[];
|
|
146
|
+
}
|
|
147
|
+
export declare function summarizeFindings(findings: CompatibilityFinding[]): CompatibilityReport["summary"];
|
|
148
|
+
export declare function makeReport(input: MakeReportInput): CompatibilityReport;
|
|
149
|
+
export declare function validateCompatibilityReport(value: unknown): CompatibilityReport;
|
|
150
|
+
export declare function combineReports(reports: CompatibilityReport[]): CompatibilityReport;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const TOOL_VERSION = "0.2.2";
|
|
3
|
+
export const severitySchema = z.enum(["low", "medium", "high", "unknown"]);
|
|
4
|
+
export const confidenceSchema = z.enum(["low", "medium", "high"]);
|
|
5
|
+
export const reportDomainSchema = z.enum([
|
|
6
|
+
"contracts",
|
|
7
|
+
"indexer",
|
|
8
|
+
"validator",
|
|
9
|
+
"monitoring",
|
|
10
|
+
"execution",
|
|
11
|
+
"consensus",
|
|
12
|
+
"networking",
|
|
13
|
+
"builder",
|
|
14
|
+
"tooling"
|
|
15
|
+
]);
|
|
16
|
+
export const targetKindSchema = z.enum([
|
|
17
|
+
"bytecode",
|
|
18
|
+
"trace",
|
|
19
|
+
"indexer",
|
|
20
|
+
"validator",
|
|
21
|
+
"combined"
|
|
22
|
+
]);
|
|
23
|
+
export const findingSchema = z.object({
|
|
24
|
+
id: z.string().min(1),
|
|
25
|
+
title: z.string().min(1),
|
|
26
|
+
severity: severitySchema,
|
|
27
|
+
confidence: confidenceSchema,
|
|
28
|
+
domain: z.array(reportDomainSchema).min(1),
|
|
29
|
+
relatedEips: z.array(z.string()).default([]),
|
|
30
|
+
description: z.string().min(1),
|
|
31
|
+
evidence: z.array(z.unknown()).default([]),
|
|
32
|
+
recommendation: z.string().min(1)
|
|
33
|
+
});
|
|
34
|
+
export const reportSummarySchema = z.object({
|
|
35
|
+
risk: severitySchema,
|
|
36
|
+
findingCount: z.number().int().nonnegative(),
|
|
37
|
+
highCount: z.number().int().nonnegative(),
|
|
38
|
+
mediumCount: z.number().int().nonnegative(),
|
|
39
|
+
lowCount: z.number().int().nonnegative(),
|
|
40
|
+
unknownCount: z.number().int().nonnegative()
|
|
41
|
+
});
|
|
42
|
+
export const compatibilityReportSchema = z.object({
|
|
43
|
+
toolVersion: z.string().min(1),
|
|
44
|
+
fork: z.string().min(1),
|
|
45
|
+
target: z.object({
|
|
46
|
+
kind: targetKindSchema,
|
|
47
|
+
name: z.string().min(1)
|
|
48
|
+
}),
|
|
49
|
+
summary: reportSummarySchema,
|
|
50
|
+
findings: z.array(findingSchema),
|
|
51
|
+
assumptions: z.array(z.string()).default([]),
|
|
52
|
+
limitations: z.array(z.string()).default([])
|
|
53
|
+
});
|
|
54
|
+
export function summarizeFindings(findings) {
|
|
55
|
+
const highCount = findings.filter((finding) => finding.severity === "high").length;
|
|
56
|
+
const mediumCount = findings.filter((finding) => finding.severity === "medium").length;
|
|
57
|
+
const lowCount = findings.filter((finding) => finding.severity === "low").length;
|
|
58
|
+
const unknownCount = findings.filter((finding) => finding.severity === "unknown").length;
|
|
59
|
+
const risk = highCount > 0
|
|
60
|
+
? "high"
|
|
61
|
+
: mediumCount > 0
|
|
62
|
+
? "medium"
|
|
63
|
+
: lowCount > 0
|
|
64
|
+
? "low"
|
|
65
|
+
: unknownCount > 0
|
|
66
|
+
? "unknown"
|
|
67
|
+
: "low";
|
|
68
|
+
return {
|
|
69
|
+
risk,
|
|
70
|
+
findingCount: findings.length,
|
|
71
|
+
highCount,
|
|
72
|
+
mediumCount,
|
|
73
|
+
lowCount,
|
|
74
|
+
unknownCount
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
export function makeReport(input) {
|
|
78
|
+
return compatibilityReportSchema.parse({
|
|
79
|
+
toolVersion: TOOL_VERSION,
|
|
80
|
+
fork: input.fork ?? "glamsterdam",
|
|
81
|
+
target: input.target,
|
|
82
|
+
summary: summarizeFindings(input.findings),
|
|
83
|
+
findings: input.findings,
|
|
84
|
+
assumptions: input.assumptions ?? [],
|
|
85
|
+
limitations: input.limitations ?? []
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
export function validateCompatibilityReport(value) {
|
|
89
|
+
return compatibilityReportSchema.parse(value);
|
|
90
|
+
}
|
|
91
|
+
export function combineReports(reports) {
|
|
92
|
+
const findings = reports.flatMap((report) => report.findings.map((finding) => ({
|
|
93
|
+
...finding,
|
|
94
|
+
id: `${report.target.kind}.${finding.id}`,
|
|
95
|
+
evidence: [`Source report: ${report.target.kind} ${report.target.name}`, ...finding.evidence]
|
|
96
|
+
})));
|
|
97
|
+
return makeReport({
|
|
98
|
+
fork: reports[0]?.fork ?? "glamsterdam",
|
|
99
|
+
target: {
|
|
100
|
+
kind: "combined",
|
|
101
|
+
name: `${reports.length} report${reports.length === 1 ? "" : "s"}`
|
|
102
|
+
},
|
|
103
|
+
findings,
|
|
104
|
+
assumptions: dedupe(reports.flatMap((report) => report.assumptions)),
|
|
105
|
+
limitations: dedupe(reports.flatMap((report) => report.limitations))
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function dedupe(values) {
|
|
109
|
+
return [...new Set(values)];
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=reportTypes.js.map
|