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 pub lifetime_deployed: u64,
55}
56
57impl Miner {
58 pub fn pda(&self) -> (Pubkey, u8) {
59 miner_pda(self.authority)
60 }
61
62 pub fn claim_ore(&mut self, clock: &Clock, treasury: &mut Treasury) -> u64 {
63 self.update_rewards(treasury);
64 let refined_ore = self.refined_ore;
65 let rewards_ore = self.rewards_ore;
66 let mut amount = refined_ore + rewards_ore;
67 self.refined_ore = 0;
68 self.rewards_ore = 0;
69 treasury.total_unclaimed -= rewards_ore;
70 treasury.total_refined -= refined_ore;
71 self.last_claim_ore_at = clock.unix_timestamp;
72
73 if treasury.total_unclaimed > 0 {
75 let fee = rewards_ore / 10;
76 amount -= fee;
77 treasury.miner_rewards_factor += Numeric::from_fraction(fee, treasury.total_unclaimed);
78 treasury.total_refined += fee;
79 self.lifetime_rewards_ore -= fee;
80 }
81
82 amount
83 }
84
85 pub fn claim_sol(&mut self, clock: &Clock) -> u64 {
86 let amount = self.rewards_sol;
87 self.rewards_sol = 0;
88 self.last_claim_sol_at = clock.unix_timestamp;
89 amount
90 }
91
92 pub fn update_rewards(&mut self, treasury: &Treasury) {
93 if treasury.miner_rewards_factor > self.rewards_factor {
95 let accumulated_rewards = treasury.miner_rewards_factor - self.rewards_factor;
96 if accumulated_rewards < Numeric::ZERO {
97 panic!("Accumulated rewards is negative");
98 }
99 let personal_rewards = accumulated_rewards * Numeric::from_u64(self.rewards_ore);
100 self.refined_ore += personal_rewards.to_u64();
101 self.lifetime_rewards_ore += personal_rewards.to_u64();
102 }
103
104 self.rewards_factor = treasury.miner_rewards_factor;
106 }
107}
108
109account!(OreAccount, Miner);