Skip to main content

Marketplace

The marketplace is Token Studio's built-in secondary trading venue. Shareholders can list their pool shares for sale, and investors can browse, discover, and purchase shares across all active pools. All settlements happen on-chain through Stellar Soroban smart contracts.

Access the marketplace: home.dobprotocol.com/marketplace

How It Works

The marketplace follows a simple listing-and-purchase model:

SELLER                          MARKETPLACE                         BUYER
| | |
| 1. Create listing | |
| (shares, price, payment token) | |
|--------------------------------->| |
| | 2. Listing visible |
| | on marketplace |
| |<-------------------------------|
| | 3. Buyer selects listing |
| | |
| | 4. Buyer signs purchase TX |
| |<-------------------------------|
| | |
| 5. Shares transferred | 5. Payment transferred |
| from seller to buyer | from buyer to seller |
|<---------------------------------|------------------------------->|
| | |
| | 6. Commission deducted (1.5%) |
| | |

Listing Shares

Creating a Listing

A shareholder creates a listing by specifying:

ParameterDescription
Shares to sellNumber of shares from their holding (1-10,000)
Price per sharePrice in the chosen payment token
Payment tokenToken the buyer will pay with (e.g., fUSDC, XLM)

Listing Rules

  • A user can have one active listing per pool at a time
  • The listing does not lock or escrow shares -- shares remain in the seller's wallet until purchase
  • Listings can be cancelled at any time before purchase
  • Each listing receives a unique sale_address identifier (format: SALE_ + 32 hex characters)

Listing Identifier

The sale_address is a randomly generated unique ID, not the pool address:

sale_address:  SALE_a1b2c3d4e5f6...   (unique per listing)
token_address: CABC123... (pool contract address)

This distinction is important: sale_address identifies the listing, while token_address identifies which pool the shares belong to.

Purchasing Shares

Purchase Flow

  1. Browse: Buyer visits the marketplace and browses available listings, filtered by pool or across all pools
  2. Select: Buyer chooses a listing and specifies the number of shares to buy (up to the listed amount)
  3. Approve: Buyer approves the payment token transfer (if required by the token contract)
  4. Sign: Buyer signs the purchase transaction with their wallet (Freighter for Stellar)
  5. Settlement: Smart contract executes the atomic swap -- shares to buyer, payment to seller
  6. Commission: 1.5% commission deducted from the payment

Purchase Commission

ComponentAmount
Share price (per share)Set by seller
Total pricePrice per share x number of shares
Commission (1.5%)Deducted from total price
Seller receivesTotal price - commission

Example:

Listing: 500 shares at $10/share
Buyer purchases all 500 shares

Total price: $5,000.00
Commission (1.5%): - $75.00
Seller receives: $4,925.00
Buyer receives: 500 shares

Marketplace Views

Browse All Pools

The main marketplace page shows listings across all active pools:

URL: /marketplace

Displays:

  • Pool name and ticker
  • Number of active listings
  • Price range
  • Pool performance metrics

Single Pool Marketplace

View all listings for a specific pool:

URL: /marketplace/pool/{pool_address}?network_id={chain_id}

Example:

/marketplace/pool/CABC123...?network_id=10

Displays:

  • All active listings for this pool
  • Pool details (shares, distributions, APR)
  • Listing prices and quantities
  • Buy button for each listing

Database Schema

The marketplace uses two tables: one for listings and one for completed transactions.

dob_buy_sales (Listings)

ColumnTypeDescription
idINTEGERAuto-generated ID
sale_addressVARCHAR (unique)Unique listing identifier (SALE_ + 32 hex chars)
token_addressVARCHARPool address (which pool the shares belong to)
owner_addressVARCHARSeller's wallet address
payment_token_addressVARCHARToken used for payment (SAC address on Stellar)
price_per_shareDECIMALPrice per share in the payment token
shares_amountINTEGERNumber of shares listed for sale
chain_idVARCHARNetwork identifier
is_activeBOOLEANWhether the listing is currently active
created_atTIMESTAMPListing creation time
updated_atTIMESTAMPLast update time

dob_buy_sale_transactions (Purchases)

ColumnTypeDescription
idINTEGERAuto-generated ID
sale_addressVARCHAR (FK)References dob_buy_sales.sale_address
token_addressVARCHARPool address
buyer_addressVARCHARBuyer's wallet address
shares_amountINTEGERNumber of shares purchased
total_priceDECIMALTotal amount paid
commissionDECIMALCommission deducted
chain_idVARCHARNetwork identifier
created_atTIMESTAMPTransaction timestamp

