Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lazer/stellar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ integration on Stellar:
1. **Verify** a signed Lazer update via the deployed `pyth-lazer-stellar` verifier contract.
2. **Parse** the verified payload with the published
[`pyth-lazer-stellar-sdk`](https://crates.io/crates/pyth-lazer-stellar-sdk).
3. **Freshness-check** the feed's update timestamp against a deployment-configured threshold.
3. **Freshness-check** the feed's update timestamp against a deployment-configured threshold, and
reject any update whose timestamp is not strictly newer than the stored price (monotonic updates).
4. **Store / retrieve** the latest price for a single configured feed.

This is an example, not a production library — it tracks exactly one feed and keeps only the most
Expand Down
1 change: 1 addition & 0 deletions lazer/stellar/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub enum Error {
PriceNotInitialized = 6,
Overflow = 7,
ParseError = 8,
PriceOutdated = 9,
}

impl From<ParseError> for Error {
Expand Down
12 changes: 11 additions & 1 deletion lazer/stellar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ impl PythLazerExample {
}

/// Verify a signed Pyth Lazer update, check it is fresh, and store the
/// latest price for the configured feed.
/// latest price for the configured feed. Rejects the update if its feed
/// timestamp is not strictly newer than the currently stored price.
pub fn update_price(env: Env, payload: Bytes) -> Result<(), Error> {
let lazer = state::get_lazer(&env);
let feed_id = state::get_feed_id(&env);
Expand Down Expand Up @@ -62,6 +63,15 @@ impl PythLazerExample {
return Err(Error::PriceStale);
}

// Never overwrite a newer price with an older one: the update's feed
// timestamp must strictly exceed the stored one. This keeps the stored
// price monotonic even if updates arrive out of order.
if let Some(stored) = state::get_latest_price(&env) {
if feed_ts_us <= stored.timestamp_us {
return Err(Error::PriceOutdated);
}
}

let price = feed.price.ok_or(Error::PriceMissing)?;
let exponent = i32::from(feed.exponent.ok_or(Error::ExponentMissing)?);

Expand Down
Loading