Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions common/src/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ pub mod error {
pub struct LiquidationLockError;
}

pub struct LinkedBorrowPosition<M> {
pub struct BorrowPositionRef<M> {
market: M,
account_id: AccountId,
position: BorrowPosition,
}

impl<M> LinkedBorrowPosition<M> {
impl<M> BorrowPositionRef<M> {
pub fn new(market: M, account_id: AccountId, position: BorrowPosition) -> Self {
Self {
market,
Expand All @@ -200,7 +200,7 @@ impl<M> LinkedBorrowPosition<M> {
}
}

impl<M: Deref<Target = Market>> LinkedBorrowPosition<M> {
impl<M: Deref<Target = Market>> BorrowPositionRef<M> {
pub fn with_pending_interest(&mut self) {
self.position.borrow_asset_fees.pending_estimate =
self.calculate_interest(u32::MAX).get_amount();
Expand Down Expand Up @@ -321,9 +321,9 @@ impl<M: Deref<Target = Market>> LinkedBorrowPosition<M> {
}
}

pub struct LinkedBorrowPositionMut<'a>(LinkedBorrowPosition<&'a mut Market>);
pub struct BorrowPositionGuard<'a>(BorrowPositionRef<&'a mut Market>);

impl Drop for LinkedBorrowPositionMut<'_> {
impl Drop for BorrowPositionGuard<'_> {
fn drop(&mut self) {
self.0
.market
Expand All @@ -332,23 +332,23 @@ impl Drop for LinkedBorrowPositionMut<'_> {
}
}

impl<'a> Deref for LinkedBorrowPositionMut<'a> {
type Target = LinkedBorrowPosition<&'a mut Market>;
impl<'a> Deref for BorrowPositionGuard<'a> {
type Target = BorrowPositionRef<&'a mut Market>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for LinkedBorrowPositionMut<'_> {
impl DerefMut for BorrowPositionGuard<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl<'a> LinkedBorrowPositionMut<'a> {
impl<'a> BorrowPositionGuard<'a> {
pub fn new(market: &'a mut Market, account_id: AccountId, position: BorrowPosition) -> Self {
Self(LinkedBorrowPosition::new(market, account_id, position))
Self(BorrowPositionRef::new(market, account_id, position))
}

pub fn record_collateral_asset_deposit(&mut self, amount: CollateralAssetAmount) {
Expand Down
66 changes: 27 additions & 39 deletions common/src/market/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ use near_sdk::{

use crate::{
asset::BorrowAssetAmount,
borrow::{BorrowPosition, LinkedBorrowPosition, LinkedBorrowPositionMut},
borrow::{BorrowPosition, BorrowPositionGuard, BorrowPositionRef},
chunked_append_only_list::ChunkedAppendOnlyList,
event::MarketEvent,
market::MarketConfiguration,
number::Decimal,
snapshot::Snapshot,
static_yield::StaticYieldRecord,
supply::{LinkedSupplyPosition, LinkedSupplyPositionMut, SupplyPosition},
supply::{SupplyPosition, SupplyPositionGuard, SupplyPositionRef},
withdrawal_queue::{error::WithdrawalQueueLockError, WithdrawalQueue},
};

Expand Down Expand Up @@ -162,68 +162,56 @@ impl Market {
self.supply_positions.keys()
}

pub fn get_linked_supply_position(
&self,
account_id: AccountId,
) -> Option<LinkedSupplyPosition<&Self>> {
pub fn supply_position_ref(&self, account_id: AccountId) -> Option<SupplyPositionRef<&Self>> {
self.supply_positions
.get(&account_id)
.map(|position| LinkedSupplyPosition::new(self, account_id, position))
.map(|position| SupplyPositionRef::new(self, account_id, position))
}

pub fn get_linked_supply_position_mut(
&mut self,
account_id: AccountId,
) -> Option<LinkedSupplyPositionMut> {
pub fn supply_position_guard(&mut self, account_id: AccountId) -> Option<SupplyPositionGuard> {
self.supply_positions
.get(&account_id)
.map(|position| LinkedSupplyPositionMut::new(self, account_id, position))
.map(|position| SupplyPositionGuard::new(self, account_id, position))
}

pub fn get_or_create_linked_supply_position_mut(
pub fn get_or_create_supply_position_guard(
&mut self,
account_id: AccountId,
) -> LinkedSupplyPositionMut {
) -> SupplyPositionGuard {
let position = self
.supply_positions
.get(&account_id)
.unwrap_or_else(|| SupplyPosition::new(self.snapshot()));

LinkedSupplyPositionMut::new(self, account_id, position)
SupplyPositionGuard::new(self, account_id, position)
}

pub fn iter_borrow_account_ids(&self) -> impl Iterator<Item = AccountId> + '_ {
self.borrow_positions.keys()
}

pub fn get_linked_borrow_position(
&self,
account_id: AccountId,
) -> Option<LinkedBorrowPosition<&Self>> {
pub fn borrow_position_ref(&self, account_id: AccountId) -> Option<BorrowPositionRef<&Self>> {
self.borrow_positions
.get(&account_id)
.map(|position| LinkedBorrowPosition::new(self, account_id, position))
.map(|position| BorrowPositionRef::new(self, account_id, position))
}

pub fn get_linked_borrow_position_mut(
&mut self,
account_id: AccountId,
) -> Option<LinkedBorrowPositionMut> {
pub fn borrow_position_guard(&mut self, account_id: AccountId) -> Option<BorrowPositionGuard> {
self.borrow_positions
.get(&account_id)
.map(|position| LinkedBorrowPositionMut::new(self, account_id, position))
.map(|position| BorrowPositionGuard::new(self, account_id, position))
}

pub fn get_or_create_linked_borrow_position_mut(
pub fn get_or_create_borrow_position_guard(
&mut self,
account_id: AccountId,
) -> LinkedBorrowPositionMut {
) -> BorrowPositionGuard {
let position = self
.borrow_positions
.get(&account_id)
.unwrap_or_else(|| BorrowPosition::new(self.snapshot()));

LinkedBorrowPositionMut::new(self, account_id, position)
BorrowPositionGuard::new(self, account_id, position)
}

/// # Errors
Expand All @@ -234,17 +222,17 @@ impl Market {
) -> Result<Option<WithdrawalResolution>, WithdrawalQueueLockError> {
let (account_id, requested_amount) = self.withdrawal_queue.try_lock()?;

let Some((amount, mut supply_position)) = self
.get_linked_supply_position_mut(account_id)
.and_then(|supply_position| {
// Cap withdrawal amount to deposit amount at most.
let amount = supply_position
.inner()
.get_borrow_asset_deposit()
.min(requested_amount);

(!amount.is_zero()).then_some((amount, supply_position))
})
let Some((amount, mut supply_position)) =
self.supply_position_guard(account_id)
.and_then(|supply_position| {
// Cap withdrawal amount to deposit amount at most.
let amount = supply_position
.inner()
.get_borrow_asset_deposit()
.min(requested_amount);

(!amount.is_zero()).then_some((amount, supply_position))
})
else {
// The amount that the entry is eligible to withdraw is zero, so skip it.
self.withdrawal_queue
Expand Down
20 changes: 10 additions & 10 deletions common/src/supply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,13 @@ impl SupplyPosition {
}
}

pub struct LinkedSupplyPosition<M> {
pub struct SupplyPositionRef<M> {
market: M,
account_id: AccountId,
position: SupplyPosition,
}

impl<M> LinkedSupplyPosition<M> {
impl<M> SupplyPositionRef<M> {
pub fn new(market: M, account_id: AccountId, position: SupplyPosition) -> Self {
Self {
market,
Expand All @@ -96,7 +96,7 @@ impl<M> LinkedSupplyPosition<M> {
}
}

impl<M: Deref<Target = Market>> LinkedSupplyPosition<M> {
impl<M: Deref<Target = Market>> SupplyPositionRef<M> {
pub fn with_pending_yield_estimate(&mut self) {
self.position.borrow_asset_yield.pending_estimate = self.calculate_yield().get_amount();
self.position
Expand Down Expand Up @@ -170,9 +170,9 @@ impl<M: Deref<Target = Market>> LinkedSupplyPosition<M> {
}
}

pub struct LinkedSupplyPositionMut<'a>(LinkedSupplyPosition<&'a mut Market>);
pub struct SupplyPositionGuard<'a>(SupplyPositionRef<&'a mut Market>);

impl Drop for LinkedSupplyPositionMut<'_> {
impl Drop for SupplyPositionGuard<'_> {
fn drop(&mut self) {
self.0
.market
Expand All @@ -181,23 +181,23 @@ impl Drop for LinkedSupplyPositionMut<'_> {
}
}

impl<'a> Deref for LinkedSupplyPositionMut<'a> {
type Target = LinkedSupplyPosition<&'a mut Market>;
impl<'a> Deref for SupplyPositionGuard<'a> {
type Target = SupplyPositionRef<&'a mut Market>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for LinkedSupplyPositionMut<'_> {
impl DerefMut for SupplyPositionGuard<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl<'a> LinkedSupplyPositionMut<'a> {
impl<'a> SupplyPositionGuard<'a> {
pub fn new(market: &'a mut Market, account_id: AccountId, position: SupplyPosition) -> Self {
Self(LinkedSupplyPosition::new(market, account_id, position))
Self(SupplyPositionRef::new(market, account_id, position))
}

pub fn accumulate_yield(&mut self) -> YieldAccumulationProof {
Expand Down
28 changes: 12 additions & 16 deletions contract/market/src/impl_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{Contract, ContractExt};
impl Contract {
pub fn execute_supply(&mut self, account_id: AccountId, amount: BorrowAssetAmount) {
let supply_maximum_amount = self.configuration.supply_maximum_amount;
let mut supply_position = self.get_or_create_linked_supply_position_mut(account_id);
let mut supply_position = self.get_or_create_supply_position_guard(account_id);
let proof = supply_position.accumulate_yield();
supply_position.record_deposit(proof, amount, env::block_timestamp_ms());
if let Some(ref supply_maximum_amount) = supply_maximum_amount {
Expand All @@ -33,7 +33,7 @@ impl Contract {
// The sign-up step would only be NFT gating or something of
// that sort, which is just an additional pre condition check.
// -- https://github.com/Templar-Protocol/contract-mvp/pull/6#discussion_r1923871982
let mut borrow_position = self.get_or_create_linked_borrow_position_mut(account_id);
let mut borrow_position = self.get_or_create_borrow_position_guard(account_id);
borrow_position.record_collateral_asset_deposit(amount);
}

Expand All @@ -43,7 +43,7 @@ impl Contract {
account_id: AccountId,
amount: BorrowAssetAmount,
) -> BorrowAssetAmount {
if let Some(mut borrow_position) = self.get_linked_borrow_position_mut(account_id) {
if let Some(mut borrow_position) = self.borrow_position_guard(account_id) {
let proof = borrow_position.accumulate_interest();
// Returns the amount that should be returned to the borrower.
borrow_position.record_repay(proof, amount)
Expand All @@ -59,7 +59,7 @@ impl Contract {
amount: BorrowAssetAmount,
price_pair: &PricePair,
) -> CollateralAssetAmount {
let mut borrow_position = self.get_or_create_linked_borrow_position_mut(account_id);
let mut borrow_position = self.get_or_create_borrow_position_guard(account_id);

require!(
borrow_position.can_be_liquidated(price_pair, env::block_timestamp_ms()),
Expand Down Expand Up @@ -88,11 +88,9 @@ impl Contract {
amount: BorrowAssetAmount,
success: bool,
) -> BorrowAssetAmount {
let mut borrow_position = self
.get_linked_borrow_position_mut(account_id)
.unwrap_or_else(|| {
env::panic_str("Invariant violation: Liquidation of nonexistent position.")
});
let mut borrow_position = self.borrow_position_guard(account_id).unwrap_or_else(|| {
env::panic_str("Invariant violation: Liquidation of nonexistent position.")
});

if success {
borrow_position.record_full_liquidation(liquidator_id, amount);
Expand Down Expand Up @@ -145,8 +143,7 @@ impl Contract {
.of(amount)
.unwrap_or_else(|| env::panic_str("Fee calculation failed"));

let Some(mut borrow_position) = self.get_linked_borrow_position_mut(account_id.clone())
else {
let Some(mut borrow_position) = self.borrow_position_guard(account_id.clone()) else {
env::panic_str("No borrower record. Please deposit collateral first.");
};

Expand Down Expand Up @@ -179,7 +176,7 @@ impl Contract {
) {
require!(env::promise_results_count() == 1);

let Some(mut borrow_position) = self.get_linked_borrow_position_mut(account_id) else {
let Some(mut borrow_position) = self.borrow_position_guard(account_id) else {
env::panic_str("Invariant violation: borrow position does not exist after transfer.");
};

Expand Down Expand Up @@ -260,7 +257,7 @@ impl Contract {
env::log_str("The withdrawal request cannot be fulfilled at this time. Please try again later.");
self.withdrawal_queue.unlock();
if let Some(mut supply_position) =
self.get_linked_supply_position_mut(withdrawal_resolution.account_id.clone())
self.supply_position_guard(withdrawal_resolution.account_id.clone())
{
let proof = supply_position.accumulate_yield();
let mut amount = withdrawal_resolution.amount_to_account;
Expand Down Expand Up @@ -330,8 +327,7 @@ impl Contract {
.create_price_pair(&oracle_response)
.unwrap_or_else(|e| env::panic_str(&e.to_string()));

let Some(mut borrow_position) = self.get_linked_borrow_position_mut(account_id.clone())
else {
let Some(mut borrow_position) = self.borrow_position_guard(account_id.clone()) else {
env::panic_str("No borrower record. Please deposit collateral first.");
};

Expand Down Expand Up @@ -363,7 +359,7 @@ impl Contract {
if transfer_was_successful {
// Do nothing
} else {
let Some(mut borrow_position) = self.get_linked_borrow_position_mut(account_id) else {
let Some(mut borrow_position) = self.borrow_position_guard(account_id) else {
env::panic_str("Invariant violation: Borrow position must exist after collateral withdrawal failure.");
};

Expand Down
Loading