For the complete documentation index, see llms.txt. This page is also available as Markdown.

76301 bc insight base flashblocks eth simulatev1 pending state expansion enables remote node dos

Submitted on May 3rd 2026 at 18:58:35 UTC by @z41zen for Audit Comp | Base Azul

  • Report ID: #76301

  • Report Type: Blockchain/DLT

  • Report severity: Insight

  • Target: https://github.com/base/base/tree/v0.8.0-rc.28

  • Impacts:

    • Shutdown of greater than or equal to 30% of network processing nodes without brute force actions, but does not shut down the network

    • Increasing network processing node resource consumption by at least 30% without brute force actions, compared to the preceding 24 hours

Description

Brief/Intro

Base Flashblocks eth_simulateV1 expands the full Flashblocks pending state override into every requested simulated block before delegating to reth. A remote JSON-RPC client can send valid eth_simulateV1 requests using the pending block tag and force the node to clone and materialize the server-side pending state many times.

The request itself can be very small and can remain within reth's accepted max_simulate_blocks = 256 limit. In a controlled five-node fleet, six concurrent valid pending-state simulations against each target node made two independent nodes unreachable. That is 2/5 nodes, or 40% of the measured fleet.

Vulnerability Details

The affected code is in crates/execution/flashblocks/src/rpc/eth.rs.

When eth_simulateV1 is called with the pending block tag, Base reads the current Flashblocks pending state:

Base then prepends that pending state to every requested simulated block:

This creates O(number_of_requested_blocks * pending_state_size) server-side work before reth processes the request.

Reth does enforce a maximum number of simulated blocks:

However, the Base wrapper creates the expanded SimulatePayload before this reth validation is reached. For requests at the limit, such as 256 blocks, reth accepts the request and the node still performs the full pending-state expansion and simulation work.

The method is exposed on Base preconf endpoints. A benign over-limit request confirms that the public endpoints route to reth's eth_simulateV1 limit check:

Heavy measurements were performed only against controlled local targets.

Impact Details

The attacker does not need to send the large state. The expensive data is the server-side Flashblocks pending state, which Base copies into every requested simulated block.

At the maximum accepted block count, the JSON-RPC request body is only about 3.4 KiB:

Controlled five-node fleet measurement:

Observed concurrency threshold:

The 6-concurrent case satisfies the impact class for shutdown of greater than or equal to 30% of network processing nodes in the controlled fleet. I am not claiming total Base network shutdown.

https://gist.github.com/s-zaizen/8f982dc21ed74ac3cc473e4f869a4497

Proof of Concept

The PoC is provided as a secret Gist:

https://gist.github.com/s-zaizen/8f982dc21ed74ac3cc473e4f869a4497

To reproduce the lightweight confirmation:

The lightweight PoC confirms that Base materializes pending-state copies before reth's over-limit rejection:

The external-node availability harness used for the 30%+ fleet measurement is included in:

To reproduce the external-node path, use a separate checkout of Base at the target commit:

Single-node availability command:

For the 30%+ impact reproduction, run the same command on five independent nodes and monitor each node externally. The measured critical case used five independent nodes and made two nodes unreachable.

Observed Verification

Observed controlled-fleet output:

Selected node A output from the 6-concurrent case:

Selected node B output from the 6-concurrent case:

Observed single-node threshold output:

Observed local-node over-limit measurement highlights:

References

  • Base Flashblocks eth_simulateV1 wrapper:

    • crates/execution/flashblocks/src/rpc/eth.rs

    • https://github.com/base/base/blob/b7f44d73a3e353f3f0024d2fc55b9a48099c79f4/crates/execution/flashblocks/src/rpc/eth.rs

  • Lightweight pending-state materialization PoC:

    • main.rs

    • run_poc.sh

    • payload_size.py

  • External availability measurement harness:

    • simulate_v1_external_node.rs

    • measure_external_node.py

    • run_independent_node.sh

  • Critical controlled-fleet measurement log:

    • controlled-fleet-critical-measurement.log

  • Secret Gist containing the runnable PoC and evidence:

    • https://gist.github.com/s-zaizen/8f982dc21ed74ac3cc473e4f869a4497

Was this helpful?