Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
{
"description": "Realistic repository fixture covering multi-language DEX smart contracts and bridges",
"tenantId": "org-defi-protocols",
"repositoryId": "stellar-evm-dex-repo",
"commitHash": "9f3c2a71d4e85b0c6a1f27e3d98b54c0a2e1f6d7",
"rulePackVersion": "2.1.0",
"languageOutputs": {
"solidity": {
"language": "solidity",
"filesAnalyzed": 2,
"findings": [
{
"ruleId": "gas-opt-uncached-array-length",
"message": "Array length should be cached outside for-loop condition to save gas",
"severity": "low",
"location": {
"file": "contracts/evm/BridgeVault.sol",
"startLine": 45,
"endLine": 45,
"startColumn": 12,
"endColumn": 30
},
"estimatedGasSavings": 320
},
{
"ruleId": "sec-reentrancy-eth-transfer",
"message": "Potential reentrancy vulnerability via external call before state update",
"severity": "high",
"location": {
"file": "contracts/evm/BridgeVault.sol",
"startLine": 112,
"endLine": 118,
"startColumn": 8,
"endColumn": 10
}
}
],
"summary": {
"critical": 0,
"high": 1,
"medium": 0,
"low": 1,
"info": 0
},
"totalEstimatedGasSavings": 320
},
"soroban": {
"language": "soroban",
"filesAnalyzed": 4,
"findings": [
{
"ruleId": "soroban-storage-rent-bump",
"message": "Persistent storage entry missing rent bump on active access",
"severity": "medium",
"location": {
"file": "contracts/soroban/amm_pool/src/lib.rs",
"startLine": 78,
"endLine": 82,
"startColumn": 4,
"endColumn": 6
}
}
],
"summary": {
"critical": 0,
"high": 0,
"medium": 1,
"low": 0,
"info": 0
}
},
"rust": {
"language": "rust",
"filesAnalyzed": 2,
"findings": [],
"summary": {
"critical": 0,
"high": 0,
"medium": 0,
"low": 0,
"info": 0
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
{
"description": "Regression case fixture showing modified and unexpected findings",
"tenantId": "org-defi-protocols",
"repositoryId": "stellar-evm-dex-repo",
"commitHash": "9f3c2a71d4e85b0c6a1f27e3d98b54c0a2e1f6d7",
"rulePackVersion": "2.1.0",
"actualOutputsWithRegression": {
"solidity": {
"language": "solidity",
"filesAnalyzed": 2,
"findings": [
{
"ruleId": "gas-opt-uncached-array-length",
"message": "Array length should be cached outside for-loop condition to save gas",
"severity": "low",
"location": {
"file": "contracts/evm/BridgeVault.sol",
"startLine": 45,
"endLine": 45,
"startColumn": 12,
"endColumn": 30
},
"estimatedGasSavings": 320
},
{
"ruleId": "sec-reentrancy-eth-transfer",
"message": "REGRESSED_MESSAGE: Potential reentrancy vulnerability via external call before state update",
"severity": "high",
"location": {
"file": "contracts/evm/BridgeVault.sol",
"startLine": 112,
"endLine": 118,
"startColumn": 8,
"endColumn": 10
}
},
{
"ruleId": "sec-unexpected-regression-rule",
"message": "Spurious finding generated by modified rule-pack engine",
"severity": "critical",
"location": {
"file": "contracts/evm/BridgeVault.sol",
"startLine": 200,
"endLine": 205
}
}
],
"summary": {
"critical": 1,
"high": 1,
"medium": 0,
"low": 1,
"info": 0
},
"totalEstimatedGasSavings": 320
},
"soroban": {
"language": "soroban",
"filesAnalyzed": 4,
"findings": [],
"summary": {
"critical": 0,
"high": 0,
"medium": 0,
"low": 0,
"info": 0
}
}
}
}
52 changes: 52 additions & 0 deletions apps/api/src/golden-snapshots/golden-snapshot-config.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { loadGoldenSnapshotConfig } from "./golden-snapshot-config";
import { GoldenSnapshotError } from "./golden-snapshot-types";

describe("GoldenSnapshotConfig", () => {
it("loads default config when env is empty", () => {
const config = loadGoldenSnapshotConfig({});
expect(config.enabled).toBe(true);
expect(config.enforceMatching).toBe(false);
expect(config.autoUpdate).toBe(false);
expect(config.maxDiffCount).toBe(500);
expect(config.maxPayloadSizeBytes).toBe(10 * 1024 * 1024);
});

it("parses valid custom env variables", () => {
const config = loadGoldenSnapshotConfig({
GOLDEN_SNAPSHOT_ENABLED: "false",
GOLDEN_SNAPSHOT_STORAGE_DIR: "/tmp/snapshots",
GOLDEN_SNAPSHOT_ENFORCE_MATCHING: "true",
GOLDEN_SNAPSHOT_AUTO_UPDATE: "1",
GOLDEN_SNAPSHOT_MAX_DIFF_COUNT: "100",
GOLDEN_SNAPSHOT_MAX_PAYLOAD_SIZE: "2048",
});
expect(config.enabled).toBe(false);
expect(config.storageDir).toBe("/tmp/snapshots");
expect(config.enforceMatching).toBe(true);
expect(config.autoUpdate).toBe(true);
expect(config.maxDiffCount).toBe(100);
expect(config.maxPayloadSizeBytes).toBe(2048);
});

it("throws on invalid maxDiffCount", () => {
expect(() =>
loadGoldenSnapshotConfig({
GOLDEN_SNAPSHOT_MAX_DIFF_COUNT: "not-a-number",
}),
).toThrow(GoldenSnapshotError);

expect(() =>
loadGoldenSnapshotConfig({
GOLDEN_SNAPSHOT_MAX_DIFF_COUNT: "-5",
}),
).toThrow(GoldenSnapshotError);
});

it("throws on invalid maxPayloadSize", () => {
expect(() =>
loadGoldenSnapshotConfig({
GOLDEN_SNAPSHOT_MAX_PAYLOAD_SIZE: "0",
}),
).toThrow(GoldenSnapshotError);
});
});
84 changes: 84 additions & 0 deletions apps/api/src/golden-snapshots/golden-snapshot-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* Configuration options and environment loader for Golden Output Snapshots (#1253).
*/

import { GoldenSnapshotError } from "./golden-snapshot-types";

export interface GoldenSnapshotConfig {
/** Master toggle / kill-switch for golden snapshot verification. */
enabled: boolean;
/** Directory where snapshot manifest JSON files are stored. */
storageDir: string;
/** Whether to fail scans or quality gates when snapshots mismatch. */
enforceMatching: boolean;
/** Allow auto-updating or generating missing snapshots in non-production environments. */
autoUpdate: boolean;
/** Maximum allowable diff count before aborting full diff computation. */
maxDiffCount: number;
/** Maximum snapshot payload size in bytes. */
maxPayloadSizeBytes: number;
}

export const DEFAULT_GOLDEN_SNAPSHOT_CONFIG: GoldenSnapshotConfig = {
enabled: true,
storageDir: process.env.GOLDEN_SNAPSHOT_STORAGE_DIR || "./data/golden-snapshots",
enforceMatching: process.env.GOLDEN_SNAPSHOT_ENFORCE_MATCHING === "true",
autoUpdate: process.env.GOLDEN_SNAPSHOT_AUTO_UPDATE === "true",
maxDiffCount: 500,
maxPayloadSizeBytes: 10 * 1024 * 1024, // 10MB
};

export function loadGoldenSnapshotConfig(
env: Record<string, string | undefined> = process.env,
): GoldenSnapshotConfig {
const enabled =
env.GOLDEN_SNAPSHOT_ENABLED !== undefined
? env.GOLDEN_SNAPSHOT_ENABLED !== "false" && env.GOLDEN_SNAPSHOT_ENABLED !== "0"
: DEFAULT_GOLDEN_SNAPSHOT_CONFIG.enabled;

const storageDir =
env.GOLDEN_SNAPSHOT_STORAGE_DIR || DEFAULT_GOLDEN_SNAPSHOT_CONFIG.storageDir;

const enforceMatching =
env.GOLDEN_SNAPSHOT_ENFORCE_MATCHING !== undefined
? env.GOLDEN_SNAPSHOT_ENFORCE_MATCHING === "true" || env.GOLDEN_SNAPSHOT_ENFORCE_MATCHING === "1"
: DEFAULT_GOLDEN_SNAPSHOT_CONFIG.enforceMatching;

const autoUpdate =
env.GOLDEN_SNAPSHOT_AUTO_UPDATE !== undefined
? env.GOLDEN_SNAPSHOT_AUTO_UPDATE === "true" || env.GOLDEN_SNAPSHOT_AUTO_UPDATE === "1"
: DEFAULT_GOLDEN_SNAPSHOT_CONFIG.autoUpdate;

let maxDiffCount = DEFAULT_GOLDEN_SNAPSHOT_CONFIG.maxDiffCount;
if (env.GOLDEN_SNAPSHOT_MAX_DIFF_COUNT) {
const parsed = parseInt(env.GOLDEN_SNAPSHOT_MAX_DIFF_COUNT, 10);
if (isNaN(parsed) || parsed <= 0) {
throw new GoldenSnapshotError(
"INVALID_CONFIG",
`GOLDEN_SNAPSHOT_MAX_DIFF_COUNT must be a positive integer, got '${env.GOLDEN_SNAPSHOT_MAX_DIFF_COUNT}'`,
);
}
maxDiffCount = parsed;
}

let maxPayloadSizeBytes = DEFAULT_GOLDEN_SNAPSHOT_CONFIG.maxPayloadSizeBytes;
if (env.GOLDEN_SNAPSHOT_MAX_PAYLOAD_SIZE) {
const parsed = parseInt(env.GOLDEN_SNAPSHOT_MAX_PAYLOAD_SIZE, 10);
if (isNaN(parsed) || parsed <= 0) {
throw new GoldenSnapshotError(
"INVALID_CONFIG",
`GOLDEN_SNAPSHOT_MAX_PAYLOAD_SIZE must be a positive integer, got '${env.GOLDEN_SNAPSHOT_MAX_PAYLOAD_SIZE}'`,
);
}
maxPayloadSizeBytes = parsed;
}

return {
enabled,
storageDir,
enforceMatching,
autoUpdate,
maxDiffCount,
maxPayloadSizeBytes,
};
}
Loading
Loading