@sdk.markets/sdk is currently a preview package. These docs show the SDK surface we're building toward.Join the waitlist
markets sdk

Settlement

Finalizing a market and redeeming winnings.

Once the challenge window elapses without a successful dispute, the market is ready to finalize. Finalization routes fees and moves the market to Finalized; winners then claim pro‑rata payouts.

Finalizing

if (await client.markets.canFinalize(marketAddress)) {
  await client.markets.finalize({ marketAddress });
}

Permissionless — anyone can call it. Requires:

  • Status is ResolvedPendingFinality.
  • The challenge window has fully elapsed.

In one transaction the contract computes creator + platform fees against the total pool, transfers them, flips status to Finalized, and emits MarketFinalized + FeesPaid.

Because it's permissionless, most hosts run a lightweight cron that finalizes ripe markets so participants don't pay gas on a housekeeping call before redeeming. A minimal worker:

import { MarketsClient } from "@sdk.markets/sdk";

const client = new MarketsClient({ publicClient, walletClient });

for (const address of knownMarketAddresses) {
  if (await client.markets.canFinalize(address)) {
    await client.markets.finalize({ marketAddress: address });
    console.log("finalized", address);
  }
}

Redeeming

await client.markets.redeem({ marketAddress });

Available only on Finalized markets. Pays the caller their pro‑rata share of the post‑fee pool, computed against their stake on the winning option.

Payout formula:

payout = userStake[winningOption]
       * (totalPool - creatorFee - platformFee)
       / optionPool[winningOption]
  • Callers with zero stake on the winning option revert. They didn't win.
  • Each address can redeem once per market; hasRedeemed[caller] guards re‑entry.
  • Rounding is standard integer division — dust accrues to the contract and is unrecoverable. This is typically single‑digit wei and not worth addressing.

Emits:

event Redeemed(address user, uint256 payoutAmount);

Refunding (voided markets)

If the market voided instead of finalizing, use refund() instead of redeem(). See disputes.

A worked example

Market with three participants on a two‑option question, 1% creator fee, 1% platform fee (combined 200 bps = 2%):

ParticipantStakeOption
A100 USDCYes
B200 USDCYes
C300 USDCNo

Total pool: 600 USDC. Winning option: Yes. Fees: 2% × 600 = 12 USDC. Payout pool: 588 USDC.

  • A redeems 100 / 300 × 588 = 196 USDC (net +96).
  • B redeems 200 / 300 × 588 = 392 USDC (net +192).
  • C redeems nothing (net −300).

Creator receives 6 USDC, platform receives 6 USDC.

Edge cases

  • No winners. If nobody staked on the winning option, optionPool[winningOption] is zero and redeem would divide by zero. In practice this is impossible in any market with real activity, but if you're stress‑testing: the contract reverts on redeem and no payouts go out. The pool remains locked. Hosts should surface this in UI as a "bad market" case and steer creators away from options nobody picks.
  • Partial redeem is not supported. redeem pays the full winning‑option stake share in one call.
  • Stakes across options. If a participant staked on both the winning and a losing option, only the winning stake counts toward the redeem computation. The losing stake is absorbed into the pool like any other losing stake.

On this page