Conceptio › Archive › arXiv CS
arXiv CS open access

CuEVM: Scaling Smart Contract Execution on GPUs

Nhut-Minh Ho et al. · arxiv_cs
arXiv CS · Papers
Open Source ↗Direct PDF ↓
clouddistributed-computingparallel-computing
Smart contracts on Ethereum blockchain process transactions worth billions of US dollars daily. They run on top of Ethereum Virtual Machine (EVM) which executes transactions sequentially. This execution model creates a performance bottleneck, especially for new blockchain workloads with large number
Conceptio Open Archive

Analyze & explore related research in Conceptio

Connect this record directly into your research workflow or AI agent. Explore citations across open repositories, query full text, and export structured proof bundles.

CuEVM: Scaling Smart Contract Execution on GPUs Nhut-Minh Ho1 , Tien Tuan Anh Dinh2 , Quang Trung Ta1 , Fredrik Svantes3 , Xiaokui Xiao1 , Beng Chin Ooi4

arXiv:2611.14916v1 [cs.DC] 11 Nov 2026

1

National University of Singapore, Singapore 2 Deakin University, Australia 3 Ethereum Foundation, Switzerland 4 Zhejiang University, China minhhn@comp.nus.edu.sg, anh.dinh@deakin.edu.au, taqt@nus.edu.sg, fredrik@ethereum.org, xkxiao@nus.edu.sg, ooibc@zju.edu.cn

Abstract—Smart contracts on Ethereum blockchain process transactions worth billions of US dollars daily. They run on top of Ethereum Virtual Machine (EVM) which executes transactions sequentially. This execution model creates a performance bottleneck, especially for new blockchain workloads with large numbers of transactions, such as security testing. We present CuEVM, a GPU-native and semantically complete EVM execution engine that treats transaction execution as a massively parallel dataprocessing problem. It employs novel data structures and GPUaware scheduling to accelerate execution. Unlike prior works that transpile the contract and rely on a host CPU for many operations, CuEVM supports complete EVM semantics natively on the GPU. It passes 100% of the Ethereum VMTests and 96.2% of the full execution-test suite. On a single commodity GPU, CuEVM executes over 8 million ERC-20 transfers per second, outperforming existing baselines by up to two orders of magnitude. We build a smart contract fuzzer, called CuEVMfuzz, on top of CuEVM. The fuzzer achieves over a million end-to-end executions per second, up to 23× and 4.8× higher than the state-of-the-art CPU-based and GPU-based baselines, respectively.

I. I NTRODUCTION Smart contracts enable complex blockchain applications that process high-value transactions. For example, decentralized finance (DeFi) applications on Ethereum have over 150 billion USD in total locked value [1]. The Ethereum Virtual Machine (EVM) executes transactions sequentially, even when the transactions are independent, creating a throughput bottleneck [2]. This bottleneck is critical for new blockchain applications that process a large number of transactions, and most of the transactions are independent and can be executed in parallel. Examples of such applications include transaction simulation [3], [4] and coverage-guided fuzzing [5], [6]. Our goal is to design an EVM engine that executes parallel transactions over thousands of GPU threads. There are two challenges in realizing our goal. The first is supporting complete EVM semantics under a massively parallel execution model. A recent work on GPU-based EVM execution, namely MAU [5], transpiles smart contract bytecode to PTX assembly to emulate execution. But it supports only a subset of the EVM semantics [2], omitting critical features such as external calls, precompiled contracts, contract creation, and rollbacks. It also restricts the world state to a single contract without crosscontract interactions. MAU fails more than 80% of the official Ethereum tests and must fall back to a host CPU reference

EVM, which reintroduces the sequential execution. The second challenge is reducing memory access latency and CPU-GPU communication overhead. In particular, memory access is sensitive to data layout [7]. Thus, EVM states and auxiliary data structures must be carefully designed to avoid overhead. MAU, for example, uses separate data buffers to track fuzzing code coverage for different GPU threads, therefore incurring high overhead. We present CuEVM, a semantically complete EVM engine for conflict-free workloads that runs natively on GPUs. CuEVM addresses the first challenge by executing EVM bytecode following the yellow paper [2]. It is compatible with existing EVM implementations, and passes 100% of the Ethereum VMTests and 96.2% of the full execution-test suite. CuEVM addresses the second challenge by adopting a columnar layout for the EVM states, batching tens of thousands of transactions per kernel, and using a GPU-aware transaction scheduler. Using CuEVM for our primary use case, we build CuEVMfuzz, the first GPU-native fuzzer that migrates the entire fuzzing loop to GPUs. Our evaluation shows that CuEVM-fuzz can perform up to 1.1 million end-to-end fuzzing executions per second on an Nvidia RTX 5000 Ada. It detects existing CVEs 300× faster than a state-of-the-art fuzzer (Smartian). On 500 large smart contracts collected from Etherscan [8], it identifies 1.75× more integer overflow bugs and 2× more leaking ether bugs than Smartian, and 1.67× more reentrancy bugs than ItyFuzz. In real-world testing on 20,000 popular contracts on Ethereum and Binance Smart Chain, CuEVMfuzz detects 115 projects with high-risk bugs. In summary, we make the following contributions: • We introduce CuEVM, the first GPU-native EVM that is fully adhering to the EVM specification [2]. It passes all the core functionality tests in the official Ethereum test suite. The code is available at https://github.com/sbip-sg/ CuEVM. • We present a novel design that incorporates columnar-style memory layout and GPU-aware transaction scheduling that minimizes GPU-related overheads. Our microbenchmarks show that CuEVM can execute up to 8.3 million independent ERC-20 transfers per second. • We introduce CuEVM-fuzz that leverages CuEVM for smart contract fuzzing. CuEVM-fuzz performs up to 1.1

© 2026 IEEE. Personal use of this material is permitted. Permission from IEEE must be obtained for all other uses, in any current or future media, including reprinting/republishing this material for advertising or promotional purposes, creating new collective works, for resale or redistribution to servers or lists, or reuse of any copyrighted component of this work in other works.

million end-to-end fuzzing executions per second. It detects new high-risk bugs in 115 recent real-world contracts. • We discuss another use case of CuEVM, namely attack imitation [9], in which CuEVM enables efficient search for rescue transactions upon detection of on-chain security incidents. The next section presents relevant background. Section III describes the motivating example, followed by the overview of CuEVM in Section IV. Section V provides the design and implementation of CuEVM. Section VI discusses the design of CuEVM-fuzz. Section VII presents the experimental results. Section VIII discusses the related works before Section IX concludes. II. BACKGROUND A. Blockchain and Smart Contract A blockchain is a replicated, append-only, and tamperevident ledger maintained by a set of mutually distrustful nodes that agree on its contents through a consensus protocol [10], [11]. From a data-management standpoint, blockchains share notable similarities with, but also key differences from, distributed databases [12], a dichotomy that has motivated hybrid blockchain-database systems [13]. A common abstraction decomposes a blockchain into four layers: application, execution engine, data, and consensus for performance benchmarking [14]. CuEVM speeds the execution layer up by harnessing the parallel processing power of GPUs. Applications are enabled through smart contracts, and Ethereum is the most popular blockchain supporting smart contracts. All nodes in Ethereum agree on a world state σ — the states of all accounts in the blockchain. The world state is a mapping between account address a and its state. For each 160-bit address a, the account state σ[a] consists of four components: σ[a] = ⟨nonce, balance, code, storage⟩

(1)

where code and storage are for smart contract accounts. A user interacts with Ethereum by submitting a transaction T , which updates the current world state σ to σ ′ via σ ′ = Υ(σ, T ), where Υ is the state transition function that executes T . Each transaction T has various fields and is signed by the sender with five key fields relevant to transaction execution as below: T = ⟨sender, receiver, data, value, gasLimit, . . .⟩ (2) When T ’s receiver is a smart contract address, the EVM passes T ’s data, which contains the encoded high-level function and arguments following Application Binary Interface (ABI) encoding [15]. The value encodes the transaction value in Ethereum while the gasLimit determines the upper bound on execution complexity. The EVM executes the contract’s bytecode to perform state transition logic in Υ following EVM semantics [2]. The execution may involve multiple accounts and multiple smart contract calls. Once it completes successfully, the state changes are materialized to a new world state σ ′ .

Smart contracts are written in higher-level languages such as Solidity before being compiled to bytecode and deployed on the blockchain. They are susceptible to bugs and deployment errors that may lead to catastrophic financial loss. B. Ethereum Virtual Machine Ethereum Virtual Machine (EVM) is the engine that executes smart contracts on Ethereum and on other EVMcompatible blockchains, such as Polygon and Binance Smart Chain. The EVM is a stack-based virtual machine with a word size of 256 bits. It executes instructions represented as opcodes, embedded in the bytecode and indexed by a program counter (pc). Each transaction T instantiates an EVM instance to apply the state transition function Υ to the world state σ. The EVM first launches an initial contract call to execute the target contract bytecode. This initial call may spawn a number of sub-calls, depending on the contract logic and the runtime state. Each call maintains a separate call context (C) that captures the runtime state of the EVM. We represent C as: C = ⟨env, bytecode, data, value | stack, memory, σ, pc, gas⟩ {z } | {z } | static

