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.
Files changed (96) hide show
  1. package/CONTRIBUTING.md +59 -0
  2. package/LICENSE +21 -0
  3. package/README.md +187 -0
  4. package/ROADMAP.md +76 -0
  5. package/SECURITY.md +19 -0
  6. package/data/client-compat/clients.example.json +42 -0
  7. package/data/detectors/thresholds.ci.json +33 -0
  8. package/data/detectors/thresholds.json +33 -0
  9. package/data/detectors/thresholds.research.json +33 -0
  10. package/data/eips/glamsterdam.json +85 -0
  11. package/dist/cli.d.ts +2 -0
  12. package/dist/cli.js +163 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/detectors/balDetectors.d.ts +3 -0
  15. package/dist/detectors/balDetectors.js +26 -0
  16. package/dist/detectors/balDetectors.js.map +1 -0
  17. package/dist/detectors/contractSizeDetectors.d.ts +3 -0
  18. package/dist/detectors/contractSizeDetectors.js +37 -0
  19. package/dist/detectors/contractSizeDetectors.js.map +1 -0
  20. package/dist/detectors/epbsDetectors.d.ts +7 -0
  21. package/dist/detectors/epbsDetectors.js +33 -0
  22. package/dist/detectors/epbsDetectors.js.map +1 -0
  23. package/dist/detectors/gasRepricingDetectors.d.ts +4 -0
  24. package/dist/detectors/gasRepricingDetectors.js +135 -0
  25. package/dist/detectors/gasRepricingDetectors.js.map +1 -0
  26. package/dist/detectors/nativeEthTransferLogDetectors.d.ts +8 -0
  27. package/dist/detectors/nativeEthTransferLogDetectors.js +54 -0
  28. package/dist/detectors/nativeEthTransferLogDetectors.js.map +1 -0
  29. package/dist/detectors/stateCreationDetectors.d.ts +4 -0
  30. package/dist/detectors/stateCreationDetectors.js +46 -0
  31. package/dist/detectors/stateCreationDetectors.js.map +1 -0
  32. package/dist/detectors/thresholds.d.ts +34 -0
  33. package/dist/detectors/thresholds.js +45 -0
  34. package/dist/detectors/thresholds.js.map +1 -0
  35. package/dist/detectors/types.d.ts +15 -0
  36. package/dist/detectors/types.js +23 -0
  37. package/dist/detectors/types.js.map +1 -0
  38. package/dist/index.d.ts +16 -0
  39. package/dist/index.js +13 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/registry/eipRegistry.d.ts +6 -0
  42. package/dist/registry/eipRegistry.js +30 -0
  43. package/dist/registry/eipRegistry.js.map +1 -0
  44. package/dist/registry/schemas.d.ts +76 -0
  45. package/dist/registry/schemas.js +34 -0
  46. package/dist/registry/schemas.js.map +1 -0
  47. package/dist/reports/jsonReporter.d.ts +2 -0
  48. package/dist/reports/jsonReporter.js +5 -0
  49. package/dist/reports/jsonReporter.js.map +1 -0
  50. package/dist/reports/markdownReporter.d.ts +2 -0
  51. package/dist/reports/markdownReporter.js +75 -0
  52. package/dist/reports/markdownReporter.js.map +1 -0
  53. package/dist/reports/reportTypes.d.ts +150 -0
  54. package/dist/reports/reportTypes.js +111 -0
  55. package/dist/reports/reportTypes.js.map +1 -0
  56. package/dist/scanners/bytecodeScanner.d.ts +11 -0
  57. package/dist/scanners/bytecodeScanner.js +107 -0
  58. package/dist/scanners/bytecodeScanner.js.map +1 -0
  59. package/dist/scanners/indexerScanner.d.ts +13 -0
  60. package/dist/scanners/indexerScanner.js +129 -0
  61. package/dist/scanners/indexerScanner.js.map +1 -0
  62. package/dist/scanners/rpcTraceScanner.d.ts +40 -0
  63. package/dist/scanners/rpcTraceScanner.js +121 -0
  64. package/dist/scanners/rpcTraceScanner.js.map +1 -0
  65. package/dist/scanners/traceScanner.d.ts +24 -0
  66. package/dist/scanners/traceScanner.js +272 -0
  67. package/dist/scanners/traceScanner.js.map +1 -0
  68. package/dist/scanners/validatorScanner.d.ts +40 -0
  69. package/dist/scanners/validatorScanner.js +210 -0
  70. package/dist/scanners/validatorScanner.js.map +1 -0
  71. package/dist/utils/bytecode.d.ts +11 -0
  72. package/dist/utils/bytecode.js +140 -0
  73. package/dist/utils/bytecode.js.map +1 -0
  74. package/dist/utils/files.d.ts +10 -0
  75. package/dist/utils/files.js +51 -0
  76. package/dist/utils/files.js.map +1 -0
  77. package/dist/utils/severity.d.ts +2 -0
  78. package/dist/utils/severity.js +13 -0
  79. package/dist/utils/severity.js.map +1 -0
  80. package/docs/fixtures.md +60 -0
  81. package/docs/release.md +132 -0
  82. package/examples/storage-heavy-bytecode.md +57 -0
  83. package/fixtures/bytecode/storage-heavy.hex +1 -0
  84. package/fixtures/indexers/balance-diff-indexer.json +15 -0
  85. package/fixtures/indexers/subgraph.yaml +24 -0
  86. package/fixtures/traces/besu-debug-structlogs.json +18 -0
  87. package/fixtures/traces/call-tracer-tree.json +27 -0
  88. package/fixtures/traces/drpc-call-tracer-real.json +373 -0
  89. package/fixtures/traces/erigon-action-trace.json +29 -0
  90. package/fixtures/traces/foundry-json-trace.json +19 -0
  91. package/fixtures/traces/geth-json-rpc-structlogs.json +16 -0
  92. package/fixtures/traces/hardhat-debug-trace.json +13 -0
  93. package/fixtures/traces/nethermind-debug-structlogs.json +17 -0
  94. package/fixtures/traces/storage-heavy-trace.json +25 -0
  95. package/fixtures/validator/operator-config.yaml +15 -0
  96. package/package.json +80 -0
