Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 66 additions & 101 deletions docs/nitrolite/learn/core-concepts/challenge-response.mdx
Original file line number Diff line number Diff line change
@@ -1,155 +1,120 @@
---
sidebar_position: 4
title: Challenge-Response & Disputes
description: How Yellow Network handles disputes and ensures fund safety
title: Challenge & Recovery
description: How Yellow Network lets participants recover funds when a counterparty stops cooperating
keywords: [challenge, dispute, security, settlement, fund recovery]
---

import Tooltip from '@site/src/components/Tooltip';
import { tooltipDefinitions } from '@site/src/constants/tooltipDefinitions';

:::warning[Work in Progress]
This page was carried over from the v0.5.x documentation and has not yet been fully updated for v1.x. Some terminology, code examples, and API references may be outdated. An update is in progress.
:::

# Challenge-Response & Disputes
# Challenge & Recovery

In this guide, you will learn how Yellow Network resolves disputes and ensures your funds are always recoverable.
A challenge is the on-chain fallback that lets a participant recover from an unresponsive or broken counterparty.

**Goal**: Understand the security guarantees that make off-chain transactions safe.
**Goal**: understand why off-chain updates remain recoverable even when Nitronode is unavailable.

---

## Why Challenge-Response Matters
## Why Challenges Matter

In any off-chain system, a critical question arises: **What if someone tries to cheat?**
In any off-chain system, a critical question arises: what if the counterparty stops signing, stops responding, or tries to use an on-chain state you disagree with?

<Tooltip content={tooltipDefinitions.channel}>State channels</Tooltip> solve this with a challenge-response mechanism:
<Tooltip content={tooltipDefinitions.channel}>State channels</Tooltip> answer this with versioned, signed states:

1. Anyone can submit a <Tooltip content={tooltipDefinitions.channelState}>state</Tooltip> to the blockchain
2. Counterparties have time to respond with a newer state
3. The newest valid state always wins
4. Funds are distributed according to that state

---
1. Old states cannot replace newer states because versions must increase.
2. A participant can enforce a signed <Tooltip content={tooltipDefinitions.channelState}>state</Tooltip> on-chain when cooperation fails.
3. If a challenge is active, the counterparty has a response window to enforce a newer valid state.
4. If no newer state is accepted before the window expires, the challenged state can be closed.

## The Trust Model
## Trust Model

State channels are **trustless** because:

| Guarantee | How It's Achieved |
|-----------|-------------------|
| **Fund custody** | Smart contract holds funds, not Clearnode |
| **State validity** | Only signed states are accepted |
| **Dispute resolution** | On-chain fallback if disagreement |
| **Recovery** | You can always get your funds back |

---
| Guarantee | How it is achieved |
| --- | --- |
| **Fund custody** | ChannelHub holds channel funds on-chain, not Nitronode. |
| **State validity** | Only states signed by the required participants, with a greater version and correct intent, can advance the channel. |
| **Dispute resolution** | A participant can force the latest valid state on-chain. |
| **Recovery** | Funds are recoverable from the latest enforceable state. |

## Channel Dispute Flow
## Channel Challenge Flow

### Scenario: Clearnode Becomes Unresponsive
### Scenario: Nitronode becomes unresponsive

You have a <Tooltip content={tooltipDefinitions.channel}>channel</Tooltip> with 100 USDC. The <Tooltip content={tooltipDefinitions.clearnode}>Clearnode</Tooltip> stops responding.
You have a <Tooltip content={tooltipDefinitions.channel}>channel</Tooltip> with 100 USDC. Nitronode stops responding.

**Your options:**
Your options:

1. Wait for Clearnode to recover
2. Force settlement on-chain via challenge
1. Wait for Nitronode to recover.
2. Submit the latest mutually signed state on-chain and start the challenge path.

### The Process
### Process

1. **Initiate Challenge**: Submit your latest signed state to the blockchain
2. **Challenge Period**: Contract sets a timer (e.g., 24 hours)
3. **Response Window**: Counterparty can submit a newer state
4. **Resolution**: After timeout, challenged state becomes final
1. **Initiate challenge**: submit a mutually signed state to ChannelHub with a challenger signature.
2. **Challenge period**: ChannelHub sets the response deadline.
3. **Response window**: a counterparty can enforce a newer mutually signed state.
4. **Resolution**: a newer state returns the channel to `open`; after timeout, the challenged state can be closed.

```mermaid
stateDiagram-v2
[*] --> ACTIVE
ACTIVE --> DISPUTE: challenge()
DISPUTE --> ACTIVE: checkpoint() with newer state
DISPUTE --> FINAL: Timeout expires
FINAL --> [*]

note right of DISPUTE: Anyone can submit<br/>newer valid state
```
[*] --> open
open --> challenged: challenge
challenged --> open: enforce newer state
challenged --> closed: close after timeout
closed --> [*]

---
note right of challenged: A newer valid state<br/>can defeat the challenge
```

## Why This Works

### States Are Ordered
### States are ordered

Every state has a version number. A newer (higher version) state always supersedes older states.
Every channel state has a version number. ChannelHub rejects stale submissions that do not advance the version beyond the state already recorded on-chain.

### States Are Signed
### States are signed

With the default SimpleConsensus adjudicator, both parties must sign every state. If someone signed a state, they can't later claim they didn't agree.
The default v1 channel path requires both user and node signatures for enforceable states. A party that signed a state cannot later deny that signature.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a matter of fact, for a state to be valid, it must be signed by both a user and the Node. Therefore, this sentence should be reformulated.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kept this explicit: the default v1 enforceable channel path requires both user and Node signatures. 5d2508e


:::note Other Adjudicators
Different adjudicators may have different signing requirements. For example, a Remittance adjudicator may only require the sender's signature. The signing rules are defined by the channel's adjudicator contract.
:::

### Challenge Period Provides Fairness
### Challenge period provides fairness

The waiting window ensures honest parties have time to respond. Network delays don't cause losses.
The waiting window gives honest parties time to respond. Network delays should not cause immediate loss of funds.

### On-Chain Contract is Neutral
### ChannelHub is neutral

The smart contract accepts any valid signed state, picks the highest version, and distributes funds exactly as specified.
ChannelHub validates signatures, state version, status, and ledger invariants. It does not rely on Nitronode cooperation once a valid state is submitted.

---
## Enforcement vs Challenge

## Challenge Period Selection
| Operation | Purpose | Channel status |
| --- | --- | --- |
| Enforce a signed state | Record a valid state without starting the dispute path. | Stays `open`. |
| `challenge()` | Start the on-chain dispute path. | Changes to `challenged`. |

| Duration | Trade-offs |
|----------|------------|
| **1 hour** | Fast resolution, tight response window |
| **24 hours** | Balanced (recommended) |
| **7 days** | Maximum safety, slow settlement |

The Custody Contract enforces a minimum of 1 hour.

---

## Checkpoint vs Challenge

| Operation | Purpose | Channel Status |
|-----------|---------|----------------|
| `checkpoint()` | Record state without dispute | Stays ACTIVE |
| `challenge()` | Force dispute resolution | Changes to DISPUTE |

Use checkpoint for safety snapshots. Use challenge when you need to force settlement.

---
Use ordinary state enforcement when you only need the chain to record a newer state. Use challenge when you need to force recovery because a counterparty is not cooperating.

## What Happens If...

| Scenario | Outcome |
|----------|---------|
| **Clearnode goes offline** | Challenge with latest state, withdraw after timeout |
| **You lose state history** | Challenge with old state; counterparty submits newer if they have it |
| **Counterparty submits wrong state** | Submit your newer state via checkpoint |
| **Block reorg occurs** | Replay events from last confirmed block |

---
| --- | --- |
| **Nitronode goes offline** | Challenge with the latest signed state, then close after timeout. |
| **You lose state history** | An older state can be defeated by a newer valid state if the counterparty has it. |
| **Counterparty submits a stale state** | ChannelHub rejects it if it does not have a higher version than the current on-chain state. |
| **Counterparty challenges with a stale state** | Enforce a newer valid state during the challenge window to resolve the challenge. |
| **Block reorg occurs** | Wait for the transaction to be included in the canonical chain again. No special challenge action is required only because of a reorg. |

## Key Takeaways

| Concept | Remember |
|---------|----------|
| **Challenge** | Force on-chain dispute resolution |
| **Response** | Submit newer state to defeat challenge |
| **Timeout** | After period, challenged state becomes final |
| **Checkpoint** | Record state without dispute |

:::success Security Guarantee
You can **always** recover your funds according to the latest mutually signed state, regardless of counterparty behavior.
| --- | --- |
| **Challenge** | Starts on-chain dispute resolution. |
| **Response** | A newer mutually signed state resolves an older challenged state. |
| **Timeout** | The time window during which a challenge can be resolved. After expiry, the challenged state can be closed. |
| **Enforcement** | Records state without starting the dispute path. |

:::success Security guarantee
You can recover funds according to the latest enforceable state even if the off-chain counterparty stops cooperating.
:::

---

## Deep Dive

For protocol details, see the [App Layer](/nitrolite/protocol/introduction) section.
For protocol details, see [Enforcement and Settlement](/nitrolite/protocol/enforcement-and-settlement).
Loading
Loading