dynamic

(3) where the components are defined as follows: • Static state (immutable during C execution): environment env, smart contract bytecode, call data, call value • Dynamic state (mutable during C execution): stack, memory, world state σ, program counter pc, remaining gas The environment env of each call includes the call depth, the sender, receiver, the state address, call gas limit, transaction origin, and blockchain-related states such as block number, block time, etc. The sender and receiver of each sub-call may differ from the transaction’s originator (tx.origin) and the original target contract. The state address is required for special opcodes such as delegatecall or callcode where the receiver of the call differs from the contract owning the code or the storage. This execution model maps directly onto database transaction processing: the shared world state σ is the persistent data, and the contract logic together with the EVM internals defines the state transition that each transaction applies. The EVM executes transactions sequentially, each mutating σ to a new version, and a group of transactions forms a block that is finalized by the consensus layer. C. GPU-Accelerated Smart Contract Execution 1) GPUs: Parallel computing has evolved from multithreaded to massively parallel models on special hardware like GPUs [16]. A GPU program is called a kernel (written in CUDA for Nvidia GPUs [17]), which can run thousands of lightweight threads in parallel. The threads are grouped into blocks, each containing warps of 32 threads. These warps are the instruction execution units, which are scheduled to the streaming multiprocessors on the GPU. The whole warp

can only execute one instruction at a time. When threads in the warp wait for each other’s diverged instructions, thread divergence incurs additional overhead. Each thread has its own registers for local variables, while all threads within a block share a small but faster shared memory. All threads in the kernel can access a slower global memory, which is gigabytes in size. Thread memory access patterns and execution path are important factors that affect GPU program performance. 2) Smart contract execution on GPUs: To the best of our knowledge, there is no existing general-purpose EVM execution engine on GPUs. For a specialized engine serving a specific purpose of fuzzing smart contracts, MAU [5] introduces a GPU-accelerated fuzzer with a smart contract emulator running on GPUs. It transpiles EVM bytecode to PTX assembly to simulate execution on GPUs and utilizes Ityfuzz [6] on the CPU side to complete each fuzzing loop. From the execution-engine perspective, MAU suffers from two drawbacks: incomplete semantics and low GPU utilization. We postulate that a semantically complete EVM is necessary not only for fuzzing use cases as in MAU but also for general parallel workload where correctness is as important as speed. III. M OTIVATION We observe that there are emerging blockchain applications that process a large number of transactions, and most of the transactions can be executed in parallel. One example is parallel clients that re-execute blocks to validate optimistic schedules [18], [19]. Another example involves executing synthetic transactions to find vulnerabilities [5], to build anomaly detection models [4], or to find rescue transactions [9]. These applications are currently limited by the EVM because the latter executes transactions sequentially. A. Smart Contract Fuzzing Smart contracts process transactions worth billions of dollars. Thus, implementation bugs or security vulnerabilities can lead to catastrophic financial loss [20]. Fuzzing is a widely adopted technique to find bugs and vulnerabilities in smart contracts, inspired by the success of fuzzers in traditional software testing [21] and database systems [22]. A (greybox) fuzzer executes a large number of transactions. It reads feedback from each execution to decide which transactions are interesting and to generate new transactions [23]–[25]. Listing 1 shows an example from the Ronin Bridge contract, where the bug is an unauthorized withdrawal that becomes reachable after calling initializeV4(). To trigger this bug, the fuzzer must drive the contract execution into this state and then issue submitWithdrawal(·) with the corresponding call data. Because the space of callable functions, their arguments, and their orderings is large, the fuzzer mutates transactions to make progress under the guidance of a feedback metric, for example, code coverage. In summary, fuzzing requires executing a large number of candidate transactions, most of which are independent from each other, and the throughput of the engine determines how quickly bugs are found.

Listing 1: Simplified contract from the Ronin Bridge incident. contract MainchainGatewayV3 { // function initializeV3() // function initializeV4() function submitWithdrawal(Transfer.Receipt calldata _receipt, Signature[] calldata _signatures) external virtual whenNotPaused () { // other logic uint256 quantity = _receipt.info.quantity; address tokenAddr = _receipt.mainchain.tokenAddr ; if(_reachedWithdrawalLimit(tokenAddr,quantity)){ revert();} // withdrawal limit check. // flawed verification with _totalOperatorWeight = 0 // execute withdrawal quantity from tokenAddr } // ... other functions }

B. Other Use Cases In August 2024, the Ronin Bridge was exploited for over 12 million USD1 . The root cause was a recently upgraded contract with misconfigured state variables, allowing unauthorized withdrawals (Listing 1). The incident unfolded as follows: • Block 20468438: the contract was misconfigured. One block later (approximately 12 seconds), an exploit transaction with the value of 34 USD was recorded. • Block 20468679: an optimized transaction with the value of 10 million USD (3,996 ETH) was recorded approximately 49 minutes later. • Block 20468866: the bridge was paused to prevent further loss 38 minutes after the first major loss. The incident reveals that the attacker went through multiple exploits to extract the most value from the vulnerability. This gives a window for security researchers to respond to the incident. In particular, the researchers solve the following problem: given a vulnerability, find the exploit that extracts the most value. Such an exploit is called rescue transaction, as it can front-run the real exploits from the attacker to rescue the asset [9], [26], [27]. In the Ronin bridge example, the parameter quantity at bytes 324–356 of the transaction data and the daily limit of 4,000 ETH determine the maximum extractable amount. Without knowledge of the logic, finding the rescue transaction requires random mutation of transaction data and measuring the extracted value. CuEVM helps find transaction parameters in one second that could have extracted 9,000 USD more than the recorded transaction. CuEVM is useful beyond fuzzing and incident response. In particular, it enables MEV search [3], speed up block validation by parallelizing execution of independent transactions within the block [18]. IV. OVERVIEW CuEVM is a semantically complete EVM engine that executes batches of transactions entirely in GPUs. Figure 1 1 The fund was rescued by whitehats with a bounty

Inputs …

𝒮! Host Application

𝒯!,#

𝒯!,$

𝒯!,%

N Sequences

Initialize State

World State σ

𝒯#,#

…

𝒯#,%

…

…

…

𝒯&,#

…

𝒯&,%

…

CUDA Kernel

CUDA Kernel

Execution Result

CPU GPU

Partition 𝒫"

… Partition 𝒫!

Copy Results

Fig. 1: Overview of CuEVM

shows how it interacts with a host application running on CPU. The host application maintains persistent data, schedules transaction batches, and implements the application logic. A. Host Application A host application runs multiple rounds of batched execution until it reaches a target output or state. In each round, it schedules a batch of transaction sequences with a world state, then processes the execution results (or feedback) to drive the next round. This workflow applies to multiple use cases. • Smart contract fuzzing: the host application collects execution feedback in terms of code coverage, and uses it to generate the next batch of transactions. • Incident response: the host application refines the search regions of the transaction parameters after each round. • MEV search: the host application tracks the best transaction ordering with the most extractable value, and generates new ordering after each round. Adapting a CPU-based application to CuEVM requires a GPU-aware scheduler and input generator that keep the GPU fully utilized. We discuss these components for smart contract fuzzing in Section VI. B. Execution Model The host application runs in iterations. Each iteration generates a batch of N transaction sequences, where each sequence contains up to M transactions: Batch = {Si }N i=1 ,

Si = (Ti,1 , Ti,2 , . . . , Ti,M ),

(4)

where Ti,j denotes transaction j of the sequence i CuEVM adopts the shared-nothing, partitioned execution model: each sequence runs on its own partition Pi that holds an isolated version σi of the world state, analogous to GPUbased transaction execution over independent partitions [28]. This is the ideal, fully partitioned case. Some use cases, however, require data shared across partitions. For clarity we first present the general-purpose engine with N partitions and read-only shared state, which covers the majority of use cases; we defer the handling of mutable shared state to the fuzzing use case in Section VI. CuEVM executes the batch by a sequence of M CUDA kernels. The j-th kernel applies the j-th transaction of every sequence in parallel, that is, σi ← Υ(σi , Ti,j ) for i ∈ [1, N ], following the Ethereum Yellow Paper [2]. Each partition Pi is initialized with its own version σi of the world state

before the first kernel and persists this version throughout the batch execution. At the end of each iteration, the results are transferred back to the host for persistent storage before the next iteration begins. CuEVM is built for high parallelism, supporting hundreds of thousands of transactions in parallel, bounded mainly by device memory. Because a warp executes one instruction at a time across its 32 threads, the dominant performance risk is control-flow divergence within a warp. CuEVM therefore exposes a scheduling interface to the host application: the host should group transactions with similar control flow into the same warp. The engine is agnostic to how this grouping is produced and stays generic for possible applications on the host; each application supplies a GPU-aware adaptor that emits warp-friendly batches. We describe the concrete adaptor for fuzzing, which assigns one contract function per warp and varies only its inputs, in Section VI. This is finer-grained than MAU, which forces an entire kernel of thousands of threads to execute a single function and is therefore far more restrictive for the host. C. CPU-GPU Communication A naive design transfers a large amount of data between the host and device at every transaction, which is dominated by data-movement cost over the host-device interconnect [29]. CuEVM instead exchanges data only at batch boundaries, once per direction per iteration: host-to-device when a batch of N sequences is dispatched, and device-to-host when its results are collected. The result payload is application-defined. In fuzzing it is a list of bugs or coverage-increasing sequences, while in MEV search or incident response it is the sequence with the highest yield. This batched scheme follows from the observation that most transaction-execution use cases need only the final output of a sequence rather than its intermediate states. Further reductions require application-specific optimization and compression, for which we present techniques for the fuzzing use case in Section VI. V. D ESIGN AND I MPLEMENTATION This section describes the core component CuEVM in detail, which implements EVM semantics on GPU, executes N sequences of transactions in parallel on N partitions, each containing a version of the world state.

EVM1

EVMN D1

Logical Data Structure Preallocated Buffer Layout

𝑑!,! , … , 𝑑!,#

DN Dynamic Allocation

…

𝑑$,! , … , 𝑑$,#

Dynamic Allocation

𝑑!,! 𝑑%,! … 𝑑$,! … 𝑑!,# 𝑑%,# … 𝑑$,#

Fig. 2: Columnar data layout for coalesced memory access

A. Data Structures and Data Layout CuEVM runs thousands of transactions in parallel, each on its own EVM instance. Their combined execution state behaves like a large collection of records that are read and updated concurrently. We adopt two ideas from data systems to make this efficient. A columnar layout (Section V-A1) stores the same field of all instances contiguously [30]. An optimistic undo-logging scheme (Section V-C) handles transaction rollback without snapshotting or versioning the world state at every call. Each instance executes against its own version of the world state, so instances do not interfere and can run in parallel without coordination. 1) Memory access pattern and thread divergence: CUDA programs are sensitive to memory access patterns, where adjacent threads accessing adjacent memory locations can maximize effective memory bandwidth [31]. This scheme is called coalesced memory access [32]. Because memory requests within a warp are grouped before issuance, scattered requests introduce extra memory transactions, increasing delay and reducing throughput. Similarly, thread divergence within a warp (Section II-C1) incurs extra instructions and stalls as threads wait for divergent paths to complete. For coalesced memory access, we arrange the logical data elements of adjacent EVM instances contiguously in memory. When threads access the same logical data structure (e.g., the first item on each EVM’s stack), they access adjacent memory locations. For example, at the beginning of execution, neighboring threads execute the same PUSH instruction and update the top of their respective stacks. This benefits from coalesced access, as the first entries of the stacks are allocated contiguously in memory. To reduce thread divergence, we expose the transactionscheduling interface to the host program. The ideal case is when all 32 threads in a warp execute the same instruction at each step. For example, in the fuzzing use case, the host can schedule transactions that target the same contract function, so threads in a warp follow similar execution paths and divergence is reduced. 2) Call context: Each EVM instance creates a call context C (Section II-B) composed of several data structures. We distinguish two kinds. Fixed-size components are elementary values of known width, such as the 256-bit integers for the gas tracker and the transaction value, and the 64-bit values for the program counter and the call-data size. Dynamic-size components carry a data segment whose length grows and shrinks during execution, namely the memory, the stack,

