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