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
27 changes: 2 additions & 25 deletions common/src/asset.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{fmt::Display, marker::PhantomData};

use near_contract_standards::fungible_token::core::ext_ft_core;
use near_sdk::{env, ext_contract, json_types::U128, near, AccountId, NearToken, Promise};
use near_sdk::{env, json_types::U128, near, AccountId, NearToken, Promise};

use crate::number::Decimal;

Expand All @@ -17,41 +17,27 @@ pub struct FungibleAsset<T: AssetClass> {

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[near(serializers = [json, borsh])]
#[non_exhaustive]
enum FungibleAssetKind {
Native,
Nep141(AccountId),
}

impl<T: AssetClass> FungibleAsset<T> {
pub fn transfer(&self, receiver_id: AccountId, amount: FungibleAssetAmount<T>) -> Promise {
match self.kind {
FungibleAssetKind::Native => {
Promise::new(receiver_id).transfer(NearToken::from_yoctonear(amount.to_u128()))
}
FungibleAssetKind::Nep141(ref contract_id) => ext_ft_core::ext(contract_id.clone())
.with_attached_deposit(NearToken::from_yoctonear(1))
.ft_transfer(receiver_id, amount.to_u128().into(), None),
}
}

pub fn native() -> Self {
Self {
discriminant: PhantomData,
kind: FungibleAssetKind::Native,
}
}

pub fn nep141(contract_id: AccountId) -> Self {
Self {
discriminant: PhantomData,
kind: FungibleAssetKind::Nep141(contract_id),
}
}

pub fn is_native(&self) -> bool {
matches!(self.kind, FungibleAssetKind::Native)
}

pub fn is_nep141(&self, account_id: &AccountId) -> bool {
if let FungibleAssetKind::Nep141(ref contract_id) = self.kind {
contract_id == account_id
Expand All @@ -71,28 +57,19 @@ impl<T: AssetClass> FungibleAsset<T> {
pub fn current_account_balance(&self) -> Promise {
let current_account_id = env::current_account_id();
match self.kind {
FungibleAssetKind::Native => {
ext_return_native_balance::ext(current_account_id).return_native_balance()
}
FungibleAssetKind::Nep141(ref account_id) => {
ext_ft_core::ext(account_id.clone()).ft_balance_of(current_account_id.clone())
}
}
}
}

#[ext_contract(ext_return_native_balance)]
pub trait ReturnNativeBalance {
fn return_native_balance(&self) -> U128;
}

impl<T: AssetClass> Display for FungibleAsset<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self.kind {
FungibleAssetKind::Native => "[native NEAR]",
FungibleAssetKind::Nep141(ref contract_id) => contract_id.as_str(),
}
)
Expand Down
4 changes: 0 additions & 4 deletions common/src/market/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ pub trait MarketExternalInterface {
// ==================

// ft_on_receive :: where msg = Collateralize
fn collateralize_native(&mut self);
// ft_on_receive :: where msg = Repay
fn repay_native(&mut self) -> PromiseOrValue<()>;

/// This function may report fees slightly inaccurately. This is because
/// the function has to estimate what fees will be applied between the last
Expand Down Expand Up @@ -76,7 +74,6 @@ pub trait MarketExternalInterface {
// don't yet support supplying of remote assets.

// ft_on_receive :: where msg = Supply
fn supply_native(&mut self);

fn get_supply_position(&self, account_id: AccountId) -> Option<SupplyPosition>;

Expand Down Expand Up @@ -106,7 +103,6 @@ pub trait MarketExternalInterface {
// =====================

// ft_on_receive :: where msg = Liquidate { account_id }
fn liquidate_native(&mut self, account_id: AccountId) -> Promise;

// =================
// YIELD FUNCTIONS
Expand Down
58 changes: 0 additions & 58 deletions contract/market/src/impl_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,64 +330,6 @@ impl Contract {
refund_to_liquidator.into()
}

#[private]
pub fn liquidate_native_01_consume_price(
&mut self,
liquidator_id: AccountId,
account_id: AccountId,
amount: BorrowAssetAmount,
#[callback_unwrap] oracle_response: OracleResponse,
) -> Promise {
let price_pair = self
.configuration
.balance_oracle
.create_price_pair(&oracle_response)
.unwrap_or_else(|e| env::panic_str(&e.to_string()));

let liquidated_collateral =
self.execute_liquidate_initial(account_id.clone(), amount, &price_pair);

self.configuration
.collateral_asset
.transfer(liquidator_id.clone(), liquidated_collateral)
.then(
Self::ext(env::current_account_id()).liquidate_native_02_finalize(
liquidator_id,
account_id,
amount,
),
)
}

#[private]
pub fn liquidate_native_02_finalize(
&mut self,
liquidator_id: AccountId,
account_id: AccountId,
borrow_asset_amount: BorrowAssetAmount,
) -> PromiseOrValue<()> {
require!(env::promise_results_count() == 1);

let success = matches!(env::promise_result(0), PromiseResult::Successful(_));

let refund_to_liquidator = self.execute_liquidate_final(
liquidator_id.clone(),
account_id,
borrow_asset_amount,
success,
);

if refund_to_liquidator.is_zero() {
PromiseOrValue::Value(())
} else {
PromiseOrValue::Promise(
self.configuration
.borrow_asset
.transfer(liquidator_id, refund_to_liquidator),
)
}
}

#[private]
pub fn withdraw_collateral_01_consume_price(
&mut self,
Expand Down
77 changes: 0 additions & 77 deletions contract/market/src/impl_market_external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -341,81 +341,4 @@ impl MarketExternalInterface for Contract {
_ => env::panic_str("No yield to withdraw"),
} // TODO: Check for success
}

#[payable]
fn supply_native(&mut self) {
require!(
self.configuration.borrow_asset.is_native(),
"Unsupported borrow asset",
);

let amount = BorrowAssetAmount::from(env::attached_deposit().as_yoctonear());

require!(!amount.is_zero(), "Deposit must be nonzero");

self.execute_supply(env::predecessor_account_id(), amount);
}

#[payable]
fn collateralize_native(&mut self) {
require!(
self.configuration.collateral_asset.is_native(),
"Unsupported collateral asset",
);

let amount = CollateralAssetAmount::from(env::attached_deposit().as_yoctonear());

require!(!amount.is_zero(), "Deposit must be nonzero");

self.execute_collateralize(env::predecessor_account_id(), amount);
}

#[payable]
fn repay_native(&mut self) -> PromiseOrValue<()> {
require!(
self.configuration.borrow_asset.is_native(),
"Unsupported borrow asset",
);

let amount = BorrowAssetAmount::from(env::attached_deposit().as_yoctonear());

require!(!amount.is_zero(), "Deposit must be nonzero");

let predecessor = env::predecessor_account_id();

let refund = self.execute_repay(predecessor.clone(), amount);

if refund.is_zero() {
PromiseOrValue::Value(())
} else {
PromiseOrValue::Promise(
self.configuration
.borrow_asset
.transfer(predecessor, amount),
)
}
}

#[payable]
fn liquidate_native(&mut self, account_id: AccountId) -> Promise {
require!(
self.configuration.borrow_asset.is_native(),
"Unsupported borrow asset",
);

let amount = BorrowAssetAmount::from(env::attached_deposit().as_yoctonear());

require!(!amount.is_zero(), "Deposit must be nonzero");

self.configuration
.balance_oracle
.retrieve_price_pair()
.then(
Self::ext(env::current_account_id()).liquidate_native_01_consume_price(
env::predecessor_account_id(),
account_id,
amount,
),
)
}
}
14 changes: 2 additions & 12 deletions contract/market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@

use std::ops::{Deref, DerefMut};

use near_sdk::{env, json_types::U128, near, BorshStorageKey, PanicOnDefault};
use templar_common::{
asset::ReturnNativeBalance,
market::{Market, MarketConfiguration},
};
use near_sdk::{near, BorshStorageKey, PanicOnDefault};
use templar_common::market::{Market, MarketConfiguration};

#[derive(BorshStorageKey)]
#[near(serializers = [borsh])]
Expand Down Expand Up @@ -44,13 +41,6 @@ impl DerefMut for Contract {
}
}

#[near]
impl ReturnNativeBalance for Contract {
fn return_native_balance(&self) -> U128 {
U128(env::account_balance().as_yoctonear())
}
}

mod impl_ft_receiver;
mod impl_helper;
mod impl_market_external;
Expand Down
60 changes: 10 additions & 50 deletions contract/market/tests/happy_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,14 @@ use rstest::rstest;
use tokio::join;

use templar_common::{
asset::FungibleAsset, borrow::BorrowStatus, dec, interest_rate_strategy::InterestRateStrategy,
number::Decimal,
borrow::BorrowStatus, dec, interest_rate_strategy::InterestRateStrategy, number::Decimal,
};
use test_utils::*;

#[allow(dead_code)]
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
enum NativeAssetCase {
Neither,
BorrowAsset,
CollateralAsset,
}

#[rstest]
#[case(NativeAssetCase::Neither)]
// TODO: Figure out gas accounting for native asset borrows.
// #[case(NativeAssetCase::BorrowAsset)]
// #[case(NativeAssetCase::CollateralAsset)]
#[allow(clippy::too_many_lines)]
#[tokio::test]
async fn test_happy(#[case] native_asset_case: NativeAssetCase) {
async fn test_happy() {
let SetupEverything {
c,
supply_user,
Expand All @@ -31,48 +18,21 @@ async fn test_happy(#[case] native_asset_case: NativeAssetCase) {
insurance_yield_user,
..
} = setup_everything(|c| {
match native_asset_case {
NativeAssetCase::Neither => {}
NativeAssetCase::BorrowAsset => {
c.borrow_asset = FungibleAsset::native();
}
NativeAssetCase::CollateralAsset => {
c.collateral_asset = FungibleAsset::native();
}
}
c.borrow_interest_rate_strategy =
InterestRateStrategy::linear(Decimal::ZERO, Decimal::ZERO).unwrap();
})
.await;

let configuration = c.get_configuration().await;

match native_asset_case {
NativeAssetCase::Neither => {
assert_eq!(
&configuration.collateral_asset.into_nep141().unwrap(),
c.collateral_asset.nep141_id().unwrap(),
);
assert_eq!(
&configuration.borrow_asset.into_nep141().unwrap(),
c.borrow_asset.nep141_id().unwrap(),
);
}
NativeAssetCase::BorrowAsset => {
assert_eq!(
&configuration.collateral_asset.into_nep141().unwrap(),
c.collateral_asset.nep141_id().unwrap(),
);
assert!(&configuration.borrow_asset.is_native());
}
NativeAssetCase::CollateralAsset => {
assert!(&configuration.collateral_asset.is_native());
assert_eq!(
&configuration.borrow_asset.into_nep141().unwrap(),
c.borrow_asset.nep141_id().unwrap(),
);
}
}
assert_eq!(
&configuration.collateral_asset.into_nep141().unwrap(),
c.collateral_asset.id(),
);
assert_eq!(
&configuration.borrow_asset.into_nep141().unwrap(),
c.borrow_asset.id(),
);

assert!(configuration.borrow_mcr.near_equal(dec!("1.2")));

Expand Down
Loading
Loading