ore_api/state/
automation.rs1use ore_mint_api::consts::ONE_ORE;
2use serde::{Deserialize, Serialize};
3use steel::*;
4
5use crate::state::{automation_pda, OreAccount};
6
7#[repr(C)]
8#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
9pub struct Automation {
10 pub amount: u64,
12
13 pub authority: Pubkey,
15
16 pub balance: u64,
18
19 pub executor: Pubkey,
21
22 pub fee: u64,
24
25 pub strategy: u64,
27
28 pub mask: u64,
31
32 pub reload: u64,
34
35 pub total_sol_spent: u64,
37
38 pub total_ore_earned: u64,
40
41 pub conditions: AutomationConditions,
43}
44
45#[repr(C)]
47#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable, Serialize, Deserialize)]
48pub struct AutomationConditions {
49 pub max_production_cost: u64,
52
53 pub min_motherlode: u16,
56
57 pub max_motherlode: u16,
60
61 pub split_tiles: u16,
64
65 pub solo_tiles: u16,
68
69 pub _buffer: u64,
71}
72
73#[repr(u8)]
74#[derive(Clone, Copy, Debug, PartialEq, IntoPrimitive, TryFromPrimitive)]
75pub enum AutomationStrategy {
76 Random = 0,
77 Preferred = 1,
78 Discretionary = 2,
79 DiscretionaryBps = 3,
80}
81
82impl AutomationStrategy {
83 pub fn from_u64(value: u64) -> Self {
84 Self::try_from(value as u8).unwrap()
85 }
86}
87
88impl Default for AutomationConditions {
89 fn default() -> Self {
90 Self {
91 max_production_cost: u64::MAX,
92 min_motherlode: 0,
93 max_motherlode: u16::MAX,
94 split_tiles: 0,
95 solo_tiles: 0,
96 _buffer: 0,
97 }
98 }
99}
100
101impl AutomationConditions {
102 pub fn to_bytes(&self) -> [u8; 24] {
103 let mut bytes = [0; 24];
104 bytes[0..8].copy_from_slice(&self.max_production_cost.to_le_bytes());
105 bytes[8..10].copy_from_slice(&self.min_motherlode.to_le_bytes());
106 bytes[10..12].copy_from_slice(&self.max_motherlode.to_le_bytes());
107 bytes[12..14].copy_from_slice(&self.split_tiles.to_le_bytes());
108 bytes[14..16].copy_from_slice(&self.solo_tiles.to_le_bytes());
109 bytes[16..24].copy_from_slice(&self._buffer.to_le_bytes());
110 bytes
111 }
112
113 pub fn from_bytes(bytes: [u8; 24]) -> Self {
114 Self {
115 max_production_cost: u64::from_le_bytes(bytes[0..8].try_into().unwrap()),
116 min_motherlode: u16::from_le_bytes(bytes[8..10].try_into().unwrap()),
117 max_motherlode: u16::from_le_bytes(bytes[10..12].try_into().unwrap()),
118 split_tiles: u16::from_le_bytes(bytes[12..14].try_into().unwrap()),
119 solo_tiles: u16::from_le_bytes(bytes[14..16].try_into().unwrap()),
120 _buffer: u64::from_le_bytes(bytes[16..24].try_into().unwrap()),
121 }
122 }
123}
124
125impl Automation {
126 pub fn pda(&self) -> (Pubkey, u8) {
127 automation_pda(self.authority)
128 }
129
130 pub fn min_fee(&self, deploy_amount: u64) -> u64 {
131 if self.strategy == AutomationStrategy::DiscretionaryBps as u64 {
132 ((deploy_amount as u128 * self.fee as u128) / crate::consts::DENOMINATOR_BPS as u128) as u64
133 } else {
134 self.fee
135 }
136 }
137
138 pub fn production_cost(&self) -> u64 {
139 if self.total_ore_earned == 0 {
140 return 0;
141 }
142 ((self.total_sol_spent as u128) * (ONE_ORE as u128) / (self.total_ore_earned as u128))
143 as u64
144 }
145}
146
147account!(OreAccount, Automation);