From 3faa7ec6e19ec39d88f3cde4fba86fd3d0f465e3 Mon Sep 17 00:00:00 2001 From: oluwagbemiga Date: Sat, 31 Jan 2026 10:31:17 +0100 Subject: [PATCH] feat: implement user balance tracking and management - Updated distribute_payouts to credit user Internal Balance using BalanceStorage - Updated claim_winnings to credit Internal Balance instead of direct transfer - Fixed double-counting bug in distribute_payouts for bet stakes --- contracts/predictify-hybrid/src/lib.rs | 49 ++++++++++++++++---------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/contracts/predictify-hybrid/src/lib.rs b/contracts/predictify-hybrid/src/lib.rs index 7df78f12..72244bac 100644 --- a/contracts/predictify-hybrid/src/lib.rs +++ b/contracts/predictify-hybrid/src/lib.rs @@ -1072,8 +1072,13 @@ impl PredictifyHybrid { // Emit winnings claimed event EventEmitter::emit_winnings_claimed(&env, &market_id, &user, payout); - // Transfer tokens - match bets::BetUtils::unlock_funds(&env, &user, payout) { + // Credit tokens to user balance + match storage::BalanceStorage::add_balance( + &env, + &user, + &types::ReflectorAsset::Stellar, + payout, + ) { Ok(_) => {} Err(e) => panic_with_error!(env, e), } @@ -1841,6 +1846,11 @@ impl PredictifyHybrid { // Sum bet amounts for user in bettors.iter() { + // Avoid double counting if user is already in votes (legacy support) + if market.votes.contains_key(user.clone()) { + continue; + } + if let Some(bet) = bets::BetStorage::get_bet(&env, &market_id, &user) { if bet.outcome == *winning_outcome { winning_total += bet.amount; @@ -1884,6 +1894,15 @@ impl PredictifyHybrid { total_distributed = total_distributed .checked_add(payout) .ok_or(Error::InvalidInput)?; + + // Credit winnings to user balance + storage::BalanceStorage::add_balance( + &env, + &user, + &types::ReflectorAsset::Stellar, + payout, + )?; + EventEmitter::emit_winnings_claimed(&env, &market_id, &user, payout); } } @@ -1915,11 +1934,17 @@ impl PredictifyHybrid { bet.status = BetStatus::Won; let _ = bets::BetStorage::store_bet(&env, &bet); - EventEmitter::emit_winnings_claimed(&env, &market_id, &user, payout); - match bets::BetUtils::unlock_funds(&env, &user, payout) { + // Credit winnings to user balance instead of direct transfer + match storage::BalanceStorage::add_balance( + &env, + &user, + &types::ReflectorAsset::Stellar, + payout, + ) { Ok(_) => {} Err(e) => panic_with_error!(env, e), } + EventEmitter::emit_winnings_claimed(&env, &market_id, &user, payout); } } } else { @@ -2718,13 +2743,7 @@ impl PredictifyHybrid { env.storage().persistent().set(&market_id, &market); // Emit category update event - EventEmitter::emit_category_updated( - &env, - &market_id, - &old_category, - &category, - &admin, - ); + EventEmitter::emit_category_updated(&env, &market_id, &old_category, &category, &admin); Ok(()) } @@ -2843,13 +2862,7 @@ impl PredictifyHybrid { env.storage().persistent().set(&market_id, &market); // Emit tags update event - EventEmitter::emit_tags_updated( - &env, - &market_id, - &old_tags, - &tags, - &admin, - ); + EventEmitter::emit_tags_updated(&env, &market_id, &old_tags, &tags, &admin); Ok(()) }