Skip to content

Commit

Permalink
Merge pull request #1309 from bifrost-finance/market-bond
Browse files Browse the repository at this point in the history
Market bond
  • Loading branch information
SunTiebing authored Jul 19, 2024
2 parents 5307f58 + ae7b059 commit 9ba9adf
Show file tree
Hide file tree
Showing 9 changed files with 933 additions and 8 deletions.
15 changes: 15 additions & 0 deletions pallets/lend-market/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,11 @@ benchmarks! {
transfer_initial_balance::<T>(caller.clone());
let deposit_amount: u32 = 200_000_000;
let borrowed_amount: u32 = 100_000_000;
assert_ok!(LendMarket::<T>::add_market_bond(
SystemOrigin::Root.into(),
DOT_U,
vec![DOT_U]
));
assert_ok!(LendMarket::<T>::add_market(SystemOrigin::Root.into(), DOT_U, pending_market_mock::<T>(LUSDT)));
assert_ok!(LendMarket::<T>::activate_market(SystemOrigin::Root.into(), DOT_U));
assert_ok!(LendMarket::<T>::mint(SystemOrigin::Signed(caller.clone()).into(), DOT_U, deposit_amount.into()));
Expand Down Expand Up @@ -267,6 +272,11 @@ benchmarks! {
let deposit_amount: u32 = 200_000_000;
let borrowed_amount: u32 = 100_000_000;
let repay_amount: u32 = 100;
assert_ok!(LendMarket::<T>::add_market_bond(
SystemOrigin::Root.into(),
DOT_U,
vec![DOT_U]
));
assert_ok!(LendMarket::<T>::add_market(SystemOrigin::Root.into(), DOT_U, pending_market_mock::<T>(LUSDT)));
assert_ok!(LendMarket::<T>::activate_market(SystemOrigin::Root.into(), DOT_U));
assert_ok!(LendMarket::<T>::mint(SystemOrigin::Signed(caller.clone()).into(), DOT_U, deposit_amount.into()));
Expand All @@ -283,6 +293,11 @@ benchmarks! {
let deposit_amount: u32 = 200_000_000;
let borrowed_amount: u32 = 100_000_000;
assert_ok!(LendMarket::<T>::add_market(SystemOrigin::Root.into(), DOT_U, pending_market_mock::<T>(LUSDT)));
assert_ok!(LendMarket::<T>::add_market_bond(
SystemOrigin::Root.into(),
DOT_U,
vec![DOT_U]
));
assert_ok!(LendMarket::<T>::activate_market(SystemOrigin::Root.into(), DOT_U));
assert_ok!(LendMarket::<T>::mint(SystemOrigin::Signed(caller.clone()).into(), DOT_U, deposit_amount.into()));
assert_ok!(LendMarket::<T>::collateral_asset(SystemOrigin::Signed(caller.clone()).into(), DOT_U, true));
Expand Down
69 changes: 69 additions & 0 deletions pallets/lend-market/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ pub mod pallet {
CodecError,
/// Collateral is reserved and cannot be liquidated
CollateralReserved,
/// Market bond does not exist
MarketBondDoesNotExist,
}

#[pallet::event]
Expand Down Expand Up @@ -260,6 +262,10 @@ pub mod pallet {
IncentiveReservesReduced(T::AccountId, AssetIdOf<T>, BalanceOf<T>),
/// Liquidation free collaterals has been updated
LiquidationFreeCollateralsUpdated(Vec<AssetIdOf<T>>),
MarketBonded {
asset_id: AssetIdOf<T>,
market_bond: Vec<AssetIdOf<T>>,
},
}

/// The timestamp of the last calculation of accrued interest
Expand Down Expand Up @@ -446,6 +452,10 @@ pub mod pallet {
pub type RewardAccrued<T: Config> =
StorageMap<_, Blake2_128Concat, T::AccountId, BalanceOf<T>, ValueQuery>;

#[pallet::storage]
pub type MarketBond<T: Config> =
StorageMap<_, Blake2_128Concat, AssetIdOf<T>, Vec<AssetIdOf<T>>>;

/// DefaultVersion is using for initialize the StorageVersion
#[pallet::type_value]
pub(super) fn DefaultVersion() -> Versions {
Expand Down Expand Up @@ -1126,6 +1136,21 @@ pub mod pallet {
Self::deposit_event(Event::<T>::LiquidationFreeCollateralsUpdated(collaterals));
Ok(().into())
}

#[pallet::call_index(22)]
#[pallet::weight(T::WeightInfo::add_market())]
#[transactional]
pub fn add_market_bond(
origin: OriginFor<T>,
asset_id: AssetIdOf<T>,
market_bond: Vec<AssetIdOf<T>>,
) -> DispatchResultWithPostInfo {
T::UpdateOrigin::ensure_origin(origin)?;
MarketBond::<T>::insert(asset_id, market_bond.clone());

Self::deposit_event(Event::<T>::MarketBonded { asset_id, market_bond });
Ok(().into())
}
}
}

Expand Down Expand Up @@ -1460,6 +1485,20 @@ impl<T: Config> Pallet<T> {
Ok(())
}

/// Borrower shouldn't borrow more than his bonded collateral value
fn borrow_allowed_for_market_bond(
borrow_asset_id: AssetIdOf<T>,
borrower: &T::AccountId,
borrow_amount: BalanceOf<T>,
) -> DispatchResult {
Self::ensure_under_borrow_cap(borrow_asset_id, borrow_amount)?;
Self::ensure_enough_cash(borrow_asset_id, borrow_amount)?;
let borrow_value = Self::get_asset_value(borrow_asset_id, borrow_amount)?;
Self::ensure_liquidity_for_market_bond(borrow_asset_id, borrower, borrow_value)?;

Ok(())
}

#[require_transactional]
fn do_repay_borrow_with_amount(
borrower: &T::AccountId,
Expand Down Expand Up @@ -1877,6 +1916,35 @@ impl<T: Config> Pallet<T> {
Err(Error::<T>::InsufficientLiquidity.into())
}

fn ensure_liquidity_for_market_bond(
borrow_asset_id: AssetIdOf<T>,
account: &T::AccountId,
reduce_amount: FixedU128,
) -> DispatchResult {
let collateral_asset_ids = MarketBond::<T>::try_get(borrow_asset_id)
.map_err(|_err| Error::<T>::MarketBondDoesNotExist)?;

let currency_borrow_amount = Self::current_borrow_balance(account, borrow_asset_id)?;
let total_borrow_value = Self::get_asset_value(borrow_asset_id, currency_borrow_amount)?;

let mut total_collateral_value: FixedU128 = FixedU128::zero();
for asset_id in collateral_asset_ids {
total_collateral_value = total_collateral_value
.checked_add(&Self::collateral_asset_value(account, asset_id)?)
.ok_or(ArithmeticError::Overflow)?;
}

let total_liquidity = total_collateral_value
.checked_sub(&total_borrow_value)
.ok_or(ArithmeticError::Underflow)?;

if total_liquidity >= reduce_amount {
return Ok(());
}

Err(Error::<T>::InsufficientLiquidity.into())
}

pub fn calc_underlying_amount(
voucher_amount: BalanceOf<T>,
exchange_rate: Rate,
Expand Down Expand Up @@ -2064,6 +2132,7 @@ impl<T: Config> LendMarketTrait<AssetIdOf<T>, AccountIdOf<T>, BalanceOf<T>> for
Self::ensure_active_market(asset_id)?;

Self::accrue_interest(asset_id)?;
Self::borrow_allowed_for_market_bond(asset_id, borrower, amount)?;
Self::borrow_allowed(asset_id, borrower, amount)?;

// update borrow index after accrue interest.
Expand Down
Loading

0 comments on commit 9ba9adf

Please sign in to comment.