diff --git a/README.md b/README.md index 36dd807..68213f2 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,8 @@ Click an RFP to view details. Use the Submit Proposal button to apply. | RFP-016 | [Token Launchpad: LBP](RFPs/RFP-016-lbp-launchpad.md) | XL | $XXXXX | open | Applications & Integrations | [Submit Proposal](https://github.com/logos-co/rfp/issues/new?template=proposal.yml) | | RFP-008 | [Lending & Borrowing Protocol](RFPs/RFP-008-lending-borrowing-protocol.md) | XL | $XXXXX | open | Applications & Integrations | [Submit Proposal](https://github.com/logos-co/rfp/issues/new?template=proposal.yml) | | RFP-012 | [Advanced Lending Features](RFPs/RFP-012-advanced-lending-features.md) | L | $XXXXX | open | Applications & Integrations | [Submit Proposal](https://github.com/logos-co/rfp/issues/new?template=proposal.yml) | +| RFP-019 | [On-Chain TWAP Oracle](RFPs/RFP-019-twap-oracle.md) | L | $XXXXX | open | Developer Tooling & Infrastructure | [Submit Proposal](https://github.com/logos-co/rfp/issues/new?template=proposal.yml) | +| RFP-020 | [RedStone Off-Chain Oracle Adaptor for LEZ](RFPs/RFP-020-redstone-oracle-adaptor.md) | M | $XXXXX | open | Developer Tooling & Infrastructure | [Submit Proposal](https://github.com/logos-co/rfp/issues/new?template=proposal.yml) | ## Terms & Conditions diff --git a/RFPs/RFP-019-twap-oracle.md b/RFPs/RFP-019-twap-oracle.md new file mode 100644 index 0000000..1577d2e --- /dev/null +++ b/RFPs/RFP-019-twap-oracle.md @@ -0,0 +1,460 @@ +--- +id: RFP-019 +title: "On-Chain TWAP Oracle" +tier: L +funding: $XXXXX +status: open +dependencies: See Platform Dependencies section +category: Developer Tooling & Infrastructure +--- + + +# RFP-019 — On-Chain TWAP Oracle + +## 🧭 Overview + +Build an on-chain TWAP (time-weighted average price) oracle program +for LEZ that reads pool accumulators from a LEZ DEX (RFP-004) and +exposes geometric-mean prices through a canonical oracle price +account standard, together with a circuit-breaker interface against +external price sources. The TWAP tier is the on-chain +defence-in-depth layer alongside off-chain feeds: its security +depends on DEX liquidity depth and is independent of any bridge or +off-chain publisher. This RFP covers the TWAP program, the +canonical price account standard, and the circuit-breaker interface +only. External oracle adaptors (RedStone in RFP-020, Pyth in a +future RFP) populate the same standard. The applying team should +have experience with AMM mathematics, oracle manipulation analysis, +and SVM program development. + +## 🔥 Why This Matters + +Every DeFi protocol on LEZ that consumes price data, including the +lending protocol ([RFP-008](./RFP-008-lending-borrowing-protocol.md)), +the reflexive stablecoin +([RFP-013](./RFP-013-reflexive-stablecoin-protocol.md)), and any +derivatives or liquidation engines, faces the same risk: a single +oracle source under thin-liquidity conditions is cheap to +manipulate. 36 documented flash-loan oracle attacks have caused +over $418M in cumulative losses [5]. The defence is layered: combine +on-chain TWAP with an off-chain feed and flag divergence above a +threshold. Without an on-chain TWAP tier, LEZ DeFi has to trust a +single off-chain provider with no on-chain cross-check. + +The TWAP tier also enables designs that depend on on-chain pair +pricing without trusting an external publisher. One example is the +LGS/LSC composite oracle path that the LSC stablecoin (RFP-013) +may choose: an external LGS/USD feed combined with an on-chain +LGS/LSC TWAP. Whether RFP-013 picks the direct LSC/USD path or the +composite path is a business decision for the implementer; either +path needs a working TWAP tier as a swappable building block. + +On new chains, on-chain TWAP is vulnerable on its own: with thin +liquidity, a PoS validator controlling two consecutive blocks can +manipulate the TWAP accumulator at a cost roughly equal to the +round-trip swap fees and price impact, with no competition for the +back-run [6]. The attack cost scales linearly with pool depth, so +pools with $1M in liquidity offer far less protection than pools +with $100M. The circuit-breaker interface in this RFP exists to +bound this risk: when an external feed is registered for the same +pair, divergence above a configurable threshold flags the price as +disputed. + +## 🏗 Design Rationale + +### Public oracle execution + +Oracle programs run as public LEZ executions with no confidential +state. Accumulator updates, TWAP computation (including the +geometric mean), and price queries are all visible to any caller. +This is intentional: oracles are a shared public good on LEZ, and +every dapp must be able to read the same canonical price. +Confidential execution is reserved for application-layer protocols +that consume oracle prices (for example, private DEX swaps in +RFP-004); the price feed itself stays public. + +### Geometric mean over arithmetic mean + +Uniswap v3 moved from arithmetic-mean TWAP (v2) to geometric-mean +TWAP (v3) for good reason. The geometric mean, computed via +tick-based accumulators (log-price space), is more +manipulation-resistant for multiplicative price processes: an +attacker who moves the price up by 10x in one block and back by 10x +in the next leaves no net impact on the geometric mean, whereas an +arithmetic mean would be skewed upward [9]. LEZ's TWAP oracle +should adopt the v3 approach. + +### Configurable cardinality + +Uniswap v3 pools default to storing a single observation +(cardinality 1). Expanding the observation ring buffer to N slots +costs a one-time storage payment and enables TWAP lookback of up to +N blocks. At 12s blocks, the maximum cardinality of 65,535 provides +approximately 9 days of history [9]. Protocols can trade storage +cost for lookback depth depending on their needs: a lending +protocol may need 1 to 2 hours of history, while a governance +oracle may need 7 days. + +### LEZ oracle data standard + +On EVM, Chainlink's `AggregatorV3Interface` (`latestRoundData()`) +became the de facto oracle standard because Chainlink was the first +mover; Pyth, RedStone, Switchboard, and DIA all ship compatible +wrapper contracts so that consuming protocols need no code changes. +The interface has known limitations: no confidence interval, no +source identifier, confusing `answeredInRound` semantics, and +variable `decimals()` per feed. + +On SVM (Solana, LEZ), no equivalent standard exists. Each oracle +provider defines its own account data layout (Pyth's `PriceAccount`, +Switchboard's `AggregatorAccountData`), so consuming programs write +per-provider integration code. This fragmentation is not an +architectural necessity; a shared account struct is feasible on SVM. + +LEZ can define a canonical oracle price account structure now, +before ecosystem fragmentation sets in. The struct should include +fields that `AggregatorV3Interface` lacks: confidence interval, +source identifier, and circuit-breaker dispute status. Because +account data structures on SVM are append-friendly (a program can +add new fields at the end of the struct without breaking consumers +that read only the existing fields), the standard can evolve over +time without requiring coordinated upgrades across consuming +protocols. + +The standard is defined in this RFP. External oracle adaptors +(RFP-020 RedStone, future Pyth RFP) populate the same struct so +that consuming protocols integrate once and remain agnostic to the +underlying data source. If a new oracle provider becomes available +on LEZ, it populates the same struct without requiring any change +to consuming protocols. + +### Circuit-breaker interface + +When both on-chain TWAP and an external feed are available for the +same pair through the canonical price account standard, the program +compares them; if divergence exceeds a configurable threshold (e.g. +5%), the price is flagged as disputed. While the dispute is active, +the unified interface returns the most recent non-disputed price +(if available within `maxAge`) or reverts. Multi-source price +validation is the production norm: Aave V3 uses Chainlink with a +configurable fallback oracle [15]; Compound V2 anchored Coinbase +reporter prices against a Uniswap V2 TWAP with a 20% divergence +tolerance [16]; MakerDAO interposes a one-hour Oracle Security +Module (OSM) delay as a manipulation circuit breaker [15a]. Most +major lending protocols use at least two tiers of price validation +[6]. + +#### What the production record actually shows + +The production record favours **source diversification** more +clearly than it favours the specific TWAP-anchor + +divergence-flag mechanic this RFP includes. The strongest +documented saves are not divergence-flag firings; they are +incidents where a protocol consumed a robustly-aggregated +external feed that held while a single market venue dislocated: + +- **Curve / Vyper exploit, 30 July 2023.** During the + reentrancy attack, the on-chain CRV/USD price on Curve pools + collapsed to roughly $0.08; Chainlink's CRV/USD feed, + aggregated across CEX prices, bottomed at approximately + $0.59. Aave and other lending markets consuming the + Chainlink feed avoided cascade liquidation on a position + reported in coverage at roughly $200M. This is a clean + source-diversification save; the divergence between the + on-chain venue and the off-chain aggregate was the signal, + but no protocol-side divergence-flag firing is documented. +- **USDe Binance flash, 11 October 2025.** On-chain consumers + of robust USDe pricing stayed within roughly 30 basis points + of $1 despite a Binance wick, again driven by aggregate + price feeds rather than a circuit breaker. +- **MakerDAO OSM delay, 31 March 2025.** The mandatory one-hour + delay absorbed roughly $84.4M of whale positions during an + ETH wick. Passive save: no governance `stop()` was called; + the delay window itself was the protection. +- **Base sequencer outage, 5 August 2025.** Aave and Moonwell + on Base used the generic Chainlink Sequencer Uptime Feed to + pause borrowing and liquidations during a 33-minute handoff + outage. Note that this is the generic L2 uptime feed, not + Aave's `PriceOracleSentinel` wrapper. + +The track record of the specific TWAP-anchor + +divergence-flag mechanic this RFP includes is thinner. The +canonical reference is Compound V2's `UniswapAnchoredView` +during the November 2020 DAI spike: the 20% TWAP anchor +rejected the most extreme prices but did not prevent +approximately $89M of liquidations because the tolerance was +too wide. Compound V3 then dropped the TWAP anchor entirely. +Aave removed `PriceOracleSentinel` in v3.7 after years on four +chains with no documented saves and repeated false positives. +Aave's CAPO wstETH safety wrapper itself became the failure +source on 10 March 2026, causing roughly $27M of +false-positive liquidations. No protocol publishes "divergence +flag fired and saved $N" events the way protocols publish +post-mortems for losses. + +Layered defence pays off, but the load-bearing layer is +**source diversification** with robust aggregate feeds that +hold under venue-level distortion, not **bounds-checking +circuit breakers** that fire when sources disagree. This RFP's +circuit-breaker interface is worth shipping for the cases it +does catch (the bounds it imposes are a hedge against either +source going badly wrong), but the RFP-013, RFP-008, and +RFP-004 implementers should not treat the divergence flag as a +substitute for selecting feeds whose aggregation method is +itself robust. The Recommended Consumer Pattern in the SDK doc +packet should be explicit on this point: cross-check is a +guard rail, not a primary defence. + +### Fee structure + +Proposals must specify a fee model covering: who pays for oracle +updates (consumer, protocol, or subsidised), when fees are charged +(per query, per update, or per registration), the fee rate or +formula, and where fees are routed (protocol treasury, oracle +operators, or burned). The fee model should be sustainable without +ongoing subsidies once LEZ reaches moderate TVL. + +## ✅ Scope of Work + +### Hard Requirements + +#### Functionality + +1. Implement an on-chain TWAP oracle program that reads pool + accumulators from a LEZ DEX (RFP-004) and computes the geometric + mean TWAP over a configurable observation window. +2. Implement tick-based accumulator storage with configurable + cardinality: default 1, expandable up to 65,535 observations + per pool. +3. Provide a query interface: given a pool address and a window + length, return the TWAP price and the observation timestamps + used. +4. Define and implement the canonical LEZ oracle price account + structure as a reusable standard for the ecosystem (see Design + Rationale, "LEZ oracle data standard"). The struct must include + at minimum: price, timestamp, source identifier, confidence + interval (where the source provides one; zero otherwise), and + circuit-breaker dispute flag. The TWAP source must populate this + struct. The struct must be specified as a SPEL IDL and published + as a standalone artefact that other programs (including external + oracle adaptors in RFP-020 and any future Pyth RFP) can import + without depending on the TWAP program itself. The interface must + reject any price that is zero, negative, or otherwise invalid + before writing it to the account. +5. Implement a circuit breaker against external price sources that + conform to the canonical price account standard: when both the + on-chain TWAP and at least one external source are registered + for the same pair, the program compares them; if divergence + exceeds a configurable threshold (e.g. 5%), the program flags + the price as disputed. While the dispute is active, the unified + interface returns the most recent non-disputed price (if + available within `maxAge`) or reverts if no valid non-disputed + price exists. Consuming protocols can query the dispute status + and act accordingly. +6. The oracle program owner can register new TWAP price feed + sources (add a pool) and external price sources (any program + that publishes to the canonical price account standard), and + deregister stale or compromised sources. +7. Every price returned through the unified interface includes a + timestamp. Consuming protocols can specify a `maxAge` parameter; + the interface rejects prices older than `maxAge`. + +#### Usability + +1. Provide an SDK that can be used to build Logos modules for + interacting with the oracle program (querying prices, expanding + cardinality, registering feed sources). +2. Provide a Logos mini-app GUI (price feed dashboard) with local + build instructions, downloadable assets, and loadable in Logos + app (Basecamp) via git repo. The dashboard must display: live + TWAP prices, TWAP versus registered external source comparison, + circuit-breaker status, and observation history. +3. Provide a CLI that covers core functionality: query price, + expand cardinality, register and deregister feed sources. +4. Provide an IDL for the oracle program and the oracle price + account standard, using the + [SPEL framework](https://github.com/logos-co/spel). The price + account IDL must be published as a standalone artefact that + other programs can import without depending on the oracle + program itself. +5. Return clear, actionable error messages for all failure modes: + stale price, disputed price (circuit breaker triggered), no + observation history for the requested window, cardinality too + low for the requested window, zero or negative price from + source, and no valid non-disputed price available. +6. Provide a **reference consumer program**: a minimal LEZ program + (or equivalently a documented program-side code snippet plus + tests) that demonstrates the recommended consumer-side + integration pattern for reading the canonical price account. + The reference must show: reading price and timestamp from the + account, rejecting prices older than the consumer's chosen + `maxAge`, refusing to act on a price whose dispute flag is set, + and the recommended response when a price is unavailable + (typically: refuse the action, do not fall back to an unsafe + default). This is a guidance artefact for downstream consumer + protocols (RFP-008, RFP-013, RFP-004), not a production + product on its own. + +#### Reliability + +1. A price query is read-only and never modifies oracle state. +2. Cardinality expansion is atomic: partial failure leaves + existing observations intact. +3. Circuit-breaker evaluation is deterministic: given the same + on-chain state, the same divergence result is produced. + +#### Performance + +1. A TWAP query completes within a single LEZ transaction. +2. Document the compute unit (CU) cost of each operation: TWAP + query, accumulator update, cardinality expansion, and circuit + breaker evaluation. LEZ's per-transaction compute budget may + change during testnet. + +#### Supportability + +1. The oracle program is deployed and tested on LEZ devnet/testnet. +2. End-to-end integration tests run against a LEZ sequencer + (standalone mode) and are included in CI; CI must be green on + the default branch. +3. Every hard requirement in Functionality, Usability, Reliability, + and Performance has at least one corresponding test. The test + suite must include: TWAP computation correctness (known + accumulator values produce expected prices), manipulation + detection (circuit breaker triggers when TWAP and an external + source diverge beyond threshold), staleness rejection (prices + older than `maxAge` are rejected), and registration / dispute + state transitions. +4. A README documents end-to-end usage: deployment steps, program + addresses, and step-by-step instructions for querying prices, + expanding cardinality, and registering feed sources via CLI and + mini-app. +5. Submit a [doc packet](https://github.com/logos-co/logos-docs/issues/new?template=doc-packet.yml) + for the SDK, covering the developer integration journey for + querying prices, expanding cardinality, and registering feed + sources, **plus a "Recommended Consumer Pattern" section** that + walks a downstream protocol developer through the reference + consumer program from Usability #6: staleness handling, + dispute-flag handling, behaviour when no valid non-disputed + price is available, and the recommended pairing with an + external feed for divergence checking. +6. Submit a [doc packet](https://github.com/logos-co/logos-docs/issues/new?template=doc-packet.yml) + for the CLI, covering the core operator/user journey. +7. Provide Figma designs or equivalent for the mini-app GUI (price + feed dashboard). + +#### + Oracle Security + +1. The TWAP computation must sample the accumulator at block + boundaries (before any same-block trades execute), not + mid-block, to resist within-block manipulation. +2. The minimum recommended observation window for lending protocol + use is documented, with a manipulation-cost analysis for + representative LEZ liquidity levels ($1M, $10M, $50M, and $100M + pool depth). + +### Soft Requirements + +1. Aggregator-helper SDK utility: a client-side library that + composes the canonical price account with one or more + external-feed accounts (registered via the same standard) and + applies the documented Recommended Consumer Pattern from the + SDK doc packet: staleness rejection, dispute-flag handling, + divergence cross-check, and fail-safe behaviour when no valid + non-disputed price is available. This reduces duplicated + boilerplate across consumer protocols (RFP-008, RFP-013, + RFP-004) without changing the on-chain program surface. + +### Out of Scope + +The following are explicitly excluded from this RFP and addressed +elsewhere: + +- External oracle adaptors. RedStone is delivered in + [RFP-020](./RFP-020-redstone-oracle-adaptor.md). A Pyth adaptor + (which depends on Wormhole on LEZ) is deferred to a future RFP. +- Confidential or shielded oracle execution. Oracle programs run + as public LEZ executions (see Design Rationale, "Public oracle + execution"). +- The reflexive stablecoin design. RFP-013 owns the LSC stablecoin + and is the consumer of TWAP and external feeds; the choice + between LSC/USD direct and LGS/USD + LGS/LSC composite is a + business decision for that RFP's implementer. + +## ⚠ Platform Dependencies + +### Hard blockers + +These must be available on LEZ before the corresponding features +can be developed. + +#### RFP-004 (Privacy-Preserving DEX) + +The TWAP oracle reads pool accumulators from the DEX. Without +RFP-004, the on-chain TWAP tier cannot be exercised. The canonical +price account standard and circuit-breaker interface can be +designed and prototyped in parallel. + +### Soft blockers + +Desirable but the RFP can open without them. + +#### Event emission (LP-0012) + +Analytics, monitoring, and the circuit-breaker dashboard benefit +from structured on-chain events for price updates, circuit-breaker +triggers, and cardinality expansions. +[LP-0012](https://github.com/logos-co/lambda-prize/blob/main/prizes/LP-0012.md) +(Structured events for LEZ program execution) is currently +**open**. + +## 👤 Recommended Team Profile + +Team experienced with: + +- Oracle or DeFi protocol infrastructure development +- AMM mechanics and TWAP mathematics (accumulator design, + geometric-mean computation, window selection) +- Solana or SVM program development (Anchor or native) +- Smart-contract security auditing (oracle manipulation, flash-loan + attack vectors) + +## ⏱ Timeline Expectations + +Estimated duration: **8 to 12 weeks**. + +The canonical price account standard and circuit-breaker interface +can be designed and shipped early; the TWAP program itself depends +on RFP-004 (DEX) and is the longer pole. + +## 🌍 Open Source Requirement + +All code must be released under the **MIT+Apache2.0 dual License**. + + +## Resources + +- [RFP-004 — Privacy-Preserving DEX](./RFP-004-privacy-preserving-dex.md) + (pool accumulators, TWAP data source) +- [RFP-008 — Lending & Borrowing Protocol](./RFP-008-lending-borrowing-protocol.md) + (primary consumer of oracle price feeds) +- [RFP-012 — Advanced Lending Features](./RFP-012-advanced-lending-features.md) + (eMode and multi-collateral require reliable oracles) +- [RFP-013 — Reflexive Stablecoin Protocol](./RFP-013-reflexive-stablecoin-protocol.md) + (consumer of price feeds; LGS/LSC composite oracle path depends + on TWAP) +- [RFP-020 — RedStone Off-Chain Oracle Adaptor](./RFP-020-redstone-oracle-adaptor.md) + (first external adaptor to the canonical price account standard) +- [Appendix: Oracle Ecosystem](../appendix/oracle-ecosystem.md) +- [Uniswap v3 Oracle Documentation](https://docs.uniswap.org/concepts/protocol/oracle) +- [Uniswap v3 TWAP Oracles in PoS](https://blog.uniswap.org/uniswap-v3-oracles) + + +## ✏️ How to Apply + +👉 Submit a proposal using the Issue form: + +**[Submit Proposal](https://github.com/logos-co/rfp/issues/new?template=proposal.yml)** + +We typically respond within **14 days**. For clarification questions, +please use **Discussions**. diff --git a/RFPs/RFP-020-redstone-oracle-adaptor.md b/RFPs/RFP-020-redstone-oracle-adaptor.md new file mode 100644 index 0000000..38cf376 --- /dev/null +++ b/RFPs/RFP-020-redstone-oracle-adaptor.md @@ -0,0 +1,645 @@ +--- +id: RFP-020 +title: "RedStone Off-Chain Oracle Adaptor for LEZ" +tier: M +funding: $XXXXX +status: open +dependencies: See Platform Dependencies section +category: Developer Tooling & Infrastructure +--- + + +# RFP-020 — RedStone Off-Chain Oracle Adaptor for LEZ + +## 🧭 Overview + +Build a RedStone off-chain oracle adaptor for LEZ: a public-mode +LEZ program that verifies RedStone-signed data packages, exposes +the resulting prices through the canonical oracle price account +standard defined in [RFP-019](./RFP-019-twap-oracle.md), and +supports day-one delivery of XMR/USD and ZEC/USD feeds. RedStone's +data packages are signed with secp256k1 + keccak256 by its data +nodes; verification on LEZ runs as in-program code inside the +RISC-V zkVM (no cross-chain bridge, no Wormhole dependency). The +adaptor uses a push-mode aggregator pattern: a public-mode program +verifies signatures on the write side, stores the result in a +public price account, and consumers (including private-execution +programs) read the slot. + +LEZ is RISC0-based, so any signature scheme can be implemented in +program code. Early prototype work on in-program secp256k1 ECDSA +verification inside RISC0 ([`fryorcraken/lez-signature-bench`](https://github.com/fryorcraken/lez-signature-bench)) shows the +verification is slow enough that **pull-mode reads from inside a +private transaction are not feasible on consumer hardware** (a +private consumer would spend several minutes generating the proof +for each read), absent a RISC0-specific signature-verification +accelerator. The push-mode aggregator pattern is therefore the +working assumption: the verifier runs once per update on the write +side in public execution; consumers (public or private) read the +resulting public price account without doing any signature work. +Cost measurement remains a primary deliverable for the public-mode +write side, where amortisation across all downstream reads can +make in-program verification workable; if the measured public-mode +cost is unacceptable the measurement becomes the input to a +follow-on RFP that proposes adding a secp256k1 ECDSA + keccak256 +precompile to LEZ. + +### Scope + +In scope: + +- The RedStone off-chain oracle adaptor as a public-mode push aggregator on LEZ. +- Day-one XMR/USD and ZEC/USD feeds, registered and exercised on LEZ devnet/testnet. +- Cost measurement of the in-program RISC-V verification path as a primary deliverable. + +Out of scope at the Overview level (full list under Out of Scope below): + +- The on-chain TWAP tier and the canonical oracle price account standard, owned by [RFP-019](./RFP-019-twap-oracle.md). +- A Pyth adaptor: depends on Wormhole on LEZ, deferred to a future RFP. +- Pull-mode reads from inside private execution: blocked on a RISC0 signature accelerator or a LEZ secp256k1 + keccak256 precompile, neither of which exists today. A precompile is the subject of a possible cost-conditional follow-on RFP. + +## 🔥 Why This Matters + +Private DeFi is what LEZ is positioned to support, and reliable +USD reference prices for privacy collateral, in particular Monero +(XMR) and Zcash (ZEC), are a necessary step. The LSC stablecoin +([RFP-013](./RFP-013-reflexive-stablecoin-protocol.md)), the +privacy-preserving DEX +([RFP-004](./RFP-004-privacy-preserving-dex.md)), wrapped privacy +assets, and other cross-chain primitives all need those reference +prices to function. + +The on-chain TWAP tier in +[RFP-019](./RFP-019-twap-oracle.md) is not sufficient on its own +for the day-one asset list. TWAP security scales linearly with +pool depth: on a new chain where liquidity is thin, a validator +controlling two consecutive blocks can manipulate the accumulator +at a cost roughly equal to the round-trip swap fees and price +impact, which on a $1M pool is cheap (see +[Appendix: TWAP Manipulation Vectors](../appendix/oracle-ecosystem.md)). +More structurally, TWAP only produces a price for pairs that +exist as pools on LEZ; XMR/USD and ZEC/USD don't, because XMR and +ZEC aren't natively on LEZ. An off-chain feed is the only way to +get those prices on chain at all, and pairing it with TWAP for +the pairs where TWAP does work is the production norm for layered +oracle defence. + +Across the surveyed off-chain oracle providers, RedStone is the +only one that combines: support for both XMR and ZEC in its public +token registry, a portable connector pattern (single secp256k1 +ECDSA + keccak256 verification path that works the same on every +host chain), no cross-chain bridge requirement, and a self-serve +deployment path that does not require an oracle-team business +engagement. Pyth covers both feeds and adds higher publisher +counts and confidence intervals, but is gated on Wormhole +integration on LEZ; it should land as a fast-follow in a future +RFP. Chainlink is permissioned and not self-serve. DIA Lumina is +permissionless but requires bespoke per-chain deployment. See +[Appendix: Oracle Ecosystem, Privacy-Asset Feed Availability](../appendix/oracle-ecosystem.md) +for the full coverage matrix. + +The combination of "private DeFi needs XMR and ZEC" and "RedStone +is the only path that is self-serve on LEZ today" makes this the +priority off-chain oracle integration for LEZ. + +### A building block in a layered oracle stack + +Neither an off-chain feed nor an on-chain TWAP is a complete +oracle on its own; both have known failure modes and the +production norm in DeFi is to layer them. This RFP delivers the +off-chain adaptor as a swappable building block in that layered +stack: production-grade code on its own terms, paired with the +TWAP tier from [RFP-019](./RFP-019-twap-oracle.md) on the +consumer side. Consuming protocols (the LSC stablecoin in +[RFP-013](./RFP-013-reflexive-stablecoin-protocol.md), the +lending market in +[RFP-008](./RFP-008-lending-borrowing-protocol.md), the DEX in +[RFP-004](./RFP-004-privacy-preserving-dex.md)) compose these +pieces according to their own production-security choices, with +the canonical price account standard from RFP-019 keeping +swap-out cheap if those choices change later. + +## 🏗 Design Rationale + +### Public-mode aggregator with private-account composability + +The adaptor runs as a public-mode LEZ program with no confidential +state. Signature verification, data-package decoding, and price +publication are all visible to any caller. Any LEZ dapp can read +the same canonical price. + +This shape is determined by where signature verification can run +on LEZ. LEZ is a RISC-V zkVM built on RISC0; any code that runs +inside a private transaction has to be expressible inside the +RISC-V zkVM circuit, so a private transaction that wants to verify +a secp256k1 ECDSA signature has two options, both unappealing: +verify the signature inside the privacy circuit (forfeits the +batching benefits that make ZK proof amortisation work; RISC0 +elliptic-curve performance for this primitive is currently +unmeasured), or place the signature in the transaction journal +where it is publicly disclosed (breaks the privacy of the +transaction). Neither option preserves both efficiency and +privacy. + +The adaptor therefore runs the verifier in a public-mode +aggregator: signatures are recovered once per update on the write +side, and the verified price plus timestamp are stored in a public +price account. Private-execution programs compose with the price +by reading the public account, not by carrying signed payloads +inline. Cost is paid once per update and amortises across all +downstream reads, public and private. Confidential execution is +reserved for application-layer protocols that consume oracle +prices (for example, private DEX swaps in +[RFP-004](./RFP-004-privacy-preserving-dex.md)); the price feed +itself stays public. + +Pull-mode reads (where a public consumer transaction carries a +signed payload and verifies inline) remain technically possible on +LEZ inside public execution, but are out of scope for this RFP +because they don't extend to private execution and because the +push-mode aggregator gives strictly better cost amortisation for +the LEZ DeFi consumer set. They can be revisited in a follow-on +once measured cost data is in. + +See [Appendix: Oracle Ecosystem, Implications for LEZ](../appendix/oracle-ecosystem.md#implications-for-lez) +for the full four-shape analysis (trusted re-signer, FROST-BIP340 +federation, DLC-oracle extension, and the cost-conditional +precompile path) that this section condenses. + +A LEZ-specific freshness pattern follows from the public / private +execution split. A user who needs a price fresher than the +heartbeat's last update can submit a public transaction that +pushes a fresh signed payload to the aggregator account, then +submit a private transaction immediately after that reads the +just-updated public price. Verification cost is paid in the public +path (cheaper, especially under the precompile follow-on); the +private transaction does no signature work. This recovers pull +mode's "fresh at transaction time" property for private consumers +without paying the in-circuit cost in the privacy proof. The +adaptor program already accommodates this: any caller can submit +a valid signed payload and the program writes if signatures and +timestamps check out. + +The same mechanism enables a **consumer-pays push variant** that +does not require a dedicated relayer at all. Users push when they +need a fresh price; idle periods incur zero update cost; the +aggregator only advances when someone needs it. This is +operationally pull (consumer-pays, on-demand) but structurally +push (the program owns the public price account that downstream +private consumers read from). Whether to run a heartbeat relayer +in addition (RedStone's own pusher, a sovereign relayer, or +neither) is a deployment-time choice: a heartbeat keeps the slot[]() +warm for read-only consumers; consumer-pays push keeps the cost +model strictly proportional to demand. Both can coexist; the +program logic does not distinguish between them. + +The two-transaction split (public push, then private read) is +distinct from the rejected "put the signature in the journal" +option. The signature is carried only in the public push; the +private transaction reads the resulting public price account by +address with no upstream signature in its calldata or journal, +so the private transaction's contents (assets, counterparty, +amount) stay private. This fits the adaptor's existing write +path: the program already accepts signed payloads from any +caller and writes a public price account, regardless of whether +the caller is a relayer or an end user. There is a residual +linkability risk that the consumer needs to handle on its side, +not the adaptor's: an observer can correlate a public push from +wallet X at time T with a private transaction at time T plus +epsilon and infer that the same actor is consuming the +just-pushed price. Mitigations (separate funding wallet for the +push, timing decorrelation, reliance on a heartbeat to mask +single-purpose pushes) are consumer-side production-security +choices. The privacy story is strictly better than +journal-disclosed signatures (the private transaction's body +stays private) but not equivalent to a heartbeat-only push +model. + +### RISC-V verification path and the precompile question + +This RFP implements signature verification in RISC-V program code, +running inside RISC0. There is no host primitive to call: the +recovery is an in-program ECDSA + keccak256 path written against +existing Rust crates (k256 / sha3 / equivalents) and proved by +RISC0 along with the rest of the program. + +This is the central technical bet of the RFP. Early prototype +work on in-program secp256k1 ECDSA verification inside RISC0 +([`fryorcraken/lez-signature-bench`](https://github.com/fryorcraken/lez-signature-bench)) is already enough to flag that the +naive in-circuit path is slow on consumer hardware: a private +consumer attempting pull-mode verification would spend several +minutes generating the proof for each read. That rules out +private-execution pull mode in any practical sense for the +in-program path, absent a RISC0-specific signature-verification +accelerator (e.g. a future `risc0-ecdsa` extension or a secp256k1 +precompile wired into the zkVM proving system itself). The first concrete +deliverable of this RFP refines this picture for the public-mode +write side: implement the verifier in RISC-V, run it on LEZ, +document the cost (compute units, proof time, proof size, +per-update bytes) for both the per-signature recovery and the +full 3-of-N aggregator write, and characterise where the +public-mode cost lands relative to the production-cadence budget. +Public-mode cost is the cost that matters for shipping the +adaptor: it amortises across all downstream reads. + +Two outcomes are possible from that measurement: + +1. **Measured cost is acceptable for the push-mode aggregator.** + The adaptor ships on the runtime as it stands. The aggregator's + update cadence amortises the per-update cost across all + downstream reads. No runtime change required. +2. **Measured cost is unacceptable.** The measurement becomes the + input to a follow-on RFP that proposes adding a secp256k1 ECDSA + + keccak256 precompile to LEZ for use by public-execution + programs. A precompile lives outside the ZK proof boundary and + is invoked as native validator code, so the cost goes from + "ZK-proven elliptic-curve operations" to "native ECDSA recovery + + keccak", which is the cost profile RedStone's existing + connectors assume on every other chain. The precompile is an + optimisation path conditional on the measurement, not a + precondition for this RFP. + +The applicant should therefore design the verification path so +that swapping in a precompile in a later release is a localised +change (a single trait implementation or syscall wrapper), not a +restructuring of the program. + +### Why RedStone first + +Three reasons specific to LEZ's constraints: + +1. **Privacy-asset coverage with no bridge.** Both XMR and ZEC are + in RedStone's public token registry, and the RedStone connector + pattern is fully self-serve: deployment does not require an + oracle-team engagement, a bridge, or a per-chain registration + step. LEZ can deploy and exercise these feeds without touching + any external infrastructure. Pyth and DIA both cover the same + assets but require either Wormhole (Pyth) or bespoke per-chain + deployment (DIA Lumina) before they work on a new chain. +2. **Single verification primitive, no bridge.** RedStone's + signature scheme is plain m-of-N secp256k1 ECDSA over keccak256 + (typically 3-of-N). Verification on LEZ is in-program ECDSA + recovery and keccak256 hashing inside RISC0; the cost profile + is the open variable this RFP measures (see "RISC-V verification + path and the precompile question"). Pyth's full 13-of-19 + Wormhole VAA verification is heavier in two ways: it adds a + Merkle proof on top of more signatures, and it presupposes a + Wormhole guardian-set tracking program on LEZ that does not yet + exist. RedStone has neither cost. +3. **Independent of LEZ's external integration timeline.** + Choosing RedStone first decouples the oracle layer from when + Wormhole on LEZ is decided. Pyth then fast-follows in a future + RFP, contributing higher publisher counts (especially the + roughly 80+ on XMR/USD versus RedStone's smaller per-feed + roster) and confidence intervals that RedStone does not + natively expose. + +See +[Appendix: Oracle Ecosystem, Signature Verification Schemes](../appendix/oracle-ecosystem.md) +for the full per-scheme analysis and citations. + +### Conformance to the canonical price account standard + +The canonical oracle price account standard is owned by RFP-019 +(see "LEZ oracle data standard" in that RFP's Design Rationale). +The RedStone adaptor populates the same struct as the on-chain +TWAP source: price, timestamp, source identifier, confidence +interval (zero, since RedStone does not publish one), and +circuit-breaker dispute flag. Consuming protocols query a single +data layout and remain agnostic to whether the price came from +TWAP, RedStone, or any future provider. + +If RFP-019 has not yet shipped the canonical struct when this RFP +is delivered, the team must define a forward-compatible minimal +struct using append-friendly account-data conventions, so that a +later RFP-019 release can extend the struct without breaking +consumers. + +### Fee structure + +In the push-aggregator shape this RFP commits to, the on-chain +verification cost is paid once per update by whoever submits the +signed data package to the aggregator, and is amortised across all +downstream reads (public and private). RedStone itself does not +publish prices on-chain; a relayer fetches the signed packages from +the RedStone gateway and pushes them, so "whoever pays for an +update" in practice means whoever runs (or pays for) the relayer. +The adaptor does not need to fund a dedicated node operator pool. + +Beyond that structural point, this RFP does not prescribe a fee +model. Downstream users of the adaptor (consuming protocols, +relayer operators, deployers) are free to handle fees in whatever +way fits their product: subsidised by the consuming protocol, +charged per read, charged per update, routed to a treasury, burned, +or left at zero. The adaptor program itself should not bake in +policy that forecloses these choices. + +## ✅ Scope of Work + +### Hard Requirements + +#### Functionality + +1. Implement a public-mode LEZ program (push-mode aggregator) that + accepts signed RedStone data packages, recovers each signer's + public key via in-program secp256k1 ECDSA recovery (with + keccak256 hashing) running inside the RISC-V zkVM, and verifies + that the recovered public keys match the configured set of + authorised RedStone data nodes for the requested feed. + Structure the verification path so that swapping the in-program + recovery for a future host primitive (precompile or syscall) is + a localised change. +2. Verify the M-of-N signer threshold for each feed (configurable + at registration; default 3-of-N consistent with RedStone's + reference parameters) and reject any data package that does + not meet the threshold. +3. Decode the RedStone data package format (asset identifier, + value, timestamp, signer set) and reject any package whose + timestamp is older than a configurable `maxAge`, whose value is + zero, negative, or otherwise invalid, or whose asset identifier + does not match the registered feed. +4. Publish the verified price into a canonical oracle price + account conforming to the standard defined in RFP-019. The + adaptor must populate price, timestamp, source identifier (a + constant identifying RedStone), confidence interval (zero), and + circuit-breaker dispute flag (always cleared at write time; + the TWAP program in RFP-019 owns dispute-state transitions). +5. The adaptor program owner can register new RedStone feeds (by + asset identifier, M-of-N threshold, and authorised signer set), + update an existing feed's signer set on RedStone roster + changes, and deregister feeds. +6. XMR/USD and ZEC/USD feeds must be registered and exercised on + LEZ devnet/testnet as part of the deliverable. + +#### Usability + +1. Provide an SDK that can be used to build Logos modules for + submitting RedStone data packages and reading verified prices + from the canonical price account. +2. Provide a Logos mini-app GUI (off-chain feed dashboard) with + local build instructions, downloadable assets, and loadable in + Logos app (Basecamp) via git repo. The dashboard must display: + live prices for each registered feed, the configured signer + set, the current M-of-N threshold, the latest data-package + timestamp, and the staleness of each feed. +3. Provide a CLI that covers core functionality: submit a data + package, query the verified price, register and deregister + feeds, update signer sets. +4. Provide a relayer daemon (runnable from the CLI) that fetches + signed RedStone data packages from the RedStone gateway for the + registered feeds, pushes them to the LEZ adaptor on a + configurable cadence, and is suitable for an operator to run as + a long-running process. The daemon must support: configurable + feed list and update cadence per feed, retry and back-off on + transient gateway or LEZ errors, structured logging of submitted + updates and rejections (with the on-chain rejection reason where + available), and a clean shutdown path. Document the operator + journey end-to-end: install, configure, run, monitor. +5. Provide an IDL for the adaptor program and the canonical + oracle price account standard (re-exported from RFP-019, not + forked), using the + [SPEL framework](https://github.com/logos-co/spel). +6. Return clear, actionable error messages for all failure modes: + stale data package, signer-threshold not met, signer not in + authorised set, asset identifier mismatch, malformed package, + invalid signature, zero or negative price. +7. Provide a **reference consumer program**: a minimal LEZ program + (or equivalently a documented program-side code snippet plus + tests) that demonstrates the recommended consumer-side + integration pattern for reading the canonical price account + populated by this adaptor. The reference must show: reading + price and timestamp from the account, rejecting prices older + than the consumer's chosen `maxAge`, refusing to act on a + price whose dispute flag is set (the dispute flag is owned by + RFP-019's circuit breaker), and the recommended response when + a price is unavailable (typically: refuse the action, do not + fall back to an unsafe default). This is a guidance artefact + for downstream consumer protocols (RFP-008, RFP-013, RFP-004), + not a production product on its own. + +#### Reliability + +1. A price read is read-only and never modifies adaptor state. +2. Feed registration is atomic: partial failure leaves existing + registrations intact. +3. Signature verification is deterministic: given the same data + package and signer set, the verification result is the same. + +#### Performance + +1. End-to-end signature verification and price publication for a + single 3-of-N RedStone data package must complete within a + single LEZ public transaction at the per-transaction compute and + proof budget in force on LEZ at delivery time. +2. Cost measurement is a primary deliverable, not a side report. + The applicant must measure and document, for the RISC-V + in-program verification path: per-signer ECDSA recovery cost + (compute units, RISC0 proof time, RISC0 proof size), keccak256 + hashing cost, package decoding cost, signer-set membership + check, canonical price account write, and feed registration. + Numbers must be reproducible from the test suite. +3. Document the cost delta between the in-program path and a + hypothetical native ECDSA + keccak256 precompile, using existing + per-chain reference points (for example, the RedStone EVM + end-to-end gas range of 50K to 100K, and the per-recovery cost + profile on chains that expose a native primitive). The delta + informs whether a follow-on precompile RFP is warranted. + +#### Supportability + +1. The adaptor program is deployed and tested on LEZ + devnet/testnet. +2. End-to-end integration tests run against a LEZ sequencer + (standalone mode) and are included in CI; CI must be green on + the default branch. +3. Every hard requirement in Functionality, Usability, Reliability, + and Performance has at least one corresponding test. The test + suite must include: valid signature acceptance, invalid + signature rejection, signer-threshold enforcement (M-of-N, + including boundary cases), stale-package rejection (`maxAge`), + asset-identifier mismatch rejection, zero or negative price + rejection, and feed registration / signer-set update transitions. +4. A README documents end-to-end usage: deployment steps, program + addresses, initial XMR/USD and ZEC/USD feed registrations, and + step-by-step instructions for submitting data packages and + querying prices via CLI and mini-app. +5. Submit a [doc packet](https://github.com/logos-co/logos-docs/issues/new?template=doc-packet.yml) + for the SDK, covering the developer integration journey for + submitting RedStone data packages and reading verified prices, + **plus a "Recommended Consumer Pattern" section** that walks a + downstream protocol developer through the reference consumer + program from Usability #7: staleness handling, dispute-flag + handling, behaviour when no valid non-disputed price is + available, and the recommended pairing with the on-chain TWAP + tier from RFP-019 for divergence checking. +6. Submit a [doc packet](https://github.com/logos-co/logos-docs/issues/new?template=doc-packet.yml) + for the CLI, covering the core operator/user journey. +7. Provide Figma designs or equivalent for the mini-app GUI + (off-chain feed dashboard). + +#### + Adaptor Security + +1. The adaptor must reject any data package whose recovered + signer is not in the configured authorised signer set for the + requested feed. +2. The signer set must be updatable only by the program owner; + the update path itself must be tested. +3. The minimum recommended `maxAge` for production use is + documented, with a manipulation analysis covering signer + compromise, replay of stale packages, and signer-set update + delays. + +### Soft Requirements + +1. Multi-feed batched verification: amortise calldata and + signature recovery overhead across multiple feeds in a single + instruction (analogous to Pyth's Perseus amortisation). +2. Circuit-breaker integration test against the on-chain TWAP + tier from RFP-019 once the TWAP program is available: confirm + that divergence between the RedStone-published price and the + TWAP-published price triggers the dispute flag as specified in + RFP-019. + +### Out of Scope + +The following are explicitly excluded from this RFP and addressed +elsewhere: + +- The on-chain TWAP tier and the canonical oracle price account + standard are owned by [RFP-019](./RFP-019-twap-oracle.md). This + RFP populates the standard, it does not define it. +- A Pyth adaptor. Pyth depends on Wormhole on LEZ and is deferred + to a future RFP. Higher publisher counts and confidence + intervals (which RedStone does not natively expose) come with + that adaptor. +- Adaptors for other off-chain oracles (Chainlink, DIA, Chronicle, + Switchboard, Supra). None of these match the combination of + privacy-asset coverage, single-primitive verification, and + bridge independence that motivates this RFP. Future RFPs may + add them. +- Pull-mode reads from inside private execution. A private + transaction that wants to verify a secp256k1 signature inline + cannot do so without forfeiting batching benefits or breaking + privacy (see Design Rationale). Private composability is via + reading the public price account that the push-mode aggregator + writes to. +- Adding a secp256k1 ECDSA + keccak256 precompile to LEZ. The + RISC-V in-program path is the deliverable here. A precompile + becomes a candidate for a follow-on RFP if and only if the cost + measurement in this RFP shows the in-program path is too + expensive for production cadence. +- The choice between LSC/USD direct and LGS/USD + LGS/LSC + composite for the LSC stablecoin + ([RFP-013](./RFP-013-reflexive-stablecoin-protocol.md)). That + is a business decision left to the RFP-013 implementer. + +## ⚠ Platform Dependencies + +### Hard blockers + +None at the runtime level. The adaptor builds on the LEZ runtime +as it stands today (RISC-V zkVM on RISC0, public-execution mode, +public account storage). Signature verification runs as in-program +code; no new precompile or syscall is required to deliver the +adaptor. + +### Cost-conditional follow-on (not a blocker for this RFP) + +#### secp256k1 ECDSA + keccak256 precompile in public-execution mode + +If the cost measurement deliverable shows that in-program ECDSA +recovery and keccak256 hashing in RISC0 are too expensive for the +push-mode aggregator's production cadence, a follow-on RFP can +propose adding a precompile (or accelerated host function) to LEZ +for use by public-execution programs. That RFP would substitute +for the in-program verification path in this adaptor via the +localised swap-out described in the Functionality requirements. +The precompile would be public-mode only; private execution paths +are unaffected because they do not call this primitive. + +The LEZ runtime team has noted that supporting a secp256k1 +primitive raises a broader set of design questions (nullifier +tracking for replay, privacy-circuit branching to support +Ethereum-signed private accounts, identifier-flow / wallet +implications) that are not blockers for the narrow oracle use of +the precompile but should be acknowledged. Those questions can be +scoped out of the follow-on or addressed in a separate runtime +RFP, depending on appetite. + +### Soft blockers + +#### RFP-019 (canonical oracle price account standard) + +This RFP populates the canonical price account standard defined in +[RFP-019](./RFP-019-twap-oracle.md). If RFP-019 has not landed +when this RFP is delivered, the applicant defines a +forward-compatible minimal struct (see Design Rationale). + +#### Event emission (LP-0012) + +Analytics and monitoring benefit from structured on-chain events +for price updates, feed registrations, and signer-set changes. +[LP-0012](https://github.com/logos-co/lambda-prize/blob/main/prizes/LP-0012.md) +(Structured events for LEZ program execution) is currently +**open**. + +## 👤 Recommended Team Profile + +Team experienced with: + +- Oracle or DeFi protocol infrastructure development +- Cryptographic verification (secp256k1 ECDSA recovery, keccak256 + hashing, calldata parsing, signer-set management) +- LEZ / RISC0 program development; in particular, comfort writing + and measuring elliptic-curve and hash-function code in RISC-V + programs proved by RISC0 (cost characterisation experience is a + strong signal, since cost measurement is a primary deliverable) +- RedStone's data-package format, EVM connector, or Solana + connector (any prior integration is a strong signal) +- Smart-contract security auditing (signer compromise, replay + attacks, signer-set update races) + +## ⏱ Timeline Expectations + +Estimated duration: **6 to 10 weeks**. + +The adaptor has no hard runtime dependencies; it builds on LEZ as +it stands today. The canonical price account standard is a soft +dependency on RFP-019 with a documented fallback. The cost +measurement deliverable resolves the open question of whether +in-program ECDSA + keccak256 in RISC0 is fast enough for the +push-mode aggregator at production cadence; if not, a follow-on +RFP for a secp256k1 precompile becomes the optimisation path, +with this adaptor as the immediate consumer. + +## 🌍 Open Source Requirement + +All code must be released under the **MIT+Apache2.0 dual License**. + + +## Resources + +- [RFP-004 — Privacy-Preserving DEX](./RFP-004-privacy-preserving-dex.md) + (consumer of price feeds; private swaps consume the + RedStone-published prices) +- [RFP-008 — Lending & Borrowing Protocol](./RFP-008-lending-borrowing-protocol.md) + (primary consumer of price feeds) +- [RFP-013 — Reflexive Stablecoin Protocol](./RFP-013-reflexive-stablecoin-protocol.md) + (LSC stablecoin; either Path A direct LSC/USD or Path B + composite uses this adaptor) +- [RFP-019 — On-Chain TWAP Oracle](./RFP-019-twap-oracle.md) + (defines the canonical oracle price account standard and + circuit-breaker interface) +- [Appendix: Oracle Ecosystem](../appendix/oracle-ecosystem.md) +- [RedStone Documentation](https://docs.redstone.finance/) +- [RedStone token registry](https://github.com/redstone-finance/redstone-api/blob/main/docs/ALL_SUPPORTED_TOKENS.md) + + +## ✏️ How to Apply + +👉 Submit a proposal using the Issue form: + +**[Submit Proposal](https://github.com/logos-co/rfp/issues/new?template=proposal.yml)** + +We typically respond within **14 days**. For clarification questions, +please use **Discussions**. diff --git a/appendix/oracle-ecosystem.md b/appendix/oracle-ecosystem.md new file mode 100644 index 0000000..79ef660 --- /dev/null +++ b/appendix/oracle-ecosystem.md @@ -0,0 +1,1329 @@ +# Appendix: Oracle Ecosystem + +This appendix surveys oracle protocols, TWAP mechanics, manipulation +vectors, and external oracle models relevant to +[RFP-019](../RFPs/RFP-019-twap-oracle.md). It provides the technical +and market context for the two-tier oracle architecture proposed for +LEZ. + +## Oracles Surveyed + +DeFi-style oracles are ordered by Total Value Secured (TVS), +largest first; this order is maintained throughout the document. +The DLC-oracle row is appended at the end because the DLC +attestation model does not have a TVS metric comparable to +push/pull DeFi oracles (DLC oracles secure individual Bitcoin DLC +contracts at maturity rather than continuously-running DeFi +positions). DLC oracles are included because the BIP-340 +attestation format they publish is the LEZ-native signature +primitive, which makes them relevant to the verification-cost +analysis later in this document; their structural fit is +prediction markets, not streaming price feeds. + +| Protocol | TVS | Chains | Model | Feed Count | Key Feature | +|----------|-----|--------|-------|------------|-------------| +| Chainlink | $66B-$75B (May 2025) | 27 push / 60+ via CCIP | Push (OCR/DON) | 1,000+ | Decentralised Oracle Network with VWAP from premium data aggregators | +| Chronicle | $10.2B+ (per [2]); Messari Q1 2025 cites $12.6B | 13 | Push | Limited | MakerDAO-native; concentrated TVS from Sky's $10B+ TVL | +| Pyth | $8.6B+ | 50+ via Wormhole | Pull (Wormhole) | 2,800+ | First-party data from 120+ institutional publishers; confidence intervals | +| RedStone | $10B+ | 50+ push / 120+ pull | Pull (calldata) | 1,000+ | No bridge dependency; modular push+pull; fastest-growing oracle | +| Switchboard | $3B+ [1] | 9 | Pull (TEE) | Permissionless | TEE (SGX/SEV) security; permissionless custom feed creation | +| Supra | $650M+ [1]; Supra positioning cites 50+ networks | 45 | Push+Pull | N/A | Newer entrant; DORA (Distributed Oracle Agreement) consensus | +| DLC oracles (Pythia live; Sibyls, P2PDerivatives, Ernest, Magnolia, others non-public or dormant) | N/A (not DeFi-TVS measured) | Bitcoin native; BIP-340 attestations portable to any verifying chain | Event-driven attestation (pre-announced R-points, signed at maturity) | Limited (BTC/USD; some chain metrics) | Native BIP-340 Schnorr; live ecosystem split between plain SHA-256 (Pythia, P2PDerivatives, rust-dlc) and tagged SHA-256 (Kormir, Ernest, Sibyls dlc_v0 mode); structural fit is prediction markets, not streaming price feeds | + +## Scale and Traction + +Total Value Secured measures the aggregate DeFi TVL in protocols that +depend on a given oracle. An oracle with higher TVS has withstood +more economic scrutiny, though TVS is a trailing indicator: new chains +start at $0 regardless of oracle choice. + +### Market share + +Chainlink dominates with approximately 68% of global oracle TVS and +over 80% on Ethereum specifically [1]. Chronicle's high TVS +(approximately 17%) is concentrated in a single protocol +(MakerDAO/Sky) and does not reflect general-purpose adoption [2]. +Pyth leads on data quality through first-party institutional +publishers; per Pyth's own April 2026 positioning, the network reaches +"100+ blockchains" via Wormhole, with cross-chain support +established on roughly 50+ chains in production. RedStone has the +fastest growth trajectory, driven by explicit support for L2s, +appchains, and rollups; RedStone reports no oracle-induced mispricing +on its flagship integrations (Ethena, Gearbox) through early 2026 +[2][3][17]. + +### Per-protocol adoption + +**Chainlink.** Deployed on 27 chains with push model and 60+ public +and private blockchains via CCIP. Network integration requirements +include high-availability RPC providers, valid SSL, Ethereum +JSON-RPC compatibility, and 30-day historical RPC performance +metrics, making it inaccessible for new chains at launch [4]. Uses +Off-Chain Reporting (OCR) where nodes aggregate prices from premium +data vendors (Kaiko, CoinMetrics) and submit a single signed +transaction per round. Update triggers are deviation threshold (e.g. +0.5% price change) or heartbeat (e.g. 1 hour maximum staleness). + +**Pyth.** Originated on Solana and now cross-chain via Wormhole. +Aggregates first-party data from 120+ institutional publishers +(April 2026), including Jane Street, Coinbase, and Binance, across +2,800+ price feeds (December 2025). Architecture: publishers post +prices on Pythnet (a Solana appchain) every 400ms; Wormhole guardians +sign a Merkle root; the Hermes off-chain cache stores latest proofs; +users fetch and submit proofs in their transactions. Every price +includes a confidence interval, enabling protocols to reject +high-uncertainty updates. Known incidents include the September 2021 +BTC/USD mispricing, where the feed reported approximately $5,402 +against an actual price near $43,500 (an approximately 87% drop) +[37], and the March 2025 Morpho cbETH wrongful liquidation on Base, +where a roughly 7-minute cbETH/ETH staleness window distorted the +collateral price and liquidated a user for approximately $33,000 on +a Re7 Labs vault [38]. + +**RedStone.** Modular oracle with both push and pull delivery. Pull +model attaches signed data to EVM calldata; the on-chain contract +verifies node signatures without requiring a bridge or dedicated +relay infrastructure [3]. Fastest-growing oracle in 2024 to 2025, +with deployments on Monad, Hyperliquid (HyperStone), and 120+ pull +chains. Zero reported mispricing incidents as of early 2026 [3][17]. +Expanding into RWA feeds (BlackRock BUIDL, VanEck VBILL) and risk +ratings via Credora acquisition. + +**Switchboard.** Permissionless feed creation via TEE (SGX/SEV) +oracle nodes [13]. Any developer can create custom feeds for assets +not covered by Pyth or RedStone. Can aggregate from multiple upstream +oracles (Pyth + Chainlink + custom APIs) in a single feed. The core +protocol contract is a single-deployment artefact per chain +(deployed by the Switchboard team), but feed creation on top of it +is permissionless; TEE hardware requirements limit the operator pool. + +**DIA Lumina.** Fully permissionless: both data sourcing (Feeder +nodes) and feed deployment (Aggregator contracts) require no team +permission [7]. ZK proof verification aligns with privacy-focused +chains. Smaller feed catalogue (200+) and newer ZK architecture +(Lumina V2) make it less battle-tested than Pyth or RedStone. + +## TWAP Mechanics + +### Uniswap v2 accumulator + +Each Uniswap v2 pool stores `price0CumulativeLast` and +`price1CumulativeLast` variables. These accumulators are updated at +the beginning of each block (before any same-block trades execute) +using the price set by the last trade of the previous block [14]. The +formula: `cumulativePrice += price * timeElapsed`. To compute a TWAP, +an external contract reads the accumulator at two timestamps (T1 and +T2) and divides: + +``` +TWAP = (accumulator[T2] - accumulator[T1]) / (T2 - T1) +``` + +This yields an arithmetic mean price. No off-chain components are +required. + +### Uniswap v3 accumulator + +Uniswap v3 replaced the raw price accumulator with a tick-based +accumulator (`tickCumulative`), which stores the running sum of +`currentTick * secondsElapsed` [9]. The TWAP is: + +``` +averageTick = (tickCumulative[T2] - tickCumulative[T1]) / (T2 - T1) +price = 1.0001^averageTick +``` + +This yields a geometric mean price, which is more appropriate for +multiplicative price processes. The observation buffer is a circular +array of up to 65,535 slots, expandable via +`increaseObservationCardinalityNext()` at a one-time gas cost [9]. + +Note on Uniswap v4: v4 removed the oracle from core pool state and +moved it to an optional hook, so pools that do not need an oracle +no longer pay the per-swap accumulator-update gas. The v3 design +described above remains the production reference for on-chain TWAP +(v3 is still the dominant AMM by deployed volume), and is what an +LEZ-side TWAP program would emulate. v4's hook-based oracle is a +deployment choice on top of the same accumulator pattern, not a +replacement for it. + +### Geometric vs arithmetic mean + +The arithmetic mean (v2) is sensitive to outliers: an attacker who +moves the price up by 10x in one block and back by 10x in the next +leaves a net upward bias in the arithmetic mean. The geometric mean +(v3) is invariant to such symmetric multiplicative manipulation, +because `log(10x) + log(1/10x) = 0` [9]. For this reason, the v3 +approach is strictly preferred for price oracle use. + +### Example computation (v3) + +``` +tickCumulatives = [70,000, 1,070,000] over 10 seconds +averageTick = (1,070,000 - 70,000) / 10 = 100,000 +price = 1.0001^100,000 = 22,015.5 USDC/WETH +``` + +Minor imprecision arises because ticks are integers and fractional +ticks are truncated, but this is negligible for most use cases [9]. + +## TWAP Manipulation Vectors + +### Flash loan attacks (within-block) + +An attacker borrows massive capital via a flash loan, moves the pool +price heavily, and profits from a protocol that reads the manipulated +price in the same or next block. Under Uniswap v2/v3, the accumulator +is updated at block start (before same-block trades), so within-block +manipulation does not affect the current block's accumulator sample. +However, the attacker can manipulate price at the end of block N, +which contaminates the accumulator sample in block N+1 [6][10]. + +### PoS multi-block validator attacks + +Under Proof of Stake, validators know one epoch ahead (32 blocks on +Ethereum, approximately 6.4 minutes) whether they control consecutive +blocks. A validator controlling two consecutive blocks can move the +price in block N and reverse it in block N+1, at a cost approximately +equal to the round-trip swap fees and price impact, with no back-run +competition [6]. This contaminates one accumulator data point per +attack. On high-liquidity pools (e.g. +USDC/WETH 5bps on Ethereum), the attack is economically infeasible; +on low-liquidity pools, it is trivially cheap. + +### Low-liquidity vulnerability + +Manipulation cost scales approximately linearly with pool liquidity +depth [6][10]. On the deep USDC/WETH 5bps pool, adding $1M of +wide-range liquidity raises the marginal cost of a two-block oracle +attack by approximately $360B above the already-large baseline, +demonstrating extreme sensitivity [6]. On a new chain like LEZ with +$1M pools, the same attack that costs trillions on Ethereum mainnet +costs only thousands. + +### Short observation window attacks + +An attacker sustains a manipulated price across multiple blocks for +the duration of a short TWAP window (e.g. 5 minutes). This is more +expensive than single-block manipulation but feasible on low-liquidity +pools [10]. The cost scales with both window length and pool depth. + +### Historical losses + +According to the Rekt Database (cited in the Ormer paper), 36 flash +loan oracle attacks alone caused over $418M in cumulative losses [5]. +Oracle manipulation is the primary attack vector in DeFi exploits. + +## Window Selection Tradeoffs + +### The core tradeoff + +Short TWAP windows (e.g. 5 minutes) provide fresh prices but are +cheap to manipulate. Long windows (e.g. 24 hours) are expensive to +manipulate but lag the market severely during genuine volatility. +Unlike external oracle networks, AMM TWAP cannot simultaneously +optimise both security and freshness [10]. + +### Production standards + +The majority of TWAP oracles in production DeFi use windows between +30 minutes and 12 hours [11]. + +| Use case | Typical window | Rationale | +|----------|---------------|-----------| +| Lending collateral valuation | 30 min to 2 h | Resist short-term manipulation; liquidation timing tolerable | +| DEX AMM internal pricing | 5 to 30 min | Requires responsiveness for arbitrage | +| Governance and voting | 24 h to 7 days | Resist flash attacks on governance weight | + +### Cardinality math + +At 12-second blocks, the maximum observation cardinality of 65,535 +provides approximately 218 hours (roughly 9 days) of lookback [9]. +Protocols trading off storage cost vs lookback depth should expand +cardinality to at least `(desired_window_seconds / block_time) + buffer`. +For a 2-hour window at 12s blocks, minimum cardinality is 600 + buffer. + +### Manipulation cost scaling + +Moving the price by 5% on a 1-hour TWAP requires sustaining that 5% +deviation every block for 1 hour, at a cost approximately equal to +the arbitrage losses and fees incurred per block, multiplied by the +number of blocks [10]. Doubling pool liquidity approximately doubles +the cost; doubling the window length approximately doubles the cost. + +## External Oracle Models + +### Push vs pull + +Push oracles (Chainlink) submit price updates to an on-chain contract +on a heartbeat (e.g. every hour) or deviation trigger (e.g. 0.5% +price change). Gas cost per update ranges from 300K to 2.4M gas +depending on the aggregation method [4]. Pull oracles (Pyth, RedStone) +sign data off-chain; the consumer fetches the signed data and submits +it as part of their own transaction, paying the verification gas cost +(approximately 50K to 100K gas per update) [3][5]. + +For new chains, pull is strongly preferred: no dedicated per-chain +node operators, no ongoing gas subsidies, and immediate availability +once the verification contract is deployed. + +### DON vs single-source + +Chainlink's Decentralised Oracle Network (DON) uses Off-Chain +Reporting (OCR) where multiple independent nodes each fetch prices +from premium data aggregators, communicate via P2P, elect a leader +who produces a signed report containing all observations, and submit +the median on-chain [12]. This is technically VWAP (volume-weighted +from multi-exchange aggregation), not a strict TWAP from a single +AMM [12]. + +Single-source oracles (a single AMM TWAP) offer maximum +trustlessness but depend entirely on that source's liquidity and +availability. DON-style oracles trade some trustlessness (off-chain +node operators) for dramatically better manipulation resistance and +market coverage. + +### Comparison table + +| Dimension | AMM TWAP | Pyth | RedStone | Chainlink DON | +|-----------|---------|------|----------|---------------| +| Trust model | Trustless (on-chain) | Semi-trusted (publishers + Wormhole) | Semi-trusted (node signatures) | Semi-trusted (node operators + staking) | +| Data source | Single DEX pool | 70+ first-party publishers | CEX + DEX + aggregators | Premium aggregators (Kaiko, CoinMetrics) | +| Market coverage | On-chain pairs only | 2,800+ feeds (Dec 2025; crypto, FX, equities) | 1,000+ feeds | 1,000+ feeds | +| New-chain deployability | Requires AMM with liquidity | Requires Wormhole | No bridge needed | Requires multiple high-availability RPC providers, valid SSL, JSON-RPC compatibility, 30-day historical RPC performance metrics | +| Manipulation resistance | Scales with pool depth | Independent of on-chain liquidity | Independent of on-chain liquidity | Independent of on-chain liquidity | +| Gas per query | Very low (read accumulator) | 50K to 100K (VAA verification) | 50K to 100K (signature verification) | N/A (push: consumer reads storage) | +| Confidence interval | No | Yes | No | No | +| Real-world assets | No | Yes | Yes (RWA feeds) | Yes | + +## Signature Verification Schemes + +The cost of verifying oracle signatures on-chain dictates whether +LEZ can host an oracle adaptor at all. LEZ is a RISC-V zkVM +execution environment built on RISC0. The on-chain signature +primitive currently wired into the runtime is single-key secp256k1 +Schnorr (BIP-340) over SHA-256, validated as a witness on the +transaction (the runtime checks the signature when it admits the +transaction). This primitive is **not exposed to guest programs**: +a program running inside the RISC-V zkVM cannot invoke it as a +host function. No threshold or aggregate scheme (BLS, Schnorr +multisig, t-Schnorr) is exposed to guest programs either, and no +other signing scheme has a host primitive at all. Any signature +that a program needs to verify (whether BIP-340 Schnorr from a +DLC or FROST publisher, secp256k1 ECDSA from RedStone or Pyth, +ed25519 from Switchboard) has to run as program code inside the +RISC-V zkVM, where verification cost is dominated by the ZK +proving overhead of the underlying primitive. ECDSA recovery and +keccak256 are both expensive to prove; in-circuit Schnorr/SHA-256 +performance on RISC0 is currently unmeasured. The cost question +is identical in shape across signature schemes: how much does +in-circuit verification cost, and is that acceptable for the +adaptor's update cadence. + +This matters because every general-purpose price oracle in +production today (RedStone, Pyth via Wormhole, Chainlink Data +Streams, Chronicle's per-signer leg) signs with secp256k1 ECDSA +over keccak256, and Switchboard signs with ed25519. None of these +match the LEZ-native primitive. Verifying their payloads on chain +therefore requires either (a) adding a secp256k1 ECDSA + keccak256 +precompile to LEZ, or (b) running a trusted relayer that re-signs +upstream payloads in BIP-340 Schnorr over SHA-256, which collapses +the trust set from N publishers to one re-signer. This section walks through what schemes Pyth and +RedStone actually use, and what they cost on chains that do expose +the matching primitive, so the gap between the upstream cost +profile and the LEZ-side cost is visible to the reader. + +### Wormhole VAA verification (Pyth dependency) + +A Verifiable Action Approval (VAA) is the canonical Wormhole +attestation. The guardian set is a fixed roster of 19 nodes; a +super-majority of 13 signatures is required for a VAA to be +considered valid [19][20]. Each guardian signs the +double-keccak256 hash of the VAA body (single keccak256 on Solana, +because the Solana secp256k1 program hashes the message itself) +[19]. The signature scheme is plain m-of-n ECDSA over secp256k1, +with no aggregation: the VAA carries 13 independent (v, r, s) +tuples plus a guardian index per signature [19][21]. Wormhole's +own protocol documentation explains the choice: BLS aggregation +would cost roughly 130K gas to verify on Ethereum, whereas plain +ECDSA via the ecrecover precompile costs about 5K gas per +signature, so the simpler scheme wins on cost despite the linear +verification work [21][22]. + +On EVM chains, the core bridge contract calls verifyVM, which +invokes verifySignatures and loops over the 13 signatures one by +one, calling ecrecover for each [21][22]. The ecrecover +precompile has a fixed base cost of 3,000 gas [23]; combined with +calldata costs, the documented per-signature cost is +approximately 5K + 5K (recovery + calldata), giving roughly 130K +gas for the signature step alone before Merkle proof verification +and storage writes [22]. On Solana, Wormhole calls the native +secp256k1 precompile via verify_signatures, but Solana's per-call +compute-unit budget forces the verification to be split across +multiple instructions, each verifying six or seven signatures at +a time [22][24]. The Solana secp256k1 precompile costs +approximately 6,690 compute units per signature verified [24][25]. +For Pyth specifically, the Perseus upgrade amortises the VAA +verification step across multiple price updates: a single set of +Wormhole signatures is verified once per transaction regardless +of how many feeds are updated, yielding a 50 to 80 per cent gas +reduction when updating five feeds at once [26]. + +Alternative verification paths exist but are not in production +for Pyth. Wormhole has shipped a Boundless ZK verifier (RISC Zero +Groth16 proofs of Ethereum consensus) deployed on Ethereum, Base, +Optimism, Arbitrum, Linea, and Avalanche, with a two-of-two +policy that requires both a valid guardian signature set and a +valid ZK proof before a transfer executes [27]. The +wormhole-foundation/example-zk-light-clients repository contains +ZK light client templates for various source chains [27]. None of +these supersede the 13-of-19 ECDSA path for Pyth price-feed +delivery; they augment it. + +### RedStone per-chain signatures + +RedStone signs every data package with one scheme everywhere it +operates: ECDSA over secp256k1 with a keccak256 message hash, +matching Ethereum's signing convention [28][29]. The reference +implementation lives in the redstone-finance/rust-sdk crate; its +Cargo.toml depends on either the secp256k1 crate (with the +recovery feature) or the k256 ECDSA crate, plus sha3 for keccak +[29]. The crypto module exposes recover_public_key and +recover_address functions that validate signature malleability +against the secp256k1 curve order and accept Ethereum-style +recovery bytes (0, 1, 27, 28) [29]. The on-chain EVM consumer +contract calls SignatureLib.recoverSignerAddress on +keccak256(signedMessage), then enforces a per-feed unique-signer +threshold via getUniqueSignersThreshold(); RedStone's +documentation recommends at least three unique signers as a +balance between security and gas cost [28][30]. + +The signing scheme does not change per chain; only the +verification primitive does. Each chain-specific connector +recovers the same secp256k1 ECDSA signatures using whatever +host-chain primitive is available: + +| Chain | Verification primitive | Source | +|-------|-----------------------|--------| +| EVM | ECRECOVER precompile (secp256k1, keccak256) | [28][30] | +| Solana | secp256k1_recover syscall / secp256k1 program | [25][29] | +| Sui | sui::ecdsa_k1::secp256k1_ecrecover Move builtin | [31] | +| Stellar (Soroban) | recover_key_ecdsa_secp256k1 host function | [32][33] | +| Fuel | Sway contract using secp256k1 recovery | [34] | +| Radix (Scrypto) | Rust SDK with secp256k1 / k256 crate | [29][35] | +| Casper | Rust SDK with secp256k1 / k256 crate | [29] | + +Note: although Stellar's native account model uses ed25519 +(referenced in RedStone's Stellar connector deployment +documentation [36]), RedStone's data-package signing and +verification on Stellar use the same secp256k1 ECDSA over +keccak256 as on every other chain, via Soroban's +`recover_key_ecdsa_secp256k1` host function [32][33]. + +Per-chain verification cost (single signature): + +| Chain | Cost per ECDSA recovery | Source | +|-------|------------------------|--------| +| Ethereum / EVM | 3,000 gas (precompile) plus calldata | [23] | +| Solana | approximately 6,690 compute units | [24][25] | +| Stellar (Soroban) | 2.3M CPU instructions | [32] | + +For an M-of-N RedStone payload with the recommended threshold +of three unique signers [30], total verification cost on EVM is +approximately 9,000 gas for the precompile calls plus calldata +and signer-bitmap accounting; the documented end-to-end gas cost +of a RedStone update on EVM falls in the 50K to 100K range [3] +(consistent with the table in External Oracle Models above). + +### Implications for LEZ + +The discussion below applies only to off-chain price oracles +(external publishers signing data that has to be verified on +chain). The on-chain TWAP tier is structurally separate: it reads +LEZ-native AMM pool state, accumulates price observations, and +exposes them through a program account. No external signature is +involved, so the LEZ-native single-sig BIP-340 Schnorr primitive +is sufficient (it covers transaction authentication, not data +attestation). RFP-019 sits entirely on the on-chain side and is +unaffected by what follows. + +For the off-chain side, the gap is real: every general-purpose +price oracle in production today signs with secp256k1 ECDSA over +keccak256 (RedStone, Pyth via Wormhole, Chainlink, Chronicle's +per-signer leg) or ed25519 (Switchboard). None match the +LEZ-native primitive. The candidates that *do* sign in BIP-340 +Schnorr over tagged SHA-256 are concentrated in the Bitcoin DLC +ecosystem (Pythia from DLC Markets, Sibyls, Suredbits, Ernest +Oracle on Nostr), all of which are single-operator BTC/USD +publishers built around discrete-event attestation rather than +continuous price streams. None today publish ZEC/USD or XMR/USD, +and none are decentralised in the way a DeFi-grade feed needs. + +Four realistic adaptor shapes exist for closing this gap. They +are independent of RFP-019. A constraint that runs across B, C, +and D: no signature-verification primitive is currently exposed +to guest programs on LEZ, so any in-program signature check +(whether ECDSA-keccak for shape D's adaptor, BIP-340 Schnorr for +shape B's federation output, or BIP-340 for shape C's DLC +attestations) runs as RISC-V code inside the RISC0 zkVM. The +cost question is the same shape across all three; only the +upstream supply differs. Shape A avoids the question because the +signature being checked authenticates the LEZ transaction itself, +not data carried inside calldata: the re-signer is a regular LEZ +user, the runtime validates the BIP-340 transaction witness at +admission time as part of the standard transaction-admission flow, +and the price-aggregator program does only an equality check on +the authenticated caller against a registered relayer pubkey. +There is no in-program signature verification, so the in-circuit +cost question never arises. The cost is trust: collapse from N +upstream publishers to one re-signer. + +The structural test that distinguishes A from B/C/D is **whose +signature authenticates the LEZ transaction**. If it is the +re-signer's, the runtime handles verification and the guest +program does an authorisation check on the caller (shape A). If +the LEZ transaction carries an upstream publisher's signature +inside calldata, distinct from the transaction sender, the guest +program has to verify it in-circuit (shapes B/C/D). + +**Shape A — Trusted re-signer relayer.** A LEZ-side process +fetches RedStone or Pyth payloads, verifies them off chain, and +submits a regular LEZ transaction that calls the price-aggregator +program with the resulting price. The relayer's BIP-340 Schnorr +signature is on the transaction itself; the runtime validates it +at admission time. The aggregator program checks the authenticated +caller against a registered relayer pubkey (an equality check, not +a signature verification) and writes the price to a public price +account. The trust set collapses from N upstream publishers to one +re-signer; the chain has no cryptographic evidence that the relayer +reported what the publishers actually signed. + +**Shape B — FROST-BIP340 federation.** A t-of-n federation runs a +distributed key generation and produces a single BIP-340-verifiable +Schnorr signature per price update, aggregating data ingested from +upstream sources. The signing infrastructure already exists as +libraries (Zcash Foundation FROST [45], Blockstream `bip-frost-dkg` +[46], Frostsnap [47]; jesseposner FROST-BIP340 [48] is the +reference implementation), and ZF is actively building FROST +tooling for Zcash, which aligns with the privacy-asset focus. + +**This shape is conditional on LEZ exposing BIP-340 Schnorr** +**verification to guest programs at acceptable cost.** The runtime's +existing BIP-340 primitive validates transaction witnesses only; +it is not callable from a guest program running inside the +RISC-V zkVM. An adaptor that consumes a FROST-aggregated BIP-340 +attestation would therefore have to verify the Schnorr signature +in-circuit, with the same unmeasured ZK-proving cost that ECDSA +verification faces under shape D. The "natively verifiable +without a runtime change" framing only holds if Schnorr +verification is later exposed to guest programs as a host +primitive; **absent that, shape B carries the same cost-question as** +**shape D plus the open R&D risks listed below. Pursuing shape B** +**without that runtime exposure is therefore not the right call.** + +No price-oracle product is deployed in this shape today. Public +framing of FROST by its implementers and grant funders is +exclusively wallet and custody (Blockstream `bip-frost-dkg` README, +ZF FROST documentation, OpenSats and Brink grants for +jesseposner/FROST-BIP340 and Frostsnap, Blockchain Commons HRF 2025 +FROST grant for shared-custody multisig). The closest production +precedent is iBTC Network (formerly dlcBTC; operator rebranded +DLC.Link to BitSafe in 2025), which runs a t-of-n attestor +federation at sizes 10-of-15 (iBTC on EVM) and 7-of-10 (CBTC on +Canton, mainnet October 2025). The federation runs two parallel +signing modes [51]: per-attestor secp256k1 ECDSA over keccak256 +for EVM-bridge attestations (verified on chain by +`ECDSAUpgradeable.recover` per signature, not aggregated), and a +single FROST-aggregated BIP-340 Schnorr signature inside the +Taproot spend path on Bitcoin. The FROST-BIP-340 path is therefore +live but only inside a Bitcoin script; there is no off-chain wire +format that a downstream LEZ verifier could subscribe to as a +single BIP-340 stream. The attestation content is also contract +outcomes (was a burn observed on the counterparty chain) rather +than continuous price data, and the FROST library used is the +project's own `DLC-link/conduition-frost` (a fork-of-fork of ZF +FROST) rather than Blockstream's `bip-frost-dkg` or jesseposner's +implementation. Chainflip +runs FROST in production at 100-of-150 for cross-chain vault signing +[52], showing FROST scales operationally, but its use is internal +transaction signing rather than external attestation. Babylon EOTS +[53] uses BIP-340 Schnorr but is per-validator (not threshold) and +signs consensus votes, not external data. The only academic proposal +specifically for FROST-as-oracle is *FrostOracle* (Chen et al., IEEE +iThings 2023, [54]), which describes the construction but has no +known implementation. + +A consequence of FROST's round-stateful design is that +nonce-management discipline for repeated signing differs from the +one-shot wallet-ceremony model the existing libraries are scoped to. +Public reference deployments of FROST for high-frequency repeated +signing (such as a heartbeat-driven price update) do not exist, and +the existing audits of ZF FROST and `bip-frost-dkg` cover the +wallet-custody threat model rather than an oracle-shaped one. + +**Shape C — DLC-oracle extension.** A handful of DLC oracle +publishers emit BIP-340 attestations natively. + +Two disqualifiers apply, either of which is sufficient on its own. +First, shape C carries the same runtime dependency as shape B: +verifying a DLC attestation requires the guest program to verify +BIP-340 Schnorr in-circuit at unmeasured cost, multiplied by N +(the bit-precision of the numeric DLC encoding). Pursuing shape C +is therefore not the right call unless LEZ later exposes Schnorr +verification to guest programs at acceptable cost. Second, even +with cheap Schnorr verification, the structural fit of the DLC +attestation model is prediction markets and discrete-outcome +contracts (which is what the format was designed for), not +streaming price feeds for DeFi protocols. Either condition alone +moves shape C out of scope for the current oracle work; the +description below documents the ecosystem state for reference and +for a future prediction-market RFP. + +A DLC oracle pre-announces nonce points (R-values) for a future +event with a known maturity time, then at maturity publishes the +s-values that, combined with the pre-committed R-points, yield +BIP-340 Schnorr signatures over a hash of the outcome. The native +cadence is "one attestation per scheduled event," which matches +"did BTC settle above $X on date D" but does not match "what is +BTC/USD right now, updated every 30 seconds." For a continuous +price feed, every update has to be modelled as a scheduled event +in advance, which is an unusual usage pattern relative to what +existing publishers operate. + +#### Two signing conventions in the live ecosystem + +The dlcspecs `Oracle.md` text mandates a tagged SHA-256 +construction with domain `DLC/oracle/announcement/v0` for the +announcement signature and `DLC/oracle/attestation/v0` for the +attestation signature. The live ecosystem does not implement this +uniformly. Two distinct conventions exist, both calling themselves +dlcspecs-compatible: + +- **Plain SHA-256 lineage.** Pythia (DLC Markets) [49], the + P2PDerivatives reference oracle [56], and the rust-dlc reference + verifier all use plain `SHA256(message)` with no tag. Pythia + inherited this from sibyls but removed sibyls' dual-mode support; + rust-dlc's `OracleAnnouncement::validate` and + `OracleAttestation::validate` follow the same plain-SHA-256 path. + Anything verified against this lineage will not verify under a + strict reading of `Oracle.md`. +- **Tagged SHA-256 lineage.** Kormir [57] (active reference + library), Ernest Oracle [58] (which delegates to Kormir), and + Sibyls in `dlc_v0` mode (the `SigningVersion` selected by Lava's + shipped `config/oracle.json` before the operator wound down) use + the tagged construction byte-for-byte per the spec. + +The two lineages produce different signed bytes for the same +underlying message. A LEZ-side verifier consuming attestations +from this ecosystem must either pick a lineage and reject the +other, or maintain both code paths. Choosing the rust-dlc / +plain-SHA-256 path captures the more numerous and more +historically-deployed publishers (Pythia is the only one of those +currently live); choosing the spec-correct tagged path captures +Kormir, Ernest, and any future deployments that follow Kormir's +canonical reference. + +#### State of the live publishers (May 2026) + +- **Pythia (DLC Markets) [49]:** live mainnet, `https://pythia.dlcmarkets.com`, + cron every minute, BTC/USD only, single oracle pubkey, no + rotation, no public attestation index (consumers must already + know the maturity timestamp). Plain SHA-256 lineage. +- **Sibyls (Lava) [50]:** operator dead. `oracle.lava.xyz` returns + 404 (Wayback last-alive 2025-04-14, dead by 2025-11-12). The + `lava-xyz/sibyls` GitHub repo has been deleted; the codebase + exists only on a third-party mirror (`briefgaming/sibyls`) + whose owner is unaffiliated with Lava. Lava itself abandoned + DLCs in late 2025 and went custodial. No surviving Sibyls + operator. +- **P2PDerivatives oracle (Crypto Garage) [56]:** repo dormant + since 2022-05-24. Last historical operator URLs verified dead + (`oracle.10101.finance`, `oracle.lava.xyz`). Library code in + `rust-dlc` continues; the application code is frozen. The only + multi-asset DLC oracle in the survey (BTC/USD plus BTC/JPY) + but not currently published. +- **Kormir [57]:** active library, monthly releases continuing + through March 2026. Live reference deployment at + `kormir.dlcdevkit.com` is dev/test data only. Operator runbook + is minimal (Postgres plus a Nostr nsec key); no bundled price + feed or scheduler. +- **Ernest Oracle [58]:** on hiatus since 2025-06-02. The OpenSats + blog characterises Ernest as a Nostr publisher; the daemon does + not import Nostr in-tree and exposes only an HTTP API on port + 3001 (the Nostr publication path lives in `kormir-server` which + Ernest does not deploy). Implements four Bitcoin chain-metric + attestations (hashrate, fee rate, block fees, difficulty); the + UTXO-size metric mentioned in the announcement post is not in + the source. No public deployment located. Repo is unlicensed + (no LICENSE file, no `license` field in `Cargo.toml`). +- **Magnolia Financial price oracle [59]:** live commercial, + powers Lygos institutional Bitcoin lending. Attestations are + dlcspecs-shaped BIP-340 (per the operator's public statements) + but not publicly retrievable: the documented endpoint + `GET /oracle/events/{eventId}` requires an API key, and there + is no public attestation explorer or relay. Closed source. +- **v0l on Nostr (kind 1009) [60]:** live single-publisher feed. + The signature is BIP-340 native (Nostr's signature scheme) but + the message is `serialised_event_json` per NIP-01 with plain + SHA-256, not the dlcspecs construction. Cannot be reused as a + DLC attestation without the publisher dual-signing. The + successor proposal NIP-1658 defines kinds 31892 / 1892 / 10041, + not kind 1009; kind 1009 is informal and not in the official + NIPs registry. + +#### Numeric DLC verification cost on LEZ + +The numeric DLC encoding signs the outcome bit-by-bit: a price +attested with N-bit precision requires N nonce-point announcements +up front and N independent BIP-340 signatures at maturity, which +the consumer chain verifies in sequence. For 18-bit base-2 +precision (covering integer dollar amounts up to roughly +$262,000; cent granularity for prices in that range would require +27+ binary digits, which is what Pythia's production config uses +at 30 digits), that is 18 single-sig Schnorr verifications per +update on LEZ. As +noted in the Signature Verification Schemes section, BIP-340 +verification is not exposed to guest programs on LEZ, so each of +those 18 verifications runs in-circuit; the per-update cost is +therefore 18× whatever in-circuit BIP-340 + SHA-256 verification +costs in RISC0 (currently unmeasured). If LEZ later exposes +Schnorr verification as a host primitive at low cost, the +multiplier becomes a constant overhead instead of dominating; until +then, shape C inherits the same in-circuit cost question that +shape D's ECDSA path does. + +#### Trust and decentralisation + +Trust is single operator per oracle. DLC's multi-oracle pattern +combines independent attestations via t-of-t adaptor signatures on +the Bitcoin spend path [55]; the LEZ analogue is an aggregator +program that registers K independent BIP-340 publishers and +requires M-of-K agreement within a tolerance window. The +publishers do not coordinate, no DKG is involved, and each +publisher remains a single-key DLC oracle. With Sibyls dead, +P2PDerivatives dormant, Magnolia closed, and Ernest in hiatus, +the realistic candidate set for an LEZ M-of-K federation today is +one (Pythia) plus whatever forks an external builder stands up. + +#### Privacy-asset coverage + +None of the live BIP-340 publishers attest XMR/USD or ZEC/USD. +Pythia's roadmap covers BTC options, not non-BTC pairs. Forking +Pythia or Kormir for additional asset pairs is a few hundred lines +of code (per the deep-research notes for both projects); the +harder constraint is operator obligations (key custody, rotation, +uptime) and pricefeed selection (LN Markets and BitcoinAverage are +BTC-only; Kraken delisted XMR/USD for US users; coverage on +Gate.io and Bitstamp is patchy). + +The cleaner long-term home for shape C is a future prediction- +market RFP, where the discrete-event attestation model is the +native fit and the operational pattern matches what DLC publishers +already run. + +**Shape D — secp256k1 ECDSA on LEZ.** Verify RedStone (or Pyth) +secp256k1 ECDSA + keccak256 signatures on the LEZ side. Two +implementation paths share the same adaptor program shape; only +the verification call site differs. + +**Path D1 (day one): RISC-V in-program verification.** Implement +ECDSA recovery and keccak256 hashing as program code running +inside the RISC0 zkVM, using existing Rust crates (k256 / sha3 / +equivalents) proved by RISC0 along with the rest of the program. +This is what RFP-020 commits to for the public-mode write side. +No runtime change required. Early prototype work +([`fryorcraken/lez-signature-bench`](https://github.com/fryorcraken/lez-signature-bench)) is already enough to establish that +naive in-circuit ECDSA is slow on consumer hardware (proof +generation in the order of minutes for a private read), which +rules out private-execution pull mode under D1 absent a +RISC0-specific signature-verification accelerator. Public-mode +cost remains the open variable RFP-020 measures: it amortises +across all downstream reads, so a write-side cost that would be +unworkable per-private-transaction may still be acceptable per +heartbeat. + +**Path D2 (cost-conditional follow-on): an accelerated precompile +or host function in public-execution mode.** Triggered only if D1 +is too expensive at the push-mode aggregator's production cadence. +A precompile lives outside the ZK proof boundary, so a public-mode +program calls it as native code. The upstream cost reference +points are approximately 6,690 CU per recovery on Solana +[24][25] and an end-to-end RedStone EVM update in the 50K to 100K +gas range [3]; LEZ public-mode cost via a precompile would track +the lower of these two on a constant-overhead basis [22][29]. D2 +is the optimisation path, not a precondition. + +#### Public-mode aggregator design (applies to both D1 and D2) + +The adaptor runs in public execution: the verifier executes once +per update on the write side, and the verified price plus +timestamp land in a public price account. Private-execution +programs compose by reading the public account, not by carrying +signed payloads inline. This is push mode. The reasoning for +preferring it differs slightly between D1 and D2, but the +end-state design is identical. + +Under D1, in-program verification is technically reachable from +private execution (the same RISC-V code can run inside a user's +private proof), but prototype data ([`fryorcraken/lez-signature-bench`](https://github.com/fryorcraken/lez-signature-bench)) +establishes the proof-generation cost is in the order of minutes +on consumer hardware. That makes private-execution pull mode +infeasible in practice, not merely expensive, absent a +RISC0-specific signature-verification accelerator. Push mode +amortises the cost once across all downstream reads on the +public-mode write side instead. + +Under D2, the asymmetry becomes structural rather than economic. +A precompile is unreachable from private execution: anything in a +private transaction has to be expressible inside the RISC-V zkVM +circuit, and a host function lives outside it. Private execution +that wants to verify a secp256k1 signature would have to either +(a) verify in the privacy circuit (forfeits batching, pays +unmeasured RISC0 EC cost, defeats the precompile's purpose), or +(b) place the signature in the transaction's journal and break +privacy. Neither option preserves both efficiency and privacy. So +under D2 push mode is not a preference but the only design that +works. + +In both cases, push mode is the right choice. Under D1 the +amortisation argument carries it; under D2 the structural +argument forces it. The aggregator program is the same either +way, which is what makes D2 a localised swap-in for D1 if cost +forces the upgrade. + +Pull-mode reads are therefore deliberately out of scope: + +- **Pull mode from public execution under D1.** Technically + possible (the in-program verifier can be called from a public + consumer's transaction), but it pays full proving cost per + consumer transaction with no amortisation, which is strictly + worse than reading the push-mode aggregator's public price + account. Excluded by design. +- **Pull mode from private execution under D1.** Possible at + a heavy proving-cost penalty for every private transaction. + Excluded by design. +- **Pull mode from public execution under D2.** Available (a + public consumer can carry a signed payload and call the + precompile inline), but offers no benefit over reading the + push-mode aggregator's public price account. Out of scope. +- **Pull mode from private execution under D2.** Structurally + unavailable (precompile cannot be called from inside the + privacy circuit). Out of scope. + +#### Broader open issues with adding a secp256k1 primitive (path D2 only) + +Beyond the oracle adaptor, the broader question of "what does a +secp256k1 primitive in LEZ unlock" has open design issues that +LEZ runtime developers have flagged but not resolved. The Solana +precompile's main published use case is letting Ethereum users +authorise transactions on Solana with their existing Ethereum +keys; mapping that flow to LEZ raises additional questions: + +- **Nullifier tracking.** Replay protection for secp256k1 + signatures used in either public or privacy execution requires + tracking nullifiers so the same signature cannot be reused. +- **Privacy-circuit branching.** Supporting private accounts + authorised by an Ethereum signature (rather than the LEZ-native + `nsk`) requires branching logic in the privacy circuit. +- **Account-identifier flow.** A recent LEZ change introduces + identifiers that let one private-key set support multiple + private accounts, with maintenance and recovery encrypted under + the viewing public key. Identifiers are not currently supported + for public accounts (each public account requires a fresh key + set), so an Ethereum-signed public-account flow would imply + fresh Ethereum accounts per use, and Ethereum-signed private + accounts would require LEZ-specific wallet support to handle the + identifier flow. + +These issues are not blockers for the narrow oracle-adaptor use of +the precompile (push-mode aggregator writing a public price +account), but they are part of why the LEZ runtime team is not +currently championing a precompile addition: the cost is real, the +in-circuit elliptic-curve performance is unmeasured, and the +compelling-use-case story beyond oracle adaptors is not yet +established. If RFP-020's cost measurement triggers a follow-on +RFP for path D2, that follow-on should be scoped on the assumption +that the precompile is bespoke runtime work that has to be argued +for, not a small extension that is already on the LEZ roadmap. + +For private-account composability with off-chain price data, push +mode is therefore the structural design under both D1 and D2. +The pull-vs-push analysis below frames the same point in terms of +the upstream RedStone / Pyth dichotomy. + +#### Push mode is preferable to pull mode on LEZ + +RedStone supports both pull (signed payload attached to consumer +calldata) and push (a relayer submits signed updates to an +aggregator contract on a heartbeat or deviation trigger). On LEZ +the push model is the better fit: + +- **Verification cost is paid once per update, not once per + read.** The aggregator program recovers signatures and checks + the unique-signer threshold on write, then stores the latest + price and timestamp in a public account. Consumers just read + the slot. The single write-side cost amortises across all + downstream reads instead of being paid by every consuming + transaction. +- **Composes cleanly with private accounts.** A private account + reads a public price-feed account's slot the same way it reads + any other shared public state. Pull mode is the awkward case: + the consumer's transaction must carry the signed payload in + calldata, coupling oracle data into the private execution path + and making both signature recovery and payload handling part of + the private workload. Under D1 this is technically reachable + but pays the full in-circuit ECDSA cost in every private + consumer's proof; under D2 it is structurally unavailable + because the precompile cannot be called from inside the privacy + circuit. Either way push mode is strictly better for private + consumers. +- **Update cadence is a tunable parameter.** Heartbeat plus + deviation threshold trade cost against freshness. For a TWAP + oracle this is acceptable because the consumer is already + smoothing; pull mode's "fresh at transaction time" guarantee + is not required. + +Tradeoffs: push mode requires someone to operate the relayer +(RedStone runs the pusher for their existing push deployments; a +sovereign LEZ deployment would rely on RedStone's relayer or run +its own), and the aggregator program still has to perform +secp256k1 recovery and keccak256 hashing on the write side. Under +D1 that path is RISC-V program code; under D2 it is a precompile +call. The write-side cost per update differs between the two but +the design shape does not. + +There is one freshness pattern that is unusual to LEZ and worth +calling out: a user who needs a price fresher than the +heartbeat's last update can submit a **public transaction that +pushes a fresh signed payload to the aggregator account**, and +then submit a **private transaction immediately afterwards that +reads the just-updated public price**. The verification cost is +paid in the public transaction (where it is cheaper, especially +under D2 where the precompile is callable), and the private +transaction does no signature work at all, just reads a slot. +This pattern is uninteresting on chains without a public / private +execution split because it collapses to ordinary pull mode, but on +LEZ it captures pull mode's "fresh at transaction time" property +without paying the in-circuit cost in the privacy proof. Cost is +borne by the consumer, in the public path, once per private +action that needs a guaranteed-fresh price. The aggregator program +already accommodates this: any caller can submit a valid signed +payload and the program writes if signatures and timestamps check +out. + +A useful corollary: this enables a **consumer-pays push variant** +that does not require a dedicated relayer at all. Users push when +they need a fresh price, paying the verification cost themselves +in the public path; idle periods incur zero update cost; the +aggregator only advances when someone actually needs it. This is +operationally pull (consumer-pays, on-demand) but structurally +push (the program owns the public price account that downstream +private consumers read from). Whether to run a heartbeat relayer +in addition is a deployment-time choice: a heartbeat keeps the +slot warm for protocols that read it without first pushing +themselves; consumer-pays push keeps the cost model strictly +proportional to demand. Both can coexist; the program logic does +not distinguish between them. + +#### How this differs from "put the signature in the journal" + +The two-transaction split (public push, then private read) is +not the same as embedding the upstream signature in the +private transaction's journal. The differences matter: + +- **Two distinct transactions, not one.** The signature is + carried only in the public push transaction. The private + transaction reads the resulting public price account by + address, with no upstream signature in its calldata or + journal. The private transaction's *contents* (which assets, + which counterparty, which amount) remain private; only the + fact that some price update happened is observable, and + that fact is observable for any push regardless of who + submitted it. +- **Fits the existing aggregator design.** The aggregator + program already accepts signed payloads from any caller and + writes a public price account; that is its normal write + path. Consumer-pays push exercises this path from an + end-user wallet rather than from a dedicated relayer. No + new program logic. +- **Linkability risk to clarify, not to wave away.** An + observer can correlate "wallet X pushes a price update at + time T" with "private transaction at time T plus epsilon" + and infer that the same actor is consuming the just-pushed + price. Strength of the inference depends on push frequency + and the consumer's wallet hygiene. Mitigations are + consumer-side, not adaptor-side: push from a separate + funding wallet from the one used in the private + transaction, time-shift the push and consume across enough + blocks that timing correlation weakens, or rely on a + heartbeat relayer so that single-purpose pushes are not the + observable pattern. None of these are guaranteed by the + aggregator program; they are choices the consumer protocol + or end user makes. + +The privacy story is therefore strictly better than +journal-disclosed signatures (the private transaction's body +stays private) but not equivalent to a heartbeat-only push +model (timing-correlation linkability remains). Whether the +residual linkability is acceptable is a consumer-side +production-security decision, the same way any DEX-routing or +liquidity-management decision is. + +RedStone is the simpler day-one option for the upstream-source +side because it carries no bridge dependency. Pyth depends on the +full 13-of-19 VAA verification plus Merkle proof verification, +though it amortises across many feeds per transaction after the +Perseus upgrade [26]. Neither requires threshold or aggregate +schemes (BLS, Schnorr) on the *upstream* side, so the crypto +surface required by shape D is limited to secp256k1 ECDSA +recovery with keccak256 hashing — implemented in-program under D1 +(no runtime change) and exposed as a precompile under D2 (cost- +conditional follow-on). + +## Production Oracle Architectures + +Major lending and borrowing protocols have converged on multi-source +oracle designs with fallback mechanisms. These production patterns +inform the requirements and design rationale of RFP-019. + +### Aave V3 + +Aave V3's `AaveOracle` contract uses Chainlink aggregators as the +primary price source via `getAssetPrice()`. Each asset is mapped to a +Chainlink feed through `setAssetSources()`. If the Chainlink feed +returns a price <= 0, the call is forwarded to a configurable fallback +oracle via `getFallbackOracle()` [15]. On Layer 2 deployments, the +`PriceOracleSentinel` contract monitors sequencer uptime: if the L2 +sequencer goes down, borrowing is disabled and liquidations are paused +for a configurable grace period (`setGracePeriod()`), giving users +time to restore position health after an outage [15]. Aave does not +use TWAP as a primary or secondary price source; it relies entirely +on Chainlink feeds with governance-managed fallback. + +### Compound V2 and V3 + +Compound V2's `UniswapAnchoredView` contract implemented a two-source +design: Coinbase as the primary reporter, anchored against a Uniswap +V2 TWAP. If the Coinbase price diverged beyond 20% of the TWAP +anchor, the price was rejected and the system retained the last valid +price [16]. This is the closest production precedent to RFP-019's +circuit breaker design. On 26 November 2020, a DAI price spike to +$1.30 on Coinbase triggered approximately $89M in liquidations; +the TWAP anchor limited the damage by rejecting the most extreme +prices, but the 20% tolerance was too wide to prevent all +mispricing [16]. Compound V3 (Comet) dropped the TWAP anchor entirely +and uses Chainlink feeds directly via `AggregatorV3Interface`, with +only zero-value validation; some markets use derived-asset price +wrappers (e.g. wstETH/ETH multiplied by ETH/USD) but these are +conversion adaptors, not bounds-checking circuit breakers [16]. + +### MakerDAO / Sky + +MakerDAO's oracle pipeline has two layers: the Median contract +(aggregates prices from multiple whitelisted feed providers) and +the Oracle Security Module (OSM), which imposes a mandatory one-hour +delay before new prices take effect in the system [15a]. The delay +is a circuit breaker by design: it gives governance one hour to +detect and respond to oracle manipulation before the system acts on +a compromised price. Emergency responses include calling `stop()` +to freeze the OSM or triggering Emergency Shutdown. MakerDAO does +not use Uniswap TWAP. Chronicle Protocol evolved from MakerDAO's +internal oracle infrastructure, using Schnorr signature aggregation +to consolidate validator signatures into a single "super signature," +achieving constant-time verification at approximately 52K gas +regardless of the number of validators [15b]. + +### Liquity V2 + +Liquity V2 explicitly rejected Uniswap V3 TWAP as a primary or +fallback source due to liquidity migration risk (uncertainty about +whether v3 liquidity would persist after the Uniswap v4 launch) +[18]. Instead, Liquity V2 uses Chainlink as the primary oracle (composing multiple +Chainlink feeds for LST collateral, e.g. ETH/USD combined with an +LST market-rate feed) with a simple fallback: if the primary feed +is frozen for more than 12 hours or returns bad data, the system +falls back to a secondary oracle (once, with no cascading). Liquity V2 explicitly prefers +this simple fallback over complex circuit breaker designs (e.g. +Gyroscope's pause-on-divergence model), reasoning that pausing +operations requires human intervention to set a new oracle and +unpause, which conflicts with their immutability goals [18]. The design prioritises automation: simple +trigger conditions, single fallback, no manual intervention required. + +### Common patterns + +| Protocol | Primary | Secondary / fallback | Circuit breaker | TWAP role | +|----------|---------|---------------------|-----------------|-----------| +| Aave V3 | Chainlink | Governance-set fallback | PriceOracleSentinel (L2 sequencer) | None | +| Compound V2 | Coinbase reporter | Last valid price | 20% TWAP anchor tolerance | Anchor / sanity check | +| Compound V3 | Chainlink | None (governance pauses) | Zero-value check only | None | +| MakerDAO | Median (multi-feed) | Emergency Shutdown | 1-hour OSM delay | None | +| Liquity V2 | Chainlink | Simple fallback (one hop) | None (by design) | Rejected | + +Two patterns emerge. First, most major lending protocols use at +least two tiers of price validation (Aave, MakerDAO, Liquity V2, +Compound V2): cross-check, delay, or fallback. Compound V3 is the +notable exception, relying on Chainlink with only zero-value +validation and governance-managed pause as its safety net. Second, +TWAP serves as an anchor or sanity check in the protocols that use +it (Compound V2), never as the sole price source for lending. These +patterns motivate RFP-019's two-tier architecture (on-chain TWAP + +external feeds) and circuit breaker design as a defence-in-depth +choice rather than a universal industry default. + +## Privacy-Asset Feed Availability + +LEZ's privacy focus likely makes XMR/USD and ZEC/USD first-class +pricing requirements. On-chain TWAP cannot supply these prices: no +wrapped XMR or ZEC token has sufficient DEX liquidity (low five to +six figures across all surveyed pools on Ethereum and Solana) for a +manipulation-resistant TWAP, so an off-chain feed is the only viable +path on day one. Coverage across the surveyed oracles is summarised +below. + +| Oracle | XMR/USD | ZEC/USD | Self-serve on LEZ? | +|--------|---------|---------|--------------------| +| Chainlink (push) | Active on Optimism (1,200s heartbeat, 0.2% deviation) and Polygon (24h, 1%) [39] | Active on Ethereum (24h, 2%) and Polygon (24h, 1%) [40] | No: permissioned onboarding | +| Chainlink Data Streams | 43+ chains, subscription-gated [39] | 35+ chains, subscription-gated [40] | No: paid product | +| Pyth (pull) | `crypto-xmr-usd`, multiple publishers across both Pyth clusters; live count at [41] | `crypto-zec-usd`, multiple publishers; live count at [41] | Yes, once Wormhole endpoint and the Pyth receiver are deployed | +| RedStone (pull) | Listed; data feed ID `XMR` [42] | Listed; data feed ID `ZEC` [42] | Yes once shape D1 or D2 lands per RFP-020 (LEZ-side ECDSA + keccak verification path); no bridge dependency on the upstream side, no per-chain RedStone team engagement | +| DIA / Lumina | Production-ready (MAIR aggregation, 120s, announced January 2026) [43] | Available (MAIR, 120s) [43] | Yes via Lumina; bespoke deployment per chain | +| Supra | XMR_USDT, 195 sources (Standard tier) [44] | ZEC_USDT, 60 sources (Premium tier) [44] | No: requires Supra team engagement | +| Chronicle | Not in public feed catalogue | Not in public feed catalogue | N/A | +| API3 | Not found | Not found | N/A | +| Switchboard | Not found | Not found | Permissionless feed creation supported but no XMR or ZEC feed currently exists | + +## LEZ Bootstrap Strategy + +### Phase 1: Genesis (no TVL) + +Deploy RedStone pull oracle contract (no bridge dependency) and, if +Wormhole is available, the Pyth EVM receiver contract. This provides +400 to 1,500+ price feeds immediately with zero per-chain oracle node +infrastructure [3][5]. RedStone is the practical day-one oracle +because it requires no cross-chain bridge; Pyth is conditional on +Wormhole integration [8]. + +### Phase 2: Early growth (first DEX, some TVL) + +Once RFP-004 (DEX) is live, deploy the on-chain TWAP oracle as a +supplementary data source. At this stage, TWAP should be used only +as a sanity check (circuit breaker comparison against external feeds), +not as a primary price source, because pool liquidity will be +insufficient for manipulation resistance [10]. + +Engage Switchboard for core EVM contract deployment (TEE security, +permissionless custom feeds). Consider DIA Lumina as a permissionless +fallback for assets not covered by Pyth or RedStone [7]. + +### Phase 3: Maturity (significant TVL) + +As DEX pools grow beyond $50M to $100M in depth, on-chain TWAP +becomes a viable secondary price source for lending and liquidation +use cases. At this stage, multi-source aggregation (median of TWAP + +Pyth + RedStone) provides the highest reliability [6]. + +Engage Chainlink for official DON deployment once LEZ meets +infrastructure requirements (3+ independent RPC providers, sufficient +TVL, dedicated node operators). Treat Chainlink as a 12 to 24 month +post-launch milestone [4][8]. + +### Graduation path + +The TWAP tier's role evolves with liquidity: + +| Pool depth | TWAP role | Recommended window | +|------------|-----------|-------------------| +| < $1M | Not usable (manipulation trivially cheap) | N/A | +| $1M to $10M | Sanity check only (circuit breaker) | 2 to 12 h | +| $10M to $50M | Secondary source (median with external) | 30 min to 2 h | +| > $50M | Co-primary source alongside external feeds | 30 min to 1 h | + +## References + +1. DefiLlama, "Oracles" dashboard, accessed Q1 2026. + https://defillama.com/oracles +2. Mitosis University, "Which Oracle Powers What," 2025. + https://university.mitosis.org/chainlink-pyth-redstone-chronicle-supra-switchboard-which-oracle-powers-what/ +3. RedStone, "Blockchain Oracles Comparison: Chainlink vs Pyth vs + RedStone 2025," Jan 2025. + https://blog.redstone.finance/2025/01/16/blockchain-oracles-comparison-chainlink-vs-pyth-vs-redstone-2025/ +4. Chainlink, "Network Integration Requirements." + https://docs.chain.link/resources/network-integration +5. Bai et al., "Ormer: A Manipulation-Resistant and Gas-Efficient + Blockchain Oracle Scheme," arXiv:2410.07893v2, Oct 2024. + https://arxiv.org/html/2410.07893v2 +6. ChainSecurity, "Oracle Manipulation After The Merge," 2022. + https://www.chainsecurity.com/blog/oracle-manipulation-after-merge +7. DIA, "Lumina" documentation, accessed 2026. + https://www.diadata.org/lumina/ +8. Pyth Network, "Cross-Chain Delivery" documentation. + https://docs.pyth.network/price-feeds/core/how-pyth-works/cross-chain +9. Uniswap, "Oracle" (v3 protocol concepts). + https://docs.uniswap.org/concepts/protocol/oracle +10. Uniswap Labs, "Uniswap v3 Oracles" (PoS analysis), 2022. + https://blog.uniswap.org/uniswap-v3-oracles +11. SmartContent, "TWAP Oracles vs Chainlink Price Feeds: A + Comparative Analysis." + https://smartcontentpublication.medium.com/twap-oracles-vs-chainlink-price-feeds-a-comparative-analysis-8155a3483cbd +12. Chainlink, "Off-Chain Reporting" documentation. + https://docs.chain.link/architecture-overview/off-chain-reporting +13. Switchboard, "Protocol" documentation. + https://docs.switchboard.xyz/how-it-works/switchboard-protocol +14. Uniswap, "Oracles" (v2 protocol concepts). + https://docs.uniswap.org/contracts/v2/concepts/core-concepts/oracles +15. Aave, "Oracles" (v3 smart contracts documentation). + https://aave.com/docs/aave-v3/smart-contracts/oracles +15a. MakerDAO, "Oracle Security Module (OSM)" documentation. + https://docs.makerdao.com/smart-contract-modules/oracle-module/oracle-security-module-osm-detailed-documentation +15b. Chronicle Labs, "Understanding Chronicle" documentation. + https://docs.chroniclelabs.org/understandingChronicle +16. Compound Finance, "Price Feed" documentation. + https://compound.finance/docs/prices +17. RedStone, "Blockchain Oracles Comparison: Chainlink vs Pyth vs + RedStone 2026," Mar 2026. + https://blog.redstone.finance/2026/03/30/blockchain-oracles-comparison-chainlink-vs-pyth-vs-redstone-2026/ +18. Liquity, "The Oracle Conundrum," 2023. + https://www.liquity.org/blog/the-oracle-conundrum +19. Wormhole, "VAAs (Verifiable Action Approvals)" documentation, + accessed Apr 2026. + https://wormhole.com/docs/protocol/infrastructure/vaas/ +20. Wormhole, "Guardians" documentation, accessed Apr 2026. + https://wormhole.com/docs/protocol/infrastructure/guardians/ +21. Wormhole, "Security" documentation, accessed Apr 2026. + https://wormhole.com/docs/protocol/security/ +22. Sec3, "How Do Cross-Chain Bridges Work? A Case on Wormhole + (Part 2)," 2022. + https://www.sec3.dev/blog/bridges2 +23. Ethereum, "Precompiled Contracts" (ECRECOVER at address 0x01, + base cost 3,000 gas). + https://www.evm.codes/precompiled +24. Solana Labs, "block_cost_limits.rs" (secp256k1 verification + compute units). + https://github.com/solana-labs/solana/blob/master/cost-model/src/block_cost_limits.rs +25. Solana Foundation, "Fee Structure" (Ed25519, Secp256k1, + Secp256r1 precompile programs). + https://solana.com/docs/core/fees/fee-structure +26. Pyth Network, "Perseus Network Upgrade" blog post, 2025. + https://www.pyth.network/blog/perseus-network-upgrade +27. Wormhole, "Boundless Partners with Wormhole to Launch ZK + Network Powered by RISC Zero," 2025. + https://wormhole.com/blog/boundless-partners-with-wormhole-to-launch-zk-network-powered-by-risc-zero +28. RedStone, "How Data Flows to the Blockchain" architecture + documentation, accessed Apr 2026. + https://docs.redstone.finance/docs/architecture/ +29. RedStone, "rust-sdk" repository (crates/redstone, including + crypto/mod.rs and Cargo.toml dependencies on secp256k1 and + k256). + https://github.com/redstone-finance/rust-sdk +30. RedStone, "redstone-oracles-monorepo" EVM connector + (RedstoneConsumerBase.sol, getUniqueSignersThreshold, + SignatureLib.recoverSignerAddress). + https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/evm-connector/contracts/core/RedstoneConsumerBase.sol +31. Sui Documentation, "Module sui::ecdsa_k1" + (secp256k1_ecrecover Move builtin). + https://docs.sui.io/references/framework/sui_sui/ecdsa_k1 +32. Stellar, "CAP-0051: Smart Contract Host Functionality" + (recover_key_ecdsa_secp256k1, 2.3M CPU instructions). + https://github.com/stellar/stellar-protocol/blob/master/core/cap-0051.md +33. Veridise, "RedStone Stellar Connector" security assessment, + Oct 2025. + https://veridise.com/wp-content/uploads/2025/10/VAR-Redstone-251006-Oracles-SDK-V2.pdf +34. RedStone, "redstone-oracles-monorepo" Fuel connector + (Sway contract adapter). + https://github.com/redstone-finance/redstone-oracles-monorepo/blob/main/packages/fuel-connector/README.md +35. RedStone, "RedStone Brings Secure, Gas-Efficient Oracle + Solutions to Radix DeFi Ecosystem," Jun 2025. + https://blog.redstone.finance/2025/06/12/redstone-brings-secure-gas-efficient-oracle-solutions-to-radix-defi-ecosystem/ +36. RedStone, "redstone-oracles-monorepo" Stellar connector + DeployingFeed.md (Stellar account key uses Ed25519-curve; + refers to deployer key, not RedStone signing scheme). + https://github.com/redstone-finance/redstone-oracles-monorepo/blob/570006fccf0f919ad9722d11914dd0bc1c5b136d/packages/stellar-connector/DeployingFeed.md +37. CoinDesk, "Bitcoin Flash Crashed to $5K on Pyth Network's Data + Feed," Sep 2021. + https://www.coindesk.com/markets/2021/09/22/bitcoin-flash-crashes-to-5k-on-pyth-networks-data-feed +38. Morpho governance forum, "PYTH CBETH price feed is easily + manipulated, resulted in me losing $33,000," Mar 2025. + https://forum.morpho.org/t/pyth-cbeth-price-feed-is-easily-manipulated-resulted-in-me-losing-33000/1577 +39. Chainlink, XMR/USD price feeds: Optimism Mainnet + (`0x2a8D91686A048E98e6CCF1A89E82f40D14312672`) and Polygon + Mainnet (`0xBE6FB0AB6302B693368D0E9001fAF77ecc6571db`); Data + Streams XMR/USD-RefPrice product on 43+ chains. + https://data.chain.link/feeds/optimism/mainnet/xmr-usd + https://data.chain.link/feeds/polygon/mainnet/xmr-usd + https://data.chain.link/streams/xmr-usd-cexprice-streams +40. Chainlink, ZEC/USD price feeds: Ethereum Mainnet + (`0x3f929667bdf783b99274F10465a89d6aF772736E`) and Polygon + Mainnet (`0xBC08c639e579a391C4228F20d0C29d0690092DF0`); Data + Streams ZEC/USD-RefPrice product on 35+ chains. + https://data.chain.link/ethereum/mainnet/crypto-usd/zec-usd + https://data.chain.link/feeds/polygon/mainnet/zec-usd + https://data.chain.link/streams/zec-usd-cexprice-streams +41. Pyth Network, legacy price feeds dashboard + (`crypto-xmr-usd`, `crypto-zec-usd`). + https://insights.pyth.network/legacy-price-feeds/crypto-xmr-usd + https://insights.pyth.network/legacy-price-feeds/crypto-zec-usd +42. RedStone, "ALL_SUPPORTED_TOKENS" registry (XMR and ZEC listed). + https://github.com/redstone-finance/redstone-api/blob/main/docs/ALL_SUPPORTED_TOKENS.md +43. DIA, asset price index (XMR and ZEC). + https://www.diadata.org/app/price/asset/Monero/0x0000000000000000000000000000000000000000/ + https://www.diadata.org/app/price/asset/Zcash/0x0000000000000000000000000000000000000000/ +44. Supra, "Data Feeds Index" (XMR_USDT, ZEC_USDT). + https://docs.supra.com/oracles/data-feeds/data-feeds-index +45. Zcash Foundation, FROST (Flexible Round-Optimised Schnorr + Threshold) reference implementation and documentation. + https://frost.zfnd.org/ +46. Blockstream Research, `bip-frost-dkg` (FROST distributed key + generation, BIP-340 compatible). + https://github.com/BlockstreamResearch/bip-frost-dkg +47. Frostsnap, hardware-wallet stack using secp256kfun for FROST + threshold Schnorr. + https://github.com/frostsnap/frostsnap +48. Jesse Posner, `FROST-BIP340` (reference implementation of + FROST emitting BIP-340-verifiable signatures). + https://github.com/jesseposner/FROST-BIP340 +49. DLC Markets, "DLC Markets open-sources its oracle Pythia," + May 2025; Pythia source. + https://blog.dlcmarkets.com/dlc-markets-open-sources-its-oracle-pythia/ + https://github.com/dlc-markets/pythia +50. Lava, `sibyls` (DLC oracle implementing BIP-340 attestation + over numeric outcomes). + https://github.com/lava-xyz/sibyls +51. iBTC Network (formerly DLC.Link / dlcBTC), "FROST at DLC.Link: + Pioneering Advanced Security for DLCs"; technical stack + documentation describing the 5-of-7 attestor federation. + https://www.ibtc.network/blog/frost-at-dlc-link-pioneering-advanced-security-for-dlcs + https://docs.dlc.link/tech-stack +52. Chainflip, "FROST Signature Scheme" protocol documentation + (100-of-150 threshold for cross-chain vault signing). + https://docs.chainflip.io/protocol/frost-signature-scheme +53. Babylon Labs, "EOTS Manager" architecture documentation + (per-validator BIP-340 Schnorr finality voting; not threshold). + https://docs.babylonlabs.io/guides/architecture/btc_staking_program/eots_manager/ +54. Chen et al., "FrostOracle: A Novel and Efficient Blockchain + Oracle Scheme Based on Threshold Signature," IEEE iThings/ + CPSCom 2023. + https://ieeexplore.ieee.org/document/10501857/ +55. Discreet Log Contracts specifications, "MultiOracle.md" + (combining independent oracle attestations via t-of-t + adaptor signatures). + https://github.com/discreetlogcontracts/dlcspecs/blob/master/MultiOracle.md +56. P2PDerivatives / Crypto Garage, `p2pderivatives-oracle` + reference DLC oracle (Go; signs BTC/USD and BTC/JPY; repo + last commit 2022-05-24). + https://github.com/p2pderivatives/p2pderivatives-oracle +57. Kormir, reference Rust DLC oracle library + (`bennyhodl/dlcdevkit/kormir`; tagged SHA-256 per dlcspecs; + monthly releases through March 2026). + https://github.com/bennyhodl/dlcdevkit +58. Ernest Oracle (`ernest-money/ernest-oracle`); Bitcoin + chain-metric DLC oracle delegating to Kormir; HTTP-only, + no Nostr publication in-tree; on hiatus since 2025-06-02. + https://github.com/ernest-money/ernest-oracle +59. Magnolia Financial Services, "Oracles" product page; + commercial DLC oracle powering Lygos, attestations gated + behind API key. + https://magnolia.financial/oracles/ +60. NIP-1658, asset price publishing on Nostr (proposed kinds + 31892 / 1892 / 10041); kind 1009 is informal and not in + the official NIPs registry. + https://github.com/nostr-protocol/nips/pull/1658