@reinforcedai/hardhat-security-review 2512.24.1 → 2512.25.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/README.md +10 -10
- package/dist/ReinforcedHardhatRuntimeEnvironmentField.d.ts +9 -9
- package/dist/ReinforcedHardhatRuntimeEnvironmentField.d.ts.map +1 -1
- package/dist/ReinforcedHardhatRuntimeEnvironmentField.js +29 -29
- package/dist/ReinforcedHardhatRuntimeEnvironmentField.js.map +1 -1
- package/dist/consts.d.ts +1 -1
- package/dist/consts.d.ts.map +1 -1
- package/dist/consts.js +2 -2
- package/dist/consts.js.map +1 -1
- package/dist/index.js +30 -30
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ReinforcedHardhatRuntimeEnvironmentField.ts +31 -31
- package/src/consts.ts +1 -1
- package/src/index.ts +30 -30
- package/src/types.ts +3 -3
package/README.md
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
# Reinforced Hardhat Plugin
|
|
2
2
|
|
|
3
|
-
This plugin integrates Reinforced-powered smart contract
|
|
3
|
+
This plugin integrates Reinforced-powered smart contract security reviews into the Hardhat workflow. It enables both automatic and manual security scans of Solidity contracts before deployment, leveraging decentralized intelligence for vulnerability detection and remediation suggestions. The plugin provides tasks for scanning all contracts and formatting the results for easy review.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- Automatic
|
|
8
|
-
- Manual
|
|
9
|
-
- Integration with Reinforced API for contract analysis
|
|
7
|
+
- Automatic scanning after compilation
|
|
8
|
+
- Manual scanning task (`npx hardhat scan`)
|
|
9
|
+
- Integration with the Reinforced API for contract analysis
|
|
10
10
|
- Tabular vulnerability reports
|
|
11
11
|
|
|
12
12
|
## Usage
|
|
13
13
|
|
|
14
|
-
1. Install the plugin and configure your Reinforced API key in
|
|
15
|
-
2. Run `npx hardhat
|
|
16
|
-
3.
|
|
14
|
+
1. Install the plugin and configure your Reinforced API key in hardhat.config.js.
|
|
15
|
+
2. Run `npx hardhat scan` to manually scan contracts.
|
|
16
|
+
3. Security reviews are also performed automatically before deployment.
|
|
17
17
|
|
|
18
18
|
## Configuration
|
|
19
19
|
|
|
@@ -23,11 +23,11 @@ Add the following to your `hardhat.config.js` to enable the plugin:
|
|
|
23
23
|
module.exports = {
|
|
24
24
|
// ...existing config...
|
|
25
25
|
reinforced: {
|
|
26
|
-
compilationHookEnabled: true, // Set to true to enable
|
|
26
|
+
compilationHookEnabled: true, // Set to true to enable automatic scanning
|
|
27
27
|
apiKey: "YOUR_REINFORCED_API_KEY" // Your Reinforced API key
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
- `compilationHookEnabled` (boolean): Enables or disables automatic Reinforced
|
|
33
|
-
- `apiKey` (string): Your API key for accessing Reinforced's
|
|
32
|
+
- `compilationHookEnabled` (boolean): Enables or disables automatic Reinforced security reviews before deployment. The manual scan task always works regardless of this flag.
|
|
33
|
+
- `apiKey` (string): Your API key for accessing Reinforced's security review service.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ScanResult } from './types';
|
|
2
2
|
export declare class ReinforcedHardhatRuntimeEnvironmentField {
|
|
3
|
-
|
|
4
|
-
private
|
|
5
|
-
private
|
|
6
|
-
private
|
|
7
|
-
private
|
|
8
|
-
private
|
|
9
|
-
private
|
|
10
|
-
private
|
|
3
|
+
scanContract(sourceCode: string, apiKey: string, statusCheckInterval?: number, maxRetries?: number, reportFolder?: string): Promise<ScanResult>;
|
|
4
|
+
private checkScanStatusWithRetry;
|
|
5
|
+
private getScanResultWithRetry;
|
|
6
|
+
private requestScanWithRetry;
|
|
7
|
+
private fetchScan;
|
|
8
|
+
private requestScan;
|
|
9
|
+
private checkScanStatus;
|
|
10
|
+
private getScanResult;
|
|
11
11
|
private getPdfReport;
|
|
12
12
|
}
|
|
13
13
|
//# sourceMappingURL=ReinforcedHardhatRuntimeEnvironmentField.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReinforcedHardhatRuntimeEnvironmentField.d.ts","sourceRoot":"","sources":["../src/ReinforcedHardhatRuntimeEnvironmentField.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"ReinforcedHardhatRuntimeEnvironmentField.d.ts","sourceRoot":"","sources":["../src/ReinforcedHardhatRuntimeEnvironmentField.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAwD,MAAM,SAAS,CAAC;AAE3F,qBAAa,wCAAwC;IACtC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;YAgC9I,wBAAwB;YAIxB,sBAAsB;YAItB,oBAAoB;YAIpB,SAAS;YAQT,WAAW;YAcX,eAAe;YAkBf,aAAa;YAmBb,YAAY;CAc3B"}
|
|
@@ -9,11 +9,11 @@ const nanospinner_1 = require("nanospinner");
|
|
|
9
9
|
const consts_1 = require("./consts");
|
|
10
10
|
const types_1 = require("./types");
|
|
11
11
|
class ReinforcedHardhatRuntimeEnvironmentField {
|
|
12
|
-
async
|
|
13
|
-
const taskId = await this.
|
|
12
|
+
async scanContract(sourceCode, apiKey, statusCheckInterval, maxRetries, reportFolder) {
|
|
13
|
+
const taskId = await this.requestScanWithRetry(statusCheckInterval, maxRetries, sourceCode, apiKey);
|
|
14
14
|
let spinner = null;
|
|
15
15
|
while (true) {
|
|
16
|
-
const status = await this.
|
|
16
|
+
const status = await this.checkScanStatusWithRetry(statusCheckInterval, maxRetries, taskId, apiKey);
|
|
17
17
|
if (status == 'pending' || status == 'processing') {
|
|
18
18
|
if (!spinner)
|
|
19
19
|
spinner = (0, nanospinner_1.createSpinner)('Processing...').start();
|
|
@@ -24,7 +24,7 @@ class ReinforcedHardhatRuntimeEnvironmentField {
|
|
|
24
24
|
}
|
|
25
25
|
if (spinner)
|
|
26
26
|
spinner.success();
|
|
27
|
-
const result = this.
|
|
27
|
+
const result = this.getScanResultWithRetry(statusCheckInterval, maxRetries, taskId, apiKey);
|
|
28
28
|
fs_1.default.mkdirSync(reportFolder ?? './reinforcedai_reports', { recursive: true });
|
|
29
29
|
try {
|
|
30
30
|
const report = await this.getPdfReport(taskId, apiKey);
|
|
@@ -40,68 +40,68 @@ class ReinforcedHardhatRuntimeEnvironmentField {
|
|
|
40
40
|
}
|
|
41
41
|
return result;
|
|
42
42
|
}
|
|
43
|
-
async
|
|
44
|
-
return await retryHttpRequest(() => this.
|
|
43
|
+
async checkScanStatusWithRetry(retryDelay, maxRetries, ...args) {
|
|
44
|
+
return await retryHttpRequest(() => this.checkScanStatus(...args), retryDelay, maxRetries);
|
|
45
45
|
}
|
|
46
|
-
async
|
|
47
|
-
return await retryHttpRequest(() => this.
|
|
46
|
+
async getScanResultWithRetry(retryDelay, maxRetries, ...args) {
|
|
47
|
+
return await retryHttpRequest(() => this.getScanResult(...args), retryDelay, maxRetries);
|
|
48
48
|
}
|
|
49
|
-
async
|
|
50
|
-
return await retryHttpRequest(() => this.
|
|
49
|
+
async requestScanWithRetry(retryDelay, maxRetries, ...args) {
|
|
50
|
+
return await retryHttpRequest(() => this.requestScan(...args), retryDelay, maxRetries);
|
|
51
51
|
}
|
|
52
|
-
async
|
|
53
|
-
return await fetch(consts_1.
|
|
52
|
+
async fetchScan(payload, apiKey) {
|
|
53
|
+
return await fetch(consts_1.BACKEND_URL, {
|
|
54
54
|
method: 'POST',
|
|
55
|
-
headers:
|
|
55
|
+
headers: backendHeaders(apiKey),
|
|
56
56
|
body: JSON.stringify(payload),
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
|
-
async
|
|
59
|
+
async requestScan(sourceCode, apiKey) {
|
|
60
60
|
const payload = {
|
|
61
61
|
'jsonrpc': '2.0',
|
|
62
62
|
'method': 'audit.get',
|
|
63
63
|
'params': { 'code': sourceCode },
|
|
64
64
|
'id': 1,
|
|
65
65
|
};
|
|
66
|
-
const response = await this.
|
|
66
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
67
67
|
if (!response.ok) {
|
|
68
68
|
throw new types_1.HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
69
69
|
}
|
|
70
70
|
return (await response.json()).result.task_id;
|
|
71
71
|
}
|
|
72
|
-
async
|
|
72
|
+
async checkScanStatus(taskId, apiKey) {
|
|
73
73
|
const payload = {
|
|
74
74
|
'jsonrpc': '2.0',
|
|
75
75
|
'method': 'task.status',
|
|
76
76
|
'params': { 'task_id': taskId },
|
|
77
77
|
'id': 2,
|
|
78
78
|
};
|
|
79
|
-
const response = await this.
|
|
79
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
80
80
|
if (!response.ok) {
|
|
81
81
|
throw new types_1.HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
82
82
|
}
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
85
|
-
throw new Error(`Error on task.status ${
|
|
83
|
+
const scanResponse = (await response.json());
|
|
84
|
+
if (scanResponse.result.error_message) {
|
|
85
|
+
throw new Error(`Error on task.status ${scanResponse.result.error_message}`);
|
|
86
86
|
}
|
|
87
|
-
return
|
|
87
|
+
return scanResponse.result.status;
|
|
88
88
|
}
|
|
89
|
-
async
|
|
89
|
+
async getScanResult(taskId, apiKey) {
|
|
90
90
|
const payload = {
|
|
91
91
|
'jsonrpc': '2.0',
|
|
92
92
|
'method': 'task.result',
|
|
93
93
|
'params': { 'task_id': taskId },
|
|
94
94
|
'id': 3,
|
|
95
95
|
};
|
|
96
|
-
const response = await this.
|
|
96
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
97
97
|
if (!response.ok) {
|
|
98
98
|
throw new types_1.HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
99
99
|
}
|
|
100
|
-
const
|
|
101
|
-
if (
|
|
102
|
-
throw new Error(`Error on task.result ${
|
|
100
|
+
const scanResponse = (await response.json());
|
|
101
|
+
if (scanResponse.result.error_message) {
|
|
102
|
+
throw new Error(`Error on task.result ${scanResponse.result.error_message}`);
|
|
103
103
|
}
|
|
104
|
-
return
|
|
104
|
+
return scanResponse.result;
|
|
105
105
|
}
|
|
106
106
|
async getPdfReport(taskId, apiKey) {
|
|
107
107
|
const payload = {
|
|
@@ -110,7 +110,7 @@ class ReinforcedHardhatRuntimeEnvironmentField {
|
|
|
110
110
|
'params': { 'task_id': taskId },
|
|
111
111
|
'id': 4,
|
|
112
112
|
};
|
|
113
|
-
const response = await this.
|
|
113
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
114
114
|
if (!response.ok) {
|
|
115
115
|
throw new types_1.HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
116
116
|
}
|
|
@@ -142,7 +142,7 @@ async function retryHttpRequest(request, retryDelay = consts_1.STATUS_CHECK_INTE
|
|
|
142
142
|
function sleep(ms) {
|
|
143
143
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
144
144
|
}
|
|
145
|
-
function
|
|
145
|
+
function backendHeaders(apiKey) {
|
|
146
146
|
return {
|
|
147
147
|
'Content-Type': 'application/json',
|
|
148
148
|
'X-Auth-Token': 'Bearer ' + apiKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReinforcedHardhatRuntimeEnvironmentField.js","sourceRoot":"","sources":["../src/ReinforcedHardhatRuntimeEnvironmentField.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,6CAA4C;AAC5C,
|
|
1
|
+
{"version":3,"file":"ReinforcedHardhatRuntimeEnvironmentField.js","sourceRoot":"","sources":["../src/ReinforcedHardhatRuntimeEnvironmentField.ts"],"names":[],"mappings":"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"}
|
package/dist/consts.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export declare const STATUS_CHECK_INTERVAL = 10000;
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const BACKEND_URL = "https://api.reinforced.app/jsonrpc";
|
|
3
3
|
export declare const MAX_RETRIES = 3;
|
|
4
4
|
//# sourceMappingURL=consts.d.ts.map
|
package/dist/consts.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAC5C,eAAO,MAAM,WAAW,uCAAuC,CAAC;AAChE,eAAO,MAAM,WAAW,IAAI,CAAC"}
|
package/dist/consts.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MAX_RETRIES = exports.
|
|
3
|
+
exports.MAX_RETRIES = exports.BACKEND_URL = exports.STATUS_CHECK_INTERVAL = void 0;
|
|
4
4
|
exports.STATUS_CHECK_INTERVAL = 10_000;
|
|
5
|
-
exports.
|
|
5
|
+
exports.BACKEND_URL = 'https://api.reinforced.app/jsonrpc';
|
|
6
6
|
exports.MAX_RETRIES = 3;
|
|
7
7
|
//# sourceMappingURL=consts.js.map
|
package/dist/consts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":";;;AAAa,QAAA,qBAAqB,GAAG,MAAM,CAAC;AAC/B,QAAA,
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":";;;AAAa,QAAA,qBAAqB,GAAG,MAAM,CAAC;AAC/B,QAAA,WAAW,GAAG,oCAAoC,CAAC;AACnD,QAAA,WAAW,GAAG,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -48,20 +48,20 @@ require("./type-extensions");
|
|
|
48
48
|
console.log('Reinforced verification not enabled.');
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
await
|
|
52
|
-
console.log('✅
|
|
51
|
+
await scanAllContracts(hre);
|
|
52
|
+
console.log('✅ Scan completed before deployment.');
|
|
53
53
|
});
|
|
54
|
-
(0, config_1.task)('scan', 'Run pre-deployment
|
|
54
|
+
(0, config_1.task)('scan', 'Run pre-deployment scan', async (_, hre) => {
|
|
55
55
|
await hre.run(task_names_1.TASK_COMPILE_SOLIDITY, { force: false, quiet: true });
|
|
56
|
-
await
|
|
57
|
-
console.log('✅
|
|
56
|
+
await scanAllContracts(hre);
|
|
57
|
+
console.log('✅ Scan completed');
|
|
58
58
|
});
|
|
59
|
-
(0, config_1.task)('scan:autofix', 'Run
|
|
59
|
+
(0, config_1.task)('scan:autofix', 'Run scan and apply auto-fixes for vulnerabilities', async (_, hre) => {
|
|
60
60
|
await hre.run(task_names_1.TASK_COMPILE_SOLIDITY, { force: false, quiet: true });
|
|
61
|
-
await
|
|
62
|
-
console.log('✅
|
|
61
|
+
await scanAllContractsWithAutoFix(hre);
|
|
62
|
+
console.log('✅ Vulnerability scan and auto-fix completed');
|
|
63
63
|
});
|
|
64
|
-
async function
|
|
64
|
+
async function scanAllContractsWithAutoFix(hre) {
|
|
65
65
|
const apiKey = hre.config.reinforced?.apiKey;
|
|
66
66
|
if (!apiKey) {
|
|
67
67
|
console.log('Reinforced API key not set.');
|
|
@@ -79,21 +79,21 @@ async function auditAllContractsWithAutoFix(hre) {
|
|
|
79
79
|
if (sourcePaths.length > 0) {
|
|
80
80
|
try {
|
|
81
81
|
if (sourcePaths.length > 1) {
|
|
82
|
-
console.log('
|
|
82
|
+
console.log('Scanning:');
|
|
83
83
|
for (const path of sourcePaths)
|
|
84
84
|
console.log(' ', path);
|
|
85
85
|
}
|
|
86
86
|
else {
|
|
87
|
-
console.log('
|
|
87
|
+
console.log('Scanning ', sourcePaths[0]);
|
|
88
88
|
}
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
console.log('Error processing contract:',
|
|
92
|
-
else if (!
|
|
89
|
+
const scanResult = await hre.reinforced.scanContract(flatSource, apiKey, hre.config.reinforced?.statusCheckInterval);
|
|
90
|
+
if (scanResult.error_message)
|
|
91
|
+
console.log('Error processing contract:', scanResult.error_message);
|
|
92
|
+
else if (!scanResult.result || scanResult.result.length == 0)
|
|
93
93
|
console.log('No vulnerabilities found');
|
|
94
94
|
else {
|
|
95
|
-
const enrichedVulnerabilities = enrichVulnerabilitiesWithOriginalMapping(
|
|
96
|
-
console.log(
|
|
95
|
+
const enrichedVulnerabilities = enrichVulnerabilitiesWithOriginalMapping(scanResult.result, flatSource, sourcePaths.map(sp => sp.trim()));
|
|
96
|
+
console.log(formatScanResult(enrichedVulnerabilities, flatSource));
|
|
97
97
|
const autoFixManager = new AutoFixManager_1.AutoFixManager();
|
|
98
98
|
const selections = autoFixManager.promptUserForVulnerabilitySelection(enrichedVulnerabilities);
|
|
99
99
|
if (selections.some(s => s.shouldFix)) {
|
|
@@ -103,7 +103,7 @@ async function auditAllContractsWithAutoFix(hre) {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
catch (error) {
|
|
106
|
-
console.error('
|
|
106
|
+
console.error('Failed to scan contracts for vulnerabilities:', error);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
}
|
|
@@ -123,7 +123,7 @@ function enrichVulnerabilitiesWithOriginalMapping(vulnerabilities, flattenedSour
|
|
|
123
123
|
return vuln;
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
|
-
async function
|
|
126
|
+
async function scanAllContracts(hre) {
|
|
127
127
|
const apiKey = hre.config.reinforced?.apiKey;
|
|
128
128
|
if (!apiKey) {
|
|
129
129
|
console.log('Reinforced API key not set.');
|
|
@@ -141,21 +141,21 @@ async function auditAllContracts(hre) {
|
|
|
141
141
|
if (sourcePaths.length > 0) {
|
|
142
142
|
try {
|
|
143
143
|
if (sourcePaths.length > 1) {
|
|
144
|
-
console.log('
|
|
144
|
+
console.log('Scanning:');
|
|
145
145
|
for (const path of sourcePaths)
|
|
146
146
|
console.log(' ', path);
|
|
147
147
|
}
|
|
148
148
|
else {
|
|
149
|
-
console.log('
|
|
149
|
+
console.log('Scanning ', sourcePaths[0]);
|
|
150
150
|
}
|
|
151
|
-
const
|
|
152
|
-
if (
|
|
153
|
-
console.log('Error processing contract:',
|
|
154
|
-
else if (!
|
|
151
|
+
const scanResult = await hre.reinforced.scanContract(flatSource, apiKey, hre.config.reinforced?.statusCheckInterval);
|
|
152
|
+
if (scanResult.error_message)
|
|
153
|
+
console.log('Error processing contract:', scanResult.error_message);
|
|
154
|
+
else if (!scanResult.result || scanResult.result.length == 0)
|
|
155
155
|
console.log('No vulnerabilities found');
|
|
156
156
|
else {
|
|
157
|
-
const enrichedVulnerabilities = enrichVulnerabilitiesWithOriginalMapping(
|
|
158
|
-
console.log(
|
|
157
|
+
const enrichedVulnerabilities = enrichVulnerabilitiesWithOriginalMapping(scanResult.result, flatSource, sourcePaths.map(sp => sp.trim()));
|
|
158
|
+
console.log(formatScanResult(enrichedVulnerabilities, flatSource));
|
|
159
159
|
if (hre.config.reinforced?.autoFixEnabled !== false) {
|
|
160
160
|
const autoFixManager = new AutoFixManager_1.AutoFixManager();
|
|
161
161
|
const selections = autoFixManager.promptUserForVulnerabilitySelection(enrichedVulnerabilities);
|
|
@@ -166,16 +166,16 @@ async function auditAllContracts(hre) {
|
|
|
166
166
|
}
|
|
167
167
|
else {
|
|
168
168
|
console.log('\n💡 Auto-fix is disabled. You can enable it by setting "autoFixEnabled: true" in your hardhat.config.ts');
|
|
169
|
-
console.log(' Or run "npx hardhat
|
|
169
|
+
console.log(' Or run "npx hardhat scan:autofix" to run with auto-fix enabled.');
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
catch (error) {
|
|
174
|
-
console.error('
|
|
174
|
+
console.error('Failed to scan contracts for vulnerabilities:', error);
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
|
-
function
|
|
178
|
+
function formatScanResult(vulnerabilities, sourceCode) {
|
|
179
179
|
let output = '\n';
|
|
180
180
|
for (let i = 0; i < vulnerabilities.length; i++) {
|
|
181
181
|
const vulnerability = vulnerabilities[i];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,iEAA0H;AAC1H,2CAAkE;AAClE,iEAAuE;AAKvE,iCAA8B;AAE9B,qDAAkD;AAClD,+DAA4D;AAC5D,yGAAsG;AACtG,6BAA2B;AAE3B,IAAA,gBAAO,EAAC,kCAAqB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;IAC3D,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,gCAAgC;IACtD,IAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,sBAAsB,EAAE,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,iEAA0H;AAC1H,2CAAkE;AAClE,iEAAuE;AAKvE,iCAA8B;AAE9B,qDAAkD;AAClD,+DAA4D;AAC5D,yGAAsG;AACtG,6BAA2B;AAE3B,IAAA,gBAAO,EAAC,kCAAqB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE;IAC3D,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,gCAAgC;IACtD,IAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,sBAAsB,EAAE,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IACD,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;AACrD,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,MAAM,EAAE,yBAAyB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;IACvD,MAAM,GAAG,CAAC,GAAG,CAAC,kCAAqB,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;IAClE,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;AAClC,CAAC,CAAC,CAAC;AAEH,IAAA,aAAI,EAAC,cAAc,EAAE,mDAAmD,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;IACzF,MAAM,GAAG,CAAC,GAAG,CAAC,kCAAqB,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;IAClE,MAAM,2BAA2B,CAAC,GAAG,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,2BAA2B,CAAC,GAA8B;IACvE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC;IAC7C,IAAG,CAAC,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,8CAAiC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;IAEjG,MAAM,sBAAsB,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,yBAAyB,EAAE,CAAC;IAC/E,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAI,MAAM,qBAAqB,IAAI,sBAAsB,EAAE,CAAC;QAC1D,MAAM,EAAC,UAAU,EAAC,GAAG,IAAA,wCAAuB,EAAC,qBAAqB,CAAC,CAAC;QACpE,IAAG,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;YACjC,SAAS;QACX,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;IACD,IAAG,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,IAAG,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACzB,KAAI,MAAM,IAAI,IAAI,WAAW;oBAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;YACrH,IAAG,UAAU,CAAC,aAAa;gBACzB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;iBACjE,IAAG,CAAC,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC;gBACzD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;iBACrC,CAAC;gBACJ,MAAM,uBAAuB,GAAG,wCAAwC,CACtE,UAAU,CAAC,MAAM,EACjB,UAAU,EACV,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CACjC,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC,CAAC;gBAEnE,MAAM,cAAc,GAAG,IAAI,+BAAc,EAAE,CAAC;gBAC5C,MAAM,UAAU,GAAG,cAAc,CAAC,mCAAmC,CAAC,uBAAuB,CAAC,CAAC;gBAE/F,IAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;oBACrC,MAAM,MAAM,GAAG,cAAc,CAAC,cAAc,CAC1C,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CACjC,CAAC;oBACF,cAAc,CAAC,qBAAqB,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;gBACxE,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,wCAAwC,CAC/C,eAAgC,EAChC,eAAuB,EACvB,WAAqB;IAErB,MAAM,WAAW,GAAG,IAAI,yCAAmB,EAAE,CAAC;IAC9C,WAAW,CAAC,cAAc,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;IAEzD,OAAO,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAChC,MAAM,OAAO,GAAG,WAAW,CAAC,0BAA0B,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACrF,IAAG,OAAO,EAAE,CAAC;YACX,OAAO;gBACL,GAAG,IAAI;gBACP,aAAa,EAAE,OAAO,CAAC,YAAY;gBACnC,kBAAkB,EAAE,OAAO,CAAC,gBAAgB;gBAC5C,gBAAgB,EAAE,OAAO,CAAC,cAAc;aACzC,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,GAA8B;IAC5D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC;IAC7C,IAAG,CAAC,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,8CAAiC,EAAE,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAC,CAAC,CAAC;IAEjG,MAAM,sBAAsB,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,yBAAyB,EAAE,CAAC;IAC/E,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAI,MAAM,qBAAqB,IAAI,sBAAsB,EAAE,CAAC;QAC1D,MAAM,EAAC,UAAU,EAAC,GAAG,IAAA,wCAAuB,EAAC,qBAAqB,CAAC,CAAC;QACpE,IAAG,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC;YACjC,SAAS;QACX,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC/B,CAAC;IACD,IAAG,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,IAAG,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;gBACzB,KAAI,MAAM,IAAI,IAAI,WAAW;oBAC3B,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC;YACD,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;YACrH,IAAG,UAAU,CAAC,aAAa;gBACzB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;iBACjE,IAAG,CAAC,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC;gBACzD,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;iBACrC,CAAC;gBACJ,MAAM,uBAAuB,GAAG,wCAAwC,CACtE,UAAU,CAAC,MAAM,EACjB,UAAU,EACV,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CACjC,CAAC;gBAEF,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,UAAU,CAAC,CAAC,CAAC;gBAEnE,IAAG,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,cAAc,KAAK,KAAK,EAAE,CAAC;oBACnD,MAAM,cAAc,GAAG,IAAI,+BAAc,EAAE,CAAC;oBAC5C,MAAM,UAAU,GAAG,cAAc,CAAC,mCAAmC,CAAC,uBAAuB,CAAC,CAAC;oBAE/F,IAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;wBACrC,MAAM,MAAM,GAAG,cAAc,CAAC,cAAc,CAC1C,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CACjC,CAAC;wBACF,cAAc,CAAC,qBAAqB,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;oBACxE,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,GAAG,CAAC,0GAA0G,CAAC,CAAC;oBACxH,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;gBACpF,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,eAAgC,EAAE,UAAkB;IAC5E,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/C,MAAM,aAAa,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;QAEzC,MAAM,IAAI,2BAA2B,aAAa,CAAC,mBAAmB,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACpK,MAAM,OAAO,GAAG,CAAC;gBACf,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,KAAK;aACb;YACD;gBACE,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,KAAK;aACb,CAAC,CAAC;QAEH,IAAI,YAAoB,CAAC;QACzB,IAAG,aAAa,CAAC,aAAa,IAAI,aAAa,CAAC,kBAAkB,IAAI,aAAa,CAAC,gBAAgB,EAAE,CAAC;YACrG,IAAI,CAAC;gBACH,MAAM,mBAAmB,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;gBACjF,YAAY,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC;qBAC3C,KAAK,CAAC,aAAa,CAAC,kBAAkB,GAAG,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC;qBAC3E,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBACnB,MAAM,UAAU,GAAG,aAAa,CAAC,kBAAmB,GAAG,KAAK,CAAC;oBAC7D,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC9D,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;qBAClC,KAAK,CAAC,aAAa,CAAC,SAAS,GAAG,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC;qBACzD,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBACnB,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC;oBACnD,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC9D,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;iBAClC,KAAK,CAAC,aAAa,CAAC,SAAS,GAAG,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC;iBACzD,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBACnB,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC;gBACnD,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9D,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAED,MAAM,IAAI,GAAG;YACX,CAAC,aAAa,EAAE,GAAG,aAAa,CAAC,mBAAmB,IAAI,aAAa,CAAC,yBAAyB,EAAE,CAAC;YAClG,CAAC,aAAa,EAAE,aAAa,CAAC,WAAW,CAAC;YAC1C,CAAC,eAAe,EAAE,YAAY,CAAC;YAC/B,CAAC,cAAc,EAAE,aAAa,CAAC,WAAW,IAAI,iBAAiB,CAAC;YAChE,CAAC,WAAW,EAAE,aAAa,CAAC,SAAS,IAAI,uBAAuB,CAAC;YACjE,CAAC,eAAe,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;SAC9D,CAAC;QAEF,MAAM,MAAM,GAAG;YACb,OAAO,EAAE;gBACP,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;gBAChB,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,EAAE;aACtB;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,GAAG;gBACZ,OAAO,EAAE,GAAG;gBACZ,OAAO,EAAE,GAAG;gBACZ,QAAQ,EAAE,GAAG;gBAEb,UAAU,EAAE,GAAG;gBACf,UAAU,EAAE,GAAG;gBACf,UAAU,EAAE,GAAG;gBACf,WAAW,EAAE,GAAG;gBAEhB,QAAQ,EAAE,GAAG;gBACb,SAAS,EAAE,GAAG;gBACd,QAAQ,EAAE,GAAG;gBAEb,QAAQ,EAAE,GAAG;gBACb,QAAQ,EAAE,GAAG;gBACb,SAAS,EAAE,GAAG;gBACd,QAAQ,EAAE,GAAG;aACd;SACF,CAAC;QAEF,MAAM,IAAI,IAAI,CAAC;QACf,MAAM,IAAI,IAAA,aAAK,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9B,MAAM,IAAI,MAAM,CAAC;IACnB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,IAAA,0BAAiB,EAAC,CAAC,GAAG,EAAE,EAAE;IACxB,GAAG,CAAC,UAAU,GAAG,IAAI,mFAAwC,EAAE,CAAC;AAClE,CAAC,CAAC,CAAC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export type
|
|
2
|
-
export interface
|
|
1
|
+
export type ScanStatus = 'pending' | 'processing' | 'failed' | 'completed';
|
|
2
|
+
export interface ScanResult {
|
|
3
3
|
error_message: string | null;
|
|
4
4
|
result: Vulnerability[] | null;
|
|
5
|
-
status:
|
|
5
|
+
status: ScanStatus;
|
|
6
6
|
task_id: string;
|
|
7
7
|
}
|
|
8
8
|
export interface JRPCResponse<T> {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE3E,MAAM,WAAW,UAAU;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,aAAa,EAAG,GAAG,IAAI,CAAC;IAChC,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,CAAC,CAAA;CACZ;AAED,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,MAAM,CAAC;IAClC,SAAS,EAAE,GAAG,EAAG,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAuB,SAAQ,aAAa;IACzD,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,qBAAa,SAAU,SAAQ,KAAK;IAC3B,UAAU,EAAE,MAAM,CAAC;gBAEd,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;CAKhD"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"types": "dist/index.d.ts",
|
|
5
5
|
"type": "commonjs",
|
|
6
|
-
"version": "2512.
|
|
6
|
+
"version": "2512.25.1",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"lint:fix": "prettier --write 'src/**/*.{js,ts}' 'test/**/*.{js,ts}' && tslint --fix --config tslint.json --project tsconfig.json",
|
|
9
9
|
"lint": "tslint --config tslint.json --project tsconfig.json",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import { createSpinner } from 'nanospinner';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { BACKEND_URL, MAX_RETRIES, STATUS_CHECK_INTERVAL } from './consts';
|
|
4
|
+
import { ScanResult, ScanStatus, HttpError, JRPCResponse, PdfReportResult } from './types';
|
|
5
5
|
|
|
6
6
|
export class ReinforcedHardhatRuntimeEnvironmentField {
|
|
7
|
-
public async
|
|
8
|
-
const taskId = await this.
|
|
7
|
+
public async scanContract(sourceCode: string, apiKey: string, statusCheckInterval?: number, maxRetries?: number, reportFolder?: string): Promise<ScanResult> {
|
|
8
|
+
const taskId = await this.requestScanWithRetry(statusCheckInterval, maxRetries, sourceCode, apiKey);
|
|
9
9
|
let spinner = null;
|
|
10
10
|
while(true) {
|
|
11
|
-
const status = await this.
|
|
11
|
+
const status = await this.checkScanStatusWithRetry(statusCheckInterval, maxRetries, taskId, apiKey);
|
|
12
12
|
if(status == 'pending' || status == 'processing') {
|
|
13
13
|
if(!spinner)
|
|
14
14
|
spinner = createSpinner('Processing...').start();
|
|
@@ -19,7 +19,7 @@ export class ReinforcedHardhatRuntimeEnvironmentField {
|
|
|
19
19
|
}
|
|
20
20
|
if(spinner)
|
|
21
21
|
spinner.success();
|
|
22
|
-
const result = this.
|
|
22
|
+
const result = this.getScanResultWithRetry(statusCheckInterval, maxRetries, taskId, apiKey);
|
|
23
23
|
fs.mkdirSync(reportFolder ?? './reinforcedai_reports', {recursive: true});
|
|
24
24
|
|
|
25
25
|
try {
|
|
@@ -36,75 +36,75 @@ export class ReinforcedHardhatRuntimeEnvironmentField {
|
|
|
36
36
|
return result;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
private async
|
|
40
|
-
return await retryHttpRequest(() => this.
|
|
39
|
+
private async checkScanStatusWithRetry (retryDelay?: number, maxRetries?: number, ...args: Parameters<typeof this.checkScanStatus>) {
|
|
40
|
+
return await retryHttpRequest(() => this.checkScanStatus(...args), retryDelay, maxRetries);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
private async
|
|
44
|
-
return await retryHttpRequest(() => this.
|
|
43
|
+
private async getScanResultWithRetry(retryDelay?: number, maxRetries?: number, ...args: Parameters<typeof this.getScanResult>) {
|
|
44
|
+
return await retryHttpRequest(() => this.getScanResult(...args), retryDelay, maxRetries);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
private async
|
|
48
|
-
return await retryHttpRequest(() => this.
|
|
47
|
+
private async requestScanWithRetry(retryDelay?: number, maxRetries?: number, ...args: Parameters<typeof this.requestScan>) {
|
|
48
|
+
return await retryHttpRequest(() => this.requestScan(...args), retryDelay, maxRetries);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
private async
|
|
52
|
-
return await fetch(
|
|
51
|
+
private async fetchScan(payload: any, apiKey: string): Promise<Response> {
|
|
52
|
+
return await fetch(BACKEND_URL, {
|
|
53
53
|
method: 'POST',
|
|
54
|
-
headers:
|
|
54
|
+
headers: backendHeaders(apiKey),
|
|
55
55
|
body: JSON.stringify(payload),
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
private async
|
|
59
|
+
private async requestScan(sourceCode: string, apiKey: string): Promise<string> {
|
|
60
60
|
const payload = {
|
|
61
61
|
'jsonrpc': '2.0',
|
|
62
62
|
'method': 'audit.get',
|
|
63
63
|
'params': {'code': sourceCode},
|
|
64
64
|
'id': 1,
|
|
65
65
|
};
|
|
66
|
-
const response = await this.
|
|
66
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
67
67
|
if(!response.ok) {
|
|
68
68
|
throw new HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
69
69
|
}
|
|
70
70
|
return (await response.json()).result.task_id;
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
private async
|
|
73
|
+
private async checkScanStatus(taskId: string, apiKey: string): Promise<ScanStatus> {
|
|
74
74
|
const payload = {
|
|
75
75
|
'jsonrpc': '2.0',
|
|
76
76
|
'method': 'task.status',
|
|
77
77
|
'params': {'task_id': taskId},
|
|
78
78
|
'id': 2,
|
|
79
79
|
};
|
|
80
|
-
const response = await this.
|
|
80
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
81
81
|
if(!response.ok) {
|
|
82
82
|
throw new HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
83
83
|
}
|
|
84
|
-
const
|
|
85
|
-
if(
|
|
86
|
-
throw new Error(`Error on task.status ${
|
|
84
|
+
const scanResponse = (await response.json()) as JRPCResponse<ScanResult>;
|
|
85
|
+
if(scanResponse.result.error_message) {
|
|
86
|
+
throw new Error(`Error on task.status ${scanResponse.result.error_message}`);
|
|
87
87
|
}
|
|
88
|
-
return
|
|
88
|
+
return scanResponse.result.status;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
private async
|
|
91
|
+
private async getScanResult(taskId: string, apiKey: string): Promise<ScanResult> {
|
|
92
92
|
const payload = {
|
|
93
93
|
'jsonrpc': '2.0',
|
|
94
94
|
'method': 'task.result',
|
|
95
95
|
'params': {'task_id': taskId},
|
|
96
96
|
'id': 3,
|
|
97
97
|
};
|
|
98
|
-
const response = await this.
|
|
98
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
99
99
|
if(!response.ok) {
|
|
100
100
|
throw new HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
const
|
|
104
|
-
if(
|
|
105
|
-
throw new Error(`Error on task.result ${
|
|
103
|
+
const scanResponse = (await response.json()) as JRPCResponse<ScanResult>;
|
|
104
|
+
if(scanResponse.result.error_message) {
|
|
105
|
+
throw new Error(`Error on task.result ${scanResponse.result.error_message}`);
|
|
106
106
|
}
|
|
107
|
-
return
|
|
107
|
+
return scanResponse.result;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
private async getPdfReport(taskId: string, apiKey: string): Promise<PdfReportResult> {
|
|
@@ -114,7 +114,7 @@ export class ReinforcedHardhatRuntimeEnvironmentField {
|
|
|
114
114
|
'params': {'task_id': taskId},
|
|
115
115
|
'id': 4,
|
|
116
116
|
};
|
|
117
|
-
const response = await this.
|
|
117
|
+
const response = await this.fetchScan(payload, apiKey);
|
|
118
118
|
if(!response.ok) {
|
|
119
119
|
throw new HttpError(`HTTP ${response.status} ${response.statusText}`, response.status);
|
|
120
120
|
}
|
|
@@ -147,7 +147,7 @@ function sleep(ms: number): Promise<void> {
|
|
|
147
147
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
function
|
|
150
|
+
function backendHeaders(apiKey: string) {
|
|
151
151
|
return {
|
|
152
152
|
'Content-Type': 'application/json',
|
|
153
153
|
'X-Auth-Token': 'Bearer ' + apiKey,
|
package/src/consts.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -19,23 +19,23 @@ subtask(TASK_COMPILE_SOLIDITY, async (args, hre, runSuper) => {
|
|
|
19
19
|
console.log('Reinforced verification not enabled.');
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
-
await
|
|
23
|
-
console.log('✅
|
|
22
|
+
await scanAllContracts(hre);
|
|
23
|
+
console.log('✅ Scan completed before deployment.');
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
-
task('scan', 'Run pre-deployment
|
|
26
|
+
task('scan', 'Run pre-deployment scan', async (_, hre) => {
|
|
27
27
|
await hre.run(TASK_COMPILE_SOLIDITY, {force: false, quiet: true});
|
|
28
|
-
await
|
|
29
|
-
console.log('✅
|
|
28
|
+
await scanAllContracts(hre);
|
|
29
|
+
console.log('✅ Scan completed');
|
|
30
30
|
});
|
|
31
31
|
|
|
32
|
-
task('scan:autofix', 'Run
|
|
32
|
+
task('scan:autofix', 'Run scan and apply auto-fixes for vulnerabilities', async (_, hre) => {
|
|
33
33
|
await hre.run(TASK_COMPILE_SOLIDITY, {force: false, quiet: true});
|
|
34
|
-
await
|
|
35
|
-
console.log('✅
|
|
34
|
+
await scanAllContractsWithAutoFix(hre);
|
|
35
|
+
console.log('✅ Vulnerability scan and auto-fix completed');
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
async function
|
|
38
|
+
async function scanAllContractsWithAutoFix(hre: HardhatRuntimeEnvironment) {
|
|
39
39
|
const apiKey = hre.config.reinforced?.apiKey;
|
|
40
40
|
if(!apiKey) {
|
|
41
41
|
console.log('Reinforced API key not set.');
|
|
@@ -56,24 +56,24 @@ async function auditAllContractsWithAutoFix(hre: HardhatRuntimeEnvironment) {
|
|
|
56
56
|
if(sourcePaths.length > 0) {
|
|
57
57
|
try {
|
|
58
58
|
if(sourcePaths.length > 1) {
|
|
59
|
-
console.log('
|
|
59
|
+
console.log('Scanning:');
|
|
60
60
|
for(const path of sourcePaths)
|
|
61
61
|
console.log(' ', path);
|
|
62
62
|
} else {
|
|
63
|
-
console.log('
|
|
63
|
+
console.log('Scanning ', sourcePaths[0]);
|
|
64
64
|
}
|
|
65
|
-
const
|
|
66
|
-
if(
|
|
67
|
-
console.log('Error processing contract:',
|
|
68
|
-
else if(!
|
|
65
|
+
const scanResult = await hre.reinforced.scanContract(flatSource, apiKey, hre.config.reinforced?.statusCheckInterval);
|
|
66
|
+
if(scanResult.error_message)
|
|
67
|
+
console.log('Error processing contract:', scanResult.error_message);
|
|
68
|
+
else if(!scanResult.result || scanResult.result.length == 0)
|
|
69
69
|
console.log('No vulnerabilities found');
|
|
70
70
|
else {
|
|
71
71
|
const enrichedVulnerabilities = enrichVulnerabilitiesWithOriginalMapping(
|
|
72
|
-
|
|
72
|
+
scanResult.result,
|
|
73
73
|
flatSource,
|
|
74
74
|
sourcePaths.map(sp => sp.trim()),
|
|
75
75
|
);
|
|
76
|
-
console.log(
|
|
76
|
+
console.log(formatScanResult(enrichedVulnerabilities, flatSource));
|
|
77
77
|
|
|
78
78
|
const autoFixManager = new AutoFixManager();
|
|
79
79
|
const selections = autoFixManager.promptUserForVulnerabilitySelection(enrichedVulnerabilities);
|
|
@@ -89,7 +89,7 @@ async function auditAllContractsWithAutoFix(hre: HardhatRuntimeEnvironment) {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
} catch (error) {
|
|
92
|
-
console.error('
|
|
92
|
+
console.error('Failed to scan contracts for vulnerabilities:', error);
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -116,7 +116,7 @@ function enrichVulnerabilitiesWithOriginalMapping(
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
async function
|
|
119
|
+
async function scanAllContracts(hre: HardhatRuntimeEnvironment) {
|
|
120
120
|
const apiKey = hre.config.reinforced?.apiKey;
|
|
121
121
|
if(!apiKey) {
|
|
122
122
|
console.log('Reinforced API key not set.');
|
|
@@ -137,25 +137,25 @@ async function auditAllContracts(hre: HardhatRuntimeEnvironment) {
|
|
|
137
137
|
if(sourcePaths.length > 0) {
|
|
138
138
|
try {
|
|
139
139
|
if(sourcePaths.length > 1) {
|
|
140
|
-
console.log('
|
|
140
|
+
console.log('Scanning:');
|
|
141
141
|
for(const path of sourcePaths)
|
|
142
142
|
console.log(' ', path);
|
|
143
143
|
} else {
|
|
144
|
-
console.log('
|
|
144
|
+
console.log('Scanning ', sourcePaths[0]);
|
|
145
145
|
}
|
|
146
|
-
const
|
|
147
|
-
if(
|
|
148
|
-
console.log('Error processing contract:',
|
|
149
|
-
else if(!
|
|
146
|
+
const scanResult = await hre.reinforced.scanContract(flatSource, apiKey, hre.config.reinforced?.statusCheckInterval);
|
|
147
|
+
if(scanResult.error_message)
|
|
148
|
+
console.log('Error processing contract:', scanResult.error_message);
|
|
149
|
+
else if(!scanResult.result || scanResult.result.length == 0)
|
|
150
150
|
console.log('No vulnerabilities found');
|
|
151
151
|
else {
|
|
152
152
|
const enrichedVulnerabilities = enrichVulnerabilitiesWithOriginalMapping(
|
|
153
|
-
|
|
153
|
+
scanResult.result,
|
|
154
154
|
flatSource,
|
|
155
155
|
sourcePaths.map(sp => sp.trim()),
|
|
156
156
|
);
|
|
157
157
|
|
|
158
|
-
console.log(
|
|
158
|
+
console.log(formatScanResult(enrichedVulnerabilities, flatSource));
|
|
159
159
|
|
|
160
160
|
if(hre.config.reinforced?.autoFixEnabled !== false) {
|
|
161
161
|
const autoFixManager = new AutoFixManager();
|
|
@@ -172,16 +172,16 @@ async function auditAllContracts(hre: HardhatRuntimeEnvironment) {
|
|
|
172
172
|
}
|
|
173
173
|
} else {
|
|
174
174
|
console.log('\n💡 Auto-fix is disabled. You can enable it by setting "autoFixEnabled: true" in your hardhat.config.ts');
|
|
175
|
-
console.log(' Or run "npx hardhat
|
|
175
|
+
console.log(' Or run "npx hardhat scan:autofix" to run with auto-fix enabled.');
|
|
176
176
|
}
|
|
177
177
|
}
|
|
178
178
|
} catch (error) {
|
|
179
|
-
console.error('
|
|
179
|
+
console.error('Failed to scan contracts for vulnerabilities:', error);
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
-
function
|
|
184
|
+
function formatScanResult(vulnerabilities: Vulnerability[], sourceCode: string): string {
|
|
185
185
|
let output = '\n';
|
|
186
186
|
for(let i = 0; i < vulnerabilities.length; i++) {
|
|
187
187
|
const vulnerability = vulnerabilities[i];
|
package/src/types.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type ScanStatus = 'pending' | 'processing' | 'failed' | 'completed';
|
|
2
2
|
|
|
3
|
-
export interface
|
|
3
|
+
export interface ScanResult {
|
|
4
4
|
error_message: string | null,
|
|
5
5
|
result: Vulnerability [] | null,
|
|
6
|
-
status:
|
|
6
|
+
status: ScanStatus,
|
|
7
7
|
task_id: string
|
|
8
8
|
};
|
|
9
9
|
|