From 968f0e7b0151e9f24ba8764f616aa8b792dc2ebb Mon Sep 17 00:00:00 2001 From: Muyideen-js Date: Fri, 26 Jun 2026 12:25:22 -0400 Subject: [PATCH] fix(contracts): restore investor tier wrapper and remove duplicate compute_investor_tier definitions --- quicklendx-contracts/src/verification.rs | 90 +++++++----------------- 1 file changed, 27 insertions(+), 63 deletions(-) diff --git a/quicklendx-contracts/src/verification.rs b/quicklendx-contracts/src/verification.rs index 48c66091..1eccde63 100644 --- a/quicklendx-contracts/src/verification.rs +++ b/quicklendx-contracts/src/verification.rs @@ -1279,6 +1279,30 @@ pub fn calculate_investor_risk_score( Ok(risk_score) } +/// Compute investor tier from the investor record and a risk score. +/// +/// This wrapper is used by public contract entrypoints and internal business +/// logic, while the core deterministic tier rules are implemented in the +/// `compute_investor_tier_from_stats` helper. +pub fn compute_investor_tier( + env: &Env, + investor: &Address, + risk_score: u32, +) -> Result { + validate_risk_score(risk_score)?; + + if let Some(verification) = InvestorVerificationStorage::get(env, investor) { + return compute_investor_tier_from_stats( + verification.total_invested, + verification.successful_investments, + verification.defaulted_investments, + risk_score, + ); + } + + Ok(InvestorTier::Basic) +} + /// Determine investor tier based on risk score and investment history. /// Calculate the investor tier using deterministic performance thresholds. /// @@ -1299,21 +1323,10 @@ pub fn determine_investor_tier( investor: &Address, risk_score: u32, ) -> Result { - validate_risk_score(risk_score)?; - - if let Some(verification) = InvestorVerificationStorage::get(env, investor) { - return compute_investor_tier_from_stats( - verification.total_invested, - verification.successful_investments, - verification.defaulted_investments, - risk_score, - ); - } - - Ok(InvestorTier::Basic) + compute_investor_tier(env, investor, risk_score) } -pub fn compute_investor_tier( +pub fn compute_investor_tier_from_stats( total_invested: i128, successful_investments: u32, defaulted_investments: u32, @@ -1377,55 +1390,6 @@ pub fn determine_risk_level(risk_score: u32) -> InvestorRiskLevel { } } -/// Core tier computation using raw counters (total invested, successes, defaults). -pub fn compute_investor_tier( - total_invested: i128, - successful_investments: u32, - defaulted_investments: u32, - risk_score: u32, -) -> Result { - let total = successful_investments.saturating_add(defaulted_investments); - let default_rate = if total > 0 { - (defaulted_investments.saturating_mul(100)) / total - } else { - 0u32 - }; - - if risk_score <= 10 - && total_invested >= 5_000_000 - && successful_investments >= 50 - && default_rate <= 5 - { - return Ok(InvestorTier::VIP); - } - - if risk_score <= 20 - && total_invested >= 1_000_000 - && successful_investments >= 20 - && default_rate <= 10 - { - return Ok(InvestorTier::Platinum); - } - - if risk_score <= 40 - && total_invested >= 100_000 - && successful_investments >= 10 - && default_rate <= 15 - { - return Ok(InvestorTier::Gold); - } - - if risk_score <= 60 - && total_invested >= 10_000 - && successful_investments >= 3 - && default_rate <= 25 - { - return Ok(InvestorTier::Silver); - } - - Ok(InvestorTier::Basic) -} - /// Calculate investment limit based on tier and risk level pub fn calculate_investment_limit( tier: &InvestorTier, @@ -1670,7 +1634,7 @@ pub fn recompute_investor_tier( let risk_score = calculate_investor_risk_score(env, investor, &verification.kyc_data)?; validate_risk_score(risk_score)?; - let tier = compute_investor_tier( + let tier = compute_investor_tier_from_stats( verification.total_invested, verification.successful_investments, verification.defaulted_investments,