Skip to main content

Risk Gates

Risk gates are explicit preconditions that run before certain state transitions. They are implemented as gate functions and are called by SignalsCore before delegating to the module that performs the actual update. A gate failure is a normal on-chain revert, which means:

  • no state changes occur, and
  • the outcome is deterministic given the pre-state and the inputs.

In the current release, the only active enforcement gate is market creation. Trade entrypoints call gate hooks, but exposure cap enforcement is not yet active.

The design goal is legibility. If a gate rejects a configuration, it does so by reverting before any state mutation. There is no partially-created market and no ambiguous "soft failure." The chain history contains either a successful state transition or a revert.

Gate surfaces

The public surfaces follow a single pattern: gate first, then update.

  • Market creation: createMarket gates before a market can be registered.
  • Position open: openPosition calls a gate hook before the trade module runs.
  • Position increase: increasePosition calls a gate hook before the trade module runs.

This is a structural guarantee, not a UI convention. The contract calls the gate before the delegated module executes.

At the call-site level, SignalsCore runs a gate by delegatecall into the risk module and bubbles the revert if the gate fails. This matters because it fixes the ordering: the gate runs in the same storage context as the update, and it runs before the delegated module can mutate state.

In pseudocode, the shape is:

gate(...);      // can revert, no state changes committed
update(...); // executes only if gate succeeded

The delegatecall detail matters because it keeps the gate and the update in the same storage context. A gate is not an off-chain recommendation and not a UI filter. It is part of the state transition logic for the public entrypoint.

Market creation gate in v1

Market creation enforces two constraints:

  1. Depth admissibility: the market's depth α\alpha must fit inside an on-chain limit derived from maker-side capital and grid size.
  2. Prior admissibility: the market's prior concentration budget must fit inside an effective backstop budget.

Both constraints are checked at creation time. If either fails, market creation reverts.

Depth admissibility

The depth limit is computed in two steps: a base bound from maker NAV, then an effective bound that shrinks under peak drawdown.

Let:

  • EtE_t be maker NAV (internal units are WAD),
  • nn be the number of outcome bins in the market, and
  • λ(0,1)\lambda \in (0, 1) be the safety parameter controlling the uniform-prior loss envelope.

The base bound is:

αbase=λEtln(n)\alpha_\text{base} = \frac{\lambda E_t}{\ln(n)}

Let PtP_t be the current maker share price and PtpeakP_t^\text{peak} the running peak. Peak drawdown is:

DDt=max ⁣(0, 1PtPtpeak)DD_t = \max\!\left(0,\ 1 - \frac{P_t}{P_t^\text{peak}}\right)

With drawdown sensitivity kk, the effective bound is:

αlimit=max ⁣(0, αbase(1kDDt))\alpha_\text{limit} = \max\!\left(0,\ \alpha_\text{base}\,(1 - k\,DD_t)\right)

The gate enforces:

ααlimit\alpha \le \alpha_\text{limit}

This inequality has a direct CLMSR interpretation. For a market with nn bins, CLMSR has a worst-case loss scale proportional to αln(n)\alpha\ln(n). Bounding that loss scale by a fraction of maker-side capital yields a constraint of the form αconstEt/ln(n)\alpha \le \text{const}\cdot E_t/\ln(n). The exact constant and rounding rules are part of the implementation, but the structural dependence is stable.

Two implementation details are relevant for researchers reading the exact surface:

  • the logarithm uses an upward-rounded bound, and
  • the multiplication/division use conservative rounding so the bound is not accidentally loosened by truncation.

The alpha gate is also conditional. If alpha enforcement is disabled in the on-chain configuration, or if maker NAV is zero, the alpha check is skipped.

The conditional behavior is part of the surface: a market can only be rejected by the alpha gate when both:

  • enforcement is enabled, and
  • maker NAV is nonzero.

Prior admissibility

Prior admissibility summarizes prior concentration as a tail budget term ΔEt\Delta E_t computed from the seed factors attached to the market at creation.

Let the market provide nn base factors (f0,,fn1)(f_0,\dots,f_{n-1}) in WAD. Define:

