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

75013 bc medium da backlog accounting misses encoded unpublished data causing mempool processing beyond configured throttle limits

Submitted on Apr 26th 2026 at 17:14:01 UTC by @OxPrince for Audit Comp | Base Azul

  • Report ID: #75013

  • Report Type: Blockchain/DLT

  • Report severity: Medium

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

  • Impacts:

    • Causing network processing nodes to process transactions from the mempool beyond set parameters

Description

Brief/Intro

The batcher DA throttle only counts user transactions that are still waiting to be encoded. Once a block is encoded into a channel, the same DA payload is no longer counted by da_backlog_bytes() even when it has not been published or confirmed on L1. As a result, the batch driver can tell the block builder to use unthrottled DA limits while unpublished DA backlog is already above the configured threshold, causing network processing nodes to process mempool transactions beyond the intended DA throttle parameters.

Vulnerability Details

The batcher exposes a DA throttle intended to reduce builder throughput when unsubmitted DA backlog exceeds a configured threshold. The default threshold is 1,000,000 bytes, and the default throttled limits are much lower than the unthrottled limits:

// crates/batcher/core/src/throttle.rs
threshold_bytes: 1_000_000,
block_size_lower_limit: 2_000,
block_size_upper_limit: 130_000,
tx_size_lower_limit: 150,
tx_size_upper_limit: 20_000,

The CLI documents the same behavior:

However, the driver drains encoding before applying the throttle:

The encoder's backlog function only counts blocks at and after block_cursor:

This excludes DA that has already been encoded into the current channel, ready channels, pending submissions, or in-flight L1 transactions. Those bytes are still unpublished and still consume DA capacity, but they are invisible to the throttle signal.

The vulnerable sequence is:

  1. User transactions create DA backlog above the configured throttle threshold.

  2. BatchDriver::run() calls drain_encoding() first.

  3. Encoding advances block_cursor and moves the bytes into unpublished channel/frame state.

  4. BatchDriver::run() then calls da_backlog_bytes().

  5. The backlog now reports 0 or an artificially low value.

  6. DaThrottle applies unthrottled builder limits even though unpublished DA backlog remains above the threshold.

This is not an admin misconfiguration. The default config enables throttling, and the bug appears in the normal driver/encoder accounting path.

Impact Details

The relevant set parameters are the DA throttle limits configured through ThrottleConfig and applied to the block builder. When backlog is above the threshold, the system is expected to reduce builder DA limits. With the default config, the relevant difference is:

Condition
max_tx_size
max_block_size

Throttled

150

2,000

Unthrottled

20,000

130,000

The PoC demonstrates a state where unpublished DA backlog is above 1 MB, but the driver still applies the unthrottled limits (20,000, 130,000). This means the builder can continue accepting and processing mempool transactions at normal DA size limits even though the throttle condition is already met.

The practical security risk is liveness degradation under L1 publication pressure. If L1 submissions are delayed, blocked, or slow to confirm, encoded unpublished DA can accumulate while the builder continues producing blocks at unthrottled DA limits. This defeats the backpressure mechanism that is supposed to keep DA publication backlog bounded.

References

  • crates/batcher/core/src/driver.rs: BatchDriver::run() drains encoding before throttle application.

  • crates/batcher/encoder/src/encoder.rs: BatchEncoder::da_backlog_bytes() only counts blocks after block_cursor.

  • crates/batcher/core/src/throttle.rs: default throttle threshold and throttled/unthrottled DA limits.

  • bin/batcher/src/cli.rs: CLI documents that DA backlog above threshold should reduce block throughput.

Proof of Concept

poc_driver_leaves_builder_unthrottled_with_unpublished_da_backlog

Was this helpful?