@@ -177,23 +177,23 @@ pub struct UserPredictionDetail {
177177#[ derive( Clone ) ]
178178pub enum DataKey {
179179 Pool ( u64 ) ,
180- Prediction ( Address , u64 ) ,
181- PoolIdCounter ,
182- HasClaimed ( Address , u64 ) ,
183- OutcomeStake ( u64 , u32 ) ,
180+ Pred ( Address , u64 ) ,
181+ PoolIdCtr ,
182+ Claimed ( Address , u64 ) ,
183+ OutStake ( u64 , u32 ) ,
184184 /// Optimized storage for markets with many outcomes (e.g., 32+ teams).
185185 /// Stores all outcome stakes as a single Vec<i128> to reduce storage reads.
186- OutcomeStakes ( u64 ) ,
187- UserPredictionCount ( Address ) ,
188- UserPredictionIndex ( Address , u32 ) ,
186+ OutStakes ( u64 ) ,
187+ UsrPrdCnt ( Address ) ,
188+ UsrPrdIdx ( Address , u32 ) ,
189189 Config ,
190190 Paused ,
191- ReentrancyGuard ,
192- CategoryPoolCount ( Symbol ) ,
193- CategoryPoolIndex ( Symbol , u32 ) ,
191+ RentGuard ,
192+ CatPoolCt ( Symbol ) ,
193+ CatPoolIx ( Symbol , u32 ) ,
194194 /// Token whitelist: TokenWhitelist(token_address) -> true if allowed for betting.
195- TokenWhitelist ( Address ) ,
196- ParticipantsCount ( u64 ) ,
195+ TokenWl ( Address ) ,
196+ PartCnt ( u64 ) ,
197197}
198198
199199#[ contracttype]
@@ -594,15 +594,15 @@ impl PredifiContract {
594594 /// Get outcome stakes for a pool using optimized batch storage.
595595 /// Falls back to individual storage keys for backward compatibility.
596596 fn get_outcome_stakes ( env : & Env , pool_id : u64 , options_count : u32 ) -> Vec < i128 > {
597- let key = DataKey :: OutcomeStakes ( pool_id) ;
597+ let key = DataKey :: OutStakes ( pool_id) ;
598598 if let Some ( stakes) = env. storage ( ) . persistent ( ) . get ( & key) {
599599 Self :: extend_persistent ( env, & key) ;
600600 stakes
601601 } else {
602602 // Fallback: reconstruct from individual outcome stakes (backward compatibility)
603603 let mut stakes = Vec :: new ( env) ;
604604 for i in 0 ..options_count {
605- let outcome_key = DataKey :: OutcomeStake ( pool_id, i) ;
605+ let outcome_key = DataKey :: OutStake ( pool_id, i) ;
606606 let stake: i128 = env. storage ( ) . persistent ( ) . get ( & outcome_key) . unwrap_or ( 0 ) ;
607607 stakes. push_back ( stake) ;
608608 }
@@ -624,12 +624,12 @@ impl PredifiContract {
624624 stakes. set ( outcome, current + amount) ;
625625
626626 // Store using optimized batch key
627- let key = DataKey :: OutcomeStakes ( pool_id) ;
627+ let key = DataKey :: OutStakes ( pool_id) ;
628628 env. storage ( ) . persistent ( ) . set ( & key, & stakes) ;
629629 Self :: extend_persistent ( env, & key) ;
630630
631631 // Also update individual key for backward compatibility
632- let outcome_key = DataKey :: OutcomeStake ( pool_id, outcome) ;
632+ let outcome_key = DataKey :: OutStake ( pool_id, outcome) ;
633633 env. storage ( )
634634 . persistent ( )
635635 . set ( & outcome_key, & ( current + amount) ) ;
@@ -695,20 +695,20 @@ impl PredifiContract {
695695 }
696696
697697 fn enter_reentrancy_guard ( env : & Env ) {
698- let key = DataKey :: ReentrancyGuard ;
698+ let key = DataKey :: RentGuard ;
699699 if env. storage ( ) . temporary ( ) . has ( & key) {
700700 panic ! ( "Reentrancy detected" ) ;
701701 }
702702 env. storage ( ) . temporary ( ) . set ( & key, & true ) ;
703703 }
704704
705705 fn exit_reentrancy_guard ( env : & Env ) {
706- env. storage ( ) . temporary ( ) . remove ( & DataKey :: ReentrancyGuard ) ;
706+ env. storage ( ) . temporary ( ) . remove ( & DataKey :: RentGuard ) ;
707707 }
708708
709709 /// Returns true if the token is on the allowed betting whitelist.
710710 fn is_token_whitelisted ( env : & Env , token : & Address ) -> bool {
711- let key = DataKey :: TokenWhitelist ( token. clone ( ) ) ;
711+ let key = DataKey :: TokenWl ( token. clone ( ) ) ;
712712 let allowed = env. storage ( ) . persistent ( ) . get ( & key) . unwrap_or ( false ) ;
713713 if env. storage ( ) . persistent ( ) . has ( & key) {
714714 Self :: extend_persistent ( env, & key) ;
@@ -734,7 +734,7 @@ impl PredifiContract {
734734 resolution_delay,
735735 } ;
736736 env. storage ( ) . instance ( ) . set ( & DataKey :: Config , & config) ;
737- env. storage ( ) . instance ( ) . set ( & DataKey :: PoolIdCounter , & 0u64 ) ;
737+ env. storage ( ) . instance ( ) . set ( & DataKey :: PoolIdCtr , & 0u64 ) ;
738738 Self :: extend_instance ( & env) ;
739739
740740 InitEvent {
@@ -876,7 +876,7 @@ impl PredifiContract {
876876 . publish ( & env) ;
877877 return Err ( e) ;
878878 }
879- let key = DataKey :: TokenWhitelist ( token. clone ( ) ) ;
879+ let key = DataKey :: TokenWl ( token. clone ( ) ) ;
880880 env. storage ( ) . persistent ( ) . set ( & key, & true ) ;
881881 Self :: extend_persistent ( & env, & key) ;
882882
@@ -905,7 +905,7 @@ impl PredifiContract {
905905 . publish ( & env) ;
906906 return Err ( e) ;
907907 }
908- let key = DataKey :: TokenWhitelist ( token. clone ( ) ) ;
908+ let key = DataKey :: TokenWl ( token. clone ( ) ) ;
909909 env. storage ( ) . persistent ( ) . remove ( & key) ;
910910
911911 TokenWhitelistRemovedEvent {
@@ -1109,7 +1109,7 @@ impl PredifiContract {
11091109 let pool_id: u64 = env
11101110 . storage ( )
11111111 . instance ( )
1112- . get ( & DataKey :: PoolIdCounter )
1112+ . get ( & DataKey :: PoolIdCtr )
11131113 . unwrap_or ( 0 ) ;
11141114 Self :: extend_instance ( & env) ;
11151115
@@ -1135,7 +1135,7 @@ impl PredifiContract {
11351135 env. storage ( ) . persistent ( ) . set ( & pool_key, & pool) ;
11361136 Self :: extend_persistent ( & env, & pool_key) ;
11371137
1138- let pc_key = DataKey :: ParticipantsCount ( pool_id) ;
1138+ let pc_key = DataKey :: PartCnt ( pool_id) ;
11391139 env. storage ( ) . persistent ( ) . set ( & pc_key, & 0u32 ) ;
11401140 Self :: extend_persistent ( & env, & pc_key) ;
11411141
@@ -1146,14 +1146,14 @@ impl PredifiContract {
11461146 }
11471147
11481148 // Update category index
1149- let category_count_key = DataKey :: CategoryPoolCount ( category. clone ( ) ) ;
1149+ let category_count_key = DataKey :: CatPoolCt ( category. clone ( ) ) ;
11501150 let category_count: u32 = env
11511151 . storage ( )
11521152 . persistent ( )
11531153 . get ( & category_count_key)
11541154 . unwrap_or ( 0 ) ;
11551155
1156- let category_index_key = DataKey :: CategoryPoolIndex ( category. clone ( ) , category_count) ;
1156+ let category_index_key = DataKey :: CatPoolIx ( category. clone ( ) , category_count) ;
11571157 env. storage ( )
11581158 . persistent ( )
11591159 . set ( & category_index_key, & pool_id) ;
@@ -1166,7 +1166,7 @@ impl PredifiContract {
11661166
11671167 env. storage ( )
11681168 . instance ( )
1169- . set ( & DataKey :: PoolIdCounter , & ( pool_id + 1 ) ) ;
1169+ . set ( & DataKey :: PoolIdCtr , & ( pool_id + 1 ) ) ;
11701170 Self :: extend_instance ( & env) ;
11711171
11721172 PoolCreatedEvent {
@@ -1407,17 +1407,37 @@ impl PredifiContract {
14071407 ) ;
14081408 }
14091409
1410- let pred_key = DataKey :: Prediction ( user. clone ( ) , pool_id) ;
1411- if !env. storage ( ) . persistent ( ) . has ( & pred_key) {
1412- let pc_key = DataKey :: ParticipantsCount ( pool_id) ;
1410+ let pred_key = DataKey :: Pred ( user. clone ( ) , pool_id) ;
1411+ if let Some ( mut existing_pred) = env. storage ( ) . persistent ( ) . get :: < _ , Prediction > ( & pred_key)
1412+ {
1413+ assert ! (
1414+ existing_pred. outcome == outcome,
1415+ "Cannot change prediction outcome"
1416+ ) ;
1417+ existing_pred. amount = existing_pred. amount . checked_add ( amount) . expect ( "overflow" ) ;
1418+ env. storage ( ) . persistent ( ) . set ( & pred_key, & existing_pred) ;
1419+ Self :: extend_persistent ( & env, & pred_key) ;
1420+ } else {
1421+ env. storage ( )
1422+ . persistent ( )
1423+ . set ( & pred_key, & Prediction { amount, outcome } ) ;
1424+ Self :: extend_persistent ( & env, & pred_key) ;
1425+
1426+ let pc_key = DataKey :: PartCnt ( pool_id) ;
14131427 let pc: u32 = env. storage ( ) . persistent ( ) . get ( & pc_key) . unwrap_or ( 0 ) ;
14141428 env. storage ( ) . persistent ( ) . set ( & pc_key, & ( pc + 1 ) ) ;
14151429 Self :: extend_persistent ( & env, & pc_key) ;
1430+
1431+ let count_key = DataKey :: UsrPrdCnt ( user. clone ( ) ) ;
1432+ let count: u32 = env. storage ( ) . persistent ( ) . get ( & count_key) . unwrap_or ( 0 ) ;
1433+
1434+ let index_key = DataKey :: UsrPrdIdx ( user. clone ( ) , count) ;
1435+ env. storage ( ) . persistent ( ) . set ( & index_key, & pool_id) ;
1436+ Self :: extend_persistent ( & env, & index_key) ;
1437+
1438+ env. storage ( ) . persistent ( ) . set ( & count_key, & ( count + 1 ) ) ;
1439+ Self :: extend_persistent ( & env, & count_key) ;
14161440 }
1417- env. storage ( )
1418- . persistent ( )
1419- . set ( & pred_key, & Prediction { amount, outcome } ) ;
1420- Self :: extend_persistent ( & env, & pred_key) ;
14211441
14221442 // Update total stake (INV-1)
14231443 pool. total_stake = pool. total_stake . checked_add ( amount) . expect ( "overflow" ) ;
@@ -1428,16 +1448,6 @@ impl PredifiContract {
14281448 let _stakes =
14291449 Self :: update_outcome_stake ( & env, pool_id, outcome, amount, pool. options_count ) ;
14301450
1431- let count_key = DataKey :: UserPredictionCount ( user. clone ( ) ) ;
1432- let count: u32 = env. storage ( ) . persistent ( ) . get ( & count_key) . unwrap_or ( 0 ) ;
1433-
1434- let index_key = DataKey :: UserPredictionIndex ( user. clone ( ) , count) ;
1435- env. storage ( ) . persistent ( ) . set ( & index_key, & pool_id) ;
1436- Self :: extend_persistent ( & env, & index_key) ;
1437-
1438- env. storage ( ) . persistent ( ) . set ( & count_key, & ( count + 1 ) ) ;
1439- Self :: extend_persistent ( & env, & count_key) ;
1440-
14411451 // --- INTERACTIONS ---
14421452
14431453 let token_client = token:: Client :: new ( & env, & pool. token ) ;
@@ -1501,7 +1511,7 @@ impl PredifiContract {
15011511 return Err ( PredifiError :: PoolNotResolved ) ;
15021512 }
15031513
1504- let claimed_key = DataKey :: HasClaimed ( user. clone ( ) , pool_id) ;
1514+ let claimed_key = DataKey :: Claimed ( user. clone ( ) , pool_id) ;
15051515 if env. storage ( ) . persistent ( ) . has ( & claimed_key) {
15061516 // 🔴 HIGH ALERT: repeated claim attempt on an already-claimed pool.
15071517 SuspiciousDoubleClaimEvent {
@@ -1516,7 +1526,7 @@ impl PredifiContract {
15161526
15171527 // --- CHECKS ---
15181528
1519- let pred_key = DataKey :: Prediction ( user. clone ( ) , pool_id) ;
1529+ let pred_key = DataKey :: Pred ( user. clone ( ) , pool_id) ;
15201530 let prediction: Option < Prediction > = env. storage ( ) . persistent ( ) . get ( & pred_key) ;
15211531
15221532 if env. storage ( ) . persistent ( ) . has ( & pred_key) {
@@ -1645,7 +1655,7 @@ impl PredifiContract {
16451655 offset : u32 ,
16461656 limit : u32 ,
16471657 ) -> Vec < UserPredictionDetail > {
1648- let count_key = DataKey :: UserPredictionCount ( user. clone ( ) ) ;
1658+ let count_key = DataKey :: UsrPrdCnt ( user. clone ( ) ) ;
16491659 let count: u32 = env. storage ( ) . persistent ( ) . get ( & count_key) . unwrap_or ( 0 ) ;
16501660 if env. storage ( ) . persistent ( ) . has ( & count_key) {
16511661 Self :: extend_persistent ( & env, & count_key) ;
@@ -1660,15 +1670,15 @@ impl PredifiContract {
16601670 let end = core:: cmp:: min ( offset. saturating_add ( limit) , count) ;
16611671
16621672 for i in offset..end {
1663- let index_key = DataKey :: UserPredictionIndex ( user. clone ( ) , i) ;
1673+ let index_key = DataKey :: UsrPrdIdx ( user. clone ( ) , i) ;
16641674 let pool_id: u64 = env
16651675 . storage ( )
16661676 . persistent ( )
16671677 . get ( & index_key)
16681678 . expect ( "index not found" ) ;
16691679 Self :: extend_persistent ( & env, & index_key) ;
16701680
1671- let pred_key = DataKey :: Prediction ( user. clone ( ) , pool_id) ;
1681+ let pred_key = DataKey :: Pred ( user. clone ( ) , pool_id) ;
16721682 let prediction: Prediction = env
16731683 . storage ( )
16741684 . persistent ( )
@@ -1750,7 +1760,7 @@ impl PredifiContract {
17501760
17511761 /// Get a paginated list of pool IDs by category.
17521762 pub fn get_pools_by_category ( env : Env , category : Symbol , offset : u32 , limit : u32 ) -> Vec < u64 > {
1753- let count_key = DataKey :: CategoryPoolCount ( category. clone ( ) ) ;
1763+ let count_key = DataKey :: CatPoolCt ( category. clone ( ) ) ;
17541764 let count: u32 = env. storage ( ) . persistent ( ) . get ( & count_key) . unwrap_or ( 0 ) ;
17551765 if env. storage ( ) . persistent ( ) . has ( & count_key) {
17561766 Self :: extend_persistent ( & env, & count_key) ;
@@ -1767,7 +1777,7 @@ impl PredifiContract {
17671777
17681778 for i in 0 ..num_to_take {
17691779 let index = start_index. saturating_sub ( i) ;
1770- let index_key = DataKey :: CategoryPoolIndex ( category. clone ( ) , index) ;
1780+ let index_key = DataKey :: CatPoolIx ( category. clone ( ) , index) ;
17711781 let pool_id: u64 = env
17721782 . storage ( )
17731783 . persistent ( )
@@ -1793,7 +1803,7 @@ impl PredifiContract {
17931803
17941804 let stakes = Self :: get_outcome_stakes ( & env, pool_id, pool. options_count ) ;
17951805
1796- let pc_key = DataKey :: ParticipantsCount ( pool_id) ;
1806+ let pc_key = DataKey :: PartCnt ( pool_id) ;
17971807 let participants_count: u32 = env. storage ( ) . persistent ( ) . get ( & pc_key) . unwrap_or ( 0 ) ;
17981808 if env. storage ( ) . persistent ( ) . has ( & pc_key) {
17991809 Self :: extend_persistent ( & env, & pc_key) ;
0 commit comments