ore_stake_api/state/
stake.rs1use serde::{Deserialize, Serialize};
2use steel::*;
3
4use crate::state::{stake_pda, Treasury};
5
6use super::OreAccount;
7
8#[repr(C)]
9#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
10pub struct Stake {
11 pub authority: Pubkey,
13
14 pub balance: u64,
16
17 pub compound_fee: u64,
19
20 pub compound_fee_reserve: u64,
22
23 pub last_claim_at: i64,
25
26 pub last_deposit_at: i64,
28
29 pub last_withdraw_at: i64,
31
32 pub rewards_factor: Numeric,
34
35 pub rewards: u64,
37
38 pub lifetime_rewards: u64,
40}
41
42impl Stake {
43 pub fn pda(&self) -> (Pubkey, u8) {
44 stake_pda(self.authority)
45 }
46
47 pub fn claim(&mut self, amount: u64, clock: &Clock, treasury: &Treasury) -> u64 {
48 self.update_rewards(treasury);
49 let amount = self.rewards.min(amount);
50 self.rewards -= amount;
51 self.last_claim_at = clock.unix_timestamp;
52 amount
53 }
54
55 pub fn deposit(
56 &mut self,
57 amount: u64,
58 clock: &Clock,
59 treasury: &mut Treasury,
60 sender: &TokenAccount,
61 ) -> u64 {
62 self.update_rewards(treasury);
63 let amount = sender.amount().min(amount);
64 self.balance += amount;
65 self.last_deposit_at = clock.unix_timestamp;
66 treasury.total_staked += amount;
67 amount
68 }
69
70 pub fn withdraw(&mut self, amount: u64, clock: &Clock, treasury: &mut Treasury) -> u64 {
71 self.update_rewards(treasury);
72 let amount = self.balance.min(amount);
73 self.balance -= amount;
74 self.last_withdraw_at = clock.unix_timestamp;
75 treasury.total_staked -= amount;
76 amount
77 }
78
79 pub fn update_rewards(&mut self, treasury: &Treasury) {
80 if treasury.rewards_factor > self.rewards_factor {
82 let accumulated_rewards = treasury.rewards_factor - self.rewards_factor;
83 let personal_rewards = accumulated_rewards * Numeric::from_u64(self.balance);
84 self.rewards += personal_rewards.to_u64();
85 self.lifetime_rewards += personal_rewards.to_u64();
86 }
87
88 self.rewards_factor = treasury.rewards_factor;
90 }
91}
92
93account!(OreAccount, Stake);