> ## Documentation Index
> Fetch the complete documentation index at: https://docs.testnet.dev.adipredictstreet.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Settlement flow

> Per-market-type timelines from event end to USDC distribution.

Binary and neg-risk markets follow **different** on-chain settlement
paths. Pick the section that applies to the market type you're
integrating.

## Binary markets — propose → challenge → finalize

| T+         | Event                         | Owner          | Side-effect                                            |
| ---------- | ----------------------------- | -------------- | ------------------------------------------------------ |
| 0          | Real-world event concludes    | —              | Match result available at source                       |
| \~15 min   | Oracle posts `proposeOutcome` | oracle-service | `PredictStreetOracle` emits `OutcomeProposed`          |
| 16 min     | Challenge window opens        | Contract       | Book writes paused for this market                     |
| 16–136 min | Challenge can be lodged       | Any user       | 10 USDC bond required                                  |
| 136 min    | Challenge window closes       | Contract       | If no challenge → ready to finalise                    |
| 137 min    | `finalizeOutcome`             | oracle-service | `ConditionalTokens.reportPayouts`, redemption unlocked |

### Step 1 — Oracle source check

The market is configured (at admin authoring) with one or more data
sources. When the configured source(s) yield an unambiguous outcome,
the market becomes ready to propose. When data is unavailable or
ambiguous (no safe majority across configured sources), the market
moves to `DELAYED`. See
[Void & delayed](/concepts/settlement/void-delay).

### Step 2 — On-chain proposal

```solidity theme={null}
PredictStreetOracle.proposeOutcome(
    bytes32 questionId,
    uint256[] payouts
) external onlyAdmin;
```

### Step 3 — Challenge window

```solidity theme={null}
PredictStreetOracle.challengeOutcome(
    bytes32 questionId,
    bytes32 bondSnapshotHash
) external;
```

Only the first challenge is accepted.

### Step 4a — No challenge, finalise

```solidity theme={null}
PredictStreetOracle.finalizeOutcome(bytes32 questionId) external onlyAdmin;
```

Internally calls `ConditionalTokens.reportPayouts`, unlocking
redemption.

### Step 4b — Challenge, re-verify

```solidity theme={null}
resolveChallengeConfirm(questionId)
resolveChallengeOverride(questionId, newPayouts)
voidMarket(questionId)
```

## Neg-risk markets — direct winner-index report

Neg-risk markets do **not** use the propose / challenge / finalize
lifecycle above. The path is shorter:

1. **Provider-side winner selection** — `oracle-service` selects the
   winning outcome index from the configured data source(s).
2. **On-chain winner report** — the winner index is reported on the
   neg-risk adapter; the contract resolves that outcome's token at
   1.0 and **all other outcomes resolve as losers (0.0)**.
3. **Redemption** — winning-token holders redeem on chain via
   `ConditionalTokens.redeemPositions` (or the `/api/me/redemptions`
   helper); credit lands the same way as for binary markets.

There is no challenge window on neg-risk. If a neg-risk market needs
to be voided post-report (data error, event abandonment), it follows
the same admin-authorised void path as binary — but the propose →
challenge → finalize cycle is not in scope here.

## What you observe as a partner

| Phase                      | Your REST              | Your WebSocket              |
| -------------------------- | ---------------------- | --------------------------- |
| Market `OPEN`              | Normal trading         | `orderbook` deltas          |
| Event close                | `status: CLOSED`       | `market.status` → `CLOSED`  |
| Proposal on-chain (binary) | → `PENDING_RESOLUTION` | `market.status`             |
| Finalised                  | → `RESOLVED`           | `oracle.market_resolved`    |
| Voided / cancelled         | → `VOIDED`             | `oracle.market_cancelled`   |
| Delayed                    | → `DELAYED`            | `market.status` with reason |

## Redemption

Two paths produce the same end state — partners can pick whichever is
operationally easier:

1. **On-chain self-service** — call `ConditionalTokens.redeemPositions`
   directly from your client. See the
   [ConditionalTokens contract page](/concepts/contracts/conditional-tokens#redeem-winning-positions)
   for the call signature. Useful when you're already running an
   on-chain submitter and want to stay homogeneous.

2. **Off-chain helper — `POST /api/me/redemptions`** — submits a
   redemption job that the platform's submitter executes on chain on
   your vault's behalf. Body shape:

   ```json theme={null}
   {
     "marketId":   "PM-WC26-WIN-FRA-WC26-1910V2",
     "indexSets":  [1, 2]
   }
   ```

   `indexSets` selects which outcome partitions to redeem (`[1]` for
   YES only, `[2]` for NO only, `[1,2]` for both). Returns
   `{ "redemptionId": "...", "status": "QUEUED" }` and the redemption
   completes asynchronously. Missing/invalid `marketId` returns
   `400 invalid_request`.

Either way, once the on-chain redemption confirms, chain-watcher picks
up the `PayoutRedemption` event and credits the resulting USDC to
your off-chain `/api/me/balances.collateral` automatically — partners
don't need to call any platform endpoint to "claim" winnings beyond
the initial redemption call.
