Skip to content

Fix: 4 issues (#288, #291, #292, #293) - #483

Merged
OxDev-max merged 2 commits into
Refract-Protocol:mainfrom
spotkorner-dot:simple/288-291-292-293
Oct 23, 2026
Merged

OxDev-max merged 2 commits into
Refract-Protocol:mainfrom
spotkorner-dot:simple/288-291-292-293

Conversation

@spotkorner-dot

Copy link
Copy Markdown

Closes #288
Closes #291
Closes #292
Closes #293

Issues

#288 Model Oracle Attack Cost and Derive Minimum Bond and Quorum Sizing

Description:
Build an analytical model and operator tool that estimates the cost of corrupting a feed's consensus under a given quorum policy — via source bribery, collusion among N sources, or compromise of K operator keys — and derives the minimum operator bond and quorum thresholds required for the coverage exposure the feed supports.

Problem Statement & Context:
Staking parameters and quorum thresholds are otherwise chosen by intuition. Security claims like "corroborated" or "decentralized" are not verifiable without a number: how much does it cost an attacker to move this feed, and is that number large relative to the maximum payout the feed can trigger? The threat model already flags colluding sources as the residual risk after corroboration; this issue turns that risk into a parameter that configuration validation can enforce.

Scope & Acceptance Criteria:

  • A documented model covering at least: source-bribery cost, collusion threshold cost, and key-compromise cost, parameterized by source independence weights and bond sizes.
  • A CLI or script under scripts/ that takes a feed definition plus quorum policy and prints the attack cost, the maximum payout exposure it can support at a configurable safety factor, and the implied minimum bond.
  • A configuration validation rule that refuses to start when a payout-triggering feed's exposure exceeds the modeled attack cost by the configured safety factor.
  • Model outputs and inputs embedded into the trust documentation so reviewers can reproduce a number.
  • Out of scope: the staking/slashing mechanics themselves (tracked separately) and market pricing of operator capital.

Implementation Guidelines:

  1. Key Files/Modules: scripts/ (model + CLI), feed definition and quorum policy config validation, and docs/threat-model.md for the write-up.
  2. Design/Architecture: keep the model as a pure function library so it can be unit-tested and reused at validation time, not only inside the CLI; version the model alongside the policy it validates.
  3. Edge Cases/Constraints: sources with unknown independence (treat as fully dependent, i.e. worst case), zero-bond configurations, feeds whose exposure is dynamic and changes with pool TVL, and int overflow on large numbers (use bigint/decimal).
  4. Testing: unit tests against hand-computed scenarios, a regression fixture for the published reference scenario, and a validation test proving startup fails when exposure exceeds the modeled bound.

Definition of "Done":

  • Code written, tested, and documented.
  • All acceptance criteria met.
  • PR submitted with a clear description, passing CI, relevant screenshots/test output.
  • Code reviewed and approved.

Resources:

  • docs/threat-model.md — source collusion and relayer compromise sections that motivate the model.

Complexity: Medium (150 points)

#291 Make Feed Scheduling and Plausibility Checks Market-Hours and Calendar Aware

Description:
Introduce a clock/calendar abstraction for feeds that declares expected activity windows — market hours, exchange holidays, time zones and DST rules, and scheduled quiet periods — and make freshness, staleness, and plausibility evaluation respect them instead of assuming continuous 24/7 data.

Problem Statement & Context:
Price and TVL feeds derived from live markets legitimately stop moving overnight, on weekends, and on exchange holidays; aviation feeds have schedule-driven seasonality. With a flat freshness window, the pipeline will declare healthy sources stale every night, trip circuit breakers, and unpause/resume repeatedly — exactly the churn that trains operators to ignore breaker state. Calendar awareness also prevents the opposite error: accepting a holiday-quiet feed as fresh when it is in fact down.

Scope & Acceptance Criteria:

  • A feed-level calendar declaration: expected active windows, time zone (IANA), holiday calendar source, and allowed quiet behavior.
  • Freshness windows and staleness evaluation are computed against the calendar, so a closed market does not accrue staleness penalties while a feed that should be publishing does.
  • Plausibility/anomaly checks are suspended or relaxed appropriately during quiet periods, with the suspension itself recorded in the evidence and metric labels so it is auditable.
  • DST transitions handled without off-by-one-hour gaps or double windows.
  • Out of scope: shipping the holiday data itself (declare a source and license separately) and changing provider polling cadence.

Implementation Guidelines:

  1. Key Files/Modules: src/services/oracleMonitor.ts and the freshness enforcement module, feed definition config, a new calendar/clock module under src/oracle/, and .env.example defaults.
  2. Design/Architecture: inject a single clock and calendar resolver everywhere time is evaluated, so tests can drive time deterministically and all components agree on "is this feed expected to be live now".
  3. Edge Cases/Constraints: unscheduled halts (a market closes unexpectedly) must still alert after a bounded grace period, calendars may be unavailable at startup (fail safe, not silently open), and the resolver must be cached to avoid per-reading overhead.
  4. Testing: DST spring-forward/fall-back tests, holiday and weekend tests, an unexpected-closure test asserting the grace-period alert fires, and a test proving eval results are identical when the clock is frozen.

Definition of "Done":

  • Code written, tested, and documented.
  • All acceptance criteria met.
  • PR submitted with a clear description, passing CI, relevant screenshots/test output.
  • Code reviewed and approved.

Complexity: Medium (140 points)

#292 Add Consumer-Driven Contract Tests Across Backend, Contracts, and Frontend

Description:
Introduce consumer-driven contract tests that pin the shapes of oracle trust data produced by refract-backend — consensus decisions, provenance, trust status, and the on-chain reading encoding — against the expectations of refract-frontend and refract-contracts, with producer verification enforced in CI.

Problem Statement & Context:
The trust engine will ship a rapidly evolving set of payloads: decision records, provenance attestations, trust-status responses, and the encoded reading published on-chain. Today these shapes are coordinated by convention, so a renamed field or changed unit is discovered only when the frontend renders a broken badge or the contract rejects a reading — after the change has already been deployed against live policies.

Scope & Acceptance Criteria:

  • Published consumer contracts for each trust-facing interface consumed by the frontend and for the encoded on-chain reading consumed by the contracts repo.
  • Backend CI verifies its actual responses and encodings against those contracts; a breaking change fails the build with a named field.
  • Additive changes pass without ceremony; breaking changes require an explicit version bump and consumer opt-in.
  • A documented process for updating a contract (who bumps, how the consumer verifies) added to CONTRIBUTING.md or docs/.
  • Out of scope: implementing missing endpoints — this issue covers the contract mechanism plus the interfaces that already exist or land alongside it.

Implementation Guidelines:

  1. Key Files/Modules: test/ for the verification suite, the trust status and decision API route handlers, the oracle reading encoder, package.json scripts, and the .github/ workflows.
  2. Design/Architecture: use a Pact-style broker or, if a broker is undesirable, checked-in contract fixtures with a generated verifier; either way the consumer owns the expectation and the producer verifies it.
  3. Edge Cases/Constraints: contract tests must not require a live database or network, must run within the existing CI time budget, and must not become a second copy of the API docs that nobody updates.
  4. Testing: a proof test that deliberately renames a field in a branch and confirms CI fails with a readable message.

Definition of "Done":

  • Code written, tested, and documented.
  • All acceptance criteria met.
  • PR submitted with a clear description, passing CI, relevant screenshots/test output.
  • Code reviewed and approved.

Complexity: Medium (130 points)

#293 Support TEE-Attested Provider Readings for Hardware-Backed Data Provenance

Description:
Extend the signed provider submission path to accept hardware attestations (e.g. AWS Nitro Enclave or SGX quotes) bound to the submitted reading, verifying the quote, the nonce, and the payload hash so consensus can weight attested readings higher and detect tampering between the data's origin and ingestion.

Problem Statement & Context:
Signature verification proves a provider possessed a key; it does not prove the value was not altered inside the provider's own infrastructure before signing, nor that the code that produced it was the code the provider claims. For sources whose operators are also economically motivated parties, hardware attestation is the only way to extend the trust boundary upstream. It also gives highly reliable sources a defensible basis for a higher independence weight instead of an arbitrary one.

Scope & Acceptance Criteria:

  • Submission schema extended with an optional attestation object: TEE type, quote, nonce, and payload hash.
  • Verification: quote validated against a pinned vendor root, nonce bound to the request, payload hash matched against the canonicalized reading, and measurement compared against an allowlisted set of enclave measurements.
  • Attested readings are tagged with an attestation tier that is persisted, emitted in metrics, and available to consensus weighting; unattested readings remain valid at the base tier.
  • Attestation failures are recorded as evidence with the specific failure reason and never silently downgraded to "unsigned ok".
  • Out of scope: building the provider-side enclave image; a reference template may be documented but is not delivered here.

Implementation Guidelines:

  1. Key Files/Modules: the provider submission API and client SDK, a new src/oracle/attestation/ verifier module, src/db/schema.sql plus a migration for the attestation tier, and the source independence/weighting module.
  2. Design/Architecture: verification is a separate, independently testable step with a pluggable verifier per TEE type; policy decides whether an attested reading can short-circuit to a higher weight, and the policy version is recorded with the decision.
  3. Edge Cases/Constraints: clock-dependent quote validity, nonce reuse/replay, measurement rotation after a legitimate enclave upgrade (requires an admin path, not a code change), oversized quotes, and the availability risk of the vendor's root/CRL endpoint.
  4. Testing: valid and invalid quote fixtures, replayed nonce, mismatched payload hash, unknown measurement, and a downgrade-shaped payload that claims attestation without a quote.

Definition of "Done":

  • Code written, tested, and documented.
  • All acceptance criteria met.
  • PR submitted with a clear description, passing CI, relevant screenshots/test output.
  • Code reviewed and approved.

Complexity: High (210 points)

Summary

Keep the attack-cost model as a pure, versioned library so it is reused by both the CLI and startup validation. Use bigint/decimal throughout to avoid overflow and treat unknown source independence as fully dependent. For calendar awareness, inject a single clock and cached calendar resolver everywhere time is evaluated and fail safe (not silently open) when calendars are unavailable. Contract fixtures should be owned by consumers and verified by the producer without a live DB or network. The attestation verifier must be independently testable per TEE type and must never downgrade a failed attestation to unsigned-ok. Some affected files (src/oracle/oracle.service.ts, oracle.controller.ts, oracle.module.ts, package.json) were empty in the provided view; confirm their current contents before editing.

Changes

  • Create a pure, versioned attack-cost model library under scripts/ (e.g. scripts/attack-cost-model.ts) exporting functions for source-bribery cost, collusion-threshold cost, and key-compromise cost parameterized by source independence weights and bond sizes; treat unknown independence as fully dependent (worst case), use bigint/decimal arithmetic to avoid overflow, and derive the maximum supportable payout at a configurable safety factor plus the implied minimum bond. Export a MODEL_VERSION constant. Add a CLI entry (scripts/attack-cost-cli.ts) that reads a feed definition plus quorum policy JSON and prints attack cost, max supportable payout, and implied minimum bond. Add unit tests against hand-computed scenarios and a regression fixture for the published reference scenario. (scripts/attack-cost-model.ts)
  • Add a startup configuration validation rule that refuses to start when a payout-triggering feed's exposure exceeds the modeled attack cost by the configured safety factor. Import the pure attack-cost model library, read the feed definition/quorum policy and safety factor from config, and throw a clear error listing the feed, exposure, modeled attack cost, and safety factor when the bound is violated. Add a validation test proving startup fails when exposure exceeds the modeled bound. (src/config/configuration.ts)
  • Extend the environment schema with the new variables required by the attack-cost validation (e.g. ATTACK_COST_SAFETY_FACTOR, feed exposure/quorum policy inputs or a path to the feed definition) and with the calendar/clock settings for Make Feed Scheduling and Plausibility Checks Market-Hours and Calendar Aware #291 (feed calendar source, time zone, quiet-period behavior, calendar-unavailable fail-safe mode) and the TEE attestation settings for Support TEE-Attested Provider Readings for Hardware-Backed Data Provenance #293 (pinned vendor root, allowlisted measurements, attestation enable flag). Validate types and ranges and keep secrets redacted. (src/config/env.schema.ts)
  • Document the new environment variables with safe defaults and comments: attack-cost safety factor and feed exposure inputs (Model Oracle Attack Cost and Derive Minimum Bond and Quorum Sizing #288), calendar/clock and quiet-period settings including fail-safe behavior when calendars are unavailable (Make Feed Scheduling and Plausibility Checks Market-Hours and Calendar Aware #291), and TEE attestation configuration such as pinned vendor root and allowlisted measurements (Support TEE-Attested Provider Readings for Hardware-Backed Data Provenance #293). (.env.example)
  • Add a calendar/clock module under src/oracle/ (e.g. src/oracle/calendar.ts) providing a single injectable clock and a cached calendar resolver that declares expected active windows, IANA time zone, holiday calendar source, and allowed quiet behavior per feed. Implement DST-safe window evaluation (no off-by-one-hour gaps or double windows), fail-safe behavior when calendars are unavailable at startup, and a bounded grace period for unscheduled halts. Export helpers used by freshness, staleness, and plausibility evaluation. (src/oracle/calendar.ts)
  • Wire the calendar/clock resolver into OracleService so freshness and staleness are computed against the feed calendar (closed markets do not accrue staleness while feeds that should publish do), plausibility/anomaly checks are suspended or relaxed during quiet periods with the suspension recorded in evidence and metric labels, and unscheduled halts alert after the bounded grace period. Use the injected clock everywhere time is evaluated so tests can freeze time deterministically. (src/oracle/oracle.service.ts)
  • Register the new calendar/clock provider and the pluggable TEE attestation verifier provider in the OracleModule so they are injected into OracleService and the submission path, and expose the attestation tier to consensus weighting. (src/oracle/oracle.module.ts)
  • Create a pluggable TEE attestation verifier module under src/oracle/attestation/ with one verifier per TEE type. Verify the quote against a pinned vendor root, bind the nonce to the request, match the payload hash against the canonicalized reading, and compare the measurement against the allowlisted set. Return a structured result with the attestation tier and a specific failure reason; never silently downgrade a failed attestation to 'unsigned ok'. Handle clock-dependent quote validity, nonce replay, oversized quotes, and vendor root/CRL unavailability. (src/oracle/attestation/attestation-verifier.ts)
  • Extend the provider submission schema and controller to accept an optional attestation object (TEE type, quote, nonce, payload hash), invoke the attestation verifier as a separate step, persist the resulting attestation tier, emit it in metrics, and record attestation failures as evidence with the specific failure reason. Unattested readings remain valid at the base tier, and the policy version used for weighting is recorded with the decision. (src/oracle/oracle.controller.ts)
  • Extend OracleReading with an optional attestation tier field (and any provenance metadata needed for contract tests) so attested readings can be weighted higher by consensus while unattested readings default to the base tier. (src/oracle/oracle-reading.ts)
  • Add the attestation tier column (and any migration needed) to the schema so the attestation tier is persisted alongside readings, with a safe default of the base tier for existing rows. (src/db/schema.sql)
  • Add a consumer-driven contract verification suite under test/ (e.g. test/contracts/) using checked-in contract fixtures owned by refract-frontend and refract-contracts, with a generated verifier that pins consensus decision, provenance, trust status, and on-chain reading encoding shapes. The suite must run without a live database or network, fail with a readable named-field message on breaking changes, and pass additive changes. Include a proof test that renames a field and confirms the verifier fails. (test/integration/jest.integration.config.ts)
  • Add npm scripts for running the attack-cost CLI and the consumer contract verification suite, and wire the contract verification into the existing test/CI flow so producer verification is enforced. (package.json)
  • Add a CI step that runs the consumer-driven contract verification suite so a breaking change to trust-facing payloads fails the build with a named field, within the existing CI time budget. (.github/workflows/ci.yml)
  • Document the consumer-driven contract update process (who bumps a contract, how the consumer verifies, how breaking changes require an explicit version bump and consumer opt-in) and the attack-cost model usage/CLI so reviewers can reproduce the published numbers. (CONTRIBUTING.md)
  • Embed the attack-cost model inputs and outputs into the trust documentation: document the source-bribery, collusion-threshold, and key-compromise cost model, the parameterization by source independence weights and bond sizes, the published reference scenario with reproducible numbers, and the startup validation rule that refuses to start when a payout-triggering feed's exposure exceeds the modeled attack cost by the configured safety factor. (docs/threat-model.md)

spotkorner-dot and others added 2 commits October 22, 2026 13:17
Co-authored-by: Simple Agent <agent@simple.dev>
# Conflicts:
#	docs/threat-model.md
#	package.json
#	src/config/configuration.ts
#	src/config/env.schema.ts
#	src/db/schema.sql
#	src/oracle/oracle-reading.ts
#	src/oracle/oracle.controller.ts
#	src/oracle/oracle.service.ts
#	test/integration/jest.integration.config.ts
@OxDev-max
OxDev-max merged commit 85650be into Refract-Protocol:main Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants