WHEN IT FAILS

When your app is challenged

Anyone can challenge a batch on Monad. Until the judges rule, nothing settles. Where the bench can rule on its own, your app keeps running and Monad catches up after the verdict.

A challenge names one committed batch and puts up a bond. The judges replay it, the validator and the challenger narrow the disagreement down to one transaction, and the bench votes. Until it does, nothing the node executed after that batch settles on Monad.

What your users see

Interlude can keep your app running through a dispute. It is switched on per app, off by default, and only where the bench’s judge bots can reach the vote on their own. Then calls answer as usual and the node queues its batches. It stops taking calls, until the verdict or until the reason goes, whenever the queue is at risk: a judge votes fraud, the validator’s move runs late, or too few bots answer with the vote a move away. Otherwise the app takes no calls until the verdict. Either way, put the banner on the page:

app/page.tsx
export const { DisputeBanner, useDispute } = createInterludeHooks(interlude);

function Header() {
  // One line, or nothing while there is no dispute. With a className, your styles only:
  // data-dispute carries the status.
  return <DisputeBanner className="notice" />;
}

// The same state without React:
const state = await interlude.dispute();
verifying
Verification in progress: this app keeps running, settlement on Monad resumes by 16:30. What you do meanwhile is confirmed by this app and settles after the verdict; it is rolled back if fraud is proven or no verdict comes in time.
frozen
Verification in progress: this app is paused until the judges rule
dismissed
Claim rejected by the judges: the challenger's bond was burned
fraud
Fraud proven: the validator was slashed and state after batch 40 was unwound

It reads the node’s health every 5 s, and the hub on Monad when the node cannot say. An outcome stays on screen for an hour.

What settles later

After a dismissal the node commits its queue in order, merged into as few batches as fit, and Monad catches up. settled waits through the whole dispute and never reports a queued call lost. waitSettled with a timeoutMs of your own ends with SettlementPausedError instead. Do not send a queued call again: it already ran.

The 2-hour cap

The node queues at most 2 hours of work, and 600 batches. Past that it takes no new calls until the verdict, and refuses them with SettlementPausedByDisputeError: nothing ran. What it queued keeps its place, and the banner says the app is paused.

Funds

Funds are never released from state that has not settled. The app’s delegated state stays locked on Monad through the dispute, and value only moves on Monad, so a cash-out made meanwhile pays once the verdict is in and the commit carrying it lands. If fraud is proven, the validator is slashed, every batch from the challenged one on is unwound, and the queue is dropped. If the judges do not vote in time, the session closes and the queue is dropped too. Either way settled rejects with SettlementLostError, reason: "dispute". The node shuts down with its session, so the SDK confirms the end on the hub before it says so, and asks the hub when the node stops answering.