Vortx
WebsiteDiscordTwitter/XLaunch App
  • Background
    • 👋Welcome to VORTX
    • ⁉️What is VORTX?
  • Platform Overview
    • 🚀Getting Started with VORTX
    • 🔎How Prediction Markets Work
    • 🆕Create New Markets
    • 🗒️How Market Resolutions Work
    • 💰Oracle Rewards
    • 💸Fees and Economics
  • Technical Details
    • 🔧Technical Overview
    • 🏭Factory Contract
  • 🔮Prediction Market Contract
  • 📘OrderBook Contract
  • About VORTX
    • 💵Tokenomics
Powered by GitBook

© 2025 VORTX. All rights reserved.

On this page
  • The Innovation
  • Core Function: placeOrder()
  • Market Orders: Instant Execution
  • Fee Structure Implementation
  • Order Management
  • Market Integration
  • View Functions
  • Price Conversion Helpers
  • Usage Examples

OrderBook Contract

OrderBook Contract

The OrderBook is VORTX's revolutionary breakthrough - the first fully functional on-chain orderbook for prediction markets. This single contract handles all trading across every market with the precision and speed of centralized exchanges.

The Innovation

One OrderBook, All Markets

Instead of separate orderbook contracts per market, VORTX uses one unified trading engine:

mapping(uint256 => mapping(TokenType => mapping(OrderSide => uint256[]))) public orderBook;
// marketId => tokenType => side => orderIds[]

Why this architecture works:

  • Shared infrastructure reduces gas costs

  • Unified trading interface for all markets

  • Single contract to maintain and upgrade

  • Consistent trading experience across different markets

The Magic: Collision Detection

The feature that makes VORTX predictable:

function _placeLimitOrderInBook(uint256 limitOrderId) internal {
    // Check if this limit order would immediately match with any existing order
    for (uint256 i = 0; i < opposingOrders.length; i++) {
        if (wouldMatch) {
            revert("OrderBook: Limit order would match existing order - use market order instead");
        }
    }
    // No collision detected, add to order book
    orderBook[limitOrder.marketId][limitOrder.tokenType][limitOrder.side].push(limitOrderId);
}

What this means: Your limit orders either go to the book at your exact price, or the transaction fails with a clear message. No surprises, no unexpected executions.

Core Function: placeOrder()

Unified Trading Interface

One function handles both limit and market orders:

function placeOrder(
    uint256 marketId,
    TokenType tokenType,    // YES or NO
    bool isBuy,
    OrderType orderType,    // LIMIT or MARKET
    uint256 price,          // 1-100 (representing $0.01-$1.00)
    uint256 amount,         // Number of tokens (18 decimals)
    uint256 maxSlippage,    // For market orders only (basis points)
    uint256 expiry          // Order expiration timestamp
) external returns (uint256 orderId)

Price System

VORTX uses a 1-100 price system:

  • price = 1 → $0.01 per token

  • price = 50 → $0.50 per token

  • price = 100 → $1.00 per token

Order Processing Logic

if (orderType == OrderType.MARKET) {
    _executeMarketOrder(orderId);
} else {
    _placeLimitOrderInBook(orderId);
}

Market Orders: Instant Execution

How Market Orders Work

function _executeMarketOrder(uint256 marketOrderId) internal {
    // Match against all available liquidity with slippage protection
    for (uint256 i = 0; i < opposingOrders.length; i++) {
        // Check slippage protection
        if (slippage > marketOrder.maxSlippage) {
            break; // Stop matching due to slippage
        }
        _executeTradeWithFees(makerOrderId, takerOrderId);
    }
}

Slippage Protection

uint256 slippage = _calculateSlippage(bestPrice, opposingOrder.price, marketOrder.side == OrderSide.BUY);
if (slippage > marketOrder.maxSlippage) {
    break; // Stop matching due to slippage
}

Fee Structure Implementation

Maker/Taker Fee Logic

