Skip to content

Commit 941027f

Browse files
authored
Merge pull request #2794 from pyth-network/pyth-stylus-get-prices
feat(stylus) - get prices pyth contract functions
2 parents a5a6973 + 5014fb4 commit 941027f

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use alloc::vec::Vec;
2+
3+
pub enum PythReceiverError {
4+
PriceUnavailable
5+
}
6+
7+
impl core::fmt::Debug for PythReceiverError {
8+
fn fmt(&self, _: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
9+
Ok(())
10+
}
11+
}
12+
13+
impl From<PythReceiverError> for Vec<u8> {
14+
fn from(error: PythReceiverError) -> Vec<u8> {
15+
vec![match error {
16+
PythReceiverError::PriceUnavailable => 1,
17+
}]
18+
}
19+
}

target_chains/stylus/contracts/pyth-receiver/src/lib.rs

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
extern crate alloc;
77

88
mod structs;
9+
mod error;
910

1011
use alloc::vec::Vec;
1112
use stylus_sdk::{alloy_primitives::{U256, U64, I32, I64, FixedBytes},
1213
prelude::*,
1314
storage::{StorageAddress, StorageVec, StorageMap, StorageUint, StorageBool, StorageU256}};
1415

1516
use structs::{DataSourceStorage, PriceInfoReturn, PriceInfoStorage};
17+
use error::{PythReceiverError};
1618

1719
#[storage]
1820
#[entrypoint]
@@ -31,12 +33,31 @@ pub struct PythReceiver {
3133

3234
#[public]
3335
impl PythReceiver {
34-
pub fn get_price_unsafe(&self, _id: [u8; 32]) -> PriceInfoReturn {
35-
(U64::ZERO, I32::ZERO, I64::ZERO, U64::ZERO, I64::ZERO, U64::ZERO)
36+
pub fn get_price_unsafe(&self, _id: [u8; 32]) -> Result<PriceInfoReturn, PythReceiverError> {
37+
let id_fb = FixedBytes::<32>::from(_id);
38+
39+
let price_info = self.latest_price_info.get(id_fb);
40+
41+
if price_info.publish_time.get() == U64::ZERO {
42+
return Err(PythReceiverError::PriceUnavailable);
43+
}
44+
45+
Ok((
46+
price_info.publish_time.get(),
47+
price_info.expo.get(),
48+
price_info.price.get(),
49+
price_info.conf.get(),
50+
price_info.ema_price.get(),
51+
price_info.ema_conf.get(),
52+
))
3653
}
3754

38-
pub fn get_price_no_older_than(&self, _id: [u8; 32], _age: u64) -> PriceInfoReturn {
39-
(U64::ZERO, I32::ZERO, I64::ZERO, U64::ZERO, I64::ZERO, U64::ZERO)
55+
pub fn get_price_no_older_than(&self, _id: [u8; 32], _age: u64) -> Result<PriceInfoReturn, PythReceiverError> {
56+
let price_info = self.get_price_unsafe(_id)?;
57+
if !self.is_no_older_than(price_info.0, _age) {
58+
return Err(PythReceiverError::PriceUnavailable);
59+
}
60+
Ok(price_info)
4061
}
4162

4263
pub fn get_ema_price_unsafe(&self, _id: [u8; 32]) -> PriceInfoReturn {
@@ -108,4 +129,11 @@ impl PythReceiver {
108129
) -> Vec<PriceInfoReturn> {
109130
Vec::new()
110131
}
132+
133+
fn is_no_older_than(&self, publish_time: U64, max_age: u64) -> bool {
134+
let current_u64: u64 = self.vm().block_timestamp();
135+
let publish_time_u64: u64 = publish_time.to::<u64>();
136+
137+
current_u64.saturating_sub(publish_time_u64) <= max_age
138+
}
111139
}

0 commit comments

Comments
 (0)