Skip to main content

Settlement

Settlement is the process of distributing winnings after a market resolves. This document covers the settlement flow, payout calculations, and claiming process.

Settlement Flow

Payout Rules

Winner Calculation

OutcomeWinning SharePayout per Share
UPYES1.0000 USDC
DOWNNO1.0000 USDC

Loser Calculation

Losing shares have no redemption value:

OutcomeLosing SharePayout per Share
UPNO0 USDC
DOWNYES0 USDC

Position Settlement

Settlement Transaction

pub fn settle_position(ctx: Context<SettlePosition>) -> Result<()> {
    let market = &ctx.accounts.market;
    let position = &ctx.accounts.position;

    require!(market.outcome.is_some(), SeesawError::MarketNotResolved);

    let payout = match market.outcome.unwrap() {
        Outcome::Up => position.yes_shares,
        Outcome::Down => position.no_shares,
    };

    // Transfer payout from vault to user
    transfer_tokens(
        &ctx.accounts.vault,
        &ctx.accounts.user_token_account,
        payout,
    )?;

    // Close position account, return rent
    close_account(
        &ctx.accounts.position,
        &ctx.accounts.user,
    )?;

    Ok(())
}

Example Scenarios

Scenario 1: Full Win

Alice's Position:
├── YES shares: 100
├── NO shares: 0
└── Cost basis: 60 USDC (bought at 0.60)

Market resolves: UP

Payout: 100 × 1.00 = 100 USDC
Profit: 100 - 60 = 40 USDC (67% return)

Scenario 2: Full Loss

Bob's Position:
├── YES shares: 0
├── NO shares: 50
└── Cost basis: 20 USDC (bought at 0.40)

Market resolves: UP

Payout: 0 × 1.00 = 0 USDC
Loss: 20 USDC (100% loss)

Scenario 3: Mixed Position

Carol's Position:
├── YES shares: 80
├── NO shares: 30
└── Cost basis: 55 USDC

Market resolves: UP

Payout: 80 × 1.00 = 80 USDC
NET profit: 80 - 55 = 25 USDC

Solvency Guarantee

The protocol can always pay winners because:

  1. Every share is backed by collateral
  2. Vault holds max(yes, no) USDC
  3. Only one side wins

Claiming Process

Via Web App

  1. Navigate to Portfolio tab
  2. Find resolved markets with claimable positions
  3. Click Claim button
  4. Approve transaction in wallet
  5. USDC and rent transferred to wallet

Via CLI

seesaw settle \
  --market <MARKET_ADDRESS> \
  --position <POSITION_ADDRESS>

Via SDK

import { settlePosition } from '@seesaw/sdk';

const tx = await settlePosition({
  market: marketPubkey,
  user: userPubkey,
});

await sendAndConfirmTransaction(connection, tx, [userKeypair]);

Batch Settlement

For efficiency, positions can be settled in batches:

Crank operators typically batch settlements for gas efficiency.

Rent Recovery

Position accounts are closed during settlement:

Account Lifecycle:
├── Created: User pays ~0.002 SOL rent
├── Active: Holds position data
└── Closed: Rent returned to user

Net cost: 0 SOL (rent fully recovered)

Edge Cases

Zero Position

If a position has 0 shares of both types:

  • No payout (0 USDC)
  • Account still closes
  • Rent returned

Unclaimed Positions

Positions can be claimed anytime after resolution:

  • No expiration on claims
  • Market stays open until all claimed
  • Crank incentive for settlement

Already Settled

If settle_position called twice:

  • First call succeeds
  • Second call fails (account doesn't exist)
  • No double-payment possible

Market Closure

After all positions settled:

Close Conditions

  1. Market is RESOLVED
  2. All position accounts settled (closed)
  3. Vault balance is 0

Rent Distribution

AccountRent Returns To
MarketMarket creator
VaultMarket creator
OrderbookMarket creator
PositionPosition owner

Settlement Fees

Seesaw charges no settlement fee:

OperationFee
Settlement0%
RentReturned
ClaimGas only

This maximizes user returns and encourages participation.