Skip to main content

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