function _executeTradeWithFees(uint256 makerOrderId, uint256 takerOrderId) internal {
    // Maker (existing order): 0% fee
    // Taker (new order): 0.5% fee
    
    uint256 takerFeeUSDT = (totalCostUSDT * takerFee) / 10000; // 0.5%
    uint256 effectiveCostUSDT = totalCostUSDT - takerFeeUSDT;
}

Fee Collection

collectedFees += takerFeeUSDT;

// Fees are withdrawn by admin and split:
// 50% to treasury, 50% to buybacks

Order Management

Cancellation Functions

function cancelOrder(uint256 orderId) external // Cancel single order
function cancelAllMarketOrders(uint256 marketId) external // Cancel all orders in market
function cancelAllUserOrders() external // Cancel all user orders

Important: Only LIMIT orders can be cancelled. Market orders execute immediately.

Order States

enum OrderStatus {
    ACTIVE,    // Order is live and can be filled
    FILLED,    // Order completely filled
    CANCELLED, // Order cancelled by user
    EXPIRED    // Order expired (past expiry time)
}

Market Integration

Market Registration

function registerMarket(
    uint256 marketId,
    address yesToken,
    address noToken
) external onlyRole(FACTORY_ROLE) {
    marketTokens[marketId][TokenType.YES] = yesToken;
    marketTokens[marketId][TokenType.NO] = noToken;
    marketInfo[marketId].isActive = true;
}

Escrow System

Buy orders: USDT is escrowed when order is placedSell orders: Tokens are escrowed when order is placed

if (isBuy) {
    uint256 totalCost = _priceToUSDT(price, amount);
    require(usdt0.transferFrom(msg.sender, address(this), totalCost));
} else {
    require(IERC20Burnable(tokenAddress).transferFrom(msg.sender, address(this), amount));
}

View Functions

Order Book Data

function getOrderBook(uint256 marketId, TokenType tokenType) 
    external view returns (Order[] memory buyOrders, Order[] memory sellOrders)

function getBestPrice(uint256 marketId, TokenType tokenType, OrderSide side) 
    external view returns (uint256 price)

function getSpread(uint256 marketId, TokenType tokenType) 
    external view returns (uint256)

Market Estimation

function estimateMarketOrder(uint256 marketId, TokenType tokenType, bool isBuy, uint256 amount) 
    external view returns (uint256 estimatedPrice, uint256 availableLiquidity, uint256 slippage)

Price Conversion Helpers

Internal Price Logic

function _priceToUSDT(uint256 price, uint256 amount) internal pure returns (uint256 usdtAmount) {
    // Convert 1-100 price and 18-decimal tokens to 6-decimal USDT
    return (price * amount) / (PRICE_DECIMALS * 1e12);
}

function _usdtToPrice(uint256 usdtAmount, uint256 amount) internal pure returns (uint256 price) {
    return (usdtAmount * PRICE_DECIMALS * 1e12) / amount;
}

Usage Examples

Placing a Limit Order

// Buy 100 YES tokens at $0.65 each
await orderBook.placeOrder(
    marketId,
    0, // TokenType.YES
    true, // isBuy
    0, // OrderType.LIMIT
    65, // $0.65 (price system: 1-100)
    ethers.utils.parseEther("100"), // 100 tokens
    0, // no slippage for limits
    Math.floor(Date.now() / 1000) + 3600 // expires in 1 hour
);

Market Order with Slippage Protection

// Buy YES tokens with market order, max 5% slippage
await orderBook.placeOrder(
    marketId,
    0, // TokenType.YES
    true, // isBuy
    1, // OrderType.MARKET
    0, // price ignored for market orders
    ethers.utils.parseEther("100"), // 100 tokens
    500, // 5% max slippage (500 basis points)
    , // No expiration
);

The OrderBook contract proves that sophisticated trading infrastructure can run entirely on-chain, delivering the performance of centralized exchanges with the transparency and trustlessness of DeFi.

PreviousPrediction Market ContractNextTokenomics

Last updated 1 day ago

📘