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
1 change: 1 addition & 0 deletions common/src/market/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ pub struct MarketConfiguration {
pub borrow_minimum_amount: BorrowAssetAmount,
pub borrow_maximum_amount: BorrowAssetAmount,
pub supply_withdrawal_fee: TimeBasedFee<BorrowAsset>,
pub supply_maximum_amount: Option<BorrowAssetAmount>,
pub yield_weights: YieldWeights,
pub protocol_account_id: AccountId,
/// How far below market rate to accept liquidation? This is effectively the liquidator's spread.
Expand Down
7 changes: 7 additions & 0 deletions contract/market/src/impl_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@ use crate::{Contract, ContractExt};
/// Internal helpers.
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);
supply_position.record_deposit(amount, env::block_timestamp_ms());
if let Some(ref supply_maximum_amount) = supply_maximum_amount {
require!(
supply_position.inner().get_borrow_asset_deposit() <= *supply_maximum_amount,
"New supply position cannot exceed configured supply maximum",
);
}
}

pub fn execute_collateralize(&mut self, account_id: AccountId, amount: CollateralAssetAmount) {
Expand Down
50 changes: 50 additions & 0 deletions contract/market/tests/supply_maximum_amount.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
use rstest::rstest;
use templar_common::asset::FungibleAssetAmount;
use test_utils::*;

#[rstest]
#[case([10_000], 10_000)]
#[case([1_000, 9_000], 10_000)]
#[tokio::test]
async fn supply_within_maximum(
#[case] deposits: impl IntoIterator<Item = u128>,
#[case] supply_maximum: u128,
) {
let SetupEverything { c, supply_user, .. } = setup_everything(|c| {
c.supply_maximum_amount = Some(FungibleAssetAmount::new(supply_maximum));
})
.await;

let mut sum = 0;
for deposit in deposits {
sum += deposit;
c.supply(&supply_user, deposit).await;
}

let supply_position = c.get_supply_position(supply_user.id()).await.unwrap();
assert_eq!(supply_position.get_borrow_asset_deposit().to_u128(), sum);
}

#[rstest]
#[case([10_001], 10_000)]
#[case([1, 100_000], 10_000)]
#[case([9_001, 500, 500], 10_000)]
#[case([1], 0)]
#[tokio::test]
#[should_panic = "Smart contract panicked: New supply position cannot exceed configured supply maximum"]
async fn supply_beyond_maximum(
#[case] deposits: impl IntoIterator<Item = u128>,
#[case] supply_maximum: u128,
) {
let SetupEverything { c, supply_user, .. } = setup_everything(|c| {
c.supply_maximum_amount = Some(FungibleAssetAmount::new(supply_maximum));
})
.await;

for deposit in deposits {
let r = c.supply(&supply_user, deposit).await;
for o in r.outcomes() {
o.clone().into_result().unwrap();
}
}
}
1 change: 1 addition & 0 deletions test-utils/examples/generate_testnet_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub fn main() {
borrow_minimum_amount: FungibleAssetAmount::new(1),
borrow_maximum_amount: FungibleAssetAmount::new(u128::MAX),
supply_withdrawal_fee: TimeBasedFee::zero(),
supply_maximum_amount: Some(FungibleAssetAmount::new(500 * 10u128.pow(6))),
yield_weights: YieldWeights::new_with_supply_weight(1),
liquidation_maximum_spread: Decimal::from_str("0.05").unwrap(),
protocol_account_id: "templar-in-training.testnet".parse().unwrap(),
Expand Down
1 change: 1 addition & 0 deletions test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,7 @@ pub fn market_configuration(
borrow_maximum_amount: u128::MAX.into(),
liquidation_maximum_spread: Decimal::from_str("0.05").unwrap(),
supply_withdrawal_fee: TimeBasedFee::zero(),
supply_maximum_amount: None,
yield_weights,
protocol_account_id,
}
Expand Down