Skip to content

Architecture

The platform consists of four main layers: smart contracts, backend API, matching engine, and frontend.

System Diagram

┌─────────────┐      ┌──────────────┐      ┌──────────────┐
│   Frontend   │─────▶│   Backend    │─────▶│   Matcher    │
│   (Vue/React)│      │   (NestJS)   │      │  (Fastify)   │
└─────────────┘      └──────┬───────┘      └──────┬───────┘
                            │                      │
                            │     ┌────────────────┘
                            │     │
                       ┌────▼─────▼────┐
                       │   Blockchain   │
                       │  (EVM Chain)   │
                       └───────────────┘

Smart Contracts

ContractPurpose
ConditionalTokens (CTF)Core conditional tokens engine — creates conditions, splits/merges positions
CTFExchangeValidates signed orders and settles matched fills on-chain
MockUmaAdapterOwner-controlled oracle for market creation and resolution
MockCollateralMintable ERC-20 test collateral
DeterministicWalletSigner-owned wallet for proxy/safe trading flows
PolyProxyFactoryDeterministic proxy wallet factory
PolySafeFactoryDeterministic safe wallet factory

Backend (NestJS)

The backend is the primary API for the frontend. It handles:

  • Authentication — SIWE (Sign-In with Ethereum) based auth with JWT tokens
  • Market Management — CRUD for market metadata, syncs trading pairs to the matcher
  • Trading BFF — Proxies order submission, cancellation, and orderbook queries to the matcher
  • User Management — Profiles, usernames, wallet linking
  • File Uploads — Market images via Google Cloud Storage

Auth flow: wallet signs a SIWE message → backend verifies → issues JWT access + refresh tokens.

Matcher (CLOB Engine)

The matcher is an internal service that the backend calls. It handles:

  • Market Registry — Token pair registration for each market condition
  • Order Intake — Validates signed orders (EOA, POLY_PROXY, POLY_GNOSIS_SAFE)
  • Price-Time Matching — Matches compatible buy/sell orders
  • Settlement — Submits matchOrders(...) transactions on-chain
  • Reconciliation — Listens for chain events to confirm fills

WARNING

The matcher is not meant to be called directly by the frontend. All trading requests go through the backend BFF layer.

Data Flow: Placing an Order

  1. User signs an order in the frontend (EIP-712 typed data)
  2. Frontend sends the signed order to POST /markets/:id/orders on the backend
  3. Backend validates the market is open and forwards to the matcher's POST /orders
  4. Matcher validates the signature, stores the order, and attempts to match
  5. If a match is found, matcher submits matchOrders(...) to the CTFExchange contract
  6. Exchange verifies signatures, transfers collateral, and splits/transfers conditional tokens
  7. Matcher reconciles the fill from on-chain events

Database Architecture

Both the backend and matcher use PostgreSQL with Prisma ORM.

DatabaseServiceContains
Backend DBNestJS backendUsers, markets, comments, sessions
Matcher DBFastify matcherToken pairs, orders, fills, events