Early rate$2,400 of senior audit time for $500. Early members keep the rate as it climbs.$2,400 of senior audit time for $500See how →
F-2026-0023·missing-validation

One juror can hold several concurrent panels on a single stake

Openescrowarbitrationdispute-resolution
TL;DR

Introduced by the fix for panel grinding: frozen snapshot members are re-checked at seating for activity and stake but not for existing assignments. One juror can be drawn onto several concurrent panels on a single stake, so per-case economic security and panel independence are lost.

Severity
MEDIUM
Impact
MEDIUM
Likelihood
MEDIUM
Method
MManual review
CAT.
Complexity
MEDIUM
Exploitability
MEDIUM
02Section · Description

Description

The request-time eligibility snapshot freezes the drawable population when a case is armed, which is what closes the panel-grinding route. At seating, members of that frozen list are re-checked by _isLiveSnapshotMember, which tests only that the juror is still active and still meets their tier's stake floor.

It does not test activeAssignments. The request-time filter does exclude jurors already serving, but that check is evaluated once, when the case is armed. A juror who is seated onto another case after this case was armed therefore remains drawable here.

Whenever several cases are armed before any of them seats — the normal shape of concurrent disputes, since arming and seating are separate transactions — their frozen snapshots overlap, and the same juror can be drawn onto every one of them.

Before the snapshot change, selection re-read activeAssignments at seating, so a juror locked onto one case could not be drawn onto a second. In the same scenario on the previous commit the two panels shared no jurors; on the current one they share a juror.

Vulnerable Scenario: The following steps help understand the issue:

  1. Four disputes are raised and each case is opened, so four snapshots are captured while every juror is idle and therefore eligible for all four.
  2. The coordinator delivers the four random words.
  3. Each case is seated. Nothing prevents the same juror being drawn for more than one of them.
  4. One juror is seated on all four panels, holding four concurrent assignments against a single minimum stake.

Measured with eight jurors in the pool and four cases seated: one juror held 4 of 4 panels at once, backed by a single 25,000 cNGN stake. Across the four quorum failures that followed, that juror was slashed four times for 2,666 cNGN in total — comfortably inside their stake, so the collateral is never exhausted and nothing reverts.

03Section · Impact

Impact

Economic security per case is no longer backed by a dedicated stake. The deterrent assumed for a panel is one juror's stake at risk on that panel; when one juror sits on several panels, the same stake is counted once per case. Corrupting or bribing that juror reaches every dispute they sit on for the price of influencing one, and their slashing exposure never rises to match.

Panel independence is also lost. Two disputes intended to be decided by separate randomly drawn panels can share a majority of their members, so an error or bias by one juror propagates across concurrent cases rather than being confined to one.

Both effects scale with how many cases are armed before seating, and concurrency is the expected operating state rather than an edge case.

04Section · Recommendation

Recommendation

Re-check activeAssignments when a frozen member is tested at seating, alongside the active and stake-floor checks already in _isLiveSnapshotMember. That keeps the property the snapshot exists to provide — the drawable set can only shrink after the word is delivered, never grow — while restoring the one-panel-at-a-time invariant that selection previously enforced.

Excluding busy members can shrink a snapshot below panel size, which the existing underfill path already handles by requeueing for a fresh word rather than seating a short panel, so the convergence behaviour verified for the snapshot design continues to apply.

05Section · Resolution

Resolution

Open. Not fixed at the time of publication.

06Section · Affected files

Affected files

  • lib/ArbitrationPoolSelectLib.sol — _isLiveSnapshotMember, the filter applied to a frozen snapshot at seating
  • lib/ArbitrationPoolSelectLib.sol — captureEligible / _isEligibleAtRequest, which does exclude activeAssignments at request time
  • ArbitrationPool.sol — _seat / _openCaseInternal, which locks each seated juror
F-2026-0023