Skip to content
Closed
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
8 changes: 7 additions & 1 deletion contracts/loan_manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ impl LoanManager {
const MIN_RATE_BPS: u32 = 1; // Minimum 0.01% interest rate
/// Default maximum interest rate (configurable via set_rate_bounds). #631
const MAX_RATE_BPS: u32 = 100_000; // Maximum 1000% interest rate
const MAX_CREDIT_SCORE: u32 = 850;
const MAX_PENALTY_MULTIPLIER: i128 = 2; // Total debt cannot exceed 2x original principal

fn bump_instance_ttl(env: &Env) {
Expand Down Expand Up @@ -1935,7 +1936,11 @@ impl LoanManager {
Self::default_window_ledgers(&env)
}

pub fn set_min_score(env: Env, min_score: u32) {
pub fn set_min_score(env: Env, min_score: u32) -> Result<(), LoanError> {
if min_score == 0 || min_score > Self::MAX_CREDIT_SCORE {
return Err(LoanError::InvalidConfiguration);
}

Self::admin(&env).require_auth();

let old_score: u32 = env
Expand All @@ -1946,6 +1951,7 @@ impl LoanManager {
env.storage().instance().set(&DataKey::MinScore, &min_score);
Self::bump_instance_ttl(&env);
events::min_score_updated(&env, old_score, min_score);
Ok(())
}

pub fn set_max_loan_amount(env: Env, amount: i128) -> Result<(), LoanError> {
Expand Down
40 changes: 40 additions & 0 deletions contracts/loan_manager/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,46 @@ fn test_set_interest_rate_zero_rejected() {
assert_eq!(result, Err(Ok(LoanError::InvalidRate)));
}

#[test]
fn test_set_min_score_updates_value() {
let env = Env::default();
env.mock_all_auths_allowing_non_root_auth();

let (manager, _nft_client, _pool, _token, _token_admin) = setup_test(&env);

manager.set_min_score(&700);

assert_eq!(manager.get_min_score(), 700);
}

#[test]
fn test_set_min_score_accepts_max_score_boundary() {
let env = Env::default();
env.mock_all_auths_allowing_non_root_auth();

let (manager, _nft_client, _pool, _token, _token_admin) = setup_test(&env);

manager.set_min_score(&850);

assert_eq!(manager.get_min_score(), 850);
}

#[test]
fn test_set_min_score_rejects_out_of_bounds_values() {
let env = Env::default();
env.mock_all_auths_allowing_non_root_auth();

let (manager, _nft_client, _pool, _token, _token_admin) = setup_test(&env);

let above_max = manager.try_set_min_score(&851);
assert_eq!(above_max, Err(Ok(LoanError::InvalidConfiguration)));
assert_eq!(manager.get_min_score(), 500);

let zero = manager.try_set_min_score(&0);
assert_eq!(zero, Err(Ok(LoanError::InvalidConfiguration)));
assert_eq!(manager.get_min_score(), 500);
}

#[test]
fn test_legacy_zero_interest_config_falls_back_to_default() {
let env = Env::default();
Expand Down
Loading