and the call data. Each dynamic-size component also has fixed-size fields, such as its current size and the stack head, which we treat like the other fixed-size components. We lay out all fixed-size components in the columnar form. For example, the gas value of instance EVMi is stored next to the gas value of instance EVMi+1 , and a warp that reads the gas of consecutive instances issues coalesced memory requests. A fixed-size component is the degenerate case of one element per instance, whereas a dynamic-size component has multiple elements per instance and changes during execution. We represent a dynamic-size component with the abstraction D = [d1 , . . . , dk ] and lay out its elements with the same columnar scheme. Because the world state is more complex, each instance stores a pointer to its own version of the world state σ that it executes against. The world-state design supports the rollback mechanism in Section V-C. 3) Columnar data layout: We use one general layout for the runtime state of all instances, designed for coalesced access. Given N instances, each instance EVMi holds its own version Di of a logical data structure, where each element has the type appropriate to its component, such as a 256-bit integer for stack contents. We preallocate k elements for each Di , so Di = [di,1 , . . . , di,k ], giving a buffer of size k × N laid out as in Figure 2. Rather than store each instance’s structure contiguously, we store the corresponding element of all instances contiguously: first every instance’s element d·,1 , namely d1,1 , d2,1 , . . . , dN,1 , then every element d·,2 , and so on through the k-th elements d1,k , d2,k , . . . , dN,k . Equivalently, viewing the buffer as an N × k matrix with one row per instance and one column per element position, we store it in column-major order. This is the struct-of-arrays, or columnar, organization used in column-oriented data systems [30], and it is what makes a warp’s access to one element position across consecutive instances coalesced. If a structure outgrows its k elements, we fall back to dynamic allocation at a higher cost [33]. We use this layout for all major call-context structures except the EVM memory, whose pages we store contiguously per instance for efficiency. The value of k is configurable and defaults to a size that serves common ERC20 transfers without dynamic allocation. B. Sub-Calls When a call context Cj makes a sub-call, it creates a child context Cj+1 with its depth incremented by one relative to Cj , up to the maximum depth of 1024. When Cj+1 terminates, the EVM applies the corresponding termination logic and restores the parent context Cj . Each sub-call creates its own runtime data structures, as defined in Equation 3, while preserving the parent calls’ data for later restoration. This adds a depth dimension to the columnar layout: the N × k layout conceptually becomes an N × depth × k tensor, since every instance can hold a stack of live call contexts. Materializing it directly would scale memory with the call-depth bound of 1024, at k elements per depth. We instead flatten the depth dimension into the per-instance

buffer, with each depth at a distinct contiguous offset range, as we illustrate next with the EVM’s stack of a call Cj : stack = ⟨base ptr, offset, dyn ptr, size⟩

(5)

where base ptr points to the beginning of the preallocated data segment, offset denotes where this call’s stack content begins, dyn ptr points to the dynamically allocated segment if one exists, and size is the current stack size. When creating a new context Cj+1 from Cj , we compute the child offset offsetj+1 from the parent’s offsetj and sizej as follows: offsetj+1 = min(offsetj + sizej , buffer size)

(6)

where buffer size is the per-instance buffer size preallocated in Figure 2, that is, the value k. This lets sub-calls share one buffer at distinct starting offsets while preserving the parent’s data within the same buffer. On return from a sub-call, the child’s portion of the buffer is cleared to ensure correctness. This design, combined with the columnar layout, enables coalesced memory accesses across all call depths and relevant data structures. Adjacent threads with similar workloads are likely to execute the same instructions and access the same logical data at the same call depth, where the corresponding data is stored contiguously in memory. We use this design for all relevant call-context data structures. C. World State and Rollback Mechanism CuEVM maintains a single world state shared among all sub-calls of the same EVM instance. Except for the contract bytecode, the account data fields in Equation 1 are allocated following the layout in Section V-A3. We preallocate a buffer of a configurable size (x accounts × y storage slots) and implement the storage as two arrays, one of keys and one of values, using the layout in Figure 2. Each value V is a tuple ⟨vcurr , vorg , vwarm ⟩, where vcurr is the current 256-bit value, vorg is the value before the transaction, and vwarm indicates the warm state of the slot. These fields are required to compute gas usage correctly [34]. We allocate memory dynamically when the storage exceeds the preallocated buffer or when new accounts are created during execution. When a contract call fails due to executing a revert opcode or encountering runtime exceptions, the world state is rolled back to the state before the call. State updates are committed to storage only if the call terminates gracefully, that is, on stop or return. When revert occurs at the sub-call level, the transaction is still committed, and only the changes made by the reverted sub-calls are discarded when they return. Because most blockchain transactions are expected to complete successfully, we adopt an optimistic rollback strategy: all writes are applied directly to a single world state and recorded in an undo log. On a revert, CuEVM replays the log in reverse to restore the original values for the current call. This avoids the cost of snapshotting or versioning the world state at every call and pays the rollback cost only on the rare revert.

