TrustMarket
Documentation

TrustMarket Docs

TrustMarket DEX is a decentralized P2P marketplace on Stellar Soroban. Trade trustlessly with automated escrow, decentralized arbitration, and permanent reputation.

What is TrustMarket?

TrustMarket DEX is a decentralized peer-to-peer (P2P) marketplace built on the Stellar network using Soroban smart contracts. It enables trustless trading between parties with:

Secure Escrow
Funds locked in smart contracts until trade completion
Dispute Resolution
Decentralized arbitration for fair conflict resolution
Reputation System
On-chain soulbound TRUST tokens for proven traders
Zero Middlemen
Direct P2P trading with no custodial risk

Network: Stellar Testnet  |  Language: Rust (Soroban)  |  Frontend: Next.js + TypeScript  |  Token: TRUST (Soulbound)

System Architecture

TrustMarket uses a modular smart contract architecture with 5 core contracts working together:

1
MarketplaceFactory
Central registry — deploys escrow contracts, tracks all trades, manages admin functions.
2
TradeEscrow
Per-trade contract — holds funds, manages lifecycle (lock → deliver → confirm → payout).
3
DisputeOracle
Arbitration system — handles disputes, assigns arbitrators, enforces majority vote resolution.
4
ReputationToken
Soulbound token — mints non-transferable TRUST tokens on successful trades, tracks arbitrator eligibility.
5
FeeVault
Treasury — collects platform fees (1%) from completed trades.

Pattern: The Factory pattern is used — MarketplaceFactory deploys a new TradeEscrow contract for each trade. Each escrow is an independent contract with its own state and funds.

Trade Flow

Every trade on TrustMarket follows a structured lifecycle managed by smart contracts:

1
Create TradeCreated

Seller creates a trade listing with price, description, and token type. A new TradeEscrow contract is deployed via the MarketplaceFactory.

2
Lock FundsFunded

Buyer reviews the trade and locks funds into the escrow smart contract. Tokens are transferred from the buyer's wallet to the escrow contract address.

3
Mark DeliveredDelivered

Seller marks the item or service as delivered. This is an optional step to signal to the buyer that fulfillment is complete.

4
Confirm DeliveryCompleted

Buyer confirms they received the item/service. This triggers automatic payout: seller receives 99% and 1% fee goes to the FeeVault.

D
Dispute (if needed)Disputed

Either party can raise a dispute at any time after funding. The DisputeOracle assigns arbitrators who vote on the resolution.

Timeout: If the seller doesn't act within 7 days after funding, the buyer can claim a full refund using claim_expired().

Escrow System

Each trade has its own isolated TradeEscrow contract. This ensures fund security — no single point of failure and no pool of user funds.

Escrow States

Created
Funded
Delivered
Completed
Disputed
Resolved
Cancelled
Expired

Key Functions

rust
// Initialize escrow with trade details
fn init(trade_id, buyer, seller, token, amount, ...)

// Buyer locks funds into escrow
fn lock_funds() -> Result<(), EscrowError>

// Seller marks delivery complete
fn mark_delivered() -> Result<(), EscrowError>

// Buyer confirms, triggers payout (99% seller + 1% fee)
fn confirm_delivery() -> Result<(), EscrowError>

// Raise a dispute (buyer or seller)
fn initiate_dispute(caller, reason) -> Result<u64, EscrowError>

// Cancel trade (buyer only, before funding)
fn cancel() -> Result<(), EscrowError>

// Refund if trade expired (7 day timeout)
fn claim_expired() -> Result<(), EscrowError>

Security: Only the buyer can lock funds and confirm delivery. Only the seller can mark as delivered. Only the DisputeOracle can resolve disputes. Functions enforce role-based access control via require_auth().

Marketplace Factory

The MarketplaceFactory is the central hub of TrustMarket. It deploys new escrow contracts and maintains a registry of all trades.

Capabilities

  • Deploy new TradeEscrow contracts per trade
  • Track all trades with unique IDs
  • Map user addresses to their trade history
  • Store trade metadata (buyer, seller, amount, status, escrow address)
  • Admin can pause/unpause the factory
  • Admin can update the escrow WASM hash for upgrades
rust
// Create a new trade (deploys escrow contract)
fn create_trade(
    buyer: Address,
    seller: Address,
    token: Address,
    amount: i128,
    description: Symbol,
) -> Result<(trade_id, escrow_address), FactoryError>

// Get trade info by ID
fn get_trade(trade_id: u64) -> TradeInfo

// Get all trade IDs for a user
fn get_user_trades(user: Address) -> Vec<u64>

// Get total number of trades
fn get_trade_count() -> u64

Dispute Resolution

The DisputeOracle contract provides a decentralized arbitration system. When a trade dispute is raised, trusted arbitrators review the case and vote on the outcome.

How Disputes Work

1

Either the buyer or seller calls initiate_dispute() on the escrow contract with a reason (max 32 chars).

2

The DisputeOracle creates a dispute record, randomly selects arbitrators from the eligible pool (excluding buyer & seller).

3

Arbitrators see the assigned dispute on the /arbitrate page and cast their votes (BuyerWins, SellerWins, or Split).

4

Once enough votes are collected (majority wins), the resolution is enforced and funds are distributed accordingly.

Resolution Outcomes

Buyer Wins
100% of funds returned to the buyer. Seller loses 50 TRUST.
Seller Wins
Seller receives full payment (minus 1% fee). Buyer loses 50 TRUST.
Split (50/50)
Funds split equally. Both parties lose 25 TRUST.

Arbitrator Panel

The Arbitrator Panel (/arbitrate) is where trusted community members manage disputes. To become an arbitrator, you must earn 100+ TRUST tokens through successful trading.

How to Become an Arbitrator

