Skip to main content

antegen_thread_program/state/
config.rs

1use anchor_lang::prelude::*;
2
3/// Trait for calculating commission fees
4pub trait CommissionCalculator {
5    fn calculate_commission_multiplier(&self, time_since_ready: i64) -> f64;
6    fn calculate_effective_commission(&self, time_since_ready: i64) -> u64;
7    fn calculate_executor_fee(&self, effective_commission: u64) -> u64;
8    fn calculate_core_team_fee(&self, effective_commission: u64) -> u64;
9}
10
11/// Struct to hold payment details
12#[derive(Debug)]
13pub struct PaymentDetails {
14    pub fee_payer_reimbursement: u64,
15    pub executor_commission: u64,
16    pub core_team_fee: u64,
17}
18
19/// Trait for processing payments
20pub trait PaymentProcessor {
21    fn calculate_payments(
22        &self,
23        time_since_ready: i64,
24        balance_change: i64,
25        forgo_commission: bool,
26    ) -> PaymentDetails;
27    
28    fn should_pay(&self, balance_change: i64) -> bool {
29        balance_change <= 0  // Pay if balance decreased or stayed same
30    }
31    
32    fn calculate_reimbursement(&self, balance_change: i64) -> u64 {
33        if balance_change < 0 {
34            balance_change.abs() as u64
35        } else if balance_change > 0 {
36            0  // Already paid by inner instruction
37        } else {
38            5000u64  // Default reimbursement
39        }
40    }
41}
42
43/// Global configuration for the thread program
44#[account]
45#[derive(Debug, InitSpace)]
46pub struct ThreadConfig {
47    /// Version for future upgrades
48    pub version: u64,
49    /// Bump seed for PDA
50    pub bump: u8,
51    /// Admin who can update configuration
52    pub admin: Pubkey,
53    /// Global pause flag for all threads
54    pub paused: bool,
55    /// Base commission fee in lamports (when executed on time)
56    pub commission_fee: u64,
57    /// Fee percentage for executor (9000 = 90%)
58    pub executor_fee_bps: u64,
59    /// Core team fee percentage (1000 = 10%)
60    pub core_team_bps: u64,
61    /// Grace period in seconds where full commission applies
62    pub grace_period_seconds: i64,
63    /// Decay period in seconds after grace (commission decays to 0)
64    pub fee_decay_seconds: i64,
65}
66
67impl ThreadConfig {
68    pub fn pubkey() -> Pubkey {
69        Pubkey::find_program_address(&[crate::SEED_CONFIG], &crate::ID).0
70    }
71
72    pub fn space() -> usize {
73        8 + Self::INIT_SPACE
74    }
75}
76
77impl CommissionCalculator for ThreadConfig {
78    fn calculate_commission_multiplier(&self, time_since_ready: i64) -> f64 {
79        if time_since_ready <= self.grace_period_seconds {
80            // Within grace period: full commission
81            1.0
82        } else if time_since_ready <= self.grace_period_seconds + self.fee_decay_seconds {
83            // Within decay period: linear decay from 100% to 0%
84            let time_into_decay = (time_since_ready - self.grace_period_seconds) as f64;
85            let decay_progress = time_into_decay / self.fee_decay_seconds as f64;
86            1.0 - decay_progress
87        } else {
88            // After grace + decay period: no commission
89            0.0
90        }
91    }
92    
93    fn calculate_effective_commission(&self, time_since_ready: i64) -> u64 {
94        let multiplier = self.calculate_commission_multiplier(time_since_ready);
95        (self.commission_fee as f64 * multiplier) as u64
96    }
97    
98    fn calculate_executor_fee(&self, effective_commission: u64) -> u64 {
99        (effective_commission * self.executor_fee_bps) / 10_000
100    }
101    
102    fn calculate_core_team_fee(&self, effective_commission: u64) -> u64 {
103        (effective_commission * self.core_team_bps) / 10_000
104    }
105}
106
107impl PaymentProcessor for ThreadConfig {
108    fn calculate_payments(
109        &self,
110        time_since_ready: i64,
111        balance_change: i64,
112        forgo_commission: bool,
113    ) -> PaymentDetails {
114        // Calculate effective commission
115        let effective_commission = self.calculate_effective_commission(time_since_ready);
116        
117        // Calculate reimbursement and commission for executor
118        let (fee_payer_reimbursement, executor_commission) = if self.should_pay(balance_change) {
119            let reimbursement = self.calculate_reimbursement(balance_change);
120            let commission = if !forgo_commission {
121                self.calculate_executor_fee(effective_commission)
122            } else {
123                0
124            };
125            (reimbursement, commission)
126        } else {
127            (0, 0)
128        };
129        
130        // Calculate core team fee
131        let core_team_fee = self.calculate_core_team_fee(effective_commission);
132        
133        PaymentDetails {
134            fee_payer_reimbursement,
135            executor_commission,
136            core_team_fee,
137        }
138    }
139}