1use serde::{Deserialize, Serialize};
2use steel::*;
3
4use crate::state::{miner_pda, OreAccount, Treasury};
5
6#[repr(C)]
7#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
8pub struct Miner {
9 pub authority: Pubkey,
11
12 pub auto_return: u64,
14
15 pub checkpoint_id: u64,
17
18 pub checkpoint_fee: u64,
20
21 pub deployed: [u64; 25],
24
25 pub mass: [u64; 25],
27
28 pub cumulative: [u64; 25],
31
32 pub round_id: u64,
34
35 pub rewards_factor: Numeric,
37
38 pub rewards_sol: u64,
41
42 pub refined_ore: u64,
45
46 pub rewards_ore: u64,
49
50 pub last_claim_ore_at: i64,
52
53 pub last_claim_sol_at: i64,
55
56 pub lifetime_rewards_ore: u64,
59
60 pub lifetime_deployed: u64,
62
63 pub lifetime_rewards_sol: u64,
66}
67
68impl Miner {
69 pub fn pda(&self) -> (Pubkey, u8) {
70 miner_pda(self.authority)
71 }
72
73 pub fn claim_ore(&mut self, clock: &Clock, treasury: &mut Treasury) -> u64 {
74 self.update_rewards(treasury);
75 let refined_ore = self.refined_ore;
76 let rewards_ore = self.rewards_ore;
77 let mut amount = refined_ore + rewards_ore;
78 self.refined_ore = 0;
79 self.rewards_ore = 0;
80 treasury.total_unclaimed -= rewards_ore;
81 treasury.total_refined -= refined_ore;
82 self.last_claim_ore_at = clock.unix_timestamp;
83
84 if treasury.total_unclaimed > 0 {
86 let fee = rewards_ore / 10;
87 amount -= fee;
88 treasury.miner_rewards_factor += Numeric::from_fraction(fee, treasury.total_unclaimed);
89 treasury.total_refined += fee;
90 self.lifetime_rewards_ore -= fee;
91 }
92
93 amount
94 }
95
96 pub fn claim_sol(&mut self, clock: &Clock) -> u64 {
97 let amount = self.rewards_sol;
98 self.rewards_sol = 0;
99 self.last_claim_sol_at = clock.unix_timestamp;
100 amount
101 }
102
103 pub fn update_rewards(&mut self, treasury: &Treasury) {
104 if treasury.miner_rewards_factor > self.rewards_factor {
106 let accumulated_rewards = treasury.miner_rewards_factor - self.rewards_factor;
107 if accumulated_rewards < Numeric::ZERO {
108 panic!("Accumulated rewards is negative");
109 }
110 let personal_rewards = accumulated_rewards * Numeric::from_u64(self.rewards_ore);
111 self.refined_ore += personal_rewards.to_u64();
112 self.lifetime_rewards_ore += personal_rewards.to_u64();
113 }
114
115 self.rewards_factor = treasury.miner_rewards_factor;
117 }
118}
119
120account!(OreAccount, Miner);