Skip to main content

Architecture

PolTrading is a prediction market platform with a three-layer architecture: edge proxy, backend engine, and on-chain settlement.

System Overview

┌──────────────────────────────────────────────────────────┐
│ Edge Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ Geo-Fence │ │ Rate Limiter │ │ Anomaly │ │
│ │ (MaxMind) │ │ (Token Bkt) │ │ Detector │ │
│ └──────────────┘ └──────────────┘ └────────────────┘ │
│ │
│ ┌──────────────┐ │
│ │ Outpost │ │
│ │ (Edge Proxy) │ │
│ └──────────────┘ │
└──────────────────────────┬───────────────────────────────┘
│ mTLS

┌──────────────────────────────────────────────────────────┐
│ Backend Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ PolCore API │ │ Matcher │ │ Engine │ │
│ │(POST /orders)│ │ (Order Book) │ │ (Settlement) │ │
│ └──────────────┘ └──────────────┘ └────────────────┘ │
└──────────────────────────┬───────────────────────────────┘
│ tx

┌──────────────────────────────────────────────────────────┐
│ Chain Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ Conditional │ │ MarketFactory│ │ Resolution │ │
│ │ Tokens │ │ V1 │ │ Router │ │
│ └──────────────┘ └──────────────┘ └────────────────┘ │
└──────────────────────────────────────────────────────────┘

Outpost (Edge Proxy)

Outpost is a stateless Go service that acts as the public-facing edge. It handles:

Middleware Chain

Requests pass through middleware in this order:

  1. Geo-Fence — MaxMind GeoIP2 lookup; blocks restricted jurisdictions (HTTP 451)
  2. Audit — JSON-line request logging with TLS fingerprinting
  3. Blacklist — IP blocklist check (403 if blocked)
  4. Rate Limiter — Token bucket per IP (429 if exceeded)
  5. Anomaly Detector — Sliding window abuse detection (silent drop / tarpit)
  6. Seal Guard — Rejects all requests if service is sealed (503)

Scuttle (Emergency Seal)

An irreversible shutdown mechanism triggered by:

  • Manual: poladmin -cmd scuttle
  • Auto-scuttle: When AUTO_SCUTTLE=1 and multiple IPs breach anomaly thresholds
  • Backend outage: Sustained backend unavailability

On seal: all secrets are zeroed in memory, connection pools are closed, and all routes return 503.

Heartbeat

Three-state health machine:

UNKNOWN ──▶ HEALTHY ◀──▶ DEGRADED ──▶ SEALED
│ │
└───────────────┘
(probe success) (probe fail × 3)
  • HEALTHY: Backend reachable, orders accepted
  • DEGRADED: Backend unreachable, orders rejected (503), reads served from cache
  • SEALED: After sustained outage (configurable SEAL_AFTER_OUTAGE_SECS)

Security Posture

LayerMechanism
TransportmTLS (mutual TLS) with certificate rotation
ContentEd25519 content signatures (SHA-256)
AuthenticationHMAC-SHA256 with replay window + nonce dedup
MemorySecret zeroing on seal (scuttle)
ContainerDistroless image, non-root user
NetworkGeo-fencing via MaxMind GeoIP2
AuditJSON-line request logging with TLS fingerprinting

Operational Readiness

  • Health monitoring: Three-state machine (HEALTHY → DEGRADED → SEALED)
  • Emergency seal (scuttle): Irreversible shutdown triggered by anomaly detection or manual command; all secrets zeroed, all routes return 503
  • Backup/restore: Documented runbook with tested recovery procedures
  • Chaos testing: Automated failure injection suite for resilience validation
  • Certificate management: Automated rotation with expiry monitoring

PolCore (On-Chain Engine)

The on-chain settlement layer uses Gnosis Conditional Tokens:

ContractPurpose
ConditionalTokensBinary outcome token minting/redemption
MarketFactoryV1Market creation with collateral pools
ResolutionRouterOracle-mediated market resolution
MockUSDCTestnet collateral (Amoy)

Data Flow

Market Data (Read)

Agent ──GET /v1/markets──▶ Outpost ──cache──▶ Market Data
◀──Ed25519 signed envelope──

Order Submission

Agent ──POST /v1/orders──▶ Outpost ──mTLS──▶ PolCore ──tx──▶ Chain
(validates) (POST /orders,
(forwards the verifies signature)
decoded payload)

Feed Ingestion

AI Feeder ──POST /internal/ingest/market──▶ Outpost
(HMAC + Ed25519) (verify HMAC)
(verify Ed25519)
(update cache)