diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4a40f669..0f832ff3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,6 +46,11 @@ repos: args: [--fix=lf] stages: [commit] + - id: check-added-large-files + name: Block large file commits + args: [--maxkb=1024] + stages: [commit] + # Rust formatting with rustfmt - repo: https://github.com/doublify/pre-commit-rust rev: v1.0 diff --git a/contracts/collaboration/Cargo.toml b/contracts/collaboration/Cargo.toml deleted file mode 100644 index e69de29b..00000000 diff --git a/contracts/governance/src/curation.rs b/contracts/governance/src/curation.rs deleted file mode 100644 index 22f120cb..00000000 --- a/contracts/governance/src/curation.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub struct QualityVote { - pub token_id: u64, - pub voter: Address, - pub score: u8, -} \ No newline at end of file diff --git a/contracts/insurance/API_REFERENCE.md b/contracts/insurance/API_REFERENCE.md deleted file mode 100644 index 5a23c4b4..00000000 --- a/contracts/insurance/API_REFERENCE.md +++ /dev/null @@ -1,574 +0,0 @@ -# Enhanced Insurance System - API Reference - -## Core Functions - -### Initialization -```rust -fn initialize( - env: Env, - admin: Address, - oracle: Address, - token: Address, -) -> Result<(), InsuranceError> -``` -Initialize the insurance contract with admin, oracle, and token addresses. - -### Risk Management - -#### Create/Update Risk Profile -```rust -fn create_risk_profile( - env: Env, - user: Address, - factors: RiskFactors, -) -> Result -``` -Creates or updates a user's risk profile based on provided factors. - -**Parameters:** -- `user`: User address -- `factors`: RiskFactors struct containing completion_rate, reputation_score, etc. - -**Returns:** Profile ID - -#### Get Risk Profile -```rust -fn get_risk_profile(env: Env, user: Address) -> Option -``` -Retrieves a user's current risk profile. - -#### Get Risk Multiplier -```rust -fn get_risk_multiplier(env: Env, risk_score: u32) -> Result -``` -Calculates premium multiplier based on risk score. - -**Returns:** Multiplier in basis points (e.g., 15000 = 1.5x) - -### Policy Management - -#### Purchase Insurance Policy -```rust -fn purchase_policy( - env: Env, - user: Address, - course_id: u64, - coverage_amount: i128, -) -> Result -``` -Purchase insurance with dynamic premium based on user's risk profile. - -**Parameters:** -- `user`: Policy holder address -- `course_id`: Course being insured -- `coverage_amount`: Coverage amount in tokens - -**Returns:** Policy ID - -#### Get Policy Information -```rust -fn get_policy(env: Env, policy_id: u64) -> Option -``` -Retrieve policy details by ID. - -#### Get User's Active Policies -```rust -fn get_active_policies(env: Env, user: Address) -> Vec -``` -List all active policy IDs for a user. - -### Claims Processing - -#### File Insurance Claim -```rust -fn file_claim( - env: Env, - user: Address, - policy_id: u64, - evidence_hash: [u8; 32], - reason: Bytes, -) -> Result -``` -Submit an insurance claim with evidence. - -**Parameters:** -- `policy_id`: Associated policy ID -- `evidence_hash`: 32-byte cryptographic evidence hash -- `reason`: Claim reason description - -**Returns:** Claim ID - -#### Get Claim Information -```rust -fn get_claim(env: Env, claim_id: u64) -> Option -``` -Retrieve claim details and status. - -#### Get Pending Claims -```rust -fn get_pending_claims(env: Env) -> Vec -``` -List claims awaiting oracle verification. - -### Parametric Insurance - -#### Create Parametric Trigger -```rust -fn create_parametric_trigger( - env: Env, - admin: Address, - course_id: u64, - metric: LearningMetric, - threshold: i128, - payout_amount: i128, -) -> Result -``` -Create automatic payout trigger based on learning outcomes. - -**Parameters:** -- `metric`: LearningMetric type (CompletionPercentage, AssessmentScore, etc.) -- `threshold`: Threshold value for trigger activation -- `payout_amount`: Automatic payout amount - -**Returns:** Trigger ID - -#### Execute Parametric Trigger -```rust -fn execute_trigger( - env: Env, - trigger_id: u64, - user: Address, - actual_value: i128, -) -> Result<(), InsuranceError> -``` -Execute trigger if threshold conditions are met. - -### Pool Management - -#### Create Insurance Pool -```rust -fn create_pool( - env: Env, - admin: Address, - name: Bytes, - target_utilization: u32, - risk_reserve_ratio: u32, -) -> Result -``` -Create optimized insurance pool. - -**Parameters:** -- `name`: Pool name/description -- `target_utilization`: Target utilization rate (basis points) -- `risk_reserve_ratio`: Minimum reserve ratio (basis points) - -**Returns:** Pool ID - -#### Add Reinsurance Partner -```rust -fn add_reinsurance_partner( - env: Env, - admin: Address, - pool_id: u64, - partner: Address, - allocation_percentage: u32, -) -> Result<(), InsuranceError> -``` -Add reinsurance partner to pool with allocation percentage. - -#### Optimize Pool Utilization -```rust -fn optimize_pool_utilization( - env: Env, - pool_id: u64, -) -> Result -``` -Calculate and optimize pool performance metrics. - -#### Get Pool Information -```rust -fn get_pool(env: Env, pool_id: u64) -> Option -``` -Retrieve pool configuration and status. - -#### Get Active Pools -```rust -fn get_active_pools(env: Env) -> Vec -``` -List all active pool IDs. - -### Governance - -#### Create Governance Proposal -```rust -fn create_proposal( - env: Env, - proposer: Address, - title: Bytes, - description: Bytes, - proposal_type: ProposalType, - new_value: i128, -) -> Result -``` -Create community governance proposal. - -**Parameters:** -- `proposal_type`: Type of parameter change -- `new_value`: New parameter value - -**Returns:** Proposal ID - -#### Vote on Proposal -```rust -fn vote( - env: Env, - voter: Address, - proposal_id: u64, - support: bool, -) -> Result<(), InsuranceError> -``` -Vote for or against a proposal. - -#### Execute Proposal -```rust -fn execute_proposal( - env: Env, - admin: Address, - proposal_id: u64, -) -> Result<(), InsuranceError> -``` -Execute approved proposal after voting period. - -#### Get Proposal Information -```rust -fn get_proposal(env: Env, proposal_id: u64) -> Option -``` -Retrieve proposal details and vote counts. - -#### Get Governance Parameters -```rust -fn get_governance_parameters(env: Env) -> GovernanceParameters -``` -Retrieve current governance configuration. - -### Tokenization - -#### Create Insurance Token -```rust -fn create_insurance_token( - env: Env, - admin: Address, - pool_id: u64, - name: Bytes, - symbol: Bytes, - total_supply: i128, -) -> Result -``` -Create tokenized representation of insurance pool shares. - -**Returns:** Token ID - -#### Transfer Tokens -```rust -fn transfer_tokens( - env: Env, - from: Address, - to: Address, - token_id: u64, - amount: i128, -) -> Result<(), InsuranceError> -``` -Transfer insurance tokens between addresses. - -#### Get Token Information -```rust -fn get_insurance_token(env: Env, token_id: u64) -> Option -``` -Retrieve token details. - -#### Get Token Balance -```rust -fn get_token_balance(env: Env, holder: Address, token_id: u64) -> i128 -``` -Get token balance for specific holder. - -### Analytics & Compliance - -#### Record Daily Metrics -```rust -fn record_daily_metrics(env: Env) -> Result<(), InsuranceError> -``` -Record daily insurance metrics for analytics. - -#### Generate Actuarial Report -```rust -fn generate_actuarial_report(env: Env, days: u32) -> Result -``` -Generate risk distribution analysis report. - -#### Generate Compliance Report -```rust -fn generate_compliance_report( - env: Env, - admin: Address, - period_days: u32, -) -> Result -``` -Generate regulatory compliance report. - -**Returns:** Report ID - -#### Get Compliance Report -```rust -fn get_compliance_report(env: Env, report_id: u64) -> Option -``` -Retrieve compliance report by ID. - -### Cross-Chain - -#### Register Chain Bridge -```rust -fn register_chain_bridge( - env: Env, - admin: Address, - chain_id: Address, - bridge_address: Address, -) -> Result<(), InsuranceError> -``` -Register cross-chain bridge for multi-chain operations. - -#### Create Cross-Chain Policy -```rust -fn create_cross_chain_policy( - env: Env, - user: Address, - course_id: u64, - coverage_amount: i128, - target_chain: Address, -) -> Result -``` -Create insurance policy for cross-chain coverage. - -## Data Structures - -### RiskFactors -```rust -struct RiskFactors { - completion_rate: u32, // 0-100 - reputation_score: u32, // 0-100 - course_difficulty: u32, // 1-10 - course_duration: u32, // hours - experience_level: u32, // 1-3 - claim_frequency: u32, // count - time_since_last_completion: u64, // seconds -} -``` - -### RiskProfile -```rust -struct RiskProfile { - profile_id: u64, - user: Address, - factors: RiskFactors, - risk_score: u32, // 0-100 - timestamp: u64, -} -``` - -### InsurancePolicy -```rust -struct InsurancePolicy { - policy_id: u64, - holder: Address, - course_id: u64, - risk_profile_id: u64, - base_premium: i128, - risk_multiplier: u32, // basis points - final_premium: i128, - coverage_amount: i128, - start_time: u64, - expiration_time: u64, - status: PolicyStatus, -} -``` - -### AdvancedClaim -```rust -struct AdvancedClaim { - claim_id: u64, - policy_id: u64, - filed_at: u64, - status: ClaimStatus, - ai_confidence: u32, // 0-100 - evidence_hash: [u8; 32], - oracle_verified: bool, - payout_amount: i128, - reason: String, -} -``` - -### ParametricTrigger -```rust -struct ParametricTrigger { - trigger_id: u64, - course_id: u64, - metric: LearningMetric, - threshold: i128, - payout_amount: i128, - is_active: bool, -} -``` - -### OptimizedPool -```rust -struct OptimizedPool { - pool_id: u64, - name: String, - total_assets: i128, - utilization_rate: u32, // basis points - target_utilization: u32, - risk_reserve_ratio: u32, - reinsurance_partners: Vec
, - status: PoolStatus, -} -``` - -### InsuranceProposal -```rust -struct InsuranceProposal { - proposal_id: u64, - title: String, - description: String, - proposal_type: ProposalType, - new_value: i128, - voting_start: u64, - voting_end: u64, - votes_for: u64, - votes_against: u64, - status: ProposalStatus, -} -``` - -### InsuranceToken -```rust -struct InsuranceToken { - token_id: u64, - pool_id: u64, - name: String, - symbol: String, - total_supply: i128, - holder: Address, - balance: i128, -} -``` - -### ComplianceReport -```rust -struct ComplianceReport { - report_id: u64, - period_start: u64, - period_end: u64, - total_policies: u64, - total_claims: u64, - claims_paid: u64, - premiums_collected: i128, - total_payouts: i128, - loss_ratio: u32, // basis points - reserve_ratio: u32, // basis points - generated_at: u64, -} -``` - -## Enumerations - -### PolicyStatus -- `Active`: Policy providing coverage -- `Claimed`: Policy has been claimed against -- `Expired`: Policy has expired -- `Cancelled`: Policy was cancelled - -### ClaimStatus -- `Filed`: Claim submitted -- `AiProcessing`: AI verification in progress -- `AiVerified`: AI verified, awaiting oracle -- `OracleConfirmed`: Oracle confirmed -- `Approved`: Claim paid -- `Rejected`: Claim denied -- `Disputed`: Claim in dispute - -### LearningMetric -- `CompletionPercentage`: Course completion % -- `CompletionTime`: Time to complete course -- `AssessmentScore`: Assessment results -- `EngagementLevel`: User engagement score -- `AttemptCount`: Number of attempts - -### ProposalType -- `PremiumRate`: Base premium rate changes -- `RiskMultiplier`: Risk multiplier ranges -- `UtilizationTarget`: Pool utilization targets -- `ReinsurancePartner`: Reinsurance partnerships -- `Governance`: Governance parameters - -### PoolStatus -- `Active`: Pool accepting policies -- `Paused`: Pool maintenance -- `Liquidating`: Pool in liquidation -- `Closed`: Pool closed - -## Error Codes - -| Code | Error | Description | -|------|-------|-------------| -| 499 | NotInitialized | Contract not initialized | -| 500 | AlreadyInitialized | Contract already initialized | -| 501 | UserNotInsured | User has no active insurance | -| 502 | ClaimNotFound | Claim ID not found | -| 503 | ClaimAlreadyProcessed | Claim already processed | -| 504 | ClaimNotVerified | Claim not verified for payout | -| 505 | InvalidRiskFactors | Risk factors out of range | -| 506 | RiskProfileNotFound | User risk profile not found | -| 507 | PolicyNotFound | Policy ID not found | -| 508 | PolicyExpired | Policy has expired | -| 509 | PolicyAlreadyClaimed | Policy already has claim | -| 510 | InsufficientPremium | Premium amount too low | -| 511 | InvalidParametricTrigger | Invalid trigger parameters | -| 512 | TriggerNotFound | Trigger ID not found | -| 513 | TriggerNotActive | Trigger is deactivated | -| 514 | InvalidLearningMetric | Invalid learning metric type | -| 515 | ClaimAlreadyFiled | Claim already exists for policy | -| 516 | ClaimNotInReviewableState | Claim not ready for review | -| 517 | AiVerificationFailed | AI verification failed | -| 518 | OracleVerificationRequired | Oracle verification needed | -| 519 | PoolNotFound | Pool ID not found | -| 520 | PoolNotActive | Pool is not active | -| 521 | PoolUtilizationTooHigh | Pool utilization exceeded | -| 522 | ReinsurancePartnerNotFound | Reinsurance partner not found | -| 523 | InvalidTokenParameters | Invalid token parameters | -| 524 | TokenNotFound | Token ID not found | -| 525 | InsufficientTokenBalance | Insufficient token balance | -| 526 | ProposalNotFound | Proposal ID not found | -| 527 | VotingPeriodEnded | Voting period has ended | -| 528 | AlreadyVoted | Voter already voted | -| 529 | InvalidProposalType | Invalid proposal type | -| 530 | ProposalNotActive | Proposal not in active state | -| 531 | ComplianceReportNotFound | Report ID not found | -| 532 | InvalidTimeRange | Invalid time range specified | -| 533 | AnalyticsNotAvailable | Analytics data not available | -| 534 | RiskModelNotTrained | Risk model not configured | -| 535 | ExternalOracleError | External oracle service error | -| 536 | CrossChainOperationFailed | Cross-chain operation failed | -| 537 | InvalidCrossChainParameters | Invalid cross-chain parameters | -| 538 | GovernanceQuorumNotMet | Voting quorum not reached | -| 539 | UnauthorizedGovernanceAction | Unauthorized governance action | -| 540 | RiskScoreOutOfRange | Risk score outside valid range | -| 541 | PremiumCalculationError | Error calculating premium | -| 542 | PayoutExceedsCoverage | Payout exceeds coverage amount | -| 543 | EvidenceHashInvalid | Invalid evidence hash format | -| 544 | DisputeResolutionFailed | Dispute resolution failed | -| 545 | PoolLiquidityInsufficient | Insufficient pool liquidity | -| 546 | TokenTransferFailed | Token transfer operation failed | -| 547 | InvalidPoolConfiguration | Invalid pool configuration | -| 548 | ReinsuranceLimitExceeded | Reinsurance allocation exceeded | -| 549 | ParametricConditionNotMet | Parametric trigger conditions not met | -| 550 | ReportGenerationFailed | Compliance report generation failed | \ No newline at end of file diff --git a/contracts/insurance/Cargo.toml b/contracts/insurance/Cargo.toml deleted file mode 100644 index d2627799..00000000 --- a/contracts/insurance/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "enhanced-insurance" -version = "0.2.0" -edition.workspace = true -license.workspace = true -repository.workspace = true - -[lib] -crate-type = ["cdylib", "rlib"] - -[features] - -[dependencies] -soroban-sdk.workspace = true - -[dev-dependencies] - -[lints] -workspace = true \ No newline at end of file diff --git a/contracts/insurance/README.md b/contracts/insurance/README.md deleted file mode 100644 index 28bdec1b..00000000 --- a/contracts/insurance/README.md +++ /dev/null @@ -1,361 +0,0 @@ -# Enhanced Insurance System Documentation - -## Overview - -The Enhanced Insurance System is a comprehensive decentralized insurance solution built on the Stellar blockchain using Soroban smart contracts. It provides advanced risk assessment, dynamic pricing, automated claims processing, and governance features specifically designed for the TeachLink learning platform. - -## Core Features - -### 1. AI-Powered Risk Assessment -- **Dynamic Risk Scoring**: Calculates risk scores based on multiple factors: - - User completion rate history - - Reputation score - - Course difficulty level - - Course duration - - User experience level - - Historical claim frequency - - Time since last course completion -- **Weighted Risk Model**: Configurable weights for different risk factors -- **Real-time Profile Updates**: Risk profiles update automatically based on user activity - -### 2. Dynamic Premium Pricing -- **Base Premium Rate**: Configurable base rate (default 1%) -- **Risk-Based Multipliers**: - - Low risk (0-30): 1.0x multiplier - - Medium risk (31-60): 1.5x multiplier - - High risk (61-100): 3.0x multiplier -- **Automated Calculation**: Premiums calculated automatically based on user risk profile - -### 3. Advanced Claims Processing -- **AI Verification**: Automated claim validation with confidence scoring -- **Multi-layer Validation**: AI + Oracle verification for high-value claims -- **Evidence-based**: Claims require cryptographic evidence hashes -- **Automated Dispute Resolution**: Smart contract-based dispute handling - -### 4. Parametric Insurance -- **Outcome-based Triggers**: Automatic payouts based on learning metrics -- **Supported Metrics**: - - Course completion percentage - - Time to complete course - - Assessment scores - - Engagement levels - - Number of attempts -- **Threshold-based Payouts**: Configurable conditions for automatic execution - -### 5. Insurance Pool Optimization -- **Dynamic Utilization Management**: Automatic pool rebalancing -- **Reinsurance Partnerships**: Risk distribution across multiple entities -- **Performance Analytics**: Real-time pool performance monitoring -- **Reserve Requirements**: Configurable risk reserve ratios - -### 6. Governance System -- **Community-driven Parameters**: Token-weighted voting for insurance parameters -- **Proposal Types**: - - Premium rate changes - - Risk multiplier adjustments - - Pool utilization targets - - Reinsurance partnerships - - Governance parameters -- **Quorum Requirements**: Configurable voting thresholds -- **Execution Delays**: Time-locked proposal execution - -### 7. Insurance Tokenization -- **Pool Shares**: Tokenized representation of insurance pool ownership -- **Transferable Tokens**: Tradeable insurance tokens -- **Liquidity Provision**: Token holders can provide liquidity -- **Revenue Sharing**: Token holders receive premium income - -### 8. Cross-chain Capabilities -- **Multi-chain Support**: Insurance coverage across different blockchains -- **Bridge Integration**: Cross-chain policy management -- **Unified Risk Assessment**: Consistent risk scoring across chains - -### 9. Compliance & Reporting -- **Regulatory Reports**: Automated compliance reporting -- **Audit Trails**: Complete transaction history -- **Loss Ratio Tracking**: Real-time loss monitoring -- **Reserve Ratio Monitoring**: Capital adequacy tracking - -## Architecture - -### Contract Structure -``` -contracts/insurance/ -├── src/ -│ ├── lib.rs # Main contract implementation -│ ├── types.rs # Data structures and types -│ ├── storage.rs # Storage keys and configuration -│ ├── errors.rs # Error definitions -│ └── test.rs # Comprehensive test suite -├── Cargo.toml # Package configuration -└── README.md # This documentation -``` - -### Key Components - -#### Risk Assessment Module -- `create_risk_profile()`: Creates/updates user risk profiles -- `calculate_risk_score()`: Weighted risk calculation algorithm -- `get_risk_multiplier()`: Maps risk scores to premium multipliers - -#### Policy Management -- `purchase_policy()`: Dynamic premium calculation and policy creation -- `get_policy()`: Policy information retrieval -- `get_active_policies()`: User policy listings - -#### Claims Processing -- `file_claim()`: AI-verified claim submission -- `get_claim()`: Claim status and details -- `get_pending_claims()`: Oracle review queue - -#### Parametric Insurance -- `create_parametric_trigger()`: Configurable outcome triggers -- `execute_trigger()`: Automatic payout execution - -#### Pool Management -- `create_pool()`: Insurance pool creation -- `add_reinsurance_partner()`: Risk distribution setup -- `optimize_pool_utilization()`: Performance optimization - -#### Governance -- `create_proposal()`: Community parameter proposals -- `vote()`: Token-weighted voting -- `execute_proposal()`: Approved change implementation - -#### Tokenization -- `create_insurance_token()`: Pool share tokenization -- `transfer_tokens()`: Token transfers and trading - -#### Analytics & Compliance -- `record_daily_metrics()`: Performance tracking -- `generate_compliance_report()`: Regulatory reporting -- `generate_actuarial_report()`: Risk analysis - -## API Reference - -### Initialization -```rust -fn initialize( - env: Env, - admin: Address, - oracle: Address, - token: Address, -) -> Result<(), InsuranceError> -``` - -### Risk Management -```rust -fn create_risk_profile( - env: Env, - user: Address, - factors: RiskFactors, -) -> Result - -fn get_risk_profile(env: Env, user: Address) -> Option - -fn get_risk_multiplier(env: Env, risk_score: u32) -> Result -``` - -### Policy Operations -```rust -fn purchase_policy( - env: Env, - user: Address, - course_id: u64, - coverage_amount: i128, -) -> Result - -fn get_policy(env: Env, policy_id: u64) -> Option -``` - -### Claims Processing -```rust -fn file_claim( - env: Env, - user: Address, - policy_id: u64, - evidence_hash: [u8; 32], - reason: Bytes, -) -> Result - -fn get_claim(env: Env, claim_id: u64) -> Option -``` - -### Parametric Insurance -```rust -fn create_parametric_trigger( - env: Env, - admin: Address, - course_id: u64, - metric: LearningMetric, - threshold: i128, - payout_amount: i128, -) -> Result - -fn execute_trigger( - env: Env, - trigger_id: u64, - user: Address, - actual_value: i128, -) -> Result<(), InsuranceError> -``` - -### Governance -```rust -fn create_proposal( - env: Env, - proposer: Address, - title: Bytes, - description: Bytes, - proposal_type: ProposalType, - new_value: i128, -) -> Result - -fn vote( - env: Env, - voter: Address, - proposal_id: u64, - support: bool, -) -> Result<(), InsuranceError> -``` - -## Configuration Parameters - -### Risk Model Weights -```rust -RiskModelWeights { - completion_rate_weight: 2500, // 25% - reputation_score_weight: 2000, // 20% - course_difficulty_weight: 1500, // 15% - course_duration_weight: 1000, // 10% - experience_level_weight: 1500, // 15% - claim_frequency_weight: 1000, // 10% - time_factor_weight: 500, // 5% -} -``` - -### Risk Multiplier Ranges -```rust -RiskMultiplierRanges { - low_risk_min: 0, - low_risk_max: 10000, // 1.0x - medium_risk_min: 31, - medium_risk_max: 15000, // 1.5x - high_risk_min: 61, - high_risk_max: 30000, // 3.0x -} -``` - -### Governance Parameters -```rust -GovernanceParameters { - quorum_percentage: 5000, // 50% - voting_period_days: 7, - execution_delay_hours: 24, - proposal_threshold: 1000, - veto_power_enabled: true, -} -``` - -## Testing - -The system includes comprehensive tests covering: -- Contract initialization and configuration -- Risk profile creation and scoring -- Dynamic premium calculation -- Policy purchase and management -- Claims processing workflows -- Parametric trigger execution -- Pool optimization features -- Governance proposal lifecycle -- Token transfer operations -- Compliance reporting -- Error handling and edge cases - -Run tests with: -```bash -cd contracts/insurance -cargo test -``` - -## Deployment - -### Prerequisites -- Rust 1.77+ -- Soroban CLI -- Stellar testnet account with funding - -### Deployment Steps -1. Build the contract: -```bash -cd contracts/insurance -cargo build --target wasm32-unknown-unknown --release -``` - -2. Deploy to testnet: -```bash -soroban contract deploy \ - --wasm target/wasm32-unknown-unknown/release/enhanced_insurance.wasm \ - --source YOUR_ACCOUNT_SECRET \ - --rpc-url https://soroban-testnet.stellar.org:443 \ - --network-passphrase "Test SDF Network ; September 2015" -``` - -3. Initialize the contract: -```bash -soroban contract invoke \ - --id CONTRACT_ID \ - --source YOUR_ACCOUNT_SECRET \ - --rpc-url https://soroban-testnet.stellar.org:443 \ - --network-passphrase "Test SDF Network ; September 2015" \ - -- \ - initialize \ - --admin ADMIN_ADDRESS \ - --oracle ORACLE_ADDRESS \ - --token TOKEN_ADDRESS -``` - -## Security Considerations - -### Access Control -- Admin-only functions for critical operations -- User authorization required for sensitive actions -- Oracle verification for high-value claims - -### Risk Management -- Maximum payout limits per policy -- Pool utilization caps -- Minimum reserve requirements -- Reinsurance diversification - -### Governance Security -- Quorum requirements for proposals -- Voting period delays -- Veto power for emergency situations -- Proposal threshold requirements - -## Future Enhancements - -### AI/ML Integration -- Machine learning models for risk prediction -- Natural language processing for claim analysis -- Anomaly detection for fraud prevention - -### Advanced Features -- Yield farming for insurance tokens -- Automated market making for liquidity -- Cross-protocol integrations -- DeFi composability - -### Scalability -- Sharding for large user bases -- Layer 2 solutions for cost reduction -- Batch processing optimizations -- Caching mechanisms - -## Support - -For issues, feature requests, or questions: -- GitHub Issues: [Repository Link] -- Documentation: [Docs Link] -- Community: [Discord/Telegram Link] \ No newline at end of file diff --git a/contracts/insurance/build_output.txt b/contracts/insurance/build_output.txt deleted file mode 100644 index fc4fbc6d..00000000 --- a/contracts/insurance/build_output.txt +++ /dev/null @@ -1,129 +0,0 @@ - Compiling insurance-pool v0.1.0 (/home/knights/Documents/Project/Drips/teachLink_contract/contracts/insurance) -warning: unused import: `Ledger` - --> contracts/insurance/src/test.rs:4:45 - | -4 | use soroban_sdk::{testutils::{Address as _, Ledger}, Address, Env}; - | ^^^^^^ - | - = note: `#[warn(unused_imports)]` on by default - -warning: use of deprecated method `soroban_sdk::Env::register_stellar_asset_contract`: use [Env::register_stellar_asset_contract_v2] - --> contracts/insurance/src/test.rs:17:30 - | -17 | let token_contract = env.register_stellar_asset_contract(token_admin); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: `#[warn(deprecated)]` on by default - -warning: use of deprecated method `soroban_sdk::Env::register_contract`: use `register` - --> contracts/insurance/src/test.rs:21:27 - | -21 | let contract_id = env.register_contract(None, InsurancePool); - | ^^^^^^^^^^^^^^^^^ - -error[E0599]: no method named `mint` found for struct `Client` in the current scope - --> contracts/insurance/src/test.rs:31:11 - | -31 | token.mint(&user, &1000); - | ^^^^ method not found in `Client<'_>` - -error[E0599]: no method named `mint` found for struct `Client` in the current scope - --> contracts/insurance/src/test.rs:32:11 - | -32 | token.mint(&contract_id, &1000); - | ^^^^ method not found in `Client<'_>` - -error[E0277]: `ClaimStatus` doesn't implement `Debug` - --> contracts/insurance/src/test.rs:47:5 - | -47 | assert_eq!(claim.status, ClaimStatus::Pending); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `ClaimStatus` - | - = note: add `#[derive(Debug)]` to `ClaimStatus` or manually `impl Debug for ClaimStatus` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `ClaimStatus` with `#[derive(Debug)]` - --> contracts/insurance/src/lib.rs:20:1 - | -20 + #[derive(Debug)] -21 | pub enum ClaimStatus { - | - -error[E0277]: `ClaimStatus` doesn't implement `Debug` - --> contracts/insurance/src/test.rs:53:5 - | -53 | assert_eq!(claim.status, ClaimStatus::Verified); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `ClaimStatus` - | - = note: add `#[derive(Debug)]` to `ClaimStatus` or manually `impl Debug for ClaimStatus` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `ClaimStatus` with `#[derive(Debug)]` - --> contracts/insurance/src/lib.rs:20:1 - | -20 + #[derive(Debug)] -21 | pub enum ClaimStatus { - | - -error[E0277]: `ClaimStatus` doesn't implement `Debug` - --> contracts/insurance/src/test.rs:59:5 - | -59 | assert_eq!(claim.status, ClaimStatus::Paid); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `ClaimStatus` - | - = note: add `#[derive(Debug)]` to `ClaimStatus` or manually `impl Debug for ClaimStatus` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `ClaimStatus` with `#[derive(Debug)]` - --> contracts/insurance/src/lib.rs:20:1 - | -20 + #[derive(Debug)] -21 | pub enum ClaimStatus { - | - -warning: use of deprecated method `soroban_sdk::Env::register_stellar_asset_contract`: use [Env::register_stellar_asset_contract_v2] - --> contracts/insurance/src/test.rs:78:30 - | -78 | let token_contract = env.register_stellar_asset_contract(token_admin); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: use of deprecated method `soroban_sdk::Env::register_contract`: use `register` - --> contracts/insurance/src/test.rs:81:27 - | -81 | let contract_id = env.register_contract(None, InsurancePool); - | ^^^^^^^^^^^^^^^^^ - -error[E0599]: no method named `mint` found for struct `Client` in the current scope - --> contracts/insurance/src/test.rs:85:11 - | -85 | token.mint(&user, &1000); - | ^^^^ method not found in `Client<'_>` - -error[E0277]: `ClaimStatus` doesn't implement `Debug` - --> contracts/insurance/src/test.rs:94:5 - | -94 | assert_eq!(claim.status, ClaimStatus::Rejected); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Debug` is not implemented for `ClaimStatus` - | - = note: add `#[derive(Debug)]` to `ClaimStatus` or manually `impl Debug for ClaimStatus` - = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider annotating `ClaimStatus` with `#[derive(Debug)]` - --> contracts/insurance/src/lib.rs:20:1 - | -20 + #[derive(Debug)] -21 | pub enum ClaimStatus { - | - -warning: use of deprecated method `soroban_sdk::Env::register_stellar_asset_contract`: use [Env::register_stellar_asset_contract_v2] - --> contracts/insurance/src/test.rs:112:30 - | -112 | let token_contract = env.register_stellar_asset_contract(token_admin); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -warning: use of deprecated method `soroban_sdk::Env::register_contract`: use `register` - --> contracts/insurance/src/test.rs:113:27 - | -113 | let contract_id = env.register_contract(None, InsurancePool); - | ^^^^^^^^^^^^^^^^^ - -Some errors have detailed explanations: E0277, E0599. -For more information about an error, try `rustc --explain E0277`. -warning: `insurance-pool` (lib test) generated 7 warnings -error: could not compile `insurance-pool` (lib test) due to 11 previous errors; 7 warnings emitted diff --git a/contracts/insurance/src/content_protection.rs b/contracts/insurance/src/content_protection.rs deleted file mode 100644 index e7c52d96..00000000 --- a/contracts/insurance/src/content_protection.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub struct ContentInsurancePolicy { - pub token_id: u64, - pub coverage_amount: u128, - pub premium_paid: u128, - pub active: bool, -} - -pub struct Order { - pub token_id: u64, - pub trader: Address, - pub price: u128, - pub is_buy: bool, -} \ No newline at end of file diff --git a/contracts/insurance/src/errors.rs b/contracts/insurance/src/errors.rs deleted file mode 100644 index 5fc3ebd9..00000000 --- a/contracts/insurance/src/errors.rs +++ /dev/null @@ -1,76 +0,0 @@ -use soroban_sdk::contracterror; - -/// Enhanced insurance module errors -#[contracterror] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum InsuranceError { - // Existing errors (499-504) - NotInitialized = 499, - AlreadyInitialized = 500, - UserNotInsured = 501, - ClaimNotFound = 502, - ClaimAlreadyProcessed = 503, - ClaimNotVerified = 504, - - // New errors for enhanced features (505-550) - InvalidRiskFactors = 505, - RiskProfileNotFound = 506, - PolicyNotFound = 507, - PolicyExpired = 508, - PolicyAlreadyClaimed = 509, - InsufficientPremium = 510, - InvalidParametricTrigger = 511, - TriggerNotFound = 512, - TriggerNotActive = 513, - InvalidLearningMetric = 514, - ClaimAlreadyFiled = 515, - ClaimNotInReviewableState = 516, - AiVerificationFailed = 517, - OracleVerificationRequired = 518, - PoolNotFound = 519, - PoolNotActive = 520, - PoolUtilizationTooHigh = 521, - ReinsurancePartnerNotFound = 522, - InvalidTokenParameters = 523, - TokenNotFound = 524, - InsufficientTokenBalance = 525, - ProposalNotFound = 526, - VotingPeriodEnded = 527, - AlreadyVoted = 528, - InvalidProposalType = 529, - ProposalNotActive = 530, - ComplianceReportNotFound = 531, - InvalidTimeRange = 532, - AnalyticsNotAvailable = 533, - RiskModelNotTrained = 534, - ExternalOracleError = 535, - CrossChainOperationFailed = 536, - InvalidCrossChainParameters = 537, - GovernanceQuorumNotMet = 538, - UnauthorizedGovernanceAction = 539, - RiskScoreOutOfRange = 540, - PremiumCalculationError = 541, - PayoutExceedsCoverage = 542, - EvidenceHashInvalid = 543, - DisputeResolutionFailed = 544, - PoolLiquidityInsufficient = 545, - TokenTransferFailed = 546, - InvalidPoolConfiguration = 547, - ReinsuranceLimitExceeded = 548, - ParametricConditionNotMet = 549, - ReportGenerationFailed = 550, - - // RBAC & Multi-sig Errors (551+) - UnauthorizedRole = 551, - TransferNotPending = 552, - TimelockNotExpired = 553, - NotASigner = 554, - AlreadyApproved = 555, - ThresholdNotMet = 556, - OperationExecuted = 557, - OperationNotFound = 558, -} - -/// Result type alias for insurance operations -#[allow(dead_code)] -pub type InsuranceResult = core::result::Result; diff --git a/contracts/insurance/src/lib.rs b/contracts/insurance/src/lib.rs deleted file mode 100644 index e9e6582b..00000000 --- a/contracts/insurance/src/lib.rs +++ /dev/null @@ -1,1363 +0,0 @@ -#![allow(clippy::all)] -#![allow(unused)] - -//! Enhanced Insurance Contract -//! -//! This contract implements a comprehensive decentralized insurance system with: -//! - AI-powered risk assessment and dynamic pricing -//! - Automated claims processing with AI verification -//! - Parametric insurance for learning outcomes -//! - Insurance pool optimization and reinsurance -//! - Cross-chain insurance and risk sharing -//! - Insurance tokenization and governance -//! - Compliance and regulatory reporting -//! -//! # Core Features -//! -//! ## Risk Assessment -//! - AI-powered risk scoring based on user history and course factors -//! - Dynamic premium calculation using risk multipliers -//! - Real-time risk profile updates -//! -//! ## Policy Management -//! - Time-based policies with expiration -//! - Multi-claim support per policy -//! - Parametric triggers for automatic payouts -//! -//! ## Claims Processing -//! - AI verification with confidence scoring -//! - Multi-layer validation (AI + Oracle) -//! - Automated dispute resolution -//! -//! ## Pool Optimization -//! - Dynamic utilization management -//! - Reinsurance partnerships -//! - Cross-pool risk sharing -//! -//! ## Governance -//! - Community-driven parameter changes -//! - Token-weighted voting -//! - Transparent proposal process - -#![no_std] -#![allow(clippy::needless_pass_by_value)] -#![allow(clippy::must_use_candidate)] -#![allow(clippy::missing_panics_doc)] -#![allow(clippy::missing_errors_doc)] -#![allow(clippy::doc_markdown)] -#![allow(clippy::panic_in_result_fn)] - -mod errors; -mod storage; -mod types; - -use crate::errors::InsuranceError; -use crate::storage::*; -use crate::types::*; -use soroban_sdk::{ - contract, contractimpl, contracttype, token, vec, Address, Bytes, Env, String, Vec, -}; - -#[contract] -pub struct EnhancedInsurance; - -#[contractimpl] -impl EnhancedInsurance { - // ===== Initialization ===== - - /// Initialize the enhanced insurance contract - pub fn initialize( - env: Env, - admin: Address, - oracle: Address, - token: Address, - ) -> Result<(), InsuranceError> { - if env.storage().instance().has(&DataKey::Admin) { - return Err(InsuranceError::AlreadyInitialized); - } - - env.storage().instance().set(&DataKey::Admin, &admin); - env.storage().instance().set(&DataKey::Oracle, &oracle); - env.storage().instance().set(&DataKey::Token, &token); - - // RBAC Initialization: Set admin as SUPER_ADMIN - env.storage().instance().set(&DataKey::HasRole(ROLE_SUPER_ADMIN, admin.clone()), &true); - - // Multi-sig Initialization: Admin is the first signer - let mut signers: Vec
= Vec::new(&env); - signers.push_back(admin.clone()); - env.storage().instance().set(&DataKey::MultiSigSigners, &signers); - env.storage().instance().set(&DataKey::MultiSigThreshold, &1u32); - env.storage().instance().set(&DataKey::OperationCount, &0u64); - - // Set default configuration parameters - env.storage() - .instance() - .set(&DataKey::RiskProfileCount, &0u64); - env.storage().instance().set(&DataKey::PolicyCount, &0u64); - env.storage().instance().set(&DataKey::ClaimCount, &0u64); - env.storage().instance().set(&DataKey::TriggerCount, &0u64); - env.storage().instance().set(&DataKey::PoolCount, &0u64); - env.storage().instance().set(&DataKey::TokenCount, &0u64); - env.storage().instance().set(&DataKey::ProposalCount, &0u64); - env.storage().instance().set(&DataKey::ReportCount, &0u64); - - // Emit Initialization Event for Audit - env.events().publish((soroban_sdk::symbol_short!("Init"), admin), (oracle, token)); - - // Set default configuration - env.storage() - .instance() - .set(&DataKey::RiskModelWeights, &RiskModelWeights::default()); - env.storage() - .instance() - .set(&DataKey::BasePremiumRate, &100i128); // 1% base rate - env.storage().instance().set( - &DataKey::RiskMultiplierRanges, - &RiskMultiplierRanges::default(), - ); - env.storage() - .instance() - .set(&DataKey::UtilizationTargets, &UtilizationTargets::default()); - env.storage() - .instance() - .set(&DataKey::MinimumRiskReserve, &1500u32); // 15% - env.storage().instance().set( - &DataKey::GovernanceParameters, - &GovernanceParameters::default(), - ); - env.storage() - .instance() - .set(&DataKey::GovernanceQuorum, &5000u32); // 50% - env.storage().instance().set(&DataKey::VotingPeriod, &7u32); // 7 days - - Ok(()) - } - - // ===== RBAC Helper ===== - - fn check_role(env: &Env, user: &Address, role: u32) -> Result<(), InsuranceError> { - user.require_auth(); - // Super Admin bypass - if env.storage().instance().get(&DataKey::HasRole(ROLE_SUPER_ADMIN, user.clone())).unwrap_or(false) { - return Ok(()); - } - if env.storage().instance().get(&DataKey::HasRole(role, user.clone())).unwrap_or(false) { - return Ok(()); - } - Err(InsuranceError::UnauthorizedRole) - } - - // ===== Governance & RBAC Endpoints ===== - - /// Grant a specific role (Super Admin only) - pub fn grant_role(env: Env, caller: Address, role: u32, account: Address) -> Result<(), InsuranceError> { - Self::check_role(&env, &caller, ROLE_SUPER_ADMIN)?; - env.storage().instance().set(&DataKey::HasRole(role, account.clone()), &true); - env.events().publish((soroban_sdk::symbol_short!("RoleGnt"), account), role); - Ok(()) - } - - /// Revoke a specific role (Super Admin only) - pub fn revoke_role(env: Env, caller: Address, role: u32, account: Address) -> Result<(), InsuranceError> { - Self::check_role(&env, &caller, ROLE_SUPER_ADMIN)?; - env.storage().instance().set(&DataKey::HasRole(role, account.clone()), &false); - env.events().publish((soroban_sdk::symbol_short!("RoleRvk"), account), role); - Ok(()) - } - - /// Initiate admin transfer with 24-hour timelock - pub fn transfer_admin(env: Env, caller: Address, new_admin: Address) -> Result<(), InsuranceError> { - Self::check_role(&env, &caller, ROLE_SUPER_ADMIN)?; - let ready_at = env.ledger().timestamp() + 86400; // 24 hours - env.storage().instance().set(&DataKey::PendingAdminTransfer, &new_admin); - env.storage().instance().set(&DataKey::AdminTransferTimestamp, &ready_at); - env.events().publish((soroban_sdk::symbol_short!("AdmTrns"), new_admin), ready_at); - Ok(()) - } - - /// Claim admin role after timelock expires - pub fn accept_admin(env: Env, new_admin: Address) -> Result<(), InsuranceError> { - new_admin.require_auth(); - let pending: Address = env.storage().instance().get(&DataKey::PendingAdminTransfer).ok_or(InsuranceError::TransferNotPending)?; - if pending != new_admin { return Err(InsuranceError::UnauthorizedRole); } - - let ready_at = env.storage().instance().get(&DataKey::AdminTransferTimestamp).unwrap_or(u64::MAX); - if env.ledger().timestamp() < ready_at { return Err(InsuranceError::TimelockNotExpired); } - - // Finalize transfer - let old_admin: Address = env.storage().instance().get(&DataKey::Admin).ok_or(InsuranceError::NotInitialized)?; - env.storage().instance().set(&DataKey::HasRole(ROLE_SUPER_ADMIN, old_admin), &false); - env.storage().instance().set(&DataKey::HasRole(ROLE_SUPER_ADMIN, new_admin.clone()), &true); - env.storage().instance().set(&DataKey::Admin, &new_admin); - - env.storage().instance().remove(&DataKey::PendingAdminTransfer); - env.storage().instance().remove(&DataKey::AdminTransferTimestamp); - - env.events().publish((soroban_sdk::symbol_short!("AdmAccp"), new_admin), env.ledger().timestamp()); - Ok(()) - } - - // ===== Multi-Sig Framework ===== - - /// Propose a critical action (Signers only) - pub fn propose_action(env: Env, proposer: Address, action: CriticalAction) -> Result { - proposer.require_auth(); - let signers: Vec
= env.storage().instance().get(&DataKey::MultiSigSigners).unwrap_or_else(|| Vec::new(&env)); - if !signers.contains(&proposer) { return Err(InsuranceError::NotASigner); } - - let mut count: u64 = env.storage().instance().get(&DataKey::OperationCount).unwrap_or(0); - count += 1; - let id = count as u32; - - let op = CriticalOperation { - id, - action: action.clone(), - proposer: proposer.clone(), - created_at: env.ledger().timestamp(), - ready_at: env.ledger().timestamp() + 10, // Small delay for demo, in production would be higher - executed: false, - }; - - env.storage().instance().set(&DataKey::CriticalOperation(id), &op); - env.storage().instance().set(&DataKey::OperationCount, &count); - - // Auto-approve by proposer - let mut approvals = Vec::new(&env); - approvals.push_back(proposer); - env.storage().instance().set(&DataKey::OperationApprovals(id), &approvals); - - env.events().publish((soroban_sdk::symbol_short!("PropAct"), id), action); - Ok(id) - } - - /// Approve a pending action - pub fn approve_action(env: Env, signer: Address, op_id: u32) -> Result<(), InsuranceError> { - signer.require_auth(); - let signers: Vec
= env.storage().instance().get(&DataKey::MultiSigSigners).unwrap_or_else(|| Vec::new(&env)); - if !signers.contains(&signer) { return Err(InsuranceError::NotASigner); } - - let op: CriticalOperation = env.storage().instance().get(&DataKey::CriticalOperation(op_id)).ok_or(InsuranceError::OperationNotFound)?; - if op.executed { return Err(InsuranceError::OperationExecuted); } - - let mut approvals: Vec
= env.storage().instance().get(&DataKey::OperationApprovals(op_id)).unwrap_or_else(|| Vec::new(&env)); - if approvals.contains(&signer) { return Err(InsuranceError::AlreadyApproved); } - - approvals.push_back(signer.clone()); - env.storage().instance().set(&DataKey::OperationApprovals(op_id), &approvals); - - env.events().publish((soroban_sdk::symbol_short!("Approve"), op_id), signer); - Ok(()) - } - - /// Execute an approved action - pub fn execute_action(env: Env, executor: Address, op_id: u32) -> Result<(), InsuranceError> { - executor.require_auth(); - let mut op: CriticalOperation = env.storage().instance().get(&DataKey::CriticalOperation(op_id)).ok_or(InsuranceError::OperationNotFound)?; - if op.executed { return Err(InsuranceError::OperationExecuted); } - if env.ledger().timestamp() < op.ready_at { return Err(InsuranceError::TimelockNotExpired); } - - let approvals: Vec
= env.storage().instance().get(&DataKey::OperationApprovals(op_id)).unwrap_or_else(|| Vec::new(&env)); - let threshold = env.storage().instance().get(&DataKey::MultiSigThreshold).unwrap_or(1); - - if (approvals.len() as u32) < threshold { return Err(InsuranceError::ThresholdNotMet); } - - // Execute logic based on action - match &op.action { - CriticalAction::ChangeBasePremium(new_rate) => { - env.storage().instance().set(&DataKey::BasePremiumRate, new_rate); - }, - CriticalAction::PausePool(pool_id) => { - let mut pool: OptimizedPool = env.storage().instance().get(&DataKey::Pool(*pool_id)).ok_or(InsuranceError::PoolNotFound)?; - pool.status = PoolStatus::Paused; - env.storage().instance().set(&DataKey::Pool(*pool_id), &pool); - }, - _ => { /* Other actions implemented similarly */ } - } - - op.executed = true; - env.storage().instance().set(&DataKey::CriticalOperation(op_id), &op); - - env.events().publish((soroban_sdk::symbol_short!("Execute"), op_id), ()); - Ok(()) - } - - // ===== Risk Assessment Module ===== - - /// Create or update a user's risk profile - pub fn create_risk_profile( - env: Env, - user: Address, - factors: RiskFactors, - ) -> Result { - user.require_auth(); - - // Validate risk factors - if factors.completion_rate > 100 || factors.reputation_score > 100 { - return Err(InsuranceError::InvalidRiskFactors); - } - - if factors.course_difficulty > 10 || factors.experience_level > 3 { - return Err(InsuranceError::InvalidRiskFactors); - } - - // Calculate risk score using weighted model - let weights: RiskModelWeights = env - .storage() - .instance() - .get(&DataKey::RiskModelWeights) - .unwrap_or_else(RiskModelWeights::default); - - let risk_score = Self::calculate_risk_score(&factors, &weights)?; - - // Update existing profile or create new one - let mut profile_id = env - .storage() - .instance() - .get(&DataKey::RiskProfileByUser(user.clone())) - .unwrap_or(0); - - if profile_id == 0 { - let mut count = env - .storage() - .instance() - .get(&DataKey::RiskProfileCount) - .unwrap_or(0); - count += 1; - profile_id = count; - env.storage() - .instance() - .set(&DataKey::RiskProfileCount, &count); - env.storage() - .instance() - .set(&DataKey::RiskProfileByUser(user.clone()), &profile_id); - } - - let profile = RiskProfile { - profile_id, - user: user.clone(), - factors, - risk_score, - timestamp: env.ledger().timestamp(), - }; - - env.storage() - .instance() - .set(&DataKey::RiskProfile(profile_id), &profile); - - Ok(profile_id) - } - - /// Calculate risk score based on factors and weights - fn calculate_risk_score( - factors: &RiskFactors, - weights: &RiskModelWeights, - ) -> Result { - // Normalize all factors to 0-100 scale - let completion_factor = 100 - factors.completion_rate; // Inverse: lower completion = higher risk - let reputation_factor = 100 - factors.reputation_score; // Inverse: lower reputation = higher risk - let difficulty_factor = factors.course_difficulty * 10; // Scale 1-10 to 10-100 - let duration_factor = (factors.course_duration / 10).min(100); // Cap at 100 - let experience_factor = match factors.experience_level { - 1 => 80, // Beginner - high risk - 2 => 40, // Intermediate - medium risk - 3 => 10, // Advanced - low risk - _ => 50, // Unknown - default medium risk - }; - let frequency_factor = factors.claim_frequency.min(100); - let time_factor = (factors.time_since_last_completion / 86400).min(100) as u32; // Days since last completion - - // Calculate weighted score - let total_weight = weights.completion_rate_weight - + weights.reputation_score_weight - + weights.course_difficulty_weight - + weights.course_duration_weight - + weights.experience_level_weight - + weights.claim_frequency_weight - + weights.time_factor_weight; - - if total_weight == 0 { - return Err(InsuranceError::RiskModelNotTrained); - } - - let weighted_score = ((completion_factor as u64 * weights.completion_rate_weight as u64) - + (reputation_factor as u64 * weights.reputation_score_weight as u64) - + (difficulty_factor as u64 * weights.course_difficulty_weight as u64) - + (duration_factor as u64 * weights.course_duration_weight as u64) - + (experience_factor as u64 * weights.experience_level_weight as u64) - + (frequency_factor as u64 * weights.claim_frequency_weight as u64) - + (time_factor as u64 * weights.time_factor_weight as u64)) - / total_weight as u64; - - Ok(weighted_score.min(100) as u32) - } - - /// Get risk profile for a user - pub fn get_risk_profile(env: Env, user: Address) -> Option { - let profile_id = env - .storage() - .instance() - .get(&DataKey::RiskProfileByUser(user))?; - env.storage() - .instance() - .get(&DataKey::RiskProfile(profile_id)) - } - - /// Get risk multiplier based on risk score - pub fn get_risk_multiplier(env: Env, risk_score: u32) -> Result { - if risk_score > 100 { - return Err(InsuranceError::RiskScoreOutOfRange); - } - - let ranges: RiskMultiplierRanges = env - .storage() - .instance() - .get(&DataKey::RiskMultiplierRanges) - .unwrap_or_else(RiskMultiplierRanges::default); - - let multiplier = if risk_score <= ranges.low_risk_max { - ranges.low_risk_max - } else if risk_score <= ranges.medium_risk_max { - ranges.medium_risk_max - } else { - ranges.high_risk_max - }; - - Ok(multiplier) - } - - // ===== Policy Management Module ===== - - /// Purchase insurance policy with dynamic pricing - pub fn purchase_policy( - env: Env, - user: Address, - course_id: u64, - coverage_amount: i128, - ) -> Result { - user.require_auth(); - - // Get or create risk profile - let profile = Self::get_risk_profile(env.clone(), user.clone()) - .ok_or(InsuranceError::RiskProfileNotFound)?; - - // Calculate base premium - let base_premium_rate: i128 = env - .storage() - .instance() - .get(&DataKey::BasePremiumRate) - .unwrap_or(100); // 1% default - - let base_premium = (coverage_amount * base_premium_rate) / 10000; - - // Apply risk multiplier - let risk_multiplier = Self::get_risk_multiplier(env.clone(), profile.risk_score)?; - let final_premium = (base_premium * risk_multiplier as i128) / 10000; - - // Transfer premium payment - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - token_client.transfer(&user, &env.current_contract_address(), &final_premium); - - // Create policy - let mut policy_count = env - .storage() - .instance() - .get(&DataKey::PolicyCount) - .unwrap_or(0); - policy_count += 1; - - let policy = InsurancePolicy { - policy_id: policy_count, - holder: user.clone(), - course_id, - risk_profile_id: profile.profile_id, - base_premium, - risk_multiplier, - final_premium, - coverage_amount, - start_time: env.ledger().timestamp(), - expiration_time: env.ledger().timestamp() + 30 * 24 * 60 * 60, // 30 days - status: PolicyStatus::Active, - }; - - env.storage() - .instance() - .set(&DataKey::Policy(policy_count), &policy); - env.storage() - .instance() - .set(&DataKey::PolicyCount, &policy_count); - env.storage().instance().set( - &DataKey::PolicyByUser(user.clone(), course_id), - &policy_count, - ); - - // Update user's active policies - let mut active_policies: Vec = env - .storage() - .instance() - .get(&DataKey::ActivePolicies(user.clone())) - .unwrap_or_else(|| vec![&env]); - active_policies.push_back(policy_count); - env.storage() - .instance() - .set(&DataKey::ActivePolicies(user), &active_policies); - - Ok(policy_count) - } - - // ===== Claims Processing Module ===== - - /// File an insurance claim with evidence - pub fn file_claim( - env: Env, - user: Address, - policy_id: u64, - evidence: Bytes, - reason: Bytes, - ) -> Result { - user.require_auth(); - - // Validate policy exists and is active - let mut policy: InsurancePolicy = env - .storage() - .instance() - .get(&DataKey::Policy(policy_id)) - .ok_or(InsuranceError::PolicyNotFound)?; - - if policy.status != PolicyStatus::Active { - return Err(InsuranceError::PolicyExpired); - } - - if env.ledger().timestamp() > policy.expiration_time { - return Err(InsuranceError::PolicyExpired); - } - - // Check if claim already exists for this policy - if env - .storage() - .instance() - .has(&DataKey::ClaimByPolicy(policy_id)) - { - return Err(InsuranceError::ClaimAlreadyFiled); - } - - // AI verification would happen here in a real implementation - // For now, we'll simulate with a confidence score - let ai_confidence = 75u32; // Simulated AI confidence - - // Create claim - let mut claim_count = env - .storage() - .instance() - .get(&DataKey::ClaimCount) - .unwrap_or(0); - claim_count += 1; - - let claim = AdvancedClaim { - claim_id: claim_count, - policy_id, - filed_at: env.ledger().timestamp(), - status: if ai_confidence >= 80 { - ClaimStatus::AiVerified - } else { - ClaimStatus::AiProcessing - }, - ai_confidence, - evidence, - oracle_verified: false, - payout_amount: if ai_confidence >= 80 { - policy.coverage_amount - } else { - 0 - }, - reason: String::from_str(&env, &"Claim filed"), // Simplified for now - }; - - env.storage() - .instance() - .set(&DataKey::Claim(claim_count), &claim); - env.storage() - .instance() - .set(&DataKey::ClaimByPolicy(policy_id), &claim_count); - env.storage() - .instance() - .set(&DataKey::ClaimCount, &claim_count); - - // Update policy status - if ai_confidence >= 80 { - policy.status = PolicyStatus::Claimed; - env.storage() - .instance() - .set(&DataKey::Policy(policy_id), &policy); - } - - // Add to pending claims if needs oracle review - if ai_confidence < 80 { - let mut pending: Vec = env - .storage() - .instance() - .get(&DataKey::PendingClaims) - .unwrap_or_else(|| Vec::new(&env)); - pending.push_back(claim_count); - env.storage() - .instance() - .set(&DataKey::PendingClaims, &pending); - } - - Ok(claim_count) - } - - /// Get claim information - pub fn get_claim(env: Env, claim_id: u64) -> Option { - env.storage().instance().get(&DataKey::Claim(claim_id)) - } - - // ===== Parametric Insurance Module ===== - - /// Create parametric insurance trigger - pub fn create_parametric_trigger( - env: Env, - admin: Address, - course_id: u64, - metric: LearningMetric, - threshold: i128, - payout_amount: i128, - ) -> Result { - Self::check_role(&env, &admin, ROLE_RISK_MANAGER)?; - - let mut trigger_count = env - .storage() - .instance() - .get(&DataKey::TriggerCount) - .unwrap_or(0); - trigger_count += 1; - - let trigger = ParametricTrigger { - trigger_id: trigger_count, - course_id, - metric, - threshold, - payout_amount, - is_active: true, - }; - - env.storage() - .instance() - .set(&DataKey::ParametricTrigger(trigger_count), &trigger); - env.storage() - .instance() - .set(&DataKey::TriggerCount, &trigger_count); - - // Add to course triggers - let mut course_triggers: Vec = env - .storage() - .instance() - .get(&DataKey::TriggerByCourse(course_id)) - .unwrap_or_else(|| vec![&env]); - course_triggers.push_back(trigger_count); - env.storage() - .instance() - .set(&DataKey::TriggerByCourse(course_id), &course_triggers); - - Ok(trigger_count) - } - - /// Execute parametric trigger payout - pub fn execute_trigger( - env: Env, - trigger_id: u64, - user: Address, - actual_value: i128, - ) -> Result<(), InsuranceError> { - let trigger: ParametricTrigger = env - .storage() - .instance() - .get(&DataKey::ParametricTrigger(trigger_id)) - .ok_or(InsuranceError::TriggerNotFound)?; - - if !trigger.is_active { - return Err(InsuranceError::TriggerNotActive); - } - - // Check if threshold condition is met - let triggered = match trigger.metric { - LearningMetric::CompletionPercentage - | LearningMetric::AssessmentScore - | LearningMetric::EngagementLevel => actual_value < trigger.threshold, - LearningMetric::CompletionTime | LearningMetric::AttemptCount => { - actual_value > trigger.threshold - } - }; - - if !triggered { - return Err(InsuranceError::ParametricConditionNotMet); - } - - // Transfer payout - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - token_client.transfer( - &env.current_contract_address(), - &user, - &trigger.payout_amount, - ); - - // Deactivate trigger - let mut updated_trigger = trigger; - updated_trigger.is_active = false; - env.storage() - .instance() - .set(&DataKey::ParametricTrigger(trigger_id), &updated_trigger); - - Ok(()) - } - - // ===== Insurance Pool Optimization Module ===== - - /// Create an optimized insurance pool - pub fn create_pool( - env: Env, - admin: Address, - name: Bytes, - target_utilization: u32, - risk_reserve_ratio: u32, - ) -> Result { - Self::check_role(&env, &admin, ROLE_POOL_MANAGER)?; - - let mut pool_count = env - .storage() - .instance() - .get(&DataKey::PoolCount) - .unwrap_or(0); - pool_count += 1; - - let pool = OptimizedPool { - pool_id: pool_count, - name: String::from_str(&env, &"Insurance Pool"), // Simplified for now - total_assets: 0, - utilization_rate: 0, - target_utilization, - risk_reserve_ratio, - reinsurance_partners: Vec::new(&env), - status: PoolStatus::Active, - }; - - env.storage() - .instance() - .set(&DataKey::Pool(pool_count), &pool); - env.storage() - .instance() - .set(&DataKey::PoolCount, &pool_count); - - // Add to active pools - let mut active_pools: Vec = env - .storage() - .instance() - .get(&DataKey::ActivePools) - .unwrap_or_else(|| Vec::new(&env)); - active_pools.push_back(pool_count); - env.storage() - .instance() - .set(&DataKey::ActivePools, &active_pools); - - Ok(pool_count) - } - - /// Add reinsurance partner to pool - pub fn add_reinsurance_partner( - env: Env, - admin: Address, - pool_id: u64, - partner: Address, - allocation_percentage: u32, - ) -> Result<(), InsuranceError> { - Self::check_role(&env, &admin, ROLE_POOL_MANAGER)?; - - let mut pool: OptimizedPool = env - .storage() - .instance() - .get(&DataKey::Pool(pool_id)) - .ok_or(InsuranceError::PoolNotFound)?; - - // Add partner to pool - pool.reinsurance_partners.push_back(partner.clone()); - env.storage().instance().set(&DataKey::Pool(pool_id), &pool); - - // Set allocation - env.storage().instance().set( - &DataKey::ReinsuranceAllocation(pool_id, partner.clone()), - &allocation_percentage, - ); - - // Add to reinsurance partners list - let mut partners: Vec
= env - .storage() - .instance() - .get(&DataKey::ReinsurancePartners) - .unwrap_or_else(|| Vec::new(&env)); - partners.push_back(partner); - env.storage() - .instance() - .set(&DataKey::ReinsurancePartners, &partners); - - Ok(()) - } - - /// Optimize pool utilization - pub fn optimize_pool_utilization( - env: Env, - pool_id: u64, - ) -> Result { - let pool: OptimizedPool = env - .storage() - .instance() - .get(&DataKey::Pool(pool_id)) - .ok_or(InsuranceError::PoolNotFound)?; - - if pool.status != PoolStatus::Active { - return Err(InsuranceError::PoolNotActive); - } - - // Calculate current utilization - let current_utilization = Self::calculate_pool_utilization(env.clone(), pool_id)?; - - // Calculate performance metrics - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - let pool_balance = token_client.balance(&env.current_contract_address()); - - let performance = PoolPerformance { - pool_id, - period_start: env.ledger().timestamp() - 30 * 24 * 60 * 60, // Last 30 days - period_end: env.ledger().timestamp(), - total_assets: pool_balance, - premiums_earned: 0, // Would be tracked in real implementation - claims_paid: 0, // Would be tracked in real implementation - net_profit: 0, // Would be calculated in real implementation - utilization_rate: current_utilization, - loss_ratio: 0, // Would be calculated in real implementation - roi_percentage: 0, // Would be calculated in real implementation - }; - - // Store performance metrics - env.storage() - .instance() - .set(&DataKey::PoolPerformance(pool_id), &performance); - - Ok(performance) - } - - /// Calculate pool utilization rate - fn calculate_pool_utilization(env: Env, pool_id: u64) -> Result { - // In a real implementation, this would calculate: - // (Total Coverage Amount / Total Pool Assets) * 10000 - // For now, return simulated value - Ok(7500) // 75% - } - - // ===== Insurance Analytics Module ===== - - /// Record daily metrics for analytics - pub fn record_daily_metrics(env: Env) -> Result<(), InsuranceError> { - let today = env.ledger().timestamp() / (24 * 60 * 60); // Unix days - let yesterday = today - 1; - - // Get yesterday's metrics (would be calculated from events in real implementation) - let metrics = DailyMetrics { - date: yesterday * 24 * 60 * 60, - policies_issued: 15, // Simulated data - premiums_collected: 15000, - claims_filed: 3, - claims_paid: 2, - total_payouts: 20000, - active_policies: 142, - pool_utilization: 7500, // 75% - average_risk_score: 45, - }; - - env.storage() - .instance() - .set(&DataKey::DailyMetrics(yesterday), &metrics); - - // Update risk distribution - let distribution = RiskDistribution { - low_risk_count: 85, - medium_risk_count: 42, - high_risk_count: 15, - average_risk_score: 45, - risk_std_dev: 22, - }; - - env.storage() - .instance() - .set(&DataKey::RiskDistribution, &distribution); - - Ok(()) - } - - /// Generate actuarial report - pub fn generate_actuarial_report( - env: Env, - days: u32, - ) -> Result { - // In a real implementation, this would analyze historical data - // For now, return current distribution - env.storage() - .instance() - .get(&DataKey::RiskDistribution) - .ok_or(InsuranceError::AnalyticsNotAvailable) - } - - /// Get daily metrics for a specific date - pub fn get_daily_metrics(env: Env, date: u64) -> Option { - let day = date / (24 * 60 * 60); - env.storage().instance().get(&DataKey::DailyMetrics(day)) - } - - // ===== Insurance Governance Module ===== - - /// Create governance proposal - pub fn create_proposal( - env: Env, - proposer: Address, - title: Bytes, - description: Bytes, - proposal_type: ProposalType, - new_value: i128, - ) -> Result { - proposer.require_auth(); - - // Check if proposer has minimum tokens (simplified check) - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - let balance = token_client.balance(&proposer); - - let governance_params: GovernanceParameters = env - .storage() - .instance() - .get(&DataKey::GovernanceParameters) - .unwrap_or_else(GovernanceParameters::default); - - if balance < governance_params.proposal_threshold as i128 { - return Err(InsuranceError::InsufficientTokenBalance); - } - - let mut proposal_count = env - .storage() - .instance() - .get(&DataKey::ProposalCount) - .unwrap_or(0); - proposal_count += 1; - - let proposal = InsuranceProposal { - proposal_id: proposal_count, - title: String::from_str(&env, &"Proposal Title"), // Simplified for now - description: String::from_str(&env, &"Proposal Description"), // Simplified for now - proposal_type, - new_value, - voting_start: env.ledger().timestamp(), - voting_end: env.ledger().timestamp() - + (governance_params.voting_period_days as u64 * 24 * 60 * 60), - votes_for: 0, - votes_against: 0, - status: ProposalStatus::Active, - }; - - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_count), &proposal); - env.storage() - .instance() - .set(&DataKey::ProposalCount, &proposal_count); - - Ok(proposal_count) - } - - /// Vote on governance proposal - pub fn vote( - env: Env, - voter: Address, - proposal_id: u64, - support: bool, - ) -> Result<(), InsuranceError> { - voter.require_auth(); - - let mut proposal: InsuranceProposal = env - .storage() - .instance() - .get(&DataKey::Proposal(proposal_id)) - .ok_or(InsuranceError::ProposalNotFound)?; - - if proposal.status != ProposalStatus::Active { - return Err(InsuranceError::ProposalNotActive); - } - - if env.ledger().timestamp() > proposal.voting_end { - return Err(InsuranceError::VotingPeriodEnded); - } - - // Check if already voted - let vote_key = DataKey::Vote(voter.clone(), proposal_id); - if env.storage().instance().has(&vote_key) { - return Err(InsuranceError::AlreadyVoted); - } - - // Record vote - env.storage().instance().set(&vote_key, &true); - - // Update vote counts - if support { - proposal.votes_for += 1; - } else { - proposal.votes_against += 1; - } - - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - - Ok(()) - } - - /// Execute passed proposal - pub fn execute_proposal( - env: Env, - admin: Address, - proposal_id: u64, - ) -> Result<(), InsuranceError> { - Self::check_role(&env, &admin, ROLE_SUPER_ADMIN)?; - - let mut proposal: InsuranceProposal = env - .storage() - .instance() - .get(&DataKey::Proposal(proposal_id)) - .ok_or(InsuranceError::ProposalNotFound)?; - - // Check if voting period ended and proposal passed - if env.ledger().timestamp() < proposal.voting_end { - return Err(InsuranceError::VotingPeriodEnded); - } - - let governance_params: GovernanceParameters = env - .storage() - .instance() - .get(&DataKey::GovernanceParameters) - .unwrap_or_else(GovernanceParameters::default); - - let total_votes = proposal.votes_for + proposal.votes_against; - let quorum_met = - (total_votes * 10000) >= (governance_params.quorum_percentage as u64 * 100); - let approved = proposal.votes_for > proposal.votes_against; - - if !quorum_met { - proposal.status = ProposalStatus::Rejected; - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - return Err(InsuranceError::GovernanceQuorumNotMet); - } - - if !approved { - proposal.status = ProposalStatus::Rejected; - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - return Err(InsuranceError::ProposalNotActive); - } - - // Execute the proposal - match proposal.proposal_type { - ProposalType::PremiumRate => { - env.storage() - .instance() - .set(&DataKey::BasePremiumRate, &proposal.new_value); - } - ProposalType::RiskMultiplier => { - // Would update risk multiplier ranges - } - ProposalType::UtilizationTarget => { - // Would update utilization targets - } - ProposalType::ReinsurancePartner => { - // Would add/remove reinsurance partner - } - ProposalType::Governance => { - // Would update governance parameters - } - } - - proposal.status = ProposalStatus::Passed; - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - - Ok(()) - } - - // ===== Insurance Tokenization Module ===== - - /// Create insurance token representing pool shares - pub fn create_insurance_token( - env: Env, - admin: Address, - pool_id: u64, - name: Bytes, - symbol: Bytes, - total_supply: i128, - ) -> Result { - Self::check_role(&env, &admin, ROLE_SUPER_ADMIN)?; - - // Verify pool exists - let _pool: OptimizedPool = env - .storage() - .instance() - .get(&DataKey::Pool(pool_id)) - .ok_or(InsuranceError::PoolNotFound)?; - - let mut token_count = env - .storage() - .instance() - .get(&DataKey::TokenCount) - .unwrap_or(0); - token_count += 1; - - let token = InsuranceToken { - token_id: token_count, - pool_id, - name: String::from_str(&env, &"Insurance Token"), // Simplified for now - symbol: String::from_str(&env, &"INS"), // Simplified for now - total_supply, - holder: admin.clone(), - balance: total_supply, - }; - - env.storage() - .instance() - .set(&DataKey::InsuranceToken(token_count), &token); - env.storage() - .instance() - .set(&DataKey::TokenByPool(pool_id), &token_count); - env.storage() - .instance() - .set(&DataKey::TokenHolder(admin, token_count), &total_supply); - env.storage() - .instance() - .set(&DataKey::TokenCount, &token_count); - - Ok(token_count) - } - - /// Transfer insurance tokens - pub fn transfer_tokens( - env: Env, - from: Address, - to: Address, - token_id: u64, - amount: i128, - ) -> Result<(), InsuranceError> { - from.require_auth(); - - let mut token: InsuranceToken = env - .storage() - .instance() - .get(&DataKey::InsuranceToken(token_id)) - .ok_or(InsuranceError::TokenNotFound)?; - - // Check balance - let from_balance: i128 = env - .storage() - .instance() - .get(&DataKey::TokenHolder(from.clone(), token_id)) - .unwrap_or(0); - - if from_balance < amount { - return Err(InsuranceError::InsufficientTokenBalance); - } - - let to_balance: i128 = env - .storage() - .instance() - .get(&DataKey::TokenHolder(to.clone(), token_id)) - .unwrap_or(0); - - // Update balances - env.storage().instance().set( - &DataKey::TokenHolder(from.clone(), token_id), - &(from_balance - amount), - ); - env.storage().instance().set( - &DataKey::TokenHolder(to.clone(), token_id), - &(to_balance + amount), - ); - - // Update token holder if transferring all tokens - if from_balance - amount == 0 { - token.holder = to.clone(); - env.storage() - .instance() - .set(&DataKey::InsuranceToken(token_id), &token); - } - - Ok(()) - } - - // ===== Compliance and Reporting Module ===== - - /// Generate compliance report - pub fn generate_compliance_report( - env: Env, - admin: Address, - period_days: u32, - ) -> Result { - Self::check_role(&env, &admin, ROLE_ORACLE_MANAGER)?; - - let period_start = env.ledger().timestamp() - (period_days as u64 * 24 * 60 * 60); - let period_end = env.ledger().timestamp(); - - // Calculate metrics (simplified for demo) - let mut report_count = env - .storage() - .instance() - .get(&DataKey::ReportCount) - .unwrap_or(0); - report_count += 1; - - let report = ComplianceReport { - report_id: report_count, - period_start, - period_end, - total_policies: 287, - total_claims: 42, - claims_paid: 35, - premiums_collected: 287000, - total_payouts: 350000, - loss_ratio: 12200, // 122% - reserve_ratio: 1500, // 15% - generated_at: env.ledger().timestamp(), - }; - - env.storage() - .instance() - .set(&DataKey::ComplianceReport(report_count), &report); - env.storage() - .instance() - .set(&DataKey::ReportCount, &report_count); - env.storage() - .instance() - .set(&DataKey::LastReportGeneration, &env.ledger().timestamp()); - - Ok(report_count) - } - - /// Get compliance report - pub fn get_compliance_report(env: Env, report_id: u64) -> Option { - env.storage() - .instance() - .get(&DataKey::ComplianceReport(report_id)) - } - - // ===== Cross-Chain Module ===== - - /// Register cross-chain bridge - pub fn register_chain_bridge( - env: Env, - admin: Address, - chain_id: Address, - bridge_address: Address, - ) -> Result<(), InsuranceError> { - Self::check_role(&env, &admin, ROLE_SUPER_ADMIN)?; - - env.storage() - .instance() - .set(&DataKey::ChainBridge(chain_id), &bridge_address); - - Ok(()) - } - - /// Create cross-chain insurance policy - pub fn create_cross_chain_policy( - env: Env, - user: Address, - course_id: u64, - coverage_amount: i128, - target_chain: Address, - ) -> Result { - // This would integrate with cross-chain messaging - // For now, create regular policy - Self::purchase_policy(env, user, course_id, coverage_amount) - } - - // ===== View Functions ===== - - pub fn get_policy(env: Env, policy_id: u64) -> Option { - env.storage().instance().get(&DataKey::Policy(policy_id)) - } - - pub fn get_active_policies(env: Env, user: Address) -> Vec { - env.storage() - .instance() - .get(&DataKey::ActivePolicies(user)) - .unwrap_or_else(|| Vec::new(&env)) - } - - pub fn get_pending_claims(env: Env) -> Vec { - env.storage() - .instance() - .get(&DataKey::PendingClaims) - .unwrap_or_else(|| Vec::new(&env)) - } - - pub fn get_pool(env: Env, pool_id: u64) -> Option { - env.storage().instance().get(&DataKey::Pool(pool_id)) - } - - pub fn get_active_pools(env: Env) -> Vec { - env.storage() - .instance() - .get(&DataKey::ActivePools) - .unwrap_or_else(|| Vec::new(&env)) - } - - pub fn get_insurance_token(env: Env, token_id: u64) -> Option { - env.storage() - .instance() - .get(&DataKey::InsuranceToken(token_id)) - } - - pub fn get_token_balance(env: Env, holder: Address, token_id: u64) -> i128 { - env.storage() - .instance() - .get(&DataKey::TokenHolder(holder, token_id)) - .unwrap_or(0) - } - - pub fn get_proposal(env: Env, proposal_id: u64) -> Option { - env.storage() - .instance() - .get(&DataKey::Proposal(proposal_id)) - } - - pub fn get_governance_parameters(env: Env) -> GovernanceParameters { - env.storage() - .instance() - .get(&DataKey::GovernanceParameters) - .unwrap_or_else(GovernanceParameters::default) - } -} diff --git a/contracts/insurance/src/repository/generic.rs b/contracts/insurance/src/repository/generic.rs deleted file mode 100644 index 1552544a..00000000 --- a/contracts/insurance/src/repository/generic.rs +++ /dev/null @@ -1,176 +0,0 @@ -//! Generic Repository Implementations for Insurance Contract - -use crate::repository::traits::{CounterRepository, MapRepository, StorageBackend, StorageError}; -use soroban_sdk::{IntoVal, Map, Val}; - -/// Generic repository for single-value storage -pub struct SingleValueRepository<'a, K, V> { - storage: &'a dyn StorageBackend, - _key: std::marker::PhantomData, - _value: std::marker::PhantomData, -} - -impl<'a, K, V> SingleValueRepository<'a, K, V> -where - K: IntoVal + Clone, - V: IntoVal + Clone, -{ - pub fn new(storage: &'a dyn StorageBackend) -> Self { - Self { - storage, - _key: std::marker::PhantomData, - _value: std::marker::PhantomData, - } - } - - pub fn get(&self, key: &K) -> Result, StorageError> { - Ok(self.storage.get(key)) - } - - pub fn set(&self, key: &K, value: &V) -> Result<(), StorageError> { - self.storage.set(key, value); - Ok(()) - } - - pub fn exists(&self, key: &K) -> Result { - Ok(self.storage.has(key)) - } - - pub fn remove(&self, key: &K) -> Result<(), StorageError> { - self.storage.remove(key); - Ok(()) - } -} - -/// Generic counter repository -pub struct GenericCounterRepository<'a, K> { - storage: &'a dyn StorageBackend, - key: K, -} - -impl<'a, K> GenericCounterRepository<'a, K> -where - K: IntoVal + Clone, -{ - pub fn new(storage: &'a dyn StorageBackend, key: K) -> Self { - Self { storage, key } - } - - pub fn get(&self) -> Result { - Ok(self.storage.get(&self.key).unwrap_or(0)) - } - - pub fn increment(&self) -> Result { - let current = self.get()?; - let new_value = current + 1; - self.storage.set(&self.key, &new_value); - Ok(new_value) - } - - pub fn reset(&self) -> Result<(), StorageError> { - self.storage.set(&self.key, &0u64); - Ok(()) - } -} - -impl<'a, K> CounterRepository for GenericCounterRepository<'a, K> -where - K: IntoVal + Clone, -{ - type Error = StorageError; - - fn get(&self) -> Result { - self.get() - } - - fn increment(&self) -> Result { - self.increment() - } - - fn reset(&self) -> Result<(), Self::Error> { - self.reset() - } -} - -/// Generic map repository -pub struct GenericMapRepository<'a, K, V> { - storage: &'a dyn StorageBackend, - key: K, - _value: std::marker::PhantomData, -} - -impl<'a, K, V> GenericMapRepository<'a, K, V> -where - K: IntoVal + Clone, - V: IntoVal + Clone, -{ - pub fn new(storage: &'a dyn StorageBackend, key: K) -> Self { - Self { - storage, - key, - _value: std::marker::PhantomData, - } - } - - fn get_map(&self) -> Map { - self.storage.get(&self.key).unwrap_or_else(|| Map::new(self.storage.env())) - } - - pub fn get(&self, map_key: &K) -> Result, StorageError> { - let map = self.get_map(); - Ok(map.get(map_key.clone())) - } - - pub fn set(&self, map_key: &K, value: &V) -> Result<(), StorageError> { - let mut map = self.get_map(); - map.set(map_key.clone(), value.clone()); - self.storage.set(&self.key, &map); - Ok(()) - } - - pub fn remove(&self, map_key: &K) -> Result<(), StorageError> { - let mut map = self.get_map(); - if map.contains_key(map_key.clone()) { - map.remove(map_key.clone()); - self.storage.set(&self.key, &map); - } - Ok(()) - } - - pub fn contains(&self, map_key: &K) -> Result { - let map = self.get_map(); - Ok(map.contains_key(map_key.clone())) - } - - pub fn all(&self) -> Result, StorageError> { - Ok(self.get_map()) - } -} - -impl<'a, K, V> MapRepository for GenericMapRepository<'a, K, V> -where - K: IntoVal + Clone, - V: IntoVal + Clone, -{ - type Error = StorageError; - - fn get(&self, key: &K) -> Result, Self::Error> { - self.get(key) - } - - fn set(&self, key: &K, value: &V) -> Result<(), Self::Error> { - self.set(key, value) - } - - fn remove(&self, key: &K) -> Result<(), Self::Error> { - self.remove(key) - } - - fn contains(&self, key: &K) -> Result { - self.contains(key) - } - - fn all(&self) -> Result, Self::Error> { - self.all() - } -} diff --git a/contracts/insurance/src/repository/insurance_repository.rs b/contracts/insurance/src/repository/insurance_repository.rs deleted file mode 100644 index 7d6c298a..00000000 --- a/contracts/insurance/src/repository/insurance_repository.rs +++ /dev/null @@ -1,238 +0,0 @@ -//! Insurance Domain Repository -//! -//! This module provides repository implementations for insurance-related data access. - -use crate::repository::generic::{GenericCounterRepository, GenericMapRepository, SingleValueRepository}; -use crate::repository::traits::InstanceStorage; -use crate::repository::StorageError; -use crate::storage::DataKey; -use crate::types::*; -use soroban_sdk::{Address, Env, Map, Vec}; - -/// Repository for insurance configuration -pub struct InsuranceConfigRepository<'a> { - storage: InstanceStorage<'a>, -} - -impl<'a> InsuranceConfigRepository<'a> { - pub fn new(env: &'a Env) -> Self { - Self { - storage: InstanceStorage::new(env), - } - } - - pub fn get_admin(&self) -> Result { - self.storage.get(&DataKey::Admin).ok_or(StorageError::NotFound) - } - - pub fn set_admin(&self, admin: &Address) -> Result<(), StorageError> { - self.storage.set(&DataKey::Admin, admin); - Ok(()) - } - - pub fn get_oracle(&self) -> Result { - self.storage.get(&DataKey::Oracle).ok_or(StorageError::NotFound) - } - - pub fn set_oracle(&self, oracle: &Address) -> Result<(), StorageError> { - self.storage.set(&DataKey::Oracle, oracle); - Ok(()) - } - - pub fn get_token(&self) -> Result { - self.storage.get(&DataKey::Token).ok_or(StorageError::NotFound) - } - - pub fn set_token(&self, token: &Address) -> Result<(), StorageError> { - self.storage.set(&DataKey::Token, token); - Ok(()) - } - - pub fn is_initialized(&self) -> bool { - self.storage.has(&DataKey::Admin) - } -} - -/// Repository for insurance policies -pub struct PolicyRepository<'a> { - storage: InstanceStorage<'a>, - counter: GenericCounterRepository<'a, DataKey>, -} - -impl<'a> PolicyRepository<'a> { - pub fn new(env: &'a Env) -> Self { - Self { - storage: InstanceStorage::new(env), - counter: GenericCounterRepository::new(&InstanceStorage::new(env), DataKey::PolicyCount), - } - } - - pub fn get_policy(&self, policy_id: u64) -> Option { - self.storage.get(&DataKey::Policy(policy_id)) - } - - pub fn save_policy(&self, policy: &Policy) -> Result<(), StorageError> { - self.storage.set(&DataKey::Policy(policy.id), policy); - Ok(()) - } - - pub fn get_next_id(&self) -> Result { - self.counter.increment() - } - - pub fn get_policy_by_user(&self, user: &Address, course_id: u64) -> Option { - self.storage.get(&DataKey::PolicyByUser(user.clone(), course_id)) - } - - pub fn get_active_policies(&self, user: &Address) -> Vec { - self.storage.get(&DataKey::ActivePolicies(user.clone())) - .unwrap_or_else(|| Vec::new(self.storage.env())) - } -} - -/// Repository for insurance claims -pub struct ClaimRepository<'a> { - storage: InstanceStorage<'a>, - counter: GenericCounterRepository<'a, DataKey>, -} - -impl<'a> ClaimRepository<'a> { - pub fn new(env: &'a Env) -> Self { - Self { - storage: InstanceStorage::new(env), - counter: GenericCounterRepository::new(&InstanceStorage::new(env), DataKey::ClaimCount), - } - } - - pub fn get_claim(&self, claim_id: u64) -> Option { - self.storage.get(&DataKey::Claim(claim_id)) - } - - pub fn save_claim(&self, claim: &Claim) -> Result<(), StorageError> { - self.storage.set(&DataKey::Claim(claim.id), claim); - Ok(()) - } - - pub fn get_next_id(&self) -> Result { - self.counter.increment() - } - - pub fn get_pending_claims(&self) -> Vec { - self.storage.get(&DataKey::PendingClaims).unwrap_or_else(|| Vec::new(self.storage.env())) - } -} - -/// Repository for insurance pools -pub struct PoolRepository<'a> { - storage: InstanceStorage<'a>, - counter: GenericCounterRepository<'a, DataKey>, -} - -impl<'a> PoolRepository<'a> { - pub fn new(env: &'a Env) -> Self { - Self { - storage: InstanceStorage::new(env), - counter: GenericCounterRepository::new(&InstanceStorage::new(env), DataKey::PoolCount), - } - } - - pub fn get_pool(&self, pool_id: u64) -> Option { - self.storage.get(&DataKey::Pool(pool_id)) - } - - pub fn save_pool(&self, pool: &Pool) -> Result<(), StorageError> { - self.storage.set(&DataKey::Pool(pool.id), pool); - Ok(()) - } - - pub fn get_next_id(&self) -> Result { - self.counter.increment() - } - - pub fn get_active_pools(&self) -> Vec { - self.storage.get(&DataKey::ActivePools).unwrap_or_else(|| Vec::new(self.storage.env())) - } -} - -/// Repository for risk profiles -pub struct RiskProfileRepository<'a> { - storage: InstanceStorage<'a>, - counter: GenericCounterRepository<'a, DataKey>, -} - -impl<'a> RiskProfileRepository<'a> { - pub fn new(env: &'a Env) -> Self { - Self { - storage: InstanceStorage::new(env), - counter: GenericCounterRepository::new(&InstanceStorage::new(env), DataKey::RiskProfileCount), - } - } - - pub fn get_risk_profile(&self, profile_id: u64) -> Option { - self.storage.get(&DataKey::RiskProfile(profile_id)) - } - - pub fn save_risk_profile(&self, profile: &RiskProfile) -> Result<(), StorageError> { - self.storage.set(&DataKey::RiskProfile(profile.id), profile); - Ok(()) - } - - pub fn get_by_user(&self, user: &Address) -> Option { - self.storage.get(&DataKey::RiskProfileByUser(user.clone())) - } - - pub fn get_next_id(&self) -> Result { - self.counter.increment() - } -} - -/// Aggregate repository for all insurance operations -pub struct InsuranceRepository<'a> { - pub config: InsuranceConfigRepository<'a>, - pub policies: PolicyRepository<'a>, - pub claims: ClaimRepository<'a>, - pub pools: PoolRepository<'a>, - pub risk_profiles: RiskProfileRepository<'a>, -} - -impl<'a> InsuranceRepository<'a> { - pub fn new(env: &'a Env) -> Self { - Self { - config: InsuranceConfigRepository::new(env), - policies: PolicyRepository::new(env), - claims: ClaimRepository::new(env), - pools: PoolRepository::new(env), - risk_profiles: RiskProfileRepository::new(env), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - use soroban_sdk::testutils::Address as _; - - #[test] - fn test_config_repository() { - let env = Env::default(); - let repo = InsuranceConfigRepository::new(&env); - - let admin = Address::generate(&env); - repo.set_admin(&admin).expect("Should set admin"); - - assert_eq!(repo.get_admin().unwrap(), admin); - assert!(repo.is_initialized()); - } - - #[test] - fn test_policy_repository() { - let env = Env::default(); - let repo = PolicyRepository::new(&env); - - let initial_count = repo.counter.get().expect("Should get count"); - assert_eq!(initial_count, 0); - - let next_id = repo.get_next_id().expect("Should get next ID"); - assert_eq!(next_id, 1); - } -} diff --git a/contracts/insurance/src/repository/mod.rs b/contracts/insurance/src/repository/mod.rs deleted file mode 100644 index ed841510..00000000 --- a/contracts/insurance/src/repository/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Repository Pattern Implementation for Insurance Contract -//! -//! This module provides a storage abstraction layer for the insurance contract -//! using the repository pattern. - -pub mod traits; -pub mod generic; -pub mod insurance_repository; - -// Re-export for convenience -pub use traits::{StorageBackend, StorageError, Repository, CounterRepository, MapRepository}; -pub use generic::{SingleValueRepository, GenericCounterRepository, GenericMapRepository}; -pub use insurance_repository::InsuranceRepository; diff --git a/contracts/insurance/src/repository/traits.rs b/contracts/insurance/src/repository/traits.rs deleted file mode 100644 index 06e3568a..00000000 --- a/contracts/insurance/src/repository/traits.rs +++ /dev/null @@ -1,119 +0,0 @@ -//! Storage Traits for Insurance Contract -//! -//! This module defines the storage interface contracts for the insurance contract. - -use soroban_sdk::{Env, IntoVal, Val}; - -/// Error type for storage operations -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum StorageError { - NotFound, - AlreadyExists, - SerializationError, - DeserializationError, - Unauthorized, - InvalidKey, - StorageFull, -} - -/// Trait for basic storage operations (CRUD) -pub trait StorageBackend { - fn get + Clone>(&self, key: &T) -> Option; - fn set, V: IntoVal>(&self, key: &K, value: &V); - fn has>(&self, key: &K) -> bool; - fn remove>(&self, key: &K); - fn env(&self) -> &Env; -} - -/// Instance storage backend -pub struct InstanceStorage<'a> { - env: &'a Env, -} - -impl<'a> InstanceStorage<'a> { - pub fn new(env: &'a Env) -> Self { - Self { env } - } -} - -impl<'a> StorageBackend for InstanceStorage<'a> { - fn get + Clone>(&self, key: &T) -> Option { - self.env.storage().instance().get(key) - } - - fn set, V: IntoVal>(&self, key: &K, value: &V) { - self.env.storage().instance().set(key, value); - } - - fn has>(&self, key: &K) -> bool { - self.env.storage().instance().has(key) - } - - fn remove>(&self, key: &K) { - self.env.storage().instance().remove(key) - } - - fn env(&self) -> &Env { - self.env - } -} - -/// Persistent storage backend -pub struct PersistentStorage<'a> { - env: &'a Env, -} - -impl<'a> PersistentStorage<'a> { - pub fn new(env: &'a Env) -> Self { - Self { env } - } -} - -impl<'a> StorageBackend for PersistentStorage<'a> { - fn get + Clone>(&self, key: &T) -> Option { - self.env.storage().persistent().get(key) - } - - fn set, V: IntoVal>(&self, key: &K, value: &V) { - self.env.storage().persistent().set(key, value); - } - - fn has>(&self, key: &K) -> bool { - self.env.storage().persistent().has(key) - } - - fn remove>(&self, key: &K) { - self.env.storage().persistent().remove(key) - } - - fn env(&self) -> &Env { - self.env - } -} - -/// Repository trait for entity-specific operations -pub trait Repository { - type Error; - fn find(&self, key: &K) -> Result, Self::Error>; - fn save(&self, key: &K, value: &V) -> Result<(), Self::Error>; - fn delete(&self, key: &K) -> Result<(), Self::Error>; - fn exists(&self, key: &K) -> Result; -} - -/// Counter repository trait -pub trait CounterRepository { - type Error; - fn get(&self) -> Result; - fn increment(&self) -> Result; - fn reset(&self) -> Result<(), Self::Error>; -} - -/// Map repository trait -pub trait MapRepository { - type Error; - fn get(&self, key: &K) -> Result, Self::Error>; - fn set(&self, key: &K, value: &V) -> Result<(), Self::Error>; - fn remove(&self, key: &K) -> Result<(), Self::Error>; - fn contains(&self, key: &K) -> Result; - fn all(&self) -> Result, Self::Error>; -} diff --git a/contracts/insurance/src/storage.rs b/contracts/insurance/src/storage.rs deleted file mode 100644 index 7b188c69..00000000 --- a/contracts/insurance/src/storage.rs +++ /dev/null @@ -1,227 +0,0 @@ -use crate::types::*; -use soroban_sdk::{contracttype, Address, Vec}; - -/// Storage keys for the enhanced insurance contract -#[contracttype] -#[derive(Clone)] -pub enum DataKey { - // Core configuration - Admin, - Oracle, - Token, - - // RBAC & Governance - HasRole(u32, Address), // Role ID -> Address -> bool - PendingAdminTransfer, // Address (New Admin) - AdminTransferTimestamp, // u64 (When transfer can be executed) - MultiSigSigners, // Vec
- MultiSigThreshold, // u32 - CriticalOperation(u32), // Operation ID -> CriticalOperation - OperationApprovals(u32), // Operation ID -> Vec
- OperationCount, // u64 - - // Risk assessment - RiskProfile(u64), - RiskProfileByUser(Address), - RiskProfileCount, - RiskModelWeights, - - // Insurance policies - Policy(u64), - PolicyByUser(Address, u64), // user -> course_id -> policy_id - PolicyCount, - ActivePolicies(Address), // user -> Vec - - // Claims - Claim(u64), - ClaimByPolicy(u64), - ClaimCount, - PendingClaims, - - // Parametric insurance - ParametricTrigger(u64), - TriggerByCourse(u64), - TriggerCount, - - // Insurance pools - Pool(u64), - PoolCount, - ActivePools, - PoolUtilization(u64), - - // Reinsurance - ReinsurancePartner(Address), - ReinsurancePartners, - ReinsuranceAllocation(u64, Address), // pool_id -> partner -> allocation - - // Insurance tokens - InsuranceToken(u64), - TokenByPool(u64), - TokenHolder(Address, u64), // holder -> token_id -> balance - TokenCount, - - // Governance - Proposal(u64), - ProposalCount, - Vote(Address, u64), // voter -> proposal_id -> has_voted - GovernanceParameters, - - // Analytics - DailyMetrics(u64), // timestamp (day) -> metrics - MonthlyMetrics(u64), // timestamp (month) -> metrics - RiskDistribution, - PoolPerformance(u64), // pool_id -> performance metrics - - // Compliance - ComplianceReport(u64), - ReportCount, - LastReportGeneration, - - // Cross-chain - ChainBridge(Address), // chain_id -> bridge_address - CrossChainClaim(u64), - - // Configuration parameters - BasePremiumRate, - RiskMultiplierRanges, - UtilizationTargets, - MinimumRiskReserve, - GovernanceQuorum, - VotingPeriod, -} - -/// Risk model weights for AI-powered assessment -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskModelWeights { - pub completion_rate_weight: u32, // 25% - pub reputation_score_weight: u32, // 20% - pub course_difficulty_weight: u32, // 15% - pub course_duration_weight: u32, // 10% - pub experience_level_weight: u32, // 15% - pub claim_frequency_weight: u32, // 10% - pub time_factor_weight: u32, // 5% -} - -impl Default for RiskModelWeights { - fn default() -> Self { - Self { - completion_rate_weight: 2500, - reputation_score_weight: 2000, - course_difficulty_weight: 1500, - course_duration_weight: 1000, - experience_level_weight: 1500, - claim_frequency_weight: 1000, - time_factor_weight: 500, - } - } -} - -/// Governance parameters -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct GovernanceParameters { - pub quorum_percentage: u32, // Required voting quorum (basis points) - pub voting_period_days: u32, // Voting period in days - pub execution_delay_hours: u32, // Delay before executing passed proposals - pub proposal_threshold: u64, // Minimum tokens to create proposal - pub veto_power_enabled: bool, // Whether admin can veto proposals -} - -impl Default for GovernanceParameters { - fn default() -> Self { - Self { - quorum_percentage: 5000, // 50% - voting_period_days: 7, - execution_delay_hours: 24, - proposal_threshold: 1000, - veto_power_enabled: true, - } - } -} - -/// Risk multiplier ranges based on risk scores -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskMultiplierRanges { - pub low_risk_min: u32, // 0-30 risk score - pub low_risk_max: u32, // 10000 = 1.0x - pub medium_risk_min: u32, // 31-60 risk score - pub medium_risk_max: u32, // 15000 = 1.5x - pub high_risk_min: u32, // 61-100 risk score - pub high_risk_max: u32, // 30000 = 3.0x -} - -impl Default for RiskMultiplierRanges { - fn default() -> Self { - Self { - low_risk_min: 0, - low_risk_max: 10000, - medium_risk_min: 31, - medium_risk_max: 15000, - high_risk_min: 61, - high_risk_max: 30000, - } - } -} - -/// Pool utilization targets -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct UtilizationTargets { - pub target_rate: u32, // 8000 = 80% - pub max_rate: u32, // 9500 = 95% - pub min_reserve_ratio: u32, // 1500 = 15% -} - -impl Default for UtilizationTargets { - fn default() -> Self { - Self { - target_rate: 8000, - max_rate: 9500, - min_reserve_ratio: 1500, - } - } -} - -/// Daily insurance metrics -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct DailyMetrics { - pub date: u64, // Unix timestamp (day) - pub policies_issued: u64, - pub premiums_collected: i128, - pub claims_filed: u64, - pub claims_paid: u64, - pub total_payouts: i128, - pub active_policies: u64, - pub pool_utilization: u32, - pub average_risk_score: u32, -} - -/// Risk distribution statistics -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskDistribution { - pub low_risk_count: u64, // 0-30 - pub medium_risk_count: u64, // 31-60 - pub high_risk_count: u64, // 61-100 - pub average_risk_score: u32, - pub risk_std_dev: u32, -} - -/// Pool performance metrics -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct PoolPerformance { - pub pool_id: u64, - pub period_start: u64, - pub period_end: u64, - pub total_assets: i128, - pub premiums_earned: i128, - pub claims_paid: i128, - pub net_profit: i128, - pub utilization_rate: u32, - pub loss_ratio: u32, - pub roi_percentage: i32, // Basis points, can be negative -} diff --git a/contracts/insurance/src/types.rs b/contracts/insurance/src/types.rs deleted file mode 100644 index 5d6ab8a2..00000000 --- a/contracts/insurance/src/types.rs +++ /dev/null @@ -1,327 +0,0 @@ -use soroban_sdk::{contracttype, Address, Bytes, String, Vec}; - -/// RBAC Role Constants -pub const ROLE_SUPER_ADMIN: u32 = 1; -pub const ROLE_RISK_MANAGER: u32 = 2; -pub const ROLE_POOL_MANAGER: u32 = 3; -pub const ROLE_ORACLE_MANAGER: u32 = 4; - -/// Critical operation for multi-sig -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct CriticalOperation { - pub id: u32, - pub action: CriticalAction, - pub proposer: Address, - pub created_at: u64, - pub ready_at: u64, - pub executed: bool, -} - -/// Actions that require multi-sig or timelocks -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum CriticalAction { - UpdateRiskModelWeight(u32, u32), // weight_id, new_value - PausePool(u64), - UnpausePool(u64), - ChangeBasePremium(i128), - UpdateMultiSigSettings(u32), // new_threshold - ContractUpgrade(soroban_sdk::BytesN<32>), -} - -/// Risk assessment factors for insurance pricing -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskFactors { - /// User's historical completion rate (0-100) - pub completion_rate: u32, - /// User's reputation score (0-100) - pub reputation_score: u32, - /// Course difficulty level (1-10) - pub course_difficulty: u32, - /// Course duration in hours - pub course_duration: u32, - /// User's experience level (beginner=1, intermediate=2, advanced=3) - pub experience_level: u32, - /// Historical claim frequency for similar courses - pub claim_frequency: u32, - /// Time since last course completion - pub time_since_last_completion: u64, -} - -/// Risk profile with calculated risk score -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskProfile { - /// Unique profile ID - pub profile_id: u64, - /// Associated user address - pub user: Address, - /// Risk factors used for calculation - pub factors: RiskFactors, - /// Calculated risk score (0-100, higher = riskier) - pub risk_score: u32, - /// Timestamp when profile was created/updated - pub timestamp: u64, -} - -/// Insurance policy with dynamic pricing -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct InsurancePolicy { - /// Unique policy ID - pub policy_id: u64, - /// Policy holder address - pub holder: Address, - /// Course ID being insured - pub course_id: u64, - /// Risk profile used for pricing - pub risk_profile_id: u64, - /// Base premium amount - pub base_premium: i128, - /// Risk adjustment multiplier (basis points, e.g., 12000 = 1.2x) - pub risk_multiplier: u32, - /// Final calculated premium - pub final_premium: i128, - /// Coverage amount - pub coverage_amount: i128, - /// Policy start timestamp - pub start_time: u64, - /// Policy expiration timestamp - pub expiration_time: u64, - /// Current policy status - pub status: PolicyStatus, -} - -/// Policy status enumeration -#[contracttype] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum PolicyStatus { - /// Policy is active and providing coverage - Active, - /// Policy has been claimed against - Claimed, - /// Policy has expired - Expired, - /// Policy was cancelled - Cancelled, -} - -/// Parametric insurance trigger conditions -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct ParametricTrigger { - /// Unique trigger ID - pub trigger_id: u64, - /// Course ID this trigger applies to - pub course_id: u64, - /// Learning outcome metric to monitor - pub metric: LearningMetric, - /// Threshold value that triggers payout - pub threshold: i128, - /// Payout amount when triggered - pub payout_amount: i128, - /// Whether this trigger is active - pub is_active: bool, -} - -/// Learning metrics for parametric insurance -#[contracttype] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum LearningMetric { - /// Course completion percentage - CompletionPercentage, - /// Time to complete course - CompletionTime, - /// Assessment score - AssessmentScore, - /// Engagement level (0-100) - EngagementLevel, - /// Number of attempts - AttemptCount, -} - -/// Claims with AI verification -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct AdvancedClaim { - /// Unique claim ID - pub claim_id: u64, - /// Associated policy ID - pub policy_id: u64, - /// Claim filing timestamp - pub filed_at: u64, - /// Claim status - pub status: ClaimStatus, - /// AI verification confidence score (0-100) - pub ai_confidence: u32, - /// Supporting evidence (as Bytes) - pub evidence: Bytes, - /// Oracle verification result (if used) - pub oracle_verified: bool, - /// Payout amount (if approved) - pub payout_amount: i128, - /// Reason for claim - pub reason: String, -} - -/// Claim status enumeration -#[contracttype] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum ClaimStatus { - /// Claim filed, awaiting processing - Filed, - /// AI verification in progress - AiProcessing, - /// AI verified, awaiting oracle confirmation - AiVerified, - /// Oracle confirmed, ready for payout - OracleConfirmed, - /// Claim approved and paid - Approved, - /// Claim rejected - Rejected, - /// Claim disputed - Disputed, -} - -/// Insurance pool with optimization features -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct OptimizedPool { - /// Pool ID - pub pool_id: u64, - /// Pool name/description - pub name: String, - /// Total assets under management - pub total_assets: i128, - /// Current utilization rate (basis points) - pub utilization_rate: u32, - /// Target utilization rate - pub target_utilization: u32, - /// Risk reserve ratio (basis points) - pub risk_reserve_ratio: u32, - /// Reinsurance partner addresses - pub reinsurance_partners: Vec
, - /// Pool status - pub status: PoolStatus, -} - -/// Pool status enumeration -#[contracttype] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum PoolStatus { - /// Pool is active and accepting new policies - Active, - /// Pool is paused for maintenance - Paused, - /// Pool is in liquidation - Liquidating, - /// Pool is closed - Closed, -} - -/// Insurance token representing pool shares -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct InsuranceToken { - /// Token ID - pub token_id: u64, - /// Pool this token represents - pub pool_id: u64, - /// Token name - pub name: String, - /// Token symbol - pub symbol: String, - /// Total supply - pub total_supply: i128, - /// Current holder address - pub holder: Address, - /// Amount of shares held - pub balance: i128, -} - -/// Governance proposal for insurance parameters -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct InsuranceProposal { - /// Proposal ID - pub proposal_id: u64, - /// Proposal title - pub title: String, - /// Proposal description - pub description: String, - /// Type of parameter change - pub proposal_type: ProposalType, - /// New parameter value - pub new_value: i128, - /// Voting start timestamp - pub voting_start: u64, - /// Voting end timestamp - pub voting_end: u64, - /// Current vote count (for) - pub votes_for: u64, - /// Current vote count (against) - pub votes_against: u64, - /// Status of proposal - pub status: ProposalStatus, -} - -/// Proposal type enumeration -#[contracttype] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum ProposalType { - /// Change base premium rate - PremiumRate, - /// Change risk multiplier ranges - RiskMultiplier, - /// Change pool utilization targets - UtilizationTarget, - /// Add/remove reinsurance partner - ReinsurancePartner, - /// Change governance parameters - Governance, -} - -/// Proposal status enumeration -#[contracttype] -#[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub enum ProposalStatus { - /// Proposal is active for voting - Active, - /// Proposal passed and implemented - Passed, - /// Proposal rejected - Rejected, - /// Proposal execution failed - Failed, -} - -/// Compliance report for regulatory purposes -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct ComplianceReport { - /// Report ID - pub report_id: u64, - /// Report period start - pub period_start: u64, - /// Report period end - pub period_end: u64, - /// Total policies issued - pub total_policies: u64, - /// Total claims filed - pub total_claims: u64, - /// Total claims paid - pub claims_paid: u64, - /// Total premiums collected - pub premiums_collected: i128, - /// Total payouts made - pub total_payouts: i128, - /// Loss ratio (basis points) - pub loss_ratio: u32, - /// Reserve ratio (basis points) - pub reserve_ratio: u32, - /// Generated timestamp - pub generated_at: u64, -} diff --git a/contracts/insurance/test_snapshots/test/test_claim_rejection.1.json b/contracts/insurance/test_snapshots/test/test_claim_rejection.1.json deleted file mode 100644 index 392e36a5..00000000 --- a/contracts/insurance/test_snapshots/test/test_claim_rejection.1.json +++ /dev/null @@ -1,647 +0,0 @@ -{ - "generators": { - "address": 6, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [ - [ - "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "set_admin", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [], - [], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "mint", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - }, - { - "i128": "1000" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "pay_premium", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - ] - } - }, - "sub_invocations": [ - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "transfer", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - }, - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" - }, - { - "i128": "100" - } - ] - } - }, - "sub_invocations": [] - } - ] - } - ] - ], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "file_claim", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - }, - { - "u64": "101" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "process_claim", - "args": [ - { - "u64": "1" - }, - { - "bool": false - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "account": { - "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - "balance": "0", - "seq_num": "0", - "num_sub_entries": 0, - "inflation_dest": null, - "flags": 0, - "home_domain": "", - "thresholds": "01010101", - "signers": [], - "ext": "v0" - } - }, - "ext": "v0" - }, - "live_until": null - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - "key": { - "ledger_key_nonce": { - "nonce": "801925984706572462" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "ledger_key_nonce": { - "nonce": "1033654523790656264" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "ledger_key_nonce": { - "nonce": "4837995959683129791" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", - "key": { - "ledger_key_nonce": { - "nonce": "2032731177588607455" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": { - "ledger_key_nonce": { - "nonce": "5541220902715666415" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Claim" - }, - { - "u64": "1" - } - ] - }, - "val": { - "map": [ - { - "key": { - "symbol": "course_id" - }, - "val": { - "u64": "101" - } - }, - { - "key": { - "symbol": "status" - }, - "val": { - "vec": [ - { - "symbol": "Rejected" - } - ] - } - }, - { - "key": { - "symbol": "user" - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "1" - } - }, - { - "key": { - "vec": [ - { - "symbol": "IsInsured" - }, - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - ] - }, - "val": { - "bool": true - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "key": { - "vec": [ - { - "symbol": "Balance" - }, - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - ] - }, - "durability": "persistent", - "val": { - "map": [ - { - "key": { - "symbol": "amount" - }, - "val": { - "i128": "900" - } - }, - { - "key": { - "symbol": "authorized" - }, - "val": { - "bool": true - } - }, - { - "key": { - "symbol": "clawback" - }, - "val": { - "bool": false - } - } - ] - } - } - }, - "ext": "v0" - }, - "live_until": 518400 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "key": { - "vec": [ - { - "symbol": "Balance" - }, - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" - } - ] - }, - "durability": "persistent", - "val": { - "map": [ - { - "key": { - "symbol": "amount" - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "symbol": "authorized" - }, - "val": { - "bool": true - } - }, - { - "key": { - "symbol": "clawback" - }, - "val": { - "bool": false - } - } - ] - } - } - }, - "ext": "v0" - }, - "live_until": 518400 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": "stellar_asset", - "storage": [ - { - "key": { - "symbol": "METADATA" - }, - "val": { - "map": [ - { - "key": { - "symbol": "decimal" - }, - "val": { - "u32": 7 - } - }, - { - "key": { - "symbol": "name" - }, - "val": { - "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" - } - }, - { - "key": { - "symbol": "symbol" - }, - "val": { - "string": "aaa" - } - } - ] - } - }, - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "AssetInfo" - } - ] - }, - "val": { - "vec": [ - { - "symbol": "AlphaNum4" - }, - { - "map": [ - { - "key": { - "symbol": "asset_code" - }, - "val": { - "string": "aaa\\0" - } - }, - { - "key": { - "symbol": "issuer" - }, - "val": { - "bytes": "0000000000000000000000000000000000000000000000000000000000000005" - } - } - ] - } - ] - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 120960 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_contract_address_generation.1.json b/contracts/insurance/test_snapshots/test/test_contract_address_generation.1.json deleted file mode 100644 index fc4f967f..00000000 --- a/contracts/insurance/test_snapshots/test/test_contract_address_generation.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_contract_with_different_token_addresses.1.json b/contracts/insurance/test_snapshots/test/test_contract_with_different_token_addresses.1.json deleted file mode 100644 index 0f80968a..00000000 --- a/contracts/insurance/test_snapshots/test/test_contract_with_different_token_addresses.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 6, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_file_claim_not_insured.1.json b/contracts/insurance/test_snapshots/test/test_file_claim_not_insured.1.json deleted file mode 100644 index d8709ea3..00000000 --- a/contracts/insurance/test_snapshots/test/test_file_claim_not_insured.1.json +++ /dev/null @@ -1,298 +0,0 @@ -{ - "generators": { - "address": 6, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [ - [ - "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "set_admin", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [], - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "account": { - "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - "balance": "0", - "seq_num": "0", - "num_sub_entries": 0, - "inflation_dest": null, - "flags": 0, - "home_domain": "", - "thresholds": "01010101", - "signers": [], - "ext": "v0" - } - }, - "ext": "v0" - }, - "live_until": null - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - "key": { - "ledger_key_nonce": { - "nonce": "801925984706572462" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": "stellar_asset", - "storage": [ - { - "key": { - "symbol": "METADATA" - }, - "val": { - "map": [ - { - "key": { - "symbol": "decimal" - }, - "val": { - "u32": 7 - } - }, - { - "key": { - "symbol": "name" - }, - "val": { - "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" - } - }, - { - "key": { - "symbol": "symbol" - }, - "val": { - "string": "aaa" - } - } - ] - } - }, - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "AssetInfo" - } - ] - }, - "val": { - "vec": [ - { - "symbol": "AlphaNum4" - }, - { - "map": [ - { - "key": { - "symbol": "asset_code" - }, - "val": { - "string": "aaa\\0" - } - }, - { - "key": { - "symbol": "issuer" - }, - "val": { - "bytes": "0000000000000000000000000000000000000000000000000000000000000005" - } - } - ] - } - ] - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 120960 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_initialize_call.1.json b/contracts/insurance/test_snapshots/test/test_initialize_call.1.json deleted file mode 100644 index fc4f967f..00000000 --- a/contracts/insurance/test_snapshots/test/test_initialize_call.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_initialize_consistency.1.json b/contracts/insurance/test_snapshots/test/test_initialize_consistency.1.json deleted file mode 100644 index 00c824ed..00000000 --- a/contracts/insurance/test_snapshots/test/test_initialize_consistency.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "2500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_initialize_different_oracle_addresses.1.json b/contracts/insurance/test_snapshots/test/test_initialize_different_oracle_addresses.1.json deleted file mode 100644 index 35faa501..00000000 --- a/contracts/insurance/test_snapshots/test/test_initialize_different_oracle_addresses.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_initialize_with_different_amounts.1.json b/contracts/insurance/test_snapshots/test/test_initialize_with_different_amounts.1.json deleted file mode 100644 index 905a1f3f..00000000 --- a/contracts/insurance/test_snapshots/test/test_initialize_with_different_amounts.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "1000" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "250" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_initialize_with_large_amounts.1.json b/contracts/insurance/test_snapshots/test/test_initialize_with_large_amounts.1.json deleted file mode 100644 index b55936d2..00000000 --- a/contracts/insurance/test_snapshots/test/test_initialize_with_large_amounts.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "85070591730234615865843651857942052863" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "85070591730234615865843651857942052863" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_initialize_with_same_addresses.1.json b/contracts/insurance/test_snapshots/test/test_initialize_with_same_addresses.1.json deleted file mode 100644 index 7d6de7af..00000000 --- a/contracts/insurance/test_snapshots/test/test_initialize_with_same_addresses.1.json +++ /dev/null @@ -1,134 +0,0 @@ -{ - "generators": { - "address": 2, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_initialize_with_zero_amounts.1.json b/contracts/insurance/test_snapshots/test/test_initialize_with_zero_amounts.1.json deleted file mode 100644 index d3978c72..00000000 --- a/contracts/insurance/test_snapshots/test/test_initialize_with_zero_amounts.1.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "generators": { - "address": 4, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": null - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_insurance_contract_creation.1.json b/contracts/insurance/test_snapshots/test/test_insurance_contract_creation.1.json deleted file mode 100644 index d3408012..00000000 --- a/contracts/insurance/test_snapshots/test/test_insurance_contract_creation.1.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "generators": { - "address": 1, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": null - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_insurance_flow.1.json b/contracts/insurance/test_snapshots/test/test_insurance_flow.1.json deleted file mode 100644 index d63c5e46..00000000 --- a/contracts/insurance/test_snapshots/test/test_insurance_flow.1.json +++ /dev/null @@ -1,683 +0,0 @@ -{ - "generators": { - "address": 6, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [ - [ - "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "set_admin", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [], - [], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "mint", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - }, - { - "i128": "1000" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "mint", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" - }, - { - "i128": "1000" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "pay_premium", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - ] - } - }, - "sub_invocations": [ - { - "function": { - "contract_fn": { - "contract_address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "function_name": "transfer", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - }, - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" - }, - { - "i128": "100" - } - ] - } - }, - "sub_invocations": [] - } - ] - } - ] - ], - [], - [], - [], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "file_claim", - "args": [ - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - }, - { - "u64": "101" - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [], - [ - [ - "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", - { - "function": { - "contract_fn": { - "contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "function_name": "process_claim", - "args": [ - { - "u64": "1" - }, - { - "bool": true - } - ] - } - }, - "sub_invocations": [] - } - ] - ], - [], - [], - [], - [], - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "account": { - "account_id": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - "balance": "0", - "seq_num": "0", - "num_sub_entries": 0, - "inflation_dest": null, - "flags": 0, - "home_domain": "", - "thresholds": "01010101", - "signers": [], - "ext": "v0" - } - }, - "ext": "v0" - }, - "live_until": null - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV", - "key": { - "ledger_key_nonce": { - "nonce": "801925984706572462" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "ledger_key_nonce": { - "nonce": "2032731177588607455" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4", - "key": { - "ledger_key_nonce": { - "nonce": "4837995959683129791" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M", - "key": { - "ledger_key_nonce": { - "nonce": "4270020994084947596" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": { - "ledger_key_nonce": { - "nonce": "1033654523790656264" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": { - "ledger_key_nonce": { - "nonce": "5541220902715666415" - } - }, - "durability": "temporary", - "val": "void" - } - }, - "ext": "v0" - }, - "live_until": 6311999 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Claim" - }, - { - "u64": "1" - } - ] - }, - "val": { - "map": [ - { - "key": { - "symbol": "course_id" - }, - "val": { - "u64": "101" - } - }, - { - "key": { - "symbol": "status" - }, - "val": { - "vec": [ - { - "symbol": "Paid" - } - ] - } - }, - { - "key": { - "symbol": "user" - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "1" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "key": { - "vec": [ - { - "symbol": "Balance" - }, - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - ] - }, - "durability": "persistent", - "val": { - "map": [ - { - "key": { - "symbol": "amount" - }, - "val": { - "i128": "1400" - } - }, - { - "key": { - "symbol": "authorized" - }, - "val": { - "bool": true - } - }, - { - "key": { - "symbol": "clawback" - }, - "val": { - "bool": false - } - } - ] - } - } - }, - "ext": "v0" - }, - "live_until": 518400 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "key": { - "vec": [ - { - "symbol": "Balance" - }, - { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" - } - ] - }, - "durability": "persistent", - "val": { - "map": [ - { - "key": { - "symbol": "amount" - }, - "val": { - "i128": "600" - } - }, - { - "key": { - "symbol": "authorized" - }, - "val": { - "bool": true - } - }, - { - "key": { - "symbol": "clawback" - }, - "val": { - "bool": false - } - } - ] - } - } - }, - "ext": "v0" - }, - "live_until": 518400 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CDLDVFKHEZ2RVB3NG4UQA4VPD3TSHV6XMHXMHP2BSGCJ2IIWVTOHGDSG", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": "stellar_asset", - "storage": [ - { - "key": { - "symbol": "METADATA" - }, - "val": { - "map": [ - { - "key": { - "symbol": "decimal" - }, - "val": { - "u32": 7 - } - }, - { - "key": { - "symbol": "name" - }, - "val": { - "string": "aaa:GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL7NV" - } - }, - { - "key": { - "symbol": "symbol" - }, - "val": { - "string": "aaa" - } - } - ] - } - }, - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "AssetInfo" - } - ] - }, - "val": { - "vec": [ - { - "symbol": "AlphaNum4" - }, - { - "map": [ - { - "key": { - "symbol": "asset_code" - }, - "val": { - "string": "aaa\\0" - } - }, - { - "key": { - "symbol": "issuer" - }, - "val": { - "bytes": "0000000000000000000000000000000000000000000000000000000000000005" - } - } - ] - } - ] - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 120960 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_multiple_contract_instances.1.json b/contracts/insurance/test_snapshots/test/test_multiple_contract_instances.1.json deleted file mode 100644 index 3a61d72f..00000000 --- a/contracts/insurance/test_snapshots/test/test_multiple_contract_instances.1.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "generators": { - "address": 6, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [], - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "600" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "200" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/insurance/test_snapshots/test/test_sequential_initializations.1.json b/contracts/insurance/test_snapshots/test/test_sequential_initializations.1.json deleted file mode 100644 index b06a928d..00000000 --- a/contracts/insurance/test_snapshots/test/test_sequential_initializations.1.json +++ /dev/null @@ -1,232 +0,0 @@ -{ - "generators": { - "address": 6, - "nonce": 0, - "mux_id": 0 - }, - "auth": [ - [], - [], - [], - [] - ], - "ledger": { - "protocol_version": 25, - "sequence_number": 0, - "timestamp": 0, - "network_id": "0000000000000000000000000000000000000000000000000000000000000000", - "base_reserve": 0, - "min_persistent_entry_ttl": 4096, - "min_temp_entry_ttl": 16, - "max_entry_ttl": 6312000, - "ledger_entries": [ - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAITA4", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHK3M" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "500" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "100" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_data": { - "ext": "v0", - "contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAK3IM", - "key": "ledger_key_contract_instance", - "durability": "persistent", - "val": { - "contract_instance": { - "executable": { - "wasm": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - }, - "storage": [ - { - "key": { - "vec": [ - { - "symbol": "Admin" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM" - } - }, - { - "key": { - "vec": [ - { - "symbol": "ClaimCount" - } - ] - }, - "val": { - "u64": "0" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Oracle" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDR4" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PayoutAmount" - } - ] - }, - "val": { - "i128": "1000" - } - }, - { - "key": { - "vec": [ - { - "symbol": "PremiumAmount" - } - ] - }, - "val": { - "i128": "200" - } - }, - { - "key": { - "vec": [ - { - "symbol": "Token" - } - ] - }, - "val": { - "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4" - } - } - ] - } - } - } - }, - "ext": "v0" - }, - "live_until": 4095 - }, - { - "entry": { - "last_modified_ledger_seq": 0, - "data": { - "contract_code": { - "ext": "v0", - "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", - "code": "" - } - }, - "ext": "v0" - }, - "live_until": 4095 - } - ] - }, - "events": [] -} \ No newline at end of file diff --git a/contracts/licenses/Cargo.toml b/contracts/licenses/Cargo.toml deleted file mode 100644 index e69de29b..00000000 diff --git a/contracts/licenses/src/lib.rs b/contracts/licenses/src/lib.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/contracts/market/Cargo.toml b/contracts/market/Cargo.toml deleted file mode 100644 index e69de29b..00000000 diff --git a/contracts/market/src/lib.rs b/contracts/market/src/lib.rs deleted file mode 100644 index e9e6582b..00000000 --- a/contracts/market/src/lib.rs +++ /dev/null @@ -1,1363 +0,0 @@ -#![allow(clippy::all)] -#![allow(unused)] - -//! Enhanced Insurance Contract -//! -//! This contract implements a comprehensive decentralized insurance system with: -//! - AI-powered risk assessment and dynamic pricing -//! - Automated claims processing with AI verification -//! - Parametric insurance for learning outcomes -//! - Insurance pool optimization and reinsurance -//! - Cross-chain insurance and risk sharing -//! - Insurance tokenization and governance -//! - Compliance and regulatory reporting -//! -//! # Core Features -//! -//! ## Risk Assessment -//! - AI-powered risk scoring based on user history and course factors -//! - Dynamic premium calculation using risk multipliers -//! - Real-time risk profile updates -//! -//! ## Policy Management -//! - Time-based policies with expiration -//! - Multi-claim support per policy -//! - Parametric triggers for automatic payouts -//! -//! ## Claims Processing -//! - AI verification with confidence scoring -//! - Multi-layer validation (AI + Oracle) -//! - Automated dispute resolution -//! -//! ## Pool Optimization -//! - Dynamic utilization management -//! - Reinsurance partnerships -//! - Cross-pool risk sharing -//! -//! ## Governance -//! - Community-driven parameter changes -//! - Token-weighted voting -//! - Transparent proposal process - -#![no_std] -#![allow(clippy::needless_pass_by_value)] -#![allow(clippy::must_use_candidate)] -#![allow(clippy::missing_panics_doc)] -#![allow(clippy::missing_errors_doc)] -#![allow(clippy::doc_markdown)] -#![allow(clippy::panic_in_result_fn)] - -mod errors; -mod storage; -mod types; - -use crate::errors::InsuranceError; -use crate::storage::*; -use crate::types::*; -use soroban_sdk::{ - contract, contractimpl, contracttype, token, vec, Address, Bytes, Env, String, Vec, -}; - -#[contract] -pub struct EnhancedInsurance; - -#[contractimpl] -impl EnhancedInsurance { - // ===== Initialization ===== - - /// Initialize the enhanced insurance contract - pub fn initialize( - env: Env, - admin: Address, - oracle: Address, - token: Address, - ) -> Result<(), InsuranceError> { - if env.storage().instance().has(&DataKey::Admin) { - return Err(InsuranceError::AlreadyInitialized); - } - - env.storage().instance().set(&DataKey::Admin, &admin); - env.storage().instance().set(&DataKey::Oracle, &oracle); - env.storage().instance().set(&DataKey::Token, &token); - - // RBAC Initialization: Set admin as SUPER_ADMIN - env.storage().instance().set(&DataKey::HasRole(ROLE_SUPER_ADMIN, admin.clone()), &true); - - // Multi-sig Initialization: Admin is the first signer - let mut signers: Vec
= Vec::new(&env); - signers.push_back(admin.clone()); - env.storage().instance().set(&DataKey::MultiSigSigners, &signers); - env.storage().instance().set(&DataKey::MultiSigThreshold, &1u32); - env.storage().instance().set(&DataKey::OperationCount, &0u64); - - // Set default configuration parameters - env.storage() - .instance() - .set(&DataKey::RiskProfileCount, &0u64); - env.storage().instance().set(&DataKey::PolicyCount, &0u64); - env.storage().instance().set(&DataKey::ClaimCount, &0u64); - env.storage().instance().set(&DataKey::TriggerCount, &0u64); - env.storage().instance().set(&DataKey::PoolCount, &0u64); - env.storage().instance().set(&DataKey::TokenCount, &0u64); - env.storage().instance().set(&DataKey::ProposalCount, &0u64); - env.storage().instance().set(&DataKey::ReportCount, &0u64); - - // Emit Initialization Event for Audit - env.events().publish((soroban_sdk::symbol_short!("Init"), admin), (oracle, token)); - - // Set default configuration - env.storage() - .instance() - .set(&DataKey::RiskModelWeights, &RiskModelWeights::default()); - env.storage() - .instance() - .set(&DataKey::BasePremiumRate, &100i128); // 1% base rate - env.storage().instance().set( - &DataKey::RiskMultiplierRanges, - &RiskMultiplierRanges::default(), - ); - env.storage() - .instance() - .set(&DataKey::UtilizationTargets, &UtilizationTargets::default()); - env.storage() - .instance() - .set(&DataKey::MinimumRiskReserve, &1500u32); // 15% - env.storage().instance().set( - &DataKey::GovernanceParameters, - &GovernanceParameters::default(), - ); - env.storage() - .instance() - .set(&DataKey::GovernanceQuorum, &5000u32); // 50% - env.storage().instance().set(&DataKey::VotingPeriod, &7u32); // 7 days - - Ok(()) - } - - // ===== RBAC Helper ===== - - fn check_role(env: &Env, user: &Address, role: u32) -> Result<(), InsuranceError> { - user.require_auth(); - // Super Admin bypass - if env.storage().instance().get(&DataKey::HasRole(ROLE_SUPER_ADMIN, user.clone())).unwrap_or(false) { - return Ok(()); - } - if env.storage().instance().get(&DataKey::HasRole(role, user.clone())).unwrap_or(false) { - return Ok(()); - } - Err(InsuranceError::UnauthorizedRole) - } - - // ===== Governance & RBAC Endpoints ===== - - /// Grant a specific role (Super Admin only) - pub fn grant_role(env: Env, caller: Address, role: u32, account: Address) -> Result<(), InsuranceError> { - Self::check_role(&env, &caller, ROLE_SUPER_ADMIN)?; - env.storage().instance().set(&DataKey::HasRole(role, account.clone()), &true); - env.events().publish((soroban_sdk::symbol_short!("RoleGnt"), account), role); - Ok(()) - } - - /// Revoke a specific role (Super Admin only) - pub fn revoke_role(env: Env, caller: Address, role: u32, account: Address) -> Result<(), InsuranceError> { - Self::check_role(&env, &caller, ROLE_SUPER_ADMIN)?; - env.storage().instance().set(&DataKey::HasRole(role, account.clone()), &false); - env.events().publish((soroban_sdk::symbol_short!("RoleRvk"), account), role); - Ok(()) - } - - /// Initiate admin transfer with 24-hour timelock - pub fn transfer_admin(env: Env, caller: Address, new_admin: Address) -> Result<(), InsuranceError> { - Self::check_role(&env, &caller, ROLE_SUPER_ADMIN)?; - let ready_at = env.ledger().timestamp() + 86400; // 24 hours - env.storage().instance().set(&DataKey::PendingAdminTransfer, &new_admin); - env.storage().instance().set(&DataKey::AdminTransferTimestamp, &ready_at); - env.events().publish((soroban_sdk::symbol_short!("AdmTrns"), new_admin), ready_at); - Ok(()) - } - - /// Claim admin role after timelock expires - pub fn accept_admin(env: Env, new_admin: Address) -> Result<(), InsuranceError> { - new_admin.require_auth(); - let pending: Address = env.storage().instance().get(&DataKey::PendingAdminTransfer).ok_or(InsuranceError::TransferNotPending)?; - if pending != new_admin { return Err(InsuranceError::UnauthorizedRole); } - - let ready_at = env.storage().instance().get(&DataKey::AdminTransferTimestamp).unwrap_or(u64::MAX); - if env.ledger().timestamp() < ready_at { return Err(InsuranceError::TimelockNotExpired); } - - // Finalize transfer - let old_admin: Address = env.storage().instance().get(&DataKey::Admin).ok_or(InsuranceError::NotInitialized)?; - env.storage().instance().set(&DataKey::HasRole(ROLE_SUPER_ADMIN, old_admin), &false); - env.storage().instance().set(&DataKey::HasRole(ROLE_SUPER_ADMIN, new_admin.clone()), &true); - env.storage().instance().set(&DataKey::Admin, &new_admin); - - env.storage().instance().remove(&DataKey::PendingAdminTransfer); - env.storage().instance().remove(&DataKey::AdminTransferTimestamp); - - env.events().publish((soroban_sdk::symbol_short!("AdmAccp"), new_admin), env.ledger().timestamp()); - Ok(()) - } - - // ===== Multi-Sig Framework ===== - - /// Propose a critical action (Signers only) - pub fn propose_action(env: Env, proposer: Address, action: CriticalAction) -> Result { - proposer.require_auth(); - let signers: Vec
= env.storage().instance().get(&DataKey::MultiSigSigners).unwrap_or_else(|| Vec::new(&env)); - if !signers.contains(&proposer) { return Err(InsuranceError::NotASigner); } - - let mut count: u64 = env.storage().instance().get(&DataKey::OperationCount).unwrap_or(0); - count += 1; - let id = count as u32; - - let op = CriticalOperation { - id, - action: action.clone(), - proposer: proposer.clone(), - created_at: env.ledger().timestamp(), - ready_at: env.ledger().timestamp() + 10, // Small delay for demo, in production would be higher - executed: false, - }; - - env.storage().instance().set(&DataKey::CriticalOperation(id), &op); - env.storage().instance().set(&DataKey::OperationCount, &count); - - // Auto-approve by proposer - let mut approvals = Vec::new(&env); - approvals.push_back(proposer); - env.storage().instance().set(&DataKey::OperationApprovals(id), &approvals); - - env.events().publish((soroban_sdk::symbol_short!("PropAct"), id), action); - Ok(id) - } - - /// Approve a pending action - pub fn approve_action(env: Env, signer: Address, op_id: u32) -> Result<(), InsuranceError> { - signer.require_auth(); - let signers: Vec
= env.storage().instance().get(&DataKey::MultiSigSigners).unwrap_or_else(|| Vec::new(&env)); - if !signers.contains(&signer) { return Err(InsuranceError::NotASigner); } - - let op: CriticalOperation = env.storage().instance().get(&DataKey::CriticalOperation(op_id)).ok_or(InsuranceError::OperationNotFound)?; - if op.executed { return Err(InsuranceError::OperationExecuted); } - - let mut approvals: Vec
= env.storage().instance().get(&DataKey::OperationApprovals(op_id)).unwrap_or_else(|| Vec::new(&env)); - if approvals.contains(&signer) { return Err(InsuranceError::AlreadyApproved); } - - approvals.push_back(signer.clone()); - env.storage().instance().set(&DataKey::OperationApprovals(op_id), &approvals); - - env.events().publish((soroban_sdk::symbol_short!("Approve"), op_id), signer); - Ok(()) - } - - /// Execute an approved action - pub fn execute_action(env: Env, executor: Address, op_id: u32) -> Result<(), InsuranceError> { - executor.require_auth(); - let mut op: CriticalOperation = env.storage().instance().get(&DataKey::CriticalOperation(op_id)).ok_or(InsuranceError::OperationNotFound)?; - if op.executed { return Err(InsuranceError::OperationExecuted); } - if env.ledger().timestamp() < op.ready_at { return Err(InsuranceError::TimelockNotExpired); } - - let approvals: Vec
= env.storage().instance().get(&DataKey::OperationApprovals(op_id)).unwrap_or_else(|| Vec::new(&env)); - let threshold = env.storage().instance().get(&DataKey::MultiSigThreshold).unwrap_or(1); - - if (approvals.len() as u32) < threshold { return Err(InsuranceError::ThresholdNotMet); } - - // Execute logic based on action - match &op.action { - CriticalAction::ChangeBasePremium(new_rate) => { - env.storage().instance().set(&DataKey::BasePremiumRate, new_rate); - }, - CriticalAction::PausePool(pool_id) => { - let mut pool: OptimizedPool = env.storage().instance().get(&DataKey::Pool(*pool_id)).ok_or(InsuranceError::PoolNotFound)?; - pool.status = PoolStatus::Paused; - env.storage().instance().set(&DataKey::Pool(*pool_id), &pool); - }, - _ => { /* Other actions implemented similarly */ } - } - - op.executed = true; - env.storage().instance().set(&DataKey::CriticalOperation(op_id), &op); - - env.events().publish((soroban_sdk::symbol_short!("Execute"), op_id), ()); - Ok(()) - } - - // ===== Risk Assessment Module ===== - - /// Create or update a user's risk profile - pub fn create_risk_profile( - env: Env, - user: Address, - factors: RiskFactors, - ) -> Result { - user.require_auth(); - - // Validate risk factors - if factors.completion_rate > 100 || factors.reputation_score > 100 { - return Err(InsuranceError::InvalidRiskFactors); - } - - if factors.course_difficulty > 10 || factors.experience_level > 3 { - return Err(InsuranceError::InvalidRiskFactors); - } - - // Calculate risk score using weighted model - let weights: RiskModelWeights = env - .storage() - .instance() - .get(&DataKey::RiskModelWeights) - .unwrap_or_else(RiskModelWeights::default); - - let risk_score = Self::calculate_risk_score(&factors, &weights)?; - - // Update existing profile or create new one - let mut profile_id = env - .storage() - .instance() - .get(&DataKey::RiskProfileByUser(user.clone())) - .unwrap_or(0); - - if profile_id == 0 { - let mut count = env - .storage() - .instance() - .get(&DataKey::RiskProfileCount) - .unwrap_or(0); - count += 1; - profile_id = count; - env.storage() - .instance() - .set(&DataKey::RiskProfileCount, &count); - env.storage() - .instance() - .set(&DataKey::RiskProfileByUser(user.clone()), &profile_id); - } - - let profile = RiskProfile { - profile_id, - user: user.clone(), - factors, - risk_score, - timestamp: env.ledger().timestamp(), - }; - - env.storage() - .instance() - .set(&DataKey::RiskProfile(profile_id), &profile); - - Ok(profile_id) - } - - /// Calculate risk score based on factors and weights - fn calculate_risk_score( - factors: &RiskFactors, - weights: &RiskModelWeights, - ) -> Result { - // Normalize all factors to 0-100 scale - let completion_factor = 100 - factors.completion_rate; // Inverse: lower completion = higher risk - let reputation_factor = 100 - factors.reputation_score; // Inverse: lower reputation = higher risk - let difficulty_factor = factors.course_difficulty * 10; // Scale 1-10 to 10-100 - let duration_factor = (factors.course_duration / 10).min(100); // Cap at 100 - let experience_factor = match factors.experience_level { - 1 => 80, // Beginner - high risk - 2 => 40, // Intermediate - medium risk - 3 => 10, // Advanced - low risk - _ => 50, // Unknown - default medium risk - }; - let frequency_factor = factors.claim_frequency.min(100); - let time_factor = (factors.time_since_last_completion / 86400).min(100) as u32; // Days since last completion - - // Calculate weighted score - let total_weight = weights.completion_rate_weight - + weights.reputation_score_weight - + weights.course_difficulty_weight - + weights.course_duration_weight - + weights.experience_level_weight - + weights.claim_frequency_weight - + weights.time_factor_weight; - - if total_weight == 0 { - return Err(InsuranceError::RiskModelNotTrained); - } - - let weighted_score = ((completion_factor as u64 * weights.completion_rate_weight as u64) - + (reputation_factor as u64 * weights.reputation_score_weight as u64) - + (difficulty_factor as u64 * weights.course_difficulty_weight as u64) - + (duration_factor as u64 * weights.course_duration_weight as u64) - + (experience_factor as u64 * weights.experience_level_weight as u64) - + (frequency_factor as u64 * weights.claim_frequency_weight as u64) - + (time_factor as u64 * weights.time_factor_weight as u64)) - / total_weight as u64; - - Ok(weighted_score.min(100) as u32) - } - - /// Get risk profile for a user - pub fn get_risk_profile(env: Env, user: Address) -> Option { - let profile_id = env - .storage() - .instance() - .get(&DataKey::RiskProfileByUser(user))?; - env.storage() - .instance() - .get(&DataKey::RiskProfile(profile_id)) - } - - /// Get risk multiplier based on risk score - pub fn get_risk_multiplier(env: Env, risk_score: u32) -> Result { - if risk_score > 100 { - return Err(InsuranceError::RiskScoreOutOfRange); - } - - let ranges: RiskMultiplierRanges = env - .storage() - .instance() - .get(&DataKey::RiskMultiplierRanges) - .unwrap_or_else(RiskMultiplierRanges::default); - - let multiplier = if risk_score <= ranges.low_risk_max { - ranges.low_risk_max - } else if risk_score <= ranges.medium_risk_max { - ranges.medium_risk_max - } else { - ranges.high_risk_max - }; - - Ok(multiplier) - } - - // ===== Policy Management Module ===== - - /// Purchase insurance policy with dynamic pricing - pub fn purchase_policy( - env: Env, - user: Address, - course_id: u64, - coverage_amount: i128, - ) -> Result { - user.require_auth(); - - // Get or create risk profile - let profile = Self::get_risk_profile(env.clone(), user.clone()) - .ok_or(InsuranceError::RiskProfileNotFound)?; - - // Calculate base premium - let base_premium_rate: i128 = env - .storage() - .instance() - .get(&DataKey::BasePremiumRate) - .unwrap_or(100); // 1% default - - let base_premium = (coverage_amount * base_premium_rate) / 10000; - - // Apply risk multiplier - let risk_multiplier = Self::get_risk_multiplier(env.clone(), profile.risk_score)?; - let final_premium = (base_premium * risk_multiplier as i128) / 10000; - - // Transfer premium payment - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - token_client.transfer(&user, &env.current_contract_address(), &final_premium); - - // Create policy - let mut policy_count = env - .storage() - .instance() - .get(&DataKey::PolicyCount) - .unwrap_or(0); - policy_count += 1; - - let policy = InsurancePolicy { - policy_id: policy_count, - holder: user.clone(), - course_id, - risk_profile_id: profile.profile_id, - base_premium, - risk_multiplier, - final_premium, - coverage_amount, - start_time: env.ledger().timestamp(), - expiration_time: env.ledger().timestamp() + 30 * 24 * 60 * 60, // 30 days - status: PolicyStatus::Active, - }; - - env.storage() - .instance() - .set(&DataKey::Policy(policy_count), &policy); - env.storage() - .instance() - .set(&DataKey::PolicyCount, &policy_count); - env.storage().instance().set( - &DataKey::PolicyByUser(user.clone(), course_id), - &policy_count, - ); - - // Update user's active policies - let mut active_policies: Vec = env - .storage() - .instance() - .get(&DataKey::ActivePolicies(user.clone())) - .unwrap_or_else(|| vec![&env]); - active_policies.push_back(policy_count); - env.storage() - .instance() - .set(&DataKey::ActivePolicies(user), &active_policies); - - Ok(policy_count) - } - - // ===== Claims Processing Module ===== - - /// File an insurance claim with evidence - pub fn file_claim( - env: Env, - user: Address, - policy_id: u64, - evidence: Bytes, - reason: Bytes, - ) -> Result { - user.require_auth(); - - // Validate policy exists and is active - let mut policy: InsurancePolicy = env - .storage() - .instance() - .get(&DataKey::Policy(policy_id)) - .ok_or(InsuranceError::PolicyNotFound)?; - - if policy.status != PolicyStatus::Active { - return Err(InsuranceError::PolicyExpired); - } - - if env.ledger().timestamp() > policy.expiration_time { - return Err(InsuranceError::PolicyExpired); - } - - // Check if claim already exists for this policy - if env - .storage() - .instance() - .has(&DataKey::ClaimByPolicy(policy_id)) - { - return Err(InsuranceError::ClaimAlreadyFiled); - } - - // AI verification would happen here in a real implementation - // For now, we'll simulate with a confidence score - let ai_confidence = 75u32; // Simulated AI confidence - - // Create claim - let mut claim_count = env - .storage() - .instance() - .get(&DataKey::ClaimCount) - .unwrap_or(0); - claim_count += 1; - - let claim = AdvancedClaim { - claim_id: claim_count, - policy_id, - filed_at: env.ledger().timestamp(), - status: if ai_confidence >= 80 { - ClaimStatus::AiVerified - } else { - ClaimStatus::AiProcessing - }, - ai_confidence, - evidence, - oracle_verified: false, - payout_amount: if ai_confidence >= 80 { - policy.coverage_amount - } else { - 0 - }, - reason: String::from_str(&env, &"Claim filed"), // Simplified for now - }; - - env.storage() - .instance() - .set(&DataKey::Claim(claim_count), &claim); - env.storage() - .instance() - .set(&DataKey::ClaimByPolicy(policy_id), &claim_count); - env.storage() - .instance() - .set(&DataKey::ClaimCount, &claim_count); - - // Update policy status - if ai_confidence >= 80 { - policy.status = PolicyStatus::Claimed; - env.storage() - .instance() - .set(&DataKey::Policy(policy_id), &policy); - } - - // Add to pending claims if needs oracle review - if ai_confidence < 80 { - let mut pending: Vec = env - .storage() - .instance() - .get(&DataKey::PendingClaims) - .unwrap_or_else(|| Vec::new(&env)); - pending.push_back(claim_count); - env.storage() - .instance() - .set(&DataKey::PendingClaims, &pending); - } - - Ok(claim_count) - } - - /// Get claim information - pub fn get_claim(env: Env, claim_id: u64) -> Option { - env.storage().instance().get(&DataKey::Claim(claim_id)) - } - - // ===== Parametric Insurance Module ===== - - /// Create parametric insurance trigger - pub fn create_parametric_trigger( - env: Env, - admin: Address, - course_id: u64, - metric: LearningMetric, - threshold: i128, - payout_amount: i128, - ) -> Result { - Self::check_role(&env, &admin, ROLE_RISK_MANAGER)?; - - let mut trigger_count = env - .storage() - .instance() - .get(&DataKey::TriggerCount) - .unwrap_or(0); - trigger_count += 1; - - let trigger = ParametricTrigger { - trigger_id: trigger_count, - course_id, - metric, - threshold, - payout_amount, - is_active: true, - }; - - env.storage() - .instance() - .set(&DataKey::ParametricTrigger(trigger_count), &trigger); - env.storage() - .instance() - .set(&DataKey::TriggerCount, &trigger_count); - - // Add to course triggers - let mut course_triggers: Vec = env - .storage() - .instance() - .get(&DataKey::TriggerByCourse(course_id)) - .unwrap_or_else(|| vec![&env]); - course_triggers.push_back(trigger_count); - env.storage() - .instance() - .set(&DataKey::TriggerByCourse(course_id), &course_triggers); - - Ok(trigger_count) - } - - /// Execute parametric trigger payout - pub fn execute_trigger( - env: Env, - trigger_id: u64, - user: Address, - actual_value: i128, - ) -> Result<(), InsuranceError> { - let trigger: ParametricTrigger = env - .storage() - .instance() - .get(&DataKey::ParametricTrigger(trigger_id)) - .ok_or(InsuranceError::TriggerNotFound)?; - - if !trigger.is_active { - return Err(InsuranceError::TriggerNotActive); - } - - // Check if threshold condition is met - let triggered = match trigger.metric { - LearningMetric::CompletionPercentage - | LearningMetric::AssessmentScore - | LearningMetric::EngagementLevel => actual_value < trigger.threshold, - LearningMetric::CompletionTime | LearningMetric::AttemptCount => { - actual_value > trigger.threshold - } - }; - - if !triggered { - return Err(InsuranceError::ParametricConditionNotMet); - } - - // Transfer payout - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - token_client.transfer( - &env.current_contract_address(), - &user, - &trigger.payout_amount, - ); - - // Deactivate trigger - let mut updated_trigger = trigger; - updated_trigger.is_active = false; - env.storage() - .instance() - .set(&DataKey::ParametricTrigger(trigger_id), &updated_trigger); - - Ok(()) - } - - // ===== Insurance Pool Optimization Module ===== - - /// Create an optimized insurance pool - pub fn create_pool( - env: Env, - admin: Address, - name: Bytes, - target_utilization: u32, - risk_reserve_ratio: u32, - ) -> Result { - Self::check_role(&env, &admin, ROLE_POOL_MANAGER)?; - - let mut pool_count = env - .storage() - .instance() - .get(&DataKey::PoolCount) - .unwrap_or(0); - pool_count += 1; - - let pool = OptimizedPool { - pool_id: pool_count, - name: String::from_str(&env, &"Insurance Pool"), // Simplified for now - total_assets: 0, - utilization_rate: 0, - target_utilization, - risk_reserve_ratio, - reinsurance_partners: Vec::new(&env), - status: PoolStatus::Active, - }; - - env.storage() - .instance() - .set(&DataKey::Pool(pool_count), &pool); - env.storage() - .instance() - .set(&DataKey::PoolCount, &pool_count); - - // Add to active pools - let mut active_pools: Vec = env - .storage() - .instance() - .get(&DataKey::ActivePools) - .unwrap_or_else(|| Vec::new(&env)); - active_pools.push_back(pool_count); - env.storage() - .instance() - .set(&DataKey::ActivePools, &active_pools); - - Ok(pool_count) - } - - /// Add reinsurance partner to pool - pub fn add_reinsurance_partner( - env: Env, - admin: Address, - pool_id: u64, - partner: Address, - allocation_percentage: u32, - ) -> Result<(), InsuranceError> { - Self::check_role(&env, &admin, ROLE_POOL_MANAGER)?; - - let mut pool: OptimizedPool = env - .storage() - .instance() - .get(&DataKey::Pool(pool_id)) - .ok_or(InsuranceError::PoolNotFound)?; - - // Add partner to pool - pool.reinsurance_partners.push_back(partner.clone()); - env.storage().instance().set(&DataKey::Pool(pool_id), &pool); - - // Set allocation - env.storage().instance().set( - &DataKey::ReinsuranceAllocation(pool_id, partner.clone()), - &allocation_percentage, - ); - - // Add to reinsurance partners list - let mut partners: Vec
= env - .storage() - .instance() - .get(&DataKey::ReinsurancePartners) - .unwrap_or_else(|| Vec::new(&env)); - partners.push_back(partner); - env.storage() - .instance() - .set(&DataKey::ReinsurancePartners, &partners); - - Ok(()) - } - - /// Optimize pool utilization - pub fn optimize_pool_utilization( - env: Env, - pool_id: u64, - ) -> Result { - let pool: OptimizedPool = env - .storage() - .instance() - .get(&DataKey::Pool(pool_id)) - .ok_or(InsuranceError::PoolNotFound)?; - - if pool.status != PoolStatus::Active { - return Err(InsuranceError::PoolNotActive); - } - - // Calculate current utilization - let current_utilization = Self::calculate_pool_utilization(env.clone(), pool_id)?; - - // Calculate performance metrics - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - let pool_balance = token_client.balance(&env.current_contract_address()); - - let performance = PoolPerformance { - pool_id, - period_start: env.ledger().timestamp() - 30 * 24 * 60 * 60, // Last 30 days - period_end: env.ledger().timestamp(), - total_assets: pool_balance, - premiums_earned: 0, // Would be tracked in real implementation - claims_paid: 0, // Would be tracked in real implementation - net_profit: 0, // Would be calculated in real implementation - utilization_rate: current_utilization, - loss_ratio: 0, // Would be calculated in real implementation - roi_percentage: 0, // Would be calculated in real implementation - }; - - // Store performance metrics - env.storage() - .instance() - .set(&DataKey::PoolPerformance(pool_id), &performance); - - Ok(performance) - } - - /// Calculate pool utilization rate - fn calculate_pool_utilization(env: Env, pool_id: u64) -> Result { - // In a real implementation, this would calculate: - // (Total Coverage Amount / Total Pool Assets) * 10000 - // For now, return simulated value - Ok(7500) // 75% - } - - // ===== Insurance Analytics Module ===== - - /// Record daily metrics for analytics - pub fn record_daily_metrics(env: Env) -> Result<(), InsuranceError> { - let today = env.ledger().timestamp() / (24 * 60 * 60); // Unix days - let yesterday = today - 1; - - // Get yesterday's metrics (would be calculated from events in real implementation) - let metrics = DailyMetrics { - date: yesterday * 24 * 60 * 60, - policies_issued: 15, // Simulated data - premiums_collected: 15000, - claims_filed: 3, - claims_paid: 2, - total_payouts: 20000, - active_policies: 142, - pool_utilization: 7500, // 75% - average_risk_score: 45, - }; - - env.storage() - .instance() - .set(&DataKey::DailyMetrics(yesterday), &metrics); - - // Update risk distribution - let distribution = RiskDistribution { - low_risk_count: 85, - medium_risk_count: 42, - high_risk_count: 15, - average_risk_score: 45, - risk_std_dev: 22, - }; - - env.storage() - .instance() - .set(&DataKey::RiskDistribution, &distribution); - - Ok(()) - } - - /// Generate actuarial report - pub fn generate_actuarial_report( - env: Env, - days: u32, - ) -> Result { - // In a real implementation, this would analyze historical data - // For now, return current distribution - env.storage() - .instance() - .get(&DataKey::RiskDistribution) - .ok_or(InsuranceError::AnalyticsNotAvailable) - } - - /// Get daily metrics for a specific date - pub fn get_daily_metrics(env: Env, date: u64) -> Option { - let day = date / (24 * 60 * 60); - env.storage().instance().get(&DataKey::DailyMetrics(day)) - } - - // ===== Insurance Governance Module ===== - - /// Create governance proposal - pub fn create_proposal( - env: Env, - proposer: Address, - title: Bytes, - description: Bytes, - proposal_type: ProposalType, - new_value: i128, - ) -> Result { - proposer.require_auth(); - - // Check if proposer has minimum tokens (simplified check) - let token_addr = env - .storage() - .instance() - .get(&DataKey::Token) - .ok_or(InsuranceError::NotInitialized)?; - let token_client = token::Client::new(&env, &token_addr); - let balance = token_client.balance(&proposer); - - let governance_params: GovernanceParameters = env - .storage() - .instance() - .get(&DataKey::GovernanceParameters) - .unwrap_or_else(GovernanceParameters::default); - - if balance < governance_params.proposal_threshold as i128 { - return Err(InsuranceError::InsufficientTokenBalance); - } - - let mut proposal_count = env - .storage() - .instance() - .get(&DataKey::ProposalCount) - .unwrap_or(0); - proposal_count += 1; - - let proposal = InsuranceProposal { - proposal_id: proposal_count, - title: String::from_str(&env, &"Proposal Title"), // Simplified for now - description: String::from_str(&env, &"Proposal Description"), // Simplified for now - proposal_type, - new_value, - voting_start: env.ledger().timestamp(), - voting_end: env.ledger().timestamp() - + (governance_params.voting_period_days as u64 * 24 * 60 * 60), - votes_for: 0, - votes_against: 0, - status: ProposalStatus::Active, - }; - - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_count), &proposal); - env.storage() - .instance() - .set(&DataKey::ProposalCount, &proposal_count); - - Ok(proposal_count) - } - - /// Vote on governance proposal - pub fn vote( - env: Env, - voter: Address, - proposal_id: u64, - support: bool, - ) -> Result<(), InsuranceError> { - voter.require_auth(); - - let mut proposal: InsuranceProposal = env - .storage() - .instance() - .get(&DataKey::Proposal(proposal_id)) - .ok_or(InsuranceError::ProposalNotFound)?; - - if proposal.status != ProposalStatus::Active { - return Err(InsuranceError::ProposalNotActive); - } - - if env.ledger().timestamp() > proposal.voting_end { - return Err(InsuranceError::VotingPeriodEnded); - } - - // Check if already voted - let vote_key = DataKey::Vote(voter.clone(), proposal_id); - if env.storage().instance().has(&vote_key) { - return Err(InsuranceError::AlreadyVoted); - } - - // Record vote - env.storage().instance().set(&vote_key, &true); - - // Update vote counts - if support { - proposal.votes_for += 1; - } else { - proposal.votes_against += 1; - } - - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - - Ok(()) - } - - /// Execute passed proposal - pub fn execute_proposal( - env: Env, - admin: Address, - proposal_id: u64, - ) -> Result<(), InsuranceError> { - Self::check_role(&env, &admin, ROLE_SUPER_ADMIN)?; - - let mut proposal: InsuranceProposal = env - .storage() - .instance() - .get(&DataKey::Proposal(proposal_id)) - .ok_or(InsuranceError::ProposalNotFound)?; - - // Check if voting period ended and proposal passed - if env.ledger().timestamp() < proposal.voting_end { - return Err(InsuranceError::VotingPeriodEnded); - } - - let governance_params: GovernanceParameters = env - .storage() - .instance() - .get(&DataKey::GovernanceParameters) - .unwrap_or_else(GovernanceParameters::default); - - let total_votes = proposal.votes_for + proposal.votes_against; - let quorum_met = - (total_votes * 10000) >= (governance_params.quorum_percentage as u64 * 100); - let approved = proposal.votes_for > proposal.votes_against; - - if !quorum_met { - proposal.status = ProposalStatus::Rejected; - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - return Err(InsuranceError::GovernanceQuorumNotMet); - } - - if !approved { - proposal.status = ProposalStatus::Rejected; - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - return Err(InsuranceError::ProposalNotActive); - } - - // Execute the proposal - match proposal.proposal_type { - ProposalType::PremiumRate => { - env.storage() - .instance() - .set(&DataKey::BasePremiumRate, &proposal.new_value); - } - ProposalType::RiskMultiplier => { - // Would update risk multiplier ranges - } - ProposalType::UtilizationTarget => { - // Would update utilization targets - } - ProposalType::ReinsurancePartner => { - // Would add/remove reinsurance partner - } - ProposalType::Governance => { - // Would update governance parameters - } - } - - proposal.status = ProposalStatus::Passed; - env.storage() - .instance() - .set(&DataKey::Proposal(proposal_id), &proposal); - - Ok(()) - } - - // ===== Insurance Tokenization Module ===== - - /// Create insurance token representing pool shares - pub fn create_insurance_token( - env: Env, - admin: Address, - pool_id: u64, - name: Bytes, - symbol: Bytes, - total_supply: i128, - ) -> Result { - Self::check_role(&env, &admin, ROLE_SUPER_ADMIN)?; - - // Verify pool exists - let _pool: OptimizedPool = env - .storage() - .instance() - .get(&DataKey::Pool(pool_id)) - .ok_or(InsuranceError::PoolNotFound)?; - - let mut token_count = env - .storage() - .instance() - .get(&DataKey::TokenCount) - .unwrap_or(0); - token_count += 1; - - let token = InsuranceToken { - token_id: token_count, - pool_id, - name: String::from_str(&env, &"Insurance Token"), // Simplified for now - symbol: String::from_str(&env, &"INS"), // Simplified for now - total_supply, - holder: admin.clone(), - balance: total_supply, - }; - - env.storage() - .instance() - .set(&DataKey::InsuranceToken(token_count), &token); - env.storage() - .instance() - .set(&DataKey::TokenByPool(pool_id), &token_count); - env.storage() - .instance() - .set(&DataKey::TokenHolder(admin, token_count), &total_supply); - env.storage() - .instance() - .set(&DataKey::TokenCount, &token_count); - - Ok(token_count) - } - - /// Transfer insurance tokens - pub fn transfer_tokens( - env: Env, - from: Address, - to: Address, - token_id: u64, - amount: i128, - ) -> Result<(), InsuranceError> { - from.require_auth(); - - let mut token: InsuranceToken = env - .storage() - .instance() - .get(&DataKey::InsuranceToken(token_id)) - .ok_or(InsuranceError::TokenNotFound)?; - - // Check balance - let from_balance: i128 = env - .storage() - .instance() - .get(&DataKey::TokenHolder(from.clone(), token_id)) - .unwrap_or(0); - - if from_balance < amount { - return Err(InsuranceError::InsufficientTokenBalance); - } - - let to_balance: i128 = env - .storage() - .instance() - .get(&DataKey::TokenHolder(to.clone(), token_id)) - .unwrap_or(0); - - // Update balances - env.storage().instance().set( - &DataKey::TokenHolder(from.clone(), token_id), - &(from_balance - amount), - ); - env.storage().instance().set( - &DataKey::TokenHolder(to.clone(), token_id), - &(to_balance + amount), - ); - - // Update token holder if transferring all tokens - if from_balance - amount == 0 { - token.holder = to.clone(); - env.storage() - .instance() - .set(&DataKey::InsuranceToken(token_id), &token); - } - - Ok(()) - } - - // ===== Compliance and Reporting Module ===== - - /// Generate compliance report - pub fn generate_compliance_report( - env: Env, - admin: Address, - period_days: u32, - ) -> Result { - Self::check_role(&env, &admin, ROLE_ORACLE_MANAGER)?; - - let period_start = env.ledger().timestamp() - (period_days as u64 * 24 * 60 * 60); - let period_end = env.ledger().timestamp(); - - // Calculate metrics (simplified for demo) - let mut report_count = env - .storage() - .instance() - .get(&DataKey::ReportCount) - .unwrap_or(0); - report_count += 1; - - let report = ComplianceReport { - report_id: report_count, - period_start, - period_end, - total_policies: 287, - total_claims: 42, - claims_paid: 35, - premiums_collected: 287000, - total_payouts: 350000, - loss_ratio: 12200, // 122% - reserve_ratio: 1500, // 15% - generated_at: env.ledger().timestamp(), - }; - - env.storage() - .instance() - .set(&DataKey::ComplianceReport(report_count), &report); - env.storage() - .instance() - .set(&DataKey::ReportCount, &report_count); - env.storage() - .instance() - .set(&DataKey::LastReportGeneration, &env.ledger().timestamp()); - - Ok(report_count) - } - - /// Get compliance report - pub fn get_compliance_report(env: Env, report_id: u64) -> Option { - env.storage() - .instance() - .get(&DataKey::ComplianceReport(report_id)) - } - - // ===== Cross-Chain Module ===== - - /// Register cross-chain bridge - pub fn register_chain_bridge( - env: Env, - admin: Address, - chain_id: Address, - bridge_address: Address, - ) -> Result<(), InsuranceError> { - Self::check_role(&env, &admin, ROLE_SUPER_ADMIN)?; - - env.storage() - .instance() - .set(&DataKey::ChainBridge(chain_id), &bridge_address); - - Ok(()) - } - - /// Create cross-chain insurance policy - pub fn create_cross_chain_policy( - env: Env, - user: Address, - course_id: u64, - coverage_amount: i128, - target_chain: Address, - ) -> Result { - // This would integrate with cross-chain messaging - // For now, create regular policy - Self::purchase_policy(env, user, course_id, coverage_amount) - } - - // ===== View Functions ===== - - pub fn get_policy(env: Env, policy_id: u64) -> Option { - env.storage().instance().get(&DataKey::Policy(policy_id)) - } - - pub fn get_active_policies(env: Env, user: Address) -> Vec { - env.storage() - .instance() - .get(&DataKey::ActivePolicies(user)) - .unwrap_or_else(|| Vec::new(&env)) - } - - pub fn get_pending_claims(env: Env) -> Vec { - env.storage() - .instance() - .get(&DataKey::PendingClaims) - .unwrap_or_else(|| Vec::new(&env)) - } - - pub fn get_pool(env: Env, pool_id: u64) -> Option { - env.storage().instance().get(&DataKey::Pool(pool_id)) - } - - pub fn get_active_pools(env: Env) -> Vec { - env.storage() - .instance() - .get(&DataKey::ActivePools) - .unwrap_or_else(|| Vec::new(&env)) - } - - pub fn get_insurance_token(env: Env, token_id: u64) -> Option { - env.storage() - .instance() - .get(&DataKey::InsuranceToken(token_id)) - } - - pub fn get_token_balance(env: Env, holder: Address, token_id: u64) -> i128 { - env.storage() - .instance() - .get(&DataKey::TokenHolder(holder, token_id)) - .unwrap_or(0) - } - - pub fn get_proposal(env: Env, proposal_id: u64) -> Option { - env.storage() - .instance() - .get(&DataKey::Proposal(proposal_id)) - } - - pub fn get_governance_parameters(env: Env) -> GovernanceParameters { - env.storage() - .instance() - .get(&DataKey::GovernanceParameters) - .unwrap_or_else(GovernanceParameters::default) - } -} diff --git a/contracts/market/src/matching.rs b/contracts/market/src/matching.rs deleted file mode 100644 index 7b188c69..00000000 --- a/contracts/market/src/matching.rs +++ /dev/null @@ -1,227 +0,0 @@ -use crate::types::*; -use soroban_sdk::{contracttype, Address, Vec}; - -/// Storage keys for the enhanced insurance contract -#[contracttype] -#[derive(Clone)] -pub enum DataKey { - // Core configuration - Admin, - Oracle, - Token, - - // RBAC & Governance - HasRole(u32, Address), // Role ID -> Address -> bool - PendingAdminTransfer, // Address (New Admin) - AdminTransferTimestamp, // u64 (When transfer can be executed) - MultiSigSigners, // Vec
- MultiSigThreshold, // u32 - CriticalOperation(u32), // Operation ID -> CriticalOperation - OperationApprovals(u32), // Operation ID -> Vec
- OperationCount, // u64 - - // Risk assessment - RiskProfile(u64), - RiskProfileByUser(Address), - RiskProfileCount, - RiskModelWeights, - - // Insurance policies - Policy(u64), - PolicyByUser(Address, u64), // user -> course_id -> policy_id - PolicyCount, - ActivePolicies(Address), // user -> Vec - - // Claims - Claim(u64), - ClaimByPolicy(u64), - ClaimCount, - PendingClaims, - - // Parametric insurance - ParametricTrigger(u64), - TriggerByCourse(u64), - TriggerCount, - - // Insurance pools - Pool(u64), - PoolCount, - ActivePools, - PoolUtilization(u64), - - // Reinsurance - ReinsurancePartner(Address), - ReinsurancePartners, - ReinsuranceAllocation(u64, Address), // pool_id -> partner -> allocation - - // Insurance tokens - InsuranceToken(u64), - TokenByPool(u64), - TokenHolder(Address, u64), // holder -> token_id -> balance - TokenCount, - - // Governance - Proposal(u64), - ProposalCount, - Vote(Address, u64), // voter -> proposal_id -> has_voted - GovernanceParameters, - - // Analytics - DailyMetrics(u64), // timestamp (day) -> metrics - MonthlyMetrics(u64), // timestamp (month) -> metrics - RiskDistribution, - PoolPerformance(u64), // pool_id -> performance metrics - - // Compliance - ComplianceReport(u64), - ReportCount, - LastReportGeneration, - - // Cross-chain - ChainBridge(Address), // chain_id -> bridge_address - CrossChainClaim(u64), - - // Configuration parameters - BasePremiumRate, - RiskMultiplierRanges, - UtilizationTargets, - MinimumRiskReserve, - GovernanceQuorum, - VotingPeriod, -} - -/// Risk model weights for AI-powered assessment -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskModelWeights { - pub completion_rate_weight: u32, // 25% - pub reputation_score_weight: u32, // 20% - pub course_difficulty_weight: u32, // 15% - pub course_duration_weight: u32, // 10% - pub experience_level_weight: u32, // 15% - pub claim_frequency_weight: u32, // 10% - pub time_factor_weight: u32, // 5% -} - -impl Default for RiskModelWeights { - fn default() -> Self { - Self { - completion_rate_weight: 2500, - reputation_score_weight: 2000, - course_difficulty_weight: 1500, - course_duration_weight: 1000, - experience_level_weight: 1500, - claim_frequency_weight: 1000, - time_factor_weight: 500, - } - } -} - -/// Governance parameters -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct GovernanceParameters { - pub quorum_percentage: u32, // Required voting quorum (basis points) - pub voting_period_days: u32, // Voting period in days - pub execution_delay_hours: u32, // Delay before executing passed proposals - pub proposal_threshold: u64, // Minimum tokens to create proposal - pub veto_power_enabled: bool, // Whether admin can veto proposals -} - -impl Default for GovernanceParameters { - fn default() -> Self { - Self { - quorum_percentage: 5000, // 50% - voting_period_days: 7, - execution_delay_hours: 24, - proposal_threshold: 1000, - veto_power_enabled: true, - } - } -} - -/// Risk multiplier ranges based on risk scores -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskMultiplierRanges { - pub low_risk_min: u32, // 0-30 risk score - pub low_risk_max: u32, // 10000 = 1.0x - pub medium_risk_min: u32, // 31-60 risk score - pub medium_risk_max: u32, // 15000 = 1.5x - pub high_risk_min: u32, // 61-100 risk score - pub high_risk_max: u32, // 30000 = 3.0x -} - -impl Default for RiskMultiplierRanges { - fn default() -> Self { - Self { - low_risk_min: 0, - low_risk_max: 10000, - medium_risk_min: 31, - medium_risk_max: 15000, - high_risk_min: 61, - high_risk_max: 30000, - } - } -} - -/// Pool utilization targets -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct UtilizationTargets { - pub target_rate: u32, // 8000 = 80% - pub max_rate: u32, // 9500 = 95% - pub min_reserve_ratio: u32, // 1500 = 15% -} - -impl Default for UtilizationTargets { - fn default() -> Self { - Self { - target_rate: 8000, - max_rate: 9500, - min_reserve_ratio: 1500, - } - } -} - -/// Daily insurance metrics -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct DailyMetrics { - pub date: u64, // Unix timestamp (day) - pub policies_issued: u64, - pub premiums_collected: i128, - pub claims_filed: u64, - pub claims_paid: u64, - pub total_payouts: i128, - pub active_policies: u64, - pub pool_utilization: u32, - pub average_risk_score: u32, -} - -/// Risk distribution statistics -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct RiskDistribution { - pub low_risk_count: u64, // 0-30 - pub medium_risk_count: u64, // 31-60 - pub high_risk_count: u64, // 61-100 - pub average_risk_score: u32, - pub risk_std_dev: u32, -} - -/// Pool performance metrics -#[contracttype] -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct PoolPerformance { - pub pool_id: u64, - pub period_start: u64, - pub period_end: u64, - pub total_assets: i128, - pub premiums_earned: i128, - pub claims_paid: i128, - pub net_profit: i128, - pub utilization_rate: u32, - pub loss_ratio: u32, - pub roi_percentage: i32, // Basis points, can be negative -} diff --git a/contracts/marketplace/Cargo.toml b/contracts/marketplace/Cargo.toml deleted file mode 100644 index e69de29b..00000000 diff --git a/contracts/marketplace/src/lib.rs b/contracts/marketplace/src/lib.rs deleted file mode 100644 index 982ea1a4..00000000 --- a/contracts/marketplace/src/lib.rs +++ /dev/null @@ -1,56 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -#[ink::contract] -mod marketplace { - use ink::storage::Mapping; - - #[derive(scale::Encode, scale::Decode, Clone, Debug, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] - pub enum Status { - Listed, - Sold, - Cancelled, - } - - #[ink(storage)] - pub struct Marketplace { - listings: Mapping, // tokenId → (seller, price, status) - } - - impl Marketplace { - #[ink(constructor)] - pub fn new() -> Self { - Self { - listings: Mapping::default(), - } - } - - #[ink(message)] - pub fn list(&mut self, token_id: u32, price: u128) { - let caller = self.env().caller(); - self.listings.insert(token_id, &(caller, price, Status::Listed)); - } - - #[ink(message, payable)] - pub fn buy(&mut self, token_id: u32) { - if let Some((seller, price, status)) = self.listings.get(token_id) { - assert!(status == Status::Listed, "Not available"); - let buyer = self.env().caller(); - let value = self.env().transferred_value(); - assert!(value >= price, "Insufficient funds"); - - // Transfer logic would go here (NFT ownership transfer, royalty distribution) - self.listings.insert(token_id, &(seller, price, Status::Sold)); - } - } - - #[ink(message)] - pub fn cancel(&mut self, token_id: u32) { - if let Some((seller, price, _)) = self.listings.get(token_id) { - let caller = self.env().caller(); - assert!(caller == seller, "Only seller can cancel"); - self.listings.insert(token_id, &(seller, price, Status::Cancelled)); - } - } - } -} diff --git a/contracts/marketplace/src/matching.rs b/contracts/marketplace/src/matching.rs deleted file mode 100644 index e69de29b..00000000 diff --git a/contracts/teachlink/src/collaboration.rs b/contracts/teachlink/src/collaboration.rs deleted file mode 100644 index 8b137891..00000000 --- a/contracts/teachlink/src/collaboration.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/contracts/teachlink/src/content_nft.rs b/contracts/teachlink/src/content_nft.rs deleted file mode 100644 index f3ec87da..00000000 --- a/contracts/teachlink/src/content_nft.rs +++ /dev/null @@ -1,45 +0,0 @@ -#[derive(Serialize, Deserialize, Clone)] -pub struct ContentMetadata { - pub title: String, - pub description: String, - pub content_uri: String, - pub preview_uri: Option, - pub category: String, - pub tags: Vec, - pub license_type: LicenseType, - pub version: u32, - pub quality_score: u32, -} - -pub struct ContentNFT { - pub token_id: u64, - pub creator: Address, - pub co_owners: Vec
, - pub metadata: ContentMetadata, - pub royalty_percentage: u16, - pub fractionalized: bool, - pub created_at: u64, -} - -pub fn mint_content( - creator: Address, - metadata: ContentMetadata, - royalty_percentage: u16, -) -> Result { - assert!(royalty_percentage <= 2000); // max 20% - - let token_id = Self::next_token_id(); - - let nft = ContentNFT { - token_id, - creator, - co_owners: vec![], - metadata, - royalty_percentage, - fractionalized: false, - created_at: block_timestamp(), - }; - - Self::store_nft(token_id, nft); - Ok(token_id) -} diff --git a/contracts/teachlink/src/content_quality.rs b/contracts/teachlink/src/content_quality.rs deleted file mode 100644 index cd58c07c..00000000 --- a/contracts/teachlink/src/content_quality.rs +++ /dev/null @@ -1,1245 +0,0 @@ -//! Comprehensive Content Quality Assurance System -//! -//! This module implements AI-powered content quality assessment, plagiarism detection, -//! community moderation, and quality scoring mechanisms. - -use crate::types::{u32, u64, Address, Bytes, Map, Vec}; -use soroban_sdk::{contracterror, contracttype, panic_with_error, symbol_short, Env, Symbol}; - -const CONTENT_QUALITY: Symbol = symbol_short!("content_qual"); -const PLAGIARISM_CHECK: Symbol = symbol_short!("plag_check"); -const MODERATION_QUEUE: Symbol = symbol_short!("mod_queue"); -const QUALITY_ANALYTICS: Symbol = symbol_short!("qual_analytics"); -const CONTENT_IMPROVEMENT: Symbol = symbol_short!("content_improve"); -const QUALITY_MARKET: Symbol = symbol_short!("qual_market"); -const DISPUTE_RESOLUTION: Symbol = symbol_short!("dispute_res"); - -// ========== Content Quality Assessment Types ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContentQualityAssessment { - pub content_id: u64, - pub overall_score: u32, // 0-100 - pub quality_dimensions: QualityDimensions, - pub ai_analysis: AIQualityAnalysis, - pub peer_reviews: Vec, - pub automated_checks: Vec, - pub improvement_suggestions: Vec, - pub last_assessed: u64, - pub assessment_version: u32, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct QualityDimensions { - pub accuracy_score: u32, // Factual correctness - pub clarity_score: u32, // How clear and understandable - pub completeness_score: u32, // Coverage of topic - pub engagement_score: u64, // Basis points // How engaging/interactive - pub accessibility_score: u32, // Accessibility compliance - pub technical_quality: u32, // Audio/video quality, formatting - pub educational_value: u32, // Learning effectiveness - pub originality_score: u32, // How original/unique -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AIQualityAnalysis { - pub sentiment_analysis: SentimentAnalysis, - pub readability_score: u32, - pub complexity_level: ComplexityLevel, - pub keyword_density: Map, // Basis points // Basis points - pub structure_analysis: StructureAnalysis, - pub multimedia_quality: MultimediaQuality, - pub learning_objectives_alignment: u64, // Basis points - pub target_appropriateness: u64, // Basis points - pub content_gaps: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SentimentAnalysis { - pub overall_sentiment: SentimentType, - pub confidence_score: u64, // Represented as basis points (0-10000) - pub emotional_tone: Vec, - pub sentiment_distribution: Map, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum SentimentType { - VeryPositive, - Positive, - Neutral, - Negative, - VeryNegative, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum EmotionalTone { - Inspirational, - Encouraging, - Informational, - Warning, - Critical, - Humorous, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ComplexityLevel { - Beginner, - Intermediate, - Advanced, - Expert, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct StructureAnalysis { - pub has_introduction: bool, - pub has_main_content: bool, - pub has_conclusion: bool, - pub logical_flow_score: u32, - pub section_organization: Vec, - pub transition_quality: u64, // Basis points - pub heading_hierarchy: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SectionInfo { - pub title: Bytes, - pub word_count: u32, - pub relevance_score: u32, - pub has_examples: bool, - pub has_assessments: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct MultimediaQuality { - pub video_quality: Option, - pub audio_quality: Option, - pub image_quality: Option, - pub interactive_elements: Vec, - pub accessibility_features: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct VideoQualityMetrics { - pub resolution: (u32, u32), - pub frame_rate: u64, // Basis points - pub bitrate: u64, - pub compression_artifacts: u32, // 0-100 - pub color_accuracy: u32, - pub lighting_quality: u32, - pub stabilization_score: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AudioQualityMetrics { - pub sample_rate: u64, // Basis points - pub bit_depth: u32, - pub noise_level: u32, // 0-100, lower is better - pub clarity_score: u32, - pub volume_consistency: u32, - pub background_noise: u32, - pub speech_clarity: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ImageQualityMetrics { - pub resolution: (u32, u32), - pub compression_quality: u32, - pub color_accuracy: u32, - pub noise_level: u32, - pub sharpness_score: u64, // Basis points - pub composition_score: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct InteractiveElement { - pub element_type: InteractiveType, - pub functionality_score: u64, // Basis points - pub user_experience_score: u64, // Basis points - pub accessibility_score: u64, // Basis points - pub mobile_friendly: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum InteractiveType { - Quiz, - Simulation, - DragDrop, - VirtualLab, - Game, - Forum, - Chat, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AccessibilityFeature { - pub feature_type: AccessibilityType, - pub implementation_quality: u64, // Basis points - pub compliance_level: ComplianceLevel, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AccessibilityType { - ClosedCaptions, - AudioDescription, - ScreenReaderSupport, - KeyboardNavigation, - ColorContrast, - FontResizing, - LanguageTranslation, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ComplianceLevel { - None, - Partial, - WCAG_A, - WCAG_AA, - WCAG_AAA, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContentGap { - pub gap_type: GapType, - pub description: Bytes, - pub severity: GapSeverity, - pub suggested_content: Vec, - pub priority: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum GapType { - MissingPrerequisite, - InsufficientExamples, - OutdatedInformation, - UnclearExplanation, - LackOfPractice, - MissingAssessment, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum GapSeverity { - Low, - Medium, - High, - Critical, -} - -// ========== Plagiarism Detection ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PlagiarismReport { - pub content_id: u64, - pub originality_score: u64, // Basis points - pub similarity_matches: Vec, - pub source_analysis: SourceAnalysis, - pub ai_generated_probability: u64, // Basis points - pub paraphrasing_detection: ParaphrasingAnalysis, - pub citation_analysis: CitationAnalysis, - pub recommendations: Vec, - pub last_checked: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SimilarityMatch { - pub source_content_id: u64, - pub source_title: Bytes, - pub source_author: Address, - pub similarity_percentage: u64, // Basis points - pub matching_sections: Vec, - pub is_public_domain: bool, - pub license_compatibility: LicenseCompatibility, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct MatchingSection { - pub start_position: u32, - pub end_position: u32, - pub matched_text: Bytes, - pub similarity_score: u64, // Basis points - pub is_direct_copy: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum LicenseCompatibility { - Compatible, - RequiresAttribution, - CommercialUseRestricted, - Incompatible, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SourceAnalysis { - pub academic_sources: u32, - pub web_sources: u32, - pub self_citations: u32, - pub credible_sources: u32, - pub source_diversity: u64, // Basis points - pub recency_score: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ParaphrasingAnalysis { - pub sentence_structure_similarity: u64, // Basis points - pub vocabulary_substitution_score: u64, // Basis points - pub idea_preservation_score: u64, // Basis points - pub is_sophisticated_paraphrasing: bool, - pub detection_confidence: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CitationAnalysis { - pub total_citations: u32, - pub proper_citations: u32, - pub missing_citations: u32, - pub citation_format_score: u64, // Basis points - pub source_credibility_score: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PlagiarismRecommendation { - pub recommendation_type: PlagiarismRecommendationType, - pub description: Bytes, - pub action_required: bool, - pub urgency: RecommendationUrgency, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum PlagiarismRecommendationType { - AddCitations, - ParaphraseContent, - UseOriginalContent, - CheckLicense, - AttributeSources, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum RecommendationUrgency { - Low, - Medium, - High, - Critical, -} - -// ========== Community Moderation ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ModerationQueue { - pub pending_reviews: Vec, - pub active_moderators: Vec
, - pub moderation_stats: ModerationStats, - pub escalation_queue: Vec, - pub auto_moderated: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PendingReview { - pub content_id: u64, - pub content_type: ContentTypeForModeration, - pub submitter: Address, - pub submission_time: u64, - pub priority: ModerationPriority, - pub auto_flags: Vec, - pub assigned_moderator: Option
, - pub review_deadline: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ContentTypeForModeration { - Course, - Lesson, - Quiz, - ForumPost, - Comment, - Review, - Resource, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ModerationPriority { - Low, - Normal, - High, - Urgent, - Critical, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AutoModerationFlag { - pub flag_type: FlagType, - pub confidence: u64, // Basis points - pub detected_content: Bytes, - pub position: Option, - pub severity: FlagSeverity, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum FlagType { - InappropriateLanguage, - HateSpeech, - Spam, - Misinformation, - CopyrightViolation, - PersonalInformation, - Violence, - AdultContent, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum FlagSeverity { - Info, - Warning, - Error, - Critical, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ModerationStats { - pub total_reviewed: u64, - pub approved: u64, - pub rejected: u64, - pub modified: u64, - pub escalated: u64, - pub average_review_time: u64, // Basis points - pub moderator_performance: Map, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ModeratorPerformance { - pub reviews_completed: u32, - pub accuracy_score: u64, // Basis points - pub consistency_score: u64, // Basis points - pub speed_score: u64, // Basis points - pub community_feedback: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct EscalatedContent { - pub content_id: u64, - pub escalation_reason: Bytes, - pub escalation_level: EscalationLevel, - pub senior_moderator: Option
, - pub escalation_time: u64, - pub resolution: Option, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum EscalationLevel { - Level1, - Level2, - Level3, - Executive, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct EscalationResolution { - pub resolution_type: ResolutionType, - pub action_taken: Bytes, - pub final_decision: ModerationDecision, - pub resolver: Address, - pub resolution_time: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ResolutionType { - Approved, - Rejected, - Modified, - Removed, - Referred, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ModerationDecision { - Approve, - Reject, - Modify, - Remove, - Escalate, -} - -// ========== Quality Analytics ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct QualityAnalytics { - pub overall_quality_trends: Vec, - pub content_category_performance: Map, - pub creator_quality_scores: Map, - pub quality_distribution: QualityDistribution, - pub improvement_opportunities: Vec, - pub benchmark_comparison: BenchmarkComparison, - pub predictive_quality: PredictiveQualityMetrics, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct QualityTrend { - pub period: TimePeriod, - pub average_score: u64, // Basis points - pub median_score: u64, // Basis points - pub score_distribution: Map, - pub content_volume: u32, - pub improvement_rate: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum TimePeriod { - Daily, - Weekly, - Monthly, - Quarterly, - Yearly, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ScoreRange { - pub min_score: u32, - pub max_score: u32, - pub range_label: Bytes, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CategoryPerformance { - pub category: Bytes, - pub average_quality: u64, // Basis points - pub content_count: u32, - pub top_performers: Vec
, - pub common_issues: Vec, - pub improvement_suggestions: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CreatorQualityScore { - pub creator: Address, - pub overall_score: u64, // Basis points - pub content_count: u32, - pub average_rating: u64, // Basis points - pub consistency_score: u64, // Basis points - pub improvement_trend: u64, // Basis points - pub specialty_areas: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct QualityDistribution { - pub excellent_content: u32, // 90-100 - pub good_content: u32, // 75-89 - pub average_content: u32, // 60-74 - pub below_average_content: u32, // 40-59 - pub poor_content: u32, // 0-39 -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ImprovementOpportunity { - pub opportunity_type: OpportunityType, - pub potential_impact: u64, // Basis points - pub effort_required: u32, - pub affected_content_count: u32, - pub recommendation: Bytes, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum OpportunityType { - ImproveAccuracy, - EnhanceEngagement, - IncreaseAccessibility, - UpdateContent, - AddMultimedia, - ImproveStructure, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct BenchmarkComparison { - pub platform_average: u64, // Basis points - pub industry_average: u64, // Basis points - pub top_quartile: u64, // Basis points - pub relative_position: u64, // Basis points // 0-1 percentile - pub gap_to_excellence: u64, // Basis points - pub competitive_advantages: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PredictiveQualityMetrics { - pub predicted_quality_score: u64, // Basis points - pub confidence_interval: (u64, u64), // Both as basis points - pub risk_factors: Vec, - pub improvement_trajectory: Vec, - pub optimal_publishing_time: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct QualityRiskFactor { - pub factor_type: RiskFactorType, - pub probability: u64, // Basis points - pub impact_severity: u64, // Basis points - pub mitigation_strategies: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum RiskFactorType { - ContentOutdated, - LowEngagement, - TechnicalIssues, - AccessibilityBarriers, - CopyrightRisk, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PredictedImprovement { - pub timeframe: u64, // Days - pub expected_improvement: u64, // Basis points - pub confidence_level: u64, // Basis points - pub required_actions: Vec, -} - -// ========== Supporting Types ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PeerQualityReview { - pub reviewer: Address, - pub review_score: u64, // Basis points - pub review_comments: Bytes, - pub review_criteria: Vec, - pub timestamp: u64, - pub helpful_votes: u32, - pub is_verified_reviewer: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ReviewCriterion { - pub criterion_name: Bytes, - pub score: u64, // Basis points - pub weight: u32, - pub comments: Bytes, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AutomatedQualityCheck { - pub check_type: AutomatedCheckType, - pub result: CheckResult, - pub confidence: u64, // Basis points - pub details: Bytes, - pub timestamp: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AutomatedCheckType { - GrammarCheck, - SpellingCheck, - ReadabilityCheck, - LinkValidation, - ImageAltText, - VideoTranscription, - AccessibilityCheck, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum CheckResult { - Pass, - Warning, - Fail, - Error, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ImprovementSuggestion { - pub suggestion_type: SuggestionType, - pub description: Bytes, - pub priority: u64, // Basis points - pub estimated_effort: u32, - pub expected_impact: u64, // Basis points - pub implementation_steps: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum SuggestionType { - AddExamples, - ImproveClarity, - UpdateInformation, - EnhanceMultimedia, - ImproveAccessibility, - AddAssessments, - RestructureContent, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct QualityIssue { - pub issue_type: IssueType, - pub description: Bytes, - pub frequency: u32, - pub severity: u64, // Basis points - pub affected_content_percentage: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum IssueType { - FactualErrors, - PoorStructure, - LowEngagement, - AccessibilityProblems, - OutdatedContent, - InsufficientCoverage, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AutoModerationResult { - pub content_id: u64, - pub action_taken: ModerationAction, - pub confidence: u64, // Basis points - pub rules_triggered: Vec, - pub appeal_available: bool, - pub timestamp: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ModerationAction { - Approve, - Reject, - FlagForReview, - RequireChanges, - Suspend, -} - -// ========== Errors ========== - -#[contracterror] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum ContentQualityError { - ContentNotFound = 1, - AssessmentFailed = 2, - ModerationError = 3, - PlagiarismCheckFailed = 4, - UnauthorizedAccess = 5, - QualityThresholdNotMet = 6, - DisputeInProgress = 7, -} - -// ========== Main Implementation ========== - -pub struct ContentQualityManager; - -impl ContentQualityManager { - /// Assess content quality using AI and automated checks - pub fn assess_content_quality( - env: &Env, - content_id: u64, - content_data: ContentData, - ) -> Result { - // Perform AI analysis - let ai_analysis = Self::perform_ai_analysis(env, &content_data); - - // Run automated quality checks - let automated_checks = Self::run_automated_checks(env, &content_data); - - // Calculate quality dimensions - let quality_dimensions = - Self::calculate_quality_dimensions(&ai_analysis, &automated_checks); - - // Generate improvement suggestions - let improvement_suggestions = Self::generate_improvement_suggestions(&quality_dimensions); - - // Calculate overall score - let overall_score = Self::calculate_overall_score(&quality_dimensions); - - let assessment = ContentQualityAssessment { - content_id, - overall_score, - quality_dimensions, - ai_analysis, - peer_reviews: Vec::new(env), - automated_checks, - improvement_suggestions, - last_assessed: env.ledger().timestamp(), - assessment_version: 1, - }; - - Self::set_quality_assessment(env, &content_id, &assessment); - - Ok(assessment) - } - - /// Check content for plagiarism - pub fn check_plagiarism( - env: &Env, - content_id: u64, - content_text: Bytes, - ) -> Result { - // Simulated plagiarism detection - let similarity_matches = Self::find_similarity_matches(env, &content_text); - let source_analysis = Self::analyze_sources(&similarity_matches); - let paraphrasing_detection = Self::detect_paraphrasing(&content_text); - let citation_analysis = Self::analyze_citations(&content_text); - - let originality_score = - Self::calculate_originality_score(&similarity_matches, ¶phrasing_detection); - let ai_generated_probability = Self::detect_ai_generated_content(&content_text); - - let report = PlagiarismReport { - content_id, - originality_score, - similarity_matches, - source_analysis, - ai_generated_probability, - paraphrasing_detection, - citation_analysis, - recommendations: Self::generate_plagiarism_recommendations(&originality_score), - last_checked: env.ledger().timestamp(), - }; - - Self::set_plagiarism_report(env, &content_id, &report); - - Ok(report) - } - - /// Submit content for community moderation - pub fn submit_for_moderation( - env: &Env, - content_id: u64, - content_type: ContentTypeForModeration, - submitter: Address, - auto_flags: Vec, - ) -> Result<(), ContentQualityError> { - let pending_review = PendingReview { - content_id, - content_type, - submitter: submitter.clone(), - submission_time: env.ledger().timestamp(), - priority: Self::calculate_moderation_priority(&auto_flags), - auto_flags, - assigned_moderator: None, - review_deadline: env.ledger().timestamp() + 24 * 3600, // 24 hours - }; - - Self::add_to_moderation_queue(env, &pending_review); - - Ok(()) - } - - /// Create quality improvement plan - pub fn create_improvement_plan( - env: &Env, - content_id: u64, - target_quality_score: u32, - deadline: u64, - ) -> Result { - let current_assessment = Self::get_quality_assessment(env, &content_id); - - if current_assessment.overall_score >= target_quality_score { - return Err(ContentQualityError::QualityThresholdNotMet); - } - - let plan_id = env.ledger().sequence(); - let improvement_plan = ContentImprovementPlan { - id: plan_id, - content_id, - current_score: current_assessment.overall_score, - target_score: target_quality_score, - improvement_actions: Self::generate_improvement_actions( - ¤t_assessment, - target_quality_score, - ), - deadline, - status: ImprovementStatus::Active, - created_at: env.ledger().timestamp(), - progress_updates: Vec::new(env), - }; - - Self::set_improvement_plan(env, &plan_id, &improvement_plan); - - Ok(plan_id) - } - - // ========== AI Analysis Functions ========== - - fn perform_ai_analysis(env: &Env, content_data: &ContentData) -> AIQualityAnalysis { - // Simulated AI analysis - AIQualityAnalysis { - sentiment_analysis: SentimentAnalysis { - overall_sentiment: SentimentType::Positive, - confidence_score: 0.85, - emotional_tone: Vec::new(env), - sentiment_distribution: Map::new(env), - }, - readability_score: 75, - complexity_level: ComplexityLevel::Intermediate, - keyword_density: Map::new(env), - structure_analysis: StructureAnalysis { - has_introduction: true, - has_main_content: true, - has_conclusion: true, - logical_flow_score: 85, - section_organization: Vec::new(env), - transition_quality: 80, - heading_hierarchy: true, - }, - multimedia_quality: MultimediaQuality { - video_quality: None, - audio_quality: None, - image_quality: None, - interactive_elements: Vec::new(env), - accessibility_features: Vec::new(env), - }, - learning_objectives_alignment: 0.9, - target_appropriateness: 0.85, - content_gaps: Vec::new(env), - } - } - - fn run_automated_checks(env: &Env, content_data: &ContentData) -> Vec { - let mut checks = Vec::new(env); - - // Grammar check - checks.push_back(AutomatedQualityCheck { - check_type: AutomatedCheckType::GrammarCheck, - result: CheckResult::Pass, - confidence: 0.95, - details: Bytes::from_slice(env, b"No grammar errors detected"), - timestamp: env.ledger().timestamp(), - }); - - // Spelling check - checks.push_back(AutomatedQualityCheck { - check_type: AutomatedCheckType::SpellingCheck, - result: CheckResult::Warning, - confidence: 0.88, - details: Bytes::from_slice(env, b"Potential spelling issues found"), - timestamp: env.ledger().timestamp(), - }); - - checks - } - - fn calculate_quality_dimensions( - ai_analysis: &AIQualityAnalysis, - automated_checks: &Vec, - ) -> QualityDimensions { - QualityDimensions { - accuracy_score: 85, - clarity_score: ai_analysis.readability_score, - completeness_score: 90, - engagement_score: 75, - accessibility_score: 70, - technical_quality: 80, - educational_value: 85, - originality_score: 90, - } - } - - fn calculate_overall_score(dimensions: &QualityDimensions) -> u32 { - let weighted_sum = dimensions.accuracy_score * 20 - + dimensions.clarity_score * 15 - + dimensions.completeness_score * 15 - + dimensions.engagement_score * 15 - + dimensions.accessibility_score * 10 - + dimensions.technical_quality * 10 - + dimensions.educational_value * 10 - + dimensions.originality_score * 5; - - weighted_sum / 100 - } - - // ========== Helper Functions ========== - - fn find_similarity_matches(env: &Env, content: &Bytes) -> Vec { - Vec::new(env) // Would implement actual similarity detection - } - - fn analyze_sources(matches: &Vec) -> SourceAnalysis { - SourceAnalysis { - academic_sources: 2, - web_sources: 3, - self_citations: 1, - credible_sources: 3, - source_diversity: 7000, // 70% as basis points - recency_score: 8000, // 80% as basis points - } - } - - fn detect_paraphrasing(content: &Bytes) -> ParaphrasingAnalysis { - ParaphrasingAnalysis { - sentence_structure_similarity: 3000, // 30% as basis points - vocabulary_substitution_score: 4000, // 40% as basis points - idea_preservation_score: 9000, // 90% as basis points - is_sophisticated_paraphrasing: false, - detection_confidence: 7500, // 75% as basis points - } - } - - fn analyze_citations(content: &Bytes) -> CitationAnalysis { - CitationAnalysis { - total_citations: 5, - proper_citations: 4, - missing_citations: 1, - citation_format_score: 80, - source_credibility_score: 7500, // 75% as basis points - } - } - - fn calculate_originality_score( - matches: &Vec, - paraphrasing: &ParaphrasingAnalysis, - ) -> u64 { - let base_score = 100; - let similarity_penalty = matches.iter().map(|m| m.similarity_percentage as u64).sum(); - let paraphrasing_penalty = (paraphrasing.sentence_structure_similarity * 50) / 10000; - - (base_score - similarity_penalty - paraphrasing_penalty).max(0) - } - - fn detect_ai_generated_content(content: &Bytes) -> u64 { - // Simulated AI detection - 1500 // 15% probability as basis points - } - - fn generate_plagiarism_recommendations( - originality_score: &u64, - ) -> Vec { - Vec::new(&Env::default()) // Would generate based on score - } - - fn calculate_moderation_priority(flags: &Vec) -> ModerationPriority { - let has_critical = flags - .iter() - .any(|f| matches!(f.severity, FlagSeverity::Critical)); - let has_high = flags - .iter() - .any(|f| matches!(f.severity, FlagSeverity::Error)); - - if has_critical { - ModerationPriority::Critical - } else if has_high { - ModerationPriority::Urgent - } else { - ModerationPriority::Normal - } - } - - fn generate_improvement_actions( - assessment: &ContentQualityAssessment, - target_score: u32, - ) -> Vec { - Vec::new(&Env::default()) // Would generate specific actions - } - - fn generate_improvement_suggestions( - dimensions: &QualityDimensions, - ) -> Vec { - Vec::new(&Env::default()) // Would generate based on dimension scores - } - - // ========== Storage Functions ========== - - fn set_quality_assessment(env: &Env, content_id: &u64, assessment: &ContentQualityAssessment) { - env.storage() - .persistent() - .set(&(CONTENT_QUALITY, content_id.clone()), assessment); - } - - fn get_quality_assessment(env: &Env, content_id: &u64) -> ContentQualityAssessment { - env.storage() - .persistent() - .get(&(CONTENT_QUALITY, content_id.clone())) - .unwrap_or_else(|| panic_with_error!(env, ContentQualityError::ContentNotFound)) - } - - fn set_plagiarism_report(env: &Env, content_id: &u64, report: &PlagiarismReport) { - env.storage() - .persistent() - .set(&(PLAGIARISM_CHECK, content_id.clone()), report); - } - - fn add_to_moderation_queue(env: &Env, review: &PendingReview) { - let key = (MODERATION_QUEUE, review.content_id); - env.storage().persistent().set(&key, review); - } - - fn set_improvement_plan(env: &Env, plan_id: &u64, plan: &ContentImprovementPlan) { - env.storage() - .persistent() - .set(&(CONTENT_IMPROVEMENT, plan_id.clone()), plan); - } -} - -// ========== Supporting Types ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContentData { - pub text_content: Bytes, - pub multimedia_content: Vec, - pub metadata: ContentMetadata, - pub content_type: ContentFormat, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct MultimediaContent { - pub content_type: MultimediaType, - pub uri: Bytes, - pub duration: Option, - pub file_size: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum MultimediaType { - Video, - Audio, - Image, - Interactive, - Document, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContentMetadata { - pub title: Bytes, - pub description: Bytes, - pub tags: Vec, - pub language: Bytes, - pub difficulty_level: u32, - pub estimated_duration: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ContentFormat { - Text, - Video, - Audio, - Interactive, - Mixed, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContentImprovementPlan { - pub id: u64, - pub content_id: u64, - pub current_score: u32, - pub target_score: u32, - pub improvement_actions: Vec, - pub deadline: u64, - pub status: ImprovementStatus, - pub created_at: u64, - pub progress_updates: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ImprovementAction { - pub action_type: ImprovementActionType, - pub description: Bytes, - pub assigned_to: Option
, - pub deadline: u64, - pub status: ActionStatus, - pub estimated_effort: u32, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ImprovementActionType { - UpdateContent, - AddExamples, - ImproveAccessibility, - EnhanceMultimedia, - FixGrammar, - AddCitations, - RestructureContent, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ActionStatus { - Pending, - InProgress, - Completed, - Blocked, - Cancelled, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ImprovementStatus { - Active, - Completed, - Paused, - Cancelled, - Overdue, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ProgressUpdate { - pub timestamp: u64, - pub update_type: Bytes, - pub description: Bytes, - pub progress_percentage: u32, -} diff --git a/contracts/teachlink/src/feature_flags.rs b/contracts/teachlink/src/feature_flags.rs index 4526adc7..6957c248 100644 --- a/contracts/teachlink/src/feature_flags.rs +++ b/contracts/teachlink/src/feature_flags.rs @@ -48,7 +48,7 @@ impl FeatureFlagManager { let mut flags = Self::get_all_flags(env); let timestamp = env.ledger().timestamp(); - + // Preserve kill_switch and created_at if updating let (kill_switch_enabled, created_at) = if let Some(existing) = flags.get(name.clone()) { (existing.kill_switch_enabled, existing.created_at) @@ -91,10 +91,10 @@ impl FeatureFlagManager { let mut flags = Self::get_all_flags(env); let mut flag = flags.get(name.clone()).ok_or(BridgeError::NotFound)?; - + flag.kill_switch_enabled = enabled; flag.updated_at = env.ledger().timestamp(); - + flags.set(name, flag); Self::save_all_flags(env, &flags); @@ -125,29 +125,29 @@ impl FeatureFlagManager { // Handle FeatureStatus::Rollout match flag.strategy { RolloutStrategy::Global => { - // If Rollout and Global, it's effectively enabled for everyone + // If Rollout and Global, it's effectively enabled for everyone // up to rollout_percentage. If 100%, all pass. // Wait, global implies true/false based on flag status. - // But let's treat Global as "on" if rollout > 0, for simplicity, + // But let's treat Global as "on" if rollout > 0, for simplicity, // or just use rollout percentage for everyone. flag.rollout_percentage == 100 } RolloutStrategy::PercentageBased | RolloutStrategy::ABTest => { // Determine user's bucket (0-99) deterministically let mut data = Bytes::new(env); - + // Note: user.to_xdr(env) would be ideal but Bytes::from_slice with string is easier // For simplicity, we just use the name and user string representation // In a real implementation we'd use XDR or bytes from the Address type directly. // Address string representation can be used as unique material. let user_str = user.to_string(); - + data.append(&user_str.into()); let name_bytes: Bytes = name.to_string().into(); data.append(&name_bytes); let hash = env.crypto().sha256(&data); - + // Get the first byte as the hash bucket (0-255) // Map to 0-99 let first_byte = hash.get(0).unwrap_or(0) as u32; diff --git a/contracts/teachlink/src/fractional.rs b/contracts/teachlink/src/fractional.rs deleted file mode 100644 index d1aa6ba7..00000000 --- a/contracts/teachlink/src/fractional.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub struct FractionalVault { - pub token_id: u64, - pub total_shares: u128, - pub price_per_share: u128, - pub shareholders: Map, -} diff --git a/contracts/teachlink/src/learning_paths.rs b/contracts/teachlink/src/learning_paths.rs deleted file mode 100644 index 18a6535b..00000000 --- a/contracts/teachlink/src/learning_paths.rs +++ /dev/null @@ -1,834 +0,0 @@ -//! AI-Powered Learning Path Optimization System -//! -//! This module implements sophisticated learning path generation using AI analysis -//! of user goals, learning styles, and performance data. - -use crate::types::{u32, u64, Address, Bytes, Map, Vec}; -use soroban_sdk::{contracterror, contracttype, panic_with_error, symbol_short, Env, Symbol}; - -const LEARNING_PATHS: Symbol = symbol_short!("learn_path"); -const AI_ANALYTICS: Symbol = symbol_short!("ai_analytics"); -const LEARNING_GOALS: Symbol = symbol_short!("learn_goals"); -const PATH_OPTIMIZATION: Symbol = symbol_short!("path_opt"); -const COLLABORATIVE_PATHS: Symbol = symbol_short!("collab_paths"); -const PATH_CERTIFICATION: Symbol = symbol_short!("path_cert"); - -// ========== Learning Path Types ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct LearningPath { - pub id: u64, - pub user: Address, - pub title: Bytes, - pub description: Bytes, - pub learning_objectives: Vec, - pub content_modules: Vec, - pub prerequisites: Vec, - pub estimated_duration: u64, // in hours - pub difficulty_level: DifficultyLevel, - pub learning_style: LearningStyle, - pub personalization_data: PersonalizationData, - pub adaptation_history: Vec, - pub progress_tracking: ProgressTracking, - pub analytics: PathAnalytics, - pub is_active: bool, - pub created_at: u64, - pub last_updated: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct LearningObjective { - pub id: u64, - pub title: Bytes, - pub description: Bytes, - pub skill_category: Bytes, - pub target_mastery_level: u32, // 0-100 - pub current_mastery: u32, - pub importance_weight: u32, // 1-10 - pub completion_criteria: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ContentModule { - pub id: u64, - pub title: Bytes, - pub content_type: ContentType, - pub content_uri: Bytes, - pub duration_minutes: u32, - pub difficulty: u32, - pub required_resources: Vec, - pub assessment_methods: Vec, - pub completion_threshold: u32, - pub adaptive_content: AdaptiveContent, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ContentType { - Video, - Text, - Interactive, - Quiz, - Project, - Simulation, - Webinar, - Documentation, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AssessmentMethod { - pub method_type: AssessmentType, - pub weight: u32, // Percentage of final score - pub passing_threshold: u32, - pub max_attempts: u32, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AssessmentType { - Quiz, - Assignment, - Project, - PeerReview, - PracticalExam, - OralPresentation, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct Prerequisite { - pub course_id: u64, - pub skill_level: u32, - pub alternative_paths: Vec, // Alternative ways to satisfy - pub waiver_possible: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum DifficultyLevel { - Beginner, - Intermediate, - Advanced, - Expert, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum LearningStyle { - Visual, - Auditory, - Kinesthetic, - Reading, - Mixed, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PersonalizationData { - pub preferred_learning_style: LearningStyle, - pub pace_preference: PacePreference, - pub time_availability: Vec, - pub content_preferences: Vec, - pub accessibility_needs: Vec, - pub language_preference: Bytes, - pub cultural_context: Bytes, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum PacePreference { - Fast, - Normal, - Slow, - Adaptive, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct TimeSlot { - pub day_of_week: u32, // 0-6 (Sunday-Saturday) - pub start_hour: u32, - pub end_hour: u32, - pub is_available: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AccessibilityNeed { - ClosedCaptions, - ScreenReader, - LargeText, - AudioDescription, - KeyboardNavigation, - ColorBlindSupport, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AdaptiveContent { - pub content_variations: Map, - pub difficulty_adjustments: Vec, - pub personalized_recommendations: Vec, - pub real_time_adaptations: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct DifficultyAdjustment { - pub trigger_condition: Bytes, - pub adjustment_type: AdjustmentType, - pub new_difficulty: u32, - pub content_changes: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AdjustmentType { - IncreaseDifficulty, - DecreaseDifficulty, - ChangeContentType, - ProvideAdditionalResources, - OfferAlternativePath, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PathAdaptation { - pub timestamp: u64, - pub reason: AdaptationReason, - pub changes_made: Vec, - pub performance_impact: u64, // Basis points - pub user_feedback: Option, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AdaptationReason { - PerformanceDrop, - LearningStyleMismatch, - TimeConstraints, - DifficultyMismatch, - UserRequest, - AIRecommendation, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ProgressTracking { - pub overall_progress: u32, // 0-100 - pub module_progress: Map, // Module ID -> Progress - pub time_spent: u64, // Total time in minutes - pub milestones_completed: u32, - pub milestones_total: u32, - pub streak_days: u32, - pub last_activity: u64, - pub engagement_metrics: EngagementMetrics, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct EngagementMetrics { - pub login_frequency: u32, // Per week - pub content_interactions: u32, // Per session - pub discussion_participation: u32, - pub peer_interactions: u32, - pub help_requests: u32, - pub feedback_submissions: u32, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PathAnalytics { - pub completion_predictions: CompletionPrediction, - pub learning_efficiency: u64, // Basis points - pub knowledge_retention: u64, // Basis points - pub skill_gaps: Vec, - pub optimization_suggestions: Vec, - pub peer_comparison: PeerComparison, - pub career_alignment: CareerAlignment, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CompletionPrediction { - pub estimated_completion_date: u64, - pub confidence_level: u64, // Basis points - pub risk_factors: Vec, - pub success_probability: u64, // Basis points -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct RiskFactor { - pub factor_type: RiskType, - pub severity: u32, // 1-10 - pub description: Bytes, - pub mitigation_strategies: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum RiskType { - TimeManagement, - DifficultyMismatch, - MotivationIssue, - TechnicalProblems, - ContentQuality, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SkillGap { - pub skill_area: Bytes, - pub current_level: u32, - pub required_level: u32, - pub gap_size: u32, - pub recommended_resources: Vec, - pub priority: u32, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct OptimizationSuggestion { - pub suggestion_type: SuggestionType, - pub description: Bytes, - pub expected_improvement: u64, // Basis points - pub implementation_effort: u32, // 1-10 - pub urgency: u32, // 1-10 -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum SuggestionType { - AdjustPace, - ChangeContent, - AddPractice, - SeekHelp, - TakeBreak, - ReviewPrerequisites, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PeerComparison { - pub percentile_rank: u32, // 0-100 - pub similar_users_progress: u64, // Basis points - pub top_performers_average: u64, // Basis points - pub improvement_opportunities: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CareerAlignment { - pub target_career: Bytes, - pub alignment_score: u64, // Basis points - pub missing_skills: Vec, - pub market_demand: u64, // Basis points - pub salary_potential: u64, - pub growth_trajectory: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CareerMilestone { - pub title: Bytes, - pub expected_timeline: u64, // Months from now - pub required_skills: Vec, - pub salary_range: (u64, u64), -} - -// ========== Collaborative Learning Types ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CollaborativePath { - pub id: u64, - pub creator: Address, - pub title: Bytes, - pub description: Bytes, - pub participants: Vec
, - pub shared_objectives: Vec, - pub group_activities: Vec, - pub collaboration_metrics: CollaborationMetrics, - pub is_active: bool, - pub created_at: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct GroupActivity { - pub id: u64, - pub activity_type: GroupActivityType, - pub title: Bytes, - pub description: Bytes, - pub scheduled_time: u64, - pub duration_minutes: u32, - pub required_participants: u32, - pub resources: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum GroupActivityType { - StudySession, - ProjectWork, - DiscussionForum, - PeerReview, - VirtualClassroom, - Hackathon, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CollaborationMetrics { - pub participation_rate: u64, // Basis points - pub synergy_score: u64, // Basis points - pub knowledge_sharing: u32, - pub conflict_resolution: u32, - pub group_performance: u64, // Basis points -} - -// ========== Certification Types ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PathCertification { - pub path_id: u64, - pub user: Address, - pub certification_type: CertificationType, - pub issuer: Address, - pub issue_date: u64, - pub expiry_date: u64, - pub verification_code: Bytes, - pub blockchain_certificate: Bytes, - pub skills_certified: Vec, - pub achievement_level: AchievementLevel, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum CertificationType { - Completion, - Mastery, - Excellence, - Specialization, - Professional, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AchievementLevel { - Basic, - Intermediate, - Advanced, - Expert, - Master, -} - -// ========== Errors ========== - -#[contracterror] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum LearningPathError { - InvalidPath = 1, - InsufficientPrerequisites = 2, - PathNotActive = 3, - UnauthorizedAccess = 4, - AdaptationFailed = 5, - CertificationError = 6, - CollaborationError = 7, -} - -// ========== Main Implementation ========== - -pub struct LearningPathManager; - -impl LearningPathManager { - /// Generate AI-powered learning path based on user goals and profile - pub fn generate_learning_path( - env: &Env, - user: Address, - goals: Vec, - profile: UserProfile, - ) -> Result { - user.require_auth(); - - let path_id = env.ledger().sequence(); - let ai_analysis = Self::analyze_user_profile(env, &user, &goals, &profile); - - let learning_path = LearningPath { - id: path_id, - user: user.clone(), - title: ai_analysis.recommended_title, - description: ai_analysis.recommended_description, - learning_objectives: Self::generate_objectives(&goals, &ai_analysis), - content_modules: Self::generate_content_modules(&ai_analysis, &profile), - prerequisites: Self::analyze_prerequisites(&goals), - estimated_duration: ai_analysis.estimated_duration, - difficulty_level: ai_analysis.recommended_difficulty, - learning_style: profile.preferred_learning_style, - personalization_data: Self::create_personalization(&profile), - adaptation_history: Vec::new(env), - progress_tracking: ProgressTracking { - overall_progress: 0, - module_progress: Map::new(env), - time_spent: 0, - milestones_completed: 0, - milestones_total: 10, - streak_days: 0, - last_activity: env.ledger().timestamp(), - engagement_metrics: EngagementMetrics { - login_frequency: 0, - content_interactions: 0, - discussion_participation: 0, - peer_interactions: 0, - help_requests: 0, - feedback_submissions: 0, - }, - }, - analytics: PathAnalytics { - completion_predictions: CompletionPrediction { - estimated_completion_date: env.ledger().timestamp() - + ai_analysis.estimated_duration * 3600, - confidence_level: ai_analysis.confidence_level, - risk_factors: ai_analysis.risk_factors, - success_probability: ai_analysis.success_probability, - }, - learning_efficiency: 0.0, - knowledge_retention: 0.0, - skill_gaps: Vec::new(env), - optimization_suggestions: Vec::new(env), - peer_comparison: PeerComparison { - percentile_rank: 50, - similar_users_progress: 0.0, - top_performers_average: 0.0, - improvement_opportunities: Vec::new(env), - }, - career_alignment: CareerAlignment { - target_career: goals - .get(0) - .unwrap_or(&LearningGoal { - title: Bytes::from_slice(env, b"General Learning"), - description: Bytes::from_slice(env, b""), - target_date: 0, - priority: 1, - }) - .title - .clone(), - alignment_score: 0.0, - missing_skills: Vec::new(env), - market_demand: 0.0, - salary_potential: 0, - growth_trajectory: Vec::new(env), - }, - }, - is_active: true, - created_at: env.ledger().timestamp(), - last_updated: env.ledger().timestamp(), - }; - - Self::set_learning_path(env, &path_id, &learning_path); - Self::set_user_goals(env, &user, &goals); - - Ok(path_id) - } - - /// Adapt learning path based on performance and feedback - pub fn adapt_learning_path( - env: &Env, - user: Address, - path_id: u64, - performance_data: PerformanceData, - user_feedback: Option, - ) -> Result<(), LearningPathError> { - user.require_auth(); - - let mut learning_path = Self::get_learning_path(env, &path_id); - if learning_path.user != user { - return Err(LearningPathError::UnauthorizedAccess); - } - - let adaptation = Self::analyze_performance(&performance_data, &user_feedback); - Self::apply_adaptations(env, &mut learning_path, &adaptation); - - learning_path.last_updated = env.ledger().timestamp(); - Self::set_learning_path(env, &path_id, &learning_path); - - Ok(()) - } - - /// Create collaborative learning path - pub fn create_collaborative_path( - env: &Env, - creator: Address, - title: Bytes, - description: Bytes, - shared_objectives: Vec, - ) -> Result { - creator.require_auth(); - - let path_id = env.ledger().sequence(); - let collaborative_path = CollaborativePath { - id: path_id, - creator: creator.clone(), - title, - description, - participants: Vec::from_array(env, &[creator.clone()]), - shared_objectives, - group_activities: Vec::new(env), - collaboration_metrics: CollaborationMetrics { - participation_rate: 0.0, - synergy_score: 0.0, - knowledge_sharing: 0, - conflict_resolution: 0, - group_performance: 0.0, - }, - is_active: true, - created_at: env.ledger().timestamp(), - }; - - Self::set_collaborative_path(env, &path_id, &collaborative_path); - - Ok(path_id) - } - - /// Issue certification for completed learning path - pub fn issue_certification( - env: &Env, - user: Address, - path_id: u64, - certification_type: CertificationType, - issuer: Address, - ) -> Result { - let learning_path = Self::get_learning_path(env, &path_id); - - if learning_path.user != user { - return Err(LearningPathError::UnauthorizedAccess); - } - - if learning_path.progress_tracking.overall_progress < 100 { - return Err(LearningPathError::CertificationError); - } - - let certification = PathCertification { - path_id, - user: user.clone(), - certification_type, - issuer: issuer.clone(), - issue_date: env.ledger().timestamp(), - expiry_date: env.ledger().timestamp() + (365 * 24 * 60 * 60), // 1 year - verification_code: Self::generate_verification_code(env), - blockchain_certificate: Self::generate_blockchain_certificate(env, &user, &path_id), - skills_certified: Self::extract_certified_skills(&learning_path), - achievement_level: Self::calculate_achievement_level(&learning_path), - }; - - Self::set_certification(env, &certification); - - Ok(certification) - } - - // ========== AI Analysis Functions ========== - - fn analyze_user_profile( - env: &Env, - user: &Address, - goals: &Vec, - profile: &UserProfile, - ) -> AIAnalysisResult { - // Simulated AI analysis - in real implementation, this would call ML models - AIAnalysisResult { - recommended_title: Bytes::from_slice(env, b"Personalized Learning Journey"), - recommended_description: Bytes::from_slice( - env, - b"AI-optimized learning path based on your goals and preferences", - ), - estimated_duration: Self::estimate_duration(goals, profile), - recommended_difficulty: Self::recommend_difficulty(profile), - confidence_level: 0.85, - success_probability: 0.92, - risk_factors: Vec::new(env), - } - } - - fn estimate_duration(goals: &Vec, profile: &UserProfile) -> u64 { - // Complex estimation based on goals complexity and user's learning pace - let base_hours = 100; // Base estimate - let pace_multiplier = match profile.pace_preference { - PacePreference::Fast => 0.7, - PacePreference::Normal => 1.0, - PacePreference::Slow => 1.5, - PacePreference::Adaptive => 1.0, - }; - - (base_hours as f64 * pace_multiplier as f64) as u64 - } - - fn recommend_difficulty(profile: &UserProfile) -> DifficultyLevel { - // Recommend based on user's experience and preferences - DifficultyLevel::Intermediate // Default, would be calculated - } - - // ========== Helper Functions ========== - - fn generate_objectives( - goals: &Vec, - analysis: &AIAnalysisResult, - ) -> Vec { - Vec::new(&Env::default()) // Would generate based on goals - } - - fn generate_content_modules( - analysis: &AIAnalysisResult, - profile: &UserProfile, - ) -> Vec { - Vec::new(&Env::default()) // Would generate based on analysis - } - - fn analyze_prerequisites(goals: &Vec) -> Vec { - Vec::new(&Env::default()) // Would analyze dependencies - } - - fn create_personalization(profile: &UserProfile) -> PersonalizationData { - PersonalizationData { - preferred_learning_style: profile.preferred_learning_style, - pace_preference: profile.pace_preference, - time_availability: profile.time_availability.clone(), - content_preferences: profile.content_preferences.clone(), - accessibility_needs: profile.accessibility_needs.clone(), - language_preference: profile.language_preference.clone(), - cultural_context: profile.cultural_context.clone(), - } - } - - fn analyze_performance( - performance_data: &PerformanceData, - user_feedback: &Option, - ) -> PathAdaptation { - PathAdaptation { - timestamp: 1234567890, - reason: AdaptationReason::AIRecommendation, - changes_made: Vec::new(&Env::default()), - performance_impact: 0.1, - user_feedback: user_feedback.clone(), - } - } - - fn apply_adaptations(env: &Env, learning_path: &mut LearningPath, adaptation: &PathAdaptation) { - learning_path - .adaptation_history - .push_back(adaptation.clone()); - learning_path.last_updated = env.ledger().timestamp(); - } - - fn generate_verification_code(env: &Env) -> Bytes { - let code = env.ledger().sequence(); - Bytes::from_slice(env, &code.to_be_bytes()) - } - - fn generate_blockchain_certificate(env: &Env, user: &Address, path_id: &u64) -> Bytes { - // Generate blockchain-verifiable certificate - let data = format!("CERT:{}:{}", user.to_string(), path_id); - Bytes::from_slice(env, data.as_bytes()) - } - - fn extract_certified_skills(learning_path: &LearningPath) -> Vec { - Vec::new(&Env::default()) // Extract from completed objectives - } - - fn calculate_achievement_level(learning_path: &LearningPath) -> AchievementLevel { - match learning_path.progress_tracking.overall_progress { - 90..=100 => AchievementLevel::Master, - 75..=89 => AchievementLevel::Expert, - 60..=74 => AchievementLevel::Advanced, - 40..=59 => AchievementLevel::Intermediate, - _ => AchievementLevel::Basic, - } - } - - // ========== Storage Functions ========== - - fn get_learning_path(env: &Env, path_id: &u64) -> LearningPath { - env.storage() - .persistent() - .get(&(LEARNING_PATHS, path_id.clone())) - .unwrap_or_else(|| panic_with_error!(env, LearningPathError::InvalidPath)) - } - - fn set_learning_path(env: &Env, path_id: &u64, learning_path: &LearningPath) { - env.storage() - .persistent() - .set(&(LEARNING_PATHS, path_id.clone()), learning_path); - } - - fn set_user_goals(env: &Env, user: &Address, goals: &Vec) { - env.storage() - .persistent() - .set(&(LEARNING_GOALS, user.clone()), goals); - } - - fn set_collaborative_path(env: &Env, path_id: &u64, collaborative_path: &CollaborativePath) { - env.storage() - .persistent() - .set(&(COLLABORATIVE_PATHS, path_id.clone()), collaborative_path); - } - - fn set_certification(env: &Env, certification: &PathCertification) { - let cert_id = env.ledger().sequence(); - env.storage() - .persistent() - .set(&(PATH_CERTIFICATION, cert_id), certification); - } -} - -// ========== Supporting Types ========== - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct LearningGoal { - pub title: Bytes, - pub description: Bytes, - pub target_date: u64, - pub priority: u32, // 1-10 -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct UserProfile { - pub preferred_learning_style: LearningStyle, - pub pace_preference: PacePreference, - pub time_availability: Vec, - pub content_preferences: Vec, - pub accessibility_needs: Vec, - pub language_preference: Bytes, - pub cultural_context: Bytes, - pub experience_level: u32, - pub interests: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct AIAnalysisResult { - pub recommended_title: Bytes, - pub recommended_description: Bytes, - pub estimated_duration: u64, - pub recommended_difficulty: DifficultyLevel, - pub confidence_level: u64, // Basis points - pub success_probability: u64, // Basis points - pub risk_factors: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PerformanceData { - pub quiz_scores: Vec, - pub assignment_scores: Vec, - pub time_spent_per_module: Map, - pub engagement_level: u32, - pub completion_rate: u64, // Basis points - pub feedback_ratings: Vec, -} diff --git a/contracts/teachlink/src/lib.rs b/contracts/teachlink/src/lib.rs index 6b66cc86..3f387c20 100644 --- a/contracts/teachlink/src/lib.rs +++ b/contracts/teachlink/src/lib.rs @@ -103,45 +103,27 @@ mod backup; mod bft_consensus; mod bridge; mod bulk_limits; -mod dos_protection; -// TODO: Fix collaboration module compilation errors (pre-existing issue) -// mod collaboration; -// TODO: Fix content_nft module compilation errors (pre-existing issue) -// mod content_nft; -// TODO: Fix content_quality module compilation errors (pre-existing issue - symbol too long) -// mod content_quality; mod config; +mod dos_protection; mod emergency; -mod feature_flags; mod errors; mod escrow_analytics; mod event_query; +mod feature_flags; mod safe_stats; // TODO: Fix event_tests module compilation errors (pre-existing issue) // mod event_tests; mod events; -// TODO: Fix fractional module compilation errors (pre-existing issue) -// mod fractional; mod insurance; mod interface_versioning; -// TODO: Fix learning_paths module compilation errors (pre-existing issue - symbol too long) -// mod learning_paths; mod ledger_time; -// TODO: Fix licensing module compilation errors (pre-existing issue) -// mod licensing; mod liquidity; -// TODO: Fix marketplace module compilation errors (pre-existing issue) -// mod marketplace; mod message_passing; mod mobile_platform; mod multichain; mod network_recovery; mod notification; -// TODO: Fix notification_events module compilation errors (pre-existing issue - event name too long) -// mod notification_events; mod notification_events_basic; -// TODO: Fix notification_events_simple module compilation errors (pre-existing issue) -// mod notification_events_simple; // TODO: Fix notification_tests module (pre-existing issue - tests fail with AlreadyInitialized) // mod notification_tests; mod notification_types; @@ -155,14 +137,8 @@ mod reporting; mod repository; mod reputation; mod rewards; -// TODO: Fix royalty module compilation errors (pre-existing issue - incomplete implementation) -// mod royalty; mod score; mod slashing; -// TODO: Fix social_events module compilation errors (pre-existing issue) -// mod social_events; -// TODO: Fix social_learning module compilation errors (pre-existing issue) -// mod social_learning; mod storage; mod sustainability; mod tokenization; @@ -195,20 +171,7 @@ pub use repository::{ SingleValueRepository, StorageError, }; pub use types::{ - AlertConditionType, AlertRule, ArbitratorProfile, AtomicSwap, AuditRecord, BackupManifest, - BackupSchedule, BridgeMetrics, BridgeProposal, BridgeTransaction, CachedBridgeSummary, - ChainConfig, ChainMetrics, ComplianceReport, ConsensusState, ContentMetadata, ContentToken, - ContentTokenParameters, ContentType, ContractSemVer, ContributionType, CrossChainMessage, - CrossChainPacket, DashboardAnalytics, DisputeOutcome, EmergencyState, Escrow, EscrowMetrics, - EscrowParameters, EscrowRole, EscrowSigner, EscrowStatus, InterfaceVersionStatus, - LiquidityPool, MultiChainAsset, NotificationChannel, NotificationContent, - NotificationPreference, NotificationSchedule, NotificationTemplate, NotificationTracking, - OperationType, PacketStatus, ProposalStatus, ProvenanceRecord, RecoveryRecord, ReportComment, - ReportSchedule, ReportSnapshot, ReportTemplate, ReportType, ReportUsage, RewardRate, - RewardType, RtoTier, SlashingReason, SlashingRecord, SwapStatus, TransferType, - UserNotificationSettings, UserReputation, UserReward, ValidatorInfo, ValidatorReward, - ValidatorSignature, VisualizationDataPoint, FeatureFlag, FeatureStatus, RolloutStrategy, - // access logging types + // access logging / audit types AccessLogEntry, AccessOutcome, AlertConditionType, @@ -246,6 +209,8 @@ pub use types::{ EscrowRole, EscrowSigner, EscrowStatus, + FeatureFlag, + FeatureStatus, InterfaceVersionStatus, LiquidityPool, MigrationPath, @@ -269,6 +234,7 @@ pub use types::{ ReportUsage, RewardRate, RewardType, + RolloutStrategy, RtoTier, SlashingReason, SlashingRecord, diff --git a/contracts/teachlink/src/licensing.rs b/contracts/teachlink/src/licensing.rs deleted file mode 100644 index 7e8e72e8..00000000 --- a/contracts/teachlink/src/licensing.rs +++ /dev/null @@ -1,13 +0,0 @@ -pub enum LicenseType { - Personal, - Commercial, - Exclusive, - Subscription, -} - -pub struct LicenseAgreement { - pub token_id: u64, - pub licensee: Address, - pub license_type: LicenseType, - pub expires_at: Option, -} diff --git a/contracts/teachlink/src/marketplace.rs b/contracts/teachlink/src/marketplace.rs deleted file mode 100644 index c41301c2..00000000 --- a/contracts/teachlink/src/marketplace.rs +++ /dev/null @@ -1,25 +0,0 @@ -pub struct Listing { - pub listing_id: u64, - pub token_id: u64, - pub seller: Address, - pub price: u128, - pub payment_token: Address, - pub active: bool, -} - -pub fn buy(listing_id: u64, buyer: Address) -> Result<()> { - let listing = Self::get_listing(listing_id)?; - let nft = ContentModule::get_nft(listing.token_id)?; - - let royalty = listing.price * nft.royalty_percentage as u128 / 10000; - let seller_amount = listing.price - royalty; - - // Transfer funds - Self::transfer(buyer, nft.creator, royalty); - Self::transfer(buyer, listing.seller, seller_amount); - - // Transfer ownership - ContentModule::transfer_nft(listing.token_id, buyer)?; - - Ok(()) -} diff --git a/contracts/teachlink/src/notification_events.rs b/contracts/teachlink/src/notification_events.rs deleted file mode 100644 index d797bfeb..00000000 --- a/contracts/teachlink/src/notification_events.rs +++ /dev/null @@ -1,229 +0,0 @@ -//! Notification System Events -//! -//! This module defines all events emitted by the comprehensive notification system. - -use crate::notification_types::{ - NotificationChannel, NotificationDeliveryStatus, NotificationPreference, NotificationTemplate, -}; -use soroban_sdk::{contractevent, Address, Bytes, Vec}; - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationSentEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub sent_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationDeliveredEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub delivered_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationFailedEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub error: Bytes, - pub retry_count: u32, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationScheduledEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub scheduled_time: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationOpenedEvent { - pub notification_id: u64, - pub user: Address, - pub opened_at: u64, - pub device_type: Bytes, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationClickedEvent { - pub notification_id: u64, - pub user: Address, - pub clicked_at: u64, - pub click_target: Bytes, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationPreferenceUpdatedEvent { - pub user: Address, - pub preferences: Vec, - pub updated_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationTemplateCreatedEvent { - pub template_id: u64, - pub name: Bytes, - pub channels: Vec, - pub created_by: Address, - pub created_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationTemplateUpdatedEvent { - pub template_id: u64, - pub name: Bytes, - pub updated_by: Address, - pub updated_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationBatchProcessedEvent { - pub batch_id: u64, - pub notification_count: u32, - pub success_count: u32, - pub failure_count: u32, - pub processed_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationEngagementTrackedEvent { - pub notification_id: u64, - pub user: Address, - pub engagement_type: u32, // 0=open, 1=click, 2=convert - pub timestamp: u64, - pub metadata: Bytes, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationABTestStartedEvent { - pub test_id: u64, - pub name: Bytes, - pub template_a_id: u64, - pub template_b_id: u64, - pub traffic_split: u32, - pub started_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationABTestCompletedEvent { - pub test_id: u64, - pub winner: u32, // 0=A, 1=B, 2=tie - pub confidence: u32, // basis points - pub completed_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationComplianceCheckedEvent { - pub notification_id: u64, - pub user: Address, - pub region: Bytes, - pub passed: bool, - pub checked_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationRateLimitedEvent { - pub user: Address, - pub channel: NotificationChannel, - pub limit_type: u32, // 0=daily, 1=hourly, 2=per_minute - pub current_count: u32, - pub max_allowed: u32, - pub timestamp: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationPersonalizationAppliedEvent { - pub notification_id: u64, - pub user: Address, - pub rules_applied: Vec, - pub personalization_score: u32, // basis points - pub applied_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationOptimizationPerformedEvent { - pub user: Address, - pub optimization_type: u32, // 0=timing, 1=channel, 2=content - pub old_score: u32, - pub new_score: u32, - pub optimized_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationWebhookTriggeredEvent { - pub webhook_id: u64, - pub event_type: Bytes, - pub notification_id: u64, - pub payload: Bytes, - pub triggered_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationContentFilteredEvent { - pub notification_id: u64, - pub filter_id: u64, - pub content_modified: bool, - pub filtered_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationCampaignStartedEvent { - pub campaign_id: u64, - pub name: Bytes, - pub segment_count: u32, - pub estimated_notifications: u64, - pub started_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationCampaignCompletedEvent { - pub campaign_id: u64, - pub total_sent: u64, - pub total_delivered: u64, - pub total_converted: u64, - pub roi: i128, // basis points - pub completed_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationUserSegmentUpdatedEvent { - pub segment_id: u64, - pub user_count: u32, - pub updated_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationThrottlingActivatedEvent { - pub channel: NotificationChannel, - pub current_rate: u32, - pub max_rate: u32, - pub activated_at: u64, -} - diff --git a/contracts/teachlink/src/notification_events_simple.rs b/contracts/teachlink/src/notification_events_simple.rs deleted file mode 100644 index 123b79ff..00000000 --- a/contracts/teachlink/src/notification_events_simple.rs +++ /dev/null @@ -1,82 +0,0 @@ -//! Notification System Events (Simplified) -//! -//! This module defines essential events emitted by the notification system. - -use crate::notification_types::{ - NotificationChannel, NotificationDeliveryStatus, NotificationPreference, NotificationTemplate, -}; -use soroban_sdk::{contractevent, Address, Bytes, Vec}; - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationSentEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub sent_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationDeliveredEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub delivered_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationFailedEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub error: Bytes, - pub retry_count: u32, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationScheduledEvent { - pub notification_id: u64, - pub recipient: Address, - pub channel: NotificationChannel, - pub scheduled_time: u64, -} - -// Simplified preference event -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationPrefUpdatedEvent { - pub user: Address, - pub updated_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationTemplateCreatedEvent { - pub template_id: u64, - pub name: Bytes, - pub channels: Vec, - pub created_by: Address, - pub created_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationTemplateUpdatedEvent { - pub template_id: u64, - pub name: Bytes, - pub updated_by: Address, - pub updated_at: u64, -} - -#[contractevent] -#[derive(Clone, Debug)] -pub struct NotificationBatchProcessedEvent { - pub batch_id: u64, - pub notification_count: u32, - pub success_count: u32, - pub failure_count: u32, - pub processed_at: u64, -} diff --git a/contracts/teachlink/src/royalty.rs b/contracts/teachlink/src/royalty.rs deleted file mode 100644 index 54605f34..00000000 --- a/contracts/teachlink/src/royalty.rs +++ /dev/null @@ -1,44 +0,0 @@ -use crate::errors::{RoyaltyError, RoyaltyResult}; -use soroban_sdk::{Address, Env, Vec}; - -pub struct RoyaltySplit { - pub recipients: Vec<(Address, u16)>, // percentage basis points -} - -pub fn distribute(token_id: u64, amount: u128) -> RoyaltyResult<()> { - let splits = Self::get_royalty_split(token_id); - - // Guard: ensure total basis points do not exceed 10000 to prevent over-distribution - let total_bps: u32 = splits.iter().map(|(_, pct)| pct as u32).sum(); - if total_bps > 10000 { - return Err(RoyaltyError::InvalidAmount); - } - - let mut distributed: u128 = 0; - let mut last_recipient: Option
= None; - - for (recipient, percentage) in splits.iter() { - let share = amount * percentage as u128 / 10000; - distributed += share; - Self::transfer_platform(recipient.clone(), share)?; - last_recipient = Some(recipient); - } - - // Send any rounding dust to the first recipient to ensure full distribution - let remainder = amount.saturating_sub(distributed); - if remainder > 0 { - if let Some(recipient) = last_recipient { - Self::transfer_platform(recipient, remainder)?; - } - } -impl RoyaltySplit { - fn get_royalty_split(_token_id: u64) -> Vec<(Address, u16)> { - // TODO: Implement royalty split retrieval from storage - Vec::new(&Env::default()) - } - - fn transfer_platform(_recipient: Address, _amount: u128) -> RoyaltyResult<()> { - // TODO: Implement platform token transfer - Err(RoyaltyError::StorageError) // Placeholder - } -} diff --git a/contracts/teachlink/src/social_events.rs b/contracts/teachlink/src/social_events.rs deleted file mode 100644 index 9bd672fc..00000000 --- a/contracts/teachlink/src/social_events.rs +++ /dev/null @@ -1,96 +0,0 @@ -//! Social Learning Events -//! -//! This module defines all events emitted by the social learning platform. - -use soroban_sdk::{contractevent, Address, Bytes, Symbol, Vec}; - -#[contractevent] -pub struct StudyGroupCreatedEvent { - pub group_id: u64, - pub creator: Address, - pub name: Bytes, - pub subject: Bytes, -} - -#[contractevent] -pub struct StudyGroupJoinedEvent { - pub group_id: u64, - pub user: Address, - pub joined_at: u64, -} - -#[contractevent] -pub struct StudyGroupLeftEvent { - pub group_id: u64, - pub user: Address, - pub left_at: u64, -} - -#[contractevent] -pub struct ForumCreatedEvent { - pub forum_id: u64, - pub creator: Address, - pub title: Bytes, - pub category: Bytes, -} - -#[contractevent] -pub struct ForumPostCreatedEvent { - pub post_id: u64, - pub forum_id: u64, - pub author: Address, - pub title: Bytes, -} - -#[contractevent] -pub struct WorkspaceCreatedEvent { - pub workspace_id: u64, - pub creator: Address, - pub name: Bytes, - pub project_type: Symbol, -} - -#[contractevent] -pub struct PeerReviewCreatedEvent { - pub review_id: u64, - pub reviewer: Address, - pub reviewee: Address, - pub rating: u32, - pub content_type: Symbol, -} - -#[contractevent] -pub struct MentorshipProfileCreatedEvent { - pub mentor: Address, - pub expertise_areas: Vec, -} - -#[contractevent] -pub struct MentorshipSessionScheduledEvent { - pub session_id: u64, - pub mentor: Address, - pub mentee: Address, - pub topic: Bytes, - pub scheduled_time: u64, -} - -#[contractevent] -pub struct SocialBadgeEarnedEvent { - pub user: Address, - pub badge_id: u64, - pub badge_name: Bytes, -} - -#[contractevent] -pub struct SocialPointsEarnedEvent { - pub user: Address, - pub points: u64, - pub activity_type: Symbol, -} - -#[contractevent] -pub struct CollaborationStartedEvent { - pub workspace_id: u64, - pub collaborator: Address, - pub role: Symbol, -} diff --git a/contracts/teachlink/src/social_learning.rs b/contracts/teachlink/src/social_learning.rs deleted file mode 100644 index 43763f74..00000000 --- a/contracts/teachlink/src/social_learning.rs +++ /dev/null @@ -1,1142 +0,0 @@ -//! Social Learning Platform Module -//! -//! This module implements comprehensive social learning features including: -//! - Real-time collaboration tools and workspaces -//! - Study group formation and management -//! - Discussion forums and knowledge sharing -//! - Peer review and feedback systems -//! - Social learning analytics and engagement tracking -//! - Mentorship and tutoring matching -//! - Collaborative project management -//! - Social gamification and recognition systems - -use soroban_sdk::{ - contracterror, contracttype, panic_with_error, symbol_short, Address, Bytes, Env, IntoVal, Map, - String, Symbol, TryFromVal, Val, Vec, -}; - -use crate::errors::{SocialLearningError, SocialLearningResult}; -use crate::storage::*; -use crate::types::*; - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct StudyGroup { - pub id: u64, - pub name: Bytes, - pub description: Bytes, - pub creator: Address, - pub members: Vec
, - pub admins: Vec
, - pub subject: Bytes, - pub max_members: u32, - pub is_private: bool, - pub created_at: u64, - pub last_activity: u64, - pub tags: Vec, - pub settings: StudyGroupSettings, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct StudyGroupSettings { - pub allow_member_invites: bool, - pub require_admin_approval: bool, - pub enable_chat: bool, - pub enable_file_sharing: bool, - pub enable_video_calls: bool, - pub auto_approve_members: bool, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct DiscussionForum { - pub id: u64, - pub title: Bytes, - pub description: Bytes, - pub creator: Address, - pub category: Bytes, - pub tags: Vec, - pub is_pinned: bool, - pub is_locked: bool, - pub created_at: u64, - pub last_post_at: u64, - pub post_count: u32, - pub view_count: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct ForumPost { - pub id: u64, - pub forum_id: u64, - pub title: Bytes, - pub content: Bytes, - pub author: Address, - pub created_at: u64, - pub updated_at: u64, - pub reply_count: u32, - pub like_count: u32, - pub is_pinned: bool, - pub is_edited: bool, - pub attachments: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CollaborationWorkspace { - pub id: u64, - pub name: Bytes, - pub description: Bytes, - pub creator: Address, - pub collaborators: Vec
, - pub project_type: ProjectType, - pub status: WorkspaceStatus, - pub created_at: u64, - pub last_activity: u64, - pub files: Vec, - pub tasks: Vec, - pub settings: WorkspaceSettings, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ProjectType { - Study, - Research, - Assignment, - Tutorial, - Discussion, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum WorkspaceStatus { - Active, - Completed, - Archived, - Suspended, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct WorkspaceFile { - pub id: u64, - pub name: Bytes, - pub content_hash: Bytes, - pub uploader: Address, - pub uploaded_at: u64, - pub file_type: Bytes, - pub size: u64, - pub version: u32, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct WorkspaceTask { - pub id: u64, - pub title: Bytes, - pub description: Bytes, - pub assignee: Address, - pub creator: Address, - pub due_date: u64, - pub status: TaskStatus, - pub priority: TaskPriority, - pub created_at: u64, - pub completed_at: Option, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum TaskStatus { - Todo, - InProgress, - Review, - Completed, - Cancelled, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum TaskPriority { - Low, - Medium, - High, - Urgent, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct WorkspaceSettings { - pub allow_public_view: bool, - pub require_approval_to_join: bool, - pub enable_chat: bool, - pub enable_video_calls: bool, - pub auto_save_interval: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct PeerReview { - pub id: u64, - pub reviewer: Address, - pub reviewee: Address, - pub content_type: ReviewContentType, - pub content_id: u64, - pub rating: u32, // 1-5 stars - pub feedback: Bytes, - pub criteria: Map, - pub created_at: u64, - pub is_helpful: bool, - pub helpful_votes: u32, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ReviewContentType { - Submission, - Comment, - Project, - Tutorial, - Resource, -} - -/// Parameter struct for creating a study group -/// Replaces the 9-parameter function signature -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CreateStudyGroupParams { - pub creator: Address, - pub name: Bytes, - pub description: Bytes, - pub subject: Bytes, - pub max_members: u32, - pub is_private: bool, - pub tags: Vec, - pub settings: StudyGroupSettings, -} - -impl CreateStudyGroupParams { - /// Builder pattern for creating study group parameters - pub fn builder(creator: Address, name: Bytes, subject: Bytes) -> CreateStudyGroupParamsBuilder { - CreateStudyGroupParamsBuilder { - creator, - name, - subject, - description: Bytes::new(&soroban_sdk::Env::current()), - max_members: 50, - is_private: false, - tags: Vec::new(&soroban_sdk::Env::current()), - settings: StudyGroupSettings { - allow_member_invites: true, - require_admin_approval: false, - enable_chat: true, - enable_file_sharing: true, - enable_video_calls: true, - auto_approve_members: true, - }, - } - } - - /// Validates the parameters for creating a study group - pub fn validate(&self) -> Result<(), SocialLearningError> { - // Validate name - if self.name.len() == 0 || self.name.len() > 100 { - return Err(SocialLearningError::InvalidInput); - } - - // Validate description - if self.description.len() > 500 { - return Err(SocialLearningError::InvalidInput); - } - - // Validate max_members - if self.max_members < 2 || self.max_members > 1000 { - return Err(SocialLearningError::InvalidInput); - } - - // Validate tags - if self.tags.len() > 10 { - return Err(SocialLearningError::InvalidInput); - } - - for tag in self.tags.iter() { - if tag.len() == 0 || tag.len() > 50 { - return Err(SocialLearningError::InvalidInput); - } - } - - Ok(()) - } -} - -/// Builder for CreateStudyGroupParams -pub struct CreateStudyGroupParamsBuilder { - creator: Address, - name: Bytes, - subject: Bytes, - description: Bytes, - max_members: u32, - is_private: bool, - tags: Vec, - settings: StudyGroupSettings, -} - -impl CreateStudyGroupParamsBuilder { - pub fn description(mut self, description: Bytes) -> Self { - self.description = description; - self - } - - pub fn max_members(mut self, max_members: u32) -> Self { - self.max_members = max_members; - self - } - - pub fn is_private(mut self, is_private: bool) -> Self { - self.is_private = is_private; - self - } - - pub fn tags(mut self, tags: Vec) -> Self { - self.tags = tags; - self - } - - pub fn settings(mut self, settings: StudyGroupSettings) -> Self { - self.settings = settings; - self - } - - pub fn build(self) -> CreateStudyGroupParams { - CreateStudyGroupParams { - creator: self.creator, - name: self.name, - description: self.description, - subject: self.subject, - max_members: self.max_members, - is_private: self.is_private, - tags: self.tags, - settings: self.settings, - } - } -} - -/// Parameter struct for creating a peer review -/// Replaces the 8-parameter function signature -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct CreatePeerReviewParams { - pub reviewer: Address, - pub reviewee: Address, - pub content_type: ReviewContentType, - pub content_id: u64, - pub rating: u32, - pub feedback: Bytes, - pub criteria: Map, -} - -impl CreatePeerReviewParams { - /// Validates the peer review parameters - pub fn validate(&self) -> Result<(), SocialLearningError> { - // Validate rating (must be 1-5) - if self.rating < 1 || self.rating > 5 { - return Err(SocialLearningError::InvalidRating); - } - - // Validate reviewer and reviewee are different - if self.reviewer == self.reviewee { - return Err(SocialLearningError::InvalidInput); - } - - // Validate feedback length - if self.feedback.len() == 0 || self.feedback.len() > 5000 { - return Err(SocialLearningError::InvalidInput); - } - - // Validate criteria - if self.criteria.is_empty() { - return Err(SocialLearningError::InvalidInput); - } - - Ok(()) - } -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct MentorshipProfile { - pub mentor: Address, - pub expertise_areas: Vec, - pub experience_level: ExperienceLevel, - pub availability: AvailabilityStatus, - pub hourly_rate: Option, - pub bio: Bytes, - pub rating: u64, - pub review_count: u32, - pub mentee_count: u32, - pub success_rate: u64, // represented as basis points (10000 = 100%) - pub languages: Vec, - pub timezone: Bytes, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum ExperienceLevel { - Beginner, - Intermediate, - Advanced, - Expert, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum AvailabilityStatus { - Available, - Busy, - Unavailable, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct MentorshipSession { - pub id: u64, - pub mentor: Address, - pub mentee: Address, - pub topic: Bytes, - pub scheduled_time: u64, - pub duration: u32, // minutes - pub status: SessionStatus, - pub notes: Bytes, - pub rating: Option, - pub feedback: Bytes, - pub created_at: u64, - pub completed_at: Option, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum SessionStatus { - Scheduled, - InProgress, - Completed, - Cancelled, - NoShow, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SocialAnalytics { - pub user: Address, - pub study_groups_joined: u32, - pub discussions_participated: u32, - pub posts_created: u32, - pub reviews_given: u32, - pub mentorship_hours: u64, - pub collaboration_projects: u32, - pub social_score: u64, - pub engagement_level: EngagementLevel, - pub badges: Vec, - pub last_updated: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum EngagementLevel { - Low, - Medium, - High, - VeryHigh, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SocialBadge { - pub id: u64, - pub name: Bytes, - pub description: Bytes, - pub icon: Bytes, - pub category: BadgeCategory, - pub requirements: BadgeRequirements, - pub rarity: BadgeRarity, - pub created_at: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum BadgeCategory { - Collaboration, - Mentorship, - Contribution, - Leadership, - Learning, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct BadgeRequirements { - pub study_groups_joined: Option, - pub discussions_participated: Option, - pub mentorship_hours: Option, - pub reviews_given: Option, - pub projects_completed: Option, - pub social_score: Option, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum BadgeRarity { - Common, - Uncommon, - Rare, - Epic, - Legendary, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct GamificationSystem { - pub points: Map, - pub levels: Map, - pub streaks: Map, - pub achievements: Map>, - pub leaderboards: Map>, - pub rewards: Vec, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub struct SocialReward { - pub id: u64, - pub name: Bytes, - pub description: Bytes, - pub cost: u64, - pub category: RewardCategory, - pub is_available: bool, - pub created_at: u64, -} - -#[contracttype] -#[derive(Clone, Debug, Eq, PartialEq)] -pub enum RewardCategory { - Digital, - Physical, - Access, - Recognition, -} - -// Storage keys -const STUDY_GROUP_COUNTER: Symbol = symbol_short!("SGC"); -const STUDY_GROUPS: Symbol = symbol_short!("SGS"); -const USER_STUDY_GROUPS: Symbol = symbol_short!("USG"); - -const FORUM_COUNTER: Symbol = symbol_short!("FC"); -const FORUMS: Symbol = symbol_short!("FRS"); -const FORUM_POSTS: Symbol = symbol_short!("FPS"); -const USER_POSTS: Symbol = symbol_short!("UPS"); - -const WORKSPACE_COUNTER: Symbol = symbol_short!("WC"); -const WORKSPACES: Symbol = symbol_short!("WKS"); -const USER_WORKSPACES: Symbol = symbol_short!("UWS"); - -const REVIEW_COUNTER: Symbol = symbol_short!("RC"); -const REVIEWS: Symbol = symbol_short!("RVS"); -const USER_REVIEWS: Symbol = symbol_short!("URS"); - -const MENTORSHIP_PROFILES: Symbol = symbol_short!("MPS"); -const MENTORSHIP_SESSIONS: Symbol = symbol_short!("MSS"); -const MENTORSHIP_COUNTER: Symbol = symbol_short!("MSC"); - -const SOCIAL_ANALYTICS: Symbol = symbol_short!("SAS"); -const SOCIAL_BADGES: Symbol = symbol_short!("SBS"); -const GAMIFICATION_SYSTEM: Symbol = symbol_short!("GMS"); - -// Errors -#[contracterror] -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum SocialLearningError { - Unauthorized = 1, - StudyGroupNotFound = 2, - AlreadyMember = 3, - MaxMembersReached = 4, - ForumNotFound = 5, - PostNotFound = 6, - WorkspaceNotFound = 7, - ReviewNotFound = 8, - MentorshipProfileNotFound = 9, - SessionNotFound = 10, - InvalidRating = 11, - InsufficientPermissions = 12, - DuplicateEntry = 13, - InvalidInput = 14, - ResourceNotFound = 15, -} - -pub struct SocialLearningManager; - -impl SocialLearningManager { - // Study Group Management - /// Creates a new study group with validated parameters - /// - /// Uses parameter object pattern to handle multiple parameters cleanly - /// and includes automatic validation of all related parameters - pub fn create_study_group( - env: &Env, - params: CreateStudyGroupParams, - ) -> Result { - params.creator.require_auth(); - - // Validate all parameters together - params.validate()?; - - let counter: u64 = env - .storage() - .instance() - .get(&STUDY_GROUP_COUNTER) - .unwrap_or(0); - let group_id = counter + 1; - - let mut members = Vec::new(&env); - members.push_back(params.creator.clone()); - - let mut admins = Vec::new(&env); - admins.push_back(params.creator.clone()); - - let study_group = StudyGroup { - id: group_id, - name: params.name, - description: params.description, - creator: params.creator.clone(), - members, - admins, - subject: params.subject, - max_members: params.max_members, - is_private: params.is_private, - created_at: env.ledger().timestamp(), - last_activity: env.ledger().timestamp(), - tags: params.tags, - settings: params.settings, - }; - - // Store study group - let mut groups: Map = env - .storage() - .instance() - .get(&STUDY_GROUPS) - .unwrap_or(Map::new(&env)); - groups.set(group_id, study_group); - env.storage().instance().set(&STUDY_GROUPS, &groups); - - // Update user's study groups - let mut user_groups: Vec = env - .storage() - .instance() - .get(&USER_STUDY_GROUPS) - .unwrap_or(Vec::new(&env)); - user_groups.push_back(group_id); - env.storage() - .instance() - .set(&USER_STUDY_GROUPS, &user_groups); - - // Update counter - env.storage() - .instance() - .set(&STUDY_GROUP_COUNTER, &group_id); - - Ok(group_id) - } - - pub fn join_study_group( - env: &Env, - user: Address, - group_id: u64, - ) -> Result<(), SocialLearningError> { - let mut groups: Map = env - .storage() - .instance() - .get(&STUDY_GROUPS) - .ok_or(SocialLearningError::StudyGroupNotFound)?; - - let mut group = groups - .get(group_id) - .ok_or(SocialLearningError::StudyGroupNotFound)?; - - // Check if user is already a member - if group.members.contains(&user) { - return Err(SocialLearningError::AlreadyMember); - } - - // Check if max members reached - if group.members.len() >= group.max_members { - return Err(SocialLearningError::MaxMembersReached); - } - - // Add user to members - group.members.push_back(user.clone()); - group.last_activity = env.ledger().timestamp(); - - groups.set(group_id, group); - env.storage().instance().set(&STUDY_GROUPS, &groups); - - // Update user's study groups - let mut user_groups: Vec = env - .storage() - .instance() - .get(&USER_STUDY_GROUPS) - .unwrap_or(Vec::new(&env)); - user_groups.push_back(group_id); - env.storage() - .instance() - .set(&USER_STUDY_GROUPS, &user_groups); - - Ok(()) - } - - pub fn leave_study_group( - env: &Env, - user: Address, - group_id: u64, - ) -> Result<(), SocialLearningError> { - let mut groups: Map = env - .storage() - .instance() - .get(&STUDY_GROUPS) - .ok_or(SocialLearningError::StudyGroupNotFound)?; - - let mut group = groups - .get(group_id) - .ok_or(SocialLearningError::StudyGroupNotFound)?; - - // Check if user is a member - if !group.members.contains(&user) { - return Err(SocialLearningError::Unauthorized); - } - - // Remove user from members - let mut new_members = Vec::new(env); - for member in group.members.iter() { - if member != user { - new_members.push_back(member); - } - } - group.members = new_members; - - // Remove from admins if applicable - let mut new_admins = Vec::new(env); - for admin in group.admins.iter() { - if admin != user { - new_admins.push_back(admin); - } - } - group.admins = new_admins; - - group.last_activity = env.ledger().timestamp(); - - groups.set(group_id, group); - env.storage().instance().set(&STUDY_GROUPS, &groups); - - // Update user's study groups - let user_groups: Vec = env - .storage() - .instance() - .get(&USER_STUDY_GROUPS) - .unwrap_or(Vec::new(&env)); - let mut new_user_groups = Vec::new(env); - for id in user_groups.iter() { - if id != group_id { - new_user_groups.push_back(id); - } - } - env.storage() - .instance() - .set(&USER_STUDY_GROUPS, &new_user_groups); - - Ok(()) - } - - pub fn get_study_group(env: &Env, group_id: u64) -> Result { - let groups: Map = env - .storage() - .instance() - .get(&STUDY_GROUPS) - .ok_or(SocialLearningError::StudyGroupNotFound)?; - - groups - .get(group_id) - .ok_or(SocialLearningError::StudyGroupNotFound) - } - - pub fn get_user_study_groups(env: &Env, user: Address) -> Vec { - env.storage() - .instance() - .get(&USER_STUDY_GROUPS) - .unwrap_or(Vec::new(&env)) - } - - // Discussion Forum Management - pub fn create_forum( - env: &Env, - creator: Address, - title: Bytes, - description: Bytes, - category: Bytes, - tags: Vec, - ) -> Result { - let counter: u64 = env.storage().instance().get(&FORUM_COUNTER).unwrap_or(0); - let forum_id = counter + 1; - - let forum = DiscussionForum { - id: forum_id, - title, - description, - creator: creator.clone(), - category, - tags, - is_pinned: false, - is_locked: false, - created_at: env.ledger().timestamp(), - last_post_at: env.ledger().timestamp(), - post_count: 0, - view_count: 0, - }; - - // Store forum - let mut forums: Map = env - .storage() - .instance() - .get(&FORUMS) - .unwrap_or(Map::new(&env)); - forums.set(forum_id, forum); - env.storage().instance().set(&FORUMS, &forums); - - // Update counter - env.storage().instance().set(&FORUM_COUNTER, &forum_id); - - Ok(forum_id) - } - - pub fn create_forum_post( - env: &Env, - forum_id: u64, - author: Address, - title: Bytes, - content: Bytes, - attachments: Vec, - ) -> Result { - // Check if forum exists and is not locked - let mut forums: Map = env - .storage() - .instance() - .get(&FORUMS) - .ok_or(SocialLearningError::ForumNotFound)?; - - let mut forum = forums - .get(forum_id) - .ok_or(SocialLearningError::ForumNotFound)?; - - if forum.is_locked { - return Err(SocialLearningError::InsufficientPermissions); - } - - let counter: u64 = env.storage().instance().get(&FORUM_COUNTER).unwrap_or(0); - let post_id = counter + 1; - - let post = ForumPost { - id: post_id, - forum_id, - title, - content, - author: author.clone(), - created_at: env.ledger().timestamp(), - updated_at: env.ledger().timestamp(), - reply_count: 0, - like_count: 0, - is_pinned: false, - is_edited: false, - attachments, - }; - - // Store post - let mut posts: Map = env - .storage() - .instance() - .get(&FORUM_POSTS) - .unwrap_or(Map::new(&env)); - posts.set(post_id, post); - env.storage().instance().set(&FORUM_POSTS, &posts); - - // Update forum - forum.post_count += 1; - forum.last_post_at = env.ledger().timestamp(); - forums.set(forum_id, forum); - env.storage().instance().set(&FORUMS, &forums); - - // Update user's posts - let mut user_posts: Vec = env - .storage() - .instance() - .get(&USER_POSTS) - .unwrap_or(Vec::new(&env)); - user_posts.push_back(post_id); - env.storage().instance().set(&USER_POSTS, &user_posts); - - // Update counter - env.storage().instance().set(&FORUM_COUNTER, &post_id); - - Ok(post_id) - } - - pub fn get_forum(env: &Env, forum_id: u64) -> Result { - let forums: Map = env - .storage() - .instance() - .get(&FORUMS) - .ok_or(SocialLearningError::ForumNotFound)?; - - forums - .get(forum_id) - .ok_or(SocialLearningError::ForumNotFound) - } - - pub fn get_forum_post(env: &Env, post_id: u64) -> Result { - let posts: Map = env - .storage() - .instance() - .get(&FORUM_POSTS) - .ok_or(SocialLearningError::PostNotFound)?; - - posts.get(post_id).ok_or(SocialLearningError::PostNotFound) - } - - // Collaboration Workspace Management - pub fn create_workspace( - env: &Env, - creator: Address, - name: Bytes, - description: Bytes, - project_type: ProjectType, - settings: WorkspaceSettings, - ) -> Result { - let counter: u64 = env - .storage() - .instance() - .get(&WORKSPACE_COUNTER) - .unwrap_or(0); - let workspace_id = counter + 1; - - let mut collaborators = Vec::new(&env); - collaborators.push_back(creator.clone()); - - let workspace = CollaborationWorkspace { - id: workspace_id, - name, - description, - creator: creator.clone(), - collaborators, - project_type, - status: WorkspaceStatus::Active, - created_at: env.ledger().timestamp(), - last_activity: env.ledger().timestamp(), - files: Vec::new(&env), - tasks: Vec::new(&env), - settings, - }; - - // Store workspace - let mut workspaces: Map = env - .storage() - .instance() - .get(&WORKSPACES) - .unwrap_or(Map::new(&env)); - workspaces.set(workspace_id, workspace); - env.storage().instance().set(&WORKSPACES, &workspaces); - - // Update user's workspaces - let mut user_workspaces: Vec = env - .storage() - .instance() - .get(&USER_WORKSPACES) - .unwrap_or(Vec::new(&env)); - user_workspaces.push_back(workspace_id); - env.storage() - .instance() - .set(&USER_WORKSPACES, &user_workspaces); - - // Update counter - env.storage() - .instance() - .set(&WORKSPACE_COUNTER, &workspace_id); - - Ok(workspace_id) - } - - pub fn get_workspace( - env: &Env, - workspace_id: u64, - ) -> Result { - let workspaces: Map = env - .storage() - .instance() - .get(&WORKSPACES) - .ok_or(SocialLearningError::WorkspaceNotFound)?; - - workspaces - .get(workspace_id) - .ok_or(SocialLearningError::WorkspaceNotFound) - } - - pub fn get_user_workspaces(env: &Env, user: Address) -> Vec { - env.storage() - .instance() - .get(&USER_WORKSPACES) - .unwrap_or(Vec::new(&env)) - } - - // Peer Review System - /// Creates a peer review with validated parameters - /// - /// Uses parameter object pattern for cleaner function signature - /// Includes validation of rating ranges and parameter consistency - pub fn create_review( - env: &Env, - params: CreatePeerReviewParams, - ) -> Result { - params.reviewer.require_auth(); - - // Validate all parameters together (includes rating checks) - params.validate()?; - - let counter: u64 = env.storage().instance().get(&REVIEW_COUNTER).unwrap_or(0); - let review_id = counter + 1; - - let review = PeerReview { - id: review_id, - reviewer: params.reviewer.clone(), - reviewee: params.reviewee.clone(), - content_type: params.content_type, - content_id: params.content_id, - rating: params.rating, - feedback: params.feedback, - criteria: params.criteria, - created_at: env.ledger().timestamp(), - is_helpful: false, - helpful_votes: 0, - }; - - // Store review - let mut reviews: Map = env - .storage() - .instance() - .get(&REVIEWS) - .unwrap_or(Map::new(&env)); - reviews.set(review_id, review); - env.storage().instance().set(&REVIEWS, &reviews); - - // Update user's reviews - let mut user_reviews: Vec = env - .storage() - .instance() - .get(&USER_REVIEWS) - .unwrap_or(Vec::new(&env)); - user_reviews.push_back(review_id); - env.storage().instance().set(&USER_REVIEWS, &user_reviews); - - // Update counter - env.storage().instance().set(&REVIEW_COUNTER, &review_id); - - Ok(review_id) - } - - pub fn get_review(env: &Env, review_id: u64) -> Result { - let reviews: Map = env - .storage() - .instance() - .get(&REVIEWS) - .ok_or(SocialLearningError::ReviewNotFound)?; - - reviews - .get(review_id) - .ok_or(SocialLearningError::ReviewNotFound) - } - - // Mentorship System - pub fn create_mentorship_profile( - env: &Env, - mentor: Address, - expertise_areas: Vec, - experience_level: ExperienceLevel, - availability: AvailabilityStatus, - hourly_rate: Option, - bio: Bytes, - languages: Vec, - timezone: Bytes, - ) -> Result<(), SocialLearningError> { - let profile = MentorshipProfile { - mentor: mentor.clone(), - expertise_areas, - experience_level, - availability, - hourly_rate, - bio, - rating: 0, - review_count: 0, - mentee_count: 0, - success_rate: 0, - languages, - timezone, - }; - - // Store profile - let mut profiles: Map = env - .storage() - .instance() - .get(&MENTORSHIP_PROFILES) - .unwrap_or(Map::new(&env)); - profiles.set(mentor, profile); - env.storage() - .instance() - .set(&MENTORSHIP_PROFILES, &profiles); - - Ok(()) - } - - pub fn get_mentorship_profile( - env: &Env, - mentor: Address, - ) -> Result { - let profiles: Map = env - .storage() - .instance() - .get(&MENTORSHIP_PROFILES) - .ok_or(SocialLearningError::MentorshipProfileNotFound)?; - - profiles - .get(mentor) - .ok_or(SocialLearningError::MentorshipProfileNotFound) - } - - // Social Analytics - pub fn get_user_analytics(env: &Env, user: Address) -> SocialAnalytics { - env.storage() - .instance() - .get(&SOCIAL_ANALYTICS) - .unwrap_or(SocialAnalytics { - user: user.clone(), - study_groups_joined: 0, - discussions_participated: 0, - posts_created: 0, - reviews_given: 0, - mentorship_hours: 0, - collaboration_projects: 0, - social_score: 0, - engagement_level: EngagementLevel::Low, - badges: Vec::new(&env), - last_updated: env.ledger().timestamp(), - }) - } - - pub fn update_user_analytics(env: &Env, user: Address, analytics: SocialAnalytics) -> SocialLearningResult<()> { - env.storage().instance().set(&SOCIAL_ANALYTICS, &analytics); - Ok(()) - } -} diff --git a/contracts/teachlink/src/tokenization.rs b/contracts/teachlink/src/tokenization.rs index 3b10dee6..25a87b96 100644 --- a/contracts/teachlink/src/tokenization.rs +++ b/contracts/teachlink/src/tokenization.rs @@ -300,8 +300,11 @@ impl ContentTokenization { if let Some(new_tags) = tags { // Batch size check for tags to prevent DoS - bulk_limits::check_batch_size_limit(new_tags.len(), bulk_limits::MAX_CONTENT_TAGS) - .expect("Too many tags"); + bulk_limits::check_batch_size_limit( + new_tags.len(), + bulk_limits::MAX_CONTENT_TAGS, + ) + .expect("Too many tags"); token.metadata.tags = new_tags; } diff --git a/contracts/tokenization/Cargo.toml b/contracts/tokenization/Cargo.toml deleted file mode 100644 index e69de29b..00000000 diff --git a/contracts/tokenization/src/lib.rs b/contracts/tokenization/src/lib.rs deleted file mode 100644 index d2630f0d..00000000 --- a/contracts/tokenization/src/lib.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -#[ink::contract] -mod content_nft { - use ink::storage::Mapping; - - #[derive(scale::Encode, scale::Decode, Clone, Debug, PartialEq, Eq)] - #[cfg_attr(feature = "std", derive(scale_info::TypeInfo))] - pub enum LicenseType { - Personal, - Commercial, - Exclusive, - } - - #[ink(storage)] - pub struct ContentNFT { - owner: Mapping, // tokenId → owner - metadata: Mapping, // tokenId → metadata URI - royalties: Mapping, // tokenId → royalty percentage - license: Mapping, // tokenId → license type - total_supply: u32, - } - - impl ContentNFT { - #[ink(constructor)] - pub fn new() -> Self { - Self { - owner: Mapping::default(), - metadata: Mapping::default(), - royalties: Mapping::default(), - license: Mapping::default(), - total_supply: 0, - } - } - - #[ink(message)] - pub fn mint(&mut self, to: AccountId, metadata_uri: String, royalty: u8, license: LicenseType) -> u32 { - self.total_supply += 1; - let token_id = self.total_supply; - self.owner.insert(token_id, &to); - self.metadata.insert(token_id, &metadata_uri); - self.royalties.insert(token_id, &royalty); - self.license.insert(token_id, &license); - token_id - } - - #[ink(message)] - pub fn get_metadata(&self, token_id: u32) -> Option { - self.metadata.get(token_id) - } - - #[ink(message)] - pub fn get_owner(&self, token_id: u32) -> Option { - self.owner.get(token_id) - } - } -} diff --git a/contracts/tokenization/src/royalties.rs b/contracts/tokenization/src/royalties.rs deleted file mode 100644 index d97b6f68..00000000 --- a/contracts/tokenization/src/royalties.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![cfg_attr(not(feature = "std"), no_std)] - -#[ink::contract] -mod royalty_manager { - use ink::storage::Mapping; - - #[ink(storage)] - pub struct RoyaltyManager { - shares: Mapping>, // tokenId → [(recipient, percentage)] - } - - impl RoyaltyManager { - #[ink(constructor)] - pub fn new() -> Self { - Self { - shares: Mapping::default(), - } - } - - #[ink(message)] - pub fn set_shares(&mut self, token_id: u32, recipients: Vec<(AccountId, u8)>) { - self.shares.insert(token_id, &recipients); - } - - #[ink(message)] - pub fn distribute(&self, token_id: u32, amount: u128) { - if let Some(recipients) = self.shares.get(token_id) { - for (recipient, pct) in recipients { - let payout = amount * pct as u128 / 100; - self.env().transfer(recipient, payout).unwrap(); - } - } - } - } -} diff --git a/testing/analytics/README.md b/testing/analytics/README.md deleted file mode 100644 index e0e74140..00000000 --- a/testing/analytics/README.md +++ /dev/null @@ -1,222 +0,0 @@ -# Test Analytics and Coverage Reporting - -## Overview - -Comprehensive analytics and reporting for test execution, coverage, and quality metrics. - -## Features - -- **Code Coverage**: Line, branch, and function coverage -- **Test Execution Analytics**: Success rates, duration, trends -- **Quality Metrics**: Code quality and test quality scores -- **Trend Analysis**: Historical performance tracking -- **Compliance Reporting**: Standards and requirements tracking - -## Coverage Analysis - -### Running Coverage - -```bash -# Generate coverage report -cargo tarpaulin --out Html --output-dir testing/analytics/reports/coverage - -# Coverage with specific tests -cargo tarpaulin --test test_bridge --out Html - -# Coverage for specific package -cargo tarpaulin --package teachlink-contract --out Html -``` - -### Coverage Metrics - -- **Line Coverage**: Percentage of code lines executed -- **Branch Coverage**: Percentage of branches taken -- **Function Coverage**: Percentage of functions called -- **Region Coverage**: Percentage of code regions covered - -### Coverage Targets - -| Component | Target | Current | -|-----------|--------|---------| -| Bridge | 90% | TBD | -| Escrow | 90% | TBD | -| Rewards | 85% | TBD | -| Governance | 85% | TBD | -| Insurance | 85% | TBD | -| Overall | 85% | TBD | - -## Test Execution Analytics - -### Metrics Tracked - -```rust -pub struct TestMetrics { - pub total_tests: usize, - pub passed: usize, - pub failed: usize, - pub skipped: usize, - pub duration_ms: u64, - pub success_rate: f64, -} -``` - -### Execution Reports - -```bash -# Generate execution report -./testing/analytics/scripts/execution-report.sh - -# View test trends -./testing/analytics/scripts/trend-analysis.sh - -# Compare test runs -./testing/analytics/scripts/compare-runs.sh run1.json run2.json -``` - -## Quality Metrics - -### Code Quality - -- **Cyclomatic Complexity**: Measure code complexity -- **Maintainability Index**: Code maintainability score -- **Technical Debt**: Estimated refactoring effort -- **Code Smells**: Potential issues detected - -### Test Quality - -- **Test Coverage**: Percentage of code tested -- **Assertion Density**: Assertions per test -- **Test Independence**: Tests don't depend on each other -- **Test Speed**: Average test execution time - -### Quality Score - -``` -Quality Score = (Coverage * 0.4) + - (Success Rate * 0.3) + - (Maintainability * 0.2) + - (Performance * 0.1) -``` - -## Dashboards - -### Coverage Dashboard - -```bash -# Start coverage dashboard -./testing/analytics/scripts/dashboard.sh - -# Access at http://localhost:8080 -``` - -Features: -- Real-time coverage metrics -- Historical trends -- File-level coverage details -- Uncovered code highlighting - -### Test Dashboard - -Features: -- Test execution status -- Failure analysis -- Duration trends -- Flaky test detection - -## Reports - -### HTML Reports - -Generated in `testing/analytics/reports/`: -- `coverage.html`: Interactive coverage report -- `test_results.html`: Test execution results -- `quality_metrics.html`: Quality dashboard -- `trends.html`: Historical trends - -### JSON Reports - -Machine-readable reports: -- `coverage.json`: Coverage data -- `test_results.json`: Test execution data -- `metrics.json`: Quality metrics -- `trends.json`: Historical data - -### PDF Reports - -Executive summaries: -- `test_summary.pdf`: High-level overview -- `quality_report.pdf`: Quality assessment -- `compliance_report.pdf`: Standards compliance - -## Trend Analysis - -### Historical Tracking - -```rust -pub struct TrendData { - pub timestamp: u64, - pub coverage: f64, - pub success_rate: f64, - pub test_count: usize, - pub duration_ms: u64, -} -``` - -### Trend Visualization - -```bash -# Generate trend charts -./testing/analytics/scripts/generate-charts.sh - -# View trends -./testing/analytics/scripts/view-trends.sh -``` - -Charts generated: -- Coverage over time -- Success rate trends -- Test count growth -- Execution duration trends - -## Compliance Reporting - -### Standards Tracked - -- **Test Coverage**: Minimum coverage requirements -- **Code Quality**: Quality gate thresholds -- **Security**: Security test requirements -- **Performance**: Performance benchmarks - -### Compliance Checks - -```bash -# Check compliance -./testing/analytics/scripts/compliance-check.sh - -# Generate compliance report -./testing/analytics/scripts/compliance-report.sh -``` - -### Compliance Matrix - -| Requirement | Target | Status | Evidence | -|-------------|--------|--------|----------| -| Unit Test Coverage | 85% | ✅ Pass | coverage.html | -| Integration Tests | 100% | ✅ Pass | test_results.json | -| Security Tests | All | ✅ Pass | security_scan.json | -| Performance Tests | All | ✅ Pass | benchmark_results.json | - -## Integration - -### CI/CD Integration - -```yaml -# .github/workflows/test-analytics.yml -- name: Generate Coverage - run: cargo tarpaulin --out Json - -- name: Upload to Analytics - run: ./testing/analytics/scripts/upload.sh - -- name: Check Quality Gates - run: ./te \ No newline at end of file diff --git a/testing/analytics/coverage_analyzer.rs b/testing/analytics/coverage_analyzer.rs deleted file mode 100644 index c373adc3..00000000 --- a/testing/analytics/coverage_analyzer.rs +++ /dev/null @@ -1,129 +0,0 @@ -/// Code coverage analyzer -use std::collections::{HashMap, HashSet}; -use std::fs; -use std::path::Path; - -#[derive(Debug, Clone)] -pub struct CoverageReport { - pub total_lines: usize, - pub covered_lines: usize, - pub total_functions: usize, - pub covered_functions: usize, - pub coverage_percentage: f64, - pub file_coverage: HashMap, -} - -#[derive(Debug, Clone)] -pub struct FileCoverage { - pub path: String, - pub total_lines: usize, - pub covered_lines: usize, - pub uncovered_lines: Vec, - pub coverage_percentage: f64, -} - -pub struct CoverageAnalyzer { - covered_lines: HashMap>, - total_lines: HashMap, -} - -impl CoverageAnalyzer { - pub fn new() -> Self { - Self { - covered_lines: HashMap::new(), - total_lines: HashMap::new(), - } - } - - pub fn mark_line_covered(&mut self, file: &str, line: usize) { - self.covered_lines - .entry(file.to_string()) - .or_insert_with(HashSet::new) - .insert(line); - } - - pub fn analyze_file(&mut self, file_path: &Path) -> Result<(), String> { - let content = fs::read_to_string(file_path) - .map_err(|e| format!("Failed to read file: {}", e))?; - - let executable_lines = self.count_executable_lines(&content); - self.total_lines.insert( - file_path.to_string_lossy().to_string(), - executable_lines, - ); - - Ok(()) - } - - fn count_executable_lines(&self, content: &str) -> usize { - content - .lines() - .filter(|line| { - let trimmed = line.trim(); - !trimmed.is_empty() - && !trimmed.starts_with("//") - && !trimmed.starts_with("/*") - && !trimmed.starts_with('*') - && !trimmed.starts_with('}') - && !trimmed.starts_with('{') - }) - .count() - } - - pub fn generate_report(&self) -> CoverageReport { - let mut file_coverage = HashMap::new(); - let mut total_lines = 0; - let mut covered_lines = 0; - - for (file, &total) in &self.total_lines { - let covered = self.covered_lines - .get(file) - .map(|set| set.len()) - .unwrap_or(0); - - let uncovered: Vec = (1..=total) - .filter(|line| { - !self.covered_lines - .get(file) - .map(|set| set.contains(line)) - .unwrap_or(false) - }) - .collect(); - - let coverage_pct = if total > 0 { - (covered as f64 / total as f64) * 100.0 - } else { - 0.0 - }; - - file_coverage.insert( - file.clone(), - FileCoverage { - path: file.clone(), - total_lines: total, - covered_lines: covered, - uncovered_lines: uncovered, - coverage_percentage: coverage_pct, - }, - ); - - total_lines += total; - covered_lines += covered; - } - - let coverage_percentage = if total_lines > 0 { - (covered_lines as f64 / total_lines as f64) * 100.0 - } else { - 0.0 - }; - - CoverageReport { - total_lines, - covered_lines, - total_functions: 0, - covered_functions: 0, - coverage_percentage, - file_coverage, - } - } -} diff --git a/testing/performance/benchmark_runner.rs b/testing/performance/benchmark_runner.rs deleted file mode 100644 index f1fd0aa4..00000000 --- a/testing/performance/benchmark_runner.rs +++ /dev/null @@ -1,350 +0,0 @@ -use std::collections::HashMap; -/// Performance benchmark runner with gas tracking support -use std::time::{Duration, Instant}; - -#[derive(Debug, Clone)] -pub struct BenchmarkResult { - pub name: String, - pub iterations: u64, - pub total_duration: Duration, - pub avg_duration: Duration, - pub min_duration: Duration, - pub max_duration: Duration, - pub p50: Duration, - pub p95: Duration, - pub p99: Duration, -} - -#[derive(Debug, Clone)] -pub struct GasBenchmarkResult { - pub name: String, - pub gas_used: u64, - pub threshold: u64, - pub within_threshold: bool, -} - -pub struct BenchmarkRunner { - results: HashMap, - gas_results: HashMap, - warmup_iterations: u64, - test_iterations: u64, -} - -impl BenchmarkRunner { - pub fn new(warmup_iterations: u64, test_iterations: u64) -> Self { - Self { - results: HashMap::new(), - gas_results: HashMap::new(), - warmup_iterations, - test_iterations, - } - } - - pub fn benchmark(&mut self, name: &str, mut f: F) - where - F: FnMut(), - { - // Warmup - for _ in 0..self.warmup_iterations { - f(); - } - - // Actual benchmark - let mut durations = Vec::with_capacity(self.test_iterations as usize); - - for _ in 0..self.test_iterations { - let start = Instant::now(); - f(); - let duration = start.elapsed(); - durations.push(duration); - } - - // Calculate statistics - durations.sort(); - let total: Duration = durations.iter().sum(); - let avg = total / self.test_iterations as u32; - let min = *durations.first().unwrap(); - let max = *durations.last().unwrap(); - - let p50_idx = (self.test_iterations as f64 * 0.50) as usize; - let p95_idx = (self.test_iterations as f64 * 0.95) as usize; - let p99_idx = (self.test_iterations as f64 * 0.99) as usize; - - let result = BenchmarkResult { - name: name.to_string(), - iterations: self.test_iterations, - total_duration: total, - avg_duration: avg, - min_duration: min, - max_duration: max, - p50: durations[p50_idx], - p95: durations[p95_idx], - p99: durations[p99_idx], - }; - - self.results.insert(name.to_string(), result); - } - - /// Record a gas measurement for a contract operation. - pub fn record_gas(&mut self, name: &str, gas_used: u64, threshold: u64) { - let result = GasBenchmarkResult { - name: name.to_string(), - gas_used, - threshold, - within_threshold: gas_used <= threshold, - }; - self.gas_results.insert(name.to_string(), result); - } - - /// Get a gas benchmark result by name. - pub fn get_gas_result(&self, name: &str) -> Option<&GasBenchmarkResult> { - self.gas_results.get(name) - } - - /// Check if all gas benchmarks are within thresholds. - pub fn all_gas_within_thresholds(&self) -> bool { - self.gas_results.values().all(|r| r.within_threshold) - } - - /// Get all gas regressions (operations exceeding thresholds). - pub fn get_gas_regressions(&self) -> Vec<&GasBenchmarkResult> { - self.gas_results - .values() - .filter(|r| !r.within_threshold) - .collect() - } - - pub fn get_result(&self, name: &str) -> Option<&BenchmarkResult> { - self.results.get(name) - } - - pub fn print_results(&self) { - println!("\n=== Benchmark Results ===\n"); - - for (name, result) in &self.results { - println!("Benchmark: {}", name); - println!(" Iterations: {}", result.iterations); - println!(" Average: {:?}", result.avg_duration); - println!(" Min: {:?}", result.min_duration); - println!(" Max: {:?}", result.max_duration); - println!(" P50: {:?}", result.p50); - println!(" P95: {:?}", result.p95); - println!(" P99: {:?}", result.p99); - println!(); - } - } - - pub fn print_gas_results(&self) { - println!("\n=== Gas Benchmark Results ===\n"); - println!( - " {:<35} | {:>12} | {:>12} | {}", - "Operation", "Gas Used", "Threshold", "Status" - ); - println!(" {:->35}-+-{:->12}-+-{:->12}-+{:->8}", "", "", "", ""); - - for (name, result) in &self.gas_results { - let status = if result.within_threshold { - "PASS" - } else { - "FAIL" - }; - println!( - " {:<35} | {:>12} | {:>12} | {}", - name, result.gas_used, result.threshold, status - ); - } - println!(); - } - - pub fn compare_with_baseline(&self, baseline: &BenchmarkRunner) { - println!("\n=== Comparison with Baseline ===\n"); - - for (name, current) in &self.results { - if let Some(baseline_result) = baseline.get_result(name) { - let diff_pct = ((current.avg_duration.as_nanos() as f64 - - baseline_result.avg_duration.as_nanos() as f64) - / baseline_result.avg_duration.as_nanos() as f64) - * 100.0; - - let status = if diff_pct > 5.0 { - "SLOWER" - } else if diff_pct < -5.0 { - "FASTER" - } else { - "SIMILAR" - }; - - println!("{} {}: {:.2}%", status, name, diff_pct); - } - } - } - - /// Compare gas results with a baseline runner. - pub fn compare_gas_with_baseline(&self, baseline: &BenchmarkRunner) { - println!("\n=== Gas Comparison with Baseline ===\n"); - - for (name, current) in &self.gas_results { - if let Some(baseline_result) = baseline.get_gas_result(name) { - if baseline_result.gas_used > 0 { - let diff_pct = ((current.gas_used as f64 - baseline_result.gas_used as f64) - / baseline_result.gas_used as f64) - * 100.0; - - let status = if diff_pct > 10.0 { - "REGRESSION" - } else if diff_pct > 5.0 { - "WARNING" - } else if diff_pct < -5.0 { - "IMPROVED" - } else { - "STABLE" - }; - - println!( - " {} {}: {} -> {} ({:+.1}%)", - status, name, baseline_result.gas_used, current.gas_used, diff_pct - ); - } - } - } - } - - pub fn export_json(&self) -> String { - let mut json = String::from("{\n"); - json.push_str(" \"timing_benchmarks\": [\n"); - - for (i, (name, result)) in self.results.iter().enumerate() { - json.push_str(" {\n"); - json.push_str(&format!(" \"name\": \"{}\",\n", name)); - json.push_str(&format!(" \"iterations\": {},\n", result.iterations)); - json.push_str(&format!( - " \"avg_ns\": {},\n", - result.avg_duration.as_nanos() - )); - json.push_str(&format!( - " \"min_ns\": {},\n", - result.min_duration.as_nanos() - )); - json.push_str(&format!( - " \"max_ns\": {},\n", - result.max_duration.as_nanos() - )); - json.push_str(&format!(" \"p50_ns\": {},\n", result.p50.as_nanos())); - json.push_str(&format!(" \"p95_ns\": {},\n", result.p95.as_nanos())); - json.push_str(&format!(" \"p99_ns\": {}\n", result.p99.as_nanos())); - json.push_str(" }"); - - if i < self.results.len() - 1 { - json.push_str(","); - } - json.push_str("\n"); - } - - json.push_str(" ],\n"); - json.push_str(" \"gas_benchmarks\": [\n"); - - let gas_items: Vec<_> = self.gas_results.iter().collect(); - for (i, (name, result)) in gas_items.iter().enumerate() { - json.push_str(" {\n"); - json.push_str(&format!(" \"name\": \"{}\",\n", name)); - json.push_str(&format!(" \"gas_used\": {},\n", result.gas_used)); - json.push_str(&format!(" \"threshold\": {},\n", result.threshold)); - json.push_str(&format!( - " \"within_threshold\": {}\n", - result.within_threshold - )); - json.push_str(" }"); - - if i < gas_items.len() - 1 { - json.push_str(","); - } - json.push_str("\n"); - } - - json.push_str(" ]\n"); - json.push_str("}\n"); - json - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::thread; - - #[test] - fn test_benchmark_runner() { - let mut runner = BenchmarkRunner::new(10, 100); - - runner.benchmark("sleep_1ms", || { - thread::sleep(Duration::from_micros(100)); - }); - - let result = runner.get_result("sleep_1ms").unwrap(); - assert_eq!(result.iterations, 100); - assert!(result.avg_duration.as_micros() >= 100); - } - - #[test] - fn test_multiple_benchmarks() { - let mut runner = BenchmarkRunner::new(5, 50); - - runner.benchmark("fast", || { - let _ = 1 + 1; - }); - - runner.benchmark("slow", || { - thread::sleep(Duration::from_micros(10)); - }); - - assert!(runner.results.len() == 2); - } - - #[test] - fn test_gas_tracking() { - let mut runner = BenchmarkRunner::new(0, 0); - - runner.record_gas("initialize", 350_000, 500_000); - runner.record_gas("bridge_out", 900_000, 800_000); - runner.record_gas("read_query", 50_000, 100_000); - - assert!( - runner - .get_gas_result("initialize") - .unwrap() - .within_threshold - ); - assert!( - !runner - .get_gas_result("bridge_out") - .unwrap() - .within_threshold - ); - assert!( - runner - .get_gas_result("read_query") - .unwrap() - .within_threshold - ); - - assert!(!runner.all_gas_within_thresholds()); - assert_eq!(runner.get_gas_regressions().len(), 1); - } - - #[test] - fn test_gas_comparison() { - let mut baseline = BenchmarkRunner::new(0, 0); - baseline.record_gas("op1", 1000, 2000); - baseline.record_gas("op2", 500, 1000); - - let mut current = BenchmarkRunner::new(0, 0); - current.record_gas("op1", 1100, 2000); // 10% increase - current.record_gas("op2", 450, 1000); // 10% decrease - - // op1 should show as warning (10% > 5%) - // op2 should show as improved (-10% < -5%) - // Just verify they exist - assert!(current.get_gas_result("op1").is_some()); - assert!(current.get_gas_result("op2").is_some()); - } -} diff --git a/testing/quality/complexity_analyzer.rs b/testing/quality/complexity_analyzer.rs deleted file mode 100644 index 5ca6fef9..00000000 --- a/testing/quality/complexity_analyzer.rs +++ /dev/null @@ -1,41 +0,0 @@ -use std::path::Path; -use rust_code_analysis::{ParserTrait, RustParser}; -use serde::{Serialize, Deserialize}; - -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct ComplexityMetrics { - pub cyclomatic_complexity: f64, - pub cognitive_complexity: f64, - pub loc: usize, - pub sloc: usize, -} - -pub struct ComplexityAnalyzer; - -impl ComplexityAnalyzer { - pub fn analyze_path>(path: P) -> ComplexityMetrics { - let path = path.as_ref(); - let source = std::fs::read(path).unwrap_or_default(); - let parser = RustParser::default(); - - // This is a simplified version as rust-code-analysis API can be complex - // In a real implementation, we would use the structural analysis - - ComplexityMetrics { - cyclomatic_complexity: 5.0, // Placeholder for actual analysis - cognitive_complexity: 3.0, // Placeholder for actual analysis - loc: source.len() / 40, // Rough estimation - sloc: source.len() / 50, // Rough estimation - } - } - - pub fn analyze_workspace() -> ComplexityMetrics { - // Logic to iterate over all .rs files in contracts/ - ComplexityMetrics { - cyclomatic_complexity: 12.5, - cognitive_complexity: 8.2, - loc: 2500, - sloc: 1800, - } - } -} diff --git a/testing/quality/metrics_collector.rs b/testing/quality/metrics_collector.rs deleted file mode 100644 index e892c2a3..00000000 --- a/testing/quality/metrics_collector.rs +++ /dev/null @@ -1,83 +0,0 @@ -/// Quality metrics collector -use std::collections::HashMap; - -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] -pub struct QualityMetrics { - pub test_count: usize, - pub passing_tests: usize, - pub failing_tests: usize, - pub code_coverage: f64, - pub complexity_score: f64, - pub cognitive_complexity: f64, - pub duplication_percentage: f64, - pub security_score: f64, - pub loc: usize, -} - -pub struct MetricsCollector { - metrics: HashMap, -} - -impl MetricsCollector { - pub fn new() -> Self { - Self { - metrics: HashMap::new(), - } - } - - pub fn record_metrics(&mut self, module: &str, metrics: QualityMetrics) { - self.metrics.insert(module.to_string(), metrics); - } - - pub fn load_from_reports(&mut self, reports_dir: &str) -> Result<(), Box> { - // Logic to parse reports/coverage.json, reports/duplication.json, etc. - // For now, we simulate the aggregation - Ok(()) - } - - pub fn get_overall_score(&self) -> f64 { - if self.metrics.is_empty() { - return 0.0; - } - - let total: f64 = self.metrics.values() - .map(|m| { - let test_score = if m.test_count > 0 { - (m.passing_tests as f64 / m.test_count as f64) * 100.0 - } else { - 0.0 - }; - - let duplication_penalty = m.duplication_percentage * 2.0; - let complexity_penalty = (m.complexity_score - 10.0).max(0.0) * 0.5; - - let base_score = (test_score + m.code_coverage + m.security_score) / 3.0; - (base_score - duplication_penalty - complexity_penalty).max(0.0) - }) - .sum(); - - total / self.metrics.len() as f64 - } - - pub fn generate_report(&self) -> String { - let mut report = String::from("# Comprehensive Quality Metrics Report\n\n"); - report.push_str(&format!("Generated at: {}\n\n", chrono::Utc::now().to_rfc3339())); - - report.push_str("| Module | Tests | Coverage | Complexity | Duplication | Score |\n"); - report.push_str("|--------|-------|----------|------------|-------------|-------|\n"); - - for (module, metrics) in &self.metrics { - let score = (metrics.passing_tests as f64 / metrics.test_count.max(1) as f64 * 40.0) + - (metrics.code_coverage * 0.4) + - (metrics.security_score * 0.2); - - report.push_str(&format!("| {} | {}/{} | {:.2}% | {:.2} | {:.2}% | {:.2}% |\n", - module, metrics.passing_tests, metrics.test_count, - metrics.code_coverage, metrics.complexity_score, - metrics.duplication_percentage, score)); - } - - report.push_str(&format!("\n**Overall Quality Score: {:.2}%**\n", self.get_overall_score())); - report - } -} diff --git a/testing/security/vulnerability_scanner.rs b/testing/security/vulnerability_scanner.rs deleted file mode 100644 index ef1b1633..00000000 --- a/testing/security/vulnerability_scanner.rs +++ /dev/null @@ -1,240 +0,0 @@ -/// Security vulnerability scanner for smart contracts -use std::collections::HashMap; -use std::fs; -use std::path::Path; - -#[derive(Debug, Clone)] -pub enum VulnerabilityType { - ReentrancyRisk, - IntegerOverflow, - UnauthorizedAccess, - UncheckedReturn, - TimestampDependence, - GasLimitIssue, -} - -#[derive(Debug)] -pub struct Vulnerability { - pub vuln_type: VulnerabilityType, - pub severity: Severity, - pub location: String, - pub description: String, - pub recommendation: String, -} - -#[derive(Debug, Clone, PartialEq)] -pub enum Severity { - Critical, - High, - Medium, - Low, -} - -pub struct VulnerabilityScanner { - vulnerabilities: Vec, - patterns: HashMap>, -} - -impl VulnerabilityScanner { - pub fn new() -> Self { - let mut patterns = HashMap::new(); - - // Reentrancy patterns - patterns.insert( - VulnerabilityType::ReentrancyRisk, - vec![ - "transfer.*require".to_string(), - "call.*balance".to_string(), - ], - ); - - // Integer overflow patterns - patterns.insert( - VulnerabilityType::IntegerOverflow, - vec![ - r"\+.*without.*check".to_string(), - r"\*.*without.*check".to_string(), - ], - ); - - // Unauthorized access patterns - patterns.insert( - VulnerabilityType::UnauthorizedAccess, - vec![ - "pub fn.*without.*auth".to_string(), - "fn.*no.*require_auth".to_string(), - ], - ); - - Self { - vulnerabilities: Vec::new(), - patterns, - } - } - - pub fn scan_file(&mut self, file_path: &Path) -> Result<(), String> { - let content = fs::read_to_string(file_path) - .map_err(|e| format!("Failed to read file: {}", e))?; - - self.check_reentrancy(&content, file_path); - self.check_integer_overflow(&content, file_path); - self.check_access_control(&content, file_path); - self.check_unchecked_returns(&content, file_path); - self.check_timestamp_dependence(&content, file_path); - - Ok(()) - } - - fn check_reentrancy(&mut self, content: &str, file_path: &Path) { - for (line_num, line) in content.lines().enumerate() { - if line.contains("transfer") && !line.contains("// safe") { - if self.has_state_change_after_transfer(content, line_num) { - self.vulnerabilities.push(Vulnerability { - vuln_type: VulnerabilityType::ReentrancyRisk, - severity: Severity::Critical, - location: format!("{}:{}", file_path.display(), line_num + 1), - description: "Potential reentrancy vulnerability: state changes after external call".to_string(), - recommendation: "Follow checks-effects-interactions pattern".to_string(), - }); - } - } - } - } - - fn has_state_change_after_transfer(&self, content: &str, transfer_line: usize) -> bool { - let lines: Vec<&str> = content.lines().collect(); - for i in (transfer_line + 1)..lines.len().min(transfer_line + 10) { - if lines[i].contains("set(") || lines[i].contains("storage.") { - return true; - } - } - false - } - - fn check_integer_overflow(&mut self, content: &str, file_path: &Path) { - for (line_num, line) in content.lines().enumerate() { - if (line.contains(" + ") || line.contains(" * ")) - && !line.contains("checked_add") - && !line.contains("checked_mul") - && line.contains("i128") { - self.vulnerabilities.push(Vulnerability { - vuln_type: VulnerabilityType::IntegerOverflow, - severity: Severity::High, - location: format!("{}:{}", file_path.display(), line_num + 1), - description: "Potential integer overflow without checked arithmetic".to_string(), - recommendation: "Use checked_add, checked_mul, or saturating operations".to_string(), - }); - } - } - } - - fn check_access_control(&mut self, content: &str, file_path: &Path) { - for (line_num, line) in content.lines().enumerate() { - if line.trim().starts_with("pub fn") - && !line.contains("view") - && !self.has_auth_check(content, line_num) { - self.vulnerabilities.push(Vulnerability { - vuln_type: VulnerabilityType::UnauthorizedAccess, - severity: Severity::High, - location: format!("{}:{}", file_path.display(), line_num + 1), - description: "Public function without authorization check".to_string(), - recommendation: "Add require_auth or access control validation".to_string(), - }); - } - } - } - - fn has_auth_check(&self, content: &str, fn_line: usize) -> bool { - let lines: Vec<&str> = content.lines().collect(); - for i in fn_line..(fn_line + 15).min(lines.len()) { - if lines[i].contains("require_auth") || lines[i].contains("check_admin") { - return true; - } - if lines[i].trim().starts_with("fn ") || lines[i].trim().starts_with("pub fn") { - break; - } - } - false - } - - fn check_unchecked_returns(&mut self, content: &str, file_path: &Path) { - for (line_num, line) in content.lines().enumerate() { - if line.contains(".call(") && !line.contains("?") && !line.contains("unwrap") { - self.vulnerabilities.push(Vulnerability { - vuln_type: VulnerabilityType::UncheckedReturn, - severity: Severity::Medium, - location: format!("{}:{}", file_path.display(), line_num + 1), - description: "Unchecked return value from external call".to_string(), - recommendation: "Check return value or use ? operator".to_string(), - }); - } - } - } - - fn check_timestamp_dependence(&mut self, content: &str, file_path: &Path) { - for (line_num, line) in content.lines().enumerate() { - if line.contains("timestamp()") && (line.contains("==") || line.contains("<") || line.contains(">")) { - self.vulnerabilities.push(Vulnerability { - vuln_type: VulnerabilityType::TimestampDependence, - severity: Severity::Low, - location: format!("{}:{}", file_path.display(), line_num + 1), - description: "Logic depends on exact timestamp value".to_string(), - recommendation: "Use time ranges instead of exact comparisons".to_string(), - }); - } - } - } - - pub fn get_vulnerabilities(&self) -> &[Vulnerability] { - &self.vulnerabilities - } - - pub fn get_critical_count(&self) -> usize { - self.vulnerabilities.iter() - .filter(|v| v.severity == Severity::Critical) - .count() - } - - pub fn get_high_count(&self) -> usize { - self.vulnerabilities.iter() - .filter(|v| v.severity == Severity::High) - .count() - } - - pub fn generate_report(&self) -> String { - let mut report = String::from("# Security Vulnerability Report\n\n"); - - report.push_str(&format!("Total vulnerabilities: {}\n", self.vulnerabilities.len())); - report.push_str(&format!("Critical: {}\n", self.get_critical_count())); - report.push_str(&format!("High: {}\n", self.get_high_count())); - report.push_str("\n## Findings\n\n"); - - for vuln in &self.vulnerabilities { - report.push_str(&format!("### {:?} - {:?}\n", vuln.vuln_type, vuln.severity)); - report.push_str(&format!("Location: {}\n", vuln.location)); - report.push_str(&format!("Description: {}\n", vuln.description)); - report.push_str(&format!("Recommendation: {}\n\n", vuln.recommendation)); - } - - report - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_scanner_creation() { - let scanner = VulnerabilityScanner::new(); - assert_eq!(scanner.vulnerabilities.len(), 0); - } - - #[test] - fn test_integer_overflow_detection() { - let mut scanner = VulnerabilityScanner::new(); - let code = "let result: i128 = a + b;"; - scanner.check_integer_overflow(code, Path::new("test.rs")); - assert!(scanner.get_vulnerabilities().len() > 0); - } -}