Skip to main content

Threat model & privacy

Overview

Layrs runs its production ZEN market path as private_core plus the layrs-enclave binary inside an attested Trusted Execution Environment (TEE). The privacy and integrity guarantees of the protocol come from a single, sharp boundary: the code that runs inside the attested enclave, versus everything that runs outside it on the parent host process.

This page states honestly what is public and what is private, what a malicious operator or host can and cannot do, and the specific mechanisms that enforce those limits — replay protection, journal tamper detection, snapshot rollback rejection, and recovery-floor anchoring. It also states the trust assumption plainly: you trust the attested enclave code, which is verifiable via PCR0; you do not trust the operator.

The trust assumption

Layrs does not ask you to trust the people running it. It asks you to trust a specific, measured piece of software:

  • The enclave image is measured as PCR0 (SHA-384), published via the environment value LAYRSV2_ENCLAVE_PCR0_SHA384.
  • The operator key that authorizes administrative operations is an Ed25519 key compiled into the EIF (the enclave image). It is part of the measured image, not a credential the host can supply at runtime.
  • Attestation verification pins the expected measurement with expectedPcrs: { pcr0 } and sets allowExpired: false, so an expired attestation document is rejected.

What you are trusting is therefore auditable: a particular enclave build, identified by its PCR0 measurement. What you are explicitly not trusting is the operator, the host process, the API containers, the database, or the logs — none of which ever see order plaintext.

Public vs. private

The boundary between the enclave and the host is the boundary between private and public.

Inside the enclave (private)

  • Opaque private-user identities and signed sessions.
  • Available, held, collateral, fee, and position balances.
  • Deterministic price-time matching with self-trade prevention.
  • Complete-set mint/burn and one-to-one market collateral.
  • Fee accounting: 0 bps maker, 20 bps taker, and a 5% positive winning-profit fee computed on a per-position cost basis.
  • Signed Pyth resolution.
  • The encrypted, hash-chained journal, deterministic receipts, and AEAD-encrypted snapshots.

Outside the enclave (public / host)

  • Authentication and compliance eligibility.
  • Chain and Pyth connectivity.
  • VSOCK ciphertext transport — the host relays sealed bytes and never sees plaintext.
  • Encrypted journal and snapshot storage.
  • Aggregate depth and public receipt publication — never the per-user order book.

Concretely, the public API exposes privacy fields per market: hiddenBook: true, an aggregateBucketMs (for example 1000), and the attestedPcr0Sha384 measurement bound to that market. The individual limit order book is not a public object; only bucketed aggregate depth is.

What the operator / host CAN and CANNOT do

The host is a full participant in the system — it terminates authentication, screens for compliance, connects to chains and to Pyth, and stores encrypted artifacts. It is also assumed to be potentially adversarial. The design confines it accordingly.

The operator / host CAN:

  • See ciphertext moving over the VSOCK transport, and store encrypted journals and snapshots.
  • Publish aggregate depth and public receipts.
  • Refuse to run, delay, or censor — availability is not something the enclave can force out of a hostile host.

The operator / host CANNOT:

  • Read order plaintext. Plaintext never reaches an API container, a database, or a log. The relay is ciphertext-only.
  • Submit an administrative operation. The parent/host process cannot submit an admin op without the Ed25519 operator key that is compiled into the EIF — a key that lives inside the measured image.
  • Forge or execute a user action. A user request cannot execute without all of: a registered enclave session, a valid signature, an unexpired request, and a strictly increasing sequence number.
  • Silently tamper with history — the hash-chained journal and anchored recovery floor make tampering and rollback detectable (see below).

Order flow and the attestation gate

Privacy is enforced before any secret leaves the client:

  1. The client verifies attestation first. GET /v1/attestation requires a nonce query parameter; a request without one returns ATTESTATION_NONCE_REQUIRED. The attestation document carries a requestNonce and a transportPublicKey, and freshness (the nonce plus allowExpired: false) prevents replay of a stale document.
  2. Only if attestation verifies against the expected PCR0 does the client seal a signed order to the enclave's transport public key.
  3. The sealed order is submitted via POST /v1/private/relay, which is ciphertext-only. Private sessions are established via POST /v1/private/sessions.

