templar_common/market/
external.rs

1use std::collections::HashMap;
2
3use near_sdk::{near, AccountId, Promise, PromiseOrValue};
4
5use crate::{
6    accumulator::Accumulator,
7    asset::{BorrowAsset, BorrowAssetAmount, CollateralAssetAmount},
8    borrow::{BorrowPosition, BorrowStatus},
9    number::Decimal,
10    oracle::pyth::OracleResponse,
11    snapshot::Snapshot,
12    supply::SupplyPosition,
13    withdrawal_queue::{
14        WithdrawalQueueExecutionResult, WithdrawalQueueStatus, WithdrawalRequestStatus,
15    },
16};
17
18use super::{BorrowAssetMetrics, MarketConfiguration};
19
20#[derive(Debug, Clone, Copy, Default)]
21#[near(serializers = [json, borsh])]
22pub enum HarvestYieldMode {
23    #[default]
24    Default,
25    SnapshotLimit(u32),
26}
27
28#[near_sdk::ext_contract(ext_market)]
29pub trait MarketExternalInterface {
30    // ========================
31    // MARKET GENERAL FUNCTIONS
32    // ========================
33
34    /// Retrieve the market configuration.
35    fn get_configuration(&self) -> MarketConfiguration;
36
37    /// Retrieve the current snapshot (in progress; not yet finalized).
38    fn get_current_snapshot(&self) -> Snapshot;
39
40    /// Retrieve the count of finalized snapshots.
41    fn get_finalized_snapshots_len(&self) -> u32;
42
43    /// Retrieve a list of finalized snapshots.
44    fn list_finalized_snapshots(&self, offset: Option<u32>, count: Option<u32>) -> Vec<&Snapshot>;
45
46    /// Retrieve current contract metrics about borrow asset deposit,
47    /// availability, usage, etc.
48    fn get_borrow_asset_metrics(&self) -> BorrowAssetMetrics;
49
50    // ==================
51    // BORROW FUNCTIONS
52    // ==================
53
54    // *_on_transfer where msg = Collateralize
55    // *_on_transfer where msg = Repay
56
57    /// Retrieve a map of borrow positions.
58    fn list_borrow_positions(
59        &self,
60        offset: Option<u32>,
61        count: Option<u32>,
62    ) -> HashMap<AccountId, BorrowPosition>;
63
64    /// Retrieve a specific borrow position, with estimated fees.
65    ///
66    /// This function may report fees slightly inaccurately. This is because
67    /// the function has to estimate what fees will be applied between the last
68    /// finalized market snapshot and the (present) time when the function was
69    /// called.
70    fn get_borrow_position(&self, account_id: AccountId) -> Option<BorrowPosition>;
71
72    /// Estimate the pending interest on the borrow position, that is, the
73    /// amount of interest that would accrue on the record if an accumulation
74    /// were to be run.
75    ///
76    /// - `snapshot_limit` allows the caller to limit the number of snapshots
77    ///     that will be included in the calculation. Useful to limit gas
78    ///     consumption. Default `u32::MAX`.
79    fn get_borrow_position_pending_interest(
80        &self,
81        account_id: AccountId,
82        snapshot_limit: Option<u32>,
83    ) -> Option<BorrowAssetAmount>;
84
85    /// Retrieves the status of a borrow position (healthy or in liquidation)
86    /// given some asset prices.
87    ///
88    /// This is just a read-only function, so it does not validate the price
89    /// data. It is intended to be called by liquidators so they can easily see
90    /// whether a position is eligible for liquidation.
91    fn get_borrow_status(
92        &self,
93        account_id: AccountId,
94        oracle_response: OracleResponse,
95    ) -> Option<BorrowStatus>;
96
97    /// Transfers `amount` of borrow asset tokens to the caller, provided
98    /// their borrow position will still be sufficiently collateralized.
99    fn borrow(&mut self, amount: BorrowAssetAmount) -> Promise;
100
101    /// Transfers `amount` of collateral asset tokens to the caller, provided
102    /// their borrow position will still be sufficiently collateralized.
103    fn withdraw_collateral(&mut self, amount: CollateralAssetAmount) -> Promise;
104
105    /// Applies interest to the predecessor's borrow record.
106    /// Not likely to be used in real life, since there it does not affect the
107    /// final interest calculation, and rounds fractional interest UP.
108    fn apply_interest(&mut self, account_id: Option<AccountId>, snapshot_limit: Option<u32>);
109
110    // ================
111    // SUPPLY FUNCTIONS
112    // ================
113
114    // *_on_transfer where msg = Supply
115
116    /// Retrieves a set of supply positions.
117    fn list_supply_positions(
118        &self,
119        offset: Option<u32>,
120        count: Option<u32>,
121    ) -> HashMap<AccountId, SupplyPosition>;
122
123    /// Retrieves a supply position record, with estimated yield.
124    ///
125    /// If `pending_yield_snapshot_limit` is not set, it defaults to unlimited,
126    /// which may consume a lot of gas in transactions.
127    fn get_supply_position(&self, account_id: AccountId) -> Option<SupplyPosition>;
128
129    fn get_supply_position_pending_yield(
130        &self,
131        account_id: AccountId,
132        snapshot_limit: Option<u32>,
133    ) -> Option<BorrowAssetAmount>;
134
135    /// Enters a supply position into the withdrawal queue, requesting to
136    /// withdraw `amount` borrow asset tokens.
137    ///
138    /// If the account is already in the queue, it will be moved to the back
139    /// of the queue with the updated amount.
140    fn create_supply_withdrawal_request(&mut self, amount: BorrowAssetAmount);
141
142    /// Removes a supply position from the withdrawal queue.
143    fn cancel_supply_withdrawal_request(&mut self);
144
145    /// Attempts to fulfill the first withdrawal request in the queue.
146    fn execute_next_supply_withdrawal_request(
147        &mut self,
148        batch_limit: Option<u32>,
149    ) -> PromiseOrValue<WithdrawalQueueExecutionResult>;
150
151    /// Retrieves the status of a withdrawal request in the queue.
152    fn get_supply_withdrawal_request_status(
153        &self,
154        account_id: AccountId,
155    ) -> Option<WithdrawalRequestStatus>;
156
157    /// Retrieves the status of the withdrawal queue.
158    fn get_supply_withdrawal_queue_status(&self) -> WithdrawalQueueStatus;
159
160    /// Claim any distributed yield to the supply record.
161    fn harvest_yield(
162        &mut self,
163        account_id: Option<AccountId>,
164        mode: Option<HarvestYieldMode>,
165    ) -> BorrowAssetAmount;
166
167    /// This value is an *expected average over time*.
168    /// Supply positions actually earn all of their yield the instant it is
169    /// distributed.
170    fn get_last_yield_rate(&self) -> Decimal;
171
172    // =====================
173    // LIQUIDATION FUNCTIONS
174    // =====================
175
176    // *_on_transfer where msg = Liquidate { account_id }
177
178    // =================
179    // YIELD FUNCTIONS
180    // =================
181
182    /// Retrieves the amount of yield earned by an account statically
183    /// configured to earn yield (e.g. [`MarketConfiguration::yield_weights`]
184    /// or [`MarketConfiguration::protocol_account_id`]).
185    fn get_static_yield(&self, account_id: AccountId) -> Option<Accumulator<BorrowAsset>>;
186
187    /// Accumulates yield for an account that earns static yield.
188    fn accumulate_static_yield(
189        &mut self,
190        account_id: Option<AccountId>,
191        snapshot_limit: Option<u32>,
192    );
193
194    /// Attempts to withdraw the amount of yield earned by an account
195    /// statically configured to earn yield (e.g.
196    /// [`MarketConfiguration::yield_weights`] or
197    /// [`MarketConfiguration::protocol_account_id`]).
198    ///
199    /// Calls to this function should be preceded by calls to
200    /// [`MarketExternalInterface::accumulate_static_yield`].
201    fn withdraw_static_yield(&mut self, amount: Option<BorrowAssetAmount>) -> Promise;
202}