Querying the Marketplace

Find Active Listings for a Pool

SELECT * FROM dob_buy_sales
WHERE token_address = 'CABC123...'
AND chain_id = '10'
AND is_active = true
ORDER BY price_per_share ASC;

Find a User's Active Listing

A user can only have one active listing per pool:

SELECT * FROM dob_buy_sales
WHERE token_address = 'CABC123...'
AND LOWER(owner_address) = LOWER('GBDM6...')
AND chain_id = '9'
AND is_active = true;

Find Purchase History for a Pool

SELECT t.*, s.owner_address AS seller_address
FROM dob_buy_sale_transactions t
JOIN dob_buy_sales s ON t.sale_address = s.sale_address
WHERE t.token_address = 'CABC123...'
ORDER BY t.created_at DESC;

Find a Listing by Unique Sale Address

SELECT * FROM dob_buy_sales
WHERE sale_address = 'SALE_a1b2c3d4e5f6...';

ID Generation

The marketplace uses a manual ID generation pattern to avoid database sequence permission issues:

// Find the current max ID
const maxIdResult = await db.dob_buy_sales.findOne({
attributes: [[db.Sequelize.fn('MAX', db.Sequelize.col('id')), 'maxId']],
raw: true
});
const nextId = (maxIdResult?.maxId || 0) + 1;

// Create with explicit ID
await db.dob_buy_sales.create({
id: nextId,
sale_address: `SALE_${crypto.randomBytes(16).toString('hex')}`,
token_address: poolAddress,
owner_address: sellerAddress,
// ... other fields
});

Smart Contract Integration

On Stellar Soroban, marketplace operations interact directly with the pool smart contract:

Listing Flow (On-Chain)

  1. Seller calls the marketplace contract to create a listing
  2. Contract records the listing parameters
  3. Shares are not escrowed -- ownership stays with seller until purchase

Purchase Flow (On-Chain)

  1. Buyer calls the marketplace contract with the listing ID and payment
  2. Contract verifies:
    • Listing is active
    • Seller still owns the shares
    • Buyer has sufficient payment token balance
  3. Atomic swap executes:
    • Shares transferred: seller --> buyer
    • Payment transferred: buyer --> seller (minus commission)
  4. Listing updated (deactivated if fully purchased, quantity reduced if partial)

Post-Purchase Sync

After a purchase:

  1. Stellar sync script detects the share transfer event
  2. pool_users table updated:
    • Seller's shares decreased
    • Buyer's shares increased (or new pool_users record created)
  3. Buyer now sees the pool in their dashboard
  4. Transaction recorded in dob_buy_sale_transactions

Price Discovery

The marketplace provides organic price discovery for pool shares:

  • No automated market maker -- prices are set by sellers based on their assessment of the pool's value
  • Listed price is execution price -- buyers pay exactly what is listed (no slippage)
  • Multiple listings -- different sellers may list at different prices, creating a natural order book
  • Market signals -- listing activity and pricing trends indicate pool health and investor sentiment

Factors That Influence Share Price

FactorImpact on Price
Distribution yield (APR)Higher yield tends to increase price
Distribution consistencyRegular distributions build confidence
Asset verification (TRUFA score)Higher scores increase trust
Pool age and track recordProven pools command premium
Remaining pool capacityScarcity drives price up
Broader market conditionsMarket sentiment affects demand

Network Support

NetworkMarketplace Available
Stellar Mainnet (10)Yes
Stellar Testnet (9)Yes
Ethereum Mainnet (1)Planned
Base Mainnet (8453)Planned
Polygon Mainnet (137)Planned

The marketplace is currently fully operational on Stellar networks, with EVM support planned for a future release.

API Endpoints

The marketplace is accessible through the Token Studio API:

EndpointMethodDescription
/api/marketplaceGETList all active marketplace listings
/api/marketplace?network_id=10GETListings filtered by network
/api/marketplace/pool/{address}GETListings for a specific pool
/api/marketplace/buyPOSTExecute a share purchase
/api/marketplace/sellPOSTCreate a new listing
/api/marketplace/cancelPOSTCancel an active listing

For programmatic access, see the Agent API documentation.