D. Other EVM Semantics Opcode semantics and execution model. CuEVM supports all EVM opcodes, each implemented as a separate function of the EVM instance following the Yellow Paper [2]. It includes a gas meter that tracks the execution cost of each opcode, including the dynamic gas components that can only be resolved at runtime, such as the costs of message data and memory expansion. 256-bit integer arithmetic. Since CUDA does not natively support 256-bit integers, we implement a 256-bit arithmetic library from scratch. It is adapted from the Cooperative Groups Big Numbers (CGBN) library [35] to support thread-level parallelism and finite-field arithmetic. Precompiled contracts and hashing functions. Precompiled contracts are special addresses exposing commonly used functions that contracts can call. They are analogous to UserDefined Functions in databases. CuEVM implements all precompiled contracts of the EVM Shanghai version, adapting existing libraries [36]–[38] and the reference implementation in Go Ethereum [39]. VI. C U EVM- FUZZ : C OVERAGE -G UIDED F UZZING We design a coverage-guided fuzzer, called CuEVM-fuzz, on top of CuEVM. Fuzzing is selected because it is widely used for securing smart contract, therefore CuEVM-fuzz demonstrates CuEVM’s practicality. In addition, fuzzing is execution bound, which serves as an interesting workload to demonstrate CuEVM’s performance and scalability. A. Smart Contract Fuzzing Coverage-guided fuzzing is an execution-bound workload that stresses every part of the engine, which makes it a natural first use case for CuEVM. Execution dominates the cost, because a campaign tests many transactions before a bug is revealed, so parallel execution is the established way to scale fuzzing [5], [40]. The workload, therefore, maps directly onto the batched, data-parallel model of CuEVM. In each iteration, the fuzzer forms a batch of N sequences, executes them in parallel on private clones of the world state, and adds the interesting sequences to a shared corpus. We build CuEVM-fuzz on this model. A lightweight controller on the CPU handles persistent storage and scheduling, and the GPU runs execution together with three resident modules, namely a mutator for mutating transaction data, a coverage tracker for tracking progress, and a set of bug oracles for detecting bugs. B. Batched Execution over Private State In CuEVM-fuzz, each EVM instance executes a sequence on a private clone of the world state. Within a batch there are no cross-transaction conflicts, so the engine needs no concurrency-control protocol for the transaction state, and the work reduces to layout and scheduling. The world state, the coverage map, and the bugs list are persistent on the GPU and only the world state is reinitialized from a snapshot at the start of each batch, which keeps the working set on the device and avoids per-iteration transfer.

transfer(address to, uint256 amount) Call Data

offset = 4, type = 1, length = 32

to = 0x…c0de

a9059cbb000000000000000000000000000000000000000000000000000000000000c0de 0000000000000000000000000000000000000000000000000000000000001234

offset = 36, type = 256, length = 32

amount = 0x1234

Fig. 3: Sample configuration γ for ERC-20 transfer

Algorithm 1 shows the full loop. The CPU controller drives three steps per iteration. N EXT BATCH draws a batch of N sequences from the corpus (Step ①). E XECUTE BATCH runs that batch on the GPU and returns the interesting events O (Step ②). The controller then decodes each event back into a corpus update through R ECONSTRUCT (Step ③), which rebuilds the originating sequence on the host rather than copying it back from the device. The loop typically repeats until the time budget is spent or a bug is found. E XECUTE BATCH runs entirely on the GPU and is where the private-state model takes shape. It first resets the N private clones σi from the resident snapshot, which re-initializes the world state for the new batch. It then advances the batch through M kernel launches, where launch j moves every sequence forward by one position. Inside a launch the N threads run in parallel, and thread i does three things for its sequence. It mutates the next transaction with M UTATE, applies the EVM transition function Υ to its own clone σi , and reports any feedback through T RACK E VENT. Because σi stays resident across the M launches, a sequence of length M runs to completion before returning to the host. When all threads finish, AGGREGATE R ESULTS collects the per-thread findings into one buffer for the controller. Both T RACK E VENTS and AGGREGATE R ESULTS operate on the shared coverage and bug state and are detailed in Section VI-C. Before execution, each transaction is mutated by a typeaware mutator that respects the ABI argument types embedded in the contract bytecode, which avoids transaction early reverts when those checks fail. A fuzzable transaction carries a configuration Γ = ⟨seed, [γ1 , . . . , γn ]⟩, where each γk = ⟨offset, type, length⟩ marks a mutable argument by its byte offset, type, and length in the transaction data (Figure 3). The M UTATE procedure seeds a pseudo-random generator from Γ.seed and applies standard AFL value mutators to each marked argument according to its type, such as bit and byte flips, arithmetic mutation, and dictionary insertion [21]. C. Concurrent Feedback over Shared State 1) Shared fuzzing state: Most of the engine state is private, but two structures are shared across all instances and updated concurrently by thousands of GPU threads, namely the coverage map and a set of oracle-specific buffers. We treat every update to these structures as a concurrent update to shared aggregate state and resolve it with CUDA atomic operations rather than locks [41]. The coverage map records execution feedback in the form of branch coverage and storage access. It is an array of 216 words, following the design common to existing smart contract fuzzers [5], [6], [23]. For a branch event, each word packs two

Algorithm 1 End-to-end GPU-accelerated fuzzing loop 1: Corpus ← initial corpus ▷ CPU controller 2: σ ← initial world state snapshot 3: while within time budget do 4: Batch ← N EXT BATCH(Corpus) ▷ Step ①, CPU 5: O ← E XECUTE BATCH(Batch, σ) ▷ Step ②, GPU 6: for o in O do ▷ Step ③, CPU 7: Corpus ← Corpus ∪ {R ECONSTRUCT(o)} 8: procedure E XECUTE BATCH(Batch, σ) ▷ Runs on GPU 9: for i in 1..N do ▷ Reset private clones per batch 10: σi ← σ ▷ Snapshot isolation 11: for j in 1..M do ▷ M kernels, one per sequence position 12: for i in 1..N do ▷ N GPU threads, parallel 13: Ti,j ← M UTATE(Ti,j , Γi,j ) 14: σi ← Υ(σi , Ti,j ) ▷ EVM semantics 15: T RACK E VENT(σi ) ▷ Algorithm 2 16: return AGGREGATE R ESULTS( ) ▷ Algorithm 2 17: procedure M UTATE(T , Γ) 18: rand ← S EED R ANDOM(Γ.seed) 19: for γ in Γ do 20: T ← A RG M UTATE(T , γ, rand) 21:

▷ Type-aware

return T

signals, an 8-bit branch distance in its high bits and a 24-bit hit count in its low bits, C OV[eid ] = distance | {z } ∥ |hitcount {z } . bits[31:24]

(7)

bits[23:0]

The hit count records how often an event has been observed across the campaign, so a word that is still zero marks a branch or storage access reached for the first time. The branch distance measures how close a conditional was to flipping. At the comparison that precedes a conditional jump, we record the gap between the compared operands, and a smaller gap means the input is closer to taking the branch it currently misses. This matters because EVM conditions often compare 256-bit values, where a random input either takes a branch or misses it with no signal in between, and the distance turns that all-or-nothing outcome into a progress the fuzzer can improve over time [6], [23]. We use the bit count of the distance instead of its absolute 256-bit value. The event identifier eid selects the entry in the coverage map. For a branch it combines the current program counter pc, the taken destination pcdst , and the account address a, eid = (pc ≪ 1 ⊕ pcdst ) ⊕ a,

(8)

and for a storage access it combines pc, the slot key, and a. The collision property of this encoding scheme has been analyzed in [42]. The address term a is to track coverage across different smart contracts in the world state. The oracle-specific buffers hold the extra evidence to confirm and report a specific finding, such as minimized historical call data that can confirm whether the attacker can make an arbitrary call. Oracle writes into this buffer by incrementing an atomic index, so that concurrent findings do not collide.

Algorithm 2 Concurrent feedback over shared state on GPU 1: R ← ∅ ▷ Private buffer per thread 2: procedure T RACK E VENT(o) ▷ Hit branch or storage event 3: t ← ATOMIC A DD(C OV[o.eid ], 1) 4: if t & 0xffffff == 0 then R ← R ∪ {o} ▷ New event 5: procedure T RACK D ISTANCE(o, distance) 6: cmp ← (255 − distance) ≪ 24 7: t ← ATOMIC M AX(C OV[o.eid ], cmp) 8: if cmp > t then R ← R ∪ {o}

▷ Missed branch ▷ Distance reduced

9: O ← [o1 , . . . , om ] ; count ← 0 ▷ Shared buffer and index 10: procedure AGGREGATE R ESULTS ▷ Parallel over threads 11: for o ∈ R do 12: idx ← ATOMIC A DD(count, 1) 13: if idx < m then O[idx ] ← o

2) Reporting feedback to shared state: Algorithm 2 shows how each thread reports feedback. T RACK E VENT records a new branch or storage event by atomically incrementing the word and testing whether the prior hit count was zero, so the thread that first reaches an event is the one that reports it. T RACK D ISTANCE records progress toward a missed branch by an atomic maximum on the distance field. We encode the value as 255−distance, so a shorter distance produces a larger stored value, and ATOMIC M AX keeps an input only when it improves on the best distance seen so far. We use ATOMIC M AX because the distance occupies the most significant bits, so the comparison is decided by the distance field, and the lower hit count bits cannot change its outcome. Both atomics return the old value, allowing the current thread to determine whether it actually updated the value. For extra data such as the full event o that must be copied back to the CPU, each thread writes its findings to a private buffer R during execution. Once all threads finish, AGGREGATE R ESULTS merges these buffers into the shared output buffer O using an atomic index. When multiple threads aggregate into the same buffer, ATOMIC A DD increments the index count exactly once per thread, returning a unique index into the shared buffer for updating. D. Minimizing Host-device Data Movement We minimize host-device traffic in both directions for performance. The mutation configurations and the initial world state snapshot are cached on the GPU to avoid frequent transfers. We schedule each transaction sequence to a warp of 32 threads that share one configuration, and transfer a single index idx per warp to select the cached configuration together with a per-batch base seed, where thread k derives its seed as seed + k. On the return path we avoid copying mutated transaction data back by implementing an equivalent pair of pseudo-random generators on both the CPU and GPU. The controller reconstructs an interesting sequence by replaying the same mutation from the interesting thread indices (i, j) in a batch. Each reported event is therefore compact, O = [oi,j ],

