clawcontract-cli 0.1.0

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.
Files changed (146) hide show
  1. package/README.md +229 -0
  2. package/dist/analyzer/fallback.d.ts +28 -0
  3. package/dist/analyzer/fallback.d.ts.map +1 -0
  4. package/dist/analyzer/fallback.js +142 -0
  5. package/dist/analyzer/fallback.js.map +1 -0
  6. package/dist/analyzer/index.d.ts +24 -0
  7. package/dist/analyzer/index.d.ts.map +1 -0
  8. package/dist/analyzer/index.js +73 -0
  9. package/dist/analyzer/index.js.map +1 -0
  10. package/dist/analyzer/slither.d.ts +36 -0
  11. package/dist/analyzer/slither.d.ts.map +1 -0
  12. package/dist/analyzer/slither.js +92 -0
  13. package/dist/analyzer/slither.js.map +1 -0
  14. package/dist/cli/commands/analyze.d.ts +7 -0
  15. package/dist/cli/commands/analyze.d.ts.map +1 -0
  16. package/dist/cli/commands/analyze.js +74 -0
  17. package/dist/cli/commands/analyze.js.map +1 -0
  18. package/dist/cli/commands/create.d.ts +8 -0
  19. package/dist/cli/commands/create.d.ts.map +1 -0
  20. package/dist/cli/commands/create.js +44 -0
  21. package/dist/cli/commands/create.js.map +1 -0
  22. package/dist/cli/commands/delete.d.ts +5 -0
  23. package/dist/cli/commands/delete.d.ts.map +1 -0
  24. package/dist/cli/commands/delete.js +48 -0
  25. package/dist/cli/commands/delete.js.map +1 -0
  26. package/dist/cli/commands/deploy.d.ts +7 -0
  27. package/dist/cli/commands/deploy.d.ts.map +1 -0
  28. package/dist/cli/commands/deploy.js +130 -0
  29. package/dist/cli/commands/deploy.js.map +1 -0
  30. package/dist/cli/commands/featured.d.ts +4 -0
  31. package/dist/cli/commands/featured.d.ts.map +1 -0
  32. package/dist/cli/commands/featured.js +47 -0
  33. package/dist/cli/commands/featured.js.map +1 -0
  34. package/dist/cli/commands/full.d.ts +14 -0
  35. package/dist/cli/commands/full.d.ts.map +1 -0
  36. package/dist/cli/commands/full.js +72 -0
  37. package/dist/cli/commands/full.js.map +1 -0
  38. package/dist/cli/commands/generate.d.ts +10 -0
  39. package/dist/cli/commands/generate.d.ts.map +1 -0
  40. package/dist/cli/commands/generate.js +71 -0
  41. package/dist/cli/commands/generate.js.map +1 -0
  42. package/dist/cli/commands/info.d.ts +4 -0
  43. package/dist/cli/commands/info.d.ts.map +1 -0
  44. package/dist/cli/commands/info.js +76 -0
  45. package/dist/cli/commands/info.js.map +1 -0
  46. package/dist/cli/commands/interact.d.ts +7 -0
  47. package/dist/cli/commands/interact.d.ts.map +1 -0
  48. package/dist/cli/commands/interact.js +173 -0
  49. package/dist/cli/commands/interact.js.map +1 -0
  50. package/dist/cli/commands/list.d.ts +6 -0
  51. package/dist/cli/commands/list.d.ts.map +1 -0
  52. package/dist/cli/commands/list.js +37 -0
  53. package/dist/cli/commands/list.js.map +1 -0
  54. package/dist/cli/commands/register.d.ts +4 -0
  55. package/dist/cli/commands/register.d.ts.map +1 -0
  56. package/dist/cli/commands/register.js +54 -0
  57. package/dist/cli/commands/register.js.map +1 -0
  58. package/dist/cli/commands/verified.d.ts +9 -0
  59. package/dist/cli/commands/verified.d.ts.map +1 -0
  60. package/dist/cli/commands/verified.js +61 -0
  61. package/dist/cli/commands/verified.js.map +1 -0
  62. package/dist/cli/commands/verify.d.ts +9 -0
  63. package/dist/cli/commands/verify.d.ts.map +1 -0
  64. package/dist/cli/commands/verify.js +87 -0
  65. package/dist/cli/commands/verify.js.map +1 -0
  66. package/dist/cli/index.d.ts +3 -0
  67. package/dist/cli/index.d.ts.map +1 -0
  68. package/dist/cli/index.js +160 -0
  69. package/dist/cli/index.js.map +1 -0
  70. package/dist/cli/utils.d.ts +8 -0
  71. package/dist/cli/utils.d.ts.map +1 -0
  72. package/dist/cli/utils.js +36 -0
  73. package/dist/cli/utils.js.map +1 -0
  74. package/dist/config/chains.d.ts +18 -0
  75. package/dist/config/chains.d.ts.map +1 -0
  76. package/dist/config/chains.js +52 -0
  77. package/dist/config/chains.js.map +1 -0
  78. package/dist/config/clawcontractbook.d.ts +3 -0
  79. package/dist/config/clawcontractbook.d.ts.map +1 -0
  80. package/dist/config/clawcontractbook.js +3 -0
  81. package/dist/config/clawcontractbook.js.map +1 -0
  82. package/dist/config/index.d.ts +4 -0
  83. package/dist/config/index.d.ts.map +1 -0
  84. package/dist/config/index.js +3 -0
  85. package/dist/config/index.js.map +1 -0
  86. package/dist/constants/index.d.ts +3 -0
  87. package/dist/constants/index.d.ts.map +1 -0
  88. package/dist/constants/index.js +3 -0
  89. package/dist/constants/index.js.map +1 -0
  90. package/dist/deployer/compiler.d.ts +10 -0
  91. package/dist/deployer/compiler.d.ts.map +1 -0
  92. package/dist/deployer/compiler.js +93 -0
  93. package/dist/deployer/compiler.js.map +1 -0
  94. package/dist/deployer/deploy.d.ts +28 -0
  95. package/dist/deployer/deploy.d.ts.map +1 -0
  96. package/dist/deployer/deploy.js +60 -0
  97. package/dist/deployer/deploy.js.map +1 -0
  98. package/dist/deployer/hardhat-config-template.d.ts +2 -0
  99. package/dist/deployer/hardhat-config-template.d.ts.map +1 -0
  100. package/dist/deployer/hardhat-config-template.js +21 -0
  101. package/dist/deployer/hardhat-config-template.js.map +1 -0
  102. package/dist/deployer/index.d.ts +7 -0
  103. package/dist/deployer/index.d.ts.map +1 -0
  104. package/dist/deployer/index.js +4 -0
  105. package/dist/deployer/index.js.map +1 -0
  106. package/dist/deployer/metadata.d.ts +17 -0
  107. package/dist/deployer/metadata.d.ts.map +1 -0
  108. package/dist/deployer/metadata.js +317 -0
  109. package/dist/deployer/metadata.js.map +1 -0
  110. package/dist/deployer/wallet.d.ts +6 -0
  111. package/dist/deployer/wallet.d.ts.map +1 -0
  112. package/dist/deployer/wallet.js +15 -0
  113. package/dist/deployer/wallet.js.map +1 -0
  114. package/dist/generator/index.d.ts +2 -0
  115. package/dist/generator/index.d.ts.map +1 -0
  116. package/dist/generator/index.js +2 -0
  117. package/dist/generator/index.js.map +1 -0
  118. package/dist/generator/llm.d.ts +15 -0
  119. package/dist/generator/llm.d.ts.map +1 -0
  120. package/dist/generator/llm.js +128 -0
  121. package/dist/generator/llm.js.map +1 -0
  122. package/dist/generator/utils.d.ts +5 -0
  123. package/dist/generator/utils.d.ts.map +1 -0
  124. package/dist/generator/utils.js +49 -0
  125. package/dist/generator/utils.js.map +1 -0
  126. package/dist/index.d.ts +2 -0
  127. package/dist/index.d.ts.map +1 -0
  128. package/dist/index.js +2 -0
  129. package/dist/index.js.map +1 -0
  130. package/dist/lib/clawcontractbook.d.ts +65 -0
  131. package/dist/lib/clawcontractbook.d.ts.map +1 -0
  132. package/dist/lib/clawcontractbook.js +158 -0
  133. package/dist/lib/clawcontractbook.js.map +1 -0
  134. package/dist/lib/credentials.d.ts +28 -0
  135. package/dist/lib/credentials.d.ts.map +1 -0
  136. package/dist/lib/credentials.js +73 -0
  137. package/dist/lib/credentials.js.map +1 -0
  138. package/dist/verifier/explorer-api.d.ts +21 -0
  139. package/dist/verifier/explorer-api.d.ts.map +1 -0
  140. package/dist/verifier/explorer-api.js +92 -0
  141. package/dist/verifier/explorer-api.js.map +1 -0
  142. package/dist/verifier/index.d.ts +20 -0
  143. package/dist/verifier/index.d.ts.map +1 -0
  144. package/dist/verifier/index.js +31 -0
  145. package/dist/verifier/index.js.map +1 -0
  146. package/package.json +54 -0
