Rust · 20833 bytes Raw Blame History
1 //! Smart Contract Pricing Oracles
2 //!
3 //! Decentralized price feeds and market data oracles for fair pricing
4
5 use serde::{Deserialize, Serialize};
6 use std::collections::HashMap;
7 use tokio::time::{Duration, Instant};
8
9 #[derive(Debug, Clone, Serialize, Deserialize)]
10 pub struct PriceOracle {
11 pub oracle_id: String,
12 pub oracle_name: String,
13 pub oracle_type: OracleType,
14 pub data_sources: Vec<DataSource>,
15 pub aggregation_method: AggregationMethod,
16 pub update_frequency: Duration,
17 pub reliability_score: f64,
18 pub last_update: Instant,
19 pub current_prices: HashMap<String, PriceData>,
20 }
21
22 #[derive(Debug, Clone, Serialize, Deserialize)]
23 pub enum OracleType {
24 Storage, // Storage pricing oracle
25 Bandwidth, // Bandwidth pricing oracle
26 Compute, // Compute resource pricing
27 Composite, // Multiple resource types
28 External, // External market data
29 Consensus, // Consensus-based pricing
30 }
31
32 #[derive(Debug, Clone, Serialize, Deserialize)]
33 pub struct DataSource {
34 pub source_id: String,
35 pub source_name: String,
36 pub source_type: SourceType,
37 pub endpoint: String,
38 pub weight: f64,
39 pub reliability: f64,
40 pub latency: Duration,
41 pub cost_per_query: f64,
42 }
43
44 #[derive(Debug, Clone, Serialize, Deserialize)]
45 pub enum SourceType {
46 CloudProvider, // AWS, Azure, GCP pricing
47 ExchangeAPI, // Cryptocurrency exchanges
48 MarketData, // Financial market data
49 PeerNetwork, // P2P network pricing
50 AuctionResults, // Historical auction data
51 UserReported, // Community-reported prices
52 MLModel, // ML-predicted prices
53 }
54
55 #[derive(Debug, Clone, Serialize, Deserialize)]
56 pub struct PriceData {
57 pub resource_type: String,
58 pub price: f64,
59 pub currency: String,
60 pub timestamp: Instant,
61 pub confidence_score: f64,
62 pub volume_24h: Option<f64>,
63 pub price_change_24h: Option<f64>,
64 pub market_cap: Option<f64>,
65 }
66
67 #[derive(Debug, Clone, Serialize, Deserialize)]
68 pub enum AggregationMethod {
69 WeightedAverage,
70 Median,
71 Mode,
72 VolumeWeighted,
73 TimeWeighted,
74 OutlierFiltered,
75 Consensus,
76 }
77
78 #[derive(Debug, Clone, Serialize, Deserialize)]
79 pub struct MarketData {
80 pub symbol: String,
81 pub price: f64,
82 pub volume: f64,
83 pub market_cap: f64,
84 pub price_change_24h: f64,
85 pub price_change_7d: f64,
86 pub volatility: f64,
87 pub liquidity_score: f64,
88 }
89
90 #[derive(Debug, Clone, Serialize, Deserialize)]
91 pub struct ExternalPriceSource {
92 pub provider_name: String,
93 pub api_endpoint: String,
94 pub api_key: Option<String>,
95 pub rate_limit: RateLimit,
96 pub data_format: DataFormat,
97 pub supported_assets: Vec<String>,
98 }
99
100 #[derive(Debug, Clone, Serialize, Deserialize)]
101 pub struct RateLimit {
102 pub requests_per_minute: u32,
103 pub requests_per_hour: u32,
104 pub requests_per_day: u32,
105 pub burst_limit: u32,
106 }
107
108 #[derive(Debug, Clone, Serialize, Deserialize)]
109 pub enum DataFormat {
110 JSON,
111 XML,
112 CSV,
113 Custom(String),
114 }
115
116 #[derive(Debug, Clone, Serialize, Deserialize)]
117 pub struct OracleConsensus {
118 pub consensus_method: ConsensusMethod,
119 pub minimum_oracles: u32,
120 pub consensus_threshold: f64,
121 pub dispute_resolution: DisputeResolution,
122 pub incentive_mechanism: IncentiveMechanism,
123 }
124
125 #[derive(Debug, Clone, Serialize, Deserialize)]
126 pub enum ConsensusMethod {
127 SimpleAverage,
128 WeightedAverage,
129 MedianVoting,
130 Staking,
131 ReputationBased,
132 ByzantineFaultTolerant,
133 }
134
135 #[derive(Debug, Clone, Serialize, Deserialize)]
136 pub enum DisputeResolution {
137 Voting,
138 Arbitration,
139 Slashing,
140 Reputation,
141 }
142
143 #[derive(Debug, Clone, Serialize, Deserialize)]
144 pub struct IncentiveMechanism {
145 pub reward_accurate: f64,
146 pub penalty_inaccurate: f64,
147 pub stake_requirement: f64,
148 pub reward_distribution: RewardDistribution,
149 }
150
151 #[derive(Debug, Clone, Serialize, Deserialize)]
152 pub enum RewardDistribution {
153 Equal,
154 AccuracyBased,
155 StakeBased,
156 Hybrid,
157 }
158
159 pub struct PricingOracleNetwork {
160 oracles: HashMap<String, PriceOracle>,
161 consensus_engine: ConsensusEngine,
162 validation_system: ValidationSystem,
163 price_feeds: HashMap<String, PriceFeed>,
164 external_sources: Vec<ExternalPriceSource>,
165 }
166
167 struct ConsensusEngine {
168 consensus_algorithms: HashMap<String, ConsensusAlgorithm>,
169 oracle_weights: HashMap<String, f64>,
170 historical_accuracy: HashMap<String, f64>,
171 dispute_manager: DisputeManager,
172 }
173
174 #[derive(Debug, Clone)]
175 struct ConsensusAlgorithm {
176 algorithm_name: String,
177 minimum_participants: u32,
178 consensus_threshold: f64,
179 timeout_duration: Duration,
180 }
181
182 struct DisputeManager {
183 active_disputes: HashMap<String, PriceDispute>,
184 resolution_history: Vec<DisputeResolution>,
185 arbitrators: Vec<String>,
186 }
187
188 #[derive(Debug, Clone)]
189 struct PriceDispute {
190 dispute_id: String,
191 disputed_price: f64,
192 disputing_oracles: Vec<String>,
193 evidence: Vec<String>,
194 resolution_deadline: Instant,
195 }
196
197 struct ValidationSystem {
198 validation_rules: Vec<ValidationRule>,
199 anomaly_detector: AnomalyDetector,
200 quality_assessor: QualityAssessor,
201 }
202
203 #[derive(Debug, Clone)]
204 struct ValidationRule {
205 rule_name: String,
206 condition: String,
207 action: ValidationAction,
208 severity: ValidationSeverity,
209 }
210
211 #[derive(Debug, Clone)]
212 enum ValidationAction {
213 Accept,
214 Reject,
215 Flag,
216 Investigate,
217 }
218
219 #[derive(Debug, Clone)]
220 enum ValidationSeverity {
221 Low,
222 Medium,
223 High,
224 Critical,
225 }
226
227 struct AnomalyDetector {
228 detection_models: Vec<AnomalyModel>,
229 threshold_settings: ThresholdSettings,
230 alert_system: AlertSystem,
231 }
232
233 #[derive(Debug, Clone)]
234 struct AnomalyModel {
235 model_type: ModelType,
236 sensitivity: f64,
237 training_data_window: Duration,
238 accuracy_score: f64,
239 }
240
241 #[derive(Debug, Clone)]
242 enum ModelType {
243 Statistical,
244 MachineLearning,
245 RuleBased,
246 Hybrid,
247 }
248
249 #[derive(Debug, Clone)]
250 struct ThresholdSettings {
251 price_deviation_threshold: f64,
252 volume_spike_threshold: f64,
253 volatility_threshold: f64,
254 correlation_threshold: f64,
255 }
256
257 struct AlertSystem {
258 alert_channels: Vec<String>,
259 escalation_policy: String,
260 notification_templates: HashMap<String, String>,
261 }
262
263 struct QualityAssessor {
264 quality_metrics: Vec<QualityMetric>,
265 scoring_algorithm: ScoringAlgorithm,
266 quality_thresholds: QualityThresholds,
267 }
268
269 #[derive(Debug, Clone)]
270 struct QualityMetric {
271 metric_name: String,
272 weight: f64,
273 calculation_method: String,
274 target_value: f64,
275 }
276
277 #[derive(Debug, Clone)]
278 enum ScoringAlgorithm {
279 WeightedSum,
280 MinimumThreshold,
281 Composite,
282 }
283
284 #[derive(Debug, Clone)]
285 struct QualityThresholds {
286 minimum_quality_score: f64,
287 warning_threshold: f64,
288 critical_threshold: f64,
289 }
290
291 #[derive(Debug, Clone)]
292 struct PriceFeed {
293 feed_id: String,
294 resource_type: String,
295 current_price: f64,
296 price_history: Vec<PricePoint>,
297 confidence_interval: (f64, f64),
298 last_update: Instant,
299 update_frequency: Duration,
300 }
301
302 #[derive(Debug, Clone)]
303 struct PricePoint {
304 timestamp: Instant,
305 price: f64,
306 volume: f64,
307 source: String,
308 }
309
310 impl PricingOracleNetwork {
311 pub fn new() -> Self {
312 Self {
313 oracles: HashMap::new(),
314 consensus_engine: ConsensusEngine::new(),
315 validation_system: ValidationSystem::new(),
316 price_feeds: HashMap::new(),
317 external_sources: Vec::new(),
318 }
319 }
320
321 pub async fn add_oracle(&mut self, oracle: PriceOracle) -> Result<(), Box<dyn std::error::Error>> {
322 let oracle_id = oracle.oracle_id.clone();
323
324 // Validate oracle configuration
325 self.validate_oracle(&oracle)?;
326
327 // Initialize consensus weight
328 self.consensus_engine.oracle_weights.insert(oracle_id.clone(), 1.0);
329
330 // Add to active oracles
331 self.oracles.insert(oracle_id, oracle);
332
333 Ok(())
334 }
335
336 pub async fn get_consensus_price(&self, resource_type: &str) -> Result<PriceData, Box<dyn std::error::Error>> {
337 let relevant_oracles: Vec<_> = self.oracles.values()
338 .filter(|oracle| oracle.current_prices.contains_key(resource_type))
339 .collect();
340
341 if relevant_oracles.len() < 3 {
342 return Err("Insufficient oracles for consensus".into());
343 }
344
345 let prices: Vec<_> = relevant_oracles.iter()
346 .filter_map(|oracle| oracle.current_prices.get(resource_type))
347 .collect();
348
349 let consensus_price = self.calculate_consensus_price(&prices).await?;
350
351 Ok(PriceData {
352 resource_type: resource_type.to_string(),
353 price: consensus_price,
354 currency: "ZEPH".to_string(),
355 timestamp: Instant::now(),
356 confidence_score: self.calculate_confidence_score(&prices),
357 volume_24h: None,
358 price_change_24h: None,
359 market_cap: None,
360 })
361 }
362
363 pub async fn update_price_feeds(&mut self) -> Result<(), Box<dyn std::error::Error>> {
364 for oracle in self.oracles.values_mut() {
365 if oracle.last_update.elapsed() >= oracle.update_frequency {
366 self.update_oracle_prices(oracle).await?;
367 }
368 }
369
370 // Update consensus prices
371 self.update_consensus_feeds().await?;
372
373 Ok(())
374 }
375
376 pub async fn validate_price_data(&self, price_data: &PriceData) -> Result<bool, Box<dyn std::error::Error>> {
377 self.validation_system.validate_price(price_data).await
378 }
379
380 async fn validate_oracle(&self, oracle: &PriceOracle) -> Result<(), Box<dyn std::error::Error>> {
381 // Check if oracle has valid data sources
382 if oracle.data_sources.is_empty() {
383 return Err("Oracle must have at least one data source".into());
384 }
385
386 // Validate aggregation method
387 match oracle.aggregation_method {
388 AggregationMethod::WeightedAverage => {
389 let total_weight: f64 = oracle.data_sources.iter().map(|s| s.weight).sum();
390 if (total_weight - 1.0).abs() > 0.01 {
391 return Err("Weighted average requires weights to sum to 1.0".into());
392 }
393 },
394 _ => {}
395 }
396
397 Ok(())
398 }
399
400 async fn update_oracle_prices(&mut self, oracle: &mut PriceOracle) -> Result<(), Box<dyn std::error::Error>> {
401 let mut new_prices = HashMap::new();
402
403 for source in &oracle.data_sources {
404 if let Ok(price_data) = self.fetch_from_source(source).await {
405 for (resource_type, price) in price_data {
406 new_prices.insert(resource_type, price);
407 }
408 }
409 }
410
411 // Aggregate prices using specified method
412 oracle.current_prices = self.aggregate_prices(new_prices, &oracle.aggregation_method);
413 oracle.last_update = Instant::now();
414
415 Ok(())
416 }
417
418 async fn fetch_from_source(&self, source: &DataSource) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
419 match source.source_type {
420 SourceType::CloudProvider => self.fetch_cloud_pricing(&source.endpoint).await,
421 SourceType::ExchangeAPI => self.fetch_exchange_data(&source.endpoint).await,
422 SourceType::MarketData => self.fetch_market_data(&source.endpoint).await,
423 SourceType::PeerNetwork => self.fetch_peer_pricing(&source.endpoint).await,
424 SourceType::AuctionResults => self.fetch_auction_results(&source.endpoint).await,
425 SourceType::UserReported => self.fetch_user_reports(&source.endpoint).await,
426 SourceType::MLModel => self.fetch_ml_predictions(&source.endpoint).await,
427 }
428 }
429
430 async fn fetch_cloud_pricing(&self, _endpoint: &str) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
431 // Placeholder implementation
432 let mut prices = HashMap::new();
433 prices.insert("storage".to_string(), PriceData {
434 resource_type: "storage".to_string(),
435 price: 0.023, // $0.023 per GB per month (AWS S3 standard)
436 currency: "USD".to_string(),
437 timestamp: Instant::now(),
438 confidence_score: 0.95,
439 volume_24h: None,
440 price_change_24h: Some(-0.02),
441 market_cap: None,
442 });
443 Ok(prices)
444 }
445
446 async fn fetch_exchange_data(&self, _endpoint: &str) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
447 // Placeholder implementation for crypto exchange data
448 let mut prices = HashMap::new();
449 prices.insert("bandwidth".to_string(), PriceData {
450 resource_type: "bandwidth".to_string(),
451 price: 0.08, // Per GB transferred
452 currency: "USD".to_string(),
453 timestamp: Instant::now(),
454 confidence_score: 0.88,
455 volume_24h: Some(1234567.0),
456 price_change_24h: Some(0.05),
457 market_cap: None,
458 });
459 Ok(prices)
460 }
461
462 async fn fetch_market_data(&self, _endpoint: &str) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
463 // Placeholder for general market data
464 Ok(HashMap::new())
465 }
466
467 async fn fetch_peer_pricing(&self, _endpoint: &str) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
468 // Placeholder for P2P network pricing
469 Ok(HashMap::new())
470 }
471
472 async fn fetch_auction_results(&self, _endpoint: &str) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
473 // Placeholder for auction result data
474 Ok(HashMap::new())
475 }
476
477 async fn fetch_user_reports(&self, _endpoint: &str) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
478 // Placeholder for user-reported prices
479 Ok(HashMap::new())
480 }
481
482 async fn fetch_ml_predictions(&self, _endpoint: &str) -> Result<HashMap<String, PriceData>, Box<dyn std::error::Error>> {
483 // Placeholder for ML model predictions
484 Ok(HashMap::new())
485 }
486
487 fn aggregate_prices(&self, prices: HashMap<String, PriceData>, method: &AggregationMethod) -> HashMap<String, PriceData> {
488 match method {
489 AggregationMethod::WeightedAverage => self.weighted_average_aggregation(prices),
490 AggregationMethod::Median => self.median_aggregation(prices),
491 AggregationMethod::Mode => self.mode_aggregation(prices),
492 AggregationMethod::VolumeWeighted => self.volume_weighted_aggregation(prices),
493 AggregationMethod::TimeWeighted => self.time_weighted_aggregation(prices),
494 AggregationMethod::OutlierFiltered => self.outlier_filtered_aggregation(prices),
495 AggregationMethod::Consensus => self.consensus_aggregation(prices),
496 }
497 }
498
499 fn weighted_average_aggregation(&self, prices: HashMap<String, PriceData>) -> HashMap<String, PriceData> {
500 // Placeholder implementation
501 prices
502 }
503
504 fn median_aggregation(&self, prices: HashMap<String, PriceData>) -> HashMap<String, PriceData> {
505 // Placeholder implementation
506 prices
507 }
508
509 fn mode_aggregation(&self, prices: HashMap<String, PriceData>) -> HashMap<String, PriceData> {
510 // Placeholder implementation
511 prices
512 }
513
514 fn volume_weighted_aggregation(&self, prices: HashMap<String, PriceData>) -> HashMap<String, PriceData> {
515 // Placeholder implementation
516 prices
517 }
518
519 fn time_weighted_aggregation(&self, prices: HashMap<String, PriceData>) -> HashMap<String, PriceData> {
520 // Placeholder implementation
521 prices
522 }
523
524 fn outlier_filtered_aggregation(&self, prices: HashMap<String, PriceData>) -> HashMap<String, PriceData> {
525 // Placeholder implementation
526 prices
527 }
528
529 fn consensus_aggregation(&self, prices: HashMap<String, PriceData>) -> HashMap<String, PriceData> {
530 // Placeholder implementation
531 prices
532 }
533
534 async fn calculate_consensus_price(&self, prices: &[&PriceData]) -> Result<f64, Box<dyn std::error::Error>> {
535 if prices.is_empty() {
536 return Err("No prices provided for consensus".into());
537 }
538
539 // Simple median consensus for now
540 let mut price_values: Vec<f64> = prices.iter().map(|p| p.price).collect();
541 price_values.sort_by(|a, b| a.partial_cmp(b).unwrap());
542
543 let len = price_values.len();
544 let consensus_price = if len % 2 == 0 {
545 (price_values[len / 2 - 1] + price_values[len / 2]) / 2.0
546 } else {
547 price_values[len / 2]
548 };
549
550 Ok(consensus_price)
551 }
552
553 fn calculate_confidence_score(&self, prices: &[&PriceData]) -> f64 {
554 if prices.len() < 2 {
555 return 0.5;
556 }
557
558 // Calculate price variance as inverse confidence
559 let mean_price = prices.iter().map(|p| p.price).sum::<f64>() / prices.len() as f64;
560 let variance = prices.iter()
561 .map(|p| (p.price - mean_price).powi(2))
562 .sum::<f64>() / prices.len() as f64;
563
564 let std_dev = variance.sqrt();
565 let coefficient_of_variation = std_dev / mean_price;
566
567 // Lower variance = higher confidence
568 (1.0 - coefficient_of_variation.min(1.0)).max(0.0)
569 }
570
571 async fn update_consensus_feeds(&mut self) -> Result<(), Box<dyn std::error::Error>> {
572 let resource_types = ["storage", "bandwidth", "compute"];
573
574 for resource_type in &resource_types {
575 if let Ok(consensus_price) = self.get_consensus_price(resource_type).await {
576 let feed = PriceFeed {
577 feed_id: format!("consensus_{}", resource_type),
578 resource_type: resource_type.to_string(),
579 current_price: consensus_price.price,
580 price_history: Vec::new(), // Would maintain history in real implementation
581 confidence_interval: (consensus_price.price * 0.95, consensus_price.price * 1.05),
582 last_update: consensus_price.timestamp,
583 update_frequency: Duration::from_secs(300), // 5 minutes
584 };
585
586 self.price_feeds.insert(resource_type.to_string(), feed);
587 }
588 }
589
590 Ok(())
591 }
592 }
593
594 impl ConsensusEngine {
595 fn new() -> Self {
596 Self {
597 consensus_algorithms: HashMap::new(),
598 oracle_weights: HashMap::new(),
599 historical_accuracy: HashMap::new(),
600 dispute_manager: DisputeManager {
601 active_disputes: HashMap::new(),
602 resolution_history: Vec::new(),
603 arbitrators: Vec::new(),
604 },
605 }
606 }
607 }
608
609 impl ValidationSystem {
610 fn new() -> Self {
611 Self {
612 validation_rules: Vec::new(),
613 anomaly_detector: AnomalyDetector {
614 detection_models: Vec::new(),
615 threshold_settings: ThresholdSettings {
616 price_deviation_threshold: 0.15, // 15% deviation
617 volume_spike_threshold: 2.0, // 2x volume spike
618 volatility_threshold: 0.5, // 50% volatility
619 correlation_threshold: 0.8, // 80% correlation
620 },
621 alert_system: AlertSystem {
622 alert_channels: Vec::new(),
623 escalation_policy: "standard".to_string(),
624 notification_templates: HashMap::new(),
625 },
626 },
627 quality_assessor: QualityAssessor {
628 quality_metrics: Vec::new(),
629 scoring_algorithm: ScoringAlgorithm::WeightedSum,
630 quality_thresholds: QualityThresholds {
631 minimum_quality_score: 0.7,
632 warning_threshold: 0.8,
633 critical_threshold: 0.6,
634 },
635 },
636 }
637 }
638
639 async fn validate_price(&self, price_data: &PriceData) -> Result<bool, Box<dyn std::error::Error>> {
640 // Basic validation rules
641 if price_data.price <= 0.0 {
642 return Ok(false);
643 }
644
645 if price_data.confidence_score < 0.5 {
646 return Ok(false);
647 }
648
649 // Check for anomalies
650 let is_anomaly = self.anomaly_detector.detect_anomaly(price_data).await?;
651 if is_anomaly {
652 return Ok(false);
653 }
654
655 Ok(true)
656 }
657 }
658
659 impl AnomalyDetector {
660 async fn detect_anomaly(&self, _price_data: &PriceData) -> Result<bool, Box<dyn std::error::Error>> {
661 // Placeholder implementation
662 // In practice, this would use statistical analysis or ML models
663 // to detect price anomalies based on historical patterns
664 Ok(false)
665 }
666 }