RFP ID
RFP-019
Your Project Name
On-Chain TWAP Oracle
Team or Organization Name
Independent
Primary Contact
Email - bristineth@gmail.com
telegram- bristinborah
Team Members
Member 1
Name or pseudonym: Bristin Borah
Social links: GitHub: https://github.com/bristinWild · X/other: https://x.com/borah_bristin
Role: Solo Founder / Full stack web3 engineer
Status: Full-time
Project Summary
LEZ DeFi has a pricing problem that external oracles cannot solve. LEZ-native
assets - LGS and the reflexive stablecoin (RFP-013) - trade only on a LEZ DEX,
so no off-chain publisher has data to sign for them. The single honest price
source is the DEX itself, read through an on-chain time-weighted average. This
proposal delivers that missing tier: an on-chain TWAP oracle program for LEZ
plus the canonical price-account standard that lets multiple price sources
coexist for the same pair, so consuming protocols (RFP-008 lending, RFP-013
stablecoin, RFP-004 DEX) integrate once and stay agnostic to the source.
The build follows the design the RFP lays out: geometric-mean TWAP over
tick-based accumulators (Uniswap v3 model), per-block tick-delta truncation
(Uniswap v4 truncated-oracle-hook, default MAX_TICK_DELTA = 9,116,
governable per pool), a configurable observation ring buffer from cardinality 1
up to 65,535, and a query interface that returns the TWAP and its observation
timestamps with a consumer-supplied maxAge staleness bound. The oracle program
is the writer; cross-source policy stays with consumers. We deliver the standard
as a standalone, importable SPEL IDL artefact so RFP-020 (RedStone) and a future
Pyth adaptor can populate the same struct without depending on the TWAP program.
Two facts about the current LEZ codebase shape our plan and de-risk it. First,
the twap_oracle program already carries a scaffolded OraclePriceAccount
matching hard requirement (base_asset, quote_asset, price: u128,
timestamp: u64, source_id, confidence_interval), annotated #[account_type]
so it already flows into the SPEL IDL - the standard is seeded, the engine behind
it is not. Second, the in-repo amm program is a complete constant-product AMM
with full swap/add/remove/sync logic and an extensive test suite, which means the
entire observation/accumulator/TWAP/truncation/query stack can be built and tested
against a real pool today, ahead of RFP-004's privacy DEX landing.
The hardest part of this work is not the AMM mathematics, which is well
documented; it is reconciling a TWAP's need for trusted, block-boundary
timestamps with the LEZ execution model, where a RISC Zero guest is a pure
function of committed inputs and binds time through validity windows rather than
reading an ambient clock. That execution-model problem is the core of our
technical approach and the area we are strongest in. We propose to ship the
unblocked majority of the work first (standard, accumulator engine, truncation,
manipulation analysis, tooling) and gate only the final privacy-DEX integration
on RFP-004 availability.
Technical Approach
Architecture and stack
- Language / runtime: Rust on the RISC Zero zkVM, the existing LEZ program
model (nssa_core accounts, AccountWithMetadata inputs, AccountPostState
outputs, PDAs, borsh).
- Framework: SPEL -
#[lez_program] / #[instruction] for the guest,
#[account_type] for the price account and oracle state, generate_idl! for
IDL, and the spel CLI for transaction submission, dry-runs, and account
inspection.
- Crate layout: the established three-crate pattern already present in the
repo - twap_oracle_core (shared types: instruction enum, OraclePriceAccount,
oracle/observation state), methods/guest (the on-chain program), and the
parent crate / examples for IDL generation and the CLI wrapper.
- Data source: the in-repo constant-product
amm. The oracle reads pool
reserves and, because a v2-style pool exposes no native tick accumulator,
derives the spot tick from log(reserve_b / reserve_a) and advances its own
tickCumulative under truncation. (See "Anticipated challenges" for the
v2-vs-v3 reconciliation.)
Time and block-boundary sampling (the central design problem)
A LEZ guest cannot read "now": execution is a pure function of its inputs, and
the AMM precedent binds time via with_timestamp_validity_window(..deadline) and
the SpelOutput block_validity_window / timestamp_validity_window constraints
that the sequencer enforces - not via an ambient clock read. Our accumulator
update therefore treats the observation timestamp as a committed input bound to a
block through the validity-window mechanism, so that "sample at the block boundary
before same-block trades" (Oracle Security ) becomes "record an observation as a
function of the pre-trade pool state, bound to a verified block." The first
implementation task is to confirm the exact time/block primitive the LEZ guest is
given (committed block context vs. validity-window binding only) and lock the
observation-timestamp design around it; the manipulation analysis and staleness
(maxAge) semantics both depend on this being precise.
Accumulator engine, truncation, cardinality
- Tick accumulators in log-price space, geometric-mean TWAP between two
observations (difference of tickCumulative over elapsed time), per the v3
rationale in the RFP.
- Per-block tick-delta truncation applied before the
tickCumulative
update: each update clamps the recorded delta against the previous block's tick
to a per-pool, owner-governable MAX_TICK_DELTA (default 9,116). The
manipulation-cost analysis reports figures both with and without truncation, as
required.
- Observation ring buffer with configurable cardinality (default 1,
expandable to 65,535). Expansion is atomic - a partial failure leaves existing
observations intact (Reliability).
Canonical price-account standard
We finish the seeded OraclePriceAccount: enforce reject-on-write for zero /
negative / invalid prices, populate base_asset / quote_asset as canonical IDs
(token mint IDs for LEZ tokens; agreed IDs such as USD otherwise), and publish
the price-account IDL as a standalone artefact importable without depending on
the TWAP program, so external adaptors (RFP-020, future Pyth) share it. The
struct stays append-friendly for forward evolution.
Query interface, registration, errors
observe(pool, window, maxAge) returns the TWAP price and the observation
timestamps used; reads older than maxAge return an error, not a stale value
(Functionality). A query is read-only and never mutates oracle state
(Reliability ).
- Owner-gated
register / deregister of TWAP feed sources (pools). External
sources publish their own price accounts directly and are not registered here
(Functionality).
- Per-pool isolation: one pool's failure (accumulator unavailable, cardinality
exhausted) does not affect queries against other pools (Reliability ).
- Actionable errors for every failure mode: stale price, no history for the
window, cardinality too low for the window, zero/negative source price, and
(base_asset, quote_asset) mismatch (Usability ).
Reference consumer + multi-source pattern
A minimal LEZ reference consumer demonstrating pair verification, reading
price/timestamp/confidence, maxAge rejection, and the safe "refuse, do not fall
back to an unsafe default" behaviour plus a worked multi-source example
(primary feed with staleness fallback and a divergence cross-check that logs but
does not gate), explicitly documented as illustrative since cross-source policy
belongs to the consumer. We also intend to ship the soft-requirement multi-source
helper SDK that packages this policy with diagnostic flags.
Tooling, app, docs
SDK for building Logos modules (query / expand cardinality / register), the
spel-based CLI, a Logos mini-app price-feed dashboard (live TWAP per pool,
side-by-side comparison against any other price account for the same pair,
observation history) loadable in Basecamp via git repo with build instructions
and downloadable assets, Figma designs for the dashboard, a README covering
end-to-end usage, and two doc packets (SDK - including the "Recommended Consumer
Pattern" section - and CLI).
Economic model
Pull-based, matching the RFP's framing: observation history is written as a side
effect of accumulator updates (cost borne by the actor triggering the update);
observe() is a read-only view with no metering; the only explicit cost is
cardinality-expansion rent, borne by the pool registrant choosing the lookback
depth they need. No ongoing protocol subsidy is required once LEZ reaches
moderate TVL.
Testing and performance
Every hard requirement gets at least one test, including the RFP-named cases:
TWAP correctness from known accumulator values, truncation (a synthetic excursion
beyond MAX_TICK_DELTA is clamped and the resulting TWAP matches the truncated
trajectory), maxAge staleness rejection, (base_asset, quote_asset) mismatch
rejection, and register/deregister state transitions. End-to-end tests run
against a LEZ sequencer in standalone mode in CI, kept green on the default
branch. We document the compute-unit cost of each operation (query, accumulator
update, cardinality expansion) and note where large-window proving cost is the
binding constraint.
Anticipated challenges
- The time/block primitive (above) is the main technical risk and is
front-loaded into M1–M2.
- v2 source vs. v3 design. The RFP assumes v3 tick accumulators read from the
DEX, but the available DEX is constant-product with no native accumulator. We
resolve this by having the oracle maintain its own observation buffer derived
from reserves; if RFP-004 ships native v3-style accumulators, the reader swaps
to consume them directly without changing the price-account surface.
- RFP-004 dependency. Live integration against the privacy DEX is the only
genuinely gated item; everything else is exercised against the in-repo AMM. The
final milestone absorbs RFP-004 integration when it is available.
- Build environment. SPEL documents a
ring/risc0 riscv32 cross-compilation
failure (LEZ issue #468) requiring a temporary LEZ fork + [patch]; budgeted
in M1 setup.
Out of scope (per the RFP)
External oracle adaptors (RFP-020 / future Pyth), confidential or shielded oracle
execution (oracles run public), the reflexive-stablecoin design (RFP-013), and
price-feed composition across chained denominations.
Milestones, Payout and Timeline
Milestone 1 - Setup, canonical standard, reference consumer
Payout: $7,000
Duration: 2 weeks
Deliverables:
- Workspace + CI scaffolding; resolve the risc0/ring (#468) build issue
- Finalised OraclePriceAccount: reject-on-write validation, canonical
base/quote IDs, standalone importable price-account IDL artefact
- Confirmed time/block-binding primitive design note
- Reference consumer program (pair verification, maxAge, safe-refuse) +
worked multi-source pattern, with tests
Milestone 2 - Observation engine, accumulators, truncation, registration
Payout: $12,000
Duration: 3 weeks
Deliverables:
- Tick-based accumulator storage; configurable cardinality ring buffer
(1 → 65,535) with atomic expansion
- Per-block tick-delta truncation (governable MAX_TICK_DELTA), clamp applied
before tickCumulative update
- Block-boundary observation recording bound via the validity-window model
- Owner-gated register / deregister of feed sources, with per-pool isolation
- Built and unit-tested against the in-repo constant-product AMM
Milestone 3 - Query interface, geometric-mean TWAP, staleness, errors, CU costs
Payout: $9,000
Duration: 2 weeks
Deliverables:
- observe(pool, window, maxAge) → TWAP price + observation timestamps
- Geometric-mean computation; read-only query guarantee
- All RFP error modes with actionable messages
- Documented compute-unit cost per operation
Milestone 4 - SDK, CLI, mini-app dashboard, Figma, docs, multi-source helper
Payout: $9,000
Duration: 2 weeks
Deliverables:
- SDK for Logos modules (query / expand cardinality / register)
- spel-based CLI covering core operations
- Mini-app price-feed dashboard (Basecamp-loadable) + Figma designs
- README + SDK doc packet (incl. Recommended Consumer Pattern) + CLI doc packet
- Soft requirement: multi-source consumer-pattern helper SDK
Milestone 5 - E2E tests, manipulation analysis, devnet/testnet deploy, RFP-004 integration
Payout: $6,000
Duration: 1.5 weeks
Deliverables:
- Full test matrix (one+ test per hard requirement, incl. truncation,
staleness, pair-mismatch, registration transitions)
- E2E tests against a LEZ sequencer (standalone) in CI, green on default branch
- Manipulation-cost analysis at $1M / $10M / $50M / $100M depth, with and
without truncation; documented minimum window for lending use
- Deployed and tested on LEZ devnet/testnet; program addresses documented
- Integration against the RFP-004 privacy DEX when available (else documented
against the in-repo AMM with a clearly specified swap-in path)
Milestone 6 - Security review and remediation (Audit)
Payout: $7,000
Duration: 1.5 weeks
Deliverables:
- Security review focused on oracle manipulation, accumulator/truncation
correctness, and time-binding soundness
- Remediation of findings; final report
Total duration: ~12 weeks.
Total Requested Budget (USD)
$50,000 (= 7,000 + 12,000 + 9,000 + 9,000 + 6,000 + 7,000 )
Relevant Experience
- LEZ programs, merged. LP-0012 - implemented and merged into the LEZ
programs track. https://github.com/logos-co/lambda-prize/pull/14
- LP-0013 - RISC Zero zkVM program submitted to
logos-blockchain/lez-programs
(built with RISC0_DEV_MODE=0), with demo video and evaluation note.
https://github.com/logos-co/lambda-prize/pull/56
- Confidential-compute research on LEZ - zkVM execution-model work
(commitment binding, proof-based verification of private inputs) directly
relevant to the time-binding design that is the core risk in this RFP.
https://github.com/bristinWild/tuniq-experiments
Stack: Rust, RISC Zero zkVM, SPEL framework, Groth16, Solana/SVM program model,
integration testing, CLI + IDL tooling.
Post-Delivery Plan
bristinWild maintains the program, SDK, CLI, and mini-app after delivery. All
code ships under the MIT + Apache 2.0 dual license in a public repo with an issue
tracker. Because the oracle is consumed by RFP-008 (lending), RFP-013
(stablecoin), and RFP-004 (DEX), the post-delivery commitment includes
integration support for those teams adopting the canonical price-account standard
and the Recommended Consumer Pattern, plus tracking-issue triage and compatibility
fixes as LEZ's compute budget and sequencer interfaces evolve through testnet.
Permissions and Consent
Program Requirements
RFP ID
RFP-019Your Project Name
On-Chain TWAP Oracle
Team or Organization Name
Independent
Primary Contact
Email - bristineth@gmail.com
telegram- bristinborah
Team Members
Project Summary
LEZ DeFi has a pricing problem that external oracles cannot solve. LEZ-native
assets - LGS and the reflexive stablecoin (RFP-013) - trade only on a LEZ DEX,
so no off-chain publisher has data to sign for them. The single honest price
source is the DEX itself, read through an on-chain time-weighted average. This
proposal delivers that missing tier: an on-chain TWAP oracle program for LEZ
plus the canonical price-account standard that lets multiple price sources
coexist for the same pair, so consuming protocols (RFP-008 lending, RFP-013
stablecoin, RFP-004 DEX) integrate once and stay agnostic to the source.
The build follows the design the RFP lays out: geometric-mean TWAP over
tick-based accumulators (Uniswap v3 model), per-block tick-delta truncation
(Uniswap v4 truncated-oracle-hook, default
MAX_TICK_DELTA = 9,116,governable per pool), a configurable observation ring buffer from cardinality 1
up to 65,535, and a query interface that returns the TWAP and its observation
timestamps with a consumer-supplied
maxAgestaleness bound. The oracle programis the writer; cross-source policy stays with consumers. We deliver the standard
as a standalone, importable SPEL IDL artefact so RFP-020 (RedStone) and a future
Pyth adaptor can populate the same struct without depending on the TWAP program.
Two facts about the current LEZ codebase shape our plan and de-risk it. First,
the
twap_oracleprogram already carries a scaffoldedOraclePriceAccountmatching hard requirement (
base_asset,quote_asset,price: u128,timestamp: u64,source_id,confidence_interval), annotated#[account_type]so it already flows into the SPEL IDL - the standard is seeded, the engine behind
it is not. Second, the in-repo
ammprogram is a complete constant-product AMMwith full swap/add/remove/sync logic and an extensive test suite, which means the
entire observation/accumulator/TWAP/truncation/query stack can be built and tested
against a real pool today, ahead of RFP-004's privacy DEX landing.
The hardest part of this work is not the AMM mathematics, which is well
documented; it is reconciling a TWAP's need for trusted, block-boundary
timestamps with the LEZ execution model, where a RISC Zero guest is a pure
function of committed inputs and binds time through validity windows rather than
reading an ambient clock. That execution-model problem is the core of our
technical approach and the area we are strongest in. We propose to ship the
unblocked majority of the work first (standard, accumulator engine, truncation,
manipulation analysis, tooling) and gate only the final privacy-DEX integration
on RFP-004 availability.
Technical Approach
Architecture and stack
model (
nssa_coreaccounts,AccountWithMetadatainputs,AccountPostStateoutputs, PDAs, borsh).
#[lez_program]/#[instruction]for the guest,#[account_type]for the price account and oracle state,generate_idl!forIDL, and the
spelCLI for transaction submission, dry-runs, and accountinspection.
repo -
twap_oracle_core(shared types: instruction enum,OraclePriceAccount,oracle/observation state),
methods/guest(the on-chain program), and theparent crate /
examplesfor IDL generation and the CLI wrapper.amm. The oracle reads poolreserves and, because a v2-style pool exposes no native tick accumulator,
derives the spot tick from
log(reserve_b / reserve_a)and advances its owntickCumulativeunder truncation. (See "Anticipated challenges" for thev2-vs-v3 reconciliation.)
Time and block-boundary sampling (the central design problem)
A LEZ guest cannot read "now": execution is a pure function of its inputs, and
the AMM precedent binds time via
with_timestamp_validity_window(..deadline)andthe
SpelOutputblock_validity_window/timestamp_validity_windowconstraintsthat the sequencer enforces - not via an ambient clock read. Our accumulator
update therefore treats the observation timestamp as a committed input bound to a
block through the validity-window mechanism, so that "sample at the block boundary
before same-block trades" (Oracle Security ) becomes "record an observation as a
function of the pre-trade pool state, bound to a verified block." The first
implementation task is to confirm the exact time/block primitive the LEZ guest is
given (committed block context vs. validity-window binding only) and lock the
observation-timestamp design around it; the manipulation analysis and staleness
(
maxAge) semantics both depend on this being precise.Accumulator engine, truncation, cardinality
observations (difference of
tickCumulativeover elapsed time), per the v3rationale in the RFP.
tickCumulativeupdate: each update clamps the recorded delta against the previous block's tick
to a per-pool, owner-governable
MAX_TICK_DELTA(default 9,116). Themanipulation-cost analysis reports figures both with and without truncation, as
required.
expandable to 65,535). Expansion is atomic - a partial failure leaves existing
observations intact (Reliability).
Canonical price-account standard
We finish the seeded
OraclePriceAccount: enforce reject-on-write for zero /negative / invalid prices, populate
base_asset/quote_assetas canonical IDs(token mint IDs for LEZ tokens; agreed IDs such as
USDotherwise), and publishthe price-account IDL as a standalone artefact importable without depending on
the TWAP program, so external adaptors (RFP-020, future Pyth) share it. The
struct stays append-friendly for forward evolution.
Query interface, registration, errors
observe(pool, window, maxAge)returns the TWAP price and the observationtimestamps used; reads older than
maxAgereturn an error, not a stale value(Functionality). A query is read-only and never mutates oracle state
(Reliability ).
register/deregisterof TWAP feed sources (pools). Externalsources publish their own price accounts directly and are not registered here
(Functionality).
exhausted) does not affect queries against other pools (Reliability ).
window, cardinality too low for the window, zero/negative source price, and
(base_asset, quote_asset)mismatch (Usability ).Reference consumer + multi-source pattern
A minimal LEZ reference consumer demonstrating pair verification, reading
price/timestamp/confidence,
maxAgerejection, and the safe "refuse, do not fallback to an unsafe default" behaviour plus a worked multi-source example
(primary feed with staleness fallback and a divergence cross-check that logs but
does not gate), explicitly documented as illustrative since cross-source policy
belongs to the consumer. We also intend to ship the soft-requirement multi-source
helper SDK that packages this policy with diagnostic flags.
Tooling, app, docs
SDK for building Logos modules (query / expand cardinality / register), the
spel-based CLI, a Logos mini-app price-feed dashboard (live TWAP per pool,side-by-side comparison against any other price account for the same pair,
observation history) loadable in Basecamp via git repo with build instructions
and downloadable assets, Figma designs for the dashboard, a README covering
end-to-end usage, and two doc packets (SDK - including the "Recommended Consumer
Pattern" section - and CLI).
Economic model
Pull-based, matching the RFP's framing: observation history is written as a side
effect of accumulator updates (cost borne by the actor triggering the update);
observe()is a read-only view with no metering; the only explicit cost iscardinality-expansion rent, borne by the pool registrant choosing the lookback
depth they need. No ongoing protocol subsidy is required once LEZ reaches
moderate TVL.
Testing and performance
Every hard requirement gets at least one test, including the RFP-named cases:
TWAP correctness from known accumulator values, truncation (a synthetic excursion
beyond
MAX_TICK_DELTAis clamped and the resulting TWAP matches the truncatedtrajectory),
maxAgestaleness rejection,(base_asset, quote_asset)mismatchrejection, and register/deregister state transitions. End-to-end tests run
against a LEZ sequencer in standalone mode in CI, kept green on the default
branch. We document the compute-unit cost of each operation (query, accumulator
update, cardinality expansion) and note where large-window proving cost is the
binding constraint.
Anticipated challenges
front-loaded into M1–M2.
DEX, but the available DEX is constant-product with no native accumulator. We
resolve this by having the oracle maintain its own observation buffer derived
from reserves; if RFP-004 ships native v3-style accumulators, the reader swaps
to consume them directly without changing the price-account surface.
genuinely gated item; everything else is exercised against the in-repo AMM. The
final milestone absorbs RFP-004 integration when it is available.
ring/risc0 riscv32 cross-compilationfailure (LEZ issue #468) requiring a temporary LEZ fork +
[patch]; budgetedin M1 setup.
Out of scope (per the RFP)
External oracle adaptors (RFP-020 / future Pyth), confidential or shielded oracle
execution (oracles run public), the reflexive-stablecoin design (RFP-013), and
price-feed composition across chained denominations.
Milestones, Payout and Timeline
Total duration: ~12 weeks.
Total Requested Budget (USD)
$50,000(= 7,000 + 12,000 + 9,000 + 9,000 + 6,000 + 7,000 )Relevant Experience
programs track.
https://github.com/logos-co/lambda-prize/pull/14logos-blockchain/lez-programs(built with
RISC0_DEV_MODE=0), with demo video and evaluation note.https://github.com/logos-co/lambda-prize/pull/56(commitment binding, proof-based verification of private inputs) directly
relevant to the time-binding design that is the core risk in this RFP.
https://github.com/bristinWild/tuniq-experimentsStack: Rust, RISC Zero zkVM, SPEL framework, Groth16, Solana/SVM program model,
integration testing, CLI + IDL tooling.
Post-Delivery Plan
bristinWild maintains the program, SDK, CLI, and mini-app after delivery. All
code ships under the MIT + Apache 2.0 dual license in a public repo with an issue
tracker. Because the oracle is consumed by RFP-008 (lending), RFP-013
(stablecoin), and RFP-004 (DEX), the post-delivery commitment includes
integration support for those teams adopting the canonical price-account standard
and the Recommended Consumer Pattern, plus tracking-issue triage and compatibility
fixes as LEZ's compute budget and sequencer interfaces evolve through testnet.
Permissions and Consent
provided above for follow-ups and next steps.
blogs, case studies, social posts, or analytical reporting. Redactions can be
requested at any time. (optional - uncheck if you prefer)
Program Requirements
2.0 Licenses unless explicitly approved otherwise.