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