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    /// Halving period in seconds (28 days = 2,419,200 seconds)
12    /// Halvings occur every 28 days, reducing mining rates by 50%
13    pub halving_period_seconds: u64,
14    
15    /// Timestamp of the last halving event (Unix timestamp in seconds)
16    /// Used to calculate when the next halving should occur
17    pub last_halving_time: u64,
18    
19    /// Base mining rates per well (OIL per second, in atomic units)
20    /// OIL's rates: totaling 4.5 OIL/s (12.5% higher than Macaron's 4.0 OIL/s)
21    /// - Well 0 (Seep): 0.45 OIL/s = 45,000,000,000 atomic units/s
22    /// - Well 1 (Flow): 0.9 OIL/s = 90,000,000,000 atomic units/s
23    /// - Well 2 (Gusher): 1.35 OIL/s = 135,000,000,000 atomic units/s
24    /// - Well 3 (Blowout): 1.8 OIL/s = 180,000,000,000 atomic units/s
25    /// Total: 4.5 OIL/s (12.5% higher than Macaron's 4.0 OIL/s)
26    /// Balanced approach: slightly higher rewards with lower LP SOL (55 vs 60)
27    pub base_mining_rates: [u64; 4],
28    
29    /// Minimum contribution to join auction pool (0.01 SOL = 10,000,000 lamports)
30    pub min_pool_contribution: u64,
31    
32    /// Auction duration in seconds (1 hour = 3600)
33    pub auction_duration_seconds: u64,
34    
35    /// Starting prices per well (in lamports)
36    /// Scaled to match mining rate differentiation for strategic choices:
37    /// - Well 0 (Seep): 0.1 SOL = 100,000,000 lamports (lowest price, accessible)
38    /// - Well 1 (Flow): 0.2 SOL = 200,000,000 lamports (2x Well 0)
39    /// - Well 2 (Gusher): 0.3 SOL = 300,000,000 lamports (3x Well 0)
40    /// - Well 3 (Blowout): 0.4 SOL = 400,000,000 lamports (4x Well 0)
41    pub starting_prices: [u64; 4],
42    
43    /// Buffer field (for future use)
44    pub buffer_a: Numeric,
45    
46    /// Buffer field (for future use)
47    pub buffer_b: u64,
48    
49    /// Buffer field (for future use)
50    pub buffer_c: u64,
51    
52    /// Buffer field (for future use)
53    pub buffer_d: u64,
54}
55
56impl Auction {
57    pub fn pda() -> (Pubkey, u8) {
58        auction_pda()
59    }
60
61    /// Get the timestamp when the next halving should occur
62    /// Halvings occur every halving_period_seconds (28 days)
63    pub fn next_halving_time(&self) -> u64 {
64        if self.last_halving_time == 0 {
65            // If never halved, next halving is period_seconds from now
66            // This should be set during initialization
67            return self.halving_period_seconds;
68        }
69        self.last_halving_time + self.halving_period_seconds
70    }
71    
72    /// Check if halving should be applied based on current time
73    /// Returns number of halvings to apply (can be > 1 if multiple periods passed)
74    /// Each halving reduces rates by 50% (multiply by 0.5)
75    pub fn should_apply_halving(&self, current_time: u64) -> u64 {
76        if self.last_halving_time == 0 {
77            // First halving check - if current_time >= halving_period_seconds, apply one halving
78            if current_time >= self.halving_period_seconds {
79                return 1;
80            }
81            return 0;
82        }
83        
84        if current_time < self.last_halving_time {
85            return 0; // Time hasn't reached last halving yet
86        }
87        
88        // Calculate how many halving periods have passed
89        let time_since_last_halving = current_time - self.last_halving_time;
90        let halvings_to_apply = time_since_last_halving / self.halving_period_seconds;
91        
92        halvings_to_apply
93    }
94}
95
96account!(OilAccount, Auction);
97