The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the EVMole listing page.
EVMole is a powerful library that extracts information from Ethereum Virtual Machine (EVM) bytecode, including function selectors, arguments, state mutability, persistent and transient storage layouts, and CBOR metadata, even for unverified contracts.
API documentation and usage examples (Node.js, Vite, webpack, Parcel, esbuild)
Documentation is available on docs.rs
Foundry's cast uses the Rust implementation of EVMole
For application code, use one of the language bindings above. For agent-driven bytecode analysis, choose one integration.
Use for one-off analysis and scripts:
Install routing and interpretation guidance for supported agents:
Expose EVMole as a typed local tool:
All integrations expect deployed/runtime bytecode and run locally without sending bytecode to an EVMole-operated service. See the agent integration guide for setup, schemas, limitations, and privacy details.
FP/FN - False Positive/False Negative errors; smaller is better
| Dataset | evmole rs · js · py · go | whatsabi | sevm | evmhound | heimdall | |
| coverage2k solidity 2000 addresses 45650 functions | FP addrs | 0 🥇 | 4 | 1 | 56 | 3 |
| FN addrs | 0 🥇 | 11 | 0 🥇 | 224 | 166 | |
| FP funcs | 0 🥇 | 10 | 10 | 616 | 27 | |
| FN funcs | 0 🥇 | 145 | 0 🥇 | 821 | 342 | |
| Time | 24ms · 0.3s · 31ms · 0.1s | 2.0s | 28s(*) | 86ms | 111s(*) | |
| random10k solidity 10000 addresses 223316 functions | FP addrs | 0 🥇 | 19 | 16 | 224 | 7 |
| FN addrs | 0 🥇 | 44 | 1 | 838 | 819 | |
| FP funcs | 0 🥇 | 65 | 112 | 3157 | 260 | |
| FN funcs | 0 🥇 | 173 | 7 | 4112 | 1021 | |
| Time | 0.1s · 0.8s · 0.2s · 0.8s | 7.1s | 80s(*) | 0.4s | 533s(*) | |
| coverage1k vyper 1000 addresses 38759 functions | FP addrs | 0 🥇 | 560 | 0 🥇 | 2 | 0 🥇 |
| FN addrs | 0 🥇 | 998 | 788 | 525 | 998 | |
| FP funcs | 0 🥇 | 560 | 0 🥇 | 5 | 0 🥇 | |
| FN funcs | 0 🥇 | 38759 | 34077 | 16218 | 38759 | |
| Time | 91ms · 0.4s · 0.1s · 0.3s | 1.9s | 5.4s(*) | 67ms | 12s(*) | |
Errors - when at least 1 inferred argument is incorrect: (uint256,string) ≠ (uint256,bytes)
| Dataset | evmole rs · js · py · go | heimdall | |
| coverage2k solidity 45650 functions | Errors | 8.5% 🥇 3883 | 23.3% 10643 |
| Time | 0.8s · 1.7s · 1.1s · 2.1s | 111s(*) | |
| random10k solidity 223316 functions | Errors | 6.8% 🥇 15296 | 21.4% 47878 |
| Time | 3.5s · 6.9s · 4.2s · 9.7s | 511s(*) | |
| coverage1k vyper 38759 functions | Errors | 45.4% 🥇 17590 | 100.0% 38759 |
| Time | 0.5s · 1.1s · 0.6s · 1.4s | 12s(*) | |
Errors - Results are not equal (treating view and pure as equivalent to nonpayable)
Errors strict - Results are strictly unequal (nonpayable ≠ view). Some ABIs mark pure/view functions as nonpayable, so not all strict errors indicate real issues.
| Dataset | evmole rs · js · py · go | whatsabi | sevm | heimdall | |
| coverage2k solidity 45647 functions | Errors | 0.0% 🥇 18 | 52.2% 23810 | 11.2% 5133 | 19.6% 8951 |
| Errors strict | 9.0% 🥇 4107 | 70.9% 32346 | 62.3% 28429 | 41.3% 18835 | |
| Time | 10s · 11s · 9.7s · 20s | 3.1s | 29s(*) | 112s(*) | |
| random10k solidity 223273 functions | Errors | 0.0% 🥇 39 | 48.8% 108928 | 9.3% 20713 | 18.6% 41507 |
| Errors strict | 8.9% 🥇 19940 | 69.9% 156081 | 60.9% 136069 | 40.1% 89519 | |
| Time | 48s · 50s · 46s · 88s | 12s | 81s(*) | 512s(*) | |
| coverage1k vyper 38278 functions | Errors | 0.1% 🥇 34 | 100.0% 38278 | 96.2% 36814 | 100.0% 38278 |
| Errors strict | 1.2% 🥇 441 | 100.0% 38278 | 98.4% 37650 | 100.0% 38278 | |
| Time | 45s · 39s · 44s · 89s | 2.0s | 5.5s(*) | 12s(*) | |
False Negatives - Valid blocks possibly incorrectly marked unreachable by CFG analysis. Lower count usually indicates better precision.
| evmole rs · js · py · go | ethersolve | evm-cfg | sevm | heimdall-rs | evm-cfg-builder | |
| Basic Blocks | 92.8% 🥇 483212 | 52.5% 273518 | 58.6% 305248 | 37.3% 194368 | 32.6% 169980 | 14.5% 75383 |
| False Negatives | 7.2% 🥇 37496 | 47.5% 247190 | 41.4% 215460 | 62.7% 326340 | 67.4% 350728 | 85.5% 445325 |
| Time | 14s · 26s · 12s · 55s | 888s | 36s | 9.8s | 20s | 359s |
dataset flow-challenge500, 500 contracts, 520,708 blocks
See benchmark/README.md for the methodology and commands to reproduce these results
versions: evmole v0.9.3; whatsabi v0.25.0; sevm v0.7.4; evm-hound-rs v0.1.4; heimdall-rs v0.9.3
(*): sevm and heimdall-rs are full decompilers, not limited to extracting function selectors
EVMole uses symbolic execution with a custom EVM implementation to trace how CALLDATA flows through the bytecode:
This approach is more accurate than static pattern matching because it follows the actual execution paths the EVM would take, correctly handling complex dispatchers, proxy patterns, and compiler-specific optimizations from both Solidity and Vyper.
MIT