Nector Smart Contract

Nector is implemented as a single on-chain program that manages the full lifecycle of an escrow order, including funding, delivery, dispute resolution, and timeout enforcement. The program is designed as a deterministic state machine, where every transition is governed by strict rules and economic constraints. All source code is open-source and publicly verifiable.

github

View Nector Smart Contract Code

The complete Nector smart contract source code (Rust, TypeScript and Keeper bots) is publicly accessible here. This is the exact same contract running in production on Nector.

View on GitHub →

Program Scope

The Nector smart contract handles the complete escrow lifecycle within a single program.

Core responsibilities include:

  • Order creation and initialization
  • Escrow funding (buyer and seller)
  • Delivery tracking (physical and digital)
  • Dispute initiation and resolution
  • Timeout enforcement
  • Bond and penalty logic
  • Fund distribution and settlement

The program is modular at the instruction level but operates as a unified system.

Core Accounts

The protocol relies on three primary accounts:

SellerAccount

A minimal seller profile used for:

  • Tracking order count
  • Deriving deterministic PDAs

Order

The main state container for each transaction.

Stores:

  • Buyer and seller addresses
  • Product type and mode
  • Price and bond configuration
  • Current state
  • Timestamps for each phase
  • Order index

This account represents the full lifecycle of a transaction.

EscrowAccount

A PDA-controlled account that holds locked funds.

Stores:

  • Associated order
  • Buyer address
  • Total amount locked

All escrowed lamports are held directly in this account.

State Machine

Each order follows a strict state transition model:

  1. Created
  2. BuyerFunded
  3. SellerFunded
  4. MarkShipped
  5. Completed

Alternative Paths

Cancellation

  • BuyerFunded → Cancelled
  • SellerFunded → Cancelled

Shipping Timeout

  • SellerFunded → ShippingTimedOut

Dispute Flow

  • MarkShipped → OpenDispute
  • OpenDispute → SellerResponded

From here:

  • No response → BuyerWonDispute
  • Seller refunds → Refunded
  • Buyer pays → Completed
  • No resolution → Draw

Instruction Set

The program exposes the following instructions:

Initialization

  • init_seller
  • create_order

Funding

  • buyer_fund_escrow
  • seller_fund_escrow

Order Control

  • buyer_cancel
  • seller_cancel
  • mark_shipped
  • confirm_delivery

Dispute

  • open_dispute
  • respond_dispute
  • refund_buyer
  • refund_during_discuss
  • pay_seller_during_discuss

Timeout & Resolution

  • shipping_timeout
  • confirm_timeout
  • buyer_win
  • draw

Fund Flow

The protocol uses native SOL (lamports) for all transactions.

Escrow Entry

Buyer funding:

  • Transfers product price + 20% bond to escrow
  • Pays platform fee separately

Seller funding:

  • Transfers bond based on mode
  • Pays platform fee

Escrow Exit

Funds are released based on outcome:

  • Completion → seller receives payment
  • Refund → funds returned
  • Buyer win → penalty applied
  • Draw → all funds transferred to platform

PDA Design

The program uses deterministic PDA derivation:

  • SellerAccount → [b"seller", seller_pubkey]
  • Order → [b"order", seller_pubkey, order_index]
  • Escrow → [b"escrow", order_pubkey]

Anchor handles bump validation internally.

Time Tracking

All timing logic is stored on-chain within the Order account.

Tracked timestamps include:

  • seller_funded_at
  • mark_shipped_at
  • open_dispute_at
  • seller_respond_at

These timestamps are used to validate timeout conditions.

Access Control

Access is enforced at the instruction level:

Buyer-only actions:

  • fund escrow
  • cancel (early)
  • confirm delivery
  • open dispute

Seller-only actions:

  • create order
  • fund escrow
  • mark shipped
  • respond to dispute
  • refund

Public actions (anyone can trigger):

  • timeout functions
  • dispute resolution transitions

This allows both users and external bots to execute state transitions.

Timeout Execution

Smart contracts cannot execute autonomously.

All timeout transitions require an external transaction.

Nector supports:

  • Keeper bots that monitor deadlines
  • Permissionless execution (anyone can trigger)

Each timeout is implemented as a separate instruction:

  • shipping_timeout
  • confirm_timeout
  • buyer_win
  • draw

Security Model

The contract does not attempt to verify real-world events.

Instead, it operates under the following assumptions:

  • Shipment is not verifiable on-chain
  • Product quality cannot be objectively validated
  • Users may act dishonestly

To compensate, the system relies on:

  • Bond staking
  • Time-based penalties
  • Economic loss in unresolved disputes

Limitations

The contract intentionally does not solve:

  • Proof of delivery
  • Product authenticity verification
  • Off-chain fraud
  • Subjective dispute resolution

Instead, it enforces:

  • Financial consequences for dishonest or inactive behavior.

Critical Design Choices

1. Bond Storage Limitation

The bond_lamports field is overwritten during funding.

This means:

  • Only the latest bond value is stored
  • Buyer and seller bonds are not tracked separately

2. Draw Outcome

In a draw:

  • All escrowed funds are transferred to the platform treasury.

This is an intentional design choice to:

  • Penalize unresolved disputes
  • Fund protocol development

However, it introduces:

  • A non-neutral incentive structure
  • A deviation from fully trustless designs