oi,j = ⟨seq, eid, data⟩,

(9)

where seq is a placeholder the controller fills by replay, eid identifies the bug or coverage entry, and data carries any event-specific payload. E. Bug Oracles and Controller CuEVM-fuzz implements its bug oracles natively on the GPU. We support integer overflow and underflow [24], unauthorized self-destruct, leaking ether, and arbitrary external call [43], and reentrancy that violates the check-effectinteraction pattern [43]. We select these because they cover high-risk classes that existing tools also detect, appear in common benchmarks [24], [44], and are verifiable from source code or from the exploit sequence. The controller builds on Medusa [40], a property-based fuzzer from Trail of Bits, which lets us reuse its configuration format, corpus, coverage reporting, and sequence generators with less engineering effort. We extend its generator with function dependency information from Slither [45]. For a function f , we derive Fdep (f ), the functions that write variables f reads, and Finfl (f ), the functions that read variables f writes. We prepend a sample from Fdep (f ) and append a sample from Finfl (f ) so that generated sequences exercise state dependencies. The controller schedules transactions so that each group of k GPU threads targets the same smart contract function. By default, k equals the warp size of 32. The controller can also load an arbitrary initial state, which supports stateful and cross-contract campaigns. The address term a in the event identifier of Equation 8 already separates coverage and bugs per deployed contract to support crosscontract tracking natively. VII. E VALUATION A. Methodology We first evaluate the performance and correctness of CuEVM in executing transactions in the Ethereum Execution Tests format [46]. We then evaluate the performance of CuEVM-fuzz and incident response application. Our experimental artifact is available online [47]. Metrics. We use transactions per second (TPS) to measure transaction execution throughput. We measure fuzzing effectiveness in terms of code coverage and the number of bugs found over time. In particular, we use unique instructions covered for code coverage [5], [6], [24]. In EVM, unique instructions are identified by their program counter (pc) values. For a fair comparison, we run each baseline under its best-performing configuration and adopt the common pc counting method, documenting any changes. Workloads and Datasets. We evaluate CuEVM along two axes. The workloads (ERC-20 transfers and Uniswap swaps) characterize raw execution throughput under popular transaction types and different complexities. They represent the backbone of DeFi applications and account for the majority of Ethereum traffic. The datasets (LabeledDataset, EtherScan500, RecentContract, and PopularContract) are collections of real contracts used to evaluate CuEVM-fuzz. LabeledDataset comprising two bug types: Integer Overflow/Underflow Bug

B. Correctness, Throughput, and Scalability 1) Execution correctness: We integrated CuEVM with GoEVMLab [48] to compare our EIP-3155 output with Geth on Ethereum’s Test Suite [46] to evaluate its correctness. The test suite consists of over 14,000 tests divided into smaller sets to test different aspects of EVM semantics. A test is passed if CuEVM’s trace matches Geth on the gas usage and the full stack content in each executed instruction. The results show that CuEVM passes 100% of the VMTests subset, which contains the core EVM semantics, and it passed 96.2% of all the tests. Most failures are due to minor gas differences in corner cases, which typically involve reverts near the call depth limit and trace printing timed out due to the extraction of large stack content for all instructions. These failures come from stress-test-style cases and CUDA’s printing limitation, thus they do not affect practical applications such as fuzzing, where transactions stay below the limit and printing is disabled. We instrumented MAU for correctness comparison. Because heavy instrumentation disrupts MAU operation, we relaxed the check: a test passed when MAU matches Geth in the opcode and the first stack item on each executed instruction. We disregard gas comparisons, as MAU does not support recent gas calculations such as EIP-2929. Although this estimates an upper bound for correctness, MAU only passes 18.7% of the tests. Most failures stem from external calls and contract creation, which are common in real-world smart contracts. 2) Bytecode execution throughput: We conduct microbenchmarks to measure the peak throughput of CuEVM under non-conflicting transaction workloads. We compare against three EVM implementations: GoEthereum (Geth) [39], Rustbased EVM (RETH) [49], and RETH-based Parallel EVM (PEVM) [50]. All measurements only record the bytecode execution logic, without the memory initialization and transfer

Geth

TPS (log scale)

107

RETH

PEVM

CuEVM

106 105 104

ERC20_transfer

UniswapV3_swap

Workload

Fig. 4: Comparison of execution throughput ERC20_transfer

TPS (log scale)

(IB, 58 contracts) and Reentrancy (RE, 19 contracts) from Smartian [24]. The IB contracts are reported CVEs, and the RE contracts are from the Smartbugs dataset [44]. We use three unlabeled datasets to evaluate different aspects of CuEVMfuzz. First, for direct comparison with existing works, we use EtherScan500 dataset from Smartian, which consists of the 500 largest and most popular smart contracts collected from Etherscan. This dataset evaluates performance on complex real-world contracts that all baselines can process successfully. We further construct RecentContract dataset, which contains 3,691 contracts recently deployed on Ethereum, predominantly compiled with Solidity version 0.8. Finally, to demonstrate practical security relevance, we conduct a large-scale scan on the PopularContract dataset, consisting of 20,000 popular contracts with active user activity over the past two years on Ethereum and Binance Smart Chain. Experiment setup. We run all experiments on a workstation with an Intel® Core™ i9 processor 14900 running Ubuntu 24.04 LTS. The machine is equipped with 128GB RAM and an NVIDIA RTX 5000 Ada with 32GB memory. Except the large-scale smart contracts scanning experiment, we ran each experiment 3 times and report the average.

10

7

10

6

10

5

10

4

16k

32k

UniswapV3_swap

64k 128k GPU threads

256k

512k

Fig. 5: CuEVM throughput scaling

time, which account for less than 0.1 second in CuEVM. We validate CuEVM against Geth by comparing EIP-3155 traces on this workload and confirm it matches the traces produced by Geth. We defer MAU comparison to the fuzzing use case because it lacks support for external calls. For CuEVM, we scale the workload up to 512,000 transactions and report the best result. Figure 4 shows the results. For ERC20 transfers, CuEVM achieves 8.3 million TPS. For Uniswap transactions involving many external calls, CuEVM achieves the throughput of around 441,000 TPS. 3) Scalability: Figure 5 reports the scalability of CuEVM as the number of GPU threads grows from 16k to 512k, with one transaction per thread. The two workloads scale differently, reflecting the data-layout choices in Section V. ERC20 fits the default preallocated buffer, therefore the throughput increases to over 8M TPS, ultimately bounded by memory capacity: at 512k threads it consumes about 24.9 GB. Uniswap peaks at 128k threads and then slightly declines. Its many external calls and deeper call stack use the dynamic allocated memory region which is the source of contention as the number of threads grows. We note that the buffer size is configurable, thus it is possible to profile the target workload and size the buffer accordingly to reduce this contention. C. CuEVM-fuzz We compare CuEVM-fuzz against four other state-of-the-art smart contract fuzzers: Smartian [24], ItyFuzz [6], MAU [5], and Medusa [40]. 1) Fuzzing throughput: A key performance metric for fuzzing is the seed execution speed: the more seeds a fuzzer runs, the faster it can uncover program paths and bugs. Figure 6 compares the end-to-end fuzzing seed execution speed for LabeledDataset and Etherscan500 datasets. We

Throughput (x10³ TPS)

ItyFuzz

Medusa

MAU

CuEVM-fuzz

1000

TABLE I: Bug detection results on EtherScan500 and RecentContract. IB, LE, AC, RE indicate Integer Overflow/Underflow, Leaking Ether, Arbitrary Call, and Reentrancy.

750 EtherScan500

500 250 0

EtherScan500

Dataset

LabeledDataset

LE

AC

RE

IB

LE

AC

RE

Smartian

Bugs FP

169 0

4 2

-

0 0

-

-

-

-

ItyFuzz

Bugs FP

-

-

18 0

6 193

-

-

0 0

0 3

CuEVM-fuzz

Bugs FP

295 0

8 0

20 0

10 0

5 1

6 16

0 1

0 0

Fig. 6: Fuzzing throughput

