Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cdump/evmole
Extracts function selectors, arguments, state mutability and storage layout from EVM bytecode, even for unverified contracts
https://github.com/cdump/evmole
bytecode ethereum evm solidity web3
Last synced: about 15 hours ago
JSON representation
Extracts function selectors, arguments, state mutability and storage layout from EVM bytecode, even for unverified contracts
- Host: GitHub
- URL: https://github.com/cdump/evmole
- Owner: cdump
- License: mit
- Created: 2023-11-25T07:50:16.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2024-12-31T09:28:29.000Z (11 days ago)
- Last Synced: 2025-01-03T18:03:36.152Z (8 days ago)
- Topics: bytecode, ethereum, evm, solidity, web3
- Language: Rust
- Homepage: https://evmole.xyz
- Size: 741 KB
- Stars: 299
- Watchers: 3
- Forks: 20
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-web3 - EVMole - Extracts function selectors from EVM bytecode, even for unverified contracts. (Software Development / Risk Management)
- On-Chain-Investigations-Tools-List - EVMole
README
# EVMole
[![try it online](https://img.shields.io/badge/Try_It_Online-evmole.xyz-brightgreen)](https://evmole.xyz/)
[![npm](https://img.shields.io/npm/v/evmole)](https://www.npmjs.com/package/evmole)
[![Crates.io](https://img.shields.io/crates/v/evmole?color=e9b44f)](https://crates.io/crates/evmole)
[![PyPI](https://img.shields.io/pypi/v/evmole?color=006dad)](https://pypi.org/project/evmole)EVMole is a powerful library that extracts information from Ethereum Virtual Machine (EVM) bytecode, including [function selectors](https://docs.soliditylang.org/en/latest/abi-spec.html#function-selector), arguments, [state mutability](https://docs.soliditylang.org/en/latest/contracts.html#state-mutability), and storage layout, even for unverified contracts.
## Key Features
- Multi-language support: Available as [JavaScript](#javascript), [Rust](#rust), and [Python](#python) libraries.
- High accuracy and performance: [Outperforms](#benchmark) existing tools.
- Broad compatibility: Tested with both Solidity and Vyper compiled contracts.
- Lightweight: Clean codebase with minimal external dependencies.
- Unverified contract analysis: Extracts information even from unverified bytecode.## Usage
### JavaScript
[API documentation](./javascript/#api) and [usage examples](./javascript#usage) (node, vite, webpack, parcel, esbuild)
```sh
$ npm i evmole
```
```javascript
import { contractInfo } from 'evmole'const code = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'
console.log( contractInfo(code, {selectors:true, arguments:true, stateMutability:true}) )
// {
// functions: [
// {
// selector: '2125b65b',
// bytecodeOffset: 52,
// arguments: 'uint32,address,uint224',
// stateMutability: 'pure'
// },
// ...
```### Rust
Documentation is available on [docs.rs](https://docs.rs/evmole/latest/evmole/)
```rust
let code = hex::decode("6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256").unwrap();println!("{:?}", evmole::contract_info(
evmole::ContractInfoArgs::new(&code)
.with_selectors()
.with_arguments()
.with_state_mutability()
)
);
// Contract {
// functions: Some([
// Function {
// selector: [33, 37, 182, 91],
// bytecode_offset: 52,
// arguments: Some([Uint(32), Address, Uint(224)]),
// state_mutability: Some(Pure)
// },
// ...
```### Python
[API documentation](./python/#api)
```sh
$ pip install evmole --upgrade
```
```python
from evmole import contract_infocode = '0x6080604052348015600e575f80fd5b50600436106030575f3560e01c80632125b65b146034578063b69ef8a8146044575b5f80fd5b6044603f3660046046565b505050565b005b5f805f606084860312156057575f80fd5b833563ffffffff811681146069575f80fd5b925060208401356001600160a01b03811681146083575f80fd5b915060408401356001600160e01b0381168114609d575f80fd5b80915050925092509256'
print( contract_info(code, selectors=True, arguments=True, state_mutability=True) )
# Contract(
# functions=[
# Function(
# selector=2125b65b,
# bytecode_offset=52,
# arguments=uint32,address,uint224,
# state_mutability=pure),
# ...
```### Foundry
Foundy's cast uses the Rust implementation of EVMole
```sh$ cast selectors $(cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)
0x06fdde03 view
0x095ea7b3 address,uint256 nonpayable
0x18160ddd view
0x23b872dd address,address,uint256 nonpayable
...$ cast selectors --resolve $(cast code 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)
0x06fdde03 view name()
0x095ea7b3 address,uint256 nonpayable approve(address,uint256)
0x18160ddd view totalSupply()
0x23b872dd address,address,uint256 nonpayable transferFrom(address,address,uint256)
...
```## Benchmark
### function selectors
FP/FN - [False Positive/False Negative](https://en.wikipedia.org/wiki/False_positives_and_false_negatives) errors; smaller is better
Dataset
evmole rs · js · py
whatsabi
sevm
evmhound
heimdall
smpl
largest1k
1000
addresses
24427
functions
FP addrs
1 🥈
0 🥇
0 🥇
75
18
95
FN addrs
0 🥇
0 🥇
0 🥇
40
111
9
FP funcs
192 🥈
0 🥇
0 🥇
720
600
749
FN funcs
0 🥇
0 🥇
0 🥇
191
147
12
Time
0.4s · 0.6s · 0.4s
2.8s
35s(*)
0.4s
343s(*)
1.6s
random50k
50000
addresses
1171102
functions
FP addrs
1 🥇
43
1
693
3
4136
FN addrs
9 🥇
11
10
2903
4708
77
FP funcs
3 🥇
51
3
10798
29
14652
FN funcs
10 🥇
12
11
3538
6098
96
Time
4.3s · 9.0s · 7.2s
53s
1124s(*)
5.8s
8572s(*)
44s
vyper
780
addresses
21244
functions
FP addrs
0 🥇
30
0
19
0
185
FN addrs
0 🥇
780
0
300
780
480
FP funcs
0 🥇
30
0
19
0
197
FN funcs
0 🥇
21244
0
8273
21244
12971
Time
0.3s · 0.6s · 0.4s
2.0s
46s(*)
0.3s
28s(*)
1.0s
### function arguments
Errors - when at least 1 argument is incorrect: `(uint256,string)` ≠ `(uint256,bytes)`
Dataset
evmole rs · js · py
heimdall
smpl
largest1k
24427
functions
Errors
14.0% 🥇
3410
31.1%
7593
58.3%
14242
Time
1.0s · 2.1s · 1.1s
344s(*)
0.5s
random50k
1171102
functions
Errors
4.5% 🥇
52670
19.4%
227612
54.9%
643213
Time
20s · 49s · 24s
8517s(*)
8.1s
vyper
21244
functions
Errors
48.5% 🥇
10299
100.0%
21244
56.8%
12077
Time
0.7s · 1.4s · 0.8s
28s(*)
0.5s
### function state mutability
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
whatsabi
sevm
heimdall
smpl
largest1k
24427
functions
Errors
0.0% 🥇
0
68.1%
16623
2.1%
501
25.4%
6201
2.6%
643
Errors strict
18.6% 🥇
4555
79.4%
19393
59.0%
14417
54.9%
13403
60.9%
14864
Time
8.9s · 16s · 8.9s
3.8s
33s(*)
339s(*)
0.5s
random50k
1160861
functions
Errors
0.0% 🥇
44
30.2%
351060
0.3%
3370
11.6%
134196
2.2%
24961
Errors strict
6.8% 🥇
78923
58.2%
675111
55.7%
646831
27.7%
321495
57.7%
670318
Time
169s · 334s · 172s
88s
1131s(*)
8267s(*)
8.2s
vyper
21166
functions
Errors
0.5% 🥇
110
100.0%
21166
76.3%
16150
100.0%
21166
1.8%
390
Errors strict
4.0% 🥇
854
100.0%
21166
90.2%
19092
100.0%
21166
59.6%
12610
Time
9.5s · 13s · 9.7s
2.1s
38s(*)
28s(*)
0.5s
See [benchmark/README.md](./benchmark/) for the methodology and commands to reproduce these results
versions: evmole v0.6.2; whatsabi v0.17.0; sevm v0.7.3; evm-hound-rs v0.1.4; heimdall-rs v0.8.4
(*): sevm and heimdall-rs are full decompilers, not limited to extracting function selectors
## How it works
Short: Executes code with a custom EVM and traces CALLDATA usage.
Long: TODO
## License
MIT