package/dist/cli.js ADDED
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { Command } from "commander";
4
+ import { combineReports, defaultClientMatrixPath, defaultThresholdsPath, loadEipRegistry, renderJsonReport, renderMarkdownReport, scanBytecode, scanIndexer, scanTraceFile, scanValidatorConfig, validateCompatibilityReport, fetchAndScanTransactionTrace, writeFetchedTrace } from "./index.js";
5
+ import { TOOL_VERSION } from "./reports/reportTypes.js";
6
+ import { parseDebugTraceMode } from "./scanners/rpcTraceScanner.js";
7
+ const program = new Command();
8
+ program
9
+ .name("glamsterdam")
10
+ .description("Glamsterdam Compatibility Lab CLI")
11
+ .version(TOOL_VERSION);
12
+ program
13
+ .command("scan-bytecode")
14
+ .argument("<path-or-hex>", "EVM bytecode file path or inline hex string")
15
+ .option("--format <format>", "Output format: markdown or json", "markdown")
16
+ .option("--registry <path>", "Path to Glamsterdam EIP registry JSON")
17
+ .option("--thresholds <path>", "Path to detector thresholds JSON", defaultThresholdsPath())
18
+ .description("Analyze EVM bytecode for conservative Glamsterdam compatibility prompts")
19
+ .action((pathOrHex, options) => {
20
+ const report = scanBytecode(pathOrHex, { registryPath: options.registry, thresholdsPath: options.thresholds });
21
+ writeReport(report, parseFormat(options.format));
22
+ });
23
+ program
24
+ .command("scan-traces")
25
+ .argument("<trace-json-file>", "Trace JSON file")
26
+ .option("--format <format>", "Output format: markdown or json", "markdown")
27
+ .option("--registry <path>", "Path to Glamsterdam EIP registry JSON")
28
+ .option("--thresholds <path>", "Path to detector thresholds JSON", defaultThresholdsPath())
29
+ .description("Analyze transaction traces for state-heavy, creation-heavy, calldata, log, and call patterns")
30
+ .action((traceFile, options) => {
31
+ const report = scanTraceFile(traceFile, { registryPath: options.registry, thresholdsPath: options.thresholds });
32
+ writeReport(report, parseFormat(options.format));
33
+ });
34
+ program
35
+ .command("scan-tx")
36
+ .requiredOption("--tx <hash>", "Transaction hash to fetch with debug_traceTransaction")
37
+ .option("--rpc-url <url>", "Execution RPC URL. Defaults to ETH_RPC_URL when omitted")
38
+ .option("--tracer <mode>", "Trace mode: structLogs or callTracer", "structLogs")
39
+ .option("--trace-timeout <duration>", "Execution client trace timeout hint", "30s")
40
+ .option("--rpc-timeout-ms <ms>", "HTTP RPC timeout in milliseconds", "30000")
41
+ .option("--trace-out <path>", "Write the fetched JSON-RPC trace response to a file")
42
+ .option("--format <format>", "Output format: markdown or json", "markdown")
43
+ .option("--registry <path>", "Path to Glamsterdam EIP registry JSON")
44
+ .option("--thresholds <path>", "Path to detector thresholds JSON", defaultThresholdsPath())
45
+ .description("Fetch debug_traceTransaction from an RPC endpoint and scan the returned trace")
46
+ .action(async (options) => {
47
+ const rpcUrl = options.rpcUrl ?? process.env.ETH_RPC_URL;
48
+ if (!rpcUrl) {
49
+ throw new Error("Provide --rpc-url or set ETH_RPC_URL.");
50
+ }
51
+ const result = await fetchAndScanTransactionTrace({
52
+ rpcUrl,
53
+ txHash: options.tx,
54
+ tracer: parseDebugTraceMode(options.tracer),
55
+ traceTimeout: options.traceTimeout,
56
+ rpcTimeoutMs: parsePositiveInteger(options.rpcTimeoutMs, "--rpc-timeout-ms"),
57
+ registryPath: options.registry,
58
+ thresholdsPath: options.thresholds
59
+ });
60
+ if (options.traceOut) {
61
+ writeFetchedTrace(result.trace, options.traceOut);
62
+ }
63
+ writeReport(result.report, parseFormat(options.format));
64
+ });
65
+ program
66
+ .command("scan-indexer")
67
+ .argument("<path>", "Indexer, explorer, or subgraph config path")
68
+ .option("--format <format>", "Output format: markdown or json", "markdown")
69
+ .option("--registry <path>", "Path to Glamsterdam EIP registry JSON")
70
+ .option("--thresholds <path>", "Path to detector thresholds JSON", defaultThresholdsPath())
71
+ .description("Analyze JSON/YAML indexer configuration with heuristic compatibility checks")
72
+ .action((path, options) => {
73
+ const report = scanIndexer(path, { registryPath: options.registry, thresholdsPath: options.thresholds });
74
+ writeReport(report, parseFormat(options.format));
75
+ });
76
+ program
77
+ .command("scan-validator")
78
+ .requiredOption("--config <path>", "Validator/operator config JSON or YAML")
79
+ .option("--client-matrix <path>", "Client compatibility matrix JSON", defaultClientMatrixPath())
80
+ .option("--format <format>", "Output format: markdown or json", "markdown")
81
+ .option("--registry <path>", "Path to Glamsterdam EIP registry JSON")
82
+ .option("--thresholds <path>", "Path to detector thresholds JSON", defaultThresholdsPath())
83
+ .description("Analyze validator/operator readiness from local config and user-editable compatibility data")
84
+ .action((options) => {
85
+ const report = scanValidatorConfig(options.config, {
86
+ registryPath: options.registry,
87
+ thresholdsPath: options.thresholds,
88
+ clientMatrixPath: options.clientMatrix
89
+ });
90
+ writeReport(report, parseFormat(options.format));
91
+ });
92
+ program
93
+ .command("eips")
94
+ .option("--format <format>", "Output format: markdown or json", "markdown")
95
+ .option("--registry <path>", "Path to Glamsterdam EIP registry JSON")
96
+ .description("Print the loaded Glamsterdam EIP registry")
97
+ .action((options) => {
98
+ const registry = loadEipRegistry(options.registry);
99
+ const format = parseFormat(options.format);
100
+ process.stdout.write(format === "json" ? `${JSON.stringify(registry, null, 2)}\n` : renderEipRegistry(registry));
101
+ });
102
+ program
103
+ .command("report")
104
+ .argument("[reports...]", "JSON report files generated with --format json")
105
+ .option("--format <format>", "Output format: markdown or json", "markdown")
106
+ .description("Combine multiple saved JSON scan reports into one report")
107
+ .action((reports, options) => {
108
+ if (reports.length === 0) {
109
+ throw new Error("Provide at least one JSON report file to combine.");
110
+ }
111
+ const parsedReports = reports.map((path) => validateCompatibilityReport(JSON.parse(readFileSync(path, "utf8"))));
112
+ writeReport(combineReports(parsedReports), parseFormat(options.format));
113
+ });
114
+ program.parseAsync(process.argv).catch((error) => {
115
+ const message = error instanceof Error ? error.message : String(error);
116
+ process.stderr.write(`Error: ${message}\n`);
117
+ process.exitCode = 1;
118
+ });
119
+ function writeReport(report, format) {
120
+ process.stdout.write(format === "json" ? renderJsonReport(report) : renderMarkdownReport(report));
121
+ }
122
+ function parseFormat(format) {
123
+ if (format === "markdown" || format === "json") {
124
+ return format;
125
+ }
126
+ throw new Error(`Unsupported format "${format}". Use "markdown" or "json".`);
127
+ }
128
+ function parsePositiveInteger(value, name) {
129
+ const parsed = Number(value);
130
+ if (!Number.isInteger(parsed) || parsed <= 0) {
131
+ throw new Error(`${name} must be a positive integer.`);
132
+ }
133
+ return parsed;
134
+ }
135
+ function renderEipRegistry(registry) {
136
+ const lines = [];
137
+ lines.push("# Glamsterdam EIP Registry");
138
+ lines.push("");
139
+ lines.push(`Fork: ${registry.fork}`);
140
+ lines.push(`Last updated: ${registry.lastUpdated}`);
141
+ lines.push("");
142
+ lines.push("## Sources");
143
+ lines.push("");
144
+ for (const source of registry.sources) {
145
+ lines.push(`- ${source}`);
146
+ }
147
+ lines.push("");
148
+ lines.push("## Entries");
149
+ lines.push("");
150
+ for (const entry of registry.eips) {
151
+ lines.push(`### ${entry.id}: ${entry.name}`);
152
+ lines.push("");
153
+ lines.push(`Status: ${entry.status}`);
154
+ lines.push(`Domain: ${entry.domain.join(", ")}`);
155
+ lines.push(`Detector modules: ${entry.detectors.length > 0 ? entry.detectors.join(", ") : "none"}`);
156
+ if (entry.notes) {
157
+ lines.push(`Notes: ${entry.notes}`);
158
+ }
159
+ lines.push("");
160
+ }
161
+ return `${lines.join("\n")}\n`;
162
+ }
163
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type DetectorContext } from "./types.js";
2
+ import type { CompatibilityFinding } from "../reports/reportTypes.js";
3
+ export declare function detectMissingBalIndexerPlan(configText: string, context: DetectorContext): CompatibilityFinding[];
@@ -0,0 +1,26 @@
1
+ import { domains, makeFinding, relatedEipsForDetector } from "./types.js";
2
+ export function detectMissingBalIndexerPlan(configText, context) {
3
+ const lower = configText.toLowerCase();
4
+ const mentionsBal = lower.includes("block-level access")
5
+ || lower.includes("block level access")
6
+ || lower.includes("blocklevelaccess")
7
+ || lower.includes("eip-7928")
8
+ || /\bbals?\b/.test(lower);
9
+ if (mentionsBal) {
10
+ return [];
11
+ }
12
+ return [
13
+ makeFinding({
14
+ id: "indexer.missing-bal-readiness-metadata",
15
+ title: "No explicit Block-Level Access List readiness metadata found",
16
+ severity: "medium",
17
+ confidence: "medium",
18
+ domain: domains("indexer", "monitoring"),
19
+ relatedEips: relatedEipsForDetector(context.registry, "balDetectors", ["EIP-7928"]),
20
+ description: "The configuration does not mention BALs or EIP-7928. Static config cannot prove whether the indexer is incompatible, but explorer and indexer teams should explicitly track BAL ingestion and monitoring assumptions.",
21
+ evidence: ["No BAL/EIP-7928 marker found in configuration text."],
22
+ recommendation: "Add fork-readiness metadata documenting whether BAL-related block data is ignored, stored, displayed, monitored, or replay-tested."
23
+ })
24
+ ];
25
+ }
26
+ //# sourceMappingURL=balDetectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"balDetectors.js","sourceRoot":"","sources":["../../src/detectors/balDetectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAwB,MAAM,YAAY,CAAC;AAGhG,MAAM,UAAU,2BAA2B,CAAC,UAAkB,EAAE,OAAwB;IACtF,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,oBAAoB,CAAC;WACnD,KAAK,CAAC,QAAQ,CAAC,oBAAoB,CAAC;WACpC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC;WAClC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;WAC1B,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAE7B,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO;QACL,WAAW,CAAC;YACV,EAAE,EAAE,wCAAwC;YAC5C,KAAK,EAAE,8DAA8D;YACrE,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC;YACxC,WAAW,EAAE,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,EAAE,CAAC,UAAU,CAAC,CAAC;YACnF,WAAW,EACT,uNAAuN;YACzN,QAAQ,EAAE,CAAC,qDAAqD,CAAC;YACjE,cAAc,EACZ,oIAAoI;SACvI,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type DetectorContext } from "./types.js";
2
+ import type { CompatibilityFinding } from "../reports/reportTypes.js";
3
+ export declare function detectContractSize(byteLength: number, context: DetectorContext): CompatibilityFinding[];
@@ -0,0 +1,37 @@
1
+ import { domains, makeFinding, relatedEipsForDetector } from "./types.js";
2
+ export function detectContractSize(byteLength, context) {
3
+ const relatedEips = relatedEipsForDetector(context.registry, "contractSizeDetectors", ["EIP-7954"]);
4
+ const { currentRuntimeLimitBytes, nearCurrentLimitBytes } = context.thresholds.bytecode.contractSize;
5
+ if (byteLength > currentRuntimeLimitBytes) {
6
+ return [
7
+ makeFinding({
8
+ id: "bytecode.contract-size-over-current-limit",
9
+ title: "Bytecode exceeds the current deployed contract size limit",
10
+ severity: "high",
11
+ confidence: "high",
12
+ domain: domains("contracts", "execution"),
13
+ relatedEips,
14
+ description: "The bytecode is larger than the current EIP-170 deployed runtime size limit. Glamsterdam includes considered work around contract-size limits, but this scanner does not assume a final new limit.",
15
+ evidence: [{ byteLength, currentRuntimeLimitBytes }],
16
+ recommendation: "Confirm whether this input is runtime bytecode or init code. Track the registry entry for contract-size changes and test deployment/runtime behavior against a Glamsterdam devnet or fork configuration when available."
17
+ })
18
+ ];
19
+ }
20
+ if (byteLength >= nearCurrentLimitBytes) {
21
+ return [
22
+ makeFinding({
23
+ id: "bytecode.contract-size-near-current-limit",
24
+ title: "Bytecode is near the current deployed contract size limit",
25
+ severity: "medium",
26
+ confidence: "high",
27
+ domain: domains("contracts", "execution"),
28
+ relatedEips,
29
+ description: "The bytecode is close to today's deployed runtime size limit. Contract-size proposals may change what is possible, but large bytecode still deserves deployment and tooling review.",
30
+ evidence: [{ byteLength, currentRuntimeLimitBytes }],
31
+ recommendation: "Add this contract to fork-readiness tests and verify deployment, verification, explorer, and build-pipeline behavior under any Glamsterdam devnet configuration."
32
+ })
33
+ ];
34
+ }
35
+ return [];
36
+ }
37
+ //# sourceMappingURL=contractSizeDetectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contractSizeDetectors.js","sourceRoot":"","sources":["../../src/detectors/contractSizeDetectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAwB,MAAM,YAAY,CAAC;AAGhG,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,OAAwB;IAC7E,MAAM,WAAW,GAAG,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,uBAAuB,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IACpG,MAAM,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;IAErG,IAAI,UAAU,GAAG,wBAAwB,EAAE,CAAC;QAC1C,OAAO;YACL,WAAW,CAAC;gBACV,EAAE,EAAE,2CAA2C;gBAC/C,KAAK,EAAE,2DAA2D;gBAClE,QAAQ,EAAE,MAAM;gBAChB,UAAU,EAAE,MAAM;gBAClB,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC;gBACzC,WAAW;gBACX,WAAW,EACT,oMAAoM;gBACtM,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,wBAAwB,EAAE,CAAC;gBACpD,cAAc,EACZ,yNAAyN;aAC5N,CAAC;SACH,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,IAAI,qBAAqB,EAAE,CAAC;QACxC,OAAO;YACL,WAAW,CAAC;gBACV,EAAE,EAAE,2CAA2C;gBAC/C,KAAK,EAAE,2DAA2D;gBAClE,QAAQ,EAAE,QAAQ;gBAClB,UAAU,EAAE,MAAM;gBAClB,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC;gBACzC,WAAW;gBACX,WAAW,EACT,qLAAqL;gBACvL,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,wBAAwB,EAAE,CAAC;gBACpD,cAAc,EACZ,kKAAkK;aACrK,CAAC;SACH,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type DetectorContext } from "./types.js";
2
+ import type { CompatibilityFinding } from "../reports/reportTypes.js";
3
+ export interface BuilderConfigEvidence {
4
+ builderEnabled?: unknown;
5
+ builderEndpoint?: unknown;
6
+ }
7
+ export declare function detectEpbsBuilderReadiness(evidence: BuilderConfigEvidence, context: DetectorContext): CompatibilityFinding[];
@@ -0,0 +1,33 @@
1
+ import { domains, makeFinding, relatedEipsForDetector } from "./types.js";
2
+ export function detectEpbsBuilderReadiness(evidence, context) {
3
+ const findings = [];
4
+ const relatedEips = relatedEipsForDetector(context.registry, "epbsDetectors", ["EIP-7732"]);
5
+ if (evidence.builderEnabled === undefined) {
6
+ findings.push(makeFinding({
7
+ id: "validator.missing-builder-metadata",
8
+ title: "Builder/API configuration metadata is missing",
9
+ severity: "medium",
10
+ confidence: "high",
11
+ domain: domains("validator", "builder", "consensus"),
12
+ relatedEips,
13
+ description: "The operator config does not say whether builder/API functionality is enabled. ePBS readiness requires operators to know which builder-related settings are intentional.",
14
+ evidence,
15
+ recommendation: "Record whether builder integration is enabled, disabled, or intentionally not applicable, and include the endpoint metadata used in staging/testnet environments."
16
+ }));
17
+ }
18
+ if (evidence.builderEnabled === true && !evidence.builderEndpoint) {
19
+ findings.push(makeFinding({
20
+ id: "validator.builder-enabled-without-endpoint",
21
+ title: "Builder integration is enabled but no endpoint is configured",
22
+ severity: "medium",
23
+ confidence: "high",
24
+ domain: domains("validator", "builder", "consensus"),
25
+ relatedEips,
26
+ description: "The config marks builder integration as enabled but does not include an endpoint. This may simply mean the local config is incomplete, so the scanner treats it as a readiness checklist item.",
27
+ evidence,
28
+ recommendation: "Add the intended builder endpoint or document why endpoint configuration is managed elsewhere."
29
+ }));
30
+ }
31
+ return findings;
32
+ }
33
+ //# sourceMappingURL=epbsDetectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epbsDetectors.js","sourceRoot":"","sources":["../../src/detectors/epbsDetectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAwB,MAAM,YAAY,CAAC;AAQhG,MAAM,UAAU,0BAA0B,CACxC,QAA+B,EAC/B,OAAwB;IAExB,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,WAAW,GAAG,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAE5F,IAAI,QAAQ,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QAC1C,QAAQ,CAAC,IAAI,CACX,WAAW,CAAC;YACV,EAAE,EAAE,oCAAoC;YACxC,KAAK,EAAE,+CAA+C;YACtD,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,MAAM;YAClB,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC;YACpD,WAAW;YACX,WAAW,EACT,0KAA0K;YAC5K,QAAQ;YACR,cAAc,EACZ,mKAAmK;SACtK,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,cAAc,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;QAClE,QAAQ,CAAC,IAAI,CACX,WAAW,CAAC;YACV,EAAE,EAAE,4CAA4C;YAChD,KAAK,EAAE,8DAA8D;YACrE,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,MAAM;YAClB,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,SAAS,EAAE,WAAW,CAAC;YACpD,WAAW;YACX,WAAW,EACT,gMAAgM;YAClM,QAAQ;YACR,cAAc,EACZ,gGAAgG;SACnG,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type DetectorContext } from "./types.js";
2
+ import type { CompatibilityFinding } from "../reports/reportTypes.js";
3
+ export declare function detectBytecodeGasRepricingExposure(opcodeCounts: Record<string, number>, context: DetectorContext): CompatibilityFinding[];
4
+ export declare function detectTraceGasRepricingExposure(opcodeCounts: Record<string, number>, calldataBytes: number, context: DetectorContext): CompatibilityFinding[];
@@ -0,0 +1,135 @@
1
+ import { domains, makeFinding, relatedEipsForDetector } from "./types.js";
2
+ import { opcodeCount } from "../utils/bytecode.js";
3
+ const stateAndAccountOpcodes = [
4
+ "SLOAD",
5
+ "SSTORE",
6
+ "BALANCE",
7
+ "EXTCODESIZE",
8
+ "EXTCODECOPY",
9
+ "EXTCODEHASH",
10
+ "SELFBALANCE",
11
+ "SHA3"
12
+ ];
13
+ export function detectBytecodeGasRepricingExposure(opcodeCounts, context) {
14
+ const sensitiveCount = opcodeCount(opcodeCounts, stateAndAccountOpcodes);
15
+ const calldataCopyCount = opcodeCounts.CALLDATACOPY ?? 0;
16
+ const thresholds = context.thresholds.bytecode.stateAccountOpcodeExposure;
17
+ const findings = [];
18
+ const relatedEips = relatedEipsForDetector(context.registry, "gasRepricingDetectors", [
19
+ "GAS-REPRICING",
20
+ "EIP-7904",
21
+ "EIP-8038"
22
+ ]);
23
+ if (sensitiveCount >= thresholds.mediumSensitiveOpcodeCount) {
24
+ findings.push(makeFinding({
25
+ id: "bytecode.state-account-opcode-exposure",
26
+ title: "State and account access opcodes are prominent in bytecode",
27
+ severity: "medium",
28
+ confidence: "medium",
29
+ domain: domains("contracts", "execution"),
30
+ relatedEips,
31
+ description: "This bytecode contains multiple storage, account, or hashing opcodes. Glamsterdam gas repricing candidates may change the cost profile of state-heavy execution, but static bytecode does not prove those paths are hot.",
32
+ evidence: { sensitiveOpcodeCount: sensitiveCount, opcodeCounts: pick(opcodeCounts, stateAndAccountOpcodes) },
33
+ recommendation: "Replay representative transactions and benchmark hot paths once a Glamsterdam client/devnet or local fork configuration is available."
34
+ }));
35
+ }
36
+ else if (sensitiveCount >= thresholds.lowSensitiveOpcodeCount) {
37
+ findings.push(makeFinding({
38
+ id: "bytecode.state-account-opcode-presence",
39
+ title: "State and account access opcodes are present",
40
+ severity: "low",
41
+ confidence: "medium",
42
+ domain: domains("contracts", "execution"),
43
+ relatedEips,
44
+ description: "This bytecode contains some opcodes that are commonly involved in gas repricing discussions. The scan cannot determine execution frequency.",
45
+ evidence: { sensitiveOpcodeCount: sensitiveCount, opcodeCounts: pick(opcodeCounts, stateAndAccountOpcodes) },
46
+ recommendation: "Include transactions that exercise these paths in fork-readiness tests."
47
+ }));
48
+ }
49
+ if (calldataCopyCount > 0) {
50
+ findings.push(makeFinding({
51
+ id: "bytecode.calldata-copy-exposure",
52
+ title: "Calldata copy opcode is present",
53
+ severity: "low",
54
+ confidence: "medium",
55
+ domain: domains("contracts", "execution"),
56
+ relatedEips: relatedEipsForDetector(context.registry, "gasRepricingDetectors", [
57
+ "GAS-REPRICING",
58
+ "EIP-7976"
59
+ ]),
60
+ description: "CALLDATACOPY appears in the bytecode. Calldata-related repricing candidates should be tested if this contract processes large calldata in production.",
61
+ evidence: { CALLDATACOPY: calldataCopyCount },
62
+ recommendation: "Add large-calldata cases to benchmarks and trace replay when final Glamsterdam parameters are known."
63
+ }));
64
+ }
65
+ return findings;
66
+ }
67
+ export function detectTraceGasRepricingExposure(opcodeCounts, calldataBytes, context) {
68
+ const storageOps = opcodeCount(opcodeCounts, ["SLOAD", "SSTORE"]);
69
+ const sensitiveCount = opcodeCount(opcodeCounts, stateAndAccountOpcodes);
70
+ const stateThresholds = context.thresholds.trace.stateHeavyExecution;
71
+ const calldataThresholds = context.thresholds.trace.calldataHeavy;
72
+ const findings = [];
73
+ if (storageOps >= stateThresholds.highStorageOps
74
+ || sensitiveCount >= stateThresholds.highSensitiveOpcodeCount) {
75
+ findings.push(makeFinding({
76
+ id: "trace.state-heavy-execution-high",
77
+ title: "Trace shows high state-heavy execution",
78
+ severity: "high",
79
+ confidence: "high",
80
+ domain: domains("contracts", "execution"),
81
+ relatedEips: relatedEipsForDetector(context.registry, "gasRepricingDetectors", [
82
+ "GAS-REPRICING",
83
+ "EIP-7904",
84
+ "EIP-8038"
85
+ ]),
86
+ description: "The executed trace contains many storage or state/account access operations. This is direct execution evidence and should be prioritized for fork-readiness benchmarking.",
87
+ evidence: { storageOps, sensitiveOpcodeCount: sensitiveCount, opcodeCounts: pick(opcodeCounts, stateAndAccountOpcodes) },
88
+ recommendation: "Replay this transaction class against a Glamsterdam devnet or fork configuration and compare gas, latency, and failure behavior with current mainnet rules."
89
+ }));
90
+ }
91
+ else if (storageOps >= stateThresholds.mediumStorageOps
92
+ || sensitiveCount >= stateThresholds.mediumSensitiveOpcodeCount) {
93
+ findings.push(makeFinding({
94
+ id: "trace.state-heavy-execution-medium",
95
+ title: "Trace shows state-heavy execution",
96
+ severity: "medium",
97
+ confidence: "high",
98
+ domain: domains("contracts", "execution"),
99
+ relatedEips: relatedEipsForDetector(context.registry, "gasRepricingDetectors", [
100
+ "GAS-REPRICING",
101
+ "EIP-7904",
102
+ "EIP-8038"
103
+ ]),
104
+ description: "The executed trace includes repeated storage or state/account access operations. Glamsterdam repricing candidates may affect this cost profile, depending on final fork scope.",
105
+ evidence: { storageOps, sensitiveOpcodeCount: sensitiveCount, opcodeCounts: pick(opcodeCounts, stateAndAccountOpcodes) },
106
+ recommendation: "Keep this trace as a regression fixture and replay it when final Glamsterdam client configurations are available."
107
+ }));
108
+ }
109
+ if ((opcodeCounts.CALLDATACOPY ?? 0) > 0 || calldataBytes >= calldataThresholds.mediumCalldataBytes) {
110
+ findings.push(makeFinding({
111
+ id: "trace.calldata-heavy-execution",
112
+ title: "Trace includes visible calldata-heavy execution",
113
+ severity: calldataBytes >= calldataThresholds.mediumCalldataBytes ? "medium" : "low",
114
+ confidence: calldataBytes > 0 ? "high" : "medium",
115
+ domain: domains("contracts", "execution"),
116
+ relatedEips: relatedEipsForDetector(context.registry, "gasRepricingDetectors", [
117
+ "GAS-REPRICING",
118
+ "EIP-7976"
119
+ ]),
120
+ description: "The trace includes CALLDATACOPY or explicit calldata byte counts. Calldata repricing candidates are considered registry items, so large input paths should be tested.",
121
+ evidence: { CALLDATACOPY: opcodeCounts.CALLDATACOPY ?? 0, calldataBytes },
122
+ recommendation: "Replay large-input transactions and compare gas envelopes once a Glamsterdam configuration is available."
123
+ }));
124
+ }
125
+ return findings;
126
+ }
127
+ function pick(record, keys) {
128
+ return keys.reduce((selected, key) => {
129
+ if (record[key] !== undefined) {
130
+ selected[key] = record[key];
131
+ }
132
+ return selected;
133
+ }, {});
134
+ }
135
+ //# sourceMappingURL=gasRepricingDetectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gasRepricingDetectors.js","sourceRoot":"","sources":["../../src/detectors/gasRepricingDetectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type DetectorContext } from "./types.js";
2
+ import type { CompatibilityFinding } from "../reports/reportTypes.js";
3
+ export interface IndexerHandlerSummary {
4
+ eventHandlers: number;
5
+ callHandlers: number;
6
+ blockHandlers: number;
7
+ }
8
+ export declare function detectNativeEthTransferLogReadiness(summary: IndexerHandlerSummary, configText: string, context: DetectorContext): CompatibilityFinding[];
@@ -0,0 +1,54 @@
1
+ import { domains, makeFinding, relatedEipsForDetector } from "./types.js";
2
+ export function detectNativeEthTransferLogReadiness(summary, configText, context) {
3
+ const lower = configText.toLowerCase();
4
+ const mentionsBalanceDiff = lower.includes("balance diff")
5
+ || lower.includes("balance-diff")
6
+ || lower.includes("balancediff");
7
+ const mentionsNativeTransfers = lower.includes("native eth")
8
+ || lower.includes("eth transfer")
9
+ || lower.includes("eip-7708")
10
+ || mentionsBalanceDiff;
11
+ const findings = [];
12
+ const relatedEips = relatedEipsForDetector(context.registry, "nativeEthTransferLogDetectors", ["EIP-7708"]);
13
+ if (summary.eventHandlers > 0 && summary.callHandlers === 0 && summary.blockHandlers === 0) {
14
+ findings.push(makeFinding({
15
+ id: "indexer.event-only-assumption",
16
+ title: "Indexer appears to rely on event-only handlers",
17
+ severity: "medium",
18
+ confidence: "medium",
19
+ domain: domains("indexer"),
20
+ relatedEips,
21
+ description: "This looks like an event-only indexer configuration. Event-only pipelines should be reviewed for native ETH transfer visibility, balance-diff assumptions, and fork-specific log semantics if related EIPs remain active or considered.",
22
+ evidence: summary,
23
+ recommendation: "Document how native ETH transfers are represented today, how they would be represented if transfer-log proposals are included, and how historical replay would be validated."
24
+ }));
25
+ }
26
+ if (mentionsBalanceDiff) {
27
+ findings.push(makeFinding({
28
+ id: "indexer.balance-diff-native-transfer-assumption",
29
+ title: "Indexer mentions balance-diff based native transfer handling",
30
+ severity: "medium",
31
+ confidence: "medium",
32
+ domain: domains("indexer", "monitoring"),
33
+ relatedEips,
34
+ description: "The configuration mentions balance-diff based transfer handling. That can be a valid design, but it should be reviewed if native ETH transfer log proposals remain active or considered.",
35
+ evidence: ["Balance-diff marker found in configuration text."],
36
+ recommendation: "Document whether native ETH transfers come from logs, balance diffs, traces, receipts, or a combined pipeline, and add replay tests for representative transfer cases."
37
+ }));
38
+ }
39
+ if (!mentionsNativeTransfers) {
40
+ findings.push(makeFinding({
41
+ id: "indexer.native-eth-transfer-review-missing",
42
+ title: "No native ETH transfer handling metadata found",
43
+ severity: "unknown",
44
+ confidence: "low",
45
+ domain: domains("indexer", "monitoring"),
46
+ relatedEips,
47
+ description: "The configuration does not mention native ETH transfers, balance diffs, or EIP-7708. Static config cannot determine whether the runtime indexer already handles this elsewhere.",
48
+ evidence: ["No native-transfer marker found in configuration text."],
49
+ recommendation: "Add an explicit compatibility note or test plan for native ETH transfers, especially if dashboards or alerts currently infer transfers from balance diffs."
50
+ }));
51
+ }
52
+ return findings;
53
+ }
54
+ //# sourceMappingURL=nativeEthTransferLogDetectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nativeEthTransferLogDetectors.js","sourceRoot":"","sources":["../../src/detectors/nativeEthTransferLogDetectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAwB,MAAM,YAAY,CAAC;AAShG,MAAM,UAAU,mCAAmC,CACjD,OAA8B,EAC9B,UAAkB,EAClB,OAAwB;IAExB,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACvC,MAAM,mBAAmB,GAAG,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;WACrD,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;WAC9B,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACnC,MAAM,uBAAuB,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC;WACvD,KAAK,CAAC,QAAQ,CAAC,cAAc,CAAC;WAC9B,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;WAC1B,mBAAmB,CAAC;IAEzB,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,WAAW,GAAG,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,+BAA+B,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IAE5G,IAAI,OAAO,CAAC,aAAa,GAAG,CAAC,IAAI,OAAO,CAAC,YAAY,KAAK,CAAC,IAAI,OAAO,CAAC,aAAa,KAAK,CAAC,EAAE,CAAC;QAC3F,QAAQ,CAAC,IAAI,CACX,WAAW,CAAC;YACV,EAAE,EAAE,+BAA+B;YACnC,KAAK,EAAE,gDAAgD;YACvD,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC;YAC1B,WAAW;YACX,WAAW,EACT,yOAAyO;YAC3O,QAAQ,EAAE,OAAO;YACjB,cAAc,EACZ,8KAA8K;SACjL,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,mBAAmB,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CACX,WAAW,CAAC;YACV,EAAE,EAAE,iDAAiD;YACrD,KAAK,EAAE,8DAA8D;YACrE,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,QAAQ;YACpB,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC;YACxC,WAAW;YACX,WAAW,EACT,0LAA0L;YAC5L,QAAQ,EAAE,CAAC,kDAAkD,CAAC;YAC9D,cAAc,EACZ,wKAAwK;SAC3K,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7B,QAAQ,CAAC,IAAI,CACX,WAAW,CAAC;YACV,EAAE,EAAE,4CAA4C;YAChD,KAAK,EAAE,gDAAgD;YACvD,QAAQ,EAAE,SAAS;YACnB,UAAU,EAAE,KAAK;YACjB,MAAM,EAAE,OAAO,CAAC,SAAS,EAAE,YAAY,CAAC;YACxC,WAAW;YACX,WAAW,EACT,iLAAiL;YACnL,QAAQ,EAAE,CAAC,wDAAwD,CAAC;YACpE,cAAc,EACZ,4JAA4J;SAC/J,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type DetectorContext } from "./types.js";
2
+ import type { CompatibilityFinding } from "../reports/reportTypes.js";
3
+ export declare function detectBytecodeStateCreation(opcodeCounts: Record<string, number>, context: DetectorContext): CompatibilityFinding[];
4
+ export declare function detectTraceStateCreation(opcodeCounts: Record<string, number>, context: DetectorContext): CompatibilityFinding[];
@@ -0,0 +1,46 @@
1
+ import { domains, makeFinding, relatedEipsForDetector } from "./types.js";
2
+ export function detectBytecodeStateCreation(opcodeCounts, context) {
3
+ const createCount = (opcodeCounts.CREATE ?? 0) + (opcodeCounts.CREATE2 ?? 0);
4
+ if (createCount === 0) {
5
+ return [];
6
+ }
7
+ return [
8
+ makeFinding({
9
+ id: "bytecode.contract-creation-opcodes",
10
+ title: "Contract creation opcodes are present",
11
+ severity: "medium",
12
+ confidence: "high",
13
+ domain: domains("contracts", "execution"),
14
+ relatedEips: relatedEipsForDetector(context.registry, "stateCreationDetectors", [
15
+ "GAS-REPRICING",
16
+ "EIP-8037"
17
+ ]),
18
+ description: "CREATE or CREATE2 appears in the bytecode. State-creation repricing candidates may affect factory, clone, deployment, or account-creation-heavy paths depending on final Glamsterdam scope.",
19
+ evidence: { CREATE: opcodeCounts.CREATE ?? 0, CREATE2: opcodeCounts.CREATE2 ?? 0 },
20
+ recommendation: "Identify representative deployment/factory transactions and add them to fork-readiness replay tests."
21
+ })
22
+ ];
23
+ }
24
+ export function detectTraceStateCreation(opcodeCounts, context) {
25
+ const createCount = (opcodeCounts.CREATE ?? 0) + (opcodeCounts.CREATE2 ?? 0);
26
+ if (createCount === 0) {
27
+ return [];
28
+ }
29
+ return [
30
+ makeFinding({
31
+ id: "trace.contract-creation-executed",
32
+ title: "Trace executed contract creation",
33
+ severity: "medium",
34
+ confidence: "high",
35
+ domain: domains("contracts", "execution"),
36
+ relatedEips: relatedEipsForDetector(context.registry, "stateCreationDetectors", [
37
+ "GAS-REPRICING",
38
+ "EIP-8037"
39
+ ]),
40
+ description: "The trace executed CREATE or CREATE2. This is direct evidence that this transaction class exercises state creation.",
41
+ evidence: { CREATE: opcodeCounts.CREATE ?? 0, CREATE2: opcodeCounts.CREATE2 ?? 0 },
42
+ recommendation: "Replay creation-heavy flows against Glamsterdam test environments and verify gas budgeting, relayer assumptions, and deployment automation."
43
+ })
44
+ ];
45
+ }
46
+ //# sourceMappingURL=stateCreationDetectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateCreationDetectors.js","sourceRoot":"","sources":["../../src/detectors/stateCreationDetectors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAwB,MAAM,YAAY,CAAC;AAGhG,MAAM,UAAU,2BAA2B,CACzC,YAAoC,EACpC,OAAwB;IAExB,MAAM,WAAW,GAAG,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IAE7E,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO;QACL,WAAW,CAAC;YACV,EAAE,EAAE,oCAAoC;YACxC,KAAK,EAAE,uCAAuC;YAC9C,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,MAAM;YAClB,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC;YACzC,WAAW,EAAE,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,wBAAwB,EAAE;gBAC9E,eAAe;gBACf,UAAU;aACX,CAAC;YACF,WAAW,EACT,6LAA6L;YAC/L,QAAQ,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,EAAE;YAClF,cAAc,EACZ,sGAAsG;SACzG,CAAC;KACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,YAAoC,EACpC,OAAwB;IAExB,MAAM,WAAW,GAAG,CAAC,YAAY,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC;IAE7E,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,OAAO;QACL,WAAW,CAAC;YACV,EAAE,EAAE,kCAAkC;YACtC,KAAK,EAAE,kCAAkC;YACzC,QAAQ,EAAE,QAAQ;YAClB,UAAU,EAAE,MAAM;YAClB,MAAM,EAAE,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC;YACzC,WAAW,EAAE,sBAAsB,CAAC,OAAO,CAAC,QAAQ,EAAE,wBAAwB,EAAE;gBAC9E,eAAe;gBACf,UAAU;aACX,CAAC;YACF,WAAW,EACT,qHAAqH;YACvH,QAAQ,EAAE,EAAE,MAAM,EAAE,YAAY,CAAC,MAAM,IAAI,CAAC,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,IAAI,CAAC,EAAE;YAClF,cAAc,EACZ,6IAA6I;SAChJ,CAAC;KACH,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { z } from "zod";
2
+ export declare const detectorThresholdsSchema: z.ZodObject<{
3
+ schemaVersion: z.ZodNumber;
4
+ profile: z.ZodOptional<z.ZodString>;
5
+ lastUpdated: z.ZodString;
6
+ notes: z.ZodDefault<z.ZodArray<z.ZodString>>;
7
+ bytecode: z.ZodObject<{
8
+ contractSize: z.ZodObject<{
9
+ currentRuntimeLimitBytes: z.ZodNumber;
10
+ nearCurrentLimitBytes: z.ZodNumber;
11
+ }, z.core.$strip>;
12
+ stateAccountOpcodeExposure: z.ZodObject<{
13
+ mediumSensitiveOpcodeCount: z.ZodNumber;
14
+ lowSensitiveOpcodeCount: z.ZodNumber;
15
+ }, z.core.$strip>;
16
+ storagePattern: z.ZodObject<{
17
+ mediumStorageOpcodeCount: z.ZodNumber;
18
+ }, z.core.$strip>;
19
+ }, z.core.$strip>;
20
+ trace: z.ZodObject<{
21
+ stateHeavyExecution: z.ZodObject<{
22
+ highStorageOps: z.ZodNumber;
23
+ highSensitiveOpcodeCount: z.ZodNumber;
24
+ mediumStorageOps: z.ZodNumber;
25
+ mediumSensitiveOpcodeCount: z.ZodNumber;
26
+ }, z.core.$strip>;
27
+ calldataHeavy: z.ZodObject<{
28
+ mediumCalldataBytes: z.ZodNumber;
29
+ }, z.core.$strip>;
30
+ }, z.core.$strip>;
31
+ }, z.core.$strip>;
32
+ export type DetectorThresholds = z.infer<typeof detectorThresholdsSchema>;
33
+ export declare function defaultThresholdsPath(): string;
34
+ export declare function loadDetectorThresholds(thresholdsPath?: string): DetectorThresholds;