From 1a6eac30428a05b8da8f2e1703a90c79b2212caf Mon Sep 17 00:00:00 2001 From: Alimzy Date: Wed, 29 Jul 2026 13:41:06 +0100 Subject: [PATCH] Document price precision and aggregation window on submit_price MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses #219. submit_price already had a short doc comment, but it did not explain the expected price precision/decimals or how submissions feed into TWAP aggregation, which was the real gap behind the issue. Added: - price is a fixed-point integer scaled by 10^decimals, where decimals comes from OracleConfig (max 38, validated in configure_oracle). Documented with a concrete example. - Clarified there is no fixed time-bucketed TWAP window: each feeder's latest submission is kept independently, and get_twap_price aggregates the median (or average of the two middle values on an even count) across submissions within max_staleness seconds of current ledger time. - Cross-referenced calculate_fiat_stream_payout, which divides by 10^decimals, to make clear submissions must match the currently configured decimals scale. No behavior change — doc comment only. cargo build, cargo test (42 passed), cargo fmt --check, and cargo clippy all clean on the oracle crate. --- contracts/oracle/src/lib.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/contracts/oracle/src/lib.rs b/contracts/oracle/src/lib.rs index a6694cc..5d15ebf 100644 --- a/contracts/oracle/src/lib.rs +++ b/contracts/oracle/src/lib.rs @@ -221,6 +221,23 @@ impl TwapOracle { /// Submit a price observation. Gated on `PriceFeeder` (or `Admin`). /// + /// `price` is a fixed-point integer scaled by `10^decimals`, where + /// `decimals` comes from the oracle's stored `OracleConfig` (set via + /// `configure_oracle`, max 38). For example, with `decimals: 8`, a + /// real-world price of `100.0` is submitted as `100_00000000`. + /// `calculate_fiat_stream_payout` divides by `10^decimals` when + /// converting a submission back to a real value, so submissions must + /// use the same scale as the currently configured `decimals` or + /// downstream payouts will be wrong by that scale factor. + /// + /// There is no fixed time-bucketed TWAP window. Instead, every + /// feeder's most recent submission is kept independently + /// (`DataKey::Submission`) and `get_twap_price` aggregates the median + /// (or the average of the two middle values, on an even count) across + /// every submission still within `max_staleness` seconds of the + /// current ledger time — see `get_twap_price` for the aggregation + /// logic and `OracleConfig::max_staleness` for the staleness window. + /// /// Blocked while the oracle is under an emergency pause. Each feeder's /// submission is tracked independently (`DataKey::Submission`) and /// aggregated by `get_twap_price` — no single feeder's price is trusted