exclude Smartian due to its low performance as reported in [5], [6]. We skip the large-scale datasets RecentContract and PopularContract because not all tools can process them successfully. It can be seen that our fuzzer achieves significantly higher throughput, up to 23× faster than the fastest CPU baseline (Medusa) and 4.8× faster than the state-of-theart GPU baseline (MAU). 2) Code coverage: Figure 7 compares the instruction coverage of the fuzzers over time on the three datasets. On RecentContract, MAU failed to generate the PTX files for 3,335, or 90% of the contracts, and Smartian can only execute 21 contracts. Thus, we do not include the results of these two baselines. We further exclude contracts that ItyFuzz cannot process to ensure a fair comparison. The reported results cover 3,354 contracts supported by all remaining fuzzers. The result shows that CuEVM-fuzz achieves the best coverage on both the EtherScan500 and RecentContract within the first two seconds. Compared to the second-best baseline, MAU, it achieves 4% more coverage in 30× shorter time. The gap between CuEVM-fuzz and ItyFuzz arises from features such as extracting senders from the source code. Medusa underperformed mainly because it does not fuzz fallback functions. 3) Bug finding performance: We compare our bug finding performance against ItyFuzz and Smartian. We exclude MAU from this experiment since its released artifact does not have a bug detector, and the authors have indicated via email that it remains proprietary. Medusa is excluded because it only has assertion-based oracles. For unlabeled datasets, we confirm bugs manually by mapping bytecode back to Solidity source, spending up to five minutes per report. On LabeledDataset, Ityfuzz, CuEVM-fuzz, and Smartian reported the same set of 18 true positive labeled RE bugs. For bug detection speed, CuEVM-fuzz reported 51 CVEs in two seconds, which takes Smartian 10 minutes to achieve, as reflected in Figure 8a. On unlabeled datasets, we report the bug-finding performance of Etherscan500 and RecentContract in Table I, where the Bugs row shows the number of true positives and the FP row indicates the number of false positives. CuEVM-fuzz finds 1.75× more IB bugs in one minute than Smartian does in 10 minutes. It identifies eight exploitable LE bugs caused by constructor name mismatches, 2× more than Smartian. They are critical bugs that allow attackers to gain full control of the contract and withdraw

RecentContract

IB

all the funds. CuEVM-fuzz finds 20 arbitrary call bugs in this well-fuzzed dataset. Interestingly, some of these bugs are from the ERC827 token standard draft that was deemed unsafe and had been removed [51]. For a comparison of bug detection speed between CuEVM-fuzz and ItyFuzz, we use Etherscan500 and the two types of bugs, Arbitrary Call and Reentrancy (AC and RE) that ItyFuzz supports. The speed of both tools is reported in Figure 8b. It shows that CuEVMfuzz reports more bugs in two seconds compared to ItyFuzz performance in a minute. 4) Vulnerability detection in the wild: To further evaluate the practical security relevance of CuEVM-fuzz on active projects, we leverage its high throughput to perform large-scale scanning on the PopularContract dataset (10,000 contracts each from Ethereum and Binance Smart Chain, BSC). We run CuEVM-fuzz and ItyFuzz with a time budget of 10 seconds per contract. In total, CuEVM-fuzz uncovers several high-risk bugs in 115 contracts (42 from Ethereum and 73 from BSC). Among them, 89 contracts contain IB bugs, 11 contain RE bugs, 9 contain AC bugs, and the remainder contain LE bugs. Four contracts exhibit two bug types (AC and LE). Notably, bugs observed in the EtherScan500 still exist in the PopularContract. One prime example is the ERC-827 token, which is still used by projects despite being reported as unsafe [51]. Many projects, especially on BSC, continue to use legacy code before Solidity 0.8 and remain vulnerable to IB. The majority of the affected projects were ERC-20 tokens that lack longterm maintainers. Despite using Solidity 0.8, 16 contracts still suffer from IB due to the use of unchecked blocks, which disable compiler-injected arithmetic checks to reduce gas costs in frequently executed operations. The true positives above were filtered from 303 contracts reported by CuEVM-fuzz. In comparison, ItyFuzz discovers true vulnerabilities in 18 projects (12 AC and 6 RE). Among them, 1 RE and 4 AC bugs are not detected by CuEVM-fuzz. We note that ItyFuzz’s bug oracles exhibit a higher false positive rate (256 out of 274 alarms are false positives). We adopt best-effort responsible disclosure for the affected contracts, emailing the contacts listed on project websites or cryptocurrency trackers and, where none exist, messaging the owner addresses through Blockscan. Three teams acknowledged the issues, having added user warnings or already being

100 CuEVM-fuzz ItyFuzz Medusa

50 0

0

10

20

30

40

Time (seconds)

Smartian MAU 50

60

2,000 1,500 1,000

CuEVM-fuzz ItyFuzz Medusa

500 0

0

10

(a) LabeledDataset

20

30

40

Time (seconds)

Smartian MAU 50

60

Instruction Coverage (x10³)

150

Instruction Coverage (x10³)

Instruction Coverage (x10³)

200

12,000 10,000 8,000 6,000 4,000 2,000 0

CuEVM-fuzz ItyFuzz Medusa 0

10

(b) EtherScan500

20

30

40

Time (seconds)

50

60

(c) RecentContract

30 20

CuEVM-fuzz Smartian

10 0

0

100 200 300 400 500 600

25 20 15 10 0

Time (seconds)

(a) CVEs detected over time on LabeledDataset

CuEVM-fuzz ItyFuzz

5 0

10

20

30

40

Time (seconds)

50

60

(b) AC and RE bugs detected over time on EtherScan500

Fig. 8: Detection speed comparison with the baselines

aware of them. Some projects with AC bugs carry warnings on Etherscan advising users not to grant token permissions,2 five contracts were already labeled “phishing/hack” by blockchain explorers, and some projects had migrated to new contracts following the same findings in past professional audits,3 which confirms that CuEVM-fuzz surfaces bugs that professional services also report. 5) False positive analysis: The source of false positives is mainly caused by incomplete information observed by the oracles, similar to existing fuzzers. In IB bugs, the most common case is the intended overflow used by customized math libraries with intended overflow wraparound to implement 2256 modulo arithmetic. Furthermore, some IB bugs require the contract owners to set certain parameters to be extremely large, which only occurs by accidentally calling the functions outside their intended usage. For RE bugs, the most common false-positive pattern is harmless reentrancy, where reentrancy happens, but it does not result in a trivial exploit leading to direct fund loss. One example is the deposit of user’s controlled assets, where reentrancy results in repeating the deposit actions multiple times. Ityfuzz has a high false positive rate for RE bugs because its default oracle only detects call loops, not post-call state writes, causing false positives in harmless external or read-only calls. 6) Fuzzing scalability: We study the scalability of CuEVMfuzz by varying configurations and components that affect execution speed, such as the number of GPU threads per kernel and workers for the fuzzing controller on CPU. In addition, we 2 https://archive.ph/beCZt 3 https://paladinsec.co/projects/unsellable-nfts/

CuEVM-fuzz

CPU-only

SimpleController

50 150

CVEs Detected

40

30

Instruction Coverage (×10³)

CVEs Detected

50

RE and AC Bugs Detected

Fig. 7: Instruction coverage on different datasets over time, measured every second

100 50 0

0

20

40

Time (seconds)

60

40 30 20 10 0

0

20

40

Time (seconds)

60

Fig. 9: Ablation study on LabeledDataset

introduce two variants to validate the transaction scheduling policy and the choice of data structure design in Section V-A1. For manageable runtime, we sort the EtherScan500 dataset by bytecode size and sample 50 representative contracts evenly spaced in the sorted list. The end-to-end fuzzing throughput results are reported in Figure 10. The configuration format is {GPU threads} {CPU threads}, for example, configuration 8k 32 means the fuzzer uses 8,192 GPU threads and 32 goroutines on the CPU. We vary the GPU threads from 4k to 65k. We ran the configuration 65k 1 for the no sched (remove warp-based scheduling, heighten thread divergence) and no mem (remove the data preallocation scheme and coalesced design) variants. The results show that CuEVM-fuzz scales well with the number of GPU threads, while CPU workers contribute little to end-to-end performance. This suggests that the bottleneck of end-to-end fuzzing throughput remains on the GPU side, indicating the potential of multi-GPU systems for further speedup. Both no sched and no mem perform poorly compared to other CuEVM-fuzz variants, with no mem showing the worst performance. This indicates that memory allocation and coalesced access patterns are the most important factors for a performant GPU-native execution engine solution, as many instances access memory at high frequency. 7) Fuzzing-quality ablation: We evaluate the fuzzing quality of two variants of CuEVM-fuzz, namely CPU-only and SimpleController. The former simulates the execution of CuEVM on CPU with goroutines to validate the need for a GPU-native execution engine. The latter uses a basic fuzzing controller without function-dependency extraction from Slither. Figure 9 shows the performance of the two variants in terms of code coverage and bug detection. Although

1,000 500

16 65 k_ 8 65 k_ 4 65 k_ 2 65 k_ no 1 _s ch e no d _m em

32

65 k_

32

65 k_

32 k_

2

32

16 k_

8k _3

2

0

4k _3

Throughput (x10³ TPS)

1,500

Configuration

