Skip to main content

klend_interface/state/
lending_market.rs

1use bytemuck::{Pod, Zeroable};
2use solana_pubkey::Pubkey;
3use spl_discriminator::SplDiscriminate;
4use spl_pod::primitives::PodU128;
5
6// ---------------------------------------------------------------------------
7// LendingMarket
8// ---------------------------------------------------------------------------
9
10/// Lending market account state.
11#[derive(Debug, Clone, Copy, Pod, Zeroable, SplDiscriminate)]
12#[discriminator_hash_input("account:LendingMarket")]
13#[repr(C)]
14pub struct LendingMarket {
15    pub version: u64,
16    pub bump_seed: u64,
17    pub lending_market_owner: Pubkey,
18    pub lending_market_owner_cached: Pubkey,
19    pub quote_currency: [u8; 32],
20    pub referral_fee_bps: u16,
21    pub emergency_mode: u8,
22    pub autodeleverage_enabled: u8,
23    pub borrow_disabled: u8,
24    pub price_refresh_trigger_to_max_age_pct: u8,
25    pub liquidation_max_debt_close_factor_pct: u8,
26    pub insolvency_risk_unhealthy_ltv_pct: u8,
27    pub min_full_liquidation_value_threshold: u64,
28    pub max_liquidatable_debt_market_value_at_once: u64,
29    pub reserved0: [u8; 8],
30    pub global_allowed_borrow_value: u64,
31    pub emergency_council: Pubkey,
32    pub reserved1: [u8; 8],
33    pub elevation_groups: [ElevationGroup; 32],
34    pub elevation_group_padding: [u64; 90],
35    /// Min net value in obligation (scaled fraction).
36    pub min_net_value_in_obligation_sf: PodU128,
37    pub min_value_skip_liquidation_ltv_checks: u64,
38    pub name: [u8; 32],
39    pub min_value_skip_liquidation_bf_checks: u64,
40    pub individual_autodeleverage_margin_call_period_secs: u64,
41    pub min_initial_deposit_amount: u64,
42    pub obligation_order_execution_enabled: u8,
43    pub immutable: u8,
44    pub obligation_order_creation_enabled: u8,
45    pub price_triggered_liquidation_disabled: u8,
46    pub mature_reserve_debt_liquidation_enabled: u8,
47    pub obligation_borrow_debt_term_liquidation_enabled: u8,
48    pub borrow_order_creation_enabled: u8,
49    pub borrow_order_execution_enabled: u8,
50    pub proposer_authority: Pubkey,
51    pub min_borrow_order_fill_value: u64,
52    pub withdraw_ticket_issuance_enabled: u8,
53    pub withdraw_ticket_redemption_enabled: u8,
54    pub obligation_borrow_rollover_configuration_enabled: u8,
55    pub obligation_borrow_migration_to_fixed_execution_enabled: u8,
56    pub withdraw_ticket_cancellation_enabled: u8,
57    pub padding2: [u8; 3],
58    pub min_withdraw_queued_liquidity_value: u64,
59    pub fixed_term_rollover_window_duration_seconds: u64,
60    pub open_term_rollover_window_duration_seconds: u64,
61    pub min_partial_rollover_value: u64,
62    pub term_based_full_liquidation_duration_secs: u64,
63    pub padding1: [u64; 158],
64}
65
66const _: () = assert!(core::mem::size_of::<LendingMarket>() == 4656);
67
68impl LendingMarket {
69    /// Whether the market is in emergency mode.
70    pub fn is_emergency_mode(&self) -> bool {
71        self.emergency_mode != 0
72    }
73
74    /// Whether borrowing is globally disabled.
75    pub fn is_borrow_disabled(&self) -> bool {
76        self.borrow_disabled != 0
77    }
78
79    /// Whether autodeleverage is enabled.
80    pub fn is_autodeleverage_enabled(&self) -> bool {
81        self.autodeleverage_enabled != 0
82    }
83
84    /// Max percentage of debt that can be closed in a single liquidation.
85    pub fn liquidation_max_debt_close_factor_pct(&self) -> u8 {
86        self.liquidation_max_debt_close_factor_pct
87    }
88
89    /// Minimum value threshold for full liquidation.
90    pub fn min_full_liquidation_value_threshold(&self) -> u64 {
91        self.min_full_liquidation_value_threshold
92    }
93
94    /// Maximum liquidatable debt market value at once.
95    pub fn max_liquidatable_debt_market_value_at_once(&self) -> u64 {
96        self.max_liquidatable_debt_market_value_at_once
97    }
98
99    /// Referral fee in basis points.
100    pub fn referral_fee_bps(&self) -> u16 {
101        self.referral_fee_bps
102    }
103
104    /// Get an elevation group by index (0-31). Returns `None` if out of bounds.
105    pub fn elevation_group(&self, index: usize) -> Option<&ElevationGroup> {
106        self.elevation_groups.get(index)
107    }
108
109    /// Whether the market is immutable (no more config changes).
110    pub fn is_immutable(&self) -> bool {
111        self.immutable != 0
112    }
113
114    /// Whether withdraw ticket cancellation is enabled.
115    pub fn is_withdraw_ticket_cancellation_enabled(&self) -> bool {
116        self.withdraw_ticket_cancellation_enabled != 0
117    }
118
119    /// Whether migration-to-fixed rollover execution is enabled.
120    pub fn is_obligation_borrow_migration_to_fixed_execution_enabled(&self) -> bool {
121        self.obligation_borrow_migration_to_fixed_execution_enabled != 0
122    }
123}
124
125// ---------------------------------------------------------------------------
126// ElevationGroup
127// ---------------------------------------------------------------------------
128
129#[derive(Debug, Clone, Copy, Zeroable, Pod)]
130#[repr(C)]
131pub struct ElevationGroup {
132    pub max_liquidation_bonus_bps: u16,
133    pub id: u8,
134    pub ltv_pct: u8,
135    pub liquidation_threshold_pct: u8,
136    pub allow_new_loans: u8,
137    pub max_reserves_as_collateral: u8,
138    pub padding_0: u8,
139    pub debt_reserve: Pubkey,
140    pub padding_1: [u64; 4],
141}