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