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}