edith-skep3 2.4.3
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/LICENSE +21 -0
- package/README.md +615 -0
- package/assets/banner.png +0 -0
- package/dist/ai.js +153 -0
- package/dist/brain.js +482 -0
- package/dist/explorer.js +167 -0
- package/dist/index.js +550 -0
- package/dist/intel.js +35 -0
- package/dist/parser.js +229 -0
- package/dist/simulator.js +229 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Anubhav Singh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
|
|
2
|
+
<div align="center">
|
|
3
|
+
|
|
4
|
+
<img src="assets/banner.png" alt="Edith Sentinel β Privacy-First AI-Powered Web3 Transaction Firewall" width="100%" />
|
|
5
|
+
|
|
6
|
+
# π‘οΈ EDITH SKEP3
|
|
7
|
+
|
|
8
|
+
### *The Privacy-First, AI-Powered Web3 Transaction Firewall*
|
|
9
|
+
|
|
10
|
+
> **Simulate before you sign. Know before you lose.**
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
[](https://www.typescriptlang.org/)
|
|
15
|
+
[](https://getfoundry.sh/)
|
|
16
|
+
[](https://ollama.com/)
|
|
17
|
+
[](https://viem.sh/)
|
|
18
|
+
[]()
|
|
19
|
+
[]()
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## π§ The Problem
|
|
26
|
+
|
|
27
|
+
Every year, billions of dollars are drained from crypto wallets through:
|
|
28
|
+
|
|
29
|
+
- **Infinite token approvals** β you sign once, a drainer contract steals your assets forever
|
|
30
|
+
- **Phishing contracts** β contracts that look like legitimate dApps but secretly transfer your funds
|
|
31
|
+
- **Proxy exploits** β contracts that `DELEGATECALL` into unknown implementations to execute hidden malicious logic
|
|
32
|
+
- **Fake airdrops** β contracts that first approve a drainer, then drain β two transactions that look innocent in isolation
|
|
33
|
+
|
|
34
|
+
**The core failure:** wallets show you a raw hex string and ask "sign?" You have no idea what the contract actually does until it's too late.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## β
The Solution
|
|
39
|
+
|
|
40
|
+
**EDITH Sentinel** intercepts the transaction *before you sign it*, runs it in a sandboxed local Ethereum fork, and uses a local AI to analyze exactly what happened β what tokens moved, what approvals were granted, what hidden sub-calls were made β and gives you a plain-English verdict.
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
βββββββββββ YOUR MACHINE ONLY ββββββββββββββββ
|
|
44
|
+
β β
|
|
45
|
+
Suspicious βββΊ β Fork Mainnet β Simulate β AI β βββΊ VERDICT
|
|
46
|
+
Transaction β (Anvil/Rust) (EVM) (Ollama)β SAFE / RISKY
|
|
47
|
+
β β / CRITICAL
|
|
48
|
+
βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
49
|
+
|
|
50
|
+
Zero data leaves your machine. No cloud. No API keys.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## ποΈ Architecture Overview
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
59
|
+
β EDITH SENTINEL
|
|
60
|
+
β
|
|
61
|
+
β CLI Entry (index.ts)
|
|
62
|
+
β βββ Commander.js + Ora spinners + Chalk terminal UI
|
|
63
|
+
β β
|
|
64
|
+
β ββββΊ AnvilSimulator (simulator.ts)
|
|
65
|
+
β β βββ Spawns Anvil process (Foundry/Rust EVM)
|
|
66
|
+
β β βββ Forks Ethereum Mainnet via free public RPC
|
|
67
|
+
β β βββ anvil_impersonateAccount β no private key needed
|
|
68
|
+
β β βββ anvil_setBalance β gives gas money
|
|
69
|
+
β β βββ eth_sendTransaction β runs tx in sandbox
|
|
70
|
+
β β βββ debug_traceTransaction β full EVM execution log
|
|
71
|
+
β β
|
|
72
|
+
β ββββΊ TransactionParser (parser.ts)
|
|
73
|
+
β β βββ Fetches receipt + logs via Viem
|
|
74
|
+
β β βββ Decodes ERC-20 Transfer / Approval events
|
|
75
|
+
β β βββ Detects infinite approvals (MaxUint256)
|
|
76
|
+
β β βββ Detects unexpected token outflows
|
|
77
|
+
β β βββ Extracts DELEGATECALL / SELFDESTRUCT from trace
|
|
78
|
+
β β βββ Formats full report for AI consumption
|
|
79
|
+
β β
|
|
80
|
+
β ββββΊ SecurityAuditor (ai.ts)
|
|
81
|
+
β βββ Connects to local Ollama (port 11434)
|
|
82
|
+
β βββ Sends structured security audit prompt
|
|
83
|
+
β βββ Receives VERDICT: SAFE / RISKY / CRITICAL
|
|
84
|
+
β βββ Parses structured response into display
|
|
85
|
+
β
|
|
86
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## π¬ Under The Hood β How Forking Really Works
|
|
92
|
+
|
|
93
|
+
### The Common Misconception
|
|
94
|
+
|
|
95
|
+
> β "You download the entire Ethereum blockchain (1.2 TB) locally"
|
|
96
|
+
|
|
97
|
+
**That is wrong.** Here's what actually happens:
|
|
98
|
+
|
|
99
|
+
### Lazy State Loading β Copy-On-Write
|
|
100
|
+
|
|
101
|
+
Anvil starts **completely empty**. It knows nothing about mainnet state. The moment your simulated transaction touches any piece of state β a wallet balance, a contract's storage slot, a piece of bytecode β Anvil fires a single RPC call to the remote node and fetches *just that one piece*, caches it in RAM, and uses it locally.
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
Transaction touches USDC contract:
|
|
105
|
+
|
|
106
|
+
Anvil RAM (empty) Remote RPC (ethereum.publicnode.com)
|
|
107
|
+
βββββββββββββββββ ββββββββββββββββββββββββββββββββββββ
|
|
108
|
+
"What's the code eth_getCode(0xA0b869...USDC, block=24497066)
|
|
109
|
+
at 0xA0b869...?" βββββββββββΊ returns: 0x608060405234801561001057...
|
|
110
|
+
βββββββββββ
|
|
111
|
+
Cache bytecode in RAM
|
|
112
|
+
Run EVM against it
|
|
113
|
+
(3-5 total RPC calls for a simple token tx)
|
|
114
|
+
(megabytes fetched, not terabytes)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### The Fork Point
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Ethereum Mainnet Timeline:
|
|
121
|
+
|
|
122
|
+
Block 24,497,065 βββββββββββββββΊ Block 24,497,066 βββΊ Block 24,497,067 βββΊ ...
|
|
123
|
+
β (real) (real)
|
|
124
|
+
β
|
|
125
|
+
ββββΊ Anvil "snapshot" taken here
|
|
126
|
+
β
|
|
127
|
+
ββββΊ Your Simulated Block (exists ONLY in your RAM)
|
|
128
|
+
β
|
|
129
|
+
ββββΊ Anvil process killed β RAM freed β gone forever
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Your simulated transaction runs in a **parallel universe that branches off mainnet**. Real mainnet never knows about it.
|
|
133
|
+
|
|
134
|
+
### Storage Lifetime
|
|
135
|
+
|
|
136
|
+
| Entity | Storage | Persists? |
|
|
137
|
+
|--------|---------|-----------|
|
|
138
|
+
| Ethereum Mainnet | 1.2 TB disk on real nodes | Forever |
|
|
139
|
+
| Anvil Fork | ~50-200 MB RAM | One session only |
|
|
140
|
+
| Downloaded state | RAM only | Gone on process kill |
|
|
141
|
+
| Your disk | Completely untouched | Nothing written |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## βοΈ How Contract Code is Simulated
|
|
146
|
+
|
|
147
|
+
### Step 1 β Bytecode Acquisition
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
edith scan 0xScamContract
|
|
151
|
+
|
|
152
|
+
β Anvil: eth_getCode(0xScamContract)
|
|
153
|
+
β "0x608060405234801561001057600080fd5b50..."
|
|
154
|
+
|
|
155
|
+
This IS the contract. Raw compiled EVM bytecode.
|
|
156
|
+
No source code needed. No ABI needed.
|
|
157
|
+
Anvil has the full logic.
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Step 2 β EVM Execution (Instruction by Instruction)
|
|
161
|
+
|
|
162
|
+
```
|
|
163
|
+
Your tx: from=0xYourWallet to=0xScamContract data=0xa9059cbb...
|
|
164
|
+
|
|
165
|
+
EVM begins:
|
|
166
|
+
PC=0 PUSH1 0x60 stack: [0x60]
|
|
167
|
+
PC=2 PUSH1 0x40 stack: [0x40, 0x60]
|
|
168
|
+
PC=4 MSTORE writes 0x60 to mem[0x40]
|
|
169
|
+
...
|
|
170
|
+
PC=87 SLOAD slot=0x3 β reads YOUR token balance from storage
|
|
171
|
+
PC=88 SUB β subtracts transfer amount
|
|
172
|
+
PC=89 SSTORE slot=0x3 β writes new balance back
|
|
173
|
+
...
|
|
174
|
+
PC=134 LOG3 β emits Transfer event ββ Parser catches this
|
|
175
|
+
...
|
|
176
|
+
PC=201 DELEGATECALL β calls implementation ββ RED FLAG
|
|
177
|
+
...
|
|
178
|
+
STOP Transaction complete
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Every opcode. Recorded. Nothing hidden.
|
|
182
|
+
|
|
183
|
+
### Step 3 β Architectural Analysis (v2.2.0)
|
|
184
|
+
|
|
185
|
+
Raw traces tell you *what* happened, but Bytecode tells you *why*. EDITH now provides a three-layered code analysis:
|
|
186
|
+
|
|
187
|
+
1. **Sourcify (Keyless)**: Fetches verified source files directly from the decentralized Sourcify repository.
|
|
188
|
+
2. **Etherscan (Verified)**: Fetches original Solidity source code if the contract is verified.
|
|
189
|
+
3. **Decompilation (Unverified)**: If no source is found, EDITH uses public decompilation APIs (api.dedub.io) to turn raw bytecode back into readable logic for the AI.
|
|
190
|
+
|
|
191
|
+
This allows the AI to detect hidden backdoors, rug-pull logic, and malicious modifiers *within* the contract itself, even before it's ever executed.
|
|
192
|
+
|
|
193
|
+
### Step 4 β The Execution Recording
|
|
194
|
+
|
|
195
|
+
`debug_traceTransaction` on the **local Anvil node** returns the complete call tree:
|
|
196
|
+
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"type": "CALL",
|
|
200
|
+
"from": "0xYourWallet",
|
|
201
|
+
"to": "0xScamContract",
|
|
202
|
+
"calls": [
|
|
203
|
+
{
|
|
204
|
+
"type": "DELEGATECALL",
|
|
205
|
+
"from": "0xScamContract",
|
|
206
|
+
"to": "0xHiddenImplementation",
|
|
207
|
+
"calls": [
|
|
208
|
+
{
|
|
209
|
+
"type": "CALL",
|
|
210
|
+
"to": "0xAttackerWallet",
|
|
211
|
+
"value": "0xDE0B6B3A7640000"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
],
|
|
216
|
+
"logs": [
|
|
217
|
+
{
|
|
218
|
+
"topics": ["0x8c5be1e5..."],
|
|
219
|
+
"data": "0xffffffffffffffffffffffffffffffff"
|
|
220
|
+
}
|
|
221
|
+
]
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
This is **ground truth** β not what the contract claims to do, but what it *actually did*.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## π‘οΈ The Three-Layer Detection System
|
|
230
|
+
|
|
231
|
+
### Layer 1 β Deterministic Rules (parser.ts)
|
|
232
|
+
|
|
233
|
+
Hardcoded patterns that are **objectively dangerous** regardless of context:
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
237
|
+
β RULE: Infinite Approval
|
|
238
|
+
β
|
|
239
|
+
β IF Approval.amount == MaxUint256 (2^256 - 1)
|
|
240
|
+
β THEN β "INFINITE APPROVAL to {spender}"
|
|
241
|
+
β
|
|
242
|
+
β Why: Spender can drain ALL your tokens, forever,
|
|
243
|
+
β without any further action from you
|
|
244
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
245
|
+
|
|
246
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
247
|
+
β RULE: Unexpected Token Outflow
|
|
248
|
+
β
|
|
249
|
+
β IF Transfer.from == yourWallet
|
|
250
|
+
β AND you did not explicitly intend to send
|
|
251
|
+
β THEN β "Token transfer FROM your wallet"
|
|
252
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Layer 2 β Opcode Pattern Matching (parser.ts)
|
|
256
|
+
|
|
257
|
+
Dangerous EVM opcodes detected by walking the full call tree:
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
261
|
+
β DELEGATECALL
|
|
262
|
+
β βββββββββββ
|
|
263
|
+
β Normal CALL: ContractB runs in its OWN storage context
|
|
264
|
+
β DELEGATECALL: ContractB runs in CALLER'S storage context
|
|
265
|
+
β
|
|
266
|
+
β = ContractB can READ/WRITE your token balances
|
|
267
|
+
β = Used legitimately by proxies (USDC, most DeFi)
|
|
268
|
+
β = Also the #1 tool for drainers and exploits
|
|
269
|
+
β β Always flagged, AI determines legitimacy
|
|
270
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
271
|
+
|
|
272
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
273
|
+
β SELFDESTRUCT
|
|
274
|
+
β ββββββββββββ
|
|
275
|
+
β Destroys the contract and sends all its ETH elsewhere
|
|
276
|
+
β Legitimate in almost zero user-facing scenarios
|
|
277
|
+
β β Always flagged as critical
|
|
278
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
279
|
+
|
|
280
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
281
|
+
β CREATE2
|
|
282
|
+
β βββββββ
|
|
283
|
+
β Deploys a new contract at a deterministic address
|
|
284
|
+
β Used in frontrunning attacks and flash loan exploits
|
|
285
|
+
β β Flagged for AI review
|
|
286
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Layer 3 β AI Semantic Reasoning (ai.ts)
|
|
290
|
+
|
|
291
|
+
The parser gives **facts**. The AI provides **judgment**.
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
Parser output (facts):
|
|
295
|
+
β DELEGATECALL to 0x43506849...
|
|
296
|
+
β No Transfer event emitted
|
|
297
|
+
β Transaction reverted
|
|
298
|
+
β Gas used: 28,622
|
|
299
|
+
|
|
300
|
+
AI reasoning (judgment):
|
|
301
|
+
"A legitimate token transfer ALWAYS emits a Transfer event.
|
|
302
|
+
This contract made a DELEGATECALL but emitted NO events.
|
|
303
|
+
The silence + delegation to an unverified address means
|
|
304
|
+
execution logic is hidden in an unknown implementation.
|
|
305
|
+
The revert with no logs suggests the malicious path was
|
|
306
|
+
taken but failed β indicating it IS a drainer contract
|
|
307
|
+
that couldn't complete because conditions weren't met."
|
|
308
|
+
|
|
309
|
+
β VERDICT: CRITICAL
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
**What the AI catches that rules cannot:**
|
|
313
|
+
|
|
314
|
+
| Attack Pattern | Layer 1 Rules | Layer 2 Opcodes | Layer 3 AI |
|
|
315
|
+
|---|:---:|:---:|:---:|
|
|
316
|
+
| Infinite approval | β
| β | β
explains |
|
|
317
|
+
| Unexpected token drain | β
| β | β
explains |
|
|
318
|
+
| DELEGATECALL to unknown | β | β
| β
contextualizes |
|
|
319
|
+
| SELFDESTRUCT | β | β
| β
contextualizes |
|
|
320
|
+
| No events emitted (silent drain) | β | β | β
catches |
|
|
321
|
+
| Reentrancy pattern | β | β | β
notices loops |
|
|
322
|
+
| Fake airdrop β approval β drain | β | β | β
connects chain |
|
|
323
|
+
| Legitimate proxy (USDC, AAVE) | β can't tell | β flags anyway | β
distinguishes |
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
## π€ The AI Pipeline
|
|
328
|
+
|
|
329
|
+
```
|
|
330
|
+
ββββββββββββββββ
|
|
331
|
+
β Simulation Raw JSON: receipt, logs, call trace, gas, status
|
|
332
|
+
β Report
|
|
333
|
+
ββββββββ¬ββββββββ
|
|
334
|
+
β
|
|
335
|
+
βΌ
|
|
336
|
+
ββββββββββββββββ
|
|
337
|
+
β parser.ts β Structured markdown report:
|
|
338
|
+
β .formatForAI β - Events decoded (Transfer, Approval with amounts)
|
|
339
|
+
β β - Trace summary (sub-call count, suspicious opcodes)
|
|
340
|
+
β β - Pre-detected warnings (Layer 1 + 2 results)
|
|
341
|
+
ββββββββ¬ββββββββ
|
|
342
|
+
β
|
|
343
|
+
βΌ
|
|
344
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
345
|
+
β Ollama (local, port 11434)
|
|
346
|
+
β
|
|
347
|
+
β Model: qwen3:4b-instruct (runs entirely on your CPU)
|
|
348
|
+
β
|
|
349
|
+
β System Prompt:
|
|
350
|
+
β "You are EDITH, an expert Web3 security auditor.
|
|
351
|
+
β Analyze this simulated transaction trace.
|
|
352
|
+
β Look for: infinite approvals, DELEGATECALL exploits,
|
|
353
|
+
β phishing signatures, reentrancy, hidden drains.
|
|
354
|
+
β Respond with: VERDICT / REASON / TECHNICAL_DETAIL"
|
|
355
|
+
β
|
|
356
|
+
β Temperature: 0.1 β deterministic, not creative
|
|
357
|
+
β Max tokens: 512 β concise, actionable output
|
|
358
|
+
ββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
359
|
+
β
|
|
360
|
+
βΌ
|
|
361
|
+
ββββββββββββββββ
|
|
362
|
+
β parseVerdict β Extracts structured fields from LLM response
|
|
363
|
+
β β VERDICT: SAFE | RISKY | CRITICAL
|
|
364
|
+
β β REASON: plain English for end users
|
|
365
|
+
β β TECHNICAL_DETAIL: for advanced users
|
|
366
|
+
ββββββββ¬ββββββββ
|
|
367
|
+
β
|
|
368
|
+
βΌ
|
|
369
|
+
ββββββββββββββββ
|
|
370
|
+
β Terminal UI β Color-coded verdict with warnings
|
|
371
|
+
β (Chalk) β π’ SAFE / π‘ RISKY / π΄ CRITICAL
|
|
372
|
+
ββββββββββββββββ
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## π Full Execution Flow
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
$ edith scan 0xSuspiciousContract --method "claimAirdrop()"
|
|
381
|
+
|
|
382
|
+
1. ββ Anvil spawns ββββββββββββββββββββββββββββββββββββββββββ
|
|
383
|
+
β ~/.foundry/bin/anvil --fork-url ethereum.publicnode.com
|
|
384
|
+
β HTTP poll every 300ms until port 8545 responds
|
|
385
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
386
|
+
|
|
387
|
+
2. ββ State available βββββββββββββββββββββββββββββββββββββββ
|
|
388
|
+
β On-demand fetch of only the storage slots your tx
|
|
389
|
+
β touches β a few KB total, not terabytes
|
|
390
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
391
|
+
|
|
392
|
+
3. ββ Wallet impersonation ββββββββββββββββββββββββββββββββββ
|
|
393
|
+
β anvil_impersonateAccount(yourAddress)
|
|
394
|
+
β anvil_setBalance(yourAddress, 1 ETH) β gas money
|
|
395
|
+
β No private key required. No MetaMask. Sandboxed.
|
|
396
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
397
|
+
|
|
398
|
+
4. ββ Transaction simulation ββββββββββββββββββββββββββββββββ
|
|
399
|
+
β eth_sendTransaction({ from, to, data, value })
|
|
400
|
+
β evm_mine() β force-include in next block
|
|
401
|
+
β Poll for receipt confirmation
|
|
402
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
403
|
+
|
|
404
|
+
5. ββ Trace extraction ββββββββββββββββββββββββββββββββββββββ
|
|
405
|
+
β debug_traceTransaction(txHash, {tracer:'callTracer'})
|
|
406
|
+
β Called on LOCAL Anvil β completely free
|
|
407
|
+
β Returns full recursive call tree with all opcodes
|
|
408
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
409
|
+
|
|
410
|
+
6. ββ Parsing βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
411
|
+
β Decode events β Transfer, Approval, etc.
|
|
412
|
+
β Detect infinite approvals β Layer 1
|
|
413
|
+
β Extract DELEGATECALL/SELFDESTRUCT β Layer 2
|
|
414
|
+
β Format full report for AI
|
|
415
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
416
|
+
|
|
417
|
+
7. ββ AI Analysis βββββββββββββββββββββββββββββββββββββββββββ
|
|
418
|
+
β Local Ollama β qwen3:4b-instruct
|
|
419
|
+
β Receives simulation report
|
|
420
|
+
β Returns VERDICT + REASON β Layer 3
|
|
421
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
422
|
+
|
|
423
|
+
8. ββ Verdict βββββββββββββββββββββββββββββββββββββββββββββββ
|
|
424
|
+
β SAFE β π’ Transaction appears legitimate
|
|
425
|
+
β RISKY β π‘ Proceed with caution + explanation
|
|
426
|
+
β CRITICAL β π΄ DO NOT SIGN + threat detail
|
|
427
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
428
|
+
|
|
429
|
+
9. Anvil.kill() β RAM freed β nothing persisted β clean exit
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## π¦ Tech Stack
|
|
435
|
+
|
|
436
|
+
| Layer | Technology | Purpose |
|
|
437
|
+
|---|---|---|
|
|
438
|
+
| **CLI** | Commander.js + Inquirer | Argument parsing, interactive prompts |
|
|
439
|
+
| **Terminal UI** | Chalk + Ora | Colors, spinners, rich output |
|
|
440
|
+
| **Blockchain Fork** | Foundry Anvil (Rust) | Local EVM, mainnet state forking |
|
|
441
|
+
| **Blockchain Client** | Viem v2 | Type-safe Ethereum interactions |
|
|
442
|
+
| **Local AI** | Ollama | Privacy-preserving LLM inference |
|
|
443
|
+
| **Language** | TypeScript 5 | Type safety across entire codebase |
|
|
444
|
+
| **Free RPC** | ethereum.publicnode.com | No API key, no rate limits for forking |
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## π Setup & Usage
|
|
449
|
+
|
|
450
|
+
### Prerequisites
|
|
451
|
+
|
|
452
|
+
**1. Install Foundry (Anvil)**
|
|
453
|
+
```bash
|
|
454
|
+
curl -L https://foundry.paradigm.xyz | bash
|
|
455
|
+
foundryup
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**2. Install & Start Ollama**
|
|
459
|
+
```bash
|
|
460
|
+
# Install from https://ollama.com
|
|
461
|
+
ollama serve
|
|
462
|
+
ollama pull qwen3:4b-instruct
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Installation
|
|
466
|
+
|
|
467
|
+
```bash
|
|
468
|
+
git clone <repo>
|
|
469
|
+
cd edith-sentinel
|
|
470
|
+
npm install
|
|
471
|
+
npm run build
|
|
472
|
+
npm link # This installs the 'edith' command globally!
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Commands
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
# Scan a contract interaction (most common use case)
|
|
479
|
+
edith scan 0xContractAddress --method "claimAirdrop()"
|
|
480
|
+
|
|
481
|
+
# Scan and replay a historical transaction hash
|
|
482
|
+
edith scan 0xTxHash...
|
|
483
|
+
|
|
484
|
+
# Simulate with a specific wallet address
|
|
485
|
+
edith scan 0xContract --from 0xYourWallet --method "approve(address,uint256)"
|
|
486
|
+
|
|
487
|
+
# Use an explicit RPC alias (like llamarpc) with graceful fallback
|
|
488
|
+
edith scan 0xContract --rpc llamarpc
|
|
489
|
+
|
|
490
|
+
# Setup or change your AI Brain (Cloud vs Local)
|
|
491
|
+
edith brain
|
|
492
|
+
|
|
493
|
+
# Run scan using your configured Cloud AI (Gemini, OpenAI, etc.)
|
|
494
|
+
edith scan 0xContract --brain
|
|
495
|
+
|
|
496
|
+
# View exhaustive EVM Call Traces and State Diffs
|
|
497
|
+
edith scan 0xContract -v
|
|
498
|
+
|
|
499
|
+
# Test AI connection without running a full simulation
|
|
500
|
+
edith test-ai
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Example Output
|
|
504
|
+
|
|
505
|
+
```
|
|
506
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
507
|
+
β π‘οΈ EDITH SKEP3 Β· Transaction Firewall β
|
|
508
|
+
β Privacy-First Β· Local AI Β· No Data Leaves Machine β
|
|
509
|
+
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββ£
|
|
510
|
+
β Target : 0xScamContract... β
|
|
511
|
+
β Fork : Ethereum Mainnet (via PublicNode) β
|
|
512
|
+
β Engine : Anvil + Ollama (100% Local) β
|
|
513
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
514
|
+
|
|
515
|
+
β Mainnet forked at block #24,497,066
|
|
516
|
+
β Impersonating wallet: 0xf39Fd...
|
|
517
|
+
β Simulation complete β tx: 0xd977...
|
|
518
|
+
β Trace extracted β 1 event, 2 sub-calls
|
|
519
|
+
|
|
520
|
+
[SIMULATION RESULT]
|
|
521
|
+
Status : REVERTED
|
|
522
|
+
Gas Used : 28622
|
|
523
|
+
Events : 1
|
|
524
|
+
[Events]
|
|
525
|
+
β’ Approval(address,address,uint256) @ 0xUSDC
|
|
526
|
+
owner: 0xYourWallet
|
|
527
|
+
spender: 0xDrainerContract
|
|
528
|
+
amount: INFINITE (Max Uint256)
|
|
529
|
+
|
|
530
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
531
|
+
[PARSER WARNINGS]
|
|
532
|
+
β οΈ INFINITE APPROVAL granted to 0xDrainerContract for USDC
|
|
533
|
+
π΄ Suspicious opcode: DELEGATECALL to 0xUnknownImpl
|
|
534
|
+
|
|
535
|
+
[π€ AI SECURITY AUDIT β EDITH ANALYSIS]
|
|
536
|
+
This transaction grants unlimited spending rights to an
|
|
537
|
+
unknown contract. Combined with a DELEGATECALL to an
|
|
538
|
+
unverified implementation, this is a textbook drainer
|
|
539
|
+
pattern. Do not sign under any circumstances.
|
|
540
|
+
|
|
541
|
+
π¨ VERDICT: CRITICAL
|
|
542
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
543
|
+
|
|
544
|
+
ββ DO NOT SIGN THIS TRANSACTION ββ
|
|
545
|
+
High probability of asset theft or drainer contract.
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
---
|
|
549
|
+
|
|
550
|
+
## π Privacy Architecture
|
|
551
|
+
|
|
552
|
+
```
|
|
553
|
+
What EDITH Sentinel NEVER does:
|
|
554
|
+
β Send your wallet address to any external service for analysis
|
|
555
|
+
β Upload your transaction data to any cloud API
|
|
556
|
+
β Require a paid RPC with account registration
|
|
557
|
+
β Use an external AI API (no OpenAI, no Anthropic, no cloud)
|
|
558
|
+
β Write anything to disk during simulation
|
|
559
|
+
β Phone home with usage data
|
|
560
|
+
|
|
561
|
+
What it DOES:
|
|
562
|
+
β Fetch only the specific contract bytecode + storage it needs
|
|
563
|
+
β Run all AI inference locally via Ollama
|
|
564
|
+
β Destroy all simulation state when done
|
|
565
|
+
β Use anonymous public RPC endpoints with no auth
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
---
|
|
569
|
+
|
|
570
|
+
## π Changelog
|
|
571
|
+
|
|
572
|
+
### v2.4.0 β The "Robustness" Update
|
|
573
|
+
EDITH Sentinel is now faster, far more accurate, and resilient against RPC failures and EVM false positives.
|
|
574
|
+
|
|
575
|
+
- **EVM Gas & State Diff Precision**: Fixed a false positive where standard gas fees paid for reverted transactions were being flagged as malicious asset drains. `parser.ts` now natively identifies and subtracts execution gas cost from raw State Differences.
|
|
576
|
+
- **Dynamic LlamaRPC Integration**: Added `--rpc llamarpc` alias. Includes Cloudflare WAF bypass strategies and a seamless, interactive command-prompt failover back to `ethereum.publicnode.com` if rate-limited!
|
|
577
|
+
- **Verbose Forensic Logging**: Added the `-v` (or `--verbose`) flag. View the exact JSON execution path (Call Traces) and precise mutated wallet balances (State Diffs) right in your terminal.
|
|
578
|
+
- **AI "Verification Poison" Fix**: Contracts officially verified on Etherscan or Sourcify no longer blindly inherit heuristic Threat Alerts inside the AI context prompt, drastically lowering false positive rates on standard proxies like USDC.
|
|
579
|
+
- **Dynamic 4byte Signatures**: Replaced hardcoded topic dictionaries with active REST lookups to the 4byte Directory, translating unknown DeFi calldata signatures into plain-English event names for the AI on the fly.
|
|
580
|
+
- **Massive Context Expansion**: Trace slicing limits were boosted from 64 to 512 bytes, and Contract Code analysis limits were 5x'd to 25,000 bytes, ensuring massive modern dApps are fully digested by cloud brains.
|
|
581
|
+
|
|
582
|
+
---
|
|
583
|
+
|
|
584
|
+
## πΊοΈ Roadmap
|
|
585
|
+
|
|
586
|
+
- [ ] **ABI auto-detection** β fetch verified ABIs from Etherscan for richer log decoding
|
|
587
|
+
- [ ] **Multi-chain support** β Polygon, Arbitrum, Base, BSC
|
|
588
|
+
- [ ] **Historical tx replay** β proper block pinning for replaying confirmed transactions
|
|
589
|
+
- [ ] **Batch scan** β scan all pending txs in a MetaMask queue
|
|
590
|
+
- [ ] **Browser extension** β intercept signing requests directly in the wallet UI
|
|
591
|
+
- [ ] **NFT transfer detection** β ERC-721 and ERC-1155 event decoding
|
|
592
|
+
- [ ] **Reentrancy depth analysis** β detect recursive call patterns automatically
|
|
593
|
+
- [ ] **Known drainer database** β flag addresses reported in community threat feeds
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
<div align="center">
|
|
598
|
+
|
|
599
|
+
---
|
|
600
|
+
|
|
601
|
+
```
|
|
602
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
603
|
+
β β
|
|
604
|
+
β Engineered by anu-sin-theta AKA Optimus Prime β
|
|
605
|
+
β β
|
|
606
|
+
β https://anufied.me β
|
|
607
|
+
β β
|
|
608
|
+
β Assisted by Trillion Artificial Parameters β
|
|
609
|
+
β β
|
|
610
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
*"Simulate before you sign. The blockchain never forgets β but with EDITH, you never have to regret."*
|
|
614
|
+
|
|
615
|
+
</div>
|
|
Binary file
|