package/README.md ADDED
@@ -0,0 +1,229 @@
1
+ # ClawContract 🦞
2
+
3
+ **AI-powered smart contract generator, analyzer, and deployer for BNB Chain**
4
+
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
6
+ [![Node.js 20+](https://img.shields.io/badge/Node.js-20%2B-green.svg)](https://nodejs.org)
7
+ [![BNB Chain](https://img.shields.io/badge/BNB%20Chain-BSC%20%7C%20opBNB-F0B90B.svg)](https://www.bnbchain.org)
8
+ [![Hackathon](https://img.shields.io/badge/Hackathon-Good%20Vibes%20Only-blueviolet.svg)](#hackathon)
9
+
10
+ ---
11
+
12
+ ## Overview
13
+
14
+ ClawContract turns Solidity source into production-ready, deployed smart contracts on BNB Chain. Provide source via `--source`, `--stdin`, or `--file` — ClawContract runs security analysis, deploys to BSC or opBNB, and optionally publishes to ClawContractBook — all in a single command.
15
+
16
+ ## Features
17
+
18
+ - **Security analysis** — runs Slither static analysis with an automatic regex-based fallback for environments without Python
19
+ - **One-command deployment** — deploy to BSC and opBNB (mainnet + testnet) with gas estimation
20
+ - **Non-interactive CLI** — fully automated pipeline with gas estimates, no user prompts required
21
+ - **OpenClaw skill integration** — register as an OpenClaw skill for chat-based contract generation and deployment
22
+
23
+ ## Quick Start
24
+
25
+ ```bash
26
+ git clone https://github.com/your-username/ClawContract.git
27
+ cd ClawContract
28
+ pnpm install
29
+ pnpm run build
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ ### Register (required for deploy)
35
+
36
+ ```bash
37
+ clawcontract-cli register --name "My AI Agent"
38
+ ```
39
+
40
+ Creates credentials in `clawcontractbook/credentials.json` with a wallet. Fund that address with BNB for gas.
41
+
42
+ ### Create a contract from source
43
+
44
+ ```bash
45
+ clawcontract-cli create --source "pragma solidity ^0.8.0; contract Foo { uint x; }"
46
+ cat MyContract.sol | clawcontract-cli create --stdin
47
+ ```
48
+
49
+ Writes the contract to `./contracts/`. Override with `--output <dir>`.
50
+
51
+ ### Analyze a contract for vulnerabilities
52
+
53
+ ```bash
54
+ clawcontract-cli analyze ./contracts/Counter.sol
55
+ ```
56
+
57
+ ### Deploy to a chain
58
+
59
+ ```bash
60
+ clawcontract-cli deploy ./contracts/Counter.sol --chain bsc-testnet
61
+ clawcontract-cli deploy ./contracts/Counter.sol --chain bsc-testnet --publish
62
+ clawcontract-cli deploy ./contracts/Counter.sol --chain bsc-testnet --publish --description "simple counter"
63
+ ```
64
+
65
+ Options: `--publish` to publish to ClawContractBook; `--description <text>` for the publish description.
66
+
67
+ ### Interact with a deployed contract
68
+
69
+ ```bash
70
+ clawcontract-cli interact 0xYourContractAddress getCount --chain bsc-testnet
71
+ ```
72
+
73
+ Call any function on a deployed contract. Read-only functions (`view`/`pure`) are called without gas. State-changing functions are sent as signed transactions.
74
+
75
+ ```bash
76
+ # Read-only call
77
+ clawcontract-cli interact 0xABC... getCount --chain bsc-testnet
78
+
79
+ # State-changing call
80
+ clawcontract-cli interact 0xABC... increment --chain bsc-testnet
81
+
82
+ # Payable call (send BNB value in wei)
83
+ clawcontract-cli interact 0xABC... deposit --value 100000000000000 --chain bsc-testnet
84
+
85
+ # Use ABI from source file instead of stored metadata
86
+ clawcontract-cli interact 0xABC... getCount --chain bsc-testnet --file ./contracts/Counter.sol
87
+
88
+ # Use ABI from URL (e.g. from verified/featured output)
89
+ clawcontract-cli interact 0xABC... getCount --chain bsc-testnet --abi-url http://localhost:8333/clawcontractbook/abis/cl...json
90
+ ```
91
+
92
+ ### List deployments
93
+
94
+ ```bash
95
+ clawcontract-cli list
96
+ clawcontract-cli list --chain bsc-testnet
97
+ clawcontract-cli list --json
98
+ ```
99
+
100
+ Shows address, contract name, chain, deployer, and deployment date. Use `--chain` to filter; `--json` for machine-readable output.
101
+
102
+ ### Delete a deployment record
103
+
104
+ ```bash
105
+ clawcontract-cli delete 0xYourContractAddress
106
+ clawcontract-cli delete 0xYourContractAddress --force # skip confirmation
107
+ ```
108
+
109
+ ### Info (agent address and balance)
110
+
111
+ ```bash
112
+ clawcontract-cli info
113
+ clawcontract-cli info --chain bsc-mainnet
114
+ ```
115
+
116
+ ### Browse verified and featured contracts
117
+
118
+ ```bash
119
+ clawcontract-cli verified
120
+ clawcontract-cli verified --page 2 --limit 10 --chain bsc-testnet --search counter --sort newest
121
+ clawcontract-cli verified --json
122
+
123
+ clawcontract-cli featured
124
+ clawcontract-cli featured --json
125
+ ```
126
+
127
+ ### Full pipeline (create → analyze → deploy)
128
+
129
+ ```bash
130
+ clawcontract-cli full --source "pragma solidity ^0.8.0; contract Bar {}" --chain bsc-testnet
131
+ clawcontract-cli full --stdin --chain bsc-testnet
132
+ clawcontract-cli full --file ./contracts/Counter.sol --chain bsc-testnet
133
+ ```
134
+
135
+ Options:
136
+ - `--skip-analyze` — skip security analysis step entirely
137
+ - `--skip-deploy` — stop after analysis, do not deploy
138
+ - `--publish` — publish deployment to ClawContractBook
139
+ - `--description <text>` — deployment description for publishing
140
+
141
+ ```bash
142
+ # Analyze only — review before deploying
143
+ clawcontract-cli full --file ./contracts/Counter.sol --chain bsc-testnet --skip-deploy
144
+ ```
145
+
146
+ ### Global options
147
+
148
+ | Option | Description | Default |
149
+ |---|---|---|
150
+ | `--chain <chain>` | Target blockchain | `bsc-testnet` |
151
+ | `--output <dir>` | Output directory for generated contracts | `./contracts` |
152
+
153
+ ## Supported Chains
154
+
155
+ | Chain | Chain ID | RPC | Explorer |
156
+ |---|---|---|---|
157
+ | BNB Smart Chain | 56 | `https://bsc-dataseed.binance.org` | [bscscan.com](https://bscscan.com) |
158
+ | BNB Smart Chain Testnet | 97 | `https://data-seed-prebsc-1-s1.binance.org:8545` | [testnet.bscscan.com](https://testnet.bscscan.com) |
159
+ | opBNB | 204 | `https://opbnb-mainnet-rpc.bnbchain.org` | [opbnbscan.com](https://opbnbscan.com) |
160
+ | opBNB Testnet | 5611 | `https://opbnb-testnet-rpc.bnbchain.org` | [testnet.opbnbscan.com](https://testnet.opbnbscan.com) |
161
+
162
+ ## Architecture
163
+
164
+ ```
165
+ src/
166
+ ├── cli/ # Commander.js CLI entry point + command handlers
167
+ ├── generator/ # Contract generation (template matching)
168
+ ├── analyzer/ # Security analysis (Slither + regex fallback)
169
+ ├── deployer/ # Compilation + deployment via Hardhat + ethers.js (saves metadata)
170
+ ├── config/ # Chain configurations and constants
171
+ └── lib/ # ClawContractBook publishing, credentials
172
+ ```
173
+
174
+ ## Pipeline Flow
175
+
176
+ The `full` command runs create → analyze → deploy end-to-end. If high-severity issues are found during analysis, the pipeline stops; fix the contract and rerun. Use `--skip-deploy` to stop after analysis.
177
+
178
+ ```
179
+ Source (--source / --stdin / --file)
180
+
181
+ Create (write .sol) ── or skip if --file
182
+
183
+ Security Analysis ─── Slither / regex checks (--skip-analyze to skip)
184
+
185
+ Compilation ─────── Hardhat + solc
186
+
187
+ Deployment ──────── ethers.js → BSC / opBNB (--skip-deploy to stop before)
188
+
189
+ Publish (optional) ─ ClawContractBook when --publish
190
+
191
+ Interaction ──────── ethers.js read/write calls
192
+ ```
193
+
194
+ ## OpenClaw Integration
195
+
196
+ ClawContract ships with an [OpenClaw skill](src/openclaw/SKILL.md) that teaches OpenClaw agents how to use the CLI for chat-based contract generation and deployment. Copy or symlink `src/openclaw/` into your OpenClaw workspace `skills/` directory to enable it.
197
+
198
+ ## Configuration
199
+
200
+ Deploy and interact use credentials from `clawcontract register` (stored in `clawcontractbook/credentials.json`). No `.env` or `CLAWCONTRACT_PRIVATE_KEY` needed.
201
+
202
+ Environment variables (optional):
203
+
204
+ | Variable | Description | Required |
205
+ |---|---|---|
206
+ | `CLAWCONTRACT_OPENROUTER_API_KEY` | OpenRouter API key (not needed for `--source`/`--stdin`/`--file`) | No |
207
+ | `CLAWCONTRACT_BSCSCAN_API_KEY` | BscScan / opBNBScan API key | No |
208
+
209
+ > **Security:** Never commit secrets to version control. When using Docker, set values in `docker-compose.yml` or pass them via environment variables.
210
+
211
+ > **Data:** Deployment metadata is saved to `contracts/.deployments/` using a directory-based store with deduplicated ABIs and an index for fast lookups. Legacy `.deployments.json` files are auto-migrated on first access. This directory is local and should not be committed.
212
+
213
+ ## Requirements
214
+
215
+ - **Node.js** 20.0.0 or later
216
+ - **pnpm** (recommended package manager)
217
+ - **Python 3.8+** (optional — required for Slither static analysis; regex fallback is used if unavailable)
218
+
219
+ ## Hackathon
220
+
221
+ Built for the **Good Vibes Only: OpenClaw Edition** hackathon.
222
+
223
+ - **Track:** Builders' Tools
224
+ - **Chain:** BNB Chain (BSC + opBNB)
225
+ - **Goal:** Make smart contract development accessible to everyone through AI and natural language
226
+
227
+ ## License
228
+
229
+ [MIT](LICENSE)
@@ -0,0 +1,28 @@
1
+ export interface Finding {
2
+ severity: 'High' | 'Medium' | 'Low' | 'Informational' | 'Optimization';
3
+ title: string;
4
+ description: string;
5
+ location: string;
6
+ recommendation: string;
7
+ }
8
+ export interface AnalysisSummary {
9
+ high: number;
10
+ medium: number;
11
+ low: number;
12
+ informational: number;
13
+ optimization: number;
14
+ total: number;
15
+ }
16
+ export interface AnalysisResult {
17
+ findings: Finding[];
18
+ summary: AnalysisSummary;
19
+ passed: boolean;
20
+ }
21
+ export declare function checkReentrancy(source: string): Finding[];
22
+ export declare function checkUncheckedReturn(source: string): Finding[];
23
+ export declare function checkTxOrigin(source: string): Finding[];
24
+ export declare function checkSelfDestruct(source: string): Finding[];
25
+ export declare function checkFloatingPragma(source: string): Finding[];
26
+ export declare function runFallbackAnalysis(source: string): AnalysisResult;
27
+ export declare function runFallbackAnalysisFromFile(filePath: string): AnalysisResult;
28
+ //# sourceMappingURL=fallback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fallback.d.ts","sourceRoot":"","sources":["../../src/analyzer/fallback.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,eAAe,GAAG,cAAc,CAAC;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CA2BzD;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAoB9D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAkBvD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAkB3D;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,EAAE,CAkB7D;AAyBD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAalE;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAG5E"}
@@ -0,0 +1,142 @@
1
+ import { readFileSync } from 'node:fs';
2
+ export function checkReentrancy(source) {
3
+ const findings = [];
4
+ const lines = source.split('\n');
5
+ for (let i = 0; i < lines.length; i++) {
6
+ const line = lines[i].trim();
7
+ if ((line.includes('.call{') || line.includes('.call(') || line.includes('.send(') || line.includes('.transfer(')) &&
8
+ !line.startsWith('//')) {
9
+ for (let j = i + 1; j < Math.min(i + 10, lines.length); j++) {
10
+ const subsequent = lines[j].trim();
11
+ if (subsequent.includes('=') && !subsequent.startsWith('//') && !subsequent.startsWith('require') && !subsequent.startsWith('if')) {
12
+ findings.push({
13
+ severity: 'High',
14
+ title: '[Basic Check] Potential Reentrancy',
15
+ description: `External call at line ${i + 1} is followed by a state change at line ${j + 1}. This could be vulnerable to reentrancy attacks.`,
16
+ location: `Line ${i + 1}`,
17
+ recommendation: 'Use the checks-effects-interactions pattern or a reentrancy guard. Update state variables before making external calls.',
18
+ });
19
+ break;
20
+ }
21
+ }
22
+ }
23
+ }
24
+ return findings;
25
+ }
26
+ export function checkUncheckedReturn(source) {
27
+ const findings = [];
28
+ const lines = source.split('\n');
29
+ for (let i = 0; i < lines.length; i++) {
30
+ const line = lines[i].trim();
31
+ if (line.includes('.call{') || line.includes('.call(')) {
32
+ if (!line.includes('(bool') && !line.includes('require') && !line.includes('if')) {
33
+ findings.push({
34
+ severity: 'Medium',
35
+ title: '[Basic Check] Unchecked Return Value',
36
+ description: `Low-level call at line ${i + 1} does not check the return value. The call could silently fail.`,
37
+ location: `Line ${i + 1}`,
38
+ recommendation: 'Check the return value of low-level calls: (bool success, ) = addr.call{...}(...); require(success);',
39
+ });
40
+ }
41
+ }
42
+ }
43
+ return findings;
44
+ }
45
+ export function checkTxOrigin(source) {
46
+ const findings = [];
47
+ const lines = source.split('\n');
48
+ for (let i = 0; i < lines.length; i++) {
49
+ const line = lines[i].trim();
50
+ if (line.includes('tx.origin') && !line.startsWith('//')) {
51
+ findings.push({
52
+ severity: 'Medium',
53
+ title: '[Basic Check] tx.origin Usage',
54
+ description: `tx.origin used at line ${i + 1}. Using tx.origin for authorization is vulnerable to phishing attacks.`,
55
+ location: `Line ${i + 1}`,
56
+ recommendation: 'Use msg.sender instead of tx.origin for authorization checks.',
57
+ });
58
+ }
59
+ }
60
+ return findings;
61
+ }
62
+ export function checkSelfDestruct(source) {
63
+ const findings = [];
64
+ const lines = source.split('\n');
65
+ for (let i = 0; i < lines.length; i++) {
66
+ const line = lines[i].trim();
67
+ if ((line.includes('selfdestruct(') || line.includes('selfdestruct (')) && !line.startsWith('//')) {
68
+ findings.push({
69
+ severity: 'High',
70
+ title: '[Basic Check] selfdestruct Usage',
71
+ description: `selfdestruct found at line ${i + 1}. This can permanently destroy the contract and send remaining Ether to an address.`,
72
+ location: `Line ${i + 1}`,
73
+ recommendation: 'Remove selfdestruct or protect it with strict access control. Note: selfdestruct is deprecated in newer Solidity versions.',
74
+ });
75
+ }
76
+ }
77
+ return findings;
78
+ }
79
+ export function checkFloatingPragma(source) {
80
+ const findings = [];
81
+ const lines = source.split('\n');
82
+ for (let i = 0; i < lines.length; i++) {
83
+ const line = lines[i].trim();
84
+ if (line.startsWith('pragma solidity') && line.includes('^')) {
85
+ findings.push({
86
+ severity: 'Informational',
87
+ title: '[Basic Check] Floating Pragma',
88
+ description: `Floating pragma found at line ${i + 1}: "${line}". Contracts should be deployed with the same compiler version they were tested with.`,
89
+ location: `Line ${i + 1}`,
90
+ recommendation: 'Lock the pragma to a specific version, e.g., "pragma solidity 0.8.20;" instead of "pragma solidity ^0.8.20;".',
91
+ });
92
+ }
93
+ }
94
+ return findings;
95
+ }
96
+ function buildSummary(findings) {
97
+ const summary = {
98
+ high: 0,
99
+ medium: 0,
100
+ low: 0,
101
+ informational: 0,
102
+ optimization: 0,
103
+ total: findings.length,
104
+ };
105
+ for (const finding of findings) {
106
+ switch (finding.severity) {
107
+ case 'High':
108
+ summary.high++;
109
+ break;
110
+ case 'Medium':
111
+ summary.medium++;
112
+ break;
113
+ case 'Low':
114
+ summary.low++;
115
+ break;
116
+ case 'Informational':
117
+ summary.informational++;
118
+ break;
119
+ case 'Optimization':
120
+ summary.optimization++;
121
+ break;
122
+ }
123
+ }
124
+ return summary;
125
+ }
126
+ export function runFallbackAnalysis(source) {
127
+ const findings = [
128
+ ...checkReentrancy(source),
129
+ ...checkUncheckedReturn(source),
130
+ ...checkTxOrigin(source),
131
+ ...checkSelfDestruct(source),
132
+ ...checkFloatingPragma(source),
133
+ ];
134
+ const summary = buildSummary(findings);
135
+ const passed = summary.high === 0;
136
+ return { findings, summary, passed };
137
+ }
138
+ export function runFallbackAnalysisFromFile(filePath) {
139
+ const source = readFileSync(filePath, 'utf-8');
140
+ return runFallbackAnalysis(source);
141
+ }
142
+ //# sourceMappingURL=fallback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fallback.js","sourceRoot":"","sources":["../../src/analyzer/fallback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAyBvC,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IACE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAC9G,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EACtB,CAAC;YACD,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5D,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACnC,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClI,QAAQ,CAAC,IAAI,CAAC;wBACZ,QAAQ,EAAE,MAAM;wBAChB,KAAK,EAAE,oCAAoC;wBAC3C,WAAW,EAAE,yBAAyB,CAAC,GAAG,CAAC,0CAA0C,CAAC,GAAG,CAAC,mDAAmD;wBAC7I,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;wBACzB,cAAc,EAAE,yHAAyH;qBAC1I,CAAC,CAAC;oBACH,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACjF,QAAQ,CAAC,IAAI,CAAC;oBACZ,QAAQ,EAAE,QAAQ;oBAClB,KAAK,EAAE,sCAAsC;oBAC7C,WAAW,EAAE,0BAA0B,CAAC,GAAG,CAAC,iEAAiE;oBAC7G,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;oBACzB,cAAc,EAAE,sGAAsG;iBACvH,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,+BAA+B;gBACtC,WAAW,EAAE,0BAA0B,CAAC,GAAG,CAAC,wEAAwE;gBACpH,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;gBACzB,cAAc,EAAE,+DAA+D;aAChF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAClG,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,MAAM;gBAChB,KAAK,EAAE,kCAAkC;gBACzC,WAAW,EAAE,8BAA8B,CAAC,GAAG,CAAC,qFAAqF;gBACrI,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;gBACzB,cAAc,EAAE,4HAA4H;aAC7I,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7D,QAAQ,CAAC,IAAI,CAAC;gBACZ,QAAQ,EAAE,eAAe;gBACzB,KAAK,EAAE,+BAA+B;gBACtC,WAAW,EAAE,iCAAiC,CAAC,GAAG,CAAC,MAAM,IAAI,uFAAuF;gBACpJ,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;gBACzB,cAAc,EAAE,+GAA+G;aAChI,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,QAAmB;IACvC,MAAM,OAAO,GAAoB;QAC/B,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;QACT,GAAG,EAAE,CAAC;QACN,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,KAAK,EAAE,QAAQ,CAAC,MAAM;KACvB,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;YACzB,KAAK,MAAM;gBAAE,OAAO,CAAC,IAAI,EAAE,CAAC;gBAAC,MAAM;YACnC,KAAK,QAAQ;gBAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBAAC,MAAM;YACvC,KAAK,KAAK;gBAAE,OAAO,CAAC,GAAG,EAAE,CAAC;gBAAC,MAAM;YACjC,KAAK,eAAe;gBAAE,OAAO,CAAC,aAAa,EAAE,CAAC;gBAAC,MAAM;YACrD,KAAK,cAAc;gBAAE,OAAO,CAAC,YAAY,EAAE,CAAC;gBAAC,MAAM;QACrD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,QAAQ,GAAc;QAC1B,GAAG,eAAe,CAAC,MAAM,CAAC;QAC1B,GAAG,oBAAoB,CAAC,MAAM,CAAC;QAC/B,GAAG,aAAa,CAAC,MAAM,CAAC;QACxB,GAAG,iBAAiB,CAAC,MAAM,CAAC;QAC5B,GAAG,mBAAmB,CAAC,MAAM,CAAC;KAC/B,CAAC;IAEF,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;IAElC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,QAAgB;IAC1D,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC"}
@@ -0,0 +1,24 @@
1
+ export interface Finding {
2
+ severity: 'High' | 'Medium' | 'Low' | 'Informational' | 'Optimization';
3
+ title: string;
4
+ description: string;
5
+ location: string;
6
+ recommendation: string;
7
+ }
8
+ export interface AnalysisSummary {
9
+ high: number;
10
+ medium: number;
11
+ low: number;
12
+ informational: number;
13
+ optimization: number;
14
+ total: number;
15
+ }
16
+ export interface AnalysisResult {
17
+ findings: Finding[];
18
+ summary: AnalysisSummary;
19
+ passed: boolean;
20
+ }
21
+ export declare function analyzeContract(filePath: string): Promise<AnalysisResult>;
22
+ export declare function isSlitherAvailable(): boolean;
23
+ export declare function getSlitherInstallInstructions(): string;
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,eAAe,GAAG,cAAc,CAAC;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;CACjB;AAyBD,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CA4B/E;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,wBAAgB,6BAA6B,IAAI,MAAM,CAWtD"}
@@ -0,0 +1,73 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { isSlitherInstalled, runSlither, mapSlitherResults } from './slither.js';
3
+ import { runFallbackAnalysis } from './fallback.js';
4
+ function buildSummary(findings) {
5
+ const summary = {
6
+ high: 0,
7
+ medium: 0,
8
+ low: 0,
9
+ informational: 0,
10
+ optimization: 0,
11
+ total: findings.length,
12
+ };
13
+ for (const finding of findings) {
14
+ switch (finding.severity) {
15
+ case 'High':
16
+ summary.high++;
17
+ break;
18
+ case 'Medium':
19
+ summary.medium++;
20
+ break;
21
+ case 'Low':
22
+ summary.low++;
23
+ break;
24
+ case 'Informational':
25
+ summary.informational++;
26
+ break;
27
+ case 'Optimization':
28
+ summary.optimization++;
29
+ break;
30
+ }
31
+ }
32
+ return summary;
33
+ }
34
+ export async function analyzeContract(filePath) {
35
+ if (!existsSync(filePath)) {
36
+ throw new Error(`Contract file not found: ${filePath}`);
37
+ }
38
+ if (isSlitherAvailable()) {
39
+ const output = runSlither(filePath);
40
+ const findings = mapSlitherResults(output);
41
+ const summary = buildSummary(findings);
42
+ const passed = summary.high === 0;
43
+ return { findings, summary, passed };
44
+ }
45
+ const source = readFileSync(filePath, 'utf-8');
46
+ const result = runFallbackAnalysis(source);
47
+ result.findings.unshift({
48
+ severity: 'Informational',
49
+ title: '[Basic Check] Slither Not Installed',
50
+ description: 'Slither is not installed. Only basic regex-based checks were performed. Install Slither for comprehensive analysis.',
51
+ location: 'N/A',
52
+ recommendation: getSlitherInstallInstructions(),
53
+ });
54
+ result.summary.informational++;
55
+ result.summary.total++;
56
+ return result;
57
+ }
58
+ export function isSlitherAvailable() {
59
+ return isSlitherInstalled();
60
+ }
61
+ export function getSlitherInstallInstructions() {
62
+ return [
63
+ 'Install Slither for comprehensive smart contract analysis:',
64
+ ' pip3 install slither-analyzer',
65
+ '',
66
+ 'Or with pipx:',
67
+ ' pipx install slither-analyzer',
68
+ '',
69
+ 'Requires Python 3.8+ and solc (Solidity compiler).',
70
+ 'More info: https://github.com/crytic/slither',
71
+ ].join('\n');
72
+ }
73
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analyzer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AA0BpD,SAAS,YAAY,CAAC,QAAmB;IACvC,MAAM,OAAO,GAAoB;QAC/B,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;QACT,GAAG,EAAE,CAAC;QACN,aAAa,EAAE,CAAC;QAChB,YAAY,EAAE,CAAC;QACf,KAAK,EAAE,QAAQ,CAAC,MAAM;KACvB,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,QAAQ,OAAO,CAAC,QAAQ,EAAE,CAAC;YACzB,KAAK,MAAM;gBAAE,OAAO,CAAC,IAAI,EAAE,CAAC;gBAAC,MAAM;YACnC,KAAK,QAAQ;gBAAE,OAAO,CAAC,MAAM,EAAE,CAAC;gBAAC,MAAM;YACvC,KAAK,KAAK;gBAAE,OAAO,CAAC,GAAG,EAAE,CAAC;gBAAC,MAAM;YACjC,KAAK,eAAe;gBAAE,OAAO,CAAC,aAAa,EAAE,CAAC;gBAAC,MAAM;YACrD,KAAK,cAAc;gBAAE,OAAO,CAAC,YAAY,EAAE,CAAC;gBAAC,MAAM;QACrD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAgB;IACpD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,kBAAkB,EAAE,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAc,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC;QAClC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE3C,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;QACtB,QAAQ,EAAE,eAAe;QACzB,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EAAE,qHAAqH;QAClI,QAAQ,EAAE,KAAK;QACf,cAAc,EAAE,6BAA6B,EAAE;KAChD,CAAC,CAAC;IAEH,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;IAC/B,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAEvB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,OAAO,kBAAkB,EAAE,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,OAAO;QACL,4DAA4D;QAC5D,iCAAiC;QACjC,EAAE;QACF,eAAe;QACf,iCAAiC;QACjC,EAAE;QACF,oDAAoD;QACpD,8CAA8C;KAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,36 @@
1
+ export interface SlitherDetector {
2
+ check: string;
3
+ impact: string;
4
+ confidence: string;
5
+ description: string;
6
+ elements: SlitherElement[];
7
+ first_markdown_element: string;
8
+ }
9
+ export interface SlitherElement {
10
+ type: string;
11
+ name: string;
12
+ source_mapping: {
13
+ filename_relative: string;
14
+ lines: number[];
15
+ starting_column: number;
16
+ ending_column: number;
17
+ };
18
+ }
19
+ export interface SlitherOutput {
20
+ success: boolean;
21
+ error: string | null;
22
+ results: {
23
+ detectors: SlitherDetector[];
24
+ } | null;
25
+ }
26
+ export interface Finding {
27
+ severity: 'High' | 'Medium' | 'Low' | 'Informational' | 'Optimization';
28
+ title: string;
29
+ description: string;
30
+ location: string;
31
+ recommendation: string;
32
+ }
33
+ export declare function isSlitherInstalled(): boolean;
34
+ export declare function runSlither(filePath: string): SlitherOutput;
35
+ export declare function mapSlitherResults(output: SlitherOutput): Finding[];
36
+ //# sourceMappingURL=slither.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slither.d.ts","sourceRoot":"","sources":["../../src/analyzer/slither.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE;QACd,iBAAiB,EAAE,MAAM,CAAC;QAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE;QACP,SAAS,EAAE,eAAe,EAAE,CAAC;KAC9B,GAAG,IAAI,CAAC;CACV;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,eAAe,GAAG,cAAc,CAAC;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAcD,wBAAgB,kBAAkB,IAAI,OAAO,CAQ5C;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CA6B1D;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,EAAE,CAkBlE"}
@@ -0,0 +1,92 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { platform } from 'node:os';
3
+ const IMPACT_MAP = {
4
+ High: 'High',
5
+ Medium: 'Medium',
6
+ Low: 'Low',
7
+ Informational: 'Informational',
8
+ Optimization: 'Optimization',
9
+ };
10
+ function mapImpact(impact) {
11
+ return IMPACT_MAP[impact] ?? 'Informational';
12
+ }
13
+ export function isSlitherInstalled() {
14
+ try {
15
+ const cmd = platform() === 'win32' ? 'where slither' : 'which slither';
16
+ execSync(cmd, { stdio: 'pipe' });
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ }
23
+ export function runSlither(filePath) {
24
+ try {
25
+ const stdout = execSync(`slither ${filePath} --json -`, {
26
+ encoding: 'utf-8',
27
+ stdio: ['pipe', 'pipe', 'pipe'],
28
+ timeout: 120_000,
29
+ });
30
+ const parsed = JSON.parse(stdout);
31
+ return parsed;
32
+ }
33
+ catch (err) {
34
+ if (err && typeof err === 'object' && 'stdout' in err) {
35
+ const stdout = err.stdout;
36
+ if (stdout && typeof stdout === 'string') {
37
+ try {
38
+ const parsed = JSON.parse(stdout);
39
+ return parsed;
40
+ }
41
+ catch {
42
+ // JSON parse failed, fall through
43
+ }
44
+ }
45
+ }
46
+ return {
47
+ success: false,
48
+ error: err instanceof Error ? err.message : String(err),
49
+ results: null,
50
+ };
51
+ }
52
+ }
53
+ export function mapSlitherResults(output) {
54
+ if (!output.results?.detectors) {
55
+ return [];
56
+ }
57
+ return output.results.detectors.map((detector) => {
58
+ const location = detector.elements.length > 0
59
+ ? formatLocation(detector.elements[0])
60
+ : 'Unknown';
61
+ return {
62
+ severity: mapImpact(detector.impact),
63
+ title: detector.check,
64
+ description: detector.description,
65
+ location,
66
+ recommendation: getRecommendation(detector.check),
67
+ };
68
+ });
69
+ }
70
+ function formatLocation(element) {
71
+ const file = element.source_mapping.filename_relative;
72
+ const lines = element.source_mapping.lines;
73
+ if (lines.length > 0) {
74
+ return `${file}#L${lines[0]}`;
75
+ }
76
+ return file;
77
+ }
78
+ function getRecommendation(check) {
79
+ const recommendations = {
80
+ 'reentrancy-eth': 'Use the checks-effects-interactions pattern or a reentrancy guard.',
81
+ 'reentrancy-no-eth': 'Use the checks-effects-interactions pattern or a reentrancy guard.',
82
+ 'unchecked-lowlevel': 'Check the return value of low-level calls.',
83
+ 'unchecked-send': 'Check the return value of send().',
84
+ 'tx-origin': 'Use msg.sender instead of tx.origin for authorization.',
85
+ 'suicidal': 'Remove or protect selfdestruct with access control.',
86
+ 'arbitrary-send': 'Restrict who can call functions that send Ether.',
87
+ 'locked-ether': 'Add a withdrawal function for locked Ether.',
88
+ 'solc-version': 'Use a fixed Solidity version pragma.',
89
+ };
90
+ return recommendations[check] ?? 'Review and address this finding.';
91
+ }
92
+ //# sourceMappingURL=slither.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slither.js","sourceRoot":"","sources":["../../src/analyzer/slither.ts"],"names":[],"mappings":"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"}