Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
97be245
Refactoring
merendamattia Feb 26, 2025
6b5b641
Refactored the analysis of a set of contracts
merendamattia Feb 27, 2025
b7999ac
Refactoring: integrated json, basic blocks, statistics, benchmark
merendamattia Feb 27, 2025
6ebeeaf
Refactoring: results saved to file
merendamattia Feb 27, 2025
2cfbf01
Refactoring: created .dot file manager
merendamattia Feb 27, 2025
aa39f84
Added function selectors in cfg basic blocks and fixed colors
merendamattia Feb 28, 2025
e798fcf
Added legend to .dot file
merendamattia Feb 28, 2025
1dc7fff
Refactoring: removed old methods, updated readme
merendamattia Feb 28, 2025
e2e99b0
Added new example
merendamattia Feb 28, 2025
42cf22e
Merge from master branch
merendamattia Feb 28, 2025
3cf4203
Apply spotless
merendamattia Feb 28, 2025
e604ca3
Added output directory path option
merendamattia Feb 28, 2025
507a5dc
Refactored ground truth test
merendamattia Feb 28, 2025
7fcbefa
Added ground truth data for test
merendamattia Feb 28, 2025
1963b84
Minor changes
merendamattia Feb 28, 2025
34f9f4a
Added javadoc
merendamattia Feb 28, 2025
21b0c4a
Fixed bug in the computation of functions entry points
merendamattia Feb 28, 2025
aa43ece
Refactoring and added javadoc
merendamattia Mar 1, 2025
52c28d5
Added javadoc
merendamattia Mar 1, 2025
9c76803
Removed LiSA logs printing during analysis
merendamattia Mar 1, 2025
bf477f1
Fixed colors in the cfg dump
merendamattia Mar 1, 2025
53432ed
Removed debug prints in tests, renamed extension ABI to .abi
merendamattia Mar 2, 2025
c96e7c4
Updated readme
merendamattia Mar 2, 2025
6fe7436
Apply spotless
merendamattia Mar 2, 2025
ae76268
Removed comments
merendamattia Mar 2, 2025
6a38174
Added test mode in analysis
merendamattia Mar 3, 2025
ee16bb9
Optimized the creation of contracts in buildContractsFromFile(), intr…
merendamattia Mar 3, 2025
6261ad1
Fixed basic blocks generation, fixed bug in edges' color
merendamattia Mar 4, 2025
586fdfb
Added option that allows you to pass the etherscan api key instead of…
merendamattia Mar 4, 2025
0dcbaf6
Added event label in cfg with basic blocks
merendamattia Mar 4, 2025
81fc865
Updated legend in .dot, apply spotless
merendamattia Mar 4, 2025
8ad9e7a
Minor changes
merendamattia Mar 4, 2025
5b6507c
Error message as a json
merendamattia Mar 5, 2025
52dd5c3
Fixed bug in analysis with bytecode-path and abi-path options
merendamattia Mar 6, 2025
a60e042
Added web app mode, refactoring
merendamattia Mar 7, 2025
ef3683e
Removed webb app mode
merendamattia Mar 9, 2025
9fcd5da
Merge branch 'master' of github.com:lisa-analyzer/evm-lisa into refac…
merendamattia Mar 11, 2025
bfc740f
Restored LiSA prints in tests
merendamattia Mar 11, 2025
95c3ed4
Removed unused methods, rewritten error prints, added new checks in S…
merendamattia Mar 11, 2025
e7ed430
Removed useless configs from tests
merendamattia Mar 11, 2025
c8b3ab3
Single computation of AbstractStack's size
VincenzoArceri Mar 11, 2025
8a8342c
Optimized AbstractStack replaceing ArrayList with arrays
merendamattia Mar 11, 2025
c78b42e
Restored LiSA logs
VincenzoArceri Mar 11, 2025
04af8af
Fixing add semantics in Number
VincenzoArceri Mar 11, 2025
0c620e8
Removed glb, lub, and widening from AbstractStack
VincenzoArceri Mar 11, 2025
8105a4f
Optimized compareTo for Number
VincenzoArceri Mar 11, 2025
dd100e0
Removed old configuration from manager
VincenzoArceri Mar 11, 2025
a9e7ba4
Removed size field from abstract stack, clone's method for arrays rather
VincenzoArceri Mar 11, 2025
6cf2fa3
Optimized configuration manager for tests
merendamattia Mar 12, 2025
ea1dcff
Added table of contents
merendamattia Mar 12, 2025
46406e8
Added sanitizers in taint abstract domain, updated TimestampDependenc…
merendamattia Mar 13, 2025
fe23531
Avoiding useless clones in TaintAbstractDomain
VincenzoArceri Mar 15, 2025
b4456bc
Introduced popX method, removed useless clone in EVM abstract state
VincenzoArceri Mar 15, 2025
4d18083
Removed tests
merendamattia Mar 16, 2025
80e0ccd
Refactored stack structure from linear array to circular array + upda…
shivamkumar2402 Mar 16, 2025
5dfee67
Apply spotless
shivamkumar2402 Mar 16, 2025
666b3ca
Merge pull request #47 from lisa-analyzer/sanitizers-taint-domain
VincenzoArceri Mar 17, 2025
f7a59bc
Merge remote-tracking branch 'origin/refactoring' into circ-array
shivamkumar2402 Mar 17, 2025
9c2e5d1
Added popX method + javadoc
shivamkumar2402 Mar 17, 2025
68dd9d1
Refactoring AbstractStack's equals
VincenzoArceri Mar 17, 2025
461a639
Added javadoc
shivamkumar2402 Mar 17, 2025
03e1ea8
Merge branch 'circ-array' of https://github.com/lisa-analyzer/evm-lis…
shivamkumar2402 Mar 17, 2025
5403bc5
Updating tests
VincenzoArceri Mar 17, 2025
dab6527
Added --abi option to EVMLiSA, added setAbi in SmartContract to handl…
merendamattia Mar 18, 2025
276447e
Added --abi option
merendamattia Mar 18, 2025
ff453f9
Apply spotless
merendamattia Mar 18, 2025
b0dd436
Removed jcenter repository (obsolete and deprecated), updated shadowJ…
merendamattia Mar 19, 2025
f3cd70d
Refactored stack structure from ArrayList to circular array
shivamkumar2402 Mar 20, 2025
7a9d589
Removed emptiness check in small-step semantics of TaintAbstractDomain
VincenzoArceri Mar 20, 2025
c528f25
Changed equals for taint abstract domain
VincenzoArceri Mar 20, 2025
256a10f
Added popX method and fix clone + javadoc
shivamkumar2402 Mar 20, 2025
383d13b
Apply spotless
shivamkumar2402 Mar 20, 2025
40a6dd0
Introducing popX in taint abstract domain's small-step semantics
VincenzoArceri Mar 20, 2025
cb0ba93
Checked last TODO + spotless apply
shivamkumar2402 Mar 20, 2025
f6e9b9d
Minor changes
VincenzoArceri Mar 21, 2025
084b8cb
Merge pull request #48 from lisa-analyzer/circ-array
merendamattia Mar 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,16 @@
# Ignore output directories that contain generated results
evm-outputs/
test-ground-truth-stats/
evm-testcases/ground-truth/test-ground-truth-results/logs.txt
evm-testcases/ground-truth/test-ground-truth-results/statistics.csv
evm-testcases/ground-truth/test/*

# Ignore 50-ground-truth file
evm-testcases/ground-truth/50-ground-truth/**/*.html
evm-testcases/ground-truth/50-ground-truth/**/*.opcode
evm-testcases/ground-truth/50-ground-truth/**/*.json
evm-testcases/ground-truth/50-ground-truth/**/*.dot
evm-testcases/ground-truth/50-ground-truth/**/*.js


# Ignore benchmark file
scripts/python/benchmark-checkers/**/bytecode/**
scripts/python/benchmark-checkers/**/abi/**
Expand Down
212 changes: 129 additions & 83 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,96 +12,132 @@ EVMLiSA is a static analyzer based on abstract interpretation for [EVM bytecode]
EVMLiSA is based on the peer-reviewed publication
> Vincenzo Arceri, Saverio Mattia Merenda, Greta Dolcetti, Luca Negrini, Luca Olivieri, Enea Zaffanella. _**"Towards a Sound Construction of EVM Bytecode Control-Flow Graphs"**_. In Proceedings of the 26th ACM International Workshop on Formal Techniques for Java-like Programs (FTfJP 2024), co-located with ECOOP 2024.

# 🛠 Building EVMLiSA
Compiling EVMLiSA requires:
- JDK >= 11 (optional using Docker)
- [Gradle](https://gradle.org/releases/) >= 8.0 (optional using Docker)
## Table of Contents

- [Requirements](#requirements)
- [Installation](#installation)
- [Environment Setup](#environment-setup)
- [Execution Methods](#execution-methods)
- [Using Docker](#using-docker)
- [Using CLI](#using-command-line)
- [Options](#options)
- [The Abstract Stack Set Domain](#the-abstract-stack-set-domain)
- [Jump Classification](#jump-classification)
- [Usage Example](#usage-example)
- [Example Output](#example-output)
- [EVMLiSA as a Library](#EVMLiSA-as-a-library)

---

## Requirements

To build and run EVMLiSA, you will need:

- JDK 11 or higher (optional when using Docker)
- [Gradle](https://gradle.org/releases/) 8.0 or higher (optional when using Docker)
- [Etherscan API key](https://etherscan.io/myapikey)

You need to:
- Clone the repository:
```bash
git clone https://github.com/lisa-analyzer/evm-lisa.git
cd evm-lisa
```
- Import the project into the Eclipse/IntelliJ workspace as a Gradle project (optional).
## Installation

# ⚙️ Running EVMLiSA
Before running EVMLiSA, ensure you have set up an Environment Variable with your Etherscan API Key. Follow the steps below to set up the environment variable:
1. Clone the repository:
```bash
git clone https://github.com/lisa-analyzer/evm-lisa.git
cd evm-lisa
```

1. Begin by creating a file named `.env` in the EVMLiSA project.
2. Inside the `.env` file, add the following line:
```
ETHERSCAN_API_KEY=<your_etherscan_api_key>
```
3. Replace `<your_etherscan_api_key>` with your Etherscan API key.
2. (Optional) Import the project into Eclipse or IntelliJ as a Gradle project.

> Here you can find how to generate an [Etherscan API key](https://etherscan.io/myapikey).
### Environment Setup

Once you have set up the environment variable, you can run EVMLiSA via Docker or via Bash.
Before running EVMLiSA, you must configure your Etherscan API key:

## Via Docker
Build the container:
```
mkdir -p execution/docker &&
docker build -t evm-lisa:latest .
```
1. Create a `.env` file in the project root directory.
2. Add the following line to the file:
```
ETHERSCAN_API_KEY=<your_etherscan_api_key>
```
3. Replace `<your_etherscan_api_key>` with your actual key from [Etherscan](https://etherscan.io/myapikey).

Then you can run EVMLiSA with:
```
docker run --rm -it \
-v $(pwd)/.env:/app/.env \
-v $(pwd)/execution/docker:/app/execution/results \
evm-lisa:latest \
[options]
```
Alternatively, you can pass your API key directly using the `--etherscan-api-key <key>` option when executing the analyzer.

- `-v $(pwd)/.env:/app/.env`: mount the `.env` file.
- `-v $(pwd)/execution/docker:/app/execution/results`: share the results' folder.
## Execution Methods

## Via Bash
Build the Project:
```bash
./gradlew assemble
```
### Using Docker

Then you can run EVMLiSA with:
```bash
java -jar build/libs/evm-lisa-all.jar [options]
```
1. Build the Docker container:
```bash
mkdir -p execution/docker &&
docker build -t evm-lisa:latest .
```

2. Run EVMLiSA with Docker:
```bash
docker run --rm -it \
-v $(pwd)/.env:/app/.env \
-v $(pwd)/execution/docker:/app/execution/results \
evm-lisa:latest \
[options]
```

- `-v $(pwd)/.env:/app/.env`: Mounts your environment file
- `-v $(pwd)/execution/docker:/app/execution/results`: Shares the results directory

### Using Command Line

1. Build the project:
```bash
./gradlew assemble
```

2. Run EVMLiSA:
```bash
java -jar build/libs/evm-lisa-all.jar [options]
```

## Options

```
Options:
-a,--address <arg> Address of an Ethereum smart contract.
-b,--benchmark <arg> Filepath of the benchmark.
--basic-blocks Generate CFG with basic blocks.
-c,--cores <arg> Number of cores used in benchmark.
--checker-reentrancy Enable re-entrancy checker.
--checker-timestampdependency Enable timestamp-dependency checker.
--checker-txorigin Enable tx-origin checker.
--dot Export a dot-notation file.
--download-bytecode Download the bytecode.
--dump-report Dump analysis report.
--dump-stats Dump statistics.
-f,--filepath-bytecode <arg> Filepath of the bytecode file.
--html Export a graphic HTML report.
--link-unsound-jumps-to-all-jumpdest Link all the unsound jumps to all jumpdest.
-o,--output <arg> Output directory path.
--serialize-inputs Serialize inputs.
--stack-set-size <arg> Dimension of stack-set (default: 8).
--stack-size <arg> Dimension of stack (default: 32).
--use-live-storage Use the live storage in SLOAD.
-a,--address <arg> Address of an Ethereum smart contract
--abi <arg> ABI of the bytecode to be analyzed (JSON format).
--abi-path <arg> Filepath of the ABI file
-b,--bytecode <arg> Bytecode to be analyzed (e.g., 0x6080...)
--benchmark <arg> Filepath of the benchmark
--bytecode-path <arg> Filepath of the bytecode file
-c,--cores <arg> Number of cores used in benchmark
--checker-all Enable all security checkers
--checker-reentrancy Enable reentrancy checker
--checker-timestampdependency Enable timestamp-dependency checker
--checker-txorigin Enable tx-origin checker
--etherscan-api-key <arg> Insert your Etherscan API key
--link-unsound-jumps-to-all-jumpdest Link all unsound jumps to all jumpdest
--output-directory-path <arg> Filepath of the output directory
--stack-set-size <arg> Dimension of stack-set (default: 8)
--stack-size <arg> Dimension of stack (default: 32)
--use-live-storage Use the live storage in SLOAD
```

# 🔍 Abstract Stack Set Domain
In the analysis of EVM bytecode programs, EVMLiSA employs a domain of sets of abstract stacks to enhance precision, particularly when loops are encountered in the source code.
## The Abstract Stack Set Domain

In analyzing EVM bytecode programs, EVMLiSA employs a domain of sets of abstract stacks to enhance precision, particularly for code containing loops.

The analyzer introduces the abstract stack powerset domain $\texttt{SetSt}_{k,h,l}$ consisting of sets of abstract stacks with at most $l$ elements and a maximum height of $h$. This domain allows the analyzer to maintain collections of abstract stacks, avoiding the need to compute the least upper bound (lub) and allowing each element of an abstract stack to be a $k$ integer set.

## Jump Classification

EVMLiSA classifies jump instructions in the following categories:

- **Resolved**: All destinations of the jump node have been successfully resolved
- **Definitely unreachable**: The jump node is unreachable (reached with the bottom abstract state)
- **Maybe unreachable**: The jump node is not reachable from the entry point, but may be reachable via a potentially unsound jump node
- **Unsound**: The jump node is reached with a stack containing an unknown numerical value that may correspond to a valid jump destination
- **Maybe unsound**: The stack set exceeded the maximum configured stack size

EVMLiSA introduces the abstract stack powerset domain $\texttt{SetSt}_{k,h,l}$ which consists of sets of abstract stacks with at most $l$ elements and an height of at most $h$. This domain allows the analyzer to maintain collections of abstract stacks, avoiding the need to compute the lub and allowing each element of an abstract stack to be a $k$ integer set.
## Usage Example

# 📋 Running example
Here is an example of how to run EVMLiSA. In this example, we will analyze a smart contract at the address `0x7c21C4Bbd63D05Fa9F788e38d14e18FC52E9557B` with specific options for stack size, stack-set size, live storage usage and the dump of the CFG:
Analyze a smart contract with specific configuration parameters:

- Bash:
**Using Command Line:**
```bash
java -jar build/libs/evm-lisa-all.jar \
-a 0x7c21C4Bbd63D05Fa9F788e38d14e18FC52E9557B \
Expand All @@ -110,7 +146,7 @@ java -jar build/libs/evm-lisa-all.jar \
--link-unsound-jumps-to-all-jumpdest
```

- Docker:
**Using Docker:**
```bash
docker run --rm -it \
-v $(pwd)/.env:/app/.env \
Expand All @@ -122,10 +158,11 @@ evm-lisa:latest \
--link-unsound-jumps-to-all-jumpdest
```

> Use `docker run -a stderr` to dump only the json report as standard output.
> **Tip**: Use `docker run -a stderr` to output only the JSON report to standard output.

The expected output is as follows:
```yaml
### Example Output

```
##############
Total opcodes: 344
Total jumps: 45
Expand All @@ -137,17 +174,26 @@ Maybe unsound jumps: 0
##############
```

### Jump classification
- _Resolved_: all the destinations of the jump node have been resolved;
- _Definitely unreachable_: the jump node is unreachable (i.e., it is reached with the bottom abstract state);
- _Maybe unreachable_: the jump node is not reachable in the CFG, starting from its entry point, but it may be reachable via a (maybe) unsound jump node (if any);
- _Unsound_: the jump node is reached at least with a stack with an unknown numerical value that may correspond to a
valid jump destination as the top element;
- _Maybe unsound_: the stack set exceeded the maximal stack size.
## EVMLiSA as a Library

---
EVMLiSA can be integrated as a Java library to analyze EVM smart contracts programmatically:

```java
// Analyze by contract address
EVMLiSA.analyzeContract(new SmartContract("0x123456..."));

// Analyze from bytecode file path
EVMLiSA.analyzeContract(new SmartContract(Path.of("bytecode", "code.bytecode")));

// Analyze from bytecode string
EVMLiSA.analyzeContract(new SmartContract().setBytecode("0x6080..."));

// Analyze multiple contracts
EVMLiSA.analyzeSetOfContracts(Path.of("list-of-contracts.txt"));
```

## Contributors

<a href="https://github.com/lisa-analyzer/evm-lisa/graphs/contributors">
<img src="https://contrib.rocks/image?repo=lisa-analyzer/evm-lisa" />
</a>
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ plugins {
repositories {
// Use jcenter for resolving dependencies.
// You can declare any Maven/Ivy/file repository here.
jcenter()
mavenCentral()
}

Expand All @@ -43,6 +42,8 @@ dependencies {
implementation 'io.github.cdimascio:dotenv-java:3.0.0'

implementation 'org.json:json:20210307'

implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
}


Expand Down Expand Up @@ -147,7 +148,7 @@ tasks.register('checkCodeStyle') {
}

tasks.named('shadowJar') {
archiveBaseName = 'evm-lisa'
archiveBaseName.set('evm-lisa')
manifest {
attributes(
'Main-Class': mainClassName
Expand Down
6 changes: 3 additions & 3 deletions evm-testcases/cfs/while/report.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
"files" : [ "report.json", "untyped_program.evm-testcases_cfs_while_while_eth.sol().json" ],
"info" : {
"cfgs" : "1",
"duration" : "23ms",
"end" : "2025-02-26T11:44:06.360+01:00",
"duration" : "281ms",
"end" : "2025-03-17T15:38:36.216+01:00",
"expressions" : "6",
"files" : "1",
"globals" : "0",
"members" : "1",
"programs" : "1",
"start" : "2025-02-26T11:44:06.337+01:00",
"start" : "2025-03-17T15:38:35.935+01:00",
"statements" : "16",
"units" : "0",
"version" : "0.1",
Expand Down
Loading