Skip to content

feat(twap-oracle): implement CreateCurrentTickAccount and UpdateCurre…#131

Open
0x-r4bbit wants to merge 1 commit into
feat/twap_register_priceaccountfrom
feat/tick_account
Open

feat(twap-oracle): implement CreateCurrentTickAccount and UpdateCurre…#131
0x-r4bbit wants to merge 1 commit into
feat/twap_register_priceaccountfrom
feat/tick_account

Conversation

@0x-r4bbit

Copy link
Copy Markdown
Collaborator

…ntTick

Add CurrentTickAccount — an oracle-owned PDA (one per price source) that holds the latest raw tick written by the price source and a timestamp. The price source calls UpdateCurrentTick after each price-changing operation; anyone can then call RecordTick (upcoming) to advance the PriceObservations accumulator without requiring the price source to be present. PDA is derived from price_source_id only (no window) since a single current tick serves all time windows.

@0x-r4bbit 0x-r4bbit requested review from 3esmit and gravityblast May 29, 2026 09:15
@0x-r4bbit 0x-r4bbit changed the base branch from feat/twap_register_priceaccount to main May 29, 2026 09:53
@0x-r4bbit

Copy link
Copy Markdown
Collaborator Author

Needs #130 to land first.

@0x-r4bbit

Copy link
Copy Markdown
Collaborator Author

Closing and reopening to trigger CI checks.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the TWAP oracle program from a placeholder/no-op into a set of concrete initialization + update primitives for oracle-owned PDAs. It introduces (1) per-(price source, window) observation accounts, (2) per-(price source, window) canonical oracle price accounts, and (3) a per–price-source “current tick” PDA that the price source updates after price-changing operations.

Changes:

  • Add CreatePriceObservations, CreateOraclePriceAccount, CreateCurrentTickAccount, and UpdateCurrentTick instructions + guest entrypoints.
  • Implement PDA derivation helpers and new account types (PriceObservations, CurrentTickAccount) in twap_oracle_core (and update OraclePriceAccount.source_id to AccountId).
  • Update IDL artifacts and Cargo dependencies/lockfiles to include new crates (e.g., clock_core, risc0-zkvm in core).

Reviewed changes

Copilot reviewed 13 out of 19 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
programs/twap_oracle/src/update_current_tick.rs Implements updating an existing CurrentTickAccount and adds unit tests.
programs/twap_oracle/src/noop.rs Removes the previous no-op implementation.
programs/twap_oracle/src/lib.rs Exposes new instruction modules from the program crate.
programs/twap_oracle/src/create_price_observations.rs Adds initialization for PriceObservations PDA (per source+window) and tests.
programs/twap_oracle/src/create_oracle_price_account.rs Adds initialization for OraclePriceAccount PDA (per source+window) and tests.
programs/twap_oracle/src/create_current_tick_account.rs Adds initialization for CurrentTickAccount PDA (per source) and tests.
programs/twap_oracle/methods/guest/src/bin/twap_oracle.rs Replaces no-op guest entrypoint with guest instruction wrappers for the new APIs.
programs/twap_oracle/methods/guest/Cargo.toml Adds clock_core dependency needed by new guest code.
programs/twap_oracle/methods/guest/Cargo.lock Lockfile updates for new guest dependencies.
programs/twap_oracle/core/src/lib.rs Adds new instructions, PDA seed helpers, and new account types in core.
programs/twap_oracle/core/Cargo.toml Enables workspace lints and adds risc0-zkvm dependency needed for hashing PDA seeds.
programs/twap_oracle/Cargo.toml Adds clock_core dependency and enables workspace lints.
programs/token/methods/guest/Cargo.lock Workspace lockfile churn from dependency updates.
programs/stablecoin/methods/guest/Cargo.lock Workspace lockfile churn from dependency updates.
programs/ata/methods/guest/Cargo.lock Workspace lockfile churn from dependency updates.
programs/amm/methods/guest/Cargo.lock Workspace lockfile churn from dependency updates.
Cargo.lock Workspace lockfile churn from dependency updates.
artifacts/twap_oracle-idl.json Updates the oracle IDL to reflect new instructions and account/types.
artifacts/stablecoin-idl.json Updates generated IDL types (reflecting updated shared types).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

price_source_id: AccountId,
window_duration: u64,
) -> PdaSeed {
use risc0_zkvm::sha::{Impl, Sha256};
price_source_id: AccountId,
window_duration: u64,
) -> PdaSeed {
use risc0_zkvm::sha::{Impl, Sha256};
/// Hash input: `price_source_id (32 bytes) || CURRENT_TICK_ACCOUNT_PDA_SEED (32 bytes)`.
#[must_use]
pub fn compute_current_tick_account_pda_seed(price_source_id: AccountId) -> PdaSeed {
use risc0_zkvm::sha::{Impl, Sha256};
Comment on lines +65 to +68
mod tests {
use nssa_core::account::{AccountId, Nonce};

use super::*;
Comment on lines +84 to +87
mod tests {
use nssa_core::account::{AccountId, Nonce};

use super::*;
Comment on lines +75 to +79
mod tests {
use nssa_core::account::Nonce;

use super::*;

Comment on lines +52 to +56
mod tests {
use nssa_core::account::{Account, AccountId, Nonce};
use twap_oracle_core::compute_current_tick_account_pda;

use super::*;
…ntTick

Add CurrentTickAccount — an oracle-owned PDA (one per price source) that holds
the latest raw tick written by the price source and a timestamp. The price source
calls UpdateCurrentTick after each price-changing operation; anyone can then call
RecordTick (upcoming) to advance the PriceObservations accumulator without
requiring the price source to be present. PDA is derived from price_source_id
only (no window) since a single current tick serves all time windows.

Add price_to_tick(price: u128) -> i32 to twap_oracle_core: isqrt(price << 128)
-> sqrtPriceX96 -> get_tick_at_sqrt_ratio. The sqrtPriceX96 is clamped to
>= MIN_SQRT_RATIO so a zero/dust price maps to MIN_TICK rather than erroring.

Add a pure-integer integer_sqrt(U256) (bit-by-bit, no floating point): ruint's
root is gated behind its std feature and seeds with f64, neither available in
the guest. Uses wrapping_shr for the digit loop (checked_shr rejects the
intended lossy shifts).

Pull in uniswap_v3_math (for get_tick_at_sqrt_ratio) and alloy-primitives
(U256), with ruint pinned to =1.17.0 — 1.18 raised its MSRV to rustc 1.90,
above the risc0 guest toolchain's 1.88.
@0x-r4bbit 0x-r4bbit force-pushed the feat/tick_account branch from ab6f4e7 to a314501 Compare June 11, 2026 14:05
@0x-r4bbit

Copy link
Copy Markdown
Collaborator Author

Updated this to take in prices as Q64.64 instead of ticks. So #139 will not be needed anymore

@0x-r4bbit 0x-r4bbit changed the base branch from main to feat/twap_register_priceaccount June 11, 2026 14:07
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