port_variable_rate_lending_instructions/
pyth.rs

1#![allow(missing_docs)]
2/// Derived from https://github.com/project-serum/anchor/blob/9224e0fa99093943a6190e396bccbc3387e5b230/examples/pyth/programs/pyth/src/pc.rs
3use bytemuck::{
4    cast_slice, cast_slice_mut, from_bytes, from_bytes_mut, try_cast_slice, try_cast_slice_mut,
5    Pod, PodCastError, Zeroable,
6};
7use std::mem::size_of;
8
9pub const MAGIC: u32 = 0xa1b2c3d4;
10pub const VERSION_1: u32 = 1;
11pub const VERSION_2: u32 = 2;
12pub const VERSION: u32 = VERSION_2;
13pub const MAP_TABLE_SIZE: usize = 640;
14pub const PROD_ACCT_SIZE: usize = 512;
15pub const PROD_HDR_SIZE: usize = 48;
16pub const PROD_ATTR_SIZE: usize = PROD_ACCT_SIZE - PROD_HDR_SIZE;
17
18#[derive(Copy, Clone)]
19#[repr(C)]
20pub struct AccKey {
21    pub val: [u8; 32],
22}
23
24#[derive(Copy, Clone)]
25#[repr(C)]
26pub enum AccountType {
27    Unknown,
28    Mapping,
29    Product,
30    Price,
31}
32
33#[derive(Copy, Clone)]
34#[repr(C)]
35pub enum PriceStatus {
36    Unknown,
37    Trading,
38    Halted,
39    Auction,
40}
41
42#[derive(Copy, Clone)]
43#[repr(C)]
44pub enum CorpAction {
45    NoCorpAct,
46}
47
48#[derive(Copy, Clone)]
49#[repr(C)]
50pub struct PriceInfo {
51    pub price: i64,
52    pub conf: u64,
53    pub status: PriceStatus,
54    pub corp_act: CorpAction,
55    pub pub_slot: u64,
56}
57
58#[derive(Copy, Clone)]
59#[repr(C)]
60pub struct PriceComp {
61    publisher: AccKey,
62    agg: PriceInfo,
63    latest: PriceInfo,
64}
65
66#[derive(PartialEq, Copy, Clone)]
67#[repr(C)]
68pub enum PriceType {
69    Unknown,
70    Price,
71    #[allow(clippy::upper_case_acronyms)]
72    TWAP,
73    Volatility,
74}
75
76#[derive(Copy, Clone)]
77#[repr(C)]
78pub struct Price {
79    pub magic: u32,       // Pyth magic number.
80    pub ver: u32,         // Program version.
81    pub atype: u32,       // Account type.
82    pub size: u32,        // Price account size.
83    pub ptype: PriceType, // Price or calculation type.
84    pub expo: i32,        // Price exponent.
85    pub num: u32,         // Number of component prices.
86    pub unused: u32,
87    pub curr_slot: u64,        // Currently accumulating price slot.
88    pub valid_slot: u64,       // Valid slot-time of agg. price.
89    pub twap: i64,             // Time-weighted average price.
90    pub avol: u64,             // Annualized price volatility.
91    pub drv0: i64,             // Space for future derived values.
92    pub drv1: i64,             // Space for future derived values.
93    pub drv2: i64,             // Space for future derived values.
94    pub drv3: i64,             // Space for future derived values.
95    pub drv4: i64,             // Space for future derived values.
96    pub drv5: i64,             // Space for future derived values.
97    pub prod: AccKey,          // Product account key.
98    pub next: AccKey,          // Next Price account in linked list.
99    pub agg_pub: AccKey,       // Quoter who computed last aggregate price.
100    pub agg: PriceInfo,        // Aggregate price info.
101    pub comp: [PriceComp; 32], // Price components one per quoter.
102}
103
104#[cfg(target_endian = "little")]
105unsafe impl Zeroable for Price {}
106
107#[cfg(target_endian = "little")]
108unsafe impl Pod for Price {}
109
110#[derive(Copy, Clone)]
111#[repr(C)]
112pub struct Product {
113    pub magic: u32,                 // pyth magic number
114    pub ver: u32,                   // program version
115    pub atype: u32,                 // account type
116    pub size: u32,                  // price account size
117    pub px_acc: AccKey,             // first price account in list
118    pub attr: [u8; PROD_ATTR_SIZE], // key/value pairs of reference attr.
119}
120
121#[cfg(target_endian = "little")]
122unsafe impl Zeroable for Product {}
123
124#[cfg(target_endian = "little")]
125unsafe impl Pod for Product {}
126
127pub fn load<T: Pod>(data: &[u8]) -> Result<&T, PodCastError> {
128    let size = size_of::<T>();
129    Ok(from_bytes(cast_slice::<u8, u8>(try_cast_slice(
130        &data[0..size],
131    )?)))
132}
133
134pub fn load_mut<T: Pod>(data: &mut [u8]) -> Result<&mut T, PodCastError> {
135    let size = size_of::<T>();
136    Ok(from_bytes_mut(cast_slice_mut::<u8, u8>(
137        try_cast_slice_mut(&mut data[0..size])?,
138    )))
139}