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

74357 sc low unresolvable game state when proof threshold 2 and deadline is missed in aggregateverifier

Submitted on Apr 22nd 2026 at 00:48:21 UTC by @CarlosMB for Audit Comp | Base Azul

  • Report ID: #74357

  • Report Type: Smart Contract

  • Report severity: Low

  • Target: https://github.com/base/contracts/tree/v8.1.0/src/multiproof

  • Impacts:

    • Permanent freezing of funds in the bridge or in dispute game bonds with no available recovery path

Description

Target

src/multiproof/AggregateVerifier.sol

Summary

When PROOF_THRESHOLD = 2, AggregateVerifier can enter a state with no reachable terminal resolution if the second proof is not submitted before the gameOver() deadline.

In this scenario, the contract simultaneously prevents:

  • submission of additional proofs (due to timeout),

  • resolution of the dispute game (due to insufficient proofs),

  • and recovery of bonded funds (due to unresolved state).

As a result, the dispute game remains stuck in IN_PROGRESS, and the bonded funds are not recoverable through any available contract path.

Description

The AggregateVerifier contract enforces a minimum number of proofs (PROOF_THRESHOLD) before a dispute game can be resolved.

When configured with:

PROOF_THRESHOLD = 2

the proposer must submit two valid proofs within the allowed time window.

However, if only one proof is submitted and the deadline expires:

1. Additional proofs are rejected

Once gameOver() is true, no further proofs can be submitted.

2. The game cannot be resolved

Since only one proof exists, resolve() becomes unreachable.

3. Funds cannot be reclaimed

Because resolve() is never executed, resolvedAt remains zero indefinitely.

Resulting State

This leads to a deadlock condition:

  • status == IN_PROGRESS

  • resolvedAt == 0

  • proofCount < PROOF_THRESHOLD

  • gameOver() == true

No function can transition the game to a terminal state.

Impact

  • The dispute game can remain permanently unresolved.

  • Bonded funds deposited during initialization cannot be reclaimed through any available contract path.

  • The timeout mechanism does not provide a terminal recovery path when the proof threshold is not met.

This behavior indicates that the dispute game state machine does not guarantee a terminal outcome once initiated.

Severity Justification

This issue may qualify under the program’s Critical category: “Permanent freezing of funds in dispute game bonds with no available recovery path” because once this state is reached, the bonded funds cannot be recovered through any available contract path.

The final classification may depend on whether the protocol treats incomplete proof submission as an intended forfeiture condition or expects all dispute games to eventually reach a terminal state.

Regardless of classification, the issue leaves the game unresolved and the bond inaccessible.

Proof of Concept

The following PoC demonstrates:

  1. successful initialization with a single proof and bond deposit

  2. expiration of the submission window

  3. rejection of additional proofs

  4. inability to resolve

  5. inability to reclaim funds even after extended time

The following PoC was executed using the full project repository and real contract implementation from the in-scope codebase.

The test instantiates an AggregateVerifier implementation with PROOF_THRESHOLD = 2 and deploys a clone using the same CWIA (Clones With Immutable Arguments) pattern used in production.

A minimal verifier implementation is used to isolate the state machine behavior without altering the execution flow of AggregateVerifier.

No mocking of AggregateVerifier logic is performed.

Expected Output

Root Cause

The issue arises because:

  • verifyProposalProof() blocks additional proofs after timeout

  • resolve() requires proofCount >= PROOF_THRESHOLD

  • claimCredit() requires resolvedAt != 0

  • There is no fallback path for: gameOver() == true && proofCount < PROOF_THRESHOLD

Recommendation

Allow the game to transition to a terminal state when the deadline has passed but the proof threshold is not met.

Example:

Any equivalent terminal-state transition would also resolve the issue, provided it guarantees settlement and prevents funds from remaining indefinitely locked.

This behavior shows that the dispute game state machine does not guarantee a terminal outcome once initiated.

Was this helpful?