Skip to main content

Architecture

Signals v1 is designed so the economic mechanism stays clean even as the system remains modular. Instead of hiding complexity, the architecture keeps the responsibilities visible: pricing is one concern, settlement is another, and accounting is its own discipline. This keeps the mechanism legible: each part has a clear job and a clear interface.

Signals follows a daily rhythm. Markets open and move along a shared pricing curve, settlement fixes the outcome once per day, and accounting updates once per day. The architecture exists to make that rhythm reliable and explicit.

The key architectural choice is separation: trading, settlement, and accounting are distinct, so each can be reasoned about independently. That separation keeps the system modular without blurring semantics: pricing state evolves through trades, settlement fixes a daily tick, and accounting realizes results at a single batch boundary.

Core loops

Signals can be understood as three loops that touch each other once per day:

  1. Pricing loop — trades move the shared curve.
  2. Settlement loop — a single tick is finalized.
  3. Accounting loop — daily results are applied in one update.

Each loop is independent in purpose but linked by the daily cadence. That is what keeps the system legible: a market day is a complete unit across all three loops.

Contract composition

Signals v1 uses a core contract that holds storage and delegates behavior to modules. The modules are separate contracts that execute via delegatecall, so they share the same storage layout as the core. This yields two properties that show up across the codebase:

  • the core contract is the stable entrypoint and the storage home
  • modules are swappable implementations of trading, lifecycle, oracle, risk, and vault logic

Delegatecall has a strong consequence for interpretation. A module call is not a cross-contract message with its own storage. It is an execution of the module code in the core storage context. Storage reads and writes happen as if the code were inside the core contract.

This is why wiring is part of the security surface. A module address change changes executed code for the same proxy entrypoint, and a storage layout mismatch can corrupt state.

The architectural choice here is explicit separation: pricing does not depend on settlement, settlement does not depend on accounting, and accounting does not rewrite pricing. They meet only through the finalized settlement tick and the daily batch.

Each loop can be reasoned about in isolation. Price impact analysis can ignore settlement, and finality analysis can ignore intra‑day pricing.

At the protocol level, the composed surface includes:

  • SignalsCore: entrypoint, storage, module wiring, authorization, pause
  • TradeModule: range trading and fee overlay accounting
  • MarketLifecycleModule: market creation and settlement finalization state transitions
  • OracleModule: signed sample validation and closest-sample candidate selection
  • RiskModule: admissibility checks at market creation
  • LPVaultModule: maker accounting and daily batch processing
  • SignalsPosition: position tokenization and claim semantics
  • LP share token: maker share accounting surface
  • ctUSD: the settlement and payment asset

The address-level anchors for a deployment are listed in Contract Addresses. Proxies are the stable entrypoints. Implementations and module addresses can change across regimes.

SignalsPosition and the LP share token are separate contracts because they are tokens with their own transfer semantics. The core calls into them for mint and burn, but the trade and claim rules still live in the core-driven state machine.

Object model

A Market defines the outcome grid, timing windows, settlement state, depth, and fee policy. A Position is a range claim over that grid with a quantity and is transferable until it is closed or claimed. The LP Vault is the shared pool of maker capital that is updated once per day.

This object model is deliberately small. The protocol avoids a large zoo of instruments in favor of a few primitives with clear semantics.

Because the primitives are small, protocol behavior is described by a compact set of state variables and state transitions. Fewer object types means fewer interpretation gaps.

The market object carries the fields that define execution and settlement:

  • grid: minTick, maxTick, tickSpacing, numBins
  • economics: liquidity parameter α\alpha and fee policy address
  • time: startTimestamp, endTimestamp, settlementTimestamp
  • finality: settlementTick, settlementValue, settlementFinalizedAt

The position object carries only what is needed to define claim meaning: marketId, lowerTick, upperTick, quantity. All pricing and payout semantics are read from the market and the finalized tick.

The vault object carries the daily accounting state: NAV, share supply, batch price, pending requests, and escrow totals.

Lifecycle and state machines

Markets follow a fixed lifecycle around a settlement timestamp TsetT_\text{set}:

Trading -> SettlementOpen -> PendingOps -> FinalizedPrimary
\\-> Failed -> FinalizedSecondary

SettlementOpen is the signed-sample submission window. PendingOps is the decision window where finalization becomes available. The failure path marks a market day as failed and finalizes it via a secondary settlement value.

The LP vault processes a daily batch to apply maker-side PnL and fees, then updates share accounting once per day.

The daily batch is keyed by a day index derived from a fixed timezone offset. The core storage defines a day boundary offset and a 86,400-second batch length. This makes "market day" a first-class accounting object rather than an emergent property.

Data flow at a glance

  • Trades update the pricing state.
  • Settlement finalizes a single tick.
  • Claims read the finalized tick to pay positions.
  • Accounting updates once per day at the batch boundary.

Separation is intentional. It prevents the accounting layer from rewriting pricing semantics, and it prevents settlement finality from being entangled with intra-day trading activity.

Data flow and events

Architecture is most legible through events because the mechanism is defined as state transitions. Events label those transitions and preserve the regime history as an append-only record.

Examples of event families that map directly to the core loops:

  • Trading loop: position opens/increases/decreases/closes and fee charges
  • Settlement loop: sample submission, candidate updates, market settlement, market failure, secondary settlement
  • Accounting loop: daily batch processing events and fee waterfall allocation

These events are emitted by the delegated modules but are part of the core's on-chain record because modules execute in the core storage context.

Consequences for analysis

The separation shows up in the analysis surface.

Pricing analysis is about the curve state qq, depth, and fee overlay. It does not require a model of oracle selection, and it does not require reasoning about the daily batch.

Settlement analysis is about timing windows, signed sample validity, candidate selection, and the finalization step. It does not require reasoning about intraday trade sequences beyond the fact that trading closes before settlement.

Accounting analysis is about daily aggregation: how fees and PnL are realized into maker capital and, eventually, into depth. It does not rewrite the meaning of positions or the semantics of finality; it is an end-of-day realization step.

This separation is what keeps the protocol legible as it grows. Modules can be upgraded and global configuration can move, but the core loop remains the same: trade, settle, claim, and batch.

The upgradeable architecture adds one additional analysis constraint. When a proxy upgrades or module wiring changes, the same event name can correspond to a different implementation. The event stream remains the canonical record, but the bytecode regime defines how that record was produced.

Whitepaper sections:

  • Market-Cycle Batch
  • Safety Layer
  • Oracle and Settlement