Fig. 10: Throughput of different CuEVM-fuzz variants on a subset of Etherscan500 similar coverage is achieved quickly by both variants, their bug-detection performance exhibits a different trend. The CPU-only variant lags behind by a large margin compared to the SimpleController version that still uses GPUs for executing transaction. The result strengthens our motivation for introducing GPU acceleration. Since instruction coverage can be saturated early, the main objective of fuzzing is to further mutate inputs on covered paths and run bug oracles. CuEVMfuzz accelerates both of these steps on GPUs, resulting in faster bug discovery. D. Incident Response We extend CuEVM to implement a prototype that searches for rescue transactions with the most value (see Section III for an example). We introduce the Extract Value Oracle, a universal, project-agnostic oracle that measures the ETH balance of a given account after transaction execution and returns the GPU thread index yielding the maximum observed balance. Project-specific oracles can likewise track a particular token balance, which requires knowledge of the contracts and tokens involved. We provide implementation details in our public artifact. Given contract call data encoding N parameters, the prototype uses the contract’s ABI to identify optimizable parameters (e.g., integers or addresses). It then mutates the call data, similar to CuEVM-fuzz to run parallel tests, applying a two-phase random search [52]. The oracle selects the thread with the highest attacker balance postexecution, deriving transaction data that maximizes extracted value. Within one second, the prototype finds a transaction extracting an additional 9,000 USD (3.68 ETH) over the actual optimized exploit transaction, which was submitted 49 minutes after the optimizable exploit. VIII. R ELATED W ORK Parallel database transaction processing. Main-memory databases scale throughput on multicore hardware through optimistic concurrency control and deterministic execution, such as Calvin [53] and Aria [54]. GPUs have also been used to accelerate data processing, from relational operators [55] and analytical queries [7] to high-throughput transaction execution [28], where a recurring lesson is that data placement and host-device transfer usually bound performance. Parallel smart contract execution. The sequential execution model of EVM limits the blockchain throughput.

Monad [56] introduces an optimistic execution model that executes transactions in parallel, and retries a transaction if its input storage slots are modified by other transactions. BlockSTM [18], FAFO [57], and DMVCC [58] propose concurrency control algorithms at the transaction and block level. ParallelEVM [19] proposes concurrency control algorithms at the operation level. Spectrum [59] and Seer [60] apply techniques in concurrency control and branch prediction, unlocking parallel execution potential in smart contracts. These works target parallel blockchain execution on CPUs under concurrency control. CuEVM is complementary, targeting independent, non-conflicting workloads via GPU data-parallelism. Smart contract fuzzing. Inspired by the success of fuzzing in traditional software testing [61], smart contract fuzzing has become one of the standard methods to find bugs and protect assets on blockchains. It has evolved from simple binary fuzzing with single transactions [23] to sequence-aware transaction fuzzing [62] and using approaches that leverage machine learning [63] and data flow information [24]. Most fuzzers focus on enhancing input mutation while executing transactions on CPU-based EVMs. Recent fuzzers improve execution speed by using snapshots to avoid reexecuting costly transactions [6] or by using GPUs [5]. MAU [5] transpiles EVM bytecodes into PTX assembly to emulate EVM execution on GPUs. However, MAU does not fully support EVM semantics, failing over 80% of the Ethereum Test Suite, and relies on expensive CPU-side evaluation for fuzzing. IX. C ONCLUSION We present CuEVM, a GPU-native and semantically complete EVM execution engine. CuEVM treats transaction execution as a batched, data-parallel workload and applies datamanagement techniques such as a columnar state layout to achieve up to 8.3 million ERC20 transfers per second. Our scalability study shows that throughput grows with the number of parallel instances and that the bottleneck remains on the GPU side, suggesting that the current performance can grow higher with powerful GPUs or under multi-GPUs settings. We demonstrate the practicality and performance of CuEVM by designing a smart contract fuzzer, which achieves up to 1.1 million end-to-end executions per second and detects high-risk bugs in 115 deployed contracts. We show CuEVM’s generality by implementing an incident response application which can find high-value rescue transactions within one second. R EFERENCES [1] “DefiLlama: DeFi TVL aggregator.” https://defillama.com/, 2025, (Accessed May 15, 2026). [2] G. Wood et al., “Ethereum: A secure decentralised generalised transaction ledger,” Ethereum project yellow paper, vol. 151, no. 2014, pp. 1–32, 2014. [3] W. Chen and X. Luo, “Mevisor: High-throughput mev discovery in dexs with gpu parallelism.” in NDSS, 2026. [4] D. Meng, F. Gritti, R. McLaughlin, N. Ruaro, I. Grishchenko, C. Kruegel, and G. Vigna, “Houston: Real-time anomaly detection of attacks against ethereum defi protocols.” in NDSS, 2026. [5] W. Chen, X. Luo, H. Cai, and H. Wang, “Towards smart contract fuzzing on gpus,” in 2024 IEEE Symposium on Security and Privacy (SP). IEEE, 2024, pp. 2255–2272.

[6] C. Shou, S. Tan, and K. Sen, “Ityfuzz: Snapshot-based fuzzer for smart contract,” in Proceedings of the 32nd ACM SIGSOFT International Symposium on Software Testing and Analysis, 2023, pp. 322–333. [7] A. Shanbhag, S. Madden, and X. Yu, “A study of the fundamental performance characteristics of gpus and cpus for database analytics,” in Proceedings of the 2020 ACM SIGMOD international conference on Management of data, 2020, pp. 1617–1632. [8] “Etherscan: The Ethereum Blockchain Explorer,” https://etherscan.io/, 2025, (Accessed May 15, 2026). [9] K. Qin, S. Chaliasos, L. Zhou, B. Livshits, D. Song, and A. Gervais, “The blockchain imitation game,” in 32nd USENIX Security Symposium (USENIX Security 23), 2023, pp. 3961–3978. [10] C. Mohan, “Tutorial: blockchains and databases,” Proceedings of the VLDB Endowment, vol. 10, no. 12, pp. 2000–2001, 2017. [11] T. T. A. Dinh, R. Liu, M. Zhang, G. Chen, B. C. Ooi, and J. Wang, “Untangling blockchain: A data processing view of blockchain systems,” IEEE transactions on knowledge and data engineering, vol. 30, no. 7, pp. 1366–1385, 2018. [12] P. Ruan, T. T. A. Dinh, D. Loghin, M. Zhang, G. Chen, Q. Lin, and B. C. Ooi, “Blockchains vs. distributed databases: Dichotomy and fusion,” in Proceedings of the 2021 International Conference on Management of Data, 2021, pp. 1504–1517. [13] Z. Ge, D. Loghin, B. C. Ooi, P. Ruan, and T. Wang, “Hybrid blockchain database systems: design and performance,” Proceedings of the VLDB Endowment, vol. 15, no. 5, pp. 1092–1104, 2022. [14] T. T. A. Dinh, J. Wang, G. Chen, R. Liu, B. C. Ooi, and K.-L. Tan, “Blockbench: A framework for analyzing private blockchains,” in Proceedings of the 2017 ACM international conference on management of data, 2017, pp. 1085–1100. [15] G. Zheng, L. Gao, L. Huang, and J. Guan, “Application binary interface (abi),” in Ethereum Smart Contract Development in Solidity. Springer, 2020, pp. 139–158. [16] W. J. Dally, S. W. Keckler, and D. B. Kirk, “Evolution of the graphics processing unit (gpu),” IEEE Micro, vol. 41, no. 6, pp. 42–51, 2021. [17] S. Cook, CUDA programming: a developer’s guide to parallel computing with GPUs. Newnes, 2012. [18] R. Gelashvili, A. Spiegelman, Z. Xiang, G. Danezis, Z. Li, D. Malkhi, Y. Xia, and R. Zhou, “Block-stm: Scaling blockchain execution by turning ordering curse to a performance blessing,” in Proceedings of the 28th ACM SIGPLAN Annual Symposium on Principles and Practice of Parallel Programming, 2023, pp. 232–244. [19] H. Lin, H. Feng, Y. Zhou, and L. Wu, “Parallelevm: Operation-level concurrent transaction execution for evm-compatible blockchains,” in Proceedings of the Twentieth European Conference on Computer Systems, 2025, pp. 211–225. [20] “REKT Database: Top Crypto Hacks,” https://de.fi/rekt-database, 2025, (Accessed May 15, 2026). [21] “AFL: American Fuzzy Lop,” https://github.com/google/AFL, 2025, (Accessed May 15, 2026). [22] X. Gao, Z. Liu, Y. Shen, H. Li, Y. Liu, H. Xiao, Y. Peng, and J. Cui, “Fucci: Database transaction fuzzing via random conflict construction and multilevel constraint solving,” Proceedings of the VLDB Endowment, vol. 18, no. 6, pp. 1879–1891, 2025. [23] T. D. Nguyen, L. H. Pham, J. Sun, Y. Lin, and Q. T. Minh, “sfuzz: An efficient adaptive fuzzer for solidity smart contracts,” in Proceedings of the ACM/IEEE 42nd international conference on software engineering, 2020, pp. 778–788. [24] J. Choi, D. Kim, S. Kim, G. Grieco, A. Groce, and S. K. Cha, “Smartian: Enhancing smart contract fuzzing with static and dynamic data-flow analyses,” in 2021 36th IEEE/ACM International Conference on Automated Software Engineering (ASE). IEEE, 2021, pp. 227–239. [25] C. F. Torres, A. K. Iannillo, A. Gervais, and R. State, “Confuzzius: A data dependency-aware hybrid fuzzer for smart contracts,” in 2021 IEEE European Symposium on Security and Privacy (EuroS&P). IEEE, 2021, pp. 103–119. [26] Z. Zhang, Z. Lin, M. Morales, X. Zhang, and K. Zhang, “Your exploit is mine: Instantly synthesizing counterattack smart contract,” in 32nd USENIX Security Symposium (USENIX Security 23), 2023, pp. 1757– 1774. [27] “Whitehat rescues,” https://safeharbor.securityalliance.org/whitehats, 2025, (Accessed May 5, 2026). [28] B. He and J. X. Yu, “High-throughput transaction executions on graphics processors,” Proceedings of the VLDB Endowment, vol. 4, no. 5, pp. 314–325, 2011.

