Skip to main content

tenzro_types/
fees.rs

1//! TNZO fee structures for Tenzro Ledger operations
2//!
3//! This module defines fee schedules and commission rates for services
4//! on the Tenzro Ledger. All fees are denominated in TNZO (the governance token).
5//!
6//! # Fee Streams
7//!
8//! The Tenzro Network has two primary fee streams:
9//!
10//! 1. **Ledger fees** - Transaction gas fees paid in TNZO that flow to validators
11//! 2. **Network commissions** - Percentage of AI/TEE provider payments that flow to treasury
12//!
13//! # Architecture
14//!
15//! - **Tenzro Network** = Decentralized protocol for the AI age
16//! - **Tenzro Ledger** = L1 settlement layer (identity, verification, settlement in TNZO)
17//! - **TNZO** = Governance token used for ledger fees and network settlements
18
19use serde::{Deserialize, Serialize};
20
21/// Service fees for Tenzro Ledger operations, all denominated in TNZO
22///
23/// These fees are charged for ledger-level operations like identity registration,
24/// verification, and model registration. All amounts are in the smallest TNZO unit
25/// (18 decimal places, like Ethereum's wei).
26///
27/// # Examples
28///
29/// ```
30/// use tenzro_types::ServiceFeeSchedule;
31///
32/// let fees = ServiceFeeSchedule::default();
33/// assert_eq!(fees.human_identity_registration, 10_000_000_000_000_000_000); // 10 TNZO
34/// ```
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
36pub struct ServiceFeeSchedule {
37    /// Human identity registration fee (in smallest TNZO unit)
38    ///
39    /// Default: 10 TNZO (10 * 10^18)
40    pub human_identity_registration: u128,
41
42    /// Machine identity registration fee
43    ///
44    /// Default: 5 TNZO (5 * 10^18)
45    pub machine_identity_registration: u128,
46
47    /// Agent identity registration fee
48    ///
49    /// Default: 5 TNZO (5 * 10^18)
50    pub agent_registration: u128,
51
52    /// Credential issuance fee
53    ///
54    /// Default: 2 TNZO (2 * 10^18)
55    pub credential_issuance: u128,
56
57    /// Identity verification fee
58    ///
59    /// Default: 1 TNZO (1 * 10^18)
60    pub identity_verification: u128,
61
62    /// Model registration fee
63    ///
64    /// Default: 50 TNZO (50 * 10^18)
65    pub model_registration: u128,
66
67    /// Bridge transfer base fee
68    ///
69    /// Default: 1 TNZO (1 * 10^18)
70    pub bridge_transfer_base: u128,
71}
72
73impl Default for ServiceFeeSchedule {
74    fn default() -> Self {
75        const TNZO_DECIMALS: u32 = 18;
76        const ONE_TNZO: u128 = 10u128.pow(TNZO_DECIMALS);
77
78        Self {
79            human_identity_registration: 10 * ONE_TNZO,  // 10 TNZO
80            machine_identity_registration: 5 * ONE_TNZO, // 5 TNZO
81            agent_registration: 5 * ONE_TNZO,            // 5 TNZO
82            credential_issuance: 2 * ONE_TNZO,           // 2 TNZO
83            identity_verification: ONE_TNZO,             // 1 TNZO
84            model_registration: 50 * ONE_TNZO,           // 50 TNZO
85            bridge_transfer_base: ONE_TNZO,              // 1 TNZO
86        }
87    }
88}
89
90impl ServiceFeeSchedule {
91    /// Creates a new fee schedule with custom values
92    pub fn new(
93        human_identity_registration: u128,
94        machine_identity_registration: u128,
95        agent_registration: u128,
96        credential_issuance: u128,
97        identity_verification: u128,
98        model_registration: u128,
99        bridge_transfer_base: u128,
100    ) -> Self {
101        Self {
102            human_identity_registration,
103            machine_identity_registration,
104            agent_registration,
105            credential_issuance,
106            identity_verification,
107            model_registration,
108            bridge_transfer_base,
109        }
110    }
111
112    /// Returns the total fees collected across all categories
113    ///
114    /// Note: This requires keeping track of how many operations of each type have occurred.
115    /// The counts are passed as parameters.
116    pub fn calculate_total_collected(
117        &self,
118        human_identity_count: u128,
119        machine_identity_count: u128,
120        agent_count: u128,
121        credential_count: u128,
122        verification_count: u128,
123        model_count: u128,
124        bridge_count: u128,
125    ) -> Option<u128> {
126        let total = self.human_identity_registration
127            .checked_mul(human_identity_count)?
128            .checked_add(self.machine_identity_registration.checked_mul(machine_identity_count)?)?
129            .checked_add(self.agent_registration.checked_mul(agent_count)?)?
130            .checked_add(self.credential_issuance.checked_mul(credential_count)?)?
131            .checked_add(self.identity_verification.checked_mul(verification_count)?)?
132            .checked_add(self.model_registration.checked_mul(model_count)?)?
133            .checked_add(self.bridge_transfer_base.checked_mul(bridge_count)?)?;
134        Some(total)
135    }
136}
137
138/// Network commission rates for provider payments (in basis points, 100 = 1%)
139///
140/// These commissions are taken as a percentage of payments to AI inference providers,
141/// TEE enclave providers, key management services, and model hosting providers.
142/// The commission flows to the network treasury for protocol development and governance.
143///
144/// # Examples
145///
146/// ```
147/// use tenzro_types::NetworkCommissionRates;
148///
149/// let rates = NetworkCommissionRates::default();
150/// assert_eq!(rates.inference_commission_bps, 500); // 5%
151///
152/// // Calculate commission on a 100 TNZO payment
153/// let payment = 100_000_000_000_000_000_000u128; // 100 TNZO
154/// let commission = rates.calculate_inference_commission(payment).unwrap();
155/// assert_eq!(commission, 5_000_000_000_000_000_000u128); // 5 TNZO
156/// ```
157#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
158pub struct NetworkCommissionRates {
159    /// Commission on AI inference payments (basis points)
160    ///
161    /// Default: 500 bps (5%)
162    pub inference_commission_bps: u32,
163
164    /// Commission on TEE enclave usage payments (basis points)
165    ///
166    /// Default: 500 bps (5%)
167    pub tee_commission_bps: u32,
168
169    /// Commission on key management/custody payments (basis points)
170    ///
171    /// Default: 500 bps (5%)
172    pub custody_commission_bps: u32,
173
174    /// Commission on model hosting payments (basis points)
175    ///
176    /// Default: 500 bps (5%)
177    pub model_hosting_commission_bps: u32,
178}
179
180impl Default for NetworkCommissionRates {
181    fn default() -> Self {
182        Self {
183            inference_commission_bps: 500,      // 5%
184            tee_commission_bps: 500,            // 5%
185            custody_commission_bps: 500,        // 5%
186            model_hosting_commission_bps: 500,  // 5%
187        }
188    }
189}
190
191impl NetworkCommissionRates {
192    /// Creates a new commission rate structure with custom values
193    pub fn new(
194        inference_commission_bps: u32,
195        tee_commission_bps: u32,
196        custody_commission_bps: u32,
197        model_hosting_commission_bps: u32,
198    ) -> Self {
199        Self {
200            inference_commission_bps,
201            tee_commission_bps,
202            custody_commission_bps,
203            model_hosting_commission_bps,
204        }
205    }
206
207    /// Calculates the commission amount for an inference payment
208    ///
209    /// Returns None if the calculation would overflow.
210    pub fn calculate_inference_commission(&self, payment_amount: u128) -> Option<u128> {
211        self.calculate_commission(payment_amount, self.inference_commission_bps)
212    }
213
214    /// Calculates the commission amount for a TEE enclave payment
215    ///
216    /// Returns None if the calculation would overflow.
217    pub fn calculate_tee_commission(&self, payment_amount: u128) -> Option<u128> {
218        self.calculate_commission(payment_amount, self.tee_commission_bps)
219    }
220
221    /// Calculates the commission amount for a key custody payment
222    ///
223    /// Returns None if the calculation would overflow.
224    pub fn calculate_custody_commission(&self, payment_amount: u128) -> Option<u128> {
225        self.calculate_commission(payment_amount, self.custody_commission_bps)
226    }
227
228    /// Calculates the commission amount for a model hosting payment
229    ///
230    /// Returns None if the calculation would overflow.
231    pub fn calculate_model_hosting_commission(&self, payment_amount: u128) -> Option<u128> {
232        self.calculate_commission(payment_amount, self.model_hosting_commission_bps)
233    }
234
235    /// Helper function to calculate commission from basis points
236    ///
237    /// Returns None if the calculation would overflow.
238    fn calculate_commission(&self, amount: u128, bps: u32) -> Option<u128> {
239        // Commission = amount * bps / 10000
240        amount
241            .checked_mul(bps as u128)?
242            .checked_div(10000)
243    }
244
245    /// Validates that all commission rates are within reasonable bounds (0-10000 bps = 0-100%)
246    pub fn validate(&self) -> Result<(), &'static str> {
247        const MAX_BPS: u32 = 10000; // 100%
248
249        if self.inference_commission_bps > MAX_BPS {
250            return Err("Inference commission exceeds 100%");
251        }
252        if self.tee_commission_bps > MAX_BPS {
253            return Err("TEE commission exceeds 100%");
254        }
255        if self.custody_commission_bps > MAX_BPS {
256            return Err("Custody commission exceeds 100%");
257        }
258        if self.model_hosting_commission_bps > MAX_BPS {
259            return Err("Model hosting commission exceeds 100%");
260        }
261
262        Ok(())
263    }
264}
265
266#[cfg(test)]
267mod tests {
268    use super::*;
269
270    #[test]
271    fn test_service_fee_schedule_defaults() {
272        let fees = ServiceFeeSchedule::default();
273        const ONE_TNZO: u128 = 1_000_000_000_000_000_000; // 10^18
274
275        assert_eq!(fees.human_identity_registration, 10 * ONE_TNZO);
276        assert_eq!(fees.machine_identity_registration, 5 * ONE_TNZO);
277        assert_eq!(fees.agent_registration, 5 * ONE_TNZO);
278        assert_eq!(fees.credential_issuance, 2 * ONE_TNZO);
279        assert_eq!(fees.identity_verification, ONE_TNZO);
280        assert_eq!(fees.model_registration, 50 * ONE_TNZO);
281        assert_eq!(fees.bridge_transfer_base, ONE_TNZO);
282    }
283
284    #[test]
285    fn test_service_fee_schedule_total_collected() {
286        let fees = ServiceFeeSchedule::default();
287        const ONE_TNZO: u128 = 1_000_000_000_000_000_000;
288
289        // 1 of each operation
290        let total = fees.calculate_total_collected(1, 1, 1, 1, 1, 1, 1).unwrap();
291        let expected = 10 + 5 + 5 + 2 + 1 + 50 + 1; // 74 TNZO
292        assert_eq!(total, expected * ONE_TNZO);
293    }
294
295    #[test]
296    fn test_network_commission_rates_defaults() {
297        let rates = NetworkCommissionRates::default();
298
299        assert_eq!(rates.inference_commission_bps, 500);
300        assert_eq!(rates.tee_commission_bps, 500);
301        assert_eq!(rates.custody_commission_bps, 500);
302        assert_eq!(rates.model_hosting_commission_bps, 500);
303    }
304
305    #[test]
306    fn test_commission_calculation() {
307        let rates = NetworkCommissionRates::default();
308        const ONE_HUNDRED_TNZO: u128 = 100_000_000_000_000_000_000; // 100 * 10^18
309
310        // 5% of 100 TNZO = 5 TNZO
311        let commission = rates.calculate_inference_commission(ONE_HUNDRED_TNZO).unwrap();
312        assert_eq!(commission, 5_000_000_000_000_000_000);
313    }
314
315    #[test]
316    fn test_commission_validation() {
317        let valid_rates = NetworkCommissionRates::default();
318        assert!(valid_rates.validate().is_ok());
319
320        let invalid_rates = NetworkCommissionRates::new(15000, 500, 500, 500);
321        assert!(invalid_rates.validate().is_err());
322    }
323
324    #[test]
325    fn test_commission_overflow_protection() {
326        let rates = NetworkCommissionRates::default();
327
328        // Max u128 should not panic, but may return None
329        let result = rates.calculate_inference_commission(u128::MAX);
330        // We expect None due to overflow in checked_mul
331        assert!(result.is_none());
332    }
333}