1
Earn TRUST Tokens
Complete trades to earn TRUST. Seller gets +10 per trade, Buyer gets +5 per trade.
2
Reach 100 TRUST
Accumulate at least 100 TRUST tokens — the minimum eligibility threshold for arbitration.
3
Register on /arbitrate
Click "Register as Arbitrator" — calls reputation_token.register_arbitrator() on-chain.
4
Get Assigned
You're now in the eligible pool. When disputes arise, arbitrators are randomly selected from this pool.

Arbitrator Selection Algorithm

rust
fn select_arbitrators(env, buyer, seller) -> Vec<Address> {
    // 1. Get ALL registered arbitrators
    let all_arbitrators = storage.get(Arbitrators);

    // 2. Filter: remove buyer & seller, check active status & min TRUST
    let eligible = all_arbitrators.filter(|a| {
        a != buyer &&
        a != seller &&
        a.is_active &&
        reputation.balance(a) >= MIN_TRUST_THRESHOLD  // 100 TRUST
    });

    // 3. Random selection using ledger timestamp as seed
    let seed = ledger.timestamp() ^ ledger.sequence();
    let selected = pick_n_random(eligible, PANEL_SIZE, seed);
    // PANEL_SIZE = 1 (testnet) | 3 (production)

    return selected;
}

TRUST Rewards & Penalties

EventWhoTRUST Change
Trade CompletedSeller+10 TRUST
Trade CompletedBuyer+5 TRUST
Dispute: LoseLosing Party-50 TRUST
Dispute: SplitBoth Parties-25 TRUST each
Admin Mint (testnet)Any addressCustom amount

Voting Flow on /arbitrate

View Disputes
Assigned disputes appear on your panel with trade details and reason.
Cast Vote
Vote BuyerWins, SellerWins, or Split (50/50) for each assigned case.
Auto Resolve
Once majority votes are in, funds are distributed on-chain automatically.

Admin Mint Tool (Testnet Only)

The /arbitrate page includes an Admin Mint panel for quickly minting TRUST tokens during testing. This bypasses the normal trade flow and is only available on testnet. Use it to reach the 100 TRUST threshold for testing dispute flows.

Reputation System

TrustMarket features an on-chain reputation system using soulbound TRUST tokens. These tokens are non-transferable and serve as proof of successful trading history.

Trust Levels

Newcomer
0–24 TRUST
Bronze
25–49 TRUST
Silver
50–99 TRUST
Gold
100–199 TRUST
Diamond
200+ TRUST

How It Works

  • TRUST tokens are minted by the escrow contract automatically on trade completion.
  • TRUST tokens are soulbound — they cannot be transferred or sold.
  • Your TRUST balance represents your on-chain trading reputation.
  • 100+ TRUST qualifies you to register as an arbitrator.
  • Dispute losers are penalized with TRUST burns (-50 or -25).
rust
// Mint reputation tokens (called by escrow on completion)
fn mint(to: Address, amount: i128)

// Check reputation balance (two aliases)
fn balance(owner: Address) -> i128      // called by dispute_oracle
fn balance_of(owner: Address) -> i128  // standard interface

// Register as arbitrator (requires 100+ TRUST)
fn register_arbitrator(user: Address)

// Check if user is a registered arbitrator
fn is_arbitrator(user: Address) -> bool

// Soulbound — transfer is DISABLED
fn transfer() -> Error::NotAllowed

Staking & Fee Vault

The FeeVault contract collects platform fees from every completed trade. Users can stake their tokens to earn a share of platform revenue.

Fee Collection

Every time a trade is completed via confirm_delivery(), a 1% platform fee is automatically sent to the FeeVault. The remaining 99% goes to the seller.

How Staking Works

  • Users can stake XLM tokens into the FeeVault.
  • Stakers earn a proportional share of the collected platform fees.
  • Staking helps secure the network and aligns incentives.
  • Users can unstake at any time and claim their rewards.

Fee Structure

ActionFeePaid ByGoes To
Create TradeFreeSeller
Lock FundsFree (gas only)Buyer
Trade Completion1% (100 bps)Deducted from paymentFeeVault
Dispute FilingFreeEither party
Cancel TradeFreeBuyer only

Note: The 1% fee is calculated as amount × 100 / 10000 (100 basis points). The fee is deducted from the trade amount during payout, so the buyer always pays the listed price.

Smart Contracts Reference

All contracts are written in Rust using the Soroban SDK and deployed on Stellar Testnet.

Deployed Addresses (Testnet)

marketplace_factoryCDE3N3UGFV7FMLZ2TU3VCYJPUZVGPKAP2CF3JTA72PJAWGP7ZOFIMGLK
reputation_tokenCDTS4NDJOEXQPCQU77MTY2YW6SXOQWUK3INZAMNZRGYGR7L447S6DUVP
dispute_oracleCDFH64SF26DYFSW3TXMXSW2FWXTHH62LOISP3W6AUYTH44U2SOWRNGJ4
fee_vaultCD5D43GGNHZG7V2TYVHIOP6IAIOS65BV43WZYAQPCBDNQWME5J2JOGMX

Contract Functions

MarketplaceFactory
initialize()create_trade()get_trade()get_user_trades()get_trade_count()pause()unpause()
TradeEscrow
init()lock_funds()mark_delivered()confirm_delivery()initiate_dispute()resolve()cancel()claim_expired()get_status()
DisputeOracle
initialize()create()register_arbitrator()vote()finalize()get_dispute()is_arbitrator()
ReputationToken
initialize()mint()burn()balance()balance_of()register_arbitrator()is_arbitrator()total_supply()
FeeVault
initialize()collect()stake()unstake()claim_rewards()get_total_staked()get_user_stake()

Frequently Asked Questions

Get Started

Ready to Start Trading?

Connect your wallet and explore the marketplace.