From adbb2c547bfdd02e5076bfffc8c3964a2cb6b584 Mon Sep 17 00:00:00 2001 From: spazcoin Date: Wed, 27 Mar 2024 21:42:41 +0800 Subject: [PATCH] fix(rate_model): increase MAX jump rate and full rate Recently all USDT on Polkadot was borrowed, leading to Moonwell USDT borrow rates of 192% and Interlay $492k of USDT max borrowed, resulting in Interlay USDT borrow rate pegged at 45-50%. The negative thing was that there was no remaining USDT lending liquidity for lenders to withdraw their capital. Interlay referenda 96 was approved to adjust the USDT/USDC lending params to set the jump rate to 20% and the full rate to 150% with optimal utilization of 80%. After community and team discussion, this solution was agreed to use the higher full rate to push lending back down towards the optimal lending utilization. https://interlay.subsquare.io/democracy/referenda/96 Unfortunately the referenda failed to execute because the 150% proposed full rate exceeded the hard-coded max value of 50% for the full rate. https://interlay.subscan.io/block/4905046?tab=event&event=4905046-0 In this commit I recommend: * leave 10% as max base rate * increase "jump rate" hardcoded max from 30% to 100%. We were already considering 20-30% for USDT. * increase "full rate" from 50% to 500%. I definitely support having limits since people might submit a value with wrong number of zeros accidentally. But let's place the limits higher than any "reasonable" value that we might set in governance. I can see us potentially having a market with jump rate 50% and full rate 300%. --- crates/loans/src/rate_model.rs | 4 ++-- crates/loans/src/tests/market.rs | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/loans/src/rate_model.rs b/crates/loans/src/rate_model.rs index 0e95e3cd6a..80af6aaf89 100644 --- a/crates/loans/src/rate_model.rs +++ b/crates/loans/src/rate_model.rs @@ -113,8 +113,8 @@ pub struct JumpModel { impl JumpModel { pub const MAX_BASE_RATE: Rate = Rate::from_inner(100_000_000_000_000_000); // 10% - pub const MAX_JUMP_RATE: Rate = Rate::from_inner(300_000_000_000_000_000); // 30% - pub const MAX_FULL_RATE: Rate = Rate::from_inner(500_000_000_000_000_000); // 50% + pub const MAX_JUMP_RATE: Rate = Rate::from_inner(1_000_000_000_000_000_000); // 100% + pub const MAX_FULL_RATE: Rate = Rate::from_inner(5_000_000_000_000_000_000); // 500% /// Create a new rate model pub fn new_model(base_rate: Rate, jump_rate: Rate, full_rate: Rate, jump_utilization: Ratio) -> JumpModel { diff --git a/crates/loans/src/tests/market.rs b/crates/loans/src/tests/market.rs index 446fe721c7..e971d5af46 100644 --- a/crates/loans/src/tests/market.rs +++ b/crates/loans/src/tests/market.rs @@ -38,7 +38,7 @@ macro_rules! rate_model_sanity_check { let mut market = MARKET_MOCK; market.rate_model = InterestRateModel::new_jump_model( Rate::saturating_from_rational(5, 100), - Rate::saturating_from_rational(36, 100), + Rate::saturating_from_rational(101, 100), Rate::saturating_from_rational(37, 100), Ratio::from_percent(80), ); @@ -53,7 +53,7 @@ macro_rules! rate_model_sanity_check { market.rate_model = InterestRateModel::new_jump_model( Rate::saturating_from_rational(5, 100), Rate::saturating_from_rational(15, 100), - Rate::saturating_from_rational(57, 100), + Rate::saturating_from_rational(501, 100), Ratio::from_percent(80), ); market @@ -365,7 +365,7 @@ fn update_rate_model_works() { FOREIGN_ASSET, InterestRateModel::new_jump_model( Rate::saturating_from_rational(5, 100), - Rate::saturating_from_rational(36, 100), + Rate::saturating_from_rational(101, 100), Rate::saturating_from_rational(37, 100), Ratio::from_percent(80), ) @@ -379,7 +379,7 @@ fn update_rate_model_works() { FOREIGN_ASSET, InterestRateModel::new_jump_model( Rate::saturating_from_rational(5, 100), - Rate::saturating_from_rational(15, 100), + Rate::saturating_from_rational(501, 100), Rate::saturating_from_rational(57, 100), Ratio::from_percent(80), )