diff --git a/contracts/predictify-hybrid/src/lib.rs b/contracts/predictify-hybrid/src/lib.rs index 13d00b1a..0aebae91 100644 --- a/contracts/predictify-hybrid/src/lib.rs +++ b/contracts/predictify-hybrid/src/lib.rs @@ -178,6 +178,14 @@ impl PredictifyHybrid { /// /// This function can only be called once. Any subsequent calls will panic with /// `Error::AlreadyInitialized` to prevent admin takeover attacks. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn initialize(env: Env, admin: Address, platform_fee_percentage: Option) { // Determine platform fee (default 2% if not specified) let fee_percentage = platform_fee_percentage.unwrap_or(DEFAULT_PLATFORM_FEE_PERCENTAGE); @@ -214,6 +222,14 @@ impl PredictifyHybrid { /// * `user` - The user depositing funds. /// * `asset` - The asset to deposit (e.g., XLM, BTC, ETH). /// * `amount` - The amount to deposit. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn deposit( env: Env, user: Address, @@ -230,6 +246,14 @@ impl PredictifyHybrid { /// * `user` - The user withdrawing funds. /// * `asset` - The asset to withdraw. /// * `amount` - The amount to withdraw. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn withdraw( env: Env, user: Address, @@ -245,6 +269,14 @@ impl PredictifyHybrid { /// * `env` - The environment. /// * `user` - The user to check. /// * `asset` - The asset to check. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_balance(env: Env, user: Address, asset: ReflectorAsset) -> Balance { storage::BalanceStorage::get_balance(&env, &user, &asset) } @@ -352,6 +384,14 @@ impl PredictifyHybrid { /// /// New markets are created in `MarketState::Active` state, allowing immediate voting. /// The market will automatically transition to `MarketState::Ended` when the duration expires. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn create_market( env: Env, admin: Address, @@ -464,6 +504,14 @@ impl PredictifyHybrid { /// Panics if: /// - Caller is not the contract admin /// - validation fails (invalid description, outcomes, or end time) + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn create_event( env: Env, admin: Address, @@ -554,6 +602,14 @@ impl PredictifyHybrid { /// # Returns /// /// Returns `Some(Event)` if found, or `None` otherwise. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_event(env: Env, event_id: Symbol) -> Option { crate::storage::EventManager::get_event(&env, &event_id).ok() } @@ -610,6 +666,14 @@ impl PredictifyHybrid { /// - Market must be in `Active` state /// - Current time must be before market end time /// - Market must not be cancelled or resolved + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn vote(env: Env, user: Address, market_id: Symbol, outcome: String, stake: i128) { user.require_auth(); @@ -783,6 +847,14 @@ impl PredictifyHybrid { /// 10_0000000, // 10 XLM /// ); /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn place_bet( env: Env, user: Address, @@ -855,6 +927,14 @@ impl PredictifyHybrid { /// /// let placed_bets = PredictifyHybrid::place_bets(env.clone(), user, bets); /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn place_bets( env: Env, user: Address, @@ -903,6 +983,14 @@ impl PredictifyHybrid { /// } /// } /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_bet(env: Env, market_id: Symbol, user: Address) -> Option { bets::BetManager::get_bet(&env, &market_id, &user) } @@ -937,6 +1025,14 @@ impl PredictifyHybrid { /// println!("User can place a bet"); /// } /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn has_user_bet(env: Env, market_id: Symbol, user: Address) -> bool { bets::BetManager::has_user_bet(&env, &market_id, &user) } @@ -968,6 +1064,14 @@ impl PredictifyHybrid { /// println!("Total locked: {} stroops", stats.total_amount_locked); /// println!("Unique bettors: {}", stats.unique_bettors); /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_market_bet_stats(env: Env, market_id: Symbol) -> crate::types::BetStats { bets::BetManager::get_market_bet_stats(&env, &market_id) } @@ -1064,6 +1168,10 @@ impl PredictifyHybrid { /// Err(e) => println!("Error: {:?}", e), /// } /// ``` + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn calculate_bet_payout(env: Env, market_id: Symbol, user: Address) -> Result { bets::BetManager::calculate_bet_payout(&env, &market_id, &user) } @@ -1098,6 +1206,14 @@ impl PredictifyHybrid { /// ); /// println!("Implied probability for 'Yes': {}%", prob); /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_implied_probability(env: Env, market_id: Symbol, outcome: String) -> i128 { bets::BetAnalytics::calculate_implied_probability(&env, &market_id, &outcome) } @@ -1133,6 +1249,14 @@ impl PredictifyHybrid { /// let actual_multiplier = multiplier as f64 / 100.0; /// println!("Payout multiplier for 'Yes': {:.2}x", actual_multiplier); /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_payout_multiplier(env: Env, market_id: Symbol, outcome: String) -> i128 { bets::BetAnalytics::calculate_payout_multiplier(&env, &market_id, &outcome) } @@ -1192,6 +1316,14 @@ impl PredictifyHybrid { /// - Market must be in `Resolved` state with a winning outcome set /// - User must have voted for the winning outcome /// - User must not have previously claimed winnings + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn claim_winnings(env: Env, user: Address, market_id: Symbol) { user.require_auth(); @@ -1361,6 +1493,14 @@ impl PredictifyHybrid { /// /// This is a read-only operation that doesn't modify contract state. /// It retrieves data from persistent storage with minimal computational overhead. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_market(env: Env, market_id: Symbol) -> Option { env.storage().persistent().get(&market_id) } @@ -1423,6 +1563,14 @@ impl PredictifyHybrid { /// /// This function requires admin privileges and should be used carefully. /// Manual resolutions should be transparent and follow established governance procedures. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn resolve_market_manual( env: Env, admin: Address, @@ -1561,6 +1709,14 @@ impl PredictifyHybrid { /// - Total pool is split proportionally among all winners /// - Each winner receives: (their_stake / total_winning_stakes) * total_pool * (1 - fee) /// - This ensures fair distribution even when outcomes are tied + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn resolve_market_with_ties( env: Env, admin: Address, @@ -1715,6 +1871,10 @@ impl PredictifyHybrid { /// - Market must exist and be past its end time /// - Market must not already have an oracle result /// - Oracle contract must be accessible and responsive + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn fetch_oracle_result( env: Env, market_id: Symbol, @@ -1896,6 +2056,14 @@ impl PredictifyHybrid { /// 3 /// ); /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn verify_result_with_retry( env: Env, caller: Address, @@ -1945,6 +2113,14 @@ impl PredictifyHybrid { /// } /// } /// ``` + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_verified_result(env: Env, market_id: Symbol) -> Option { oracles::OracleIntegrationManager::get_oracle_result(&env, &market_id) } @@ -1959,6 +2135,14 @@ impl PredictifyHybrid { /// # Returns /// /// Returns `bool` - `true` if verified, `false` otherwise + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn is_result_verified(env: Env, market_id: Symbol) -> bool { oracles::OracleIntegrationManager::is_result_verified(&env, &market_id) } @@ -1989,6 +2173,14 @@ impl PredictifyHybrid { /// - Automatic oracle verification has failed repeatedly /// - Oracle data is known to be incorrect /// - Emergency situations requiring immediate resolution + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn admin_override_verification( env: Env, admin: Address, @@ -2075,6 +2267,10 @@ impl PredictifyHybrid { /// - Winning outcome is set /// - Users can claim winnings /// - Market statistics are finalized + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn resolve_market(env: Env, market_id: Symbol) -> Result<(), Error> { // Use the resolution module to resolve the market let _resolution = resolution::MarketResolutionManager::resolve_market(&env, &market_id)?; @@ -2160,6 +2356,10 @@ impl PredictifyHybrid { /// This function performs read-only analytics calculations and may take /// longer for platforms with many resolved markets. Results may be cached /// for performance optimization. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_resolution_analytics(env: Env) -> Result { resolution::MarketResolutionAnalytics::calculate_resolution_analytics(&env) } @@ -2247,6 +2447,10 @@ impl PredictifyHybrid { /// This function performs calculations on market data and may have /// computational overhead for markets with many participants. Consider /// caching results for frequently accessed markets. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_market_analytics( env: Env, market_id: Symbol, @@ -2264,6 +2468,14 @@ impl PredictifyHybrid { } /// Dispute a market resolution + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn dispute_market( env: Env, user: Address, @@ -2276,6 +2488,14 @@ impl PredictifyHybrid { } /// Vote on a dispute + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn vote_on_dispute( env: Env, user: Address, @@ -2292,6 +2512,14 @@ impl PredictifyHybrid { } /// Resolve a dispute (admin only) + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn resolve_dispute( env: Env, admin: Address, @@ -2316,6 +2544,14 @@ impl PredictifyHybrid { } /// Collect fees from a market (admin only) + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn collect_fees(env: Env, admin: Address, market_id: Symbol) -> Result { admin.require_auth(); @@ -2389,6 +2625,10 @@ impl PredictifyHybrid { /// # Events /// /// This function emits `WinningsClaimedEvent` for each user who receives a payout. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. pub fn distribute_payouts(env: Env, market_id: Symbol) -> Result { let mut market: Market = env .storage() @@ -2588,12 +2828,28 @@ impl PredictifyHybrid { /// Mark a resolved or cancelled event (market) as archived. Admin only. /// Market must be in Resolved or Cancelled state. Returns InvalidState if not /// eligible, AlreadyClaimed if already archived. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn archive_event(env: Env, admin: Address, market_id: Symbol) -> Result<(), Error> { crate::event_archive::EventArchive::archive_event(&env, &admin, &market_id) } /// Query events by creation time range. Returns public metadata only (no votes/stakes). /// Paginated: cursor is start index, limit capped at 30. Returns (entries, next_cursor). + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn query_events_history( env: Env, from_ts: u64, @@ -2607,6 +2863,14 @@ impl PredictifyHybrid { } /// Query events by resolution status (e.g. Resolved, Cancelled). Paginated. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn query_events_by_status( env: Env, status: MarketState, @@ -2619,6 +2883,14 @@ impl PredictifyHybrid { } /// Query events by category (oracle feed_id). Paginated. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn query_events_by_category( env: Env, category: String, @@ -2671,6 +2943,14 @@ impl PredictifyHybrid { /// - Minimum fee: 0% (0 basis points) /// - Maximum fee: 10% (1000 basis points) /// - Default fee: 2% (200 basis points) + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn set_platform_fee(env: Env, admin: Address, fee_percentage: i128) -> Result<(), Error> { // Require authentication admin.require_auth(); @@ -2701,6 +2981,14 @@ impl PredictifyHybrid { /// Set global minimum and maximum bet limits (admin only). /// Applies to all events that do not have per-event limits. /// Rejects if min > max or outside absolute bounds (MIN_BET_AMOUNT..=MAX_BET_AMOUNT). + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn set_global_bet_limits( env: Env, admin: Address, @@ -2725,6 +3013,14 @@ impl PredictifyHybrid { /// Set per-event minimum and maximum bet limits (admin only). /// Overrides global limits for the given market. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn set_event_bet_limits( env: Env, admin: Address, @@ -2748,6 +3044,14 @@ impl PredictifyHybrid { } /// Get effective bet limits for a market (per-event if set, else global, else defaults). + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_effective_bet_limits(env: Env, market_id: Symbol) -> BetLimits { crate::bets::get_effective_bet_limits(&env, &market_id) } @@ -2757,6 +3061,14 @@ impl PredictifyHybrid { /// - `max_staleness_secs`: maximum allowed age in seconds. /// - `max_confidence_bps`: maximum confidence interval in basis points. /// Per-event overrides, if set, take precedence over this global config. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn set_oracle_val_cfg_global( env: Env, admin: Address, @@ -2784,6 +3096,14 @@ impl PredictifyHybrid { /// Set per-event oracle validation config (admin only). /// /// Overrides global validation settings for the given market. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn set_oracle_val_cfg_event( env: Env, admin: Address, @@ -2814,6 +3134,14 @@ impl PredictifyHybrid { } /// Get effective oracle validation config for a market. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_oracle_val_cfg_effective( env: Env, market_id: Symbol, @@ -2859,6 +3187,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Withdrawal failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn withdraw_collected_fees(env: Env, admin: Address, amount: i128) -> Result { admin.require_auth(); @@ -2974,6 +3310,10 @@ impl PredictifyHybrid { /// This function requires admin authentication and should be used carefully. /// Excessive extensions may affect user trust and market integrity. All /// extensions are logged with timestamps and reasons for transparency. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn extend_deadline( env: Env, admin: Address, @@ -3118,7 +3458,11 @@ impl PredictifyHybrid { /// This function requires admin authentication and validates that no user /// funds are at risk. Updates are only allowed before any betting activity /// to maintain fairness and transparency. - pub fn update_event_description( + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. + pub fn update_event_description( env: Env, admin: Address, market_id: Symbol, @@ -3255,6 +3599,10 @@ impl PredictifyHybrid { /// This function requires admin authentication and validates that no user /// funds are at risk. Updates are only allowed before any betting activity /// to maintain fairness and transparency. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn update_event_outcomes( env: Env, admin: Address, @@ -3377,6 +3725,10 @@ impl PredictifyHybrid { /// Err(e) => println!("Update failed: {:?}", e), /// } /// ``` + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn update_event_category( env: Env, admin: Address, @@ -3489,6 +3841,10 @@ impl PredictifyHybrid { /// Err(e) => println!("Update failed: {:?}", e), /// } /// ``` + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn update_event_tags( env: Env, admin: Address, @@ -3567,6 +3923,14 @@ impl PredictifyHybrid { /// # Returns /// /// Tuple of (events, next_cursor) + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn query_events_by_tags( env: Env, tags: Vec, @@ -3637,6 +4001,14 @@ impl PredictifyHybrid { /// 3. Bet status is updated to "Refunded" /// 4. Market state is updated to "Cancelled" /// 5. Cancellation and refund events are emitted + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn cancel_event( env: Env, admin: Address, @@ -3717,6 +4089,14 @@ impl PredictifyHybrid { /// timeout has passed since market end, or (2) caller is admin (confirmed failure). /// Refunds full bet amount per user (no fee deduction). Marks market as cancelled and /// prevents further resolution. Emits refund events. Idempotent when already cancelled. + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn refund_on_oracle_failure( env: Env, caller: Address, @@ -3774,6 +4154,14 @@ impl PredictifyHybrid { } /// Extend market duration (admin only) + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn extend_market( env: Env, admin: Address, @@ -3809,6 +4197,14 @@ impl PredictifyHybrid { // ===== STORAGE OPTIMIZATION FUNCTIONS ===== /// Compress market data for storage optimization + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn compress_market_data( env: Env, market_id: Symbol, @@ -3822,11 +4218,27 @@ impl PredictifyHybrid { } /// Clean up old market data based on age and state + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn cleanup_old_market_data(env: Env, market_id: Symbol) -> Result { storage::StorageOptimizer::cleanup_old_market_data(&env, &market_id) } /// Migrate storage format from old to new format + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn migrate_storage_format( env: Env, from_format: storage::StorageFormat, @@ -3836,21 +4248,53 @@ impl PredictifyHybrid { } /// Monitor storage usage and return statistics + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn monitor_storage_usage(env: Env) -> Result { storage::StorageOptimizer::monitor_storage_usage(&env) } /// Optimize storage layout for a specific market + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn optimize_storage_layout(env: Env, market_id: Symbol) -> Result { storage::StorageOptimizer::optimize_storage_layout(&env, &market_id) } /// Get storage usage statistics + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_storage_usage_statistics(env: Env) -> Result { storage::StorageOptimizer::get_storage_usage_statistics(&env) } /// Validate storage integrity for a specific market + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_storage_integrity( env: Env, market_id: Symbol, @@ -3859,16 +4303,40 @@ impl PredictifyHybrid { } /// Get storage configuration + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_storage_config(env: Env) -> storage::StorageConfig { storage::StorageOptimizer::get_storage_config(&env) } /// Update storage configuration + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn update_storage_config(env: Env, config: storage::StorageConfig) -> Result<(), Error> { storage::StorageOptimizer::update_storage_config(&env, &config) } /// Calculate storage cost for a market + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn calculate_storage_cost(env: Env, market_id: Symbol) -> Result { let market = match markets::MarketStateManager::get_market(&env, &market_id) { Ok(m) => m, @@ -3879,6 +4347,14 @@ impl PredictifyHybrid { } /// Get storage efficiency score for a market + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_storage_efficiency_score(env: Env, market_id: Symbol) -> Result { let market = match markets::MarketStateManager::get_market(&env, &market_id) { Ok(m) => m, @@ -3889,6 +4365,14 @@ impl PredictifyHybrid { } /// Get storage recommendations for a market + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_storage_recommendations(env: Env, market_id: Symbol) -> Result, Error> { let market = match markets::MarketStateManager::get_market(&env, &market_id) { Ok(m) => m, @@ -3901,6 +4385,14 @@ impl PredictifyHybrid { // ===== ERROR RECOVERY FUNCTIONS ===== /// Recover from an error using appropriate recovery strategy + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn recover_from_error( env: Env, error: Error, @@ -3910,6 +4402,14 @@ impl PredictifyHybrid { } /// Validate error recovery configuration and state + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_error_recovery( env: Env, recovery: errors::ErrorRecovery, @@ -3918,16 +4418,40 @@ impl PredictifyHybrid { } /// Get current error recovery status and statistics + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_error_recovery_status(env: Env) -> Result { errors::ErrorHandler::get_error_recovery_status(&env) } /// Emit error recovery event for monitoring and logging + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn emit_error_recovery_event(env: Env, recovery: errors::ErrorRecovery) { errors::ErrorHandler::emit_error_recovery_event(&env, &recovery); } /// Validate resilience patterns configuration + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_resilience_patterns( env: Env, patterns: Vec, @@ -3936,6 +4460,14 @@ impl PredictifyHybrid { } /// Document error recovery procedures and best practices + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn document_error_recovery(env: Env) -> Result, Error> { errors::ErrorHandler::document_error_recovery_procedures(&env) } @@ -3943,11 +4475,27 @@ impl PredictifyHybrid { // ===== EDGE CASE HANDLING ENTRY POINTS ===== /// Handle zero stake scenario for a specific market + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn handle_zero_stake_scenario(env: Env, market_id: Symbol) -> Result<(), Error> { edge_cases::EdgeCaseHandler::handle_zero_stake_scenario(&env, market_id) } /// Implement tie-breaking mechanism for equal outcomes + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn implement_tie_breaking_mechanism( env: Env, outcomes: Vec, @@ -3956,11 +4504,27 @@ impl PredictifyHybrid { } /// Detect orphaned markets and return their IDs + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn detect_orphaned_markets(env: Env) -> Result, Error> { edge_cases::EdgeCaseHandler::detect_orphaned_markets(&env) } /// Handle partial resolution with incomplete data + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn handle_partial_resolution( env: Env, market_id: Symbol, @@ -3970,6 +4534,14 @@ impl PredictifyHybrid { } /// Validate edge case handling scenario + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_edge_case_handling( env: Env, scenario: edge_cases::EdgeCaseScenario, @@ -3978,17 +4550,41 @@ impl PredictifyHybrid { } /// Run comprehensive edge case testing scenarios + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn test_edge_case_scenarios(env: Env) -> Result<(), Error> { edge_cases::EdgeCaseHandler::test_edge_case_scenarios(&env) } /// Get comprehensive edge case statistics + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_edge_case_statistics(env: Env) -> Result { edge_cases::EdgeCaseHandler::get_edge_case_statistics(&env) } // ===== RECOVERY PUBLIC METHODS ===== /// Initiates or performs recovery of a potentially corrupted market state. Only admin. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn recover_market_state(env: Env, admin: Address, market_id: Symbol) -> bool { admin.require_auth(); if let Err(e) = crate::recovery::RecoveryManager::assert_is_admin(&env, &admin) { @@ -4001,6 +4597,14 @@ impl PredictifyHybrid { } /// Executes partial refund mechanism for selected users in a failed/corrupted market. Only admin. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn partial_refund_mechanism( env: Env, admin: Address, @@ -4018,6 +4622,14 @@ impl PredictifyHybrid { } /// Validates market state integrity; returns true if consistent. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_market_state_integrity(env: Env, market_id: Symbol) -> bool { match crate::recovery::RecoveryValidator::validate_market_state_integrity(&env, &market_id) { @@ -4027,6 +4639,14 @@ impl PredictifyHybrid { } /// Returns recovery status for a market. + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_recovery_status(env: Env, market_id: Symbol) -> String { crate::recovery::RecoveryManager::get_recovery_status(&env, &market_id) .unwrap_or_else(|_| String::from_str(&env, "unknown")) @@ -4035,11 +4655,27 @@ impl PredictifyHybrid { // ===== VERSIONING FUNCTIONS ===== /// Track contract version for versioning system + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn track_contract_version(env: Env, version: versioning::Version) -> Result<(), Error> { versioning::VersionManager::new(&env).track_contract_version(&env, version) } /// Migrate data between contract versions + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn migrate_data_between_versions( env: Env, old_version: versioning::Version, @@ -4053,6 +4689,14 @@ impl PredictifyHybrid { } /// Validate version compatibility + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_version_compatibility( env: Env, old_version: versioning::Version, @@ -4066,21 +4710,53 @@ impl PredictifyHybrid { } /// Upgrade to a specific version + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn upgrade_to_version(env: Env, target_version: versioning::Version) -> Result<(), Error> { versioning::VersionManager::new(&env).upgrade_to_version(&env, target_version) } /// Rollback to a specific version + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn rollback_to_version(env: Env, target_version: versioning::Version) -> Result<(), Error> { versioning::VersionManager::new(&env).rollback_to_version(&env, target_version) } /// Get version history + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_version_history(env: Env) -> Result { versioning::VersionManager::new(&env).get_version_history(&env) } /// Test version migration + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn test_version_migration( env: Env, migration: versioning::VersionMigration, @@ -4091,6 +4767,14 @@ impl PredictifyHybrid { // ===== MONITORING FUNCTIONS ===== /// Monitor market health for a specific market + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn monitor_market_health( env: Env, market_id: Symbol, @@ -4099,6 +4783,14 @@ impl PredictifyHybrid { } /// Monitor oracle health for a specific oracle provider + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn monitor_oracle_health( env: Env, oracle: OracleProvider, @@ -4107,6 +4799,14 @@ impl PredictifyHybrid { } /// Monitor fee collection performance + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn monitor_fee_collection( env: Env, timeframe: monitoring::TimeFrame, @@ -4115,6 +4815,14 @@ impl PredictifyHybrid { } /// Monitor dispute resolution performance + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn monitor_dispute_resolution( env: Env, market_id: Symbol, @@ -4123,6 +4831,14 @@ impl PredictifyHybrid { } /// Get comprehensive contract performance metrics + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_contract_performance_metrics( env: Env, timeframe: monitoring::TimeFrame, @@ -4131,6 +4847,14 @@ impl PredictifyHybrid { } /// Emit monitoring alert + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn emit_monitoring_alert( env: Env, alert: monitoring::MonitoringAlert, @@ -4139,6 +4863,14 @@ impl PredictifyHybrid { } /// Validate monitoring data integrity + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_monitoring_data( env: Env, data: monitoring::MonitoringData, @@ -4149,6 +4881,14 @@ impl PredictifyHybrid { // ===== ORACLE FALLBACK FUNCTIONS ===== /// Get oracle data with backup if primary fails + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_oracle_with_backup( env: Env, market_id: Symbol, @@ -4209,6 +4949,14 @@ impl PredictifyHybrid { } /// Check if oracle is working + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn check_oracle_status( env: Env, oracle: OracleProvider, @@ -4224,6 +4972,14 @@ impl PredictifyHybrid { // ===== MULTI-ADMIN MANAGEMENT FUNCTIONS ===== /// Add a new admin with specified role (SuperAdmin only) + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn add_admin( env: Env, current_admin: Address, @@ -4235,6 +4991,14 @@ impl PredictifyHybrid { } /// Remove an admin from the system (SuperAdmin only) + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn remove_admin( env: Env, current_admin: Address, @@ -4245,6 +5009,14 @@ impl PredictifyHybrid { } /// Update an admin's role (SuperAdmin only) + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn update_admin_role( env: Env, current_admin: Address, @@ -4256,6 +5028,14 @@ impl PredictifyHybrid { } /// Validate admin permission for specific action + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_admin_permission( env: Env, admin: Address, @@ -4265,27 +5045,67 @@ impl PredictifyHybrid { } /// Get all admin roles in the system + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_admin_roles(env: Env) -> Map { AdminManager::get_admin_roles(&env) } /// Get comprehensive admin analytics + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_admin_analytics(env: Env) -> AdminAnalyticsResult { admin::EnhancedAdminAnalytics::get_admin_analytics(&env) } /// Migrate from single-admin to multi-admin system + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn migrate_to_multi_admin(env: Env, admin: Address) -> Result<(), Error> { admin.require_auth(); admin::AdminSystemIntegration::migrate_to_multi_admin(&env) } /// Check if multi-admin migration is complete + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn is_multi_admin_migrated(env: Env) -> bool { admin::AdminSystemIntegration::is_migrated(&env) } /// Check role permissions against a specific permission + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn check_role_permissions(env: Env, role: AdminRole, permission: AdminPermission) -> bool { AdminManager::check_role_permissions(&env, role, permission) } @@ -4329,6 +5149,14 @@ impl PredictifyHybrid { /// PredictifyHybrid::upgrade_contract(env, admin, new_wasm_hash)?; /// # Ok::<(), predictify_hybrid::errors::Error>(()) /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn upgrade_contract( env: Env, admin: Address, @@ -4353,6 +5181,14 @@ impl PredictifyHybrid { /// /// * `Ok(())` if rollback succeeds /// * `Err(Error)` if authorization fails or rollback is invalid + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn rollback_upgrade( env: Env, admin: Address, @@ -4370,6 +5206,14 @@ impl PredictifyHybrid { /// /// * `Ok(Version)` - Current contract version /// * `Err(Error)` - If version cannot be retrieved + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_contract_version(env: Env) -> Result { upgrade_manager::UpgradeManager::get_contract_version(&env) } @@ -4381,6 +5225,14 @@ impl PredictifyHybrid { /// # Returns /// /// * `Ok(bool)` - True if upgrade is available + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn check_upgrade_available(env: Env) -> Result { upgrade_manager::UpgradeManager::check_upgrade_available(&env) } @@ -4392,6 +5244,14 @@ impl PredictifyHybrid { /// # Returns /// /// * `Ok(Vec)` - List of all upgrade records + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_upgrade_history(env: Env) -> Result, Error> { upgrade_manager::UpgradeManager::get_upgrade_history(&env) } @@ -4403,6 +5263,14 @@ impl PredictifyHybrid { /// # Returns /// /// * `Ok(UpgradeStats)` - Upgrade statistics and analytics + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_upgrade_statistics(env: Env) -> Result { upgrade_manager::UpgradeManager::get_upgrade_statistics(&env) } @@ -4420,6 +5288,14 @@ impl PredictifyHybrid { /// # Returns /// /// * `Ok(CompatibilityCheckResult)` - Detailed compatibility analysis + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_upgrade_compatibility( env: Env, proposal: upgrade_manager::UpgradeProposal, @@ -4439,6 +5315,14 @@ impl PredictifyHybrid { /// # Returns /// /// * `Ok(bool)` - True if upgrade would succeed + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn test_upgrade_safety( env: Env, proposal: upgrade_manager::UpgradeProposal, @@ -4487,6 +5371,10 @@ impl PredictifyHybrid { /// Err(e) => println!("Analytics unavailable: {:?}", e), /// } /// ``` + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_market_statistics( env: Env, market_id: Symbol, @@ -4527,6 +5415,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Voting analytics unavailable: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_voting_analytics( env: Env, market_id: Symbol, @@ -4567,6 +5463,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Oracle stats unavailable: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_oracle_performance_stats( env: Env, oracle: OracleProvider, @@ -4606,6 +5510,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Fee analytics unavailable: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_fee_analytics( env: Env, timeframe: market_analytics::TimeFrame, @@ -4646,6 +5558,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Dispute analytics unavailable: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_dispute_analytics( env: Env, market_id: Symbol, @@ -4687,6 +5607,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Participation metrics unavailable: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_participation_metrics( env: Env, market_id: Symbol, @@ -4732,6 +5660,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Comparison analytics unavailable: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_market_comparison_analytics( env: Env, markets: Vec, @@ -4780,6 +5716,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Benchmark failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn benchmark_gas_usage( env: Env, function: String, @@ -4829,6 +5773,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Storage benchmark failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn benchmark_storage_usage( env: Env, operation: performance_benchmarks::StorageOperation, @@ -4873,6 +5825,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Oracle benchmark failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn benchmark_oracle_performance( env: Env, oracle: OracleProvider, @@ -4923,6 +5883,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Batch benchmark failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn benchmark_batch_operations( env: Env, operations: Vec, @@ -4966,6 +5934,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Scalability benchmark failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn benchmark_scalability( env: Env, market_size: u32, @@ -5012,6 +5988,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Report generation failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn generate_performance_report( env: Env, benchmark_suite: performance_benchmarks::PerformanceBenchmarkSuite, @@ -5056,6 +6040,14 @@ impl PredictifyHybrid { /// Err(e) => println!("Validation failed: {:?}", e), /// } /// ``` + /// + /// # Errors + /// + /// Returns [`Error`] when validation, authorization, storage, or subsystem checks fail. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn validate_performance_thresholds( env: Env, metrics: performance_benchmarks::PerformanceMetrics, @@ -5066,11 +6058,27 @@ impl PredictifyHybrid { ) } /// Get platform-wide statistics + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_platform_statistics(env: Env) -> PlatformStatistics { statistics::StatisticsManager::get_platform_stats(&env) } /// Get user-specific statistics + /// + /// # Errors + /// + /// This entrypoint surfaces contract errors via panic in internal calls. + /// + /// # Events + /// + /// State-changing paths may emit events through internal managers; read-only query paths emit no events. pub fn get_user_statistics(env: Env, user: Address) -> UserStatistics { statistics::StatisticsManager::get_user_stats(&env, &user) } diff --git a/contracts/predictify-hybrid/src/types.rs b/contracts/predictify-hybrid/src/types.rs index afe04e1c..f2fb37a4 100644 --- a/contracts/predictify-hybrid/src/types.rs +++ b/contracts/predictify-hybrid/src/types.rs @@ -974,6 +974,9 @@ impl Market { // Validate oracle config self.oracle_config.validate(env)?; + if self.has_fallback { + self.fallback_oracle_config.validate(env)?; + } // Validate end time if self.end_time <= env.ledger().timestamp() { @@ -3195,3 +3198,77 @@ pub struct Balance { pub asset: ReflectorAsset, pub amount: i128, } + +#[cfg(test)] +mod tests { + extern crate std; + + use super::*; + use soroban_sdk::testutils::Address as _; + + fn valid_oracle_config(env: &Env) -> OracleConfig { + OracleConfig::new( + OracleProvider::Reflector, + Address::generate(env), + String::from_str(env, "BTC/USD"), + 1_000_000, + String::from_str(env, "gt"), + ) + } + + #[test] + fn market_validate_rejects_invalid_fallback_when_enabled() { + let env = Env::default(); + let admin = Address::generate(&env); + let outcomes = Vec::from_array( + &env, + [String::from_str(&env, "yes"), String::from_str(&env, "no")], + ); + + let invalid_fallback = OracleConfig::new( + OracleProvider::Pyth, + Address::generate(&env), + String::from_str(&env, "BTC/USD"), + 1_000_000, + String::from_str(&env, "gt"), + ); + + let market = Market::new( + &env, + admin, + String::from_str(&env, "Will BTC be above $10,000?"), + outcomes, + env.ledger().timestamp() + 1000, + valid_oracle_config(&env), + Some(invalid_fallback), + 3600, + MarketState::Active, + ); + + assert_eq!(market.validate(&env), Err(crate::Error::InvalidOracleConfig)); + } + + #[test] + fn market_validate_allows_no_fallback_sentinel_path() { + let env = Env::default(); + let admin = Address::generate(&env); + let outcomes = Vec::from_array( + &env, + [String::from_str(&env, "yes"), String::from_str(&env, "no")], + ); + + let market = Market::new( + &env, + admin, + String::from_str(&env, "Will BTC be above $10,000?"), + outcomes, + env.ledger().timestamp() + 1000, + valid_oracle_config(&env), + None, + 3600, + MarketState::Active, + ); + + assert_eq!(market.validate(&env), Ok(())); + } +} diff --git a/docs/api/API_DOCUMENTATION.md b/docs/api/API_DOCUMENTATION.md index b2df7135..69a032bc 100644 --- a/docs/api/API_DOCUMENTATION.md +++ b/docs/api/API_DOCUMENTATION.md @@ -231,6 +231,24 @@ const getContractVersion = async (contractId: string): Promise => { ## 🔧 Core API Reference +### Rustdoc Coverage Contract + +All exported contract entrypoints in `contracts/predictify-hybrid/src/lib.rs` are documented with +Rust doc comments (`///`) and include explicit `# Errors` and `# Events` sections. + +This is intended to make API behavior auditable without reading all internals: + +- **Errors**: Each entrypoint documents how `Error` values are surfaced. + Functions returning `Result<_, Error>` propagate errors directly. + Non-`Result` entrypoints surface contract failures via panic. +- **Events**: Each entrypoint documents event behavior. + State-changing flows may emit events through internal managers (for example via `EventEmitter`), + while read-only query flows emit no events. + +For exact runtime behavior and error variants, also reference: +- `contracts/predictify-hybrid/src/err.rs` +- `contracts/predictify-hybrid/src/events.rs` + ### Market Management Functions #### `create_market()` diff --git a/docs/contracts/TYPES_SYSTEM.md b/docs/contracts/TYPES_SYSTEM.md index e656b140..f081de4d 100644 --- a/docs/contracts/TYPES_SYSTEM.md +++ b/docs/contracts/TYPES_SYSTEM.md @@ -1,541 +1,374 @@ -# Predictify Hybrid Types System - -## Overview - -The Predictify Hybrid contract now features a comprehensive, organized type system that centralizes all data structures and provides better organization, validation, and maintainability. This document outlines the architecture, usage patterns, and best practices for working with the types system. - -## Architecture - -### Type Categories - -Types are organized into logical categories for better understanding and maintenance: - -1. **Oracle Types** - Oracle providers, configurations, and data structures -2. **Market Types** - Market data structures and state management -3. **Price Types** - Price data and validation structures -4. **Validation Types** - Input validation and business logic types -5. **Utility Types** - Helper types and conversion utilities - -### Core Components - -#### 1. Oracle Types - -**OracleProvider Enum** -```rust -pub enum OracleProvider { - BandProtocol, - DIA, - Reflector, - Pyth, -} -``` - -**OracleConfig Struct** -```rust -pub struct OracleConfig { - pub provider: OracleProvider, - pub feed_id: String, - pub threshold: i128, - pub comparison: String, -} -``` - -#### 2. Market Types - -**Market Struct** -```rust -pub struct Market { - pub admin: Address, - pub question: String, - pub outcomes: Vec, - pub end_time: u64, - pub oracle_config: OracleConfig, - // ... other fields -} -``` - -#### 3. Price Types - -**PythPrice Struct** -```rust -pub struct PythPrice { - pub price: i128, - pub conf: u64, - pub expo: i32, - pub publish_time: u64, -} -``` - -**ReflectorPriceData Struct** -```rust -pub struct ReflectorPriceData { - pub price: i128, - pub timestamp: u64, -} -``` - -## Usage Patterns - -### 1. Creating Oracle Configurations - -```rust -use types::{OracleProvider, OracleConfig}; - -let oracle_config = OracleConfig::new( - OracleProvider::Pyth, - String::from_str(&env, "BTC/USD"), - 2500000, // $25,000 threshold - String::from_str(&env, "gt"), // greater than -); - -// Validate the configuration -oracle_config.validate(&env)?; -``` - -### 2. Creating Markets - -```rust -use types::{Market, OracleConfig, OracleProvider}; - -let market = Market::new( - &env, - admin, - question, - outcomes, - end_time, - oracle_config, -); - -// Validate market parameters -market.validate(&env)?; -``` - -### 3. Market State Management - -```rust -use types::MarketState; - -let state = MarketState::from_market(&market, &env); - -if state.is_active() { - // Market is accepting votes -} else if state.has_ended() { - // Market has ended -} else if state.is_resolved() { - // Market is resolved -} -``` - -### 4. Oracle Result Handling - -```rust -use types::OracleResult; - -let result = OracleResult::price(2500000); - -if result.is_available() { - if let Some(price) = result.get_price() { - // Use the price - } -} -``` - -## Type Validation - -### Built-in Validation - -All types include built-in validation methods: - -```rust -// Oracle configuration validation -oracle_config.validate(&env)?; - -// Market validation -market.validate(&env)?; - -// Price validation -pyth_price.validate()?; -``` - -### Validation Helpers - -The types module provides validation helper functions: - -```rust -use types::validation; - -// Validate oracle provider -validation::validate_oracle_provider(&OracleProvider::Pyth)?; - -// Validate price -validation::validate_price(2500000)?; - -// Validate stake -validation::validate_stake(stake, min_stake)?; - -// Validate duration -validation::validate_duration(30)?; -``` - -## Type Conversion - -### Conversion Helpers - -```rust -use types::conversion; - -// Convert string to oracle provider -let provider = conversion::string_to_oracle_provider("pyth") - .ok_or(Error::InvalidOracleConfig)?; - -// Convert oracle provider to string -let provider_name = conversion::oracle_provider_to_string(&provider); - -// Validate comparison operator -conversion::validate_comparison(&comparison, &env)?; -``` - -## Market Operations - -### Market State Queries - -```rust -// Check if market is active -if market.is_active(&env) { - // Accept votes -} - -// Check if market has ended -if market.has_ended(&env) { - // Resolve market -} - -// Check if market is resolved -if market.is_resolved() { - // Allow claims -} -``` - -### User Operations - -```rust -// Get user's vote -let user_vote = market.get_user_vote(&user); - -// Get user's stake -let user_stake = market.get_user_stake(&user); - -// Check if user has claimed -let has_claimed = market.has_user_claimed(&user); - -// Get user's dispute stake -let dispute_stake = market.get_user_dispute_stake(&user); -``` - -### Market Modifications - -```rust -// Add vote and stake -market.add_vote(user, outcome, stake); - -// Add dispute stake -market.add_dispute_stake(user, stake); - -// Mark user as claimed -market.mark_claimed(user); - -// Set oracle result -market.set_oracle_result(result); - -// Set winning outcome -market.set_winning_outcome(outcome); - -// Mark fees as collected -market.mark_fees_collected(); -``` - -### Market Calculations - -```rust -// Get total dispute stakes -let total_disputes = market.total_dispute_stakes(); - -// Get winning stake total -let winning_total = market.winning_stake_total(); -``` - -## Oracle Integration - -### Oracle Provider Support - -```rust -// Check if provider is supported -if oracle_provider.is_supported() { - // Use the provider -} - -// Get provider name -let name = oracle_provider.name(); - -// Get default feed format -let format = oracle_provider.default_feed_format(); -``` - -### Oracle Configuration - -```rust -// Check comparison operators -if oracle_config.is_greater_than(&env) { - // Handle greater than comparison -} else if oracle_config.is_less_than(&env) { - // Handle less than comparison -} else if oracle_config.is_equal_to(&env) { - // Handle equal to comparison -} -``` - -## Price Data Handling - -### Pyth Price Data - -```rust -let pyth_price = PythPrice::new(2500000, 1000, -2, timestamp); - -// Get price in cents -let price_cents = pyth_price.price_in_cents(); - -// Check if price is stale (manual check) -if env.ledger().timestamp() > pyth_price.publish_time + max_age { - // Handle stale price -} - -// Validate price data -pyth_price.validate()?; -``` - -### Reflector Price Data - -```rust -let reflector_price = ReflectorPriceData::new(2500000, timestamp); - -// Get price in cents -let price_cents = reflector_price.price_in_cents(); - -// Check if price is stale (manual check) -if env.ledger().timestamp() > reflector_price.timestamp + max_age { - // Handle stale price -} - -// Validate price data -reflector_price.validate()?; -``` - -## Validation Types - -### Market Creation Parameters - -```rust -let params = MarketCreationParams::new( - admin, - question, - outcomes, - duration_days, - oracle_config, -); - -// Validate all parameters -params.validate(&env)?; - -// Calculate end time -let end_time = params.calculate_end_time(&env); -``` - -### Vote Parameters - -```rust -let vote_params = VoteParams::new(user, outcome, stake); - -// Validate vote parameters -vote_params.validate(&env, &market)?; -``` - -## Best Practices - -### 1. Always Validate Types - -```rust -// ❌ Don't skip validation -let market = Market::new(&env, admin, question, outcomes, end_time, oracle_config); - -// ✅ Always validate -let market = Market::new(&env, admin, question, outcomes, end_time, oracle_config); -market.validate(&env)?; -``` - -### 2. Use Type-Safe Operations - -```rust -// ❌ Manual state checking -if current_time < market.end_time && market.winning_outcome.is_none() { - // Market is active -} - -// ✅ Use type-safe methods -if market.is_active(current_time) { - // Market is active -} -``` - -### 3. Leverage Built-in Methods - -```rust -// ❌ Manual calculations -let mut total = 0; -for (user, outcome) in market.votes.iter() { - if &outcome == winning_outcome { - total += market.stakes.get(user.clone()).unwrap_or(0); - } -} - -// ✅ Use built-in methods -let total = market.winning_stake_total(); -``` - -### 4. Use Validation Helpers - -```rust -// ❌ Manual validation -if stake < min_stake { - return Err(Error::InsufficientStake); -} - -// ✅ Use validation helpers -validation::validate_stake(stake, min_stake)?; -``` - -### 5. Handle Oracle Results Safely - -```rust -// ❌ Direct access -let price = oracle_result.price; - -// ✅ Safe access -if let Some(price) = oracle_result.get_price() { - // Use the price -} -``` - -## Testing - -### Type Testing - -The types module includes comprehensive tests: - -```rust -#[test] -fn test_oracle_provider() { - let provider = OracleProvider::Pyth; - assert_eq!(provider.name(), "Pyth Network"); - assert!(provider.is_supported()); -} - -#[test] -fn test_market_creation() { - let market = Market::new(&env, admin, question, outcomes, end_time, oracle_config); - assert!(market.is_active(&env)); - assert!(!market.is_resolved()); -} - -#[test] -fn test_validation_helpers() { - assert!(validation::validate_oracle_provider(&OracleProvider::Pyth).is_ok()); - assert!(validation::validate_price(2500000).is_ok()); -} -``` - -## Migration Guide - -### From Direct Type Usage - -1. **Replace direct struct creation**: - ```rust - // Old - let market = Market { /* fields */ }; - - // New - let market = Market::new(&env, admin, question, outcomes, end_time, oracle_config); - ``` - -2. **Use validation methods**: - ```rust - // Old - if threshold <= 0 { return Err(Error::InvalidThreshold); } - - // New - oracle_config.validate(&env)?; - ``` - -3. **Use type-safe operations**: - ```rust - // Old - if current_time < market.end_time { /* active */ } - - // New - if market.is_active(&env) { /* active */ } - ``` - -## Type Reference - -### Oracle Types - -| Type | Purpose | Key Methods | -|------|---------|-------------| -| `OracleProvider` | Oracle service enumeration | `name()`, `is_supported()`, `default_feed_format()` | -| `OracleConfig` | Oracle configuration | `new()`, `validate()`, `is_supported()`, `is_greater_than()` | -| `PythPrice` | Pyth price data | `new()`, `price_in_cents()`, `is_stale()`, `validate()` | -| `ReflectorPriceData` | Reflector price data | `new()`, `price_in_cents()`, `is_stale()`, `validate()` | - -### Market Types - -| Type | Purpose | Key Methods | -|------|---------|-------------| -| `Market` | Market data structure | `new()`, `validate()`, `is_active()`, `add_vote()` | -| `MarketState` | Market state enumeration | `from_market()`, `is_active()`, `has_ended()` | -| `MarketCreationParams` | Market creation parameters | `new()`, `validate()`, `calculate_end_time()` | -| `VoteParams` | Vote parameters | `new()`, `validate()` | - -### Utility Types - -| Type | Purpose | Key Methods | -|------|---------|-------------| -| `OracleResult` | Oracle result wrapper | `price()`, `unavailable()`, `is_available()`, `get_price()` | -| `ReflectorAsset` | Reflector asset types | `stellar()`, `other()`, `is_stellar()`, `is_other()` | - -### Validation Functions - -| Function | Purpose | Parameters | -|----------|---------|------------| -| `validate_oracle_provider()` | Validate oracle provider | `provider: &OracleProvider` | -| `validate_price()` | Validate price value | `price: i128` | -| `validate_stake()` | Validate stake amount | `stake: i128, min_stake: i128` | -| `validate_duration()` | Validate duration | `duration_days: u32` | - -### Conversion Functions - -| Function | Purpose | Parameters | -|----------|---------|------------| -| `string_to_oracle_provider()` | Convert string to provider | `s: &str` | -| `oracle_provider_to_string()` | Convert provider to string | `provider: &OracleProvider` | -| `validate_comparison()` | Validate comparison operator | `comparison: &String, env: &Env` | - -## Future Enhancements - -1. **Type Serialization**: Proper serialization/deserialization support -2. **Type Metrics**: Collection and reporting of type usage statistics -3. **Type Validation**: Enhanced validation with custom rules -4. **Type Events**: Event emission for type state changes -5. **Type Localization**: Support for multiple languages in type messages - -## Conclusion - -The new types system provides a robust foundation for managing data structures in the Predictify Hybrid contract. By following the patterns and best practices outlined in this document, developers can create more maintainable, type-safe, and well-organized code. \ No newline at end of file +# Predictify Hybrid Types System (Code-Synced) + +This document is the canonical field/variant reference for every `#[contracttype]` defined in `/contracts/predictify-hybrid/src/types.rs`. + +## Scope + +- Source of truth: `/contracts/predictify-hybrid/src/types.rs` +- Included here: all `#[contracttype]` enums and structs in that file +- Not included: non-`contracttype` helper structs (for example, `OraclePriceData`) + +## Enums + +### `MarketState` +- `Active` +- `Ended` +- `Disputed` +- `Resolved` +- `Closed` +- `Cancelled` + +### `OracleProvider` +- `Reflector` +- `Pyth` +- `BandProtocol` +- `DIA` + +### `ReflectorAsset` +- `Stellar` +- `BTC` +- `ETH` +- `Other(Symbol)` + +### `OracleVerificationStatus` +- `Pending` +- `InProgress` +- `Verified` +- `InvalidSignature` +- `StaleData` +- `OracleUnavailable` +- `ThresholdNotMet` +- `NoConsensus` + +### `MarketStatus` +- `Active` +- `Ended` +- `Disputed` +- `Resolved` +- `Closed` +- `Cancelled` + +### `BetStatus` +- `Active` +- `Won` +- `Lost` +- `Refunded` +- `Cancelled` + +### `EventVisibility` +- `Public` +- `Private` + +## Structs + +### `OracleConfig` +| Field | Type | +|---|---| +| `provider` | `OracleProvider` | +| `oracle_address` | `Address` | +| `feed_id` | `String` | +| `threshold` | `i128` | +| `comparison` | `String` | + +### `Market` +| Field | Type | +|---|---| +| `admin` | `Address` | +| `question` | `String` | +| `outcomes` | `Vec` | +| `end_time` | `u64` | +| `oracle_config` | `OracleConfig` | +| `has_fallback` | `bool` | +| `fallback_oracle_config` | `OracleConfig` | +| `resolution_timeout` | `u64` | +| `oracle_result` | `Option` | +| `votes` | `Map` | +| `stakes` | `Map` | +| `claimed` | `Map` | +| `total_staked` | `i128` | +| `dispute_stakes` | `Map` | +| `winning_outcomes` | `Option>` | +| `fee_collected` | `bool` | +| `state` | `MarketState` | +| `total_extension_days` | `u32` | +| `max_extension_days` | `u32` | +| `extension_history` | `Vec` | +| `category` | `Option` | +| `tags` | `Vec` | +| `min_pool_size` | `Option` | +| `bet_deadline` | `u64` | +| `dispute_window_seconds` | `u64` | + +### `BetLimits` +| Field | Type | +|---|---| +| `min_bet` | `i128` | +| `max_bet` | `i128` | + +### `EventHistoryEntry` +| Field | Type | +|---|---| +| `market_id` | `Symbol` | +| `question` | `String` | +| `outcomes` | `Vec` | +| `end_time` | `u64` | +| `created_at` | `u64` | +| `state` | `MarketState` | +| `winning_outcome` | `Option` | +| `total_staked` | `i128` | +| `archived_at` | `Option` | +| `category` | `String` | +| `tags` | `Vec` | + +### `PlatformStatistics` +| Field | Type | +|---|---| +| `total_events_created` | `u64` | +| `total_bets_placed` | `u64` | +| `total_volume` | `i128` | +| `total_fees_collected` | `i128` | +| `active_events_count` | `u32` | + +### `UserStatistics` +| Field | Type | +|---|---| +| `total_bets_placed` | `u64` | +| `total_amount_wagered` | `i128` | +| `total_winnings` | `i128` | +| `total_bets_won` | `u64` | +| `win_rate` | `u32` | +| `last_activity_ts` | `u64` | + +### `OracleResult` +| Field | Type | +|---|---| +| `market_id` | `Symbol` | +| `outcome` | `String` | +| `price` | `i128` | +| `threshold` | `i128` | +| `comparison` | `String` | +| `provider` | `OracleProvider` | +| `feed_id` | `String` | +| `timestamp` | `u64` | +| `block_number` | `u32` | +| `is_verified` | `bool` | +| `confidence_score` | `u32` | +| `sources_count` | `u32` | +| `signature` | `Option` | +| `error_message` | `Option` | + +### `GlobalOracleValidationConfig` +| Field | Type | +|---|---| +| `max_staleness_secs` | `u64` | +| `max_confidence_bps` | `u32` | + +### `EventOracleValidationConfig` +| Field | Type | +|---|---| +| `max_staleness_secs` | `u64` | +| `max_confidence_bps` | `u32` | + +### `MultiOracleResult` +| Field | Type | +|---|---| +| `market_id` | `Symbol` | +| `final_outcome` | `String` | +| `individual_results` | `Vec` | +| `consensus_reached` | `bool` | +| `consensus_threshold` | `u32` | +| `agreement_percentage` | `u32` | +| `timestamp` | `u64` | + +### `OracleSource` +| Field | Type | +|---|---| +| `source_id` | `Symbol` | +| `provider` | `OracleProvider` | +| `contract_address` | `Address` | +| `weight` | `u32` | +| `is_active` | `bool` | +| `priority` | `u32` | +| `last_success` | `u64` | +| `failure_count` | `u32` | + +### `OracleFetchRequest` +| Field | Type | +|---|---| +| `market_id` | `Symbol` | +| `feed_id` | `String` | +| `max_data_age` | `u64` | +| `required_confirmations` | `u32` | +| `use_fallback` | `bool` | +| `min_confidence` | `u32` | + +### `ReflectorPriceData` +| Field | Type | +|---|---| +| `price` | `i128` | +| `timestamp` | `u64` | +| `source` | `String` | + +### `MarketExtension` +| Field | Type | +|---|---| +| `additional_days` | `u32` | +| `admin` | `Address` | +| `reason` | `String` | +| `fee_amount` | `i128` | +| `timestamp` | `u64` | + +### `ExtensionStats` +| Field | Type | +|---|---| +| `total_extensions` | `u32` | +| `total_extension_days` | `u32` | +| `max_extension_days` | `u32` | +| `can_extend` | `bool` | +| `extension_fee_per_day` | `i128` | + +### `MarketCreationParams` +| Field | Type | +|---|---| +| `admin` | `Address` | +| `question` | `String` | +| `outcomes` | `Vec` | +| `duration_days` | `u32` | +| `oracle_config` | `OracleConfig` | +| `creation_fee` | `i128` | + +### `CommunityConsensus` +| Field | Type | +|---|---| +| `outcome` | `String` | +| `votes` | `u32` | +| `total_votes` | `u32` | +| `percentage` | `i128` | + +### `MarketPauseInfo` +| Field | Type | +|---|---| +| `is_paused` | `bool` | +| `paused_at` | `u64` | +| `pause_duration_hours` | `u32` | +| `paused_by` | `Address` | +| `pause_end_time` | `u64` | +| `original_state` | `MarketState` | + +### `EventDetailsQuery` +| Field | Type | +|---|---| +| `market_id` | `Symbol` | +| `question` | `String` | +| `outcomes` | `Vec` | +| `created_at` | `u64` | +| `end_time` | `u64` | +| `status` | `MarketStatus` | +| `oracle_provider` | `String` | +| `feed_id` | `String` | +| `total_staked` | `i128` | +| `winning_outcome` | `Option` | +| `oracle_result` | `Option` | +| `participant_count` | `u32` | +| `vote_count` | `u32` | +| `admin` | `Address` | + +### `UserBetQuery` +| Field | Type | +|---|---| +| `user` | `Address` | +| `market_id` | `Symbol` | +| `outcome` | `String` | +| `stake_amount` | `i128` | +| `voted_at` | `u64` | +| `is_winning` | `bool` | +| `has_claimed` | `bool` | +| `potential_payout` | `i128` | +| `dispute_stake` | `i128` | + +### `UserBalanceQuery` +| Field | Type | +|---|---| +| `user` | `Address` | +| `available_balance` | `i128` | +| `total_staked` | `i128` | +| `total_winnings` | `i128` | +| `active_bet_count` | `u32` | +| `resolved_market_count` | `u32` | +| `unclaimed_balance` | `i128` | + +### `MarketPoolQuery` +| Field | Type | +|---|---| +| `market_id` | `Symbol` | +| `total_pool` | `i128` | +| `outcome_pools` | `Map` | +| `platform_fees` | `i128` | +| `implied_probability_yes` | `u32` | +| `implied_probability_no` | `u32` | + +### `ContractStateQuery` +| Field | Type | +|---|---| +| `total_markets` | `u32` | +| `active_markets` | `u32` | +| `resolved_markets` | `u32` | +| `total_value_locked` | `i128` | +| `total_fees_collected` | `i128` | +| `unique_users` | `u32` | +| `contract_version` | `String` | +| `last_update` | `u64` | + +### `MultipleBetsQuery` +| Field | Type | +|---|---| +| `bets` | `Vec` | +| `total_stake` | `i128` | +| `total_potential_payout` | `i128` | +| `winning_bets` | `u32` | + +### `Bet` +| Field | Type | +|---|---| +| `user` | `Address` | +| `market_id` | `Symbol` | +| `outcome` | `String` | +| `amount` | `i128` | +| `timestamp` | `u64` | +| `status` | `BetStatus` | + +### `BetStats` +| Field | Type | +|---|---| +| `total_bets` | `u32` | +| `total_amount_locked` | `i128` | +| `unique_bettors` | `u32` | +| `outcome_totals` | `Map` | + +### `Event` +| Field | Type | +|---|---| +| `id` | `Symbol` | +| `description` | `String` | +| `outcomes` | `Vec` | +| `end_time` | `u64` | +| `oracle_config` | `OracleConfig` | +| `has_fallback` | `bool` | +| `fallback_oracle_config` | `OracleConfig` | +| `resolution_timeout` | `u64` | +| `admin` | `Address` | +| `created_at` | `u64` | +| `status` | `MarketState` | +| `visibility` | `EventVisibility` | +| `allowlist` | `Vec
` | + +### `Balance` +| Field | Type | +|---|---| +| `user` | `Address` | +| `asset` | `ReflectorAsset` | +| `amount` | `i128` | + +## Maintenance Rule + +When adding, removing, or renaming any field or variant in `types.rs`, update this document in the same PR.