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.
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:
- Created
- BuyerFunded
- SellerFunded
- MarkShipped
- 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