diff --git a/bill_payments/src/lib.rs b/bill_payments/src/lib.rs index fd310d9..7523cc7 100644 --- a/bill_payments/src/lib.rs +++ b/bill_payments/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))] use remitwise_common::{ clamp_limit, EventCategory, EventPriority, RemitwiseEvents, ARCHIVE_BUMP_AMOUNT, @@ -1064,7 +1065,7 @@ impl BillPayments { pub fn batch_pay_bills(env: Env, caller: Address, bill_ids: Vec) -> Result { caller.require_auth(); Self::require_not_paused(&env, pause_functions::PAY_BILL)?; - if bill_ids.len() > (MAX_BATCH_SIZE as usize).try_into().unwrap() { + if bill_ids.len() > (MAX_BATCH_SIZE as usize).try_into().unwrap_or(u32::MAX) { return Err(Error::BatchTooLarge); } let bills_map: Map = env diff --git a/data_migration/src/lib.rs b/data_migration/src/lib.rs index 6d41225..224c46e 100644 --- a/data_migration/src/lib.rs +++ b/data_migration/src/lib.rs @@ -3,6 +3,8 @@ //! Supports multiple formats (JSON, binary, CSV), checksum validation, //! version compatibility checks, and data integrity verification. +#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))] + use base64::Engine; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; @@ -105,7 +107,7 @@ impl ExportSnapshot { /// Compute SHA256 checksum of the payload (canonical JSON). pub fn compute_checksum(&self) -> String { let mut hasher = Sha256::new(); - hasher.update(serde_json::to_vec(&self.payload).expect("payload must be serializable")); + hasher.update(serde_json::to_vec(&self.payload).unwrap_or_else(|_| panic!("payload must be serializable"))); hex::encode(hasher.finalize().as_ref()) } diff --git a/family_wallet/src/lib.rs b/family_wallet/src/lib.rs index 10b84a2..3e93d95 100644 --- a/family_wallet/src/lib.rs +++ b/family_wallet/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))] use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, symbol_short, token::TokenClient, Address, Env, Map, Symbol, Vec, @@ -291,7 +292,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); if members.get(member_address.clone()).is_some() { return Err(Error::InvalidRole); @@ -331,7 +332,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); members.get(member_address) } @@ -356,7 +357,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); let mut record = members .get(member_address.clone()) @@ -437,7 +438,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); if !Self::is_owner_or_admin_in_members(&members, &caller) { panic!("Only Owner or Admin can configure multi-sig"); @@ -499,7 +500,7 @@ impl FamilyWallet { .storage() .instance() .get(&config_key) - .expect("Multi-sig config not found"); + .unwrap_or_else(|| panic!("Multi-sig config not found")); let requires_multisig = match (&tx_type, &data) { (TransactionType::RegularWithdrawal, TransactionData::Withdrawal(_, _, amount)) => { @@ -547,7 +548,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("PEND_TXS")) - .expect("Pending transactions map not initialized"); + .unwrap_or_else(|| panic!("Pending transactions map not initialized")); pending_txs.set(tx_id, pending_tx); env.storage() @@ -572,9 +573,9 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("PEND_TXS")) - .expect("Pending transactions map not initialized"); + .unwrap_or_else(|| panic!("Pending transactions map not initialized")); - let mut pending_tx = pending_txs.get(tx_id).expect("Transaction not found"); + let mut pending_tx = pending_txs.get(tx_id).unwrap_or_else(|| panic!("Transaction not found")); let current_time = env.ledger().timestamp(); if current_time > pending_tx.expires_at { @@ -591,7 +592,7 @@ impl FamilyWallet { .storage() .instance() .get(&Self::get_config_key(pending_tx.tx_type)) - .expect("Multi-sig config not found"); + .unwrap_or_else(|| panic!("Multi-sig config not found")); let mut is_authorized = false; for authorized_signer in config.signers.iter() { @@ -626,7 +627,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("EXEC_TXS")) - .expect("Executed transactions map not initialized"); + .unwrap_or_else(|| panic!("Executed transactions map not initialized")); executed_txs.set(tx_id, true); env.storage() @@ -660,7 +661,7 @@ impl FamilyWallet { .storage() .instance() .get(&Self::get_config_key(TransactionType::LargeWithdrawal)) - .expect("Multi-sig config not found"); + .unwrap_or_else(|| panic!("Multi-sig config not found")); let tx_type = if amount > config.spending_limit { TransactionType::LargeWithdrawal @@ -828,7 +829,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); let timestamp = env.ledger().timestamp(); members.set( @@ -857,7 +858,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("OWNER")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); if caller != owner { panic!("Only Owner can remove family members"); @@ -872,7 +873,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); members.remove(member.clone()); env.storage() @@ -888,7 +889,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("PEND_TXS")) - .expect("Pending transactions map not initialized"); + .unwrap_or_else(|| panic!("Pending transactions map not initialized")); pending_txs.get(tx_id) } @@ -902,7 +903,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); members.get(member) } @@ -911,7 +912,7 @@ impl FamilyWallet { env.storage() .instance() .get(&symbol_short!("OWNER")) - .expect("Wallet not initialized") + .unwrap_or_else(|| panic!("Wallet not initialized")) } pub fn get_emergency_config(env: Env) -> Option { @@ -1109,7 +1110,7 @@ impl FamilyWallet { env.storage() .instance() .get(&symbol_short!("OWNER")) - .expect("Wallet not initialized") + .unwrap_or_else(|| panic!("Wallet not initialized")) }); if admin != caller { panic!("Only pause admin can pause"); @@ -1128,7 +1129,7 @@ impl FamilyWallet { env.storage() .instance() .get(&symbol_short!("OWNER")) - .expect("Wallet not initialized") + .unwrap_or_else(|| panic!("Wallet not initialized")) }); if admin != caller { panic!("Only pause admin can unpause"); @@ -1180,7 +1181,7 @@ impl FamilyWallet { env.storage() .instance() .get(&symbol_short!("OWNER")) - .expect("Wallet not initialized") + .unwrap_or_else(|| panic!("Wallet not initialized")) }); if admin != caller { panic!("Only upgrade admin can set version"); @@ -1212,7 +1213,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); let timestamp = env.ledger().timestamp(); let mut count = 0u32; for item in members.iter() { @@ -1251,7 +1252,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("OWNER")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); if caller != owner { panic!("Only Owner can remove members"); } @@ -1264,7 +1265,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); let mut count = 0u32; for addr in addresses.iter() { if addr.clone() == owner { @@ -1320,7 +1321,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("EM_CONF")) - .expect("Emergency config not set"); + .unwrap_or_else(|| panic!("Emergency config not set")); if amount > config.max_amount { panic!("Emergency amount exceeds maximum allowed"); @@ -1398,7 +1399,7 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); + .unwrap_or_else(|| panic!("Wallet not initialized")); if let Some(mut member_data) = members.get(member.clone()) { member_data.role = *new_role; @@ -1499,8 +1500,8 @@ impl FamilyWallet { .storage() .instance() .get(&symbol_short!("MEMBERS")) - .expect("Wallet not initialized"); - let member = members.get(caller.clone()).expect("Not a family member"); + .unwrap_or_else(|| panic!("Wallet not initialized")); + let member = members.get(caller.clone()).unwrap_or_else(|| panic!("Not a family member")); if Self::role_has_expired(env, caller) { panic!("Role has expired"); } @@ -1533,7 +1534,7 @@ impl FamilyWallet { let mut v = Vec::new(env); let start = n - MAX_ACCESS_AUDIT_ENTRIES; for i in start..n { - v.push_back(entries.get(i).unwrap()); + v.push_back(entries.get(i).unwrap_or_else(|| panic!("Item not found"))); } entries = v; } diff --git a/insurance/src/lib.rs b/insurance/src/lib.rs index 3c6d903..1d5068f 100644 --- a/insurance/src/lib.rs +++ b/insurance/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))] use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, symbol_short, Address, Env, Map, String, Symbol, Vec, @@ -242,6 +243,7 @@ impl Insurance { } pub fn pause(env: Env, caller: Address) -> Result<(), InsuranceError> { caller.require_auth(); + let admin = Self::get_pause_admin(&env).unwrap_or_else(|| panic!("No pause admin set")); let admin = Self::get_pause_admin(&env).ok_or(InsuranceError::Unauthorized)?; if admin != caller { return Err(InsuranceError::Unauthorized); @@ -255,6 +257,7 @@ impl Insurance { } pub fn unpause(env: Env, caller: Address) -> Result<(), InsuranceError> { caller.require_auth(); + let admin = Self::get_pause_admin(&env).unwrap_or_else(|| panic!("No pause admin set")); let admin = Self::get_pause_admin(&env).ok_or(InsuranceError::Unauthorized)?; if admin != caller { return Err(InsuranceError::Unauthorized); @@ -275,7 +278,7 @@ impl Insurance { } pub fn pause_function(env: Env, caller: Address, func: Symbol) -> Result<(), InsuranceError> { caller.require_auth(); - let admin = Self::get_pause_admin(&env).expect("No pause admin set"); + let admin = Self::get_pause_admin(&env).unwrap_or_else(|| panic!("No pause admin set")); if admin != caller { return Err(InsuranceError::Unauthorized); } @@ -292,7 +295,7 @@ impl Insurance { } pub fn unpause_function(env: Env, caller: Address, func: Symbol) -> Result<(), InsuranceError> { caller.require_auth(); - let admin = Self::get_pause_admin(&env).expect("No pause admin set"); + let admin = Self::get_pause_admin(&env).unwrap_or_else(|| panic!("No pause admin set")); if admin != caller { return Err(InsuranceError::Unauthorized); } @@ -355,7 +358,10 @@ impl Insurance { } pub fn set_version(env: Env, caller: Address, new_version: u32) -> Result<(), InsuranceError> { caller.require_auth(); - let admin = Self::get_upgrade_admin(&env).expect("No upgrade admin set"); + let admin = match Self::get_upgrade_admin(&env) { + Some(a) => a, + None => panic!("No upgrade admin set"), + }; if admin != caller { return Err(InsuranceError::Unauthorized); } @@ -879,6 +885,7 @@ impl Insurance { let current_time = env.ledger().timestamp(); let mut paid_count = 0; for id in policy_ids.iter() { + let mut policy = policies.get(id).unwrap_or_else(|| panic!("Policy not found")); let mut policy = policies_map.get(id).unwrap(); policy.next_payment_date = current_time + (30 * 86400); let event = PremiumPaidEvent { @@ -1001,6 +1008,7 @@ impl Insurance { .get(&symbol_short!("POLICIES")) .unwrap_or_else(|| Map::new(&env)); + let mut policy = policies.get(policy_id).unwrap_or_else(|| panic!("Policy not found")); let mut policy = policies .get(policy_id) .ok_or(InsuranceError::PolicyNotFound)?; @@ -1151,6 +1159,7 @@ impl Insurance { .get(&symbol_short!("POLICIES")) .unwrap_or_else(|| Map::new(&env)); + let mut policy = policies.get(policy_id).unwrap_or_else(|| panic!("Policy not found")); let mut policy = policies .get(policy_id) .ok_or(InsuranceError::PolicyNotFound)?; @@ -1255,6 +1264,7 @@ impl Insurance { .get(&symbol_short!("PREM_SCH")) .unwrap_or_else(|| Map::new(&env)); + let mut schedule = schedules.get(schedule_id).unwrap_or_else(|| panic!("Schedule not found")); let mut schedule = schedules .get(schedule_id) .ok_or(InsuranceError::PolicyNotFound)?; @@ -1297,6 +1307,7 @@ impl Insurance { .get(&symbol_short!("PREM_SCH")) .unwrap_or_else(|| Map::new(&env)); + let mut schedule = schedules.get(schedule_id).unwrap_or_else(|| panic!("Schedule not found")); let mut schedule = schedules .get(schedule_id) .ok_or(InsuranceError::PolicyNotFound)?; diff --git a/remittance_split/src/lib.rs b/remittance_split/src/lib.rs index f253902..0bb6c62 100644 --- a/remittance_split/src/lib.rs +++ b/remittance_split/src/lib.rs @@ -1,4 +1,6 @@ #![no_std] +#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))] +mod test; // test module declared above use soroban_sdk::{ @@ -726,9 +728,18 @@ impl RemittanceSplit { } let split = Self::get_split(env); - let s0 = split.get(0).unwrap() as i128; - let s1 = split.get(1).unwrap() as i128; - let s2 = split.get(2).unwrap() as i128; + let s0 = match split.get(0) { + Some(v) => v as i128, + None => return Err(RemittanceSplitError::Overflow), + }; + let s1 = match split.get(1) { + Some(v) => v as i128, + None => return Err(RemittanceSplitError::Overflow), + }; + let s2 = match split.get(2) { + Some(v) => v as i128, + None => return Err(RemittanceSplitError::Overflow), + }; let spending = total_amount .checked_mul(s0) diff --git a/reporting/src/lib.rs b/reporting/src/lib.rs index 6fb213e..4617025 100644 --- a/reporting/src/lib.rs +++ b/reporting/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))] use soroban_sdk::{ contract, contractclient, contractimpl, contracttype, symbol_short, Address, Env, Map, Vec, }; @@ -393,7 +394,7 @@ impl ReportingContract { .storage() .instance() .get(&symbol_short!("ADDRS")) - .expect("Contract addresses not configured"); + .unwrap_or_else(|| panic!("Contract addresses not configured")); let split_client = RemittanceSplitClient::new(&env, &addresses.remittance_split); let split_percentages = split_client.get_split(); @@ -435,7 +436,7 @@ impl ReportingContract { .storage() .instance() .get(&symbol_short!("ADDRS")) - .expect("Contract addresses not configured"); + .unwrap_or_else(|| panic!("Contract addresses not configured")); let savings_client = SavingsGoalsClient::new(&env, &addresses.savings_goals); let goals = savings_client.get_all_goals(&user); @@ -481,7 +482,7 @@ impl ReportingContract { .storage() .instance() .get(&symbol_short!("ADDRS")) - .expect("Contract addresses not configured"); + .unwrap_or_else(|| panic!("Contract addresses not configured")); let bill_client = BillPaymentsClient::new(&env, &addresses.bill_payments); let all_bills = bill_client.get_all_bills(); @@ -552,7 +553,7 @@ impl ReportingContract { .storage() .instance() .get(&symbol_short!("ADDRS")) - .expect("Contract addresses not configured"); + .unwrap_or_else(|| panic!("Contract addresses not configured")); let insurance_client = InsuranceClient::new(&env, &addresses.insurance); let policy_page = insurance_client.get_active_policies(&user, &0, &50); @@ -590,7 +591,7 @@ impl ReportingContract { .storage() .instance() .get(&symbol_short!("ADDRS")) - .expect("Contract addresses not configured"); + .unwrap_or_else(|| panic!("Contract addresses not configured")); // Savings score (0-40 points) let savings_client = SavingsGoalsClient::new(&env, &addresses.savings_goals); @@ -779,7 +780,7 @@ impl ReportingContract { .storage() .instance() .get(&symbol_short!("ADMIN")) - .expect("Contract not initialized"); + .unwrap_or_else(|| panic!("Contract not initialized")); if caller != admin { panic!("Only admin can archive reports"); @@ -880,7 +881,7 @@ impl ReportingContract { .storage() .instance() .get(&symbol_short!("ADMIN")) - .expect("Contract not initialized"); + .unwrap_or_else(|| panic!("Contract not initialized")); if caller != admin { panic!("Only admin can cleanup reports"); diff --git a/savings_goals/src/lib.rs b/savings_goals/src/lib.rs index aae7fec..90857ed 100644 --- a/savings_goals/src/lib.rs +++ b/savings_goals/src/lib.rs @@ -1,4 +1,5 @@ #![no_std] +#![cfg_attr(not(test), deny(clippy::unwrap_used, clippy::expect_used))] use soroban_sdk::{ contract, contracterror, contractimpl, contracttype, symbol_short, Address, Env, Map, String, Symbol, Vec, @@ -295,7 +296,7 @@ impl SavingsGoalContract { pub fn pause(env: Env, caller: Address) { caller.require_auth(); - let admin = Self::get_pause_admin(&env).expect("No pause admin set"); + let admin = Self::get_pause_admin(&env).ok_or(SavingsGoalsError::Unauthorized).unwrap(); if admin != caller { panic!("Unauthorized"); } @@ -308,7 +309,7 @@ impl SavingsGoalContract { pub fn unpause(env: Env, caller: Address) { caller.require_auth(); - let admin = Self::get_pause_admin(&env).expect("No pause admin set"); + let admin = Self::get_pause_admin(&env).ok_or(SavingsGoalsError::Unauthorized).unwrap(); if admin != caller { panic!("Unauthorized"); } @@ -328,7 +329,7 @@ impl SavingsGoalContract { pub fn pause_function(env: Env, caller: Address, func: Symbol) { caller.require_auth(); - let admin = Self::get_pause_admin(&env).expect("No pause admin set"); + let admin = Self::get_pause_admin(&env).ok_or(SavingsGoalsError::Unauthorized).unwrap(); if admin != caller { panic!("Unauthorized"); } @@ -345,7 +346,7 @@ impl SavingsGoalContract { pub fn unpause_function(env: Env, caller: Address, func: Symbol) { caller.require_auth(); - let admin = Self::get_pause_admin(&env).expect("No pause admin set"); + let admin = Self::get_pause_admin(&env).ok_or(SavingsGoalsError::Unauthorized).unwrap(); if admin != caller { panic!("Unauthorized"); } @@ -394,7 +395,10 @@ impl SavingsGoalContract { pub fn set_version(env: Env, caller: Address, new_version: u32) { caller.require_auth(); - let admin = Self::get_upgrade_admin(&env).expect("No upgrade admin set"); + let admin = match Self::get_upgrade_admin(&env) { + Some(a) => a, + None => panic!("No upgrade admin set"), + }; if admin != caller { panic!("Unauthorized"); } @@ -705,7 +709,10 @@ impl SavingsGoalContract { if item.amount <= 0 { panic!("Amount must be positive"); } - let goal = goals_map.get(item.goal_id).expect("Goal not found"); + let goal = match goals_map.get(item.goal_id) { + Some(g) => g, + None => panic!("Goal not found"), + }; if goal.owner != caller { panic!("Not owner of all goals"); } @@ -718,14 +725,19 @@ impl SavingsGoalContract { .unwrap_or_else(|| Map::new(&env)); let mut count = 0u32; for item in contributions.iter() { - let mut goal = goals.get(item.goal_id).expect("Goal not found"); + let mut goal = match goals.get(item.goal_id) { + Some(g) => g, + None => panic!("Goal not found"), + }; if goal.owner != caller { panic!("Batch validation failed"); } - goal.current_amount = goal + goal.current_amount = match goal .current_amount - .checked_add(item.amount) - .expect("overflow"); + .checked_add(item.amount) { + Some(v) => v, + None => panic!("overflow"), + }; let new_total = goal.current_amount; let was_completed = new_total >= goal.target_amount; let previously_completed = (new_total - item.amount) >= goal.target_amount; @@ -1144,7 +1156,10 @@ impl SavingsGoalContract { fn increment_nonce(env: &Env, address: &Address) { let current = Self::get_nonce(env.clone(), address.clone()); - let next = current.checked_add(1).expect("nonce overflow"); + let next = match current.checked_add(1) { + Some(v) => v, + None => panic!("nonce overflow"), + }; let mut nonces: Map = env .storage() .instance() @@ -1282,7 +1297,10 @@ impl SavingsGoalContract { .get(&symbol_short!("GOALS")) .unwrap_or_else(|| Map::new(&env)); - let goal = goals.get(goal_id).expect("Goal not found"); + let goal = match goals.get(goal_id) { + Some(g) => g, + None => panic!("Goal not found"), + }; if goal.owner != owner { panic!("Only the goal owner can create schedules"); @@ -1445,10 +1463,12 @@ impl SavingsGoalContract { } if let Some(mut goal) = goals.get(schedule.goal_id) { - goal.current_amount = goal + goal.current_amount = match goal .current_amount - .checked_add(schedule.amount) - .expect("overflow"); + .checked_add(schedule.amount) { + Some(v) => v, + None => panic!("overflow"), + }; let is_completed = goal.current_amount >= goal.target_amount; goals.set(schedule.goal_id, goal.clone());