From 651b9493d9717e399bb0364dbecd41e21129eab5 Mon Sep 17 00:00:00 2001 From: Ayush Suresh Date: Thu, 19 Jun 2025 14:33:50 +0100 Subject: [PATCH 1/2] finished get_price_unsafe, get_price_no_older_than --- .../contracts/pyth-receiver/src/error.rs | 19 +++++++++++ .../stylus/contracts/pyth-receiver/src/lib.rs | 32 ++++++++++++++++--- 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 target_chains/stylus/contracts/pyth-receiver/src/error.rs diff --git a/target_chains/stylus/contracts/pyth-receiver/src/error.rs b/target_chains/stylus/contracts/pyth-receiver/src/error.rs new file mode 100644 index 0000000000..6b44614f9b --- /dev/null +++ b/target_chains/stylus/contracts/pyth-receiver/src/error.rs @@ -0,0 +1,19 @@ +use alloc::vec::Vec; + +pub enum PythReceiverError { + PriceUnavailable +} + +impl core::fmt::Debug for PythReceiverError { + fn fmt(&self, _: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + Ok(()) + } +} + +impl From for Vec { + fn from(error: PythReceiverError) -> Vec { + vec![match error { + PythReceiverError::PriceUnavailable => 1, + }] + } +} \ No newline at end of file diff --git a/target_chains/stylus/contracts/pyth-receiver/src/lib.rs b/target_chains/stylus/contracts/pyth-receiver/src/lib.rs index 2cf9b7acb0..654e39a8bb 100644 --- a/target_chains/stylus/contracts/pyth-receiver/src/lib.rs +++ b/target_chains/stylus/contracts/pyth-receiver/src/lib.rs @@ -6,6 +6,7 @@ extern crate alloc; mod structs; +mod error; use alloc::vec::Vec; use stylus_sdk::{alloy_primitives::{U256, U64, I32, I64, FixedBytes}, @@ -13,6 +14,7 @@ use stylus_sdk::{alloy_primitives::{U256, U64, I32, I64, FixedBytes}, storage::{StorageAddress, StorageVec, StorageMap, StorageUint, StorageBool, StorageU256}}; use structs::{DataSourceStorage, PriceInfoReturn, PriceInfoStorage}; +use error::{PythReceiverError}; #[storage] #[entrypoint] @@ -31,12 +33,27 @@ pub struct PythReceiver { #[public] impl PythReceiver { - pub fn get_price_unsafe(&self, _id: [u8; 32]) -> PriceInfoReturn { - (U64::ZERO, I32::ZERO, I64::ZERO, U64::ZERO, I64::ZERO, U64::ZERO) + pub fn get_price_unsafe(&self, _id: [u8; 32]) -> Result { + let id_fb = FixedBytes::<32>::from(_id); + + let price_info = self.latest_price_info.get(id_fb).unwrap_or(PythReceiverError::PriceUnavailable)?; + + Ok(( + price_info.publish_time, + price_info.expo, + price_info.price, + price_info.conf, + price_info.ema_price, + price_info.ema_conf, + )) } - pub fn get_price_no_older_than(&self, _id: [u8; 32], _age: u64) -> PriceInfoReturn { - (U64::ZERO, I32::ZERO, I64::ZERO, U64::ZERO, I64::ZERO, U64::ZERO) + pub fn get_price_no_older_than(&self, _id: [u8; 32], _age: u64) -> Result { + let price_info = self.get_price_unsafe(_id)?; + if !self.is_no_older_than(price_info.0, _age) { + return Err(PythReceiverError::PriceUnavailable); + } + Ok(price_info) } pub fn get_ema_price_unsafe(&self, _id: [u8; 32]) -> PriceInfoReturn { @@ -108,4 +125,11 @@ impl PythReceiver { ) -> Vec { Vec::new() } + + fn is_no_older_than(&self, publish_time: U64, max_age: u64) -> bool { + let current_u64: u64 = self.vm().block_timestamp(); + let publish_time_u64: u64 = publish_time.to::(); + + current_u64.saturating_sub(publish_time_u64) <= max_age + } } From 5014fb40eb41f63504ab894f60cbe0e644c164eb Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Thu, 19 Jun 2025 13:39:20 +0000 Subject: [PATCH 2/2] Fix StorageGuard access in get_price_unsafe function - Replace incorrect .try_read().ok_or() with proper .get() method calls - Add zero-value check for publish_time to determine if price data exists - Contract now compiles successfully without StorageGuard errors Co-Authored-By: ayush.suresh@dourolabs.xyz --- .../stylus/contracts/pyth-receiver/src/lib.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/target_chains/stylus/contracts/pyth-receiver/src/lib.rs b/target_chains/stylus/contracts/pyth-receiver/src/lib.rs index 654e39a8bb..35fc43c127 100644 --- a/target_chains/stylus/contracts/pyth-receiver/src/lib.rs +++ b/target_chains/stylus/contracts/pyth-receiver/src/lib.rs @@ -36,15 +36,19 @@ impl PythReceiver { pub fn get_price_unsafe(&self, _id: [u8; 32]) -> Result { let id_fb = FixedBytes::<32>::from(_id); - let price_info = self.latest_price_info.get(id_fb).unwrap_or(PythReceiverError::PriceUnavailable)?; + let price_info = self.latest_price_info.get(id_fb); + + if price_info.publish_time.get() == U64::ZERO { + return Err(PythReceiverError::PriceUnavailable); + } Ok(( - price_info.publish_time, - price_info.expo, - price_info.price, - price_info.conf, - price_info.ema_price, - price_info.ema_conf, + price_info.publish_time.get(), + price_info.expo.get(), + price_info.price.get(), + price_info.conf.get(), + price_info.ema_price.get(), + price_info.ema_conf.get(), )) }