oil_api/state/
auction.rs

1use serde::{Deserialize, Serialize};
2use steel::*;
3
4use crate::state::auction_pda;
5
6use super::OilAccount;
7
8/// Singleton auction configuration account
9#[repr(C)]
10#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
11pub struct Auction {
12    /// [REPURPOSED] Total OIL minted from auction-based mining (in atomic units)
13    /// Used for supply-based halving: halvings occur at 1M, 2.5M, 5M, 10M, etc. OIL
14    /// Originally: halving_period_seconds (no longer used for time-based halving)
15    pub halving_period_seconds: u64,
16    
17    /// [REPURPOSED] Number of halvings that have been applied (starts at 0)
18    /// Each halving reduces rates by 25% (multiply by 0.75)
19    /// Originally: last_halving_time (no longer used for time-based halving)
20    pub last_halving_time: u64,
21    
22    /// Base mining rates per well (OIL per second, in atomic units)
23    /// Macaron's rates: totaling 4.0 OIL/s
24    /// - Well 0 (Seep): 0.4 OIL/s = 40,000,000,000 atomic units/s
25    /// - Well 1 (Flow): 0.8 OIL/s = 80,000,000,000 atomic units/s
26    /// - Well 2 (Gusher): 1.2 OIL/s = 120,000,000,000 atomic units/s
27    /// - Well 3 (Blowout): 1.6 OIL/s = 160,000,000,000 atomic units/s
28    /// Total: 4.0 OIL/s (matches Macaron's rates)
29    /// Creates meaningful trade-offs: higher rates = higher competition & prices
30    pub base_mining_rates: [u64; 4],
31    
32    /// Minimum contribution to join auction pool (0.01 SOL = 10,000,000 lamports)
33    pub min_pool_contribution: u64,
34    
35    /// Auction duration in seconds (1 hour = 3600)
36    pub auction_duration_seconds: u64,
37    
38    /// Starting prices per well (in lamports)
39    /// Scaled to match mining rate differentiation for strategic choices:
40    /// - Well 0 (Seep): 0.1 SOL = 100,000,000 lamports (lowest price, accessible)
41    /// - Well 1 (Flow): 0.2 SOL = 200,000,000 lamports (2x Well 0)
42    /// - Well 2 (Gusher): 0.3 SOL = 300,000,000 lamports (3x Well 0)
43    /// - Well 3 (Blowout): 0.4 SOL = 400,000,000 lamports (4x Well 0)
44    pub starting_prices: [u64; 4],
45    
46    /// Buffer field (for future use)
47    pub buffer_a: Numeric,
48    
49    /// Total OIL minted from auction-based mining (in atomic units)
50    /// Used for supply-based halving: halvings occur at 1M, 2.5M, 5M, 10M, etc. OIL
51    /// Repurposed from buffer_b - maintains account layout compatibility
52    pub total_auction_oil_minted: u64,
53    
54    /// Number of halvings that have been applied (starts at 0)
55    /// Each halving reduces rates by 25% (multiply by 0.75)
56    /// Repurposed from buffer_c - maintains account layout compatibility
57    pub halving_count: u64,
58    
59    /// Buffer field (for future use)
60    pub buffer_d: u64,
61}
62
63impl Auction {
64    pub fn pda() -> (Pubkey, u8) {
65        auction_pda()
66    }
67
68    /// Get the next halving threshold based on current halving count
69    /// Halving thresholds: 1M, 2.5M, 5M, 10M, 20M, 40M, etc. (exponential)
70    /// Formula: threshold = 1_000_000 * (2.5 ^ halving_count) for first 3, then doubles
71    pub fn next_halving_threshold(&self) -> u64 {
72        const ONE_MILLION: u64 = 1_000_000;
73        match self.halving_count {
74            0 => ONE_MILLION,                    // 1M
75            1 => ONE_MILLION * 25 / 10,          // 2.5M
76            2 => ONE_MILLION * 5,                // 5M
77            3 => ONE_MILLION * 10,               // 10M
78            n => {
79                // After 10M, double each time: 20M, 40M, 80M, etc.
80                ONE_MILLION * 10 * (1u64 << (n - 3))
81            }
82        }
83    }
84    
85    /// Check if halving should be applied based on total OIL minted
86    /// Returns number of halvings to apply (can be > 1 if multiple thresholds crossed)
87    pub fn should_apply_halving(&self) -> u64 {
88        let mut halvings_to_apply = 0;
89        let mut current_threshold = self.next_halving_threshold();
90        let mut current_halving_count = self.halving_count;
91        
92        // Check if we've crossed any thresholds
93        while self.total_auction_oil_minted >= current_threshold {
94            halvings_to_apply += 1;
95            current_halving_count += 1;
96            
97            // Calculate next threshold
98            const ONE_MILLION: u64 = 1_000_000;
99            current_threshold = match current_halving_count {
100                0 => ONE_MILLION,
101                1 => ONE_MILLION * 25 / 10,
102                2 => ONE_MILLION * 5,
103                3 => ONE_MILLION * 10,
104                n => ONE_MILLION * 10 * (1u64 << (n - 3)),
105            };
106        }
107        
108        halvings_to_apply
109    }
110}
111
112account!(OilAccount, Auction);
113