Skip to main content

ore_api/state/
miner.rs

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    /// The authority of this miner account.
10    pub authority: Pubkey,
11
12    /// Whether or not to auto-return SOL winnings to the miner's wallet.
13    pub auto_return: u64,
14
15    /// The checkpoint ID.
16    pub checkpoint_id: u64,
17
18    /// SOL witheld in reserve to pay for checkpointing.
19    pub checkpoint_fee: u64,
20
21    /// The amount of SOL deployed on each square.
22    /// TODO: Rename to sol.
23    pub deployed: [u64; 25],
24
25    /// The amount of SOL deployed on each square, weighted by the time remaining when deployed.
26    pub mass: [u64; 25],
27
28    /// The cumulative mass on each square prior to this miner's deployment on that square.
29    /// TODO: Rename to mass_cumulative.
30    pub cumulative: [u64; 25],
31
32    /// The round ID.
33    pub round_id: u64,
34
35    /// The rewards factor last time rewards were updated on this miner account.
36    pub rewards_factor: Numeric,
37
38    /// The amount of SOL this miner has had returned and may claim.
39    /// TODO: Rename to sol_returned.
40    pub rewards_sol: u64,
41
42    /// The amount of ORE this miner has earned from refining fees and may claim.
43    /// TODO: Rename to ore_refined.
44    pub refined_ore: u64,
45
46    /// The amount of ORE this miner has mined and may claim.
47    /// TODO: Rename to ore_unrefined.
48    pub rewards_ore: u64,
49
50    /// The last time this miner claimed ORE rewards.
51    pub last_claim_ore_at: i64,
52
53    /// The last time this miner claimed SOL rewards.
54    pub last_claim_sol_at: i64,
55
56    /// The total amount of ORE this miner has mined across all blocks.
57    /// TODO: Rename to lifetime_rewards_ore.
58    pub lifetime_rewards_ore: u64,
59
60    /// The total amount of SOL this miner has deployed across all rounds.
61    pub lifetime_deployed: u64,
62
63    /// The total amount of SOL this miner has mined across all blocks.
64    /// TODO: Rename to lifetime_returned_sol.
65    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        // Charge a 10% fee and share with miners who haven't claimed yet.
85        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        // Accumulate rewards, weighted by stake balance.
105        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        // Update this miner account's last seen rewards factor.
116        self.rewards_factor = treasury.miner_rewards_factor;
117    }
118}
119
120account!(OreAccount, Miner);