1use steel::*;
2
3use crate::state::{miner_pda, Treasury};
4
5use super::OreAccount;
6
7#[repr(C)]
8#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
9pub struct Miner {
10 pub authority: Pubkey,
12
13 pub deployed: [u64; 25],
15
16 pub cumulative: [u64; 25],
18
19 pub checkpoint_fee: u64,
21
22 pub checkpoint_id: u64,
24
25 pub last_claim_ore_at: i64,
27
28 pub last_claim_sol_at: i64,
30
31 pub rewards_factor: Numeric,
33
34 pub rewards_sol: u64,
36
37 pub rewards_ore: u64,
39
40 pub refined_ore: u64,
42
43 pub round_id: u64,
45
46 pub lifetime_rewards_sol: u64,
48
49 pub lifetime_rewards_ore: u64,
51}
52
53impl Miner {
54 pub fn pda(&self) -> (Pubkey, u8) {
55 miner_pda(self.authority)
56 }
57
58 pub fn claim_ore(&mut self, clock: &Clock, treasury: &mut Treasury) -> u64 {
59 self.update_rewards(treasury);
60 let refined_ore = self.refined_ore;
61 let rewards_ore = self.rewards_ore;
62 let mut amount = refined_ore + rewards_ore;
63 self.refined_ore = 0;
64 self.rewards_ore = 0;
65 treasury.total_unclaimed -= rewards_ore;
66 treasury.total_refined -= refined_ore;
67 self.last_claim_ore_at = clock.unix_timestamp;
68
69 if treasury.total_unclaimed > 0 {
71 let fee = rewards_ore / 10;
72 amount -= fee;
73 treasury.miner_rewards_factor += Numeric::from_fraction(fee, treasury.total_unclaimed);
74 treasury.total_refined += fee;
75 self.lifetime_rewards_ore -= fee;
76 }
77
78 amount
79 }
80
81 pub fn claim_sol(&mut self, clock: &Clock) -> u64 {
82 let amount = self.rewards_sol;
83 self.rewards_sol = 0;
84 self.last_claim_sol_at = clock.unix_timestamp;
85 amount
86 }
87
88 pub fn update_rewards(&mut self, treasury: &Treasury) {
89 if treasury.miner_rewards_factor > self.rewards_factor {
91 let accumulated_rewards = treasury.miner_rewards_factor - self.rewards_factor;
92 if accumulated_rewards < Numeric::ZERO {
93 panic!("Accumulated rewards is negative");
94 }
95 let personal_rewards = accumulated_rewards * Numeric::from_u64(self.rewards_ore);
96 self.refined_ore += personal_rewards.to_u64();
97 self.lifetime_rewards_ore += personal_rewards.to_u64();
98 }
99
100 self.rewards_factor = treasury.miner_rewards_factor;
102 }
103}
104
105account!(OreAccount, Miner);