rootSum=ifiminFactor=minifi\text{rootSum} = \sum_i f_i \qquad \text{minFactor} = \min_i f_i

The uniform prior baseline uses the smallest factor:

uniformSum=nminFactor\text{uniformSum} = n \cdot \text{minFactor}

The tail budget is:

ΔEt=αln ⁣(rootSumuniformSum)\Delta E_t = \alpha \ln\!\left(\frac{\text{rootSum}}{\text{uniformSum}}\right)

Uniform priors satisfy rootSum=uniformSum\text{rootSum}=\text{uniformSum} and therefore ΔEt=0\Delta E_t = 0. More concentrated priors push the ratio above 1 and therefore produce ΔEt>0\Delta E_t > 0.

The gate compares ΔEt\Delta E_t to the effective backstop budget BeffB^\text{eff}, which is the on-chain backstop NAV in WAD units:

ΔEtBeff\Delta E_t \le B^\text{eff}

If the inequality does not hold, market creation reverts.

Prior admissibility also implies data-structure constraints. Seed factors are stored in a SeedData contract as a packed array. Creation validates that the seed data has exactly nn factors and that no factor is zero. These are not economic constraints; they are well-formedness constraints for the prior surface.

A numeric sketch

This sketch uses simple numbers to show the direction of the inequalities.

Suppose a market has n=4n=4 bins and the seed factors are:

(f0,f1,f2,f3)=(1,1,2,2)(f_0,f_1,f_2,f_3)=(1,1,2,2)

Then:

rootSum=6,minFactor=1,uniformSum=4\text{rootSum}=6,\quad \text{minFactor}=1,\quad \text{uniformSum}=4

The ratio is 6/4=1.56/4 = 1.5, so:

ΔEtαln(1.5)0.405α\Delta E_t \approx \alpha \ln(1.5) \approx 0.405\,\alpha

If α\alpha is large, the same factor shape produces a larger ΔEt\Delta E_t. Holding factors fixed, the tail budget scales linearly with depth.

The backstop inequality is then a simple budget check: the backstop must be at least as large as the computed ΔEt\Delta E_t for the market to be admissible.

Gate hooks on trades

Signals v1 uses the same core-first pattern for position modifications: the entrypoints call gateOpenPosition and gateIncreasePosition before delegating to the trade module.

In the current release, these trade gate hooks do not enforce exposure caps. Trades can still revert for trade-level constraints (invalid ranges, insufficient allowance, max-cost bounds, and other standard checks), but those are not risk gate outcomes.

The hooks exist as part of the architecture. Their presence means the core can evolve toward trade-level risk gating without changing the public trade entrypoints. For v1 behavior, the important point is simply that the hooks are called but do not currently impose caps.

What is observable

Gate outcomes appear as ordinary transaction outcomes. A rejected market configuration is a revert on the market creation entrypoint. A successful creation is a normal state transition with creation events. There is no separate "gate log" that needs privileged access.

The inputs to gates are also on-chain objects:

  • market configuration inputs such as bounds, spacing, depth, and seed factors
  • maker-side state used by admissibility checks such as vault NAV and reference tracking values
  • configuration toggles that enable or disable specific checks

This is the transparency surface of gates. A reader can explain why a market was admitted or rejected by reading the pre-state and applying the same inequality checks.

Effect on pricing and payouts

Risk gates do not rewrite CLMSR pricing. For admitted markets:

  • pricing remains the same cost function C(q)C(q) and state update rules, and
  • payout semantics are still deterministic functions of the final settlement tick.

Gates only decide whether a market configuration is admissible at the gate surface. Once a market exists, the mechanism rules are unchanged.

Revert surface

Gate outcomes appear as standard reverts. No partial updates are committed, because gates run before the delegated state transition executes.

For market creation, the most relevant revert classes correspond to:

  • α\alpha exceeding αlimit\alpha_\text{limit}, and
  • ΔEt\Delta E_t exceeding BeffB^\text{eff}.

Both are core-first reverts: if the gate reverts, the market does not exist and no partially initialized state remains.

Related reading: