oil_api/state/auction.rs
1use serde::{Deserialize, Serialize};
2use steel::*;
3
4use crate::state::auction_pda;
5use super::OilAccount;
6
7/// Singleton auction configuration account
8#[repr(C)]
9#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
10pub struct Auction {
11 /// Subsequent halving period in seconds (28 days = 2,419,200 seconds)
12 pub halving_period_seconds: u64,
13
14 /// Timestamp of the last halving event (Unix timestamp in seconds)
15 pub last_halving_time: u64,
16
17 /// Base mining rates per well (OIL per second, in atomic units)
18 pub base_mining_rates: [u64; 4],
19
20 /// Auction duration in seconds (1 hour = 3600)
21 pub auction_duration_seconds: u64,
22
23 /// Starting prices per well (in lamports)
24 pub starting_prices: [u64; 4],
25
26 /// Buffer field (for future use)
27 pub buffer_a: Numeric,
28
29 /// Number of halvings that have occurred (0 = none, 1 = first 50% halving, 2+ = 25% halvings)
30 pub halving_count: u64,
31
32 /// Buffer field (for future use)
33 pub buffer_c: u64,
34
35 /// Buffer field (for future use)
36 pub buffer_d: u64,
37}
38
39impl Auction {
40 pub fn pda() -> (Pubkey, u8) {
41 auction_pda()
42 }
43
44 /// First halving period in seconds (14 days = 1,209,600 seconds)
45 /// This is a constant, not stored in the account
46 pub const FIRST_HALVING_PERIOD_SECONDS: u64 = 14 * 24 * 60 * 60;
47
48 /// Get the timestamp when the next halving should occur
49 pub fn next_halving_time(&self) -> u64 {
50 if self.halving_count == 0 {
51 // First halving is at FIRST_HALVING_PERIOD_SECONDS (14 days) after initialization
52 // last_halving_time is set to initialization time, so add 14 days
53 return self.last_halving_time + Self::FIRST_HALVING_PERIOD_SECONDS;
54 }
55
56 // After first halving, subsequent halvings are every halving_period_seconds (28 days)
57 self.last_halving_time + self.halving_period_seconds
58 }
59
60 /// Check if halving should be applied based on current time
61 /// Returns (halvings_to_apply, is_first_halving)
62 ///
63 /// Schedule:
64 /// - First halving: 14 days after initialization (50% reduction)
65 /// - Subsequent halvings: Every 28 days after first halving (25% reduction each)
66 pub fn should_apply_halving(&self, current_time: u64) -> (u64, bool) {
67 // If no halvings have occurred yet, check for first halving (14 days)
68 if self.halving_count == 0 {
69 // last_halving_time is set to initialization time, so check if 14 days have passed
70 if current_time >= self.last_halving_time + Self::FIRST_HALVING_PERIOD_SECONDS {
71 return (1, true);
72 }
73 return (0, false);
74 }
75
76 // After first halving, check for subsequent halvings (every 28 days)
77 if current_time < self.last_halving_time {
78 return (0, false); // Time hasn't reached last halving yet
79 }
80
81 // Calculate how many halving periods have passed since last halving
82 let time_since_last_halving = current_time - self.last_halving_time;
83 let halvings_to_apply = time_since_last_halving / self.halving_period_seconds;
84
85 // After first halving, all subsequent halvings are 25% reductions
86 (halvings_to_apply, false)
87 }
88}
89
90account!(OilAccount, Auction);
91