@elytrasec/engine 0.3.0 → 0.3.1
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/dist/index.d.ts +28 -1
- package/dist/index.js +280 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1291,4 +1291,31 @@ interface DiscoverOptions {
|
|
|
1291
1291
|
*/
|
|
1292
1292
|
declare function discoverFiles(targetPath: string, opts?: DiscoverOptions): DiscoveredFile[];
|
|
1293
1293
|
|
|
1294
|
-
|
|
1294
|
+
/**
|
|
1295
|
+
* Agentic PoC generator.
|
|
1296
|
+
*
|
|
1297
|
+
* Given a Finding from our scanner and the vulnerable contract source,
|
|
1298
|
+
* asks Claude to write a Foundry exploit test, then tries to run it
|
|
1299
|
+
* against an Anvil fork to confirm the vulnerability is actually exploitable.
|
|
1300
|
+
*
|
|
1301
|
+
* Returns a PocResult indicating whether the finding was confirmed, along
|
|
1302
|
+
* with the generated test and execution output.
|
|
1303
|
+
*
|
|
1304
|
+
* Degrades gracefully when forge/anvil are not installed — the PoC code
|
|
1305
|
+
* is still generated, status is "generated" rather than "confirmed".
|
|
1306
|
+
*/
|
|
1307
|
+
|
|
1308
|
+
type PocStatus = "confirmed" | "not-exploitable" | "generated" | "error";
|
|
1309
|
+
interface PocResult {
|
|
1310
|
+
status: PocStatus;
|
|
1311
|
+
pocCode: string;
|
|
1312
|
+
output: string;
|
|
1313
|
+
rpcUrl?: string;
|
|
1314
|
+
}
|
|
1315
|
+
declare class PocGenerator {
|
|
1316
|
+
private provider;
|
|
1317
|
+
constructor(provider: AIProvider);
|
|
1318
|
+
generate(finding: Finding, contractSource: string, rpcUrl?: string): Promise<PocResult>;
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
export { AIClient, type AICompleteParams, type AICompleteResult, type AIMessage, type AIProvider, type AnalyzeCodeParams, type AnalyzeFileParams, type AnalyzeParams, AnthropicProvider, type ApplyFixesResult, type AuditIssue, type AuditReport, CWE_OWASP_MAP, type Chain, type ChangeType, type CreateProviderOptions, type CweOwaspEntry, type DepInfo, type DepVulnerability, type DependencyReport, type DiffChange, type DiffChunk, type DiffFile, type DiffHunk, type DiscoverOptions, type DiscoveredFile, type Ecosystem, type ElytraConfig, type FileClassification, type FileFixInput, type FileFixResult, type FileStatus, type FileTransform, type Finding, FindingSchema, type Framework, type FullScanParams, type GitHubReviewComment, type HardenResult, type HardenSuggestion, type IssueCategory, type Language, MockProvider, OllamaProvider, OpenAIProvider, type ParsedDiff, type PatternRule, PocGenerator, type PocResult, type PocStatus, type ProjectFile, type ProjectSummary, type ReportOptions, type ReviewResult, ReviewResultSchema, type RewriteResult, type Rule, type SecurityScore, type SecurityScoreOutput, SecurityScoreSchema, type Severity, SeveritySchema, type StaticAnalysisOptions, type StaticAnalysisResult, type StaticFinding, type ToolRunner, type ToolRunnerOptions, type TransformResult, type UpgradeItem, type UpgradeOptions, type UpgradePlan, type UpgradeResult, type UpgradeType, ALL_RULES as _ALL_RULES, scanFile as _scanFile, analyze, analyzeDependencies, analyzeFullScan, apiRules, applyFixes, applyHardenFix, auditCodebase, authRules, bestPracticeRules, classifyFile, complexityRules, computeScore, createProvider, deadCodeRules, dedupeFindings, discoverFiles, filterByConfig, formatAsReviewComments, formatStaticFindingsForAI, gasRules, generalRules, generateFallbackPlan, generateMarkdownReport, generateUpgradePlan, getAllRules, getCweOwasp, getRulesForChains, getSystemPrompt, gitleaksRunner, ingestRepo, injectionRules, loadConfig, logger, namingRules, parseDiff, patternScannerRunner, readRepoFile, readRepoFiles, reconRules, rewriteFile, rewriteFiles, runHarden, runStaticAnalysis, runUpgrade, semgrepRunner, slitherRunner, solidityRules, splitIntoChunks, transformFiles, validateFixedSyntax };
|
package/dist/index.js
CHANGED
|
@@ -4603,6 +4603,112 @@ var iacRules = [
|
|
|
4603
4603
|
pathPattern: /\.github[/\\]workflows[/\\]/
|
|
4604
4604
|
}
|
|
4605
4605
|
];
|
|
4606
|
+
var eip7702Rules = [
|
|
4607
|
+
{
|
|
4608
|
+
id: "cp-sol-7702-unguarded-init",
|
|
4609
|
+
title: "EIP-7702 delegation: unguarded initializer",
|
|
4610
|
+
description: "Contracts used as EIP-7702 delegation targets must guard initializers \u2014 constructors don't run on delegated EOAs. An unguarded `initialize()` can be front-run, letting an attacker take ownership of the delegated account.",
|
|
4611
|
+
suggestion: "Add an `initializer` modifier (OpenZeppelin) or an `initialized` flag checked at the top of every init function. Ensure no init path is callable twice.",
|
|
4612
|
+
pattern: /function\s+initialize\s*\([^)]*\)\s*(?:external|public)(?!\s+\w*[Ii]nitializer)/,
|
|
4613
|
+
severity: "critical",
|
|
4614
|
+
category: "solidity",
|
|
4615
|
+
confidence: "medium",
|
|
4616
|
+
languages: SOL
|
|
4617
|
+
},
|
|
4618
|
+
{
|
|
4619
|
+
id: "cp-sol-7702-nonce-race",
|
|
4620
|
+
title: "EIP-7702 delegation: nonce race condition",
|
|
4621
|
+
description: "EIP-7702 authorization tuples share the EOA nonce space with regular transactions. A pending delegation can be invalidated or front-run by submitting a regular transaction that increments the nonce before the authorization is mined.",
|
|
4622
|
+
suggestion: "Always set `nonce` explicitly in authorization tuples. Do not rely on mempool ordering for security-sensitive delegations \u2014 use a commit-reveal or atomic multicall pattern.",
|
|
4623
|
+
pattern: /authorization\s*=\s*\{[^}]*nonce\s*:\s*0[^x]/i,
|
|
4624
|
+
severity: "high",
|
|
4625
|
+
category: "solidity",
|
|
4626
|
+
confidence: "medium",
|
|
4627
|
+
languages: SOL
|
|
4628
|
+
}
|
|
4629
|
+
];
|
|
4630
|
+
var tstoreRules = [
|
|
4631
|
+
{
|
|
4632
|
+
id: "cp-sol-tstore-reentrancy",
|
|
4633
|
+
title: "Transient storage (TSTORE) used \u2014 verify reentrancy safety",
|
|
4634
|
+
description: "Transient storage (EIP-1153, live since Cancun) does not impose the 2300 gas minimum of SSTORE-based guards. If this contract also uses `transfer()` or `send()` for ETH, those calls are no longer reentrancy-safe \u2014 the callee has enough gas to re-enter via TLOAD/TSTORE paths.",
|
|
4635
|
+
suggestion: 'Audit every ETH transfer in this contract. Replace `transfer()`/`send()` with `call{value:}("")` + explicit reentrancy check. Ensure TSTORE lock is written before any external call.',
|
|
4636
|
+
pattern: /assembly\s*\{[^}]*tstore\s*\(|TransientSlot|tstore\s*\(/i,
|
|
4637
|
+
severity: "high",
|
|
4638
|
+
category: "solidity",
|
|
4639
|
+
confidence: "medium",
|
|
4640
|
+
languages: SOL
|
|
4641
|
+
},
|
|
4642
|
+
{
|
|
4643
|
+
id: "cp-sol-tstore-lock-pattern",
|
|
4644
|
+
title: "Transient storage lock: verify all entry points are guarded",
|
|
4645
|
+
description: "TSTORE-based reentrancy locks reset at transaction end (not call end). A lock set in `functionA` does NOT protect `functionB` called in a separate transaction, and a lock set mid-call does NOT protect earlier entry points in the same call chain.",
|
|
4646
|
+
suggestion: "Apply the TSTORE lock modifier to every external/public function that modifies state, not just the function that initiates the ETH transfer.",
|
|
4647
|
+
pattern: /assembly\s*\{[^}]*tload\s*\([^}]*\)[^}]*tstore\s*\(/is,
|
|
4648
|
+
severity: "medium",
|
|
4649
|
+
category: "solidity",
|
|
4650
|
+
confidence: "low",
|
|
4651
|
+
languages: SOL
|
|
4652
|
+
}
|
|
4653
|
+
];
|
|
4654
|
+
var uniswapV4Rules = [
|
|
4655
|
+
{
|
|
4656
|
+
id: "cp-sol-v4hook-missing-sender-check",
|
|
4657
|
+
title: "Uniswap v4 hook: missing PoolManager sender validation",
|
|
4658
|
+
description: "Hook callbacks (`beforeSwap`, `afterSwap`, `beforeAddLiquidity`, etc.) must verify `msg.sender == address(poolManager)`. Without this check, any address can call the hook directly and manipulate its state.",
|
|
4659
|
+
suggestion: 'Add `require(msg.sender == address(poolManager), "not PoolManager");` as the first line of every hook callback, or inherit from `BaseHook` which enforces this automatically.',
|
|
4660
|
+
pattern: /function\s+(?:before|after)(?:Swap|AddLiquidity|RemoveLiquidity|Initialize|Donate)\s*\(/,
|
|
4661
|
+
severity: "critical",
|
|
4662
|
+
category: "solidity",
|
|
4663
|
+
confidence: "medium",
|
|
4664
|
+
languages: SOL
|
|
4665
|
+
},
|
|
4666
|
+
{
|
|
4667
|
+
id: "cp-sol-v4hook-reentrancy-callback",
|
|
4668
|
+
title: "Uniswap v4 hook: external call inside hook callback",
|
|
4669
|
+
description: "Making external calls from within a hook callback (beforeSwap, afterSwap, etc.) while the PoolManager lock is held can trigger reentrancy into the pool. The singleton PoolManager uses a transient-storage lock that is bypassable via hooks that call back into the pool.",
|
|
4670
|
+
suggestion: "Avoid external calls in hook callbacks. If you must call out, use the `unlockCallback` pattern to queue actions and execute them after the current lock cycle completes.",
|
|
4671
|
+
pattern: /function\s+(?:before|after)(?:Swap|AddLiquidity|RemoveLiquidity|Initialize|Donate)[\s\S]{0,500}?\.call\s*\{/,
|
|
4672
|
+
multilinePattern: /function\s+(before|after)(Swap|AddLiquidity|RemoveLiquidity|Initialize|Donate)\s*\([^)]*\)[^{]*\{[\s\S]{0,800}?(?:\.call\s*\{|\.transfer\s*\(|\.send\s*\()/gm,
|
|
4673
|
+
severity: "critical",
|
|
4674
|
+
category: "solidity",
|
|
4675
|
+
confidence: "medium",
|
|
4676
|
+
languages: SOL
|
|
4677
|
+
},
|
|
4678
|
+
{
|
|
4679
|
+
id: "cp-sol-v4hook-delta-not-consumed",
|
|
4680
|
+
title: "Uniswap v4 hook: BalanceDelta returned without settle/take",
|
|
4681
|
+
description: "Hooks that return a modified `BalanceDelta` must ensure the delta is fully consumed (settled or taken) within the same unlock cycle. An unconsumed delta causes `CurrencyNotSettled` revert; partial consumption can silently strand tokens.",
|
|
4682
|
+
suggestion: "Ensure `poolManager.settle()` or `poolManager.take()` is called for both currency0 and currency1 before returning from the unlock callback.",
|
|
4683
|
+
pattern: /returns\s*\([^)]*BalanceDelta[^)]*\)(?![\s\S]{0,800}?(?:settle|\.take)\s*\()/,
|
|
4684
|
+
severity: "high",
|
|
4685
|
+
category: "solidity",
|
|
4686
|
+
confidence: "low",
|
|
4687
|
+
languages: SOL
|
|
4688
|
+
},
|
|
4689
|
+
{
|
|
4690
|
+
id: "cp-sol-v4hook-unrestricted-permissions",
|
|
4691
|
+
title: "Uniswap v4 hook: overly broad hook permissions",
|
|
4692
|
+
description: "Hook permissions are set at deployment via the address bit-flags and cannot be changed. Requesting permissions you don't need (e.g. `BEFORE_SWAP_RETURNS_DELTA` when you never return a delta) increases attack surface and gas costs for every pool interaction.",
|
|
4693
|
+
suggestion: "Return only the minimum required `Hooks.Permissions` from `getHookPermissions()`. Audit each permission flag against your actual callback implementations.",
|
|
4694
|
+
pattern: /getHookPermissions\s*\(\s*\)\s*(?:public|external|override)[^{]*\{[\s\S]{0,300}?true/,
|
|
4695
|
+
severity: "medium",
|
|
4696
|
+
category: "solidity",
|
|
4697
|
+
confidence: "low",
|
|
4698
|
+
languages: SOL
|
|
4699
|
+
},
|
|
4700
|
+
{
|
|
4701
|
+
id: "cp-sol-v4hook-sqrt-price-manipulation",
|
|
4702
|
+
title: "Uniswap v4 hook: spot sqrtPriceX96 used for pricing without limit",
|
|
4703
|
+
description: "Using spot `sqrtPriceX96` read from pool state inside a hook callback for pricing decisions without a `sqrtPriceLimitX96` bound is sandwich-attackable. The price reflects post-swap state which may be manipulated.",
|
|
4704
|
+
suggestion: "Pass `sqrtPriceLimitX96` to all swap calls from hooks. Use a TWAP oracle for pricing rather than spot price.",
|
|
4705
|
+
pattern: /sqrtPriceX96\s*[*/+-]\s*\w|sqrtPriceX96\s*=\s*(?!.*[Ll]imit)/,
|
|
4706
|
+
severity: "high",
|
|
4707
|
+
category: "solidity",
|
|
4708
|
+
confidence: "low",
|
|
4709
|
+
languages: SOL
|
|
4710
|
+
}
|
|
4711
|
+
];
|
|
4606
4712
|
var ALL_RULES2 = [
|
|
4607
4713
|
...securityRules,
|
|
4608
4714
|
...solidityRules2,
|
|
@@ -4613,7 +4719,10 @@ var ALL_RULES2 = [
|
|
|
4613
4719
|
...performanceRules,
|
|
4614
4720
|
...cleaningRules,
|
|
4615
4721
|
...reactRules,
|
|
4616
|
-
...iacRules
|
|
4722
|
+
...iacRules,
|
|
4723
|
+
...eip7702Rules,
|
|
4724
|
+
...tstoreRules,
|
|
4725
|
+
...uniswapV4Rules
|
|
4617
4726
|
];
|
|
4618
4727
|
|
|
4619
4728
|
// src/static/pattern-scanner.ts
|
|
@@ -7914,6 +8023,175 @@ function buildSummary2(findings, fileCount, toolsRan) {
|
|
|
7914
8023
|
}
|
|
7915
8024
|
return summary;
|
|
7916
8025
|
}
|
|
8026
|
+
|
|
8027
|
+
// src/ai/poc-generator.ts
|
|
8028
|
+
import { execFile as execFile7 } from "child_process";
|
|
8029
|
+
import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
8030
|
+
import { promisify as promisify7 } from "util";
|
|
8031
|
+
import { tmpdir } from "os";
|
|
8032
|
+
import { join as join4 } from "path";
|
|
8033
|
+
import { randomBytes } from "crypto";
|
|
8034
|
+
var exec7 = promisify7(execFile7);
|
|
8035
|
+
var SYSTEM_PROMPT = `You are an expert smart contract security researcher who writes Foundry (forge) exploit tests to demonstrate vulnerabilities.
|
|
8036
|
+
|
|
8037
|
+
Given a security finding and the vulnerable contract source code, write a minimal Foundry test that:
|
|
8038
|
+
1. Deploys the vulnerable contract (or a minimal reproduction of the vulnerable pattern)
|
|
8039
|
+
2. Demonstrates the exploit in a test function named test_exploit()
|
|
8040
|
+
3. Uses vm.expectRevert() or assertions to show the vulnerability is real
|
|
8041
|
+
4. Includes a brief comment explaining the attack vector
|
|
8042
|
+
|
|
8043
|
+
Rules:
|
|
8044
|
+
- Use Solidity ^0.8.20 and Foundry's Test base
|
|
8045
|
+
- Import only from forge-std (available: Test, console, Vm, StdCheats)
|
|
8046
|
+
- If the contract needs an RPC fork (e.g. for on-chain state), emit a // @fork-required comment on line 1
|
|
8047
|
+
- Keep it minimal \u2014 prove the bug, nothing else
|
|
8048
|
+
- Return ONLY valid Solidity, no markdown fences, no explanation outside comments
|
|
8049
|
+
|
|
8050
|
+
Format:
|
|
8051
|
+
\`\`\`solidity
|
|
8052
|
+
// SPDX-License-Identifier: MIT
|
|
8053
|
+
pragma solidity ^0.8.20;
|
|
8054
|
+
|
|
8055
|
+
import "forge-std/Test.sol";
|
|
8056
|
+
|
|
8057
|
+
contract ExploitTest is Test {
|
|
8058
|
+
// ...setup...
|
|
8059
|
+
|
|
8060
|
+
function test_exploit() public {
|
|
8061
|
+
// ...exploit...
|
|
8062
|
+
}
|
|
8063
|
+
}
|
|
8064
|
+
\`\`\``;
|
|
8065
|
+
function buildUserMessage(finding, contractSource) {
|
|
8066
|
+
return `## Vulnerability Finding
|
|
8067
|
+
|
|
8068
|
+
Rule ID: ${finding.ruleId}
|
|
8069
|
+
Title: ${finding.title}
|
|
8070
|
+
Severity: ${finding.severity}
|
|
8071
|
+
File: ${finding.filePath} (lines ${finding.startLine}\u2013${finding.endLine})
|
|
8072
|
+
Description: ${finding.description}
|
|
8073
|
+
|
|
8074
|
+
Vulnerable code snippet:
|
|
8075
|
+
\`\`\`solidity
|
|
8076
|
+
${finding.codeSnippet}
|
|
8077
|
+
\`\`\`
|
|
8078
|
+
|
|
8079
|
+
Fix suggestion: ${finding.suggestion}
|
|
8080
|
+
|
|
8081
|
+
## Full Contract Source
|
|
8082
|
+
|
|
8083
|
+
\`\`\`solidity
|
|
8084
|
+
${contractSource}
|
|
8085
|
+
\`\`\`
|
|
8086
|
+
|
|
8087
|
+
Write the Foundry exploit test now.`;
|
|
8088
|
+
}
|
|
8089
|
+
function extractSolidity(text) {
|
|
8090
|
+
const fenceMatch = text.match(/```(?:solidity)?\s*([\s\S]*?)```/);
|
|
8091
|
+
if (fenceMatch) return fenceMatch[1].trim();
|
|
8092
|
+
return text.trim();
|
|
8093
|
+
}
|
|
8094
|
+
async function forgeAvailable() {
|
|
8095
|
+
try {
|
|
8096
|
+
await exec7("forge", ["--version"], { timeout: 5e3 });
|
|
8097
|
+
return true;
|
|
8098
|
+
} catch {
|
|
8099
|
+
return false;
|
|
8100
|
+
}
|
|
8101
|
+
}
|
|
8102
|
+
async function runForgeTest(pocCode, rpcUrl) {
|
|
8103
|
+
const id = randomBytes(6).toString("hex");
|
|
8104
|
+
const dir = join4(tmpdir(), `elytra-poc-${id}`);
|
|
8105
|
+
const srcDir = join4(dir, "src");
|
|
8106
|
+
const testDir = join4(dir, "test");
|
|
8107
|
+
const libDir = join4(dir, "lib");
|
|
8108
|
+
try {
|
|
8109
|
+
await mkdir2(srcDir, { recursive: true });
|
|
8110
|
+
await mkdir2(testDir, { recursive: true });
|
|
8111
|
+
await mkdir2(libDir, { recursive: true });
|
|
8112
|
+
await writeFile2(
|
|
8113
|
+
join4(dir, "foundry.toml"),
|
|
8114
|
+
`[profile.default]
|
|
8115
|
+
src = "src"
|
|
8116
|
+
out = "out"
|
|
8117
|
+
libs = ["lib"]
|
|
8118
|
+
`
|
|
8119
|
+
);
|
|
8120
|
+
const testFile = join4(testDir, "Exploit.t.sol");
|
|
8121
|
+
await writeFile2(testFile, pocCode);
|
|
8122
|
+
const args = ["test", "--match-contract", "ExploitTest", "--no-match-coverage", "-vv"];
|
|
8123
|
+
if (rpcUrl) {
|
|
8124
|
+
args.push("--fork-url", rpcUrl);
|
|
8125
|
+
}
|
|
8126
|
+
const { stdout, stderr } = await exec7("forge", args, {
|
|
8127
|
+
cwd: dir,
|
|
8128
|
+
timeout: 6e4,
|
|
8129
|
+
env: { ...process.env, FOUNDRY_PROFILE: "default" }
|
|
8130
|
+
});
|
|
8131
|
+
const output = [stdout, stderr].filter(Boolean).join("\n");
|
|
8132
|
+
const passed = output.includes("PASS") || output.includes("ok");
|
|
8133
|
+
return { success: passed, output };
|
|
8134
|
+
} catch (err) {
|
|
8135
|
+
const output = err.stdout ?? err.stderr ?? String(err);
|
|
8136
|
+
return { success: false, output };
|
|
8137
|
+
} finally {
|
|
8138
|
+
exec7("rm", ["-rf", dir]).catch(() => {
|
|
8139
|
+
});
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
var PocGenerator = class {
|
|
8143
|
+
provider;
|
|
8144
|
+
constructor(provider) {
|
|
8145
|
+
this.provider = provider;
|
|
8146
|
+
}
|
|
8147
|
+
async generate(finding, contractSource, rpcUrl) {
|
|
8148
|
+
if (finding.category !== "solidity" && !finding.ruleId.startsWith("cp-sol")) {
|
|
8149
|
+
return {
|
|
8150
|
+
status: "error",
|
|
8151
|
+
pocCode: "",
|
|
8152
|
+
output: "PoC generation only supported for Solidity findings"
|
|
8153
|
+
};
|
|
8154
|
+
}
|
|
8155
|
+
let pocCode = "";
|
|
8156
|
+
try {
|
|
8157
|
+
const response = await this.provider.complete({
|
|
8158
|
+
messages: [
|
|
8159
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
8160
|
+
{ role: "user", content: buildUserMessage(finding, contractSource) }
|
|
8161
|
+
],
|
|
8162
|
+
maxTokens: 4096
|
|
8163
|
+
});
|
|
8164
|
+
pocCode = extractSolidity(response.text);
|
|
8165
|
+
if (!pocCode) {
|
|
8166
|
+
return { status: "error", pocCode: "", output: "AI returned empty response" };
|
|
8167
|
+
}
|
|
8168
|
+
} catch (err) {
|
|
8169
|
+
logger.error(`PocGenerator: AI call failed: ${err}`);
|
|
8170
|
+
return { status: "error", pocCode: "", output: String(err) };
|
|
8171
|
+
}
|
|
8172
|
+
const hasForge = await forgeAvailable();
|
|
8173
|
+
if (!hasForge) {
|
|
8174
|
+
logger.info("PocGenerator: forge not available, returning generated code only");
|
|
8175
|
+
return {
|
|
8176
|
+
status: "generated",
|
|
8177
|
+
pocCode,
|
|
8178
|
+
output: "forge not installed \u2014 PoC generated but not executed",
|
|
8179
|
+
rpcUrl
|
|
8180
|
+
};
|
|
8181
|
+
}
|
|
8182
|
+
const forkRequired = pocCode.includes("@fork-required");
|
|
8183
|
+
const { success, output } = await runForgeTest(
|
|
8184
|
+
pocCode,
|
|
8185
|
+
forkRequired ? rpcUrl : void 0
|
|
8186
|
+
);
|
|
8187
|
+
return {
|
|
8188
|
+
status: success ? "confirmed" : "not-exploitable",
|
|
8189
|
+
pocCode,
|
|
8190
|
+
output,
|
|
8191
|
+
rpcUrl: forkRequired ? rpcUrl : void 0
|
|
8192
|
+
};
|
|
8193
|
+
}
|
|
8194
|
+
};
|
|
7917
8195
|
export {
|
|
7918
8196
|
AIClient,
|
|
7919
8197
|
AnthropicProvider,
|
|
@@ -7922,6 +8200,7 @@ export {
|
|
|
7922
8200
|
MockProvider,
|
|
7923
8201
|
OllamaProvider,
|
|
7924
8202
|
OpenAIProvider,
|
|
8203
|
+
PocGenerator,
|
|
7925
8204
|
ReviewResultSchema,
|
|
7926
8205
|
SecurityScoreSchema,
|
|
7927
8206
|
SeveritySchema,
|
package/package.json
CHANGED