[29] C. Pearson, A. Dakkak, S. Hashash, C. Li, I.-H. Chung, J. Xiong, and W.-M. Hwu, “Evaluating characteristics of cuda communication primitives on high-bandwidth interconnects,” in Proceedings of the 2019 ACM/SPEC International Conference on Performance Engineering, 2019, pp. 209–218. [30] D. J. Abadi, S. R. Madden, and N. Hachem, “Column-stores vs. rowstores: how different are they really?” in Proceedings of the 2008 ACM SIGMOD international conference on Management of data, 2008, pp. 967–980. [31] N. Fauzia, L.-N. Pouchet, and P. Sadayappan, “Characterizing and enhancing global memory data coalescing on gpus,” in 2015 IEEE/ACM International Symposium on Code Generation and Optimization (CGO). IEEE, 2015, pp. 12–22. [32] “CUDA C++ Programming Guide,” https://docs.nvidia.com/cuda/cud a-c-programming-guide/#device-memory-accesses, 2025, (Accessed May 15, 2026). [33] M. Winter, M. Parger, D. Mlakar, and M. Steinberger, “Are dynamic memory managers on gpus slow? a survey and benchmarks,” in Proceedings of the 26th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming, 2021, pp. 219–233. [34] V. Buterin and M. Swende. (2020, Sep.) EIP-2929: Gas cost increases for state access opcodes. https://eips.ethereum.org/EIPS/eip- 2929. Ethereum Improvement Proposals, no. 2929. [35] Nvidia, “CGBN: CUDA Accelerated Multiple Precision Arithmetic (Big Num) using Cooperative Groups,” https://github.com/NVlabs/CGBN, 2025, (Accessed May 15, 2026). [36] “SHA-2: SHA-2 Algorithm Implementations,” https://github.com/amo snier/sha-2, 2025, (Accessed May 15, 2026). [37] “BigInt: Big Integer Library in C,” https://github.com/983/bigint, 2025, (Accessed May 15, 2026). [38] “PyECC: Python implementation of ECC pairing and curve operations,” https://github.com/ethereum/py ecc, 2025, (Accessed May 15, 2026). [39] “Go-Ethereum: Go implementation of the Ethereum protocol,” https: //github.com/ethereum/go-ethereum, 2025, (Accessed May 15, 2026). [40] “Medusa: Parallelized, coverage-guided, mutational Solidity smart contract fuzzing, powered by Go-Ethereum,” https://github.com/crytic/me dusa, 2025, (Accessed May 15, 2026). [41] “CUDA C++ Programming Guide,” https://docs.nvidia.com/cuda/cud a-c-programming-guide/#atomic-functions, 2025, (Accessed May 15, 2026). [42] J. Wang, Y. Duan, W. Song, H. Yin, and C. Song, “Be sensitive and collaborative: Analyzing impact of coverage metrics in greybox fuzzing,” in 22nd International Symposium on Research in Attacks, Intrusions and Defenses (RAID 2019), 2019, pp. 1–15. [43] “Solidity Security Considerations,” https://docs.soliditylang.org/en/lates t/security-considerations.html, 2025, (Accessed May 15, 2026). [44] J. F. Ferreira, P. Cruz, T. Durieux, and R. Abreu, “Smartbugs: A framework to analyze solidity smart contracts,” in Proceedings of the 35th IEEE/ACM international conference on automated software engineering, 2020, pp. 1349–1352. [45] J. Feist, G. Grieco, and A. Groce, “Slither: a static analysis framework for smart contracts,” in 2019 IEEE/ACM 2nd International Workshop on Emerging Trends in Software Engineering for Blockchain (WETSEB). IEEE, 2019, pp. 8–15. [46] “Ethereum Execution Tests (EVM),” https://github.com/ethereum/tests, 2025, (Accessed May 15, 2026). [47] “Cuevm experimental artifact,” https://github.com/cuevm-artifact/cuev m-artifact, 2026. [48] “Go EVMLab: Go EVM Laboratory,” https://github.com/holiman/goe vmlab, 2025, (Accessed May 15, 2026). [49] “Reth: Rust Ethereum,” https://github.com/paradigmxyz/reth, 2025, (Accessed May 15, 2026). [50] “PEVM: RISE Parallel EVM,” https://github.com/risechain/pevm, 2025, (Accessed May 15, 2026). [51] “EIP827: ERC827 Token Standard (ERC20 Extension),” https://github .com/ethereum/EIPs/issues/827, 2025, (Accessed May 15, 2026). [52] Z. B. Zabinsky, Stochastic adaptive search for global optimization. Springer Science & Business Media, 2003, vol. 72. [53] A. Thomson, T. Diamond, S.-C. Weng, K. Ren, P. Shao, and D. J. Abadi, “Calvin: fast distributed transactions for partitioned database systems,” in Proceedings of the 2012 ACM SIGMOD international conference on management of data, 2012, pp. 1–12.

[54] Y. Lu, X. Yu, L. Cao, and S. Madden, “Aria: a fast and practical deterministic oltp database,” Proceedings of the VLDB Endowment, vol. 13, no. 12, pp. 2047–2060, 2020. [55] B. He, K. Yang, R. Fang, M. Lu, N. Govindaraju, Q. Luo, and P. Sander, “Relational joins on graphics processors,” in Proceedings of the 2008 ACM SIGMOD international conference on Management of data, 2008, pp. 511–524. [56] “Monad: High-performance Ethereum-compatible L1,” https://docs.mon ad.xyz/, 2025, (Accessed May 15, 2026). [57] R. Zarick, I. Zhang, D. Wong, T. Kim, B. Pellegrino, M. Li, and K. Wong, “Fafo: Over 1 million tps on a single node running evm while still merkleizing every block,” arXiv preprint arXiv:2507.10757, 2025. [58] X. Qi, J. Jiao, and Y. Li, “Smart contract parallel execution with finegrained state accesses,” in 2023 IEEE 43rd International Conference on Distributed Computing Systems (ICDCS). IEEE, 2023, pp. 841–852. [59] Z. Chen, T. Yang, Y. Zheng, Z. Zhang, C. Jin, and A. Zhou, “Spectrum: Speedy and strictly-deterministic smart contract transactions for blockchain ledgers,” Proceedings of the VLDB Endowment, vol. 17, no. 10, pp. 2541–2554, 2024. [60] S. Zhang, R. Cheng, X. Liu, J. Xiao, H. Jin, and B. Li, “Seer: Accelerating blockchain transaction execution by fine-grained branch prediction,” Proceedings of the VLDB Endowment, vol. 18, no. 3, pp. 822–835, 2024. [61] A. Fioraldi, D. Maier, H. Eißfeldt, and M. Heuse, “{AFL++}: Combining incremental steps of fuzzing research,” in 14th USENIX workshop on offensive technologies (WOOT 20), 2020. [62] P. Qian, H. Wu, Z. Du, T. Vural, D. Rong, Z. Cao, L. Zhang, Y. Wang, J. Chen, and Q. He, “Mufuzz: Sequence-aware mutation and seed mask guidance for blockchain smart contract fuzzing,” in 2024 IEEE 40th International Conference on Data Engineering (ICDE). IEEE, 2024, pp. 1972–1985. [63] J. He, M. Balunović, N. Ambroladze, P. Tsankov, and M. Vechev, “Learning to fuzz from symbolic execution with application to smart contracts,” in Proceedings of the 2019 ACM SIGSAC conference on computer and communications security, 2019, pp. 531–548.

Related documents

Record · ID 1640067 · SHA-256 06689416f7247def
Retrieved via Conceptio: every document is proof-bundled with source, license, and retrieval metadata.
Bring this data into your agent: Connect via MCP or API · 20 free credits to start · no card required
Read the Docs → · View CLI source on GitHub · Conceptio Open Knowledge Archive