spl_token_lending/
pyth.rs

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