From 908cf55f4d61a0c1752b11e18f738b75a9af106c Mon Sep 17 00:00:00 2001 From: ONEONUORA Date: Fri, 20 Feb 2026 13:11:08 +0100 Subject: [PATCH 1/5] feat: add Comprehensive Error Types --- .../contracts/predifi-contract/src/lib.rs | 94 +++++++++++++------ .../contracts/predifi-errors/src/errors.rs | 27 ++++++ 2 files changed, 91 insertions(+), 30 deletions(-) diff --git a/contract/contracts/predifi-contract/src/lib.rs b/contract/contracts/predifi-contract/src/lib.rs index d65fe591..bc79d5b1 100644 --- a/contract/contracts/predifi-contract/src/lib.rs +++ b/contract/contracts/predifi-contract/src/lib.rs @@ -4,6 +4,7 @@ use predifi_errors::PrediFiError; use soroban_sdk::{contract, contractevent, contractimpl, contracttype, token, Address, Env}; const RESOLUTION_WINDOW: u64 = 7 * 24 * 60 * 60; // 7 days in seconds +const MAX_PAGINATION_LIMIT: u32 = 50; // Event structs for contract events #[contractevent] @@ -116,16 +117,24 @@ impl PredifiContract { env.storage() .instance() .get(&DataKey::AccessControlAddress) - .ok_or(PrediFiError::NotInitialized) + .ok_or(PrediFiError::AccessControlNotSet) } /// Get the access control client /// /// # Returns /// The AccessControlClient instance - fn get_access_control_client(env: &Env) -> access_control::AccessControlClient<'_> { - let access_control_addr = Self::get_access_control_address(env).unwrap(); - access_control::AccessControlClient::new(env, &access_control_addr) + /// + /// # Errors + /// * `AccessControlNotSet` - If access control contract is not set + fn get_access_control_client( + env: &Env, + ) -> Result, PrediFiError> { + let access_control_addr = Self::get_access_control_address(env)?; + Ok(access_control::AccessControlClient::new( + env, + &access_control_addr, + )) } /// Set the access control contract address (only callable once) @@ -155,7 +164,10 @@ impl PredifiContract { /// # Arguments /// * `treasury` - Address to receive protocol fees /// * `fee_bps` - Fee in basis points (e.g., 100 = 1%) - pub fn init(env: Env, treasury: Address, fee_bps: u32) { + pub fn init(env: Env, treasury: Address, fee_bps: u32) -> Result<(), PrediFiError> { + if fee_bps > 10000 { + return Err(PrediFiError::MaxFeeExceeded); + } // Only set if not already initialized if !env.storage().instance().has(&DataKey::PoolIdCounter) { env.storage().instance().set(&DataKey::PoolIdCounter, &0u64); @@ -166,6 +178,7 @@ impl PredifiContract { if !env.storage().instance().has(&DataKey::Treasury) { env.storage().instance().set(&DataKey::Treasury, &treasury); } + Ok(()) } /// Set the protocol fee in basis points. @@ -178,11 +191,15 @@ impl PredifiContract { /// * `InsufficientPermissions` - If caller doesn't have Admin role pub fn set_fee_bps(env: Env, caller: Address, fee_bps: u32) -> Result<(), PrediFiError> { // Check if caller has Admin role - let access_control_client = Self::get_access_control_client(&env); + let access_control_client = Self::get_access_control_client(&env)?; if !access_control_client.has_role(&caller, &Role::Admin) { return Err(PrediFiError::InsufficientPermissions); } + if fee_bps > 10000 { + return Err(PrediFiError::MaxFeeExceeded); + } + env.storage().instance().set(&DataKey::FeeBps, &fee_bps); SetFeeBpsEvent { new_fee_bps: fee_bps, @@ -209,7 +226,7 @@ impl PredifiContract { /// * `InsufficientPermissions` - If caller doesn't have Admin role pub fn set_treasury(env: Env, caller: Address, treasury: Address) -> Result<(), PrediFiError> { // Check if caller has Admin role - let access_control_client = Self::get_access_control_client(&env); + let access_control_client = Self::get_access_control_client(&env)?; if !access_control_client.has_role(&caller, &Role::Admin) { return Err(PrediFiError::InsufficientPermissions); } @@ -226,11 +243,11 @@ impl PredifiContract { /// /// # Returns /// The treasury address - pub fn get_treasury(env: Env) -> Address { + pub fn get_treasury(env: Env) -> Result { env.storage() .instance() .get(&DataKey::Treasury) - .expect("Treasury not set") + .ok_or(PrediFiError::TreasuryNotSet) } /// Create a new prediction pool. @@ -278,9 +295,12 @@ impl PredifiContract { // 5. Save State env.storage().instance().set(&DataKey::Pool(pool_id), &pool); - env.storage() - .instance() - .set(&DataKey::PoolIdCounter, &(pool_id + 1)); + env.storage().instance().set( + &DataKey::PoolIdCounter, + &(pool_id + .checked_add(1) + .ok_or(PrediFiError::AdditionOverflow)?), + ); // 6. Emit Event PoolCreatedEvent { @@ -317,7 +337,7 @@ impl PredifiContract { caller.require_auth(); // Check if caller has Admin or Operator role (oracle/admin authorization) - let access_control_client = Self::get_access_control_client(&env); + let access_control_client = Self::get_access_control_client(&env)?; if !access_control_client.has_role(&caller, &Role::Admin) && !access_control_client.has_role(&caller, &Role::Operator) { @@ -344,7 +364,11 @@ impl PredifiContract { } // Resolution must happen within the window - if current_time > pool.end_time + RESOLUTION_WINDOW { + let resolution_deadline = pool.end_time + .checked_add(RESOLUTION_WINDOW) + .ok_or(PrediFiError::AdditionOverflow)?; + + if current_time > resolution_deadline { return Err(PrediFiError::ResolutionWindowExpired); } @@ -373,8 +397,9 @@ impl PredifiContract { let fee = pool .total_stake .checked_mul(fee_bps as i128) - .and_then(|v| v.checked_div(10_000)) - .ok_or(PrediFiError::ArithmeticOverflow)?; + .ok_or(PrediFiError::MultiplicationOverflow)? + .checked_div(10_000) + .ok_or(PrediFiError::DivisionByZero)?; env.storage() .instance() @@ -434,9 +459,12 @@ impl PredifiContract { .ok_or(PrediFiError::PoolNotFound)?; // Validate amount - if amount <= 0 || amount < pool.min_stake { + if amount <= 0 { return Err(PrediFiError::InvalidPredictionAmount); } + if amount < pool.min_stake { + return Err(PrediFiError::MinStakeNotMet); + } // Check if pool is resolved if pool.resolved { @@ -473,7 +501,7 @@ impl PredifiContract { pool.total_stake = pool .total_stake .checked_add(amount) - .ok_or(PrediFiError::ArithmeticOverflow)?; + .ok_or(PrediFiError::AdditionOverflow)?; env.storage().instance().set(&DataKey::Pool(pool_id), &pool); // Update stake specific to this outcome @@ -481,7 +509,7 @@ impl PredifiContract { let current_outcome_stake: i128 = env.storage().instance().get(&outcome_key).unwrap_or(0); let new_outcome_stake = current_outcome_stake .checked_add(amount) - .ok_or(PrediFiError::ArithmeticOverflow)?; + .ok_or(PrediFiError::AdditionOverflow)?; env.storage() .instance() .set(&outcome_key, &new_outcome_stake); @@ -497,7 +525,7 @@ impl PredifiContract { .set(&DataKey::UserPredictionIndex(user.clone(), count), &pool_id); let new_count = count .checked_add(1) - .ok_or(PrediFiError::ArithmeticOverflow)?; + .ok_or(PrediFiError::AdditionOverflow)?; env.storage() .instance() .set(&DataKey::UserPredictionCount(user.clone()), &new_count); @@ -543,6 +571,10 @@ impl PredifiContract { return Err(PrediFiError::PoolNotResolved); } + if pool.outcome >= pool.options_count { + return Err(PrediFiError::InconsistentState); + } + // 2. Prevent double claiming if env .storage() @@ -569,13 +601,16 @@ impl PredifiContract { let winning_outcome_stake: i128 = env.storage().instance().get(&outcome_key).unwrap_or(0); if winning_outcome_stake == 0 { + if pool.total_stake > 0 { + return Err(PrediFiError::InconsistentState); + } return Err(PrediFiError::WinningStakeZero); } let gross_winnings = prediction .amount .checked_mul(pool.total_stake) - .ok_or(PrediFiError::ArithmeticOverflow)? + .ok_or(PrediFiError::MultiplicationOverflow)? .checked_div(winning_outcome_stake) .ok_or(PrediFiError::DivisionByZero)?; @@ -593,14 +628,14 @@ impl PredifiContract { // User's share of fee = (user's gross winnings / total pool stake) * total_fee fee_share = gross_winnings .checked_mul(total_fee) - .ok_or(PrediFiError::ArithmeticOverflow)? + .ok_or(PrediFiError::MultiplicationOverflow)? .checked_div(pool.total_stake) .ok_or(PrediFiError::DivisionByZero)?; } let net_winnings = gross_winnings .checked_sub(fee_share) - .ok_or(PrediFiError::ArithmeticOverflow)?; + .ok_or(PrediFiError::ArithmeticUnderflow)?; // 7. Transfer net winnings to user let token_client = token::Client::new(&env, &pool.token); @@ -625,11 +660,7 @@ impl PredifiContract { let fee_paid_key = DataKey::HasClaimed(marker_addr, pool_id); if !env.storage().instance().has(&fee_paid_key) { - let treasury: Address = env - .storage() - .instance() - .get(&DataKey::Treasury) - .expect("Treasury not set"); + let treasury = Self::get_treasury(env)?; token_client.transfer(&env.current_contract_address(), &treasury, &total_fee); env.storage().instance().set(&fee_paid_key, &true); @@ -670,6 +701,9 @@ impl PredifiContract { if limit == 0 { return Err(PrediFiError::InvalidLimit); } + if limit > MAX_PAGINATION_LIMIT { + return Err(PrediFiError::InvalidLimit); + } let count: u32 = env .storage() @@ -686,7 +720,7 @@ impl PredifiContract { let end = core::cmp::min( offset .checked_add(limit) - .ok_or(PrediFiError::ArithmeticOverflow)?, + .ok_or(PrediFiError::AdditionOverflow)?, count, ); @@ -707,7 +741,7 @@ impl PredifiContract { .storage() .instance() .get(&DataKey::Pool(pool_id)) - .ok_or(PrediFiError::PoolNotFound)?; + .ok_or(PrediFiError::InconsistentState)?; results.push_back(UserPredictionDetail { pool_id, diff --git a/contract/contracts/predifi-errors/src/errors.rs b/contract/contracts/predifi-errors/src/errors.rs index 7b9f0b3e..9b0e11a3 100644 --- a/contract/contracts/predifi-errors/src/errors.rs +++ b/contract/contracts/predifi-errors/src/errors.rs @@ -13,6 +13,10 @@ pub enum PrediFiError { NotInitialized = 1, /// Contract has already been initialized. AlreadyInitialized = 2, + /// Protocol treasury address is not set. + TreasuryNotSet = 3, + /// Access control contract is not set. + AccessControlNotSet = 4, // ── Authorization & Access Control (10–15) ──────────────────────────────── /// The caller is not authorized to perform this action. @@ -41,6 +45,8 @@ pub enum PrediFiError { ResolutionWindowExpired = 27, /// The number of options provided is invalid. InvalidOptionsCount = 28, + /// State inconsistency detected. + InconsistentState = 29, // ── Prediction & Betting (40–50) ────────────────────────────────────────── /// The user has no prediction for this pool. @@ -53,6 +59,8 @@ pub enum PrediFiError { PredictionTooLate = 43, /// The user has insufficient balance for this prediction. InsufficientBalance = 44, + /// The prediction amount is below the minimum required stake. + MinStakeNotMet = 45, // ── Claiming & Reward (60–70) ───────────────────────────────────────────── /// The user has already claimed winnings for this pool. @@ -81,6 +89,8 @@ pub enum PrediFiError { InvalidOffset = 93, /// The pagination limit is invalid (e.g., zero or too large). InvalidLimit = 94, + /// The fee basis points exceed the maximum allowed value. + MaxFeeExceeded = 95, // ── Arithmetic & Calculation (110–115) ──────────────────────────────────── /// An arithmetic overflow occurred. @@ -89,6 +99,10 @@ pub enum PrediFiError { ArithmeticUnderflow = 111, /// Division by zero attempted. DivisionByZero = 112, + /// An overflow occurred during addition. + AdditionOverflow = 113, + /// An overflow occurred during multiplication. + MultiplicationOverflow = 114, // ── Storage & State (120–125) ───────────────────────────────────────────── /// The storage key was not found. @@ -104,6 +118,8 @@ impl PrediFiError { // Initialization & Configuration PrediFiError::NotInitialized => "Contract not initialized", PrediFiError::AlreadyInitialized => "Contract already initialized", + PrediFiError::TreasuryNotSet => "Treasury address not set", + PrediFiError::AccessControlNotSet => "Access control address not set", // Authorization & Access Control PrediFiError::Unauthorized => "Unauthorized access", @@ -120,6 +136,7 @@ impl PrediFiError { PrediFiError::InvalidOutcome => "Invalid outcome", PrediFiError::ResolutionWindowExpired => "Resolution window has expired", PrediFiError::InvalidOptionsCount => "Invalid options count", + PrediFiError::InconsistentState => "Inconsistent state detected", // Prediction & Betting PrediFiError::PredictionNotFound => "Prediction not found", @@ -127,6 +144,7 @@ impl PrediFiError { PrediFiError::InvalidPredictionAmount => "Invalid prediction amount", PrediFiError::PredictionTooLate => "Cannot predict after pool end time", PrediFiError::InsufficientBalance => "Insufficient balance", + PrediFiError::MinStakeNotMet => "Minimum stake not met", // Claiming & Rewards PrediFiError::AlreadyClaimed => "Already claimed", @@ -144,11 +162,14 @@ impl PrediFiError { PrediFiError::InvalidToken => "Invalid token", PrediFiError::InvalidOffset => "Invalid offset", PrediFiError::InvalidLimit => "Invalid limit", + PrediFiError::MaxFeeExceeded => "Maximum fee exceeded", // Arithmetic & Calculation PrediFiError::ArithmeticOverflow => "Arithmetic overflow", PrediFiError::ArithmeticUnderflow => "Arithmetic underflow", PrediFiError::DivisionByZero => "Division by zero", + PrediFiError::AdditionOverflow => "Addition overflow", + PrediFiError::MultiplicationOverflow => "Multiplication overflow", // Storage & State PrediFiError::StorageKeyNotFound => "Storage key not found", @@ -156,3 +177,9 @@ impl PrediFiError { } } } + +impl core::fmt::Display for PrediFiError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} From 4f7c0c33f61b4c0ec36cf6f0e6d42d2d68c9fb6a Mon Sep 17 00:00:00 2001 From: ONEONUORA Date: Fri, 20 Feb 2026 13:11:35 +0100 Subject: [PATCH 2/5] feat: add Comprehensive Error Types --- contract/contracts/predifi-contract/src/lib.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/contract/contracts/predifi-contract/src/lib.rs b/contract/contracts/predifi-contract/src/lib.rs index bc79d5b1..2be284e3 100644 --- a/contract/contracts/predifi-contract/src/lib.rs +++ b/contract/contracts/predifi-contract/src/lib.rs @@ -364,10 +364,11 @@ impl PredifiContract { } // Resolution must happen within the window - let resolution_deadline = pool.end_time + let resolution_deadline = pool + .end_time .checked_add(RESOLUTION_WINDOW) .ok_or(PrediFiError::AdditionOverflow)?; - + if current_time > resolution_deadline { return Err(PrediFiError::ResolutionWindowExpired); } @@ -523,9 +524,7 @@ impl PredifiContract { env.storage() .instance() .set(&DataKey::UserPredictionIndex(user.clone(), count), &pool_id); - let new_count = count - .checked_add(1) - .ok_or(PrediFiError::AdditionOverflow)?; + let new_count = count.checked_add(1).ok_or(PrediFiError::AdditionOverflow)?; env.storage() .instance() .set(&DataKey::UserPredictionCount(user.clone()), &new_count); From acc346c02fc9b6182d168057c86ce2096c441033 Mon Sep 17 00:00:00 2001 From: ONEONUORA Date: Fri, 20 Feb 2026 13:18:55 +0100 Subject: [PATCH 3/5] feat: add Comprehensive Error Types --- contract/contracts/predifi-contract/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract/contracts/predifi-contract/src/lib.rs b/contract/contracts/predifi-contract/src/lib.rs index 2be284e3..4b90aced 100644 --- a/contract/contracts/predifi-contract/src/lib.rs +++ b/contract/contracts/predifi-contract/src/lib.rs @@ -659,7 +659,7 @@ impl PredifiContract { let fee_paid_key = DataKey::HasClaimed(marker_addr, pool_id); if !env.storage().instance().has(&fee_paid_key) { - let treasury = Self::get_treasury(env)?; + let treasury = Self::get_treasury(env.clone())?; token_client.transfer(&env.current_contract_address(), &treasury, &total_fee); env.storage().instance().set(&fee_paid_key, &true); From 2fecd125ffc74db4f8fd1c75f95edb3a59202a0c Mon Sep 17 00:00:00 2001 From: ONEONUORA Date: Fri, 20 Feb 2026 13:28:28 +0100 Subject: [PATCH 4/5] feat: add Comprehensive Error Types --- contract/contracts/predifi-contract/src/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contract/contracts/predifi-contract/src/test.rs b/contract/contracts/predifi-contract/src/test.rs index 8a91c925..3d400c06 100644 --- a/contract/contracts/predifi-contract/src/test.rs +++ b/contract/contracts/predifi-contract/src/test.rs @@ -404,7 +404,7 @@ fn test_place_prediction_min_stake() { // Try to place prediction with amount 50 (should fail) let result = client.try_place_prediction(&user, &user, &pool_id, &50, &1); - assert_eq!(result, Err(Ok(PrediFiError::InvalidPredictionAmount))); + assert_eq!(result, Err(Ok(PrediFiError::MinStakeNotMet))); // Place prediction with amount 100 (should succeed) let result = client.try_place_prediction(&user, &user, &pool_id, &100, &1); From 206137a7bd939b0cfa8aad3e9ba403b7a5a4bd99 Mon Sep 17 00:00:00 2001 From: ONEONUORA Date: Fri, 20 Feb 2026 16:10:34 +0100 Subject: [PATCH 5/5] feat: add error-types --- .../predifi-contract/src/integration_test.rs | 32 ++++++++++++------- .../contracts/predifi-contract/src/lib.rs | 6 ++-- .../contracts/predifi-contract/src/test.rs | 13 +++++--- .../contracts/predifi-errors/src/errors.rs | 10 ++---- contract/contracts/predifi-errors/src/lib.rs | 6 ++-- 5 files changed, 38 insertions(+), 29 deletions(-) diff --git a/contract/contracts/predifi-contract/src/integration_test.rs b/contract/contracts/predifi-contract/src/integration_test.rs index 6cff0126..4eef2bfb 100644 --- a/contract/contracts/predifi-contract/src/integration_test.rs +++ b/contract/contracts/predifi-contract/src/integration_test.rs @@ -2,7 +2,10 @@ use super::*; use crate::test_utils::TokenTestContext; -use soroban_sdk::{testutils::{Address as _, Ledger}, Address, Env}; +use soroban_sdk::{ + testutils::{Address as _, Ledger}, + Address, Env, +}; mod dummy_access_control { use soroban_sdk::{contract, contractimpl, Address, Env, Symbol}; @@ -27,7 +30,9 @@ mod dummy_access_control { const ROLE_ADMIN: u32 = 0; const ROLE_OPERATOR: u32 = 1; -fn setup_integration(env: &Env) -> ( +fn setup_integration( + env: &Env, +) -> ( PredifiContractClient<'static>, TokenTestContext, Address, // Admin @@ -111,13 +116,16 @@ fn test_multi_user_betting_and_balance_verification() { let (client, token_ctx, _admin, operator, _treasury) = setup_integration(&env); // 5 users - let users: soroban_sdk::Vec
= soroban_sdk::Vec::from_array(&env, [ - Address::generate(&env), - Address::generate(&env), - Address::generate(&env), - Address::generate(&env), - Address::generate(&env), - ]); + let users: soroban_sdk::Vec
= soroban_sdk::Vec::from_array( + &env, + [ + Address::generate(&env), + Address::generate(&env), + Address::generate(&env), + Address::generate(&env), + Address::generate(&env), + ], + ); for user in users.iter() { token_ctx.mint(&user, 5000); @@ -132,7 +140,7 @@ fn test_multi_user_betting_and_balance_verification() { // U3: 1500 on 3 // U4: 500 on 1 // Total 1: 1500, Total 2: 1000, Total 3: 1500. Total Stake: 4000. - + client.place_prediction(&users.get(0).unwrap(), &pool_id, &500, &1); client.place_prediction(&users.get(1).unwrap(), &pool_id, &1000, &2); client.place_prediction(&users.get(2).unwrap(), &pool_id, &500, &1); @@ -181,7 +189,7 @@ fn test_market_resolution_multiple_winners() { // U2: 300 on 1 // U3: 500 on 2 // Total 1: 500, Total 2: 500. Total Stake: 1000. - + client.place_prediction(&user1, &pool_id, &200, &1); client.place_prediction(&user2, &pool_id, &300, &1); client.place_prediction(&user3, &pool_id, &500, &2); @@ -192,7 +200,7 @@ fn test_market_resolution_multiple_winners() { // U1 Winnings: (200 / 500) * 1000 = 400 // U2 Winnings: (300 / 500) * 1000 = 600 - + let w1 = client.claim_winnings(&user1, &pool_id); let w2 = client.claim_winnings(&user2, &pool_id); diff --git a/contract/contracts/predifi-contract/src/lib.rs b/contract/contracts/predifi-contract/src/lib.rs index 10c62b50..2db960c3 100644 --- a/contract/contracts/predifi-contract/src/lib.rs +++ b/contract/contracts/predifi-contract/src/lib.rs @@ -234,7 +234,9 @@ impl PredifiContract { let new_outcome_stake = current_stake .checked_add(amount) .ok_or(PrediFiError::ArithmeticError)?; - env.storage().instance().set(&outcome_key, &new_outcome_stake); + env.storage() + .instance() + .set(&outcome_key, &new_outcome_stake); // Index prediction for pagination let count: u32 = env @@ -373,6 +375,6 @@ impl PredifiContract { } } +mod integration_test; mod test; mod test_utils; -mod integration_test; diff --git a/contract/contracts/predifi-contract/src/test.rs b/contract/contracts/predifi-contract/src/test.rs index 45cb6290..26f5bd63 100644 --- a/contract/contracts/predifi-contract/src/test.rs +++ b/contract/contracts/predifi-contract/src/test.rs @@ -2,7 +2,10 @@ #![allow(deprecated)] use super::*; -use soroban_sdk::{testutils::{Address as _, Ledger}, token, Address, Env}; +use soroban_sdk::{ + testutils::{Address as _, Ledger}, + token, Address, Env, +}; mod dummy_access_control { use soroban_sdk::{contract, contractimpl, Address, Env, Symbol}; @@ -75,7 +78,7 @@ fn test_claim_winnings() { let (_, client, token_address, token, token_admin_client, _, operator) = setup(&env); let _contract_id = env.register(PredifiContract, ()); // get contract address for balance check - // Re-derive contract address from client + // Re-derive contract address from client let contract_addr = client.address.clone(); let user1 = Address::generate(&env); @@ -119,10 +122,10 @@ fn test_double_claim() { let pool_id = client.create_pool(&100u64, &token_address); client.place_prediction(&user1, &pool_id, &100, &1); - + // Advance time past pool end_time env.ledger().with_mut(|li| li.timestamp = 101); - + client.resolve_pool(&operator, &pool_id, &1u32); client.claim_winnings(&user1, &pool_id); @@ -285,7 +288,7 @@ fn test_multiple_pools_independent() { // Advance time past pool_a end_time env.ledger().with_mut(|li| li.timestamp = 101); client.resolve_pool(&operator, &pool_a, &1u32); - + // Advance time past pool_b end_time env.ledger().with_mut(|li| li.timestamp = 201); client.resolve_pool(&operator, &pool_b, &2u32); // user2 loses diff --git a/contract/contracts/predifi-errors/src/errors.rs b/contract/contracts/predifi-errors/src/errors.rs index c30a6652..009fa849 100644 --- a/contract/contracts/predifi-errors/src/errors.rs +++ b/contract/contracts/predifi-errors/src/errors.rs @@ -4,7 +4,7 @@ use soroban_sdk::contracterror; /// The error type covers all cases across Predifi contracts. /// Gap-based numbering allows future error codes to be added without /// renumbering existing ones or breaking client-side mappings. -/// +/// /// Note: Soroban limits the number of error variants to 32. /// This enum is optimized to stay within that limit while providing /// comprehensive error coverage through consolidated error variants. @@ -214,9 +214,7 @@ impl PrediFiError { // Timestamp & Time Validation Self::InvalidTimestamp => "Invalid timestamp or time constraints not met", - Self::TimeConstraintError => { - "End time or resolution time constraints are not met" - } + Self::TimeConstraintError => "End time or resolution time constraints are not met", // Data & Validation Self::InvalidData => "Invalid data", @@ -245,9 +243,7 @@ impl PrediFiError { } // Emergency & Admin - Self::AdminError => { - "Contract pause, emergency, version mismatch, or upgrade error" - } + Self::AdminError => "Contract pause, emergency, version mismatch, or upgrade error", // Rate Limiting & Spam Prevention Self::RateLimitOrSuspiciousActivity => { diff --git a/contract/contracts/predifi-errors/src/lib.rs b/contract/contracts/predifi-errors/src/lib.rs index b1ad8c30..e9481021 100644 --- a/contract/contracts/predifi-errors/src/lib.rs +++ b/contract/contracts/predifi-errors/src/lib.rs @@ -3,10 +3,10 @@ //! # PrediFi Errors //! //! This crate provides a comprehensive error handling system for PrediFi smart contracts. -//! +//! //! ## Features -//! -//! - **Granular Error Codes**: Specific error variants for validation failures, arithmetic +//! +//! - **Granular Error Codes**: Specific error variants for validation failures, arithmetic //! overflows, state inconsistencies, and more //! - **Gap-Based Numbering**: Error codes are organized in ranges (e.g., 1-5 for initialization, //! 10-15 for authorization) allowing future additions without breaking existing mappings