Tales-Cunha
docs: create tester architecture definition
4e2e30e
Raw
History Blame
2.91 kB
import type { VulnerabilityReport } from "../agents/tester/types.js";
/**
* Maps a Finding from the Auditor to a VulnerabilityReport for the Tester.
* Enriches the description with all available auditor context:
* judge review, recommendation, exploit paths — giving the tester
* maximum information to generate a precise, specific PoC.
*/
export function mapFindingToReport(
finding: any,
sourceCode: string,
repoContext?: string
): VulnerabilityReport {
const title = finding.title || "Unknown vulnerability";
const nameMatch = finding.path?.match(/([^\/]+)\.sol$/);
const contractName = nameMatch ? nameMatch[1] : "TargetContract";
const exploitablePaths: string[] = finding.judgeReview?.exploitablePaths || [];
// Build a rich description combining all auditor context
const descriptionParts: string[] = [
finding.description || "No description provided by auditor.",
];
if (finding.judgeReview?.review) {
descriptionParts.push(`\n## Judge Analysis\n${finding.judgeReview.review}`);
}
if (finding.recommendation) {
descriptionParts.push(`\n## Recommended Fix\n${finding.recommendation}`);
}
if (exploitablePaths.length > 0) {
descriptionParts.push(`\n## Exploit Paths (step-by-step)\n${exploitablePaths.map((p, i) => `${i + 1}. ${p}`).join("\n")}`);
}
if (repoContext) {
descriptionParts.push(`\n## Protocol Context\n${repoContext.slice(0, 1500)}`);
}
// Infer vulnerability type from title/description when auditor doesn't provide one
const inferType = (): string => {
const text = `${title} ${finding.description || ""}`.toLowerCase();
if (text.includes("reentr")) return "reentrancy";
if (text.includes("access control") || text.includes("unauthorized")) return "access control";
if (text.includes("overflow") || text.includes("underflow")) return "arithmetic";
if (text.includes("flash loan")) return "flash loan";
if (text.includes("oracle") || text.includes("price manipul")) return "oracle manipulation";
if (text.includes("denial of service") || text.includes("dos")) return "denial of service";
if (text.includes("front.run") || text.includes("sandwich")) return "front-running";
return "logic error";
};
const severity = ["critical", "high", "medium", "low"].includes(finding.severity)
? finding.severity
: "medium";
return {
id: title.toLowerCase().replace(/[^a-z0-9]+/g, "-").slice(0, 50),
severity: severity as VulnerabilityReport["severity"],
type: inferType(),
title,
description: descriptionParts.join("\n"),
affectedContract: {
name: contractName,
sourceCode,
sourceFilePath: finding.path,
},
attackVector: exploitablePaths[0] ?? finding.description?.slice(0, 120) ?? "Unknown",
exploitablePaths,
codeSnippet: finding.codeSnippet,
location: finding.location,
suggestedCheatcodes: [],
};
}