streak_api/state/
treasury.rs1use steel::*;
13
14use super::{treasury_pda, StreakAccount};
15
16#[repr(C)]
17#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
18pub struct Treasury {
19 pub daily_jackpot: u64,
21 pub weekly_jackpot: u64,
23 pub buyback: u64,
25 pub last_close_price: i64,
28 pub last_close_expo: i32,
30 pub _pad_close: [u8; 4],
31 pub last_close_publish_time: i64,
33 pub stability_reserve: u64,
35 pub daily_accrual: u64,
37}
38
39impl Treasury {
40 pub fn pda() -> (Pubkey, u8) {
41 treasury_pda()
42 }
43
44 pub const LEGACY_BODY_LEN: usize = 48;
46 pub const PRE_DAILY_ACCRUAL_BODY_LEN: usize = 56;
48
49 pub fn decode_account_data(data: &[u8]) -> Result<Self, &'static str> {
51 const DISC: usize = 8;
52 let body = data.get(DISC..).ok_or("treasury account empty")?;
53 let full = std::mem::size_of::<Self>();
54 if body.len() >= full {
55 return Ok(*bytemuck::from_bytes(&body[..full]));
56 }
57 if body.len() >= Self::PRE_DAILY_ACCRUAL_BODY_LEN {
58 #[repr(C)]
59 #[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
60 struct WithStability {
61 daily_jackpot: u64,
62 weekly_jackpot: u64,
63 buyback: u64,
64 last_close_price: i64,
65 last_close_expo: i32,
66 _pad_close: [u8; 4],
67 last_close_publish_time: i64,
68 stability_reserve: u64,
69 }
70 let ws: &WithStability =
71 bytemuck::from_bytes(&body[..Self::PRE_DAILY_ACCRUAL_BODY_LEN]);
72 return Ok(Self {
73 daily_jackpot: ws.daily_jackpot,
74 weekly_jackpot: ws.weekly_jackpot,
75 buyback: ws.buyback,
76 last_close_price: ws.last_close_price,
77 last_close_expo: ws.last_close_expo,
78 _pad_close: ws._pad_close,
79 last_close_publish_time: ws.last_close_publish_time,
80 stability_reserve: ws.stability_reserve,
81 daily_accrual: 0,
82 });
83 }
84 if body.len() >= Self::LEGACY_BODY_LEN {
85 #[repr(C)]
86 #[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
87 struct Legacy {
88 daily_jackpot: u64,
89 weekly_jackpot: u64,
90 buyback: u64,
91 last_close_price: i64,
92 last_close_expo: i32,
93 _pad_close: [u8; 4],
94 last_close_publish_time: i64,
95 }
96 let leg: &Legacy = bytemuck::from_bytes(&body[..Self::LEGACY_BODY_LEN]);
97 return Ok(Self {
98 daily_jackpot: leg.daily_jackpot,
99 weekly_jackpot: leg.weekly_jackpot,
100 buyback: leg.buyback,
101 last_close_price: leg.last_close_price,
102 last_close_expo: leg.last_close_expo,
103 _pad_close: leg._pad_close,
104 last_close_publish_time: leg.last_close_publish_time,
105 stability_reserve: 0,
106 daily_accrual: 0,
107 });
108 }
109 Err("treasury account too short")
110 }
111}
112
113account!(StreakAccount, Treasury);