Because the client seals to the transportPublicKey that came out of a verified attestation document, a host that swapped in different code (a different PCR0) would fail verification, and a host that could not decrypt would gain nothing from relaying the bytes.

Replay protection

A captured request cannot be replayed to execute a second time or to execute later than intended. Execution requires, simultaneously:

  • a registered enclave session,
  • a valid signature,
  • an unexpired request, and
  • a strictly increasing sequence number.

The strictly increasing sequence means a re-submitted older request is rejected as non-increasing. The unexpired-request requirement bounds the window in which any request is valid at all. At the attestation layer, the required nonce plus allowExpired: false prevent replaying a stale attestation document to spoof the enclave's identity.

Journal tamper detection

The enclave maintains an encrypted, hash-chained journal. Because each journal entry is chained to the prior one, altering or removing any entry breaks the chain and is detectable rather than silent. Deterministic receipts and the state root give an independent way to check that a replayed journal reproduces the same state. Journal tamper detection is an explicitly tested behavior of the system.

Snapshots and rollback rejection

For durability, the enclave exports only AEAD-encrypted snapshots. A snapshot contains the journal sequence / head and the state root — not plaintext state. On restore, the enclave enforces two checks:

  • It rejects corruption — a snapshot that fails its authenticated decryption or integrity check is refused.
  • It rejects rollback — any snapshot older than an independently anchored minimum sequence is refused.

The second check is what defeats a rollback attack. A host cannot quietly hand the enclave an old, valid-but-stale snapshot to rewind the ledger to a more convenient past state, because the enclave will not accept a snapshot below the anchored floor. Snapshot restore and rollback rejection are both explicitly tested.

Recovery floor anchoring

The rollback defense is only as strong as the "minimum sequence" it compares against, so that floor is anchored outside the enclave in a way the operator cannot cheaply forge or reverse:

  • Receipts and journal records are continuously archived to Object Lock storage (write-once, so records cannot be deleted or overwritten within their retention).
  • Checkpoints — the checkpoint sequence plus state root — are anchored to a public audit rail before the accepted recovery floor advances.

Because the floor only advances after a checkpoint is publicly anchored, the "minimum acceptable sequence" the enclave uses on restore is backed by a public, append-only record. That is what makes rollback rejection meaningful rather than self-referential.

Resolution: honest limits

Resolution is deterministic and does not depend on trusting the operator's judgment. The oracle uses a signed Pyth Pro feed. For each of the opening and closing boundary, it collects exactly 25 authenticated samples at 200 ms spacing over the 5 seconds ending at the boundary (T-5s, T], each requiring at least 3 publishers and retaining its signed EVM payload. The 13th sorted E8 price (the median of 25) is taken at each boundary:

  • closing median > opening median => UP
  • closing median < opening median => DOWN
  • exact equality => PUSH

The honest trade-off: there is no recovery deadline and no alternate source. A missing valid Pyth window pauses resolution indefinitely, and Binance is intentionally not a launch fallback. The system prefers to stall correctly over resolving from an untrusted or degraded source.

Settlement

What reaches the chain is deliberately not your individual orders. Settlement happens on-chain via batchSettle on the MatchSettlement contract, under the EIP-712 domain { name: 'LayrsMatchSettlement', version: '1', chainId: 26514 }. A batch is a list of fills (marketId, buyer, seller, quantity, price, fee, nonce) plus a deadline, signed by the enclave. What reaches the chain is the netted batch, not per-user orders — so the on-chain footprint reveals aggregate settlement, not your private order flow.

Summary of the boundary

PropertyEnclave (trusted, measured by PCR0)Host / operator (untrusted)
Order plaintextSees and matches itNever sees it (ciphertext only)
Per-user book & balancesHolds themSees only aggregate depth / receipts
Admin operationsRequires Ed25519 key in the EIFCannot submit
User executionRequires session + signature + unexpired request + increasing sequenceCannot forge
History integrityHash-chained journal, tested tamper detectionCannot silently alter
RollbackRejects snapshots below anchored floorCannot rewind ledger
Recovery floorEnforced on restoreAnchored publicly (Object Lock + audit rail)

The net position: an adversarial host can deny service, but within the bounds of the attested code it cannot read your orders, impersonate you, forge admin actions, tamper with history undetectably, or roll the ledger back. And you can check which code is running by verifying PCR0 against the attestation document from /v1/attestation.