Skip to content

Commit 201bac1

Browse files
feat: add file for gas optimization (#379)
* feat: add file for gas optimization * feat: adjust files and fix details
1 parent 7dd150b commit 201bac1

File tree

3 files changed

+98
-88
lines changed

3 files changed

+98
-88
lines changed

contract/contracts/predifi-contract/src/lib.rs

Lines changed: 62 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -177,23 +177,23 @@ pub struct UserPredictionDetail {
177177
#[derive(Clone)]
178178
pub 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);

contract/contracts/predifi-contract/src/price_feed_simple.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ impl PriceFeedAdapter {
1616
admin.require_auth();
1717

1818
// Store oracle config using existing storage keys
19-
let config_key = DataKey::TokenWhitelist(pyth_contract.clone());
19+
let config_key = DataKey::TokenWl(pyth_contract.clone());
2020

2121
// Store config values as tuple
2222
env.storage()
@@ -49,7 +49,7 @@ impl PriceFeedAdapter {
4949

5050
// Store price data using existing storage pattern
5151
// Use OutcomeStake with a fixed pool_id for price data
52-
let price_key = DataKey::OutcomeStake(999999, 0); // Fixed pool_id for price feeds
52+
let price_key = DataKey::OutStake(999999, 0); // Fixed pool_id for price feeds
5353
env.storage().persistent().set(
5454
&price_key,
5555
&(feed_pair, price, confidence, timestamp, expires_at),
@@ -60,7 +60,7 @@ impl PriceFeedAdapter {
6060

6161
/// Get current price feed data
6262
pub fn get_price_feed(env: &Env, feed_pair: &Symbol) -> Option<(i128, i128, u64, u64)> {
63-
let price_key = DataKey::OutcomeStake(999999, 0); // Fixed pool_id for price feeds
63+
let price_key = DataKey::OutStake(999999, 0); // Fixed pool_id for price feeds
6464

6565
// Get all price data and find matching feed
6666
if let Some(price_data) = env
@@ -110,7 +110,7 @@ impl PriceFeedAdapter {
110110
tolerance_bps: u32,
111111
) -> Result<(), PredifiError> {
112112
// Store condition using existing storage pattern
113-
let condition_key = DataKey::OutcomeStake(pool_id, 1);
113+
let condition_key = DataKey::OutStake(pool_id, 1);
114114
env.storage().persistent().set(
115115
&condition_key,
116116
&(feed_pair, target_price, operator, tolerance_bps),
@@ -121,7 +121,7 @@ impl PriceFeedAdapter {
121121

122122
/// Get price condition for a pool
123123
pub fn get_price_condition(env: &Env, pool_id: u64) -> Option<(Symbol, i128, u32, u32)> {
124-
let condition_key = DataKey::OutcomeStake(pool_id, 1);
124+
let condition_key = DataKey::OutStake(pool_id, 1);
125125
env.storage().persistent().get(&condition_key)
126126
}
127127

@@ -183,7 +183,7 @@ impl PriceFeedAdapter {
183183

184184
/// Get oracle configuration
185185
pub fn get_oracle_config(env: &Env, pyth_contract: &Address) -> Option<(u64, u32)> {
186-
let config_key = DataKey::TokenWhitelist(pyth_contract.clone());
186+
let config_key = DataKey::TokenWl(pyth_contract.clone());
187187
env.storage().persistent().get(&config_key)
188188
}
189189

0 commit comments

Comments
 (0)