feat(twap-oracle): implement CreateOraclePriceAccount instruction#130
Open
0x-r4bbit wants to merge 1 commit into
Open
feat(twap-oracle): implement CreateOraclePriceAccount instruction#1300x-r4bbit wants to merge 1 commit into
0x-r4bbit wants to merge 1 commit into
Conversation
49e5cd5 to
58c169d
Compare
Collaborator
Author
|
Closing and reopening to trigger CI checks. |
578ab41 to
bb55bd3
Compare
There was a problem hiding this comment.
Pull request overview
Implements TWAP-oracle account-creation instructions, adding the ability to initialize canonical PDAs for (1) per-window observation buffers and (2) per-window oracle price accounts derived from (oracle_program_id, price_source_id, window_duration).
Changes:
- Replace the prior no-op interface with
CreatePriceObservationsandCreateOraclePriceAccountinstructions (guest entrypoint + IDL). - Add PDA derivation helpers and a new
PriceObservationsaccount type intwap_oracle_core; updateOraclePriceAccount.source_idtoAccountId. - Wire in
clock_coreand hashing (risc0-zkvm::sha) for initialization and PDA seeds; refresh lockfiles/artifacts.
Reviewed changes
Copilot reviewed 11 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| programs/twap_oracle/src/noop.rs | Removes the previous no-op implementation. |
| programs/twap_oracle/src/lib.rs | Exposes the new instruction modules. |
| programs/twap_oracle/src/create_price_observations.rs | Adds observation-buffer PDA initialization logic + tests. |
| programs/twap_oracle/src/create_oracle_price_account.rs | Adds oracle price account PDA initialization logic + tests. |
| programs/twap_oracle/methods/guest/src/bin/twap_oracle.rs | Replaces noop with new guest-exposed instructions. |
| programs/twap_oracle/methods/guest/Cargo.toml | Adds clock_core dependency for guest build/IDL inputs. |
| programs/twap_oracle/methods/guest/Cargo.lock | Locks new dependency graph for twap-oracle guest. |
| programs/twap_oracle/core/src/lib.rs | Adds Instruction variants, PriceObservations, PDA helpers, and changes OraclePriceAccount.source_id type. |
| programs/twap_oracle/core/Cargo.toml | Enables workspace lints and adds risc0-zkvm for hashing. |
| programs/twap_oracle/Cargo.toml | Adds clock_core and enables workspace lints. |
| artifacts/twap_oracle-idl.json | Updates IDL to reflect new instructions/accounts/types. |
| artifacts/stablecoin-idl.json | Updates IDL (via dependency inclusion) to reflect updated oracle account/types. |
| programs/token/methods/guest/Cargo.lock | Lockfile refresh from dependency resolution changes. |
| programs/stablecoin/methods/guest/Cargo.lock | Lockfile refresh from dependency resolution changes. |
| programs/ata/methods/guest/Cargo.lock | Lockfile refresh from dependency resolution changes. |
| programs/amm/methods/guest/Cargo.lock | Lockfile refresh from dependency resolution changes. |
| Cargo.lock | Workspace lockfile refresh. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
bb55bd3 to
2909f8f
Compare
3esmit
requested changes
Jun 9, 2026
Adds the CreateOraclePriceAccount instruction to the TWAP oracle program. The instruction initialises a canonical OraclePriceAccount PDA for a given price source and time window, seeding it with a non-zero initial price and the current block timestamp so the account is immediately valid to consumers. - PDA mirrors PriceObservations: derived from (oracle_program_id, price_source_id, window_duration) with a distinct seed constant, so each (source, window) pair maps to a distinct oracle price account that cannot collide with its corresponding observations account. - source_id is not a parameter: it is always set to price_source.account_id. Accepting it as a free parameter would allow callers to register a price account that claims to represent a source it does not control. Deriving it from the authorized price source account closes that vector entirely. - Authorization follows the same model as CreatePriceObservations: is_authorized = true on the price source proves the caller controls it; the PDA check ensures the supplied oracle price account address is the one derived from that specific source and window. - The initial timestamp is read from the canonical 1-block LEZ clock (CLOCK_01_PROGRAM_ACCOUNT_ID), never from a caller-supplied value. The clock account_id is asserted, so a caller cannot substitute an account they control to forge the seeding timestamp. - A zero price or zero timestamp is rejected at creation. Both are the "no valid price" sentinel consumers treat as unset, so an account must never be created in that state; the instruction asserts a non-zero initial_price and a non-zero clock timestamp. - initial_price is a Q64.64 fixed-point value (real price = initial_price / 2^64), matching the oracle price representation. The non-zero check rejects the sentinel but cannot validate scale — supplying a correctly-scaled value is the caller's responsibility. Closes #129
2909f8f to
6615bcc
Compare
Collaborator
Author
|
As per our discussion offline, I've updated this commit to not allow for price account creation with a 0 price and timestamp. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the CreateOraclePriceAccount instruction to the TWAP oracle program. The instruction initialises a canonical OraclePriceAccount PDA for a given price source and time window. The account starts with price = 0 and timestamp = 0 — a deliberately invalid sentinel state that signals "not yet published". Consumers are expected to reject any account whose timestamp is zero or stale, so the transient invalid state requires no special on-chain enforcement.
PDA mirrors PriceObservations: derived from (oracle_program_id, price_source_id, window_duration) with a distinct seed constant, so each (source, window) pair maps to a distinct oracle price account that cannot collide with its corresponding observations account.
source_id is not a parameter: it is always set to price_source.account_id. Accepting it as a free parameter would allow callers to register a price account that claims to represent a source it does not control. Deriving it from the authorized price source account closes that vector entirely.
Authorization follows the same model as CreatePriceObservations: is_authorized = true on the price source proves the caller controls it; the PDA check ensures the supplied oracle price account address is the one derived from that specific source and window.
price = 0 / timestamp = 0 is the correct initial state: coupling account creation to first publication would require the observation account to already hold a full window of ticks, blocking registration for up to the window duration. Consumers must validate oracle prices regardless, so the zero sentinel falls naturally out of the staleness check they already own.
Closes #129
This needs #128 to land first