Skip to content

rfp: add RFP-019 TWAP oracle and price feed infrastructure#37

Open
fryorcraken wants to merge 23 commits intomasterfrom
rfp/twap-oracle
Open

rfp: add RFP-019 TWAP oracle and price feed infrastructure#37
fryorcraken wants to merge 23 commits intomasterfrom
rfp/twap-oracle

Conversation

@fryorcraken
Copy link
Copy Markdown
Collaborator

@fryorcraken fryorcraken commented Apr 7, 2026

Design Rationale is ready to be reviewed before we jump in the scope/requirements

@fryorcraken fryorcraken changed the title rfp: add RFP-018 TWAP oracle and price feed infrastructure rfp: add RFP-019 TWAP oracle and price feed infrastructure Apr 8, 2026
Copy link
Copy Markdown

@seugu seugu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the informative RFP doc!

#### Functionality

1. Implement an on-chain TWAP oracle program that reads pool
accumulators from a LEZ DEX (RFP-004) and computes the geometric
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

computes the geometric mean

I assume that we do not need private computation here all computations can be done by the public executions right? Theregore, everyone can query and use the oracle price in their LEZ Dapps.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed: oracle programs run as public LEZ executions with no confidential state. All accumulator updates, TWAP computation (including the geometric mean), external feed verification, and price queries are visible to any caller, and any LEZ dapp can read the same canonical price. I have added a "Public oracle execution" subsection to the Design Rationale to make this explicit. Confidential execution is reserved for application-layer protocols that consume oracle prices (e.g. private DEX swaps in RFP-004); the price feed itself stays public.

Comment thread RFPs/RFP-019-twap-oracle.md Outdated
3. Provide a query interface: given a pool address and a window
length, return the TWAP price and the observation timestamps
used.
4. Implement an external oracle adaptor for Pyth: verify Wormhole
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that Wormhole verification requires 13 many ECDSA sig verification (one by one) over secpk256 curve from this and this which looks doable in LEZ due to its native curve, only it requres to implement ECDSA.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed against primary sources. The new "Signature Verification Schemes" appendix section documents this in detail: 19 guardians, 13-of-19 quorum, plain ECDSA over secp256k1 (no aggregation). LEZ inherits Solana's native secp256k1 SigVerify precompile, so VAA verification is feasible without new opcodes; the precompile is invoked in batches of 6-7 due to per-instruction CU limits (approximately 6,690 CU per signature, so ~87K CU for the full 13-sig set, plus the Merkle proof). Pyth's Perseus upgrade amortises this across multiple feeds for a 50-80% reduction. ZK alternatives (Boundless / RISC Zero) exist for some flows on Ethereum / L2 but are not used by Pyth in production.


**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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for redstone verification, I think they have different sig types for chains e.g. for EVM its ECDSA over the secp256k1, while for steallar they use curve25519 ref. We can choose the optimum type among these for LEZ.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Investigated against primary sources and the picture is a bit different from what the link suggests. RedStone uses the same signing scheme on every chain it serves: secp256k1 + keccak256 (Ethereum-style ECDSA) data packages. The Ed25519-curve reference in DeployingFeed.md is about the Stellar deployer account key (Stellar's native account model is ed25519), not about RedStone's data-package signature scheme. Confirmed via the rust-sdk Cargo.toml (depends on secp256k1 and k256 with sha3, no ed25519), the EVM connector (uses ecrecover on keccak256), and the Veridise audit of the Soroban Stellar contract (describes ECDSA validation). Each chain connector recovers the same ECDSA signatures using whatever host primitive is available; on Stellar that is CAP-0051's recover_key_ecdsa_secp256k1 (~2.3M CPU instructions). Implication for LEZ: no per-chain optimum to pick; LEZ inherits Solana's secp256k1 precompile and can verify RedStone's M-of-N data packages directly (approximately 20K to 35K CU for 3-of-N), making RedStone the simpler day-one integration. New "RedStone per-chain signatures" subsection in the appendix documents this with citations.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this is better.


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
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semantic Line Breaks is not applied here right?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sembr makes it difficult to read raw documents, so I usually dont apply it when it's not a protocol spec or something else that needs hard tracking.

fryorcraken added a commit that referenced this pull request Apr 28, 2026
Clarify that oracle programs run as public LEZ executions (per seugu
review). Add Signature Verification Schemes appendix section documenting
the Wormhole VAA scheme (13-of-19 ECDSA secp256k1) and RedStone's
per-chain signature reality (secp256k1 + keccak256 everywhere; the
Stellar Ed25519 reference is the deployer account key, not the data
package scheme). Refresh stale Q1 2026 figures: Chainlink TVS, Pyth
chain/feed/publisher counts, Chronicle and RedStone TVS. Correct
Compound V3 description (zero-value validation only, not
bounds-checking circuit breaker) and re-cite the Pyth incident list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fryorcraken and others added 8 commits April 28, 2026 16:22
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clarify that oracle programs run as public LEZ executions (per seugu
review). Add Signature Verification Schemes appendix section documenting
the Wormhole VAA scheme (13-of-19 ECDSA secp256k1) and RedStone's
per-chain signature reality (secp256k1 + keccak256 everywhere; the
Stellar Ed25519 reference is the deployer account key, not the data
package scheme). Refresh stale Q1 2026 figures: Chainlink TVS, Pyth
chain/feed/publisher counts, Chronicle and RedStone TVS. Correct
Compound V3 description (zero-value validation only, not
bounds-checking circuit breaker) and re-cite the Pyth incident list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Document XMR/USD and ZEC/USD coverage across surveyed oracles
(Chainlink push and Data Streams, Pyth, RedStone, DIA, Supra,
Chronicle, API3, Switchboard) with self-serve-on-LEZ assessment
for each. Pure factual content; no recommendations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Narrow RFP-019 to the on-chain TWAP tier only (TWAP program,
canonical oracle price account standard, circuit-breaker interface).
Move the external oracle adaptor work into a dedicated RFP-020 for
RedStone, motivated by enabling private DeFi via day-one XMR/USD
and ZEC/USD feeds on LEZ. Pyth is deferred to a future RFP since it
depends on Wormhole on LEZ. RFP-020 references the canonical
standard from RFP-019 and frames the LSC stablecoin Path A vs Path
B choice as a business decision left to the RFP-013 implementer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the section structure used in RFP-015/RFP-016 (Design
Rationale with emoji header) and RFP-008/RFP-012 (Out of Scope
section). Drop the non-standard Evaluation Criteria section and
extend Supportability with the standard doc-packet and Figma
requirements that live RFPs use.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the AI-tell vocabulary ("robust" twice; "the clearest
day-one differentiator and the most direct path"; "informed by
the realities of") and recast trailing participles ("reducing
reliance on any one source") as direct statements. No content
changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fryorcraken and others added 2 commits May 1, 2026 16:35
RFP-020 now implements secp256k1 ECDSA + keccak256 verification as
RISC-V program code inside RISC0 on day one; a precompile is a
cost-conditional follow-on, not a hard prerequisite. Cost
measurement of the in-program path is a primary deliverable.

Appendix expanded to reflect the actual LEZ runtime (RISC-V zkVM on
RISC0; BIP-340 wired as the transaction-witness primitive only, not
exposed to guest programs) and restructured around four adaptor
shapes: A trusted re-signer (rejected), B FROST federation
(conditional on Schnorr verification for guest programs), C DLC
oracles (better fit for prediction markets; same conditional), D
secp256k1 ECDSA on LEZ, with D split into D1 (in-program, day 1)
and D2 (precompile, cost-conditional follow-on).

Adds per-publisher state-of-play for the BIP-340 oracle ecosystem,
the dlcspecs plain-SHA-256 vs tagged-SHA-256 split between rust-dlc
and Kormir lineages, iBTC federation correction (10-of-15 on iBTC,
7-of-10 on CBTC; FROST live only on the Bitcoin spend path), a
Uniswap v4 hook note in the v3 accumulator section, and references
[45]-[60] for FROST tooling and DLC oracle infrastructure.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ixes, prose pass

RFP-019 Design Rationale gains a "What the production record
actually shows" subsection under Circuit-breaker interface,
quoting four documented saves (Curve / Vyper July 2023, USDe
Binance flash October 2025, MakerDAO OSM March 2025, Base
sequencer August 2025) and the counter-evidence (Compound V3
walked away from the TWAP anchor; Aave removed PriceOracleSentinel
in v3.7 with no documented saves; Aave CAPO wstETH glitch March
2026). Closes with the load-bearing-layer-is-source-diversification
framing and an instruction that the Recommended Consumer Pattern
should treat divergence-flag cross-check as a guard rail, not a
primary defence.

RFP-019 + RFP-020 Usability + Supportability gain explicit
requirements for a reference consumer program and a "Recommended
Consumer Pattern" section in the SDK doc packet. RFP-019 soft
requirements rewritten: dropped the median-aggregation, Ormer, and
historical-API items (each contradicted the design or duplicated
existing functionality); replaced with a single aggregator-helper
SDK utility item.

Appendix fact-check fixes: Pyth feed-count drift between tables
resolved (1,500+ -> 2,800+); Chainlink and Chronicle TVS rows
date-stamped against Q1 2026 reporting; Switchboard / Supra rows
gain DefiLlama citation; comparison-table Chainlink RPC cell
updated to match the corrected prose; "Self-serve on LEZ" RedStone
cell tightened to make the shape D dependency explicit; Liquity V2
"explicitly rejects" softened to "explicitly prefers"; numeric DLC
"cent granularity" framing tightened against base-2 precision math;
ChainSecurity reference URL updated to canonical form.

Both RFPs run through the humanize-prose skill: removed intensifier
and promotional-tone clusters from the Overview / Why This Matters
/ LEZ-data-standard sections; replaced prose em-dashes with colons;
spelling normalised to Australian English. Heading-construction
em-dashes preserved per project convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fryorcraken
Copy link
Copy Markdown
Collaborator Author

Appendix and RFP-19 ready to review

fryorcraken and others added 11 commits May 1, 2026 18:17
…mer-pays push variant

The LEZ public / private execution split enables a freshness
pattern that doesn't apply to other chains: a user who needs a
fresh price can submit a public transaction that pushes a signed
payload to the aggregator account, then submit a private
transaction immediately after that reads the just-updated price.
Verification cost is paid in the public path (cheaper, especially
under the precompile follow-on); the private path does no
signature work. This recovers pull mode's "fresh at transaction
time" property for private consumers without paying in-circuit
verification cost in the privacy proof.

The same mechanism enables a consumer-pays push variant that does
not require a dedicated relayer: users push when they need a
fresh price, idle periods incur zero update cost, the aggregator
only advances when someone needs it. Operationally pull,
structurally push. Heartbeat relayer (RedStone's own pusher or a
sovereign one) and consumer-pays push can coexist; the program
logic does not distinguish between them.

Documented in the appendix's "Push mode is preferable to pull
mode on LEZ" subsection and mirrored in RFP-020's
public-mode-aggregator design rationale.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…data

Early prototype work on in-program secp256k1 ECDSA inside RISC0
(`fryorcraken/lez-ecdsa`) puts proof generation in the order of
minutes on consumer hardware. That is enough to rule out
private-execution pull mode in practice, absent a RISC0-specific
signature-verification accelerator. The framing across the
Overview, the Public-mode-aggregator subsection, the RISC-V
verification path subsection, and the appendix shape D body now
reflects this:

- Private-execution pull mode is treated as out of reach, not as
  "expensive but possible".
- Cost measurement remains a primary deliverable, but scoped to
  the public-mode write side, where amortisation across all
  downstream reads can make a per-update cost workable that
  would be unworkable per-private-transaction.
- The escape hatch is explicit: a RISC0-specific signature-
  verification accelerator (e.g. a future risc0-ecdsa extension
  or a secp256k1 precompile in the zkVM proving system itself)
  could change the picture; until one lands, treat the result as
  fixed.

The push-mode design is the working assumption, not a
contingent choice; the precompile follow-on is closer to expected
than conditional.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Convert the bare `fryorcraken/lez-ecdsa` references to proper
markdown links pointing at https://github.com/fryorcraken/lez-ecdsa
so a reader can click through to the prototype.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The (Scope note: ... unrelated to the RLN service-attestation
oracle work on the anon-comms roadmap.) parenthetical assumes the
reader knows what RLN is. For a reader who doesn't, it adds noise
without saving them from a real misread risk.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "Logos's thesis is private DeFi" line was internal-strategy
language. The relevant motivation for an external builder is that
LEZ is positioned to support private DeFi, that USD reference
prices for XMR and ZEC are a necessary step, and that downstream
RFPs (RFP-013 stablecoin, RFP-004 DEX, wrapped privacy assets)
depend on those prices. Rewritten accordingly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the bare "without an off-chain oracle adaptor, none of
these applications can ship" closer with the substance: TWAP is
not sufficient on its own at LEZ launch (linear-with-depth
manipulation cost on thin pools, plus the structural fact that
XMR/USD and ZEC/USD have no on-chain pools to TWAP from), so an
off-chain feed is the only way to get the day-one prices on
chain. Pairs the TWAP-and-off-chain layered defence framing in
the appendix and RFP-019.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the Path A vs Path B decomposition (LSC-specific) with a
shorter "building blocks, not a production-grade design" framing.
Acknowledges that neither off-chain nor on-chain TWAP is a
complete oracle on its own and that the production norm is
layering, then notes that consuming protocols compose the pieces
according to their own production-security choices. The canonical
price account standard from RFP-019 keeps swap-out cheap if those
choices change later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous heading misread as if the deliverable itself were
not production-grade. The point is the opposite: this RFP delivers
production-grade code for one building block in a layered oracle
stack. Renamed to "A building block in a layered oracle stack"
and added an explicit "production-grade code on its own terms"
clause in the body.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…al-disclosed sigs

The previous text introduced the consumer-pays push variant
without distinguishing it from the rejected "put the signature
in the journal" option. That risked reading as if the same
privacy concern applied. Add an explicit clarification in both
the appendix and RFP-020:

- Two-transaction split: signature lives in the public push
  transaction only; the private transaction reads the public
  price account by address with no upstream signature in its
  body. Private transaction's contents (assets, counterparty,
  amount) stay private.
- Fits the existing adaptor write path: the program already
  accepts signed payloads from any caller; consumer-pays push
  exercises that path from an end-user wallet rather than from
  a dedicated relayer. No new program logic.
- Residual linkability risk: an observer can correlate a public
  push from wallet X at time T with a private transaction at
  time T+epsilon and infer the same actor consumes the
  just-pushed price. Mitigations (separate funding wallet for
  the push, timing decorrelation, heartbeat masking) are
  consumer-side production-security choices, not adaptor-side
  guarantees.

Privacy story is strictly better than journal-disclosed
signatures, not equivalent to a heartbeat-only push model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "D1" / "D2" labels are appendix internals (Path D1 = in-program,
Path D2 = precompile follow-on, under shape D in the four-shape
analysis). A reader of RFP-020 hasn't necessarily read the
appendix and won't know what D1 means. Replace the stray "under D1"
in the RISC-V verification path subsection with "for the in-program
path", which matches the descriptive labels used elsewhere in the
RFP.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fryorcraken and others added 2 commits May 4, 2026 15:58
- Resolve fee-structure TODO: stop prescribing a fee model; structural
  pull-oracle observation kept, downstream users decide policy.
- Resolve relayer-daemon TODO: add Usability #4 covering a relayer
  daemon (configurable feeds/cadence, retry/back-off, structured
  logging, clean shutdown); renumber subsequent Usability items.
- Lift scope-limit clauses out of the Overview prose into a dedicated
  Scope subsection (in scope / out of scope at Overview level).
- Cross-link the appendix's "Implications for LEZ" four-shape
  analysis from the public-mode aggregator design rationale.
- Update prototype repo URL fryorcraken/lez-ecdsa ->
  fryorcraken/lez-signature-bench in RFP-020 (2 refs) and appendix
  (2 refs).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous wording ("Because RedStone is a pull oracle, the cost
of an update naturally falls on whoever submits the signed data
package on-chain") was inherited from RedStone's native pull model
and contradicted the push-aggregator shape this RFP commits to.
Rename the subsection to "Fee structure" and explain the amortised
single-write cost model with the relayer as the entity that pays
in practice. The non-prescriptive policy paragraph is preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@fryorcraken fryorcraken marked this pull request as ready for review May 4, 2026 06:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants