High-throughput CUDA implementation of Ethereum Virtual Machine, designed for smart contract fuzzing, transaction simulation, and beyond.
- β‘ 8M+ TPS ERC20 transfers (no state conflicts) on RTX 5000 Ada
- π§ͺ 1M+ fuzzing TPS for end-to-end smart contract fuzzing with medusa-cuevm
- π Fuzzing integration: medusa-cuevm, built on top of Crytic's Medusa v1.2.1
- β
96%+ traces indentical to
go-ethereum(on eth-tests Shanghai) - π³ Fully reproducible Docker container
- medusa-cuevm built based on Crytic's Medusa
- go-evmlab forked from holiman/goevmlab
A fully reproducible environment is available via Docker:
π minhhn2910/CuEVM-container
This builds the standalone executable binary cuevm_GPU (with EIP3155 disabled - for performance testing) inside the build folder:
# From the project root folder
rm -rf build
cmake -DBUILD_GO_LIBRARY=OFF -DENABLE_EIP_3155=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCUDA_COMPUTE_CAPABILITY=86 -S . -B build
cmake --build build -j $(nproc)This builds the standalone executable binary cuevm_GPU (with EIP3155 enabled - for correctness testing) inside the build folder:
# From the project root folder
rm -rf build
cmake -DBUILD_GO_LIBRARY=OFF -DENABLE_EIP_3155=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCUDA_COMPUTE_CAPABILITY=86 -S . -B build
cmake --build build -j $(nproc)This builds the dynamic library libcuevm_go.so inside the build folder:
# From the project root folder
rm -rf build
cmake -DBUILD_GO_LIBRARY=ON -DENABLE_EIP_3155=OFF -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCUDA_COMPUTE_CAPABILITY=86 -S . -B build
cmake --build build -j $(nproc)We provide sample docker file to build in Dockerfile. However, this build is only for standalone CuEVM without fuzzing use case. Please find the sample docker with benchmarking, fuzzing, and example usages at: minhhn2910/CuEVM-container.
docker pull minhhn2910/cuevm:latestPlease visit the repository for detailed instruction how to run fuzzing and benchmark.
The executor takes an input JSON file and outputs the result to standard output after execution. The input format follows the ethereum/tests format, with the minor difference that CuEVM currently supports only one test transaction in each test json.
./build/cuevm_GPU --input erc20_mint.jsonWe developed a python library in fuzzing/ to showcase interfacing with libcuevm_go.so for bug detection in solidity smart contracts.
For a performant and ready-to-use fuzzer, please refer to our in-house fuzzing tool built based on Medusa v1.2.1.
If your system has multiple GPUs, CuEVM can automatically distribute the workload (N transactions) evenly across all available GPUs for improved performance.
By default, CuEVM detects and utilizes all available GPUs without additional configuration. If you want to limit or specify which GPUs to use, set the CUDA_VISIBLE_DEVICES environment variable.
For example, to use only GPU 0 and GPU 2 on a system with 4 GPUs:
CUDA_VISIBLE_DEVICES=0,2 ./build/cuevm_GPU --input erc20_mint.jsonCUDA_VISIBLE_DEVICES=0,2 medusa fuzz --config medusa.json
We use goevmlab to compare execution traces between the ethereum/tests run on the go-ethereum VM executor and CuEVM.
- Install go-ethereum: https://github.com/ethereum/go-ethereum (Tested with geth version 1.14.13)
- Install goevmlab:
git clone --depth=1 -b add-cuevm https://github.com/cassc/goevmlab go install ./cmd/runtest/
- Clone ethereum/tests:
git clone --depth 1 -b shanghai git@github.com:ethereum/tests.git ethereum-tests
- Run all tests in
GeneralStateTestsand compare traces between go-ethereum and CuEVM. The test scriptscripts/run-ethtest-by-fork.pyexpands the input JSON file into multiple test cases, each containing a single transaction. The script then runs the test cases on both the go-ethereum and CuEVM executors, comparing the execution traces.python3 scripts/run-ethtest-by-fork.py --ignore-errors --microtests --without-state-root \ -i ethereum-tests/GeneralStateTests \ -t ./tmp --runtest-bin runtest \ --geth geth \ --cuevm ./build/cuevm_GPU
We use test files from ethereum/tests/GeneralStateTests to verify consistency with go-ethereum results. Test results were collected using a Python script:
python3 run-ethtest-without-stateroot-comparison.py --runtest-bin runtest --geth geth --cuevm ./build/cuevm_GPU --ignore-errors -t /tmp/ethtest/Note: A single input JSON file may contain multiple tests, so the number of tests shown below may exceed the number of input files. The tests passes means all lines are matched line-by-line in every intruction, except the final stateroot value (we skipped for simplicity). The following tests are ignored as they contain stress tests that largely result in timeout in printing log or crash the test script itself: [stQuadraticComplexityTest, stTimeConsuming, vmPerformance]
| Test Folder | Total Tests | Passed (%) |
|---|---|---|
| TOTAL | 14380 | 96.2% |
| VMTests | 628 | 100.0% |
π Click to view detailed results for all test folders
| Test Folder | Total Tests | Passed (%) |
|---|---|---|
| VMTests | 628 | 100.0% |
| stZeroKnowledge2 | 519 | 100.0% |
| stStackTests | 375 | 100.0% |
| stEIP150singleCodeGasPrices | 340 | 100.0% |
| stReturnDataTest | 273 | 100.0% |
| stArgsZeroOneBalance | 96 | 100.0% |
| stLogTests | 46 | 100.0% |
| stWalletTest | 46 | 100.0% |
| Shanghai | 27 | 100.0% |
| stRefundTest | 26 | 100.0% |
| stEIP150Specific | 25 | 100.0% |
| stNonZeroCallsTest | 24 | 100.0% |
| stZeroCallsTest | 24 | 100.0% |
| stInitCodeTest | 22 | 100.0% |
| stZeroCallsRevert | 16 | 100.0% |
| stEIP3607 | 12 | 100.0% |
| stMemExpandingEIP150Calls | 10 | 100.0% |
| stBugs | 9 | 100.0% |
| stCodeSizeLimit | 7 | 100.0% |
| stEIP158Specific | 7 | 100.0% |
| stTransitionTest | 6 | 100.0% |
| stHomesteadSpecific | 5 | 100.0% |
| stCodeCopyTest | 2 | 100.0% |
| stChainId | 2 | 100.0% |
| stSLoadTest | 1 | 100.0% |
| stEIP1559 | 1845 | 99.6% |
| stSStoreTest | 475 | 99.2% |
| stSelfBalance | 42 | 97.6% |
| stRandom | 314 | 97.1% |
| stBadOpcode | 4215 | 97.1% |
| stRevertTest | 271 | 97.0% |
| stTransactionTest | 164 | 97.0% |
| stRandom2 | 226 | 96.5% |
| stSolidityTest | 23 | 95.7% |
| stExtCodeHash | 65 | 95.4% |
| stShift | 42 | 95.2% |
| stExample | 39 | 94.9% |
| stPreCompiledContracts2 | 248 | 94.8% |
| stPreCompiledContracts | 960 | 93.4% |
| stZeroKnowledge | 800 | 93.1% |
| stMemoryTest | 578 | 91.9% |
| stCreateTest | 203 | 91.6% |
| stSystemOperationsTest | 83 | 91.6% |
| stMemoryStressTest | 82 | 91.5% |
| stCallCodes | 87 | 89.7% |
| stStaticCall | 478 | 88.9% |
| stCallDelegateCodesCallCodeHomestead | 58 | 87.9% |
| stCallDelegateCodesHomestead | 58 | 87.9% |
| stSpecialTest | 22 | 86.4% |
| stEIP2930 | 140 | 83.6% |
| stCreate2 | 190 | 82.1% |
| stCallCreateCallCodeTest | 55 | 80.0% |
| stDelegatecallTestHomestead | 31 | 74.2% |
| stStaticFlagEnabled | 34 | 73.5% |
| stRecursiveCreate | 2 | 50.0% |
| stAttackTest | 2 | 50.0% |
Summary Statistics:
- Total Tests Run: 14,380
- Passed: 13,833 (96.2%)
- Failed: 295 ; Timeout: 252 ; Skipped: 37
We welcome all valuable contributions from the community. We also acknowledge the early contributors to this project:
- Nhut-Minh Ho β National University of Singapore (Maintainer)
- Stefan-Dan Ciocirlan β University Politehnica of Bucharest
- Chen Li
- Ta Quang Trung β National University of Singapore
- Prof. Xiao Xiaokui β National University of Singapore (SBIP lead)
- Prof. Ooi Beng Chin β National University of Singapore and Zhejiang University (SBIP lead)
- Prof. Anh Dinh β Deakin University
- Fredrik Svantes β Ethereum Foundation
We acknowledge contributions and support from colleagues at the Singapore Blockchain Innovation Programme (SBIP). This project is funded by the Ethereum Foundation.
An auto generated source code documentation is available at https://sbip-sg.github.io/CuEVM/files.html
This repository is the original home of CuEVM. Active development will continue on the maintainer's fork: https://github.com/minhhn2910/CuEVM, with occasional syncs back to this repository when possible.