File size: 3,660 Bytes
52550fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import "dotenv/config";
import { readFileSync, mkdirSync, writeFileSync } from "fs";
import { resolve } from "path";
import { tmpdir } from "os";

import { coderAgent } from "./src/agents/coder/agent.js";
import { auditorAgent } from "./src/agents/auditor/agent.js";
import { testerAgent } from "./src/agents/tester/agent.js";
import { mapFindingToReport } from "./src/utils/mapFinding.js";

async function runFullFlow() {
  const reqPath = resolve("input/requirements.md");
  const requirements = readFileSync(reqPath, "utf-8");

  console.log("=== 1. CODER AGENT ===");
  console.log("Generating contract...");
  const coderResult = await coderAgent.invoke({ requirements: [requirements] });
  console.log(`Contract generated successfully (${coderResult.contract.length} bytes).`);
  console.log(`Compilation Errors: ${coderResult.compilationErrors.length}`);

  console.log("\n=== 2. AUDITOR AGENT ===");
  const outputDir = resolve(tmpdir(), `talp1-e2e-${Date.now()}`);
  mkdirSync(outputDir, { recursive: true });
  writeFileSync(resolve(outputDir, "Contract.sol"), coderResult.contract, "utf-8");
  writeFileSync(resolve(outputDir, "README.md"), requirements, "utf-8");
  console.log(`Created temporary sandbox at: ${outputDir}`);

  const auditorResult = await auditorAgent.invoke({ repoPath: outputDir });
  console.log(`Findings found: ${auditorResult.findings.length}`);

  if (auditorResult.findings.length === 0) {
    console.log("No vulnerabilities found by Auditor. Injecting a fake finding to test Tester agent.");
    auditorResult.findings.push({
      title: "Função burn não respeita o estado de pausa",
      description: "A função `burn` permite que qualquer usuário queime seus próprios tokens, mas não possui o modificador `whenNotPaused`.",
      recommendation: "Adicionar o modificador `whenNotPaused` à função `burn`.",
      severity: "low",
      codeSnippet: "    function burn(uint256 amount) external {\n        _burn(msg.sender, amount);\n    }",
      path: resolve(outputDir, "Contract.sol"),
      location: "L78-80",
      judgeReview: {
        review: "Mocked review",
        isFalsePositive: false,
        confidence: 100,
        exploitablePaths: ["Call pause() then call burn() and it succeeds."]
      }
    } as any);
  }

  for (let i = 0; i < auditorResult.findings.length; i++) {
    const f = auditorResult.findings[i];
    console.log(`\n[Finding ${i + 1}] ${f.severity.toUpperCase()} - ${f.title}`);
    console.log(`Location: ${f.location}`);
  }

  console.log("\n=== 3. TESTER AGENT ===");
  // Only test the first finding, simulating server.ts
  const firstFinding = auditorResult.findings[0];
  
  const report = mapFindingToReport(
    firstFinding,
    coderResult.contract,
    auditorResult.repoContext
  );
  report.customSandboxDir = outputDir;

  console.log("Mapped Report for Tester:");
  console.log(`- ID: ${report.id}`);
  console.log(`- Type: ${report.type}`);
  console.log(`- Attack Vector: ${report.attackVector}`);
  console.log(`- Custom Sandbox Dir: ${report.customSandboxDir}`);
  console.log(`- Description length: ${report.description.length} chars (contains auditor context)`);

  const testerResult = await testerAgent.invoke({ report });
  
  console.log(`\n=== FINAL RESULT ===`);
  console.log(`Tester Status: ${testerResult.status}`);
  console.log(`Iterations: ${testerResult.iterations}`);
  if (testerResult.status === "success") {
    console.log(`\n--- GENERATED POC ---`);
    console.log(testerResult.pocCode || testerResult.solidityCode);
  } else {
    console.log("Tester failed to generate a working PoC.");
  }
}

runFullFlow().catch(console.error);