diff --git a/nac-udm/src/l1_protocol/acc/acc_collateral.rs b/nac-udm/src/l1_protocol/acc/acc_collateral.rs index dcedb60..0bbf927 100644 --- a/nac-udm/src/l1_protocol/acc/acc_collateral.rs +++ b/nac-udm/src/l1_protocol/acc/acc_collateral.rs @@ -1,62 +1,179 @@ -//! ACC协议模块 +//! ACC-Collateral: 抵押协议 +//! UID: nac.acc.ACCCollateralProtocol.v1 -///! # ACC-Collateral: 抵押协议 use crate::primitives::{Address, Hash, Timestamp}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// CollateralPosition -pub struct CollateralPosition { - /// position_id - pub position_id: Hash, - /// borrower - pub borrower: Address, - /// lender - pub lender: Address, - /// collateral_asset - pub collateral_asset: Hash, - /// collateral_amount - pub collateral_amount: u128, - /// loan_amount - pub loan_amount: u128, - /// ltv_ratio - pub ltv_ratio: u8, - /// liquidation_threshold - pub liquidation_threshold: u8, - /// start_date - pub start_date: Timestamp, - /// maturity_date - pub maturity_date: Timestamp, - /// status - pub status: CollateralStatus, +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ACCCollateralError { + CollateralNotFound(Hash), + InsufficientCollateralRatio { required: u32, actual: u32 }, + CollateralAlreadyLiquidated(Hash), + CollateralFrozen(Hash), + InvalidConstitutionalReceipt, + Unauthorized(Address), + LiquidationThresholdNotReached, } - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// CollateralStatus -pub enum CollateralStatus { - /// Active - Active, - /// Liquidated - Liquidated, - /// Closed - Closed, -} - -impl CollateralPosition { - /// new - pub fn new(borrower: Address, lender: Address, collateral_asset: Hash, collateral_amount: u128, loan_amount: u128) -> Self { - Self { - position_id: Hash::zero(), - borrower, - lender, - collateral_asset, - collateral_amount, - loan_amount, - ltv_ratio: 75, - liquidation_threshold: 85, - start_date: Timestamp::now(), - maturity_date: Timestamp::now().add_secs(365 * 24 * 3600), - status: CollateralStatus::Active, +impl std::fmt::Display for ACCCollateralError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::CollateralNotFound(h) => write!(f, "抵押记录不存在: {}", h.to_hex()), + Self::InsufficientCollateralRatio { required, actual } => write!(f, "抵押率不足: 要求 {},实际 {}", required, actual), + Self::CollateralAlreadyLiquidated(h) => write!(f, "抵押已被清算: {}", h.to_hex()), + Self::CollateralFrozen(h) => write!(f, "抵押已冻结: {}", h.to_hex()), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + Self::LiquidationThresholdNotReached => write!(f, "未达到清算阈值"), } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum CollateralStatus { Active, Frozen, Liquidating, Liquidated, Released } + +/// 抵押记录 +/// UID: nac.acc.CollateralRecord.v1 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CollateralRecord { + pub collateral_id: Hash, + pub asset_id: Hash, + pub borrower: Address, + pub lender: Address, + /// 抵押价值(XTZH) + pub collateral_value_xtzh: u128, + /// 贷款金额(XTZH) + pub loan_amount_xtzh: u128, + /// 抵押率(基点,10000=100%) + pub collateral_ratio_bps: u32, + /// 清算阈值(基点) + pub liquidation_threshold_bps: u32, + pub status: CollateralStatus, + pub maturity_time: Timestamp, + pub constitutional_receipt: Hash, + pub created_at: Timestamp, + pub updated_at: Timestamp, +} +impl CollateralRecord { + pub fn current_ratio_bps(&self, current_value: u128) -> u32 { + if self.loan_amount_xtzh == 0 { return u32::MAX; } + ((current_value as u64 * 10000) / self.loan_amount_xtzh as u64) as u32 + } + pub fn needs_liquidation(&self, current_value: u128) -> bool { + self.current_ratio_bps(current_value) < self.liquidation_threshold_bps + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum CollateralProtocolEvent { + CollateralCreated { collateral_id: Hash, asset_id: Hash, borrower: Address, loan_amount: u128, timestamp: Timestamp }, + CollateralLiquidated { collateral_id: Hash, liquidator: Address, recovered_amount: u128, timestamp: Timestamp, constitutional_receipt: Hash }, + CollateralReleased { collateral_id: Hash, timestamp: Timestamp }, + CollateralValueUpdated { collateral_id: Hash, old_value: u128, new_value: u128, timestamp: Timestamp }, +} + +/// ACC-Collateral 抵押协议 +/// UID: nac.acc.ACCCollateralProtocol.v1 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ACCCollateralProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub collaterals: HashMap, + /// 最低抵押率(基点,默认15000=150%) + pub min_collateral_ratio_bps: u32, + /// 清算阈值(基点,默认12000=120%) + pub liquidation_threshold_bps: u32, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, +} +impl ACCCollateralProtocol { + pub fn new(min_collateral_ratio_bps: u32, liquidation_threshold_bps: u32) -> Self { + Self { + protocol_uid: "nac.acc.ACCCollateralProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Collateral".to_string(), + collaterals: HashMap::new(), + min_collateral_ratio_bps, + liquidation_threshold_bps, + pending_events: Vec::new(), + created_at: Timestamp::now(), + updated_at: Timestamp::now(), + } + } + pub fn create_collateral( + &mut self, asset_id: Hash, borrower: Address, lender: Address, + collateral_value_xtzh: u128, loan_amount_xtzh: u128, maturity_secs: u64, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if constitutional_receipt.is_zero() { + return Err(ACCCollateralError::InvalidConstitutionalReceipt); + } + let ratio_bps = if loan_amount_xtzh > 0 { + ((collateral_value_xtzh as u64 * 10000) / loan_amount_xtzh as u64) as u32 + } else { u32::MAX }; + if ratio_bps < self.min_collateral_ratio_bps { + return Err(ACCCollateralError::InsufficientCollateralRatio { + required: self.min_collateral_ratio_bps, actual: ratio_bps, + }); + } + let mut data = Vec::new(); + data.extend_from_slice(asset_id.as_bytes()); + data.extend_from_slice(borrower.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let collateral_id = Hash::sha3_384(&data); + let record = CollateralRecord { + collateral_id, asset_id, borrower: borrower.clone(), lender, + collateral_value_xtzh, loan_amount_xtzh, + collateral_ratio_bps: ratio_bps, + liquidation_threshold_bps: self.liquidation_threshold_bps, + status: CollateralStatus::Active, + maturity_time: timestamp.add_secs(maturity_secs), + constitutional_receipt, + created_at: timestamp.clone(), updated_at: timestamp.clone(), + }; + self.collaterals.insert(collateral_id, record); + self.pending_events.push(CollateralProtocolEvent::CollateralCreated { + collateral_id, asset_id, borrower, loan_amount: loan_amount_xtzh, timestamp, + }); + self.updated_at = Timestamp::now(); + Ok(collateral_id) + } + pub fn liquidate( + &mut self, collateral_id: Hash, liquidator: Address, current_value: u128, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if constitutional_receipt.is_zero() { + return Err(ACCCollateralError::InvalidConstitutionalReceipt); + } + let record = self.collaterals.get_mut(&collateral_id) + .ok_or(ACCCollateralError::CollateralNotFound(collateral_id))?; + if record.status == CollateralStatus::Liquidated { + return Err(ACCCollateralError::CollateralAlreadyLiquidated(collateral_id)); + } + if !record.needs_liquidation(current_value) { + return Err(ACCCollateralError::LiquidationThresholdNotReached); + } + let recovered = current_value.min(record.loan_amount_xtzh); + record.status = CollateralStatus::Liquidated; + record.updated_at = timestamp.clone(); + self.pending_events.push(CollateralProtocolEvent::CollateralLiquidated { + collateral_id, liquidator, recovered_amount: recovered, timestamp, constitutional_receipt, + }); + Ok(recovered) + } + pub fn release_collateral( + &mut self, collateral_id: Hash, initiator: Address, timestamp: Timestamp, + ) -> Result<(), ACCCollateralError> { + let record = self.collaterals.get_mut(&collateral_id) + .ok_or(ACCCollateralError::CollateralNotFound(collateral_id))?; + if initiator != record.borrower && initiator != record.lender { + return Err(ACCCollateralError::Unauthorized(initiator)); + } + record.status = CollateralStatus::Released; + record.updated_at = timestamp.clone(); + self.pending_events.push(CollateralProtocolEvent::CollateralReleased { collateral_id, timestamp }); + Ok(()) + } + pub fn get_collateral(&self, id: &Hash) -> Option<&CollateralRecord> { self.collaterals.get(id) } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } +} diff --git a/nac-udm/src/l1_protocol/acc/acc_compliance.rs b/nac-udm/src/l1_protocol/acc/acc_compliance.rs index fddf7c0..95c5c19 100644 --- a/nac-udm/src/l1_protocol/acc/acc_compliance.rs +++ b/nac-udm/src/l1_protocol/acc/acc_compliance.rs @@ -1,53 +1,177 @@ -//! ACC协议模块 - -///! # ACC-Compliance: 合规协议 +//! acc_compliance - NAC 原生协议实现 +//! 从 acc_remaining_protocols.rs 提取 use crate::primitives::{Address, Hash, Timestamp}; -use crate::l1_protocol::gnacs::{ComplianceLevel, Jurisdiction}; -use serde::{Deserialize, Serialize}; + use serde::{Deserialize, Serialize}; + use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ComplianceRecord -pub struct ComplianceRecord { - /// entity - pub entity: Address, - /// jurisdiction - pub jurisdiction: Jurisdiction, - /// compliance_level - pub compliance_level: ComplianceLevel, - /// kyc_verified - pub kyc_verified: bool, - /// aml_verified - pub aml_verified: bool, - /// accreditation_verified - pub accreditation_verified: bool, - /// verification_date - pub verification_date: Timestamp, - /// expiry_date - pub expiry_date: Timestamp, - /// verifier - pub verifier: Address, - /// document_hash - pub document_hash: Hash, -} - -impl ComplianceRecord { - /// new - pub fn new(entity: Address, jurisdiction: Jurisdiction) -> Self { - Self { - entity, - jurisdiction, - compliance_level: ComplianceLevel::Unknown, - kyc_verified: false, - aml_verified: false, - accreditation_verified: false, - verification_date: Timestamp::now(), - expiry_date: Timestamp::now().add_secs(365 * 24 * 3600), - verifier: Address::zero(), - document_hash: Hash::zero(), + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + pub enum ACCComplianceError { + EntityNotFound(Address), + ComplianceCheckFailed { layer: u8, reason: String }, + InvalidConstitutionalReceipt, + Unauthorized(Address), + BlacklistedEntity(Address), + JurisdictionRestricted { entity: Address, jurisdiction: String }, + } + impl std::fmt::Display for ACCComplianceError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::EntityNotFound(a) => write!(f, "实体不存在: {}", a.to_hex()), + Self::ComplianceCheckFailed { layer, reason } => write!(f, "第{}层合规检查失败: {}", layer, reason), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + Self::BlacklistedEntity(a) => write!(f, "黑名单实体: {}", a.to_hex()), + Self::JurisdictionRestricted { entity, jurisdiction } => write!(f, "司法管辖区限制 {} 在 {}", entity.to_hex(), jurisdiction), + } } } - /// is_valid - pub fn is_valid(&self) -> bool { - !self.expiry_date.is_expired(Timestamp::now().as_secs()) + + /// 七层合规验证结果 + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct SevenLayerComplianceResult { + pub entity: Address, + /// L1: 身份验证 + pub l1_identity: bool, + /// L2: KYC/AML + pub l2_kyc_aml: bool, + /// L3: 司法管辖区合规 + pub l3_jurisdiction: bool, + /// L4: 资产合规 + pub l4_asset: bool, + /// L5: 交易合规 + pub l5_transaction: bool, + /// L6: AI 合规评分 + pub l6_ai_score: u8, + /// L7: 宪法合规(CBPP) + pub l7_constitutional: bool, + pub overall_pass: bool, + pub checked_at: Timestamp, + pub constitutional_receipt: Hash, + } + impl SevenLayerComplianceResult { + pub fn is_fully_compliant(&self) -> bool { + self.l1_identity && self.l2_kyc_aml && self.l3_jurisdiction + && self.l4_asset && self.l5_transaction + && self.l6_ai_score >= 70 && self.l7_constitutional + } + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ComplianceRecord { + pub entity: Address, + pub kyc_verified: bool, + pub aml_cleared: bool, + pub allowed_jurisdictions: Vec, + pub blacklisted: bool, + pub ai_risk_score: u8, + pub last_checked: Timestamp, + pub compliance_hash: Hash, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum ComplianceProtocolEvent { + EntityRegistered { entity: Address, timestamp: Timestamp }, + ComplianceChecked { entity: Address, result: bool, timestamp: Timestamp }, + EntityBlacklisted { entity: Address, reason: String, timestamp: Timestamp, constitutional_receipt: Hash }, + EntityWhitelisted { entity: Address, timestamp: Timestamp, constitutional_receipt: Hash }, + } + + /// ACC-Compliance 七层合规验证协议 + /// UID: nac.acc.ACCComplianceProtocol.v1 + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ACCComplianceProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub compliance_records: HashMap, + pub blacklist: HashMap, + pub compliance_history: HashMap>, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, + } + impl ACCComplianceProtocol { + pub fn new() -> Self { + Self { + protocol_uid: "nac.acc.ACCComplianceProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Compliance".to_string(), + compliance_records: HashMap::new(), + blacklist: HashMap::new(), + compliance_history: HashMap::new(), + pending_events: Vec::new(), + created_at: Timestamp::now(), + updated_at: Timestamp::now(), + } + } + pub fn register_entity( + &mut self, entity: Address, kyc_verified: bool, aml_cleared: bool, + allowed_jurisdictions: Vec, ai_risk_score: u8, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCComplianceError> { + if constitutional_receipt.is_zero() { return Err(ACCComplianceError::InvalidConstitutionalReceipt); } + let mut data = Vec::new(); + data.extend_from_slice(entity.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let compliance_hash = Hash::sha3_384(&data); + let record = ComplianceRecord { + entity: entity.clone(), kyc_verified, aml_cleared, + allowed_jurisdictions, blacklisted: false, ai_risk_score, + last_checked: timestamp.clone(), compliance_hash, + }; + self.compliance_records.insert(entity.clone(), record); + self.pending_events.push(ComplianceProtocolEvent::EntityRegistered { entity, timestamp }); + self.updated_at = Timestamp::now(); + Ok(()) + } + pub fn run_seven_layer_check( + &mut self, entity: Address, jurisdiction: &str, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if self.blacklist.contains_key(&entity) { + return Err(ACCComplianceError::BlacklistedEntity(entity)); + } + let record = self.compliance_records.get(&entity) + .ok_or(ACCComplianceError::EntityNotFound(entity.clone()))?; + let l1 = true; // 地址存在即通过身份验证 + let l2 = record.kyc_verified && record.aml_cleared; + let l3 = record.allowed_jurisdictions.is_empty() + || record.allowed_jurisdictions.iter().any(|j| j == jurisdiction); + let l4 = !record.blacklisted; + let l5 = record.ai_risk_score < 80; // 风险评分低于80才允许 + let l6 = 100u8.saturating_sub(record.ai_risk_score); + let l7 = !constitutional_receipt.is_zero(); + let overall = l1 && l2 && l3 && l4 && l5 && l6 >= 70 && l7; + let result = SevenLayerComplianceResult { + entity: entity.clone(), l1_identity: l1, l2_kyc_aml: l2, + l3_jurisdiction: l3, l4_asset: l4, l5_transaction: l5, + l6_ai_score: l6, l7_constitutional: l7, overall_pass: overall, + checked_at: timestamp.clone(), constitutional_receipt, + }; + self.compliance_history.entry(entity.clone()).or_insert_with(Vec::new).push(result.clone()); + self.pending_events.push(ComplianceProtocolEvent::ComplianceChecked { + entity, result: overall, timestamp, + }); + Ok(result) + } + pub fn blacklist_entity( + &mut self, entity: Address, reason: String, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCComplianceError> { + if constitutional_receipt.is_zero() { return Err(ACCComplianceError::InvalidConstitutionalReceipt); } + self.blacklist.insert(entity.clone(), reason.clone()); + if let Some(record) = self.compliance_records.get_mut(&entity) { + record.blacklisted = true; + } + self.pending_events.push(ComplianceProtocolEvent::EntityBlacklisted { + entity, reason, timestamp, constitutional_receipt, + }); + Ok(()) + } + pub fn is_compliant(&self, entity: &Address) -> bool { + if self.blacklist.contains_key(entity) { return false; } + self.compliance_records.get(entity) + .map(|r| r.kyc_verified && r.aml_cleared && !r.blacklisted) + .unwrap_or(false) + } + pub fn get_record(&self, entity: &Address) -> Option<&ComplianceRecord> { self.compliance_records.get(entity) } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } } -} diff --git a/nac-udm/src/l1_protocol/acc/acc_custody.rs b/nac-udm/src/l1_protocol/acc/acc_custody.rs index f884603..15c9262 100644 --- a/nac-udm/src/l1_protocol/acc/acc_custody.rs +++ b/nac-udm/src/l1_protocol/acc/acc_custody.rs @@ -1,56 +1,245 @@ -//! ACC协议模块 +//! ACC-Custody: 资产托管协议 +//! UID: nac.acc.ACCCustodyProtocol.v1 +//! 完全规避以太坊模式,使用 NAC 原生类型系统 -///! # ACC-Custody: 托管协议 use crate::primitives::{Address, Hash, Timestamp}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// CustodyAgreement -pub struct CustodyAgreement { - /// agreement_id - pub agreement_id: Hash, - /// asset_id - pub asset_id: Hash, - /// owner - pub owner: Address, - /// custodian - pub custodian: Address, - /// custody_type - pub custody_type: CustodyType, - /// start_date - pub start_date: Timestamp, - /// end_date - pub end_date: Option, - /// insurance_amount - pub insurance_amount: u128, - /// agreement_hash - pub agreement_hash: Hash, +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ACCCustodyError { + CustodyNotFound(Hash), + CustodyAlreadyExists(Hash), + UnauthorizedCustodian(Address), + CustodyAlreadyTerminated(Hash), + InvalidConstitutionalReceipt, + InsufficientInsurance, + Unauthorized(Address), } -#[derive(Debug, Clone, Serialize, Deserialize)] -/// CustodyType -pub enum CustodyType { - /// Physical - Physical, - /// Digital - Digital, - /// Hybrid - Hybrid, -} - -impl CustodyAgreement { - /// new - pub fn new(asset_id: Hash, owner: Address, custodian: Address) -> Self { - Self { - agreement_id: Hash::zero(), - asset_id, - owner, - custodian, - custody_type: CustodyType::Physical, - start_date: Timestamp::now(), - end_date: None, - insurance_amount: 0, - agreement_hash: Hash::zero(), +impl std::fmt::Display for ACCCustodyError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::CustodyNotFound(h) => write!(f, "托管协议不存在: {}", h.to_hex()), + Self::CustodyAlreadyExists(h) => write!(f, "托管协议已存在: {}", h.to_hex()), + Self::UnauthorizedCustodian(a) => write!(f, "未授权托管机构: {}", a.to_hex()), + Self::CustodyAlreadyTerminated(h) => write!(f, "托管协议已终止: {}", h.to_hex()), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::InsufficientInsurance => write!(f, "保险金额不足"), + Self::Unauthorized(a) => write!(f, "未授权操作: {}", a.to_hex()), } } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum CustodyType { + Physical, + Digital, + Hybrid, + SelfCustody, + ThirdPartyInstitutional, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum CustodyStatus { + Pending, + Active, + Suspended, + Terminated, + InDispute, +} + +/// 托管协议 +/// UID: nac.acc.CustodyAgreement.v1 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CustodyAgreement { + pub custody_id: Hash, + pub asset_id: Hash, + pub owner: Address, + pub custodian: Address, + pub custody_type: CustodyType, + pub status: CustodyStatus, + pub start_time: Timestamp, + pub end_time: Option, + /// 保险金额(XTZH) + pub insurance_amount: u128, + pub insurer: Option
, + /// 托管费率(基点,1基点=0.01%) + pub fee_basis_points: u16, + /// 托管协议文档哈希(SHA3-384) + pub agreement_document_hash: Hash, + pub constitutional_receipt: Hash, + pub created_at: Timestamp, + pub updated_at: Timestamp, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum CustodyProtocolEvent { + CustodyCreated { custody_id: Hash, asset_id: Hash, custodian: Address, timestamp: Timestamp }, + CustodyActivated { custody_id: Hash, timestamp: Timestamp }, + CustodyTerminated { custody_id: Hash, reason: String, timestamp: Timestamp, constitutional_receipt: Hash }, + CustodySuspended { custody_id: Hash, reason: String, timestamp: Timestamp }, + InsuranceUpdated { custody_id: Hash, old_amount: u128, new_amount: u128, timestamp: Timestamp }, +} + +/// ACC-Custody 托管协议 +/// UID: nac.acc.ACCCustodyProtocol.v1 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ACCCustodyProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub agreements: HashMap, + /// 资产到托管协议的映射(asset_id -> custody_id) + pub asset_custody_map: HashMap, + pub authorized_custodians: HashMap, + /// 最低保险要求(XTZH) + pub min_insurance_requirement: u128, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, +} + +impl ACCCustodyProtocol { + pub fn new(min_insurance_requirement: u128) -> Self { + Self { + protocol_uid: "nac.acc.ACCCustodyProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Custody".to_string(), + agreements: HashMap::new(), + asset_custody_map: HashMap::new(), + authorized_custodians: HashMap::new(), + min_insurance_requirement, + pending_events: Vec::new(), + created_at: Timestamp::now(), + updated_at: Timestamp::now(), + } + } + + pub fn authorize_custodian( + &mut self, + custodian: Address, + constitutional_receipt: Hash, + timestamp: Timestamp, + ) -> Result<(), ACCCustodyError> { + if constitutional_receipt.is_zero() { + return Err(ACCCustodyError::InvalidConstitutionalReceipt); + } + self.authorized_custodians.insert(custodian, timestamp); + Ok(()) + } + + pub fn create_custody( + &mut self, + asset_id: Hash, + owner: Address, + custodian: Address, + custody_type: CustodyType, + insurance_amount: u128, + insurer: Option
, + fee_basis_points: u16, + agreement_document_hash: Hash, + constitutional_receipt: Hash, + timestamp: Timestamp, + ) -> Result { + if custody_type != CustodyType::SelfCustody + && !self.authorized_custodians.contains_key(&custodian) + { + return Err(ACCCustodyError::UnauthorizedCustodian(custodian)); + } + if insurance_amount < self.min_insurance_requirement { + return Err(ACCCustodyError::InsufficientInsurance); + } + let mut data = Vec::new(); + data.extend_from_slice(asset_id.as_bytes()); + data.extend_from_slice(custodian.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let custody_id = Hash::sha3_384(&data); + if self.agreements.contains_key(&custody_id) { + return Err(ACCCustodyError::CustodyAlreadyExists(custody_id)); + } + let agreement = CustodyAgreement { + custody_id, + asset_id, + owner, + custodian: custodian.clone(), + custody_type, + status: CustodyStatus::Pending, + start_time: timestamp.clone(), + end_time: None, + insurance_amount, + insurer, + fee_basis_points, + agreement_document_hash, + constitutional_receipt, + created_at: timestamp.clone(), + updated_at: timestamp.clone(), + }; + self.asset_custody_map.insert(asset_id, custody_id); + self.agreements.insert(custody_id, agreement); + self.pending_events.push(CustodyProtocolEvent::CustodyCreated { + custody_id, + asset_id, + custodian, + timestamp, + }); + self.updated_at = Timestamp::now(); + Ok(custody_id) + } + + pub fn activate_custody( + &mut self, + custody_id: Hash, + constitutional_receipt: Hash, + timestamp: Timestamp, + ) -> Result<(), ACCCustodyError> { + if constitutional_receipt.is_zero() { + return Err(ACCCustodyError::InvalidConstitutionalReceipt); + } + let agreement = self.agreements.get_mut(&custody_id) + .ok_or(ACCCustodyError::CustodyNotFound(custody_id))?; + agreement.status = CustodyStatus::Active; + agreement.updated_at = timestamp.clone(); + self.pending_events.push(CustodyProtocolEvent::CustodyActivated { custody_id, timestamp }); + Ok(()) + } + + pub fn terminate_custody( + &mut self, + custody_id: Hash, + reason: String, + initiator: Address, + constitutional_receipt: Hash, + timestamp: Timestamp, + ) -> Result<(), ACCCustodyError> { + if constitutional_receipt.is_zero() { + return Err(ACCCustodyError::InvalidConstitutionalReceipt); + } + let agreement = self.agreements.get_mut(&custody_id) + .ok_or(ACCCustodyError::CustodyNotFound(custody_id))?; + if agreement.status == CustodyStatus::Terminated { + return Err(ACCCustodyError::CustodyAlreadyTerminated(custody_id)); + } + if initiator != agreement.owner && initiator != agreement.custodian { + return Err(ACCCustodyError::Unauthorized(initiator)); + } + agreement.status = CustodyStatus::Terminated; + agreement.end_time = Some(timestamp.clone()); + agreement.updated_at = timestamp.clone(); + self.pending_events.push(CustodyProtocolEvent::CustodyTerminated { + custody_id, reason, timestamp, constitutional_receipt, + }); + Ok(()) + } + + pub fn get_custody(&self, custody_id: &Hash) -> Option<&CustodyAgreement> { + self.agreements.get(custody_id) + } + + pub fn get_asset_custody(&self, asset_id: &Hash) -> Option<&CustodyAgreement> { + self.asset_custody_map.get(asset_id) + .and_then(|id| self.agreements.get(id)) + } + + pub fn drain_pending_events(&mut self) -> Vec { + std::mem::take(&mut self.pending_events) + } +} diff --git a/nac-udm/src/l1_protocol/acc/acc_governance.rs b/nac-udm/src/l1_protocol/acc/acc_governance.rs index fb66502..db186fc 100644 --- a/nac-udm/src/l1_protocol/acc/acc_governance.rs +++ b/nac-udm/src/l1_protocol/acc/acc_governance.rs @@ -1,80 +1,192 @@ -//! ACC协议模块 +//! acc_governance - NAC 原生协议实现 -///! # ACC-Governance: 治理协议 use crate::primitives::{Address, Hash, Timestamp}; -use serde::{Deserialize, Serialize}; + use serde::{Deserialize, Serialize}; + use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// GovernanceProposal -pub struct ACCGovernanceProposal { - /// proposal_id - pub proposal_id: Hash, - /// proposer - pub proposer: Address, - /// title - pub title: String, - /// description - pub description: String, - /// proposal_type - pub proposal_type: ACCProposalType, - /// created_at - pub created_at: Timestamp, - /// voting_start - pub voting_start: Timestamp, - /// voting_end - pub voting_end: Timestamp, - /// votes_for - pub votes_for: u128, - /// votes_against - pub votes_against: u128, - /// status - pub status: ACCProposalStatus, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ProposalType -pub enum ACCProposalType { - /// ParameterChange - ParameterChange, - /// ProtocolUpgrade - ProtocolUpgrade, - /// TreasuryAllocation - TreasuryAllocation, - /// Emergency - Emergency, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ProposalStatus -pub enum ACCProposalStatus { - /// Pending - Pending, - /// Active - Active, - /// Passed - Passed, - /// Rejected - Rejected, - /// Executed - Executed, -} - -impl ACCGovernanceProposal { - /// new - pub fn new(proposer: Address, title: String, description: String) -> Self { - let now = Timestamp::now(); - Self { - proposal_id: Hash::zero(), - proposer, - title, - description, - proposal_type: ACCProposalType::ParameterChange, - created_at: now, - voting_start: now.add_secs(24 * 3600), - voting_end: now.add_secs(7 * 24 * 3600), - votes_for: 0, - votes_against: 0, - status: ACCProposalStatus::Pending, + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + pub enum ACCGovernanceError { + ProposalNotFound(Hash), + ProposalAlreadyExecuted(Hash), + VotingPeriodEnded(Hash), + AlreadyVoted(Address), + InsufficientVotingPower { required: u128, actual: u128 }, + QuorumNotReached { required: u128, actual: u128 }, + InvalidConstitutionalReceipt, + Unauthorized(Address), + } + impl std::fmt::Display for ACCGovernanceError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::ProposalNotFound(h) => write!(f, "提案不存在: {}", h.to_hex()), + Self::ProposalAlreadyExecuted(h) => write!(f, "提案已执行: {}", h.to_hex()), + Self::VotingPeriodEnded(h) => write!(f, "投票期已结束: {}", h.to_hex()), + Self::AlreadyVoted(a) => write!(f, "已投票: {}", a.to_hex()), + Self::InsufficientVotingPower { required, actual } => write!(f, "投票权不足: 需要 {},实际 {}", required, actual), + Self::QuorumNotReached { required, actual } => write!(f, "未达法定人数: 需要 {},实际 {}", required, actual), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + } } } -} + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum ProposalType { + ParameterChange { parameter: String, new_value: Vec }, + ProtocolUpgrade { new_version: String, upgrade_hash: Hash }, + AssetPolicyChange { asset_id: Hash, policy_hash: Hash }, + EmergencyPause { reason: String }, + GovernanceMemberChange { member: Address, action: MemberAction }, + } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum MemberAction { Add, Remove } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum ProposalStatus { Active, Passed, Rejected, Executed, Cancelled, Expired } + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum VoteChoice { For, Against, Abstain } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct GovernanceProposal { + pub proposal_id: Hash, + pub proposer: Address, + pub proposal_type: ProposalType, + pub description: String, + pub status: ProposalStatus, + pub votes_for: u128, + pub votes_against: u128, + pub votes_abstain: u128, + pub vote_records: HashMap, + pub voting_start: Timestamp, + pub voting_end: Timestamp, + pub quorum_bps: u32, + pub pass_threshold_bps: u32, + pub constitutional_receipt: Hash, + pub created_at: Timestamp, + pub executed_at: Option, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum GovernanceProtocolEvent { + ProposalCreated { proposal_id: Hash, proposer: Address, timestamp: Timestamp }, + VoteCast { proposal_id: Hash, voter: Address, choice: VoteChoice, voting_power: u128, timestamp: Timestamp }, + ProposalPassed { proposal_id: Hash, votes_for: u128, votes_against: u128, timestamp: Timestamp }, + ProposalRejected { proposal_id: Hash, reason: String, timestamp: Timestamp }, + ProposalExecuted { proposal_id: Hash, timestamp: Timestamp, constitutional_receipt: Hash }, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ACCGovernanceProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub proposals: HashMap, + pub voting_power_registry: HashMap, + pub total_voting_power: u128, + pub default_quorum_bps: u32, + pub default_pass_threshold_bps: u32, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, + } + impl ACCGovernanceProtocol { + pub fn new(default_quorum_bps: u32, default_pass_threshold_bps: u32) -> Self { + Self { + protocol_uid: "nac.acc.ACCGovernanceProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Governance".to_string(), + proposals: HashMap::new(), + voting_power_registry: HashMap::new(), + total_voting_power: 0, + default_quorum_bps, default_pass_threshold_bps, + pending_events: Vec::new(), + created_at: Timestamp::now(), updated_at: Timestamp::now(), + } + } + pub fn register_voting_power(&mut self, address: Address, power: u128) { + let old = self.voting_power_registry.insert(address, power).unwrap_or(0); + self.total_voting_power = self.total_voting_power.saturating_sub(old).saturating_add(power); + } + pub fn create_proposal( + &mut self, proposer: Address, proposal_type: ProposalType, description: String, + voting_duration_secs: u64, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if constitutional_receipt.is_zero() { return Err(ACCGovernanceError::InvalidConstitutionalReceipt); } + let proposer_power = self.voting_power_registry.get(&proposer).copied().unwrap_or(0); + if proposer_power == 0 { + return Err(ACCGovernanceError::InsufficientVotingPower { required: 1, actual: 0 }); + } + let mut data = Vec::new(); + data.extend_from_slice(proposer.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let proposal_id = Hash::sha3_384(&data); + let proposal = GovernanceProposal { + proposal_id, proposer: proposer.clone(), proposal_type, description, + status: ProposalStatus::Active, + votes_for: 0, votes_against: 0, votes_abstain: 0, + vote_records: HashMap::new(), + voting_start: timestamp.clone(), + voting_end: timestamp.add_secs(voting_duration_secs), + quorum_bps: self.default_quorum_bps, + pass_threshold_bps: self.default_pass_threshold_bps, + constitutional_receipt, created_at: timestamp.clone(), executed_at: None, + }; + self.proposals.insert(proposal_id, proposal); + self.pending_events.push(GovernanceProtocolEvent::ProposalCreated { proposal_id, proposer, timestamp }); + self.updated_at = Timestamp::now(); + Ok(proposal_id) + } + pub fn cast_vote( + &mut self, proposal_id: Hash, voter: Address, choice: VoteChoice, timestamp: Timestamp, + ) -> Result<(), ACCGovernanceError> { + let voting_power = self.voting_power_registry.get(&voter).copied().unwrap_or(0); + if voting_power == 0 { + return Err(ACCGovernanceError::InsufficientVotingPower { required: 1, actual: 0 }); + } + let proposal = self.proposals.get_mut(&proposal_id) + .ok_or(ACCGovernanceError::ProposalNotFound(proposal_id))?; + if proposal.status != ProposalStatus::Active { + return Err(ACCGovernanceError::VotingPeriodEnded(proposal_id)); + } + if proposal.vote_records.contains_key(&voter) { + return Err(ACCGovernanceError::AlreadyVoted(voter)); + } + match choice { + VoteChoice::For => proposal.votes_for = proposal.votes_for.saturating_add(voting_power), + VoteChoice::Against => proposal.votes_against = proposal.votes_against.saturating_add(voting_power), + VoteChoice::Abstain => proposal.votes_abstain = proposal.votes_abstain.saturating_add(voting_power), + } + proposal.vote_records.insert(voter.clone(), choice); + self.pending_events.push(GovernanceProtocolEvent::VoteCast { proposal_id, voter, choice, voting_power, timestamp }); + Ok(()) + } + pub fn finalize_proposal( + &mut self, proposal_id: Hash, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if constitutional_receipt.is_zero() { return Err(ACCGovernanceError::InvalidConstitutionalReceipt); } + let proposal = self.proposals.get_mut(&proposal_id) + .ok_or(ACCGovernanceError::ProposalNotFound(proposal_id))?; + let total_votes = proposal.votes_for + proposal.votes_against + proposal.votes_abstain; + let quorum_required = (self.total_voting_power as u64 * proposal.quorum_bps as u64 / 10000) as u128; + if total_votes < quorum_required { + proposal.status = ProposalStatus::Rejected; + self.pending_events.push(GovernanceProtocolEvent::ProposalRejected { + proposal_id, reason: format!("未达法定人数: {} < {}", total_votes, quorum_required), timestamp, + }); + return Ok(false); + } + let effective_votes = proposal.votes_for + proposal.votes_against; + let pass_required = (effective_votes as u64 * proposal.pass_threshold_bps as u64 / 10000) as u128; + let passed = proposal.votes_for >= pass_required; + if passed { + proposal.status = ProposalStatus::Executed; + proposal.executed_at = Some(timestamp.clone()); + self.pending_events.push(GovernanceProtocolEvent::ProposalExecuted { proposal_id, timestamp, constitutional_receipt }); + } else { + proposal.status = ProposalStatus::Rejected; + self.pending_events.push(GovernanceProtocolEvent::ProposalRejected { + proposal_id, reason: "赞成票未达阈值".to_string(), timestamp, + }); + } + Ok(passed) + } + pub fn get_proposal(&self, id: &Hash) -> Option<&GovernanceProposal> { self.proposals.get(id) } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } + } diff --git a/nac-udm/src/l1_protocol/acc/acc_insurance.rs b/nac-udm/src/l1_protocol/acc/acc_insurance.rs index 987cefd..83f8bfe 100644 --- a/nac-udm/src/l1_protocol/acc/acc_insurance.rs +++ b/nac-udm/src/l1_protocol/acc/acc_insurance.rs @@ -1,74 +1,168 @@ -//! ACC协议模块 +//! acc_insurance - NAC 原生协议实现 -///! # ACC-Insurance: 保险协议 use crate::primitives::{Address, Hash, Timestamp}; -use serde::{Deserialize, Serialize}; + use serde::{Deserialize, Serialize}; + use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// InsurancePolicy -pub struct InsurancePolicy { - /// policy_id - pub policy_id: Hash, - /// insured_asset - pub insured_asset: Hash, - /// policy_holder - pub policy_holder: Address, - /// insurer - pub insurer: Address, - /// coverage_amount - pub coverage_amount: u128, - /// premium - pub premium: u128, - /// start_date - pub start_date: Timestamp, - /// end_date - pub end_date: Timestamp, - /// policy_type - pub policy_type: InsuranceType, - /// status - pub status: PolicyStatus, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// InsuranceType -pub enum InsuranceType { - /// PropertyDamage - PropertyDamage, - /// Theft - Theft, - /// Fraud - Fraud, - /// Comprehensive - Comprehensive, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// PolicyStatus -pub enum PolicyStatus { - /// Active - Active, - /// Expired - Expired, - /// Claimed - Claimed, - /// Cancelled - Cancelled, -} - -impl InsurancePolicy { - /// new - pub fn new(insured_asset: Hash, policy_holder: Address, insurer: Address, coverage_amount: u128) -> Self { - Self { - policy_id: Hash::zero(), - insured_asset, - policy_holder, - insurer, - coverage_amount, - premium: coverage_amount / 100, - start_date: Timestamp::now(), - end_date: Timestamp::now().add_secs(365 * 24 * 3600), - policy_type: InsuranceType::Comprehensive, - status: PolicyStatus::Active, + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + pub enum ACCInsuranceError { + PolicyNotFound(Hash), + PolicyExpired(Hash), + ClaimAlreadyProcessed(Hash), + InvalidConstitutionalReceipt, + Unauthorized(Address), + ClaimExceedsCoverage { coverage: u128, claim: u128 }, + } + impl std::fmt::Display for ACCInsuranceError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::PolicyNotFound(h) => write!(f, "保险单不存在: {}", h.to_hex()), + Self::PolicyExpired(h) => write!(f, "保险单已过期: {}", h.to_hex()), + Self::ClaimAlreadyProcessed(h) => write!(f, "理赔已处理: {}", h.to_hex()), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + Self::ClaimExceedsCoverage { coverage, claim } => write!(f, "理赔超额: 保额 {},理赔 {}", coverage, claim), + } } } -} + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum InsuranceType { AssetLoss, CustodyRisk, ComplianceRisk, MarketPrice, Comprehensive } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct InsurancePolicy { + pub policy_id: Hash, + pub asset_id: Hash, + pub insured: Address, + pub insurer: Address, + pub insurance_type: InsuranceType, + pub coverage_amount: u128, + pub claimed_amount: u128, + pub premium_rate_bps: u16, + pub start_time: Timestamp, + pub end_time: Timestamp, + pub is_active: bool, + pub constitutional_receipt: Hash, + pub created_at: Timestamp, + } + impl InsurancePolicy { + pub fn is_expired(&self) -> bool { self.end_time.is_expired(0) } + pub fn remaining_coverage(&self) -> u128 { self.coverage_amount.saturating_sub(self.claimed_amount) } + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum ClaimStatus { Pending, UnderReview, Approved, Rejected, Paid } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct InsuranceClaim { + pub claim_id: Hash, + pub policy_id: Hash, + pub claimant: Address, + pub claim_amount: u128, + pub claim_reason: String, + pub evidence_hash: Hash, + pub status: ClaimStatus, + pub submitted_at: Timestamp, + pub processed_at: Option, + pub constitutional_receipt: Hash, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum InsuranceProtocolEvent { + PolicyIssued { policy_id: Hash, asset_id: Hash, insured: Address, coverage: u128, timestamp: Timestamp }, + ClaimSubmitted { claim_id: Hash, policy_id: Hash, amount: u128, timestamp: Timestamp }, + ClaimPaid { claim_id: Hash, amount: u128, timestamp: Timestamp, constitutional_receipt: Hash }, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ACCInsuranceProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub policies: HashMap, + pub claims: HashMap, + pub insurance_pool: u128, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, + } + impl ACCInsuranceProtocol { + pub fn new() -> Self { + Self { + protocol_uid: "nac.acc.ACCInsuranceProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Insurance".to_string(), + policies: HashMap::new(), claims: HashMap::new(), + insurance_pool: 0, pending_events: Vec::new(), + created_at: Timestamp::now(), updated_at: Timestamp::now(), + } + } + pub fn fund_pool(&mut self, amount: u128) { self.insurance_pool = self.insurance_pool.saturating_add(amount); } + pub fn issue_policy( + &mut self, asset_id: Hash, insured: Address, insurer: Address, + insurance_type: InsuranceType, coverage_amount: u128, premium_rate_bps: u16, + duration_secs: u64, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if constitutional_receipt.is_zero() { return Err(ACCInsuranceError::InvalidConstitutionalReceipt); } + let mut data = Vec::new(); + data.extend_from_slice(asset_id.as_bytes()); + data.extend_from_slice(insured.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let policy_id = Hash::sha3_384(&data); + let policy = InsurancePolicy { + policy_id, asset_id, insured: insured.clone(), insurer, insurance_type, + coverage_amount, claimed_amount: 0, premium_rate_bps, + start_time: timestamp.clone(), + end_time: timestamp.add_secs(duration_secs), + is_active: true, constitutional_receipt, created_at: timestamp.clone(), + }; + self.policies.insert(policy_id, policy); + self.pending_events.push(InsuranceProtocolEvent::PolicyIssued { + policy_id, asset_id, insured, coverage: coverage_amount, timestamp, + }); + self.updated_at = Timestamp::now(); + Ok(policy_id) + } + pub fn submit_claim( + &mut self, policy_id: Hash, claimant: Address, claim_amount: u128, + claim_reason: String, evidence_hash: Hash, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + let policy = self.policies.get(&policy_id).ok_or(ACCInsuranceError::PolicyNotFound(policy_id))?; + if policy.is_expired() { return Err(ACCInsuranceError::PolicyExpired(policy_id)); } + if claim_amount > policy.remaining_coverage() { + return Err(ACCInsuranceError::ClaimExceedsCoverage { coverage: policy.remaining_coverage(), claim: claim_amount }); + } + let mut data = Vec::new(); + data.extend_from_slice(policy_id.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let claim_id = Hash::sha3_384(&data); + let claim = InsuranceClaim { + claim_id, policy_id, claimant, claim_amount, claim_reason, + evidence_hash, status: ClaimStatus::Pending, + submitted_at: timestamp.clone(), processed_at: None, constitutional_receipt, + }; + self.claims.insert(claim_id, claim); + self.pending_events.push(InsuranceProtocolEvent::ClaimSubmitted { claim_id, policy_id, amount: claim_amount, timestamp }); + Ok(claim_id) + } + pub fn pay_claim( + &mut self, claim_id: Hash, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if constitutional_receipt.is_zero() { return Err(ACCInsuranceError::InvalidConstitutionalReceipt); } + let claim = self.claims.get_mut(&claim_id).ok_or(ACCInsuranceError::PolicyNotFound(claim_id))?; + if claim.status != ClaimStatus::Pending && claim.status != ClaimStatus::UnderReview { + return Err(ACCInsuranceError::ClaimAlreadyProcessed(claim_id)); + } + let amount = claim.claim_amount; + let policy_id = claim.policy_id; + claim.status = ClaimStatus::Paid; + claim.processed_at = Some(timestamp.clone()); + if let Some(policy) = self.policies.get_mut(&policy_id) { + policy.claimed_amount = policy.claimed_amount.saturating_add(amount); + } + self.insurance_pool = self.insurance_pool.saturating_sub(amount); + self.pending_events.push(InsuranceProtocolEvent::ClaimPaid { claim_id, amount, timestamp, constitutional_receipt }); + Ok(amount) + } + pub fn get_policy(&self, id: &Hash) -> Option<&InsurancePolicy> { self.policies.get(id) } + pub fn get_claim(&self, id: &Hash) -> Option<&InsuranceClaim> { self.claims.get(id) } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } + } diff --git a/nac-udm/src/l1_protocol/acc/acc_redemption.rs b/nac-udm/src/l1_protocol/acc/acc_redemption.rs index 3f00145..b317052 100644 --- a/nac-udm/src/l1_protocol/acc/acc_redemption.rs +++ b/nac-udm/src/l1_protocol/acc/acc_redemption.rs @@ -1,55 +1,119 @@ -//! ACC协议模块 - -///! # ACC-Redemption: 赎回协议 +//! acc_redemption - NAC 原生协议实现 +//! 从 acc_remaining_protocols.rs 提取 use crate::primitives::{Address, Hash, Timestamp}; -use serde::{Deserialize, Serialize}; + use serde::{Deserialize, Serialize}; + use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// RedemptionRequest -pub struct RedemptionRequest { - /// request_id - pub request_id: Hash, - /// token_holder - pub token_holder: Address, - /// token_id - pub token_id: Hash, - /// token_amount - pub token_amount: u128, - /// redemption_value - pub redemption_value: u128, - /// requested_at - pub requested_at: Timestamp, - /// processed_at - pub processed_at: Option, - /// status - pub status: RedemptionStatus, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// RedemptionStatus -pub enum RedemptionStatus { - /// Pending - Pending, - /// Approved - Approved, - /// Rejected - Rejected, - /// Completed - Completed, -} - -impl RedemptionRequest { - /// new - pub fn new(token_holder: Address, token_id: Hash, token_amount: u128, redemption_value: u128) -> Self { - Self { - request_id: Hash::zero(), - token_holder, - token_id, - token_amount, - redemption_value, - requested_at: Timestamp::now(), - processed_at: None, - status: RedemptionStatus::Pending, + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + pub enum ACCRedemptionError { + RedemptionNotFound(Hash), + InsufficientRedemptionFund { available: u128, requested: u128 }, + RedemptionWindowClosed, + InvalidConstitutionalReceipt, + Unauthorized(Address), + RedemptionAlreadyProcessed(Hash), + } + impl std::fmt::Display for ACCRedemptionError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::RedemptionNotFound(h) => write!(f, "赎回请求不存在: {}", h.to_hex()), + Self::InsufficientRedemptionFund { available, requested } => write!(f, "赎回资金不足: 可用 {},请求 {}", available, requested), + Self::RedemptionWindowClosed => write!(f, "赎回窗口已关闭"), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + Self::RedemptionAlreadyProcessed(h) => write!(f, "赎回请求已处理: {}", h.to_hex()), + } } } -} + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum RedemptionStatus { Pending, Processing, Completed, Rejected, Cancelled } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct RedemptionRequest { + pub redemption_id: Hash, + pub asset_id: Hash, + pub redeemer: Address, + pub amount: u128, + pub redemption_price_xtzh: u128, + pub total_redemption_xtzh: u128, + pub status: RedemptionStatus, + pub requested_at: Timestamp, + pub processed_at: Option, + pub constitutional_receipt: Hash, + pub rejection_reason: Option, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum RedemptionProtocolEvent { + RedemptionRequested { redemption_id: Hash, asset_id: Hash, redeemer: Address, amount: u128, timestamp: Timestamp }, + RedemptionCompleted { redemption_id: Hash, total_xtzh: u128, timestamp: Timestamp }, + RedemptionRejected { redemption_id: Hash, reason: String, timestamp: Timestamp }, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ACCRedemptionProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub requests: HashMap, + pub redemption_fund: HashMap, + pub redemption_window_open: bool, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, + } + impl ACCRedemptionProtocol { + pub fn new() -> Self { + Self { + protocol_uid: "nac.acc.ACCRedemptionProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Redemption".to_string(), + requests: HashMap::new(), redemption_fund: HashMap::new(), + redemption_window_open: true, pending_events: Vec::new(), + created_at: Timestamp::now(), updated_at: Timestamp::now(), + } + } + pub fn fund_redemption_pool(&mut self, asset_id: Hash, amount_xtzh: u128, constitutional_receipt: Hash) -> Result<(), ACCRedemptionError> { + if constitutional_receipt.is_zero() { return Err(ACCRedemptionError::InvalidConstitutionalReceipt); } + *self.redemption_fund.entry(asset_id).or_insert(0) += amount_xtzh; + Ok(()) + } + pub fn request_redemption( + &mut self, asset_id: Hash, redeemer: Address, amount: u128, + redemption_price_xtzh: u128, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if !self.redemption_window_open { return Err(ACCRedemptionError::RedemptionWindowClosed); } + let total = amount.saturating_mul(redemption_price_xtzh); + let available = self.redemption_fund.get(&asset_id).copied().unwrap_or(0); + if available < total { return Err(ACCRedemptionError::InsufficientRedemptionFund { available, requested: total }); } + let mut data = Vec::new(); + data.extend_from_slice(asset_id.as_bytes()); + data.extend_from_slice(redeemer.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let redemption_id = Hash::sha3_384(&data); + let request = RedemptionRequest { + redemption_id, asset_id, redeemer: redeemer.clone(), amount, + redemption_price_xtzh, total_redemption_xtzh: total, + status: RedemptionStatus::Pending, + requested_at: timestamp.clone(), processed_at: None, + constitutional_receipt, rejection_reason: None, + }; + self.requests.insert(redemption_id, request); + self.pending_events.push(RedemptionProtocolEvent::RedemptionRequested { redemption_id, asset_id, redeemer, amount, timestamp }); + self.updated_at = Timestamp::now(); + Ok(redemption_id) + } + pub fn complete_redemption(&mut self, redemption_id: Hash, constitutional_receipt: Hash, timestamp: Timestamp) -> Result { + if constitutional_receipt.is_zero() { return Err(ACCRedemptionError::InvalidConstitutionalReceipt); } + let request = self.requests.get_mut(&redemption_id).ok_or(ACCRedemptionError::RedemptionNotFound(redemption_id))?; + if request.status != RedemptionStatus::Pending { return Err(ACCRedemptionError::RedemptionAlreadyProcessed(redemption_id)); } + let total = request.total_redemption_xtzh; + let asset_id = request.asset_id; + if let Some(fund) = self.redemption_fund.get_mut(&asset_id) { *fund = fund.saturating_sub(total); } + request.status = RedemptionStatus::Completed; + request.processed_at = Some(timestamp.clone()); + self.pending_events.push(RedemptionProtocolEvent::RedemptionCompleted { redemption_id, total_xtzh: total, timestamp }); + Ok(total) + } + pub fn get_request(&self, id: &Hash) -> Option<&RedemptionRequest> { self.requests.get(id) } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } + } diff --git a/nac-udm/src/l1_protocol/acc/acc_reserve.rs b/nac-udm/src/l1_protocol/acc/acc_reserve.rs index e43cb24..94deaf2 100644 --- a/nac-udm/src/l1_protocol/acc/acc_reserve.rs +++ b/nac-udm/src/l1_protocol/acc/acc_reserve.rs @@ -1,54 +1,112 @@ -//! ACC协议模块 - -///! # ACC-Reserve: 储备协议 +//! acc_reserve - NAC 原生协议实现 +//! 从 acc_remaining_protocols.rs 提取 use crate::primitives::{Address, Hash, Timestamp}; -use serde::{Deserialize, Serialize}; + use serde::{Deserialize, Serialize}; + use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ReservePool -pub struct ReservePool { - /// pool_id - pub pool_id: Hash, - /// manager - pub manager: Address, - /// total_value - pub total_value: u128, - /// assets - pub assets: Vec, - /// target_ratios - pub target_ratios: std::collections::HashMap, - /// last_audit - pub last_audit: Timestamp, - /// audit_frequency - pub audit_frequency: u64, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// PoolAsset -pub struct PoolAsset { - /// asset_id - pub asset_id: Hash, - /// asset_type - pub asset_type: String, - /// amount - pub amount: u128, - /// current_value - pub current_value: u128, - /// custody_provider - pub custody_provider: Address, -} - -impl ReservePool { - /// new - pub fn new(manager: Address) -> Self { - Self { - pool_id: Hash::zero(), - manager, - total_value: 0, - assets: Vec::new(), - target_ratios: std::collections::HashMap::new(), - last_audit: Timestamp::now(), - audit_frequency: 30 * 24 * 3600, + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + pub enum ACCReserveError { + ReserveNotFound(String), + InsufficientReserve { asset: String, available: u128, requested: u128 }, + InvalidConstitutionalReceipt, + Unauthorized(Address), + ReserveRatioViolation { required: u8, actual: u8 }, + } + impl std::fmt::Display for ACCReserveError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::ReserveNotFound(s) => write!(f, "储备资产不存在: {}", s), + Self::InsufficientReserve { asset, available, requested } => write!(f, "储备不足 {}: 可用 {},请求 {}", asset, available, requested), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + Self::ReserveRatioViolation { required, actual } => write!(f, "储备率违规: 要求 {}%,实际 {}%", required, actual), + } } } -} + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ReserveEntry { + pub asset_symbol: String, + pub amount: u128, + pub custodian: Address, + pub last_audited: Timestamp, + pub audit_hash: Hash, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum ReserveProtocolEvent { + ReserveDeposited { asset: String, amount: u128, custodian: Address, timestamp: Timestamp }, + ReserveWithdrawn { asset: String, amount: u128, recipient: Address, constitutional_receipt: Hash, timestamp: Timestamp }, + ReserveAudited { asset: String, audit_hash: Hash, timestamp: Timestamp }, + } + + /// ACC-Reserve 储备协议 + /// UID: nac.acc.ACCReserveProtocol.v1 + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ACCReserveProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub reserves: HashMap, + /// 最低储备率(百分比) + pub min_reserve_ratio: u8, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, + } + impl ACCReserveProtocol { + pub fn new(min_reserve_ratio: u8) -> Self { + Self { + protocol_uid: "nac.acc.ACCReserveProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Reserve".to_string(), + reserves: HashMap::new(), + min_reserve_ratio, + pending_events: Vec::new(), + created_at: Timestamp::now(), + updated_at: Timestamp::now(), + } + } + pub fn deposit( + &mut self, asset_symbol: String, amount: u128, custodian: Address, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCReserveError> { + if constitutional_receipt.is_zero() { return Err(ACCReserveError::InvalidConstitutionalReceipt); } + let entry = self.reserves.entry(asset_symbol.clone()).or_insert(ReserveEntry { + asset_symbol: asset_symbol.clone(), amount: 0, + custodian: custodian.clone(), last_audited: timestamp.clone(), + audit_hash: Hash::zero(), + }); + entry.amount = entry.amount.saturating_add(amount); + entry.custodian = custodian.clone(); + self.pending_events.push(ReserveProtocolEvent::ReserveDeposited { asset: asset_symbol, amount, custodian, timestamp }); + self.updated_at = Timestamp::now(); + Ok(()) + } + pub fn withdraw( + &mut self, asset_symbol: String, amount: u128, recipient: Address, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCReserveError> { + if constitutional_receipt.is_zero() { return Err(ACCReserveError::InvalidConstitutionalReceipt); } + let entry = self.reserves.get_mut(&asset_symbol) + .ok_or_else(|| ACCReserveError::ReserveNotFound(asset_symbol.clone()))?; + if entry.amount < amount { + return Err(ACCReserveError::InsufficientReserve { asset: asset_symbol.clone(), available: entry.amount, requested: amount }); + } + entry.amount -= amount; + self.pending_events.push(ReserveProtocolEvent::ReserveWithdrawn { asset: asset_symbol, amount, recipient, constitutional_receipt, timestamp }); + self.updated_at = Timestamp::now(); + Ok(()) + } + pub fn audit( + &mut self, asset_symbol: String, audit_hash: Hash, timestamp: Timestamp, + ) -> Result<(), ACCReserveError> { + let entry = self.reserves.get_mut(&asset_symbol) + .ok_or_else(|| ACCReserveError::ReserveNotFound(asset_symbol.clone()))?; + entry.last_audited = timestamp.clone(); + entry.audit_hash = audit_hash; + self.pending_events.push(ReserveProtocolEvent::ReserveAudited { asset: asset_symbol, audit_hash, timestamp }); + Ok(()) + } + pub fn get_reserve(&self, asset: &str) -> Option<&ReserveEntry> { self.reserves.get(asset) } + pub fn total_reserve_count(&self) -> usize { self.reserves.len() } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } + } diff --git a/nac-udm/src/l1_protocol/acc/acc_rwa.rs b/nac-udm/src/l1_protocol/acc/acc_rwa.rs index 83a7d32..553a978 100644 --- a/nac-udm/src/l1_protocol/acc/acc_rwa.rs +++ b/nac-udm/src/l1_protocol/acc/acc_rwa.rs @@ -1,48 +1,177 @@ -//! ACC协议模块 - -///! # ACC-RWA: RWA资产标准 +//! acc_rwa - NAC 原生协议实现 +//! 从 acc_remaining_protocols.rs 提取 use crate::primitives::{Address, Hash, Timestamp}; -use crate::l1_protocol::gnacs::GNACSCode; -use serde::{Deserialize, Serialize}; + use serde::{Deserialize, Serialize}; + use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ACCRWAAsset -pub struct ACCRWAAsset { - /// asset_id - pub asset_id: Hash, - /// gnacs_code - pub gnacs_code: GNACSCode, - /// owner - pub owner: Address, - /// valuation - pub valuation: u128, - /// custody_provider - pub custody_provider: Address, - /// legal_document_hash - pub legal_document_hash: Hash, - /// created_at - pub created_at: Timestamp, - /// last_updated - pub last_updated: Timestamp, -} - -impl ACCRWAAsset { - /// new - pub fn new(gnacs_code: GNACSCode, owner: Address, valuation: u128) -> Self { - Self { - asset_id: Hash::zero(), - gnacs_code, - owner, - valuation, - custody_provider: Address::zero(), - legal_document_hash: Hash::zero(), - created_at: Timestamp::now(), - last_updated: Timestamp::now(), + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + pub enum ACCRWAError { + AssetNotFound(Hash), + AssetAlreadyRegistered(Hash), + InvalidConstitutionalReceipt, + Unauthorized(Address), + ComplianceCheckFailed(String), + ValuationExpired(Hash), + AssetFrozen(Hash), + } + impl std::fmt::Display for ACCRWAError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::AssetNotFound(h) => write!(f, "RWA 资产不存在: {}", h.to_hex()), + Self::AssetAlreadyRegistered(h) => write!(f, "RWA 资产已注册: {}", h.to_hex()), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + Self::ComplianceCheckFailed(msg) => write!(f, "合规检查失败: {}", msg), + Self::ValuationExpired(h) => write!(f, "估值已过期: {}", h.to_hex()), + Self::AssetFrozen(h) => write!(f, "资产已冻结: {}", h.to_hex()), + } } } - /// update_valuation - pub fn update_valuation(&mut self, new_valuation: u128) { - self.valuation = new_valuation; - self.last_updated = Timestamp::now(); + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum RWAAssetType { + RealEstate, + CorporateBond, + GovernmentBond, + Commodity, + PrivateEquity, + Infrastructure, + IntellectualProperty, + NaturalResource, + Other, + } + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum RWAAssetStatus { Pending, Active, Frozen, Redeemed, Delisted } + + /// RWA 资产记录 + /// UID: nac.acc.RWAAssetRecord.v1 + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct RWAAssetRecord { + pub asset_id: Hash, + pub gnacs_code: String, + pub asset_type: RWAAssetType, + pub owner: Address, + pub issuer: Address, + pub total_supply: u128, + pub current_valuation_xtzh: u128, + pub jurisdiction: String, + pub status: RWAAssetStatus, + /// 法律文件哈希(SHA3-384) + pub legal_document_hash: Hash, + /// AI 合规评分(0-100) + pub ai_compliance_score: u8, + pub constitutional_receipt: Hash, + pub registered_at: Timestamp, + pub updated_at: Timestamp, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum RWAProtocolEvent { + AssetRegistered { asset_id: Hash, gnacs_code: String, owner: Address, valuation: u128, timestamp: Timestamp }, + AssetTransferred { asset_id: Hash, from: Address, to: Address, amount: u128, timestamp: Timestamp }, + AssetFrozen { asset_id: Hash, reason: String, timestamp: Timestamp, constitutional_receipt: Hash }, + AssetUnfrozen { asset_id: Hash, timestamp: Timestamp, constitutional_receipt: Hash }, + ValuationUpdated { asset_id: Hash, old_value: u128, new_value: u128, timestamp: Timestamp }, + } + + /// ACC-RWA 真实世界资产协议 + /// UID: nac.acc.ACCRWAProtocol.v1 + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ACCRWAProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub assets: HashMap, + /// 持仓(asset_id -> (address -> amount)) + pub holdings: HashMap>, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, + } + impl ACCRWAProtocol { + pub fn new() -> Self { + Self { + protocol_uid: "nac.acc.ACCRWAProtocol.v1".to_string(), + lens_protocol_vector: "ACC-RWA".to_string(), + assets: HashMap::new(), + holdings: HashMap::new(), + pending_events: Vec::new(), + created_at: Timestamp::now(), + updated_at: Timestamp::now(), + } + } + pub fn register_asset( + &mut self, gnacs_code: String, asset_type: RWAAssetType, owner: Address, issuer: Address, + total_supply: u128, initial_valuation_xtzh: u128, jurisdiction: String, + legal_document_hash: Hash, ai_compliance_score: u8, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result { + if constitutional_receipt.is_zero() { return Err(ACCRWAError::InvalidConstitutionalReceipt); } + if ai_compliance_score < 60 { + return Err(ACCRWAError::ComplianceCheckFailed(format!("AI 合规评分不足: {}/100", ai_compliance_score))); + } + let mut data = Vec::new(); + data.extend_from_slice(gnacs_code.as_bytes()); + data.extend_from_slice(owner.as_bytes()); + data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let asset_id = Hash::sha3_384(&data); + if self.assets.contains_key(&asset_id) { return Err(ACCRWAError::AssetAlreadyRegistered(asset_id)); } + let record = RWAAssetRecord { + asset_id, gnacs_code: gnacs_code.clone(), asset_type, owner: owner.clone(), issuer, + total_supply, current_valuation_xtzh: initial_valuation_xtzh, + jurisdiction, status: RWAAssetStatus::Active, + legal_document_hash, ai_compliance_score, constitutional_receipt, + registered_at: timestamp.clone(), updated_at: timestamp.clone(), + }; + let mut asset_holdings = HashMap::new(); + asset_holdings.insert(owner.clone(), total_supply); + self.holdings.insert(asset_id, asset_holdings); + self.assets.insert(asset_id, record); + self.pending_events.push(RWAProtocolEvent::AssetRegistered { + asset_id, gnacs_code, owner, valuation: initial_valuation_xtzh, timestamp, + }); + self.updated_at = Timestamp::now(); + Ok(asset_id) + } + pub fn transfer_asset( + &mut self, asset_id: Hash, from: Address, to: Address, amount: u128, timestamp: Timestamp, + ) -> Result<(), ACCRWAError> { + let asset = self.assets.get(&asset_id).ok_or(ACCRWAError::AssetNotFound(asset_id))?; + if asset.status == RWAAssetStatus::Frozen { return Err(ACCRWAError::AssetFrozen(asset_id)); } + let holdings = self.holdings.get_mut(&asset_id).ok_or(ACCRWAError::AssetNotFound(asset_id))?; + let from_balance = holdings.get(&from).copied().unwrap_or(0); + if from_balance < amount { + return Err(ACCRWAError::Unauthorized(from.clone())); + } + *holdings.get_mut(&from).unwrap() -= amount; + *holdings.entry(to.clone()).or_insert(0) += amount; + self.pending_events.push(RWAProtocolEvent::AssetTransferred { asset_id, from, to, amount, timestamp }); + Ok(()) + } + pub fn freeze_asset( + &mut self, asset_id: Hash, reason: String, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCRWAError> { + if constitutional_receipt.is_zero() { return Err(ACCRWAError::InvalidConstitutionalReceipt); } + let asset = self.assets.get_mut(&asset_id).ok_or(ACCRWAError::AssetNotFound(asset_id))?; + asset.status = RWAAssetStatus::Frozen; + asset.updated_at = timestamp.clone(); + self.pending_events.push(RWAProtocolEvent::AssetFrozen { asset_id, reason, timestamp, constitutional_receipt }); + Ok(()) + } + pub fn update_valuation( + &mut self, asset_id: Hash, new_valuation: u128, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCRWAError> { + if constitutional_receipt.is_zero() { return Err(ACCRWAError::InvalidConstitutionalReceipt); } + let asset = self.assets.get_mut(&asset_id).ok_or(ACCRWAError::AssetNotFound(asset_id))?; + let old_value = asset.current_valuation_xtzh; + asset.current_valuation_xtzh = new_valuation; + asset.updated_at = timestamp.clone(); + self.pending_events.push(RWAProtocolEvent::ValuationUpdated { asset_id, old_value, new_value: new_valuation, timestamp }); + Ok(()) + } + pub fn get_asset(&self, id: &Hash) -> Option<&RWAAssetRecord> { self.assets.get(id) } + pub fn balance_of(&self, asset_id: &Hash, holder: &Address) -> u128 { + self.holdings.get(asset_id).and_then(|h| h.get(holder)).copied().unwrap_or(0) + } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } } -} diff --git a/nac-udm/src/l1_protocol/acc/acc_valuation.rs b/nac-udm/src/l1_protocol/acc/acc_valuation.rs index 1311d8f..8e20073 100644 --- a/nac-udm/src/l1_protocol/acc/acc_valuation.rs +++ b/nac-udm/src/l1_protocol/acc/acc_valuation.rs @@ -1,49 +1,294 @@ -//! ACC协议模块 +//! ACC-Valuation: 资产估值协议 +//! UID: nac.acc.ACCValuationProtocol.v1 +//! +//! 完全规避以太坊模式,使用 NAC 原生类型系统: +//! - Address: 32字节 +//! - Hash: 48字节(SHA3-384) +//! - 通过 CBPP 宪法收据驱动状态变更 -///! # ACC-Valuation: 估值协议 use crate::primitives::{Address, Hash, Timestamp}; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ValuationReport -pub struct ValuationReport { - /// asset_id - pub asset_id: Hash, - /// valuation_amount - pub valuation_amount: u128, - /// currency - pub currency: String, - /// valuation_method - pub valuation_method: String, - /// appraiser - pub appraiser: Address, - /// report_date - pub report_date: Timestamp, - /// validity_period - pub validity_period: u64, - /// confidence_score - pub confidence_score: u8, - /// report_hash - pub report_hash: Hash, +/// ACC-Valuation 错误类型 +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +pub enum ACCValuationError { + AssetNotFound(Hash), + ValuationNotFound(Hash), + UnauthorizedAppraiser(Address), + ValuationExpired(Hash), + InvalidValuationAmount, + InsufficientAIConfidence { actual: u8, required: u8 }, + InvalidConstitutionalReceipt, + SDRConversionFailed(String), } -impl ValuationReport { - /// new - pub fn new(asset_id: Hash, valuation_amount: u128, appraiser: Address) -> Self { - Self { - asset_id, - valuation_amount, - currency: "USD".to_string(), - valuation_method: "Market Approach".to_string(), - appraiser, - report_date: Timestamp::now(), - validity_period: 180 * 24 * 3600, - confidence_score: 80, - report_hash: Hash::zero(), +impl std::fmt::Display for ACCValuationError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::AssetNotFound(h) => write!(f, "资产不存在: {}", h.to_hex()), + Self::ValuationNotFound(h) => write!(f, "估值记录不存在: {}", h.to_hex()), + Self::UnauthorizedAppraiser(a) => write!(f, "未授权估值机构: {}", a.to_hex()), + Self::ValuationExpired(h) => write!(f, "估值已过期: {}", h.to_hex()), + Self::InvalidValuationAmount => write!(f, "估值金额无效"), + Self::InsufficientAIConfidence { actual, required } => { + write!(f, "AI置信度不足: 实际 {},要求 {}", actual, required) + } + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::SDRConversionFailed(msg) => write!(f, "SDR转换失败: {}", msg), } } - /// is_valid +} + +/// 估值方法(NAC 原生) +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum ValuationMethod { + /// XTZH-AI-Engine 智能估值 + XTZHAIEngine, + /// 市场比较法 + MarketApproach, + /// 收益法 + IncomeApproach, + /// 成本法 + CostApproach, + /// SDR 锚定估值 + SDRAnchoredValuation, + /// 混合估值 + HybridApproach, + /// 独立第三方估值 + IndependentThirdParty, +} + +/// 估值记录 +/// UID: nac.acc.ValuationRecord.v1 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ValuationRecord { + pub valuation_id: Hash, + pub asset_id: Hash, + /// 估值金额(XTZH,精度18位) + pub amount_xtzh: u128, + /// 估值金额(SDR) + pub amount_sdr: u128, + pub method: ValuationMethod, + pub appraiser: Address, + /// AI 置信度(0-100) + pub ai_confidence: u8, + pub valuation_time: Timestamp, + /// 有效期(秒) + pub validity_secs: u64, + /// 估值报告哈希(SHA3-384,48字节) + pub report_hash: Hash, + /// 宪法收据哈希 + pub constitutional_receipt: Hash, + pub is_current: bool, +} + +impl ValuationRecord { pub fn is_valid(&self) -> bool { - !self.report_date.add_secs(self.validity_period).is_expired(Timestamp::now().as_secs()) + self.is_current && !self.valuation_time.is_expired(self.validity_secs) + } +} + +/// 估值协议事件 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ValuationProtocolEvent { + ValuationUpdated { + asset_id: Hash, + valuation_id: Hash, + old_value_xtzh: u128, + new_value_xtzh: u128, + method: ValuationMethod, + timestamp: Timestamp, + }, + AppraiserAuthorized { + appraiser: Address, + authorized_by: Address, + timestamp: Timestamp, + }, + AppraiserRevoked { + appraiser: Address, + revoked_by: Address, + timestamp: Timestamp, + }, +} + +/// ACC-Valuation 估值协议 +/// UID: nac.acc.ACCValuationProtocol.v1 +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ACCValuationProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + /// 当前估值注册表(asset_id -> 最新估值) + pub current_valuations: HashMap, + /// 历史估值 + pub valuation_history: HashMap>, + /// 授权估值机构 + pub authorized_appraisers: HashMap, + /// AI 置信度阈值(0-100) + pub ai_confidence_threshold: u8, + /// SDR 汇率(XTZH/SDR,精度18位) + pub sdr_exchange_rate: u128, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, +} + +impl ACCValuationProtocol { + pub fn new(ai_confidence_threshold: u8, sdr_exchange_rate: u128) -> Self { + Self { + protocol_uid: "nac.acc.ACCValuationProtocol.v1".to_string(), + lens_protocol_vector: "ACC-Valuation".to_string(), + current_valuations: HashMap::new(), + valuation_history: HashMap::new(), + authorized_appraisers: HashMap::new(), + ai_confidence_threshold, + sdr_exchange_rate, + pending_events: Vec::new(), + created_at: Timestamp::now(), + updated_at: Timestamp::now(), + } + } + + /// 授权估值机构 + pub fn authorize_appraiser( + &mut self, + appraiser: Address, + authorized_by: Address, + constitutional_receipt: Hash, + timestamp: Timestamp, + ) -> Result<(), ACCValuationError> { + if constitutional_receipt.is_zero() { + return Err(ACCValuationError::InvalidConstitutionalReceipt); + } + self.authorized_appraisers.insert(appraiser.clone(), timestamp.clone()); + self.pending_events.push(ValuationProtocolEvent::AppraiserAuthorized { + appraiser, + authorized_by, + timestamp, + }); + Ok(()) + } + + /// 提交资产估值 + pub fn submit_valuation( + &mut self, + asset_id: Hash, + amount_xtzh: u128, + method: ValuationMethod, + appraiser: Address, + ai_confidence: u8, + report_hash: Hash, + constitutional_receipt: Hash, + timestamp: Timestamp, + ) -> Result { + if !self.authorized_appraisers.contains_key(&appraiser) { + return Err(ACCValuationError::UnauthorizedAppraiser(appraiser)); + } + if ai_confidence < self.ai_confidence_threshold { + return Err(ACCValuationError::InsufficientAIConfidence { + actual: ai_confidence, + required: self.ai_confidence_threshold, + }); + } + if amount_xtzh == 0 { + return Err(ACCValuationError::InvalidValuationAmount); + } + let amount_sdr = if self.sdr_exchange_rate > 0 { + amount_xtzh / self.sdr_exchange_rate + } else { + 0 + }; + let old_value = self.current_valuations.get(&asset_id) + .map(|v| v.amount_xtzh) + .unwrap_or(0); + let mut val_data = Vec::new(); + val_data.extend_from_slice(asset_id.as_bytes()); + val_data.extend_from_slice(&amount_xtzh.to_be_bytes()); + val_data.extend_from_slice(×tamp.as_secs().to_be_bytes()); + let valuation_id = Hash::sha3_384(&val_data); + if let Some(old_val) = self.current_valuations.get_mut(&asset_id) { + old_val.is_current = false; + } + let record = ValuationRecord { + valuation_id, + asset_id, + amount_xtzh, + amount_sdr, + method, + appraiser: appraiser.clone(), + ai_confidence, + valuation_time: timestamp.clone(), + validity_secs: 180 * 24 * 3600, + report_hash, + constitutional_receipt, + is_current: true, + }; + self.valuation_history + .entry(asset_id) + .or_insert_with(Vec::new) + .push(record.clone()); + self.current_valuations.insert(asset_id, record); + self.pending_events.push(ValuationProtocolEvent::ValuationUpdated { + asset_id, + valuation_id, + old_value_xtzh: old_value, + new_value_xtzh: amount_xtzh, + method, + timestamp, + }); + self.updated_at = Timestamp::now(); + Ok(valuation_id) + } + + /// 查询资产当前估值 + pub fn get_current_valuation(&self, asset_id: &Hash) -> Option<&ValuationRecord> { + self.current_valuations.get(asset_id) + .filter(|v| v.is_valid()) + } + + /// 查询估值历史 + pub fn get_valuation_history(&self, asset_id: &Hash) -> &[ValuationRecord] { + self.valuation_history.get(asset_id) + .map(|v| v.as_slice()) + .unwrap_or(&[]) + } + + pub fn drain_pending_events(&mut self) -> Vec { + std::mem::take(&mut self.pending_events) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_submit_valuation() { + let mut proto = ACCValuationProtocol::new(70, 1_000_000_000_000_000_000u128); + let appraiser = Address::new([1u8; 32]); + let asset_id = Hash::sha3_384(b"asset1"); + let receipt = Hash::sha3_384(b"receipt"); + let ts = Timestamp::now(); + + proto.authorize_appraiser( + appraiser.clone(), + Address::new([9u8; 32]), + receipt.clone(), + ts.clone(), + ).unwrap(); + + let vid = proto.submit_valuation( + asset_id, + 1_000_000 * 10u128.pow(18), + ValuationMethod::XTZHAIEngine, + appraiser, + 85, + Hash::sha3_384(b"report"), + receipt, + ts, + ).unwrap(); + + assert!(!vid.is_zero()); + assert!(proto.get_current_valuation(&asset_id).is_some()); } } diff --git a/nac-udm/src/l1_protocol/acc/acc_xtzh.rs b/nac-udm/src/l1_protocol/acc/acc_xtzh.rs index fbad746..1146cd9 100644 --- a/nac-udm/src/l1_protocol/acc/acc_xtzh.rs +++ b/nac-udm/src/l1_protocol/acc/acc_xtzh.rs @@ -1,65 +1,172 @@ -//! ACC协议模块 - -///! # ACC-XTZH: XTZH稳定币协议 -#[allow(unused_imports)] +//! acc_xtzh - NAC 原生协议实现 +//! 从 acc_remaining_protocols.rs 提取 use crate::primitives::{Address, Hash, Timestamp}; -use serde::{Deserialize, Serialize}; + use serde::{Deserialize, Serialize}; + use std::collections::HashMap; -#[derive(Debug, Clone, Serialize, Deserialize)] -/// XTZHToken -pub struct XTZHToken { - /// total_supply - pub total_supply: u128, - /// sdr_peg_rate - pub sdr_peg_rate: u128, - /// gold_reserve_ratio - pub gold_reserve_ratio: u8, - /// balances - pub balances: std::collections::HashMap, - /// reserve_assets - pub reserve_assets: Vec, - /// last_rebalance - pub last_rebalance: Timestamp, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ReserveAsset -pub struct ReserveAsset { - /// asset_type - pub asset_type: ReserveAssetType, - /// amount - pub amount: u128, - /// weight - pub weight: u8, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -/// ReserveAssetType -pub enum ReserveAssetType { - /// Gold - Gold, - /// USD - USD, - /// EUR - EUR, - /// GBP - GBP, - /// JPY - JPY, - /// CNY - CNY, -} - -impl XTZHToken { - /// new - pub fn new() -> Self { - Self { - total_supply: 0, - sdr_peg_rate: 100_000_000, - gold_reserve_ratio: 40, - balances: std::collections::HashMap::new(), - reserve_assets: Vec::new(), - last_rebalance: Timestamp::now(), + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] + pub enum ACCXTZHError { + InsufficientBalance { holder: Address, available: u128, requested: u128 }, + InsufficientReserve { required: u128, available: u128 }, + InvalidConstitutionalReceipt, + Unauthorized(Address), + SDRPegViolation { current_rate: u128, min_rate: u128, max_rate: u128 }, + GoldReserveInsufficient { required_ratio: u8, actual_ratio: u8 }, + } + impl std::fmt::Display for ACCXTZHError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::InsufficientBalance { holder, available, requested } => write!(f, "余额不足 {}: 可用 {},请求 {}", holder.to_hex(), available, requested), + Self::InsufficientReserve { required, available } => write!(f, "储备不足: 需要 {},可用 {}", required, available), + Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), + Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), + Self::SDRPegViolation { current_rate, min_rate, max_rate } => write!(f, "SDR 锚定偏离: 当前 {},允许范围 [{}, {}]", current_rate, min_rate, max_rate), + Self::GoldReserveInsufficient { required_ratio, actual_ratio } => write!(f, "黄金储备不足: 要求 {}%,实际 {}%", required_ratio, actual_ratio), + } } } -} + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] + pub enum ReserveAssetType { Gold, USD, EUR, GBP, JPY, CNY, NACNative } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct ReserveAsset { + pub asset_type: ReserveAssetType, + pub amount: u128, + /// 权重(基点,10000=100%) + pub weight_bps: u16, + pub last_updated: Timestamp, + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + pub enum XTZHProtocolEvent { + Minted { recipient: Address, amount: u128, constitutional_receipt: Hash, timestamp: Timestamp }, + Burned { holder: Address, amount: u128, constitutional_receipt: Hash, timestamp: Timestamp }, + Transferred { from: Address, to: Address, amount: u128, timestamp: Timestamp }, + ReserveRebalanced { old_gold_ratio: u8, new_gold_ratio: u8, timestamp: Timestamp }, + SDRRateUpdated { old_rate: u128, new_rate: u128, timestamp: Timestamp }, + } + + /// XTZH 稳定币协议 + /// UID: nac.acc.XTZHStablecoinProtocol.v1 + /// SDR 锚定 + 黄金储备保障 + #[derive(Debug, Clone, Serialize, Deserialize)] + pub struct XTZHStablecoinProtocol { + pub protocol_uid: String, + pub lens_protocol_vector: String, + pub total_supply: u128, + /// 持仓(address -> 余额,精度18位) + pub holdings: HashMap, + /// 储备资产 + pub reserve_assets: Vec, + /// SDR 锚定汇率(XTZH/SDR,精度18位,1 XTZH = 1 SDR) + pub sdr_peg_rate: u128, + /// SDR 汇率允许偏差(基点,默认200=2%) + pub sdr_tolerance_bps: u16, + /// 黄金储备最低比例(百分比,默认40) + pub min_gold_reserve_ratio: u8, + /// 当前黄金储备比例 + pub current_gold_reserve_ratio: u8, + pub pending_events: Vec, + pub created_at: Timestamp, + pub updated_at: Timestamp, + } + impl XTZHStablecoinProtocol { + pub fn new(sdr_peg_rate: u128, min_gold_reserve_ratio: u8) -> Self { + Self { + protocol_uid: "nac.acc.XTZHStablecoinProtocol.v1".to_string(), + lens_protocol_vector: "ACC-XTZH".to_string(), + total_supply: 0, + holdings: HashMap::new(), + reserve_assets: Vec::new(), + sdr_peg_rate, + sdr_tolerance_bps: 200, + min_gold_reserve_ratio, + current_gold_reserve_ratio: 0, + pending_events: Vec::new(), + created_at: Timestamp::now(), + updated_at: Timestamp::now(), + } + } + pub fn mint( + &mut self, recipient: Address, amount: u128, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCXTZHError> { + if constitutional_receipt.is_zero() { return Err(ACCXTZHError::InvalidConstitutionalReceipt); } + if self.current_gold_reserve_ratio < self.min_gold_reserve_ratio { + return Err(ACCXTZHError::GoldReserveInsufficient { + required_ratio: self.min_gold_reserve_ratio, + actual_ratio: self.current_gold_reserve_ratio, + }); + } + *self.holdings.entry(recipient.clone()).or_insert(0) += amount; + self.total_supply = self.total_supply.saturating_add(amount); + self.pending_events.push(XTZHProtocolEvent::Minted { recipient, amount, constitutional_receipt, timestamp }); + self.updated_at = Timestamp::now(); + Ok(()) + } + pub fn burn( + &mut self, holder: Address, amount: u128, + constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCXTZHError> { + if constitutional_receipt.is_zero() { return Err(ACCXTZHError::InvalidConstitutionalReceipt); } + let balance = self.holdings.get(&holder).copied().unwrap_or(0); + if balance < amount { + return Err(ACCXTZHError::InsufficientBalance { holder: holder.clone(), available: balance, requested: amount }); + } + *self.holdings.get_mut(&holder).unwrap() -= amount; + self.total_supply = self.total_supply.saturating_sub(amount); + self.pending_events.push(XTZHProtocolEvent::Burned { holder, amount, constitutional_receipt, timestamp }); + self.updated_at = Timestamp::now(); + Ok(()) + } + pub fn transfer( + &mut self, from: Address, to: Address, amount: u128, timestamp: Timestamp, + ) -> Result<(), ACCXTZHError> { + let balance = self.holdings.get(&from).copied().unwrap_or(0); + if balance < amount { + return Err(ACCXTZHError::InsufficientBalance { holder: from.clone(), available: balance, requested: amount }); + } + *self.holdings.get_mut(&from).unwrap() -= amount; + *self.holdings.entry(to.clone()).or_insert(0) += amount; + self.pending_events.push(XTZHProtocolEvent::Transferred { from, to, amount, timestamp }); + Ok(()) + } + pub fn update_sdr_rate( + &mut self, new_rate: u128, constitutional_receipt: Hash, timestamp: Timestamp, + ) -> Result<(), ACCXTZHError> { + if constitutional_receipt.is_zero() { return Err(ACCXTZHError::InvalidConstitutionalReceipt); } + let tolerance = self.sdr_peg_rate * self.sdr_tolerance_bps as u128 / 10000; + let min_rate = self.sdr_peg_rate.saturating_sub(tolerance); + let max_rate = self.sdr_peg_rate.saturating_add(tolerance); + if new_rate < min_rate || new_rate > max_rate { + return Err(ACCXTZHError::SDRPegViolation { current_rate: new_rate, min_rate, max_rate }); + } + let old_rate = self.sdr_peg_rate; + self.sdr_peg_rate = new_rate; + self.pending_events.push(XTZHProtocolEvent::SDRRateUpdated { old_rate, new_rate, timestamp }); + Ok(()) + } + pub fn update_reserve( + &mut self, asset_type: ReserveAssetType, amount: u128, weight_bps: u16, timestamp: Timestamp, + ) { + if let Some(r) = self.reserve_assets.iter_mut().find(|r| r.asset_type == asset_type) { + r.amount = amount; + r.weight_bps = weight_bps; + r.last_updated = timestamp; + } else { + self.reserve_assets.push(ReserveAsset { asset_type, amount, weight_bps, last_updated: timestamp }); + } + self.recalculate_gold_ratio(); + } + fn recalculate_gold_ratio(&mut self) { + let total_weight: u16 = self.reserve_assets.iter().map(|r| r.weight_bps).sum(); + if total_weight == 0 { self.current_gold_reserve_ratio = 0; return; } + let gold_weight: u16 = self.reserve_assets.iter() + .filter(|r| r.asset_type == ReserveAssetType::Gold) + .map(|r| r.weight_bps).sum(); + self.current_gold_reserve_ratio = (gold_weight as u32 * 100 / total_weight as u32) as u8; + } + pub fn balance_of(&self, address: &Address) -> u128 { self.holdings.get(address).copied().unwrap_or(0) } + pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } + } diff --git a/nac-udm/src/l1_protocol/acc/mod.rs b/nac-udm/src/l1_protocol/acc/mod.rs index e32610d..c3553d1 100644 --- a/nac-udm/src/l1_protocol/acc/mod.rs +++ b/nac-udm/src/l1_protocol/acc/mod.rs @@ -1,41 +1,48 @@ -//! ACC协议模块 - -///! # ACC协议族 (Asset Classification & Compliance Protocol Suite) -///! -///! ACC协议族是NAC原生公链的核心协议标准,完全替代以太坊的ERC标准。 -///! -///! ## 13个ACC协议 -///! -///! ### 基础代币协议 -///! - **ACC-20**: 可替代代币标准(Fungible Token) -///! - **ACC-721**: 不可替代代币标准(Non-Fungible Token) -///! - **ACC-1155**: 多代币标准(Multi-Token) -///! -///! ### RWA专用协议 -///! - **ACC-RWA**: RWA资产标准 -///! - **ACC-Compliance**: 合规协议 -///! - **ACC-Valuation**: 估值协议 -///! - **ACC-Custody**: 托管协议 -///! - **ACC-Collateral**: 抵押协议 -///! - **ACC-Redemption**: 赎回协议 -///! - **ACC-Insurance**: 保险协议 -///! -///! ### 新增协议 -///! - **ACC-1594**: 收益分配协议 -///! - **ACC-1643**: 碎片化交易协议 -///! - **ACC-1644**: 跨链桥接协议 -///! - **ACC-1400**: 托管协议 -///! - **ACC-1410**: 保险协议 -///! -///! ### 治理与稳定币协议 -///! - **ACC-Governance**: 治理协议 -///! - **ACC-XTZH**: XTZH稳定币协议 -///! - **ACC-Reserve**: 储备协议 +//! ACC协议族 (Asset Classification & Compliance Protocol Suite) +//! +//! NAC原生公链核心协议标准,完全替代以太坊的ERC标准。 +//! 所有协议使用 Charter 语言编写,基于 NVM 虚拟机执行。 +//! +//! ## 完整 ACC 协议族(22个协议) +//! +//! ### 基础代币协议(4个) +//! - **ACC-20**: 可替代代币标准(Fungible Token) +//! - **ACC-20 Enhanced**: 增强可替代代币(含GNACS/主权/合规/估值/碎片化) +//! - **ACC-721**: 不可替代代币标准(Non-Fungible Token,含AssetDNA) +//! - **ACC-1155**: 多代币标准(Fungible + NFT 混合) +//! +//! ### RWA 专用协议族(8个) +//! - **ACC-RWA**: RWA 真实世界资产注册与转移协议 +//! - **ACC-Compliance**: 七层合规验证协议(KYC/AML/司法管辖区/AI评分/宪法合规) +//! - **ACC-Valuation**: AI 驱动资产估值协议(CNNL 接口) +//! - **ACC-Custody**: 资产托管协议(多级托管/托管人管理) +//! - **ACC-Collateral**: 抵押协议(抵押率/清算阈值/XTZH计价) +//! - **ACC-Redemption**: 赎回协议(赎回窗口/赎回资金池) +//! - **ACC-Insurance**: 资产保险协议(保险单/理赔/保险资金池) +//! - **ACC-Governance**: 治理协议(提案/投票/法定人数/执行) +//! +//! ### 稳定币与储备协议(2个) +//! - **ACC-XTZH**: XTZH 稳定币协议(SDR锚定+黄金储备) +//! - **ACC-Reserve**: 多资产储备协议(审计/存取/储备率) +//! +//! ### 辅助工具(2个) +//! - **ACC-Performance**: 资产性能监控模块 +//! - **XTZH-AI-Engine**: XTZH AI 稳定性引擎 +//! +//! ### 证券代币协议族(5个,符合国际证券代币标准) +//! - **ACC-1410**: 分区代币协议(股权分区/分红/投票/转让限制) +//! - **ACC-1400**: 证券代币协议(合规+股息+投票,继承 ACC-1410) +//! - **ACC-1594**: 收益分配协议(发行/赎回/分红,依赖 ACC-1410+1400) +//! - **ACC-1643**: 文档管理协议(链上文档版本控制/法律文件哈希) +//! - **ACC-1644**: 监管控制协议(冻结/强制转移/监管接管) +// === 基础代币协议 === pub mod acc20; pub mod acc20_enhanced; pub mod acc721; pub mod acc1155; + +// === RWA 专用协议族 === pub mod acc_rwa; pub mod acc_compliance; pub mod acc_valuation; @@ -44,25 +51,30 @@ pub mod acc_collateral; pub mod acc_redemption; pub mod acc_insurance; pub mod acc_governance; + +// === 稳定币与储备协议 === pub mod acc_xtzh; pub mod acc_reserve; -/// ACC资产性能监控模块 + +// === 辅助工具 === +/// ACC 资产性能监控模块 pub mod acc_performance; -/// XTZH AI引擎模块 +/// XTZH AI 稳定性引擎 pub mod xtzh_ai_engine; -// 新增协议模块 -/// ACC-1594: 收益分配协议 -pub mod acc1594; -/// ACC-1643: 碎片化交易协议 -pub mod acc1643; -/// ACC-1644: 跨链桥接协议 -pub mod acc1644; -/// ACC-1400: 托管协议 -pub mod acc1400; -/// ACC-1410: 保险协议 +// === 证券代币协议族 === +/// ACC-1410: 分区代币协议(股权分区/分红/投票/转让限制) pub mod acc1410; +/// ACC-1400: 证券代币协议(合规+股息+投票,继承 ACC-1410) +pub mod acc1400; +/// ACC-1594: 收益分配协议(发行/赎回/分红) +pub mod acc1594; +/// ACC-1643: 文档管理协议(链上文档版本控制) +pub mod acc1643; +/// ACC-1644: 监管控制协议(冻结/强制转移/监管接管) +pub mod acc1644; +// === 公开导出 === pub use acc20::*; pub use acc20_enhanced::*; pub use acc721::*; @@ -76,13 +88,13 @@ pub use acc_redemption::*; pub use acc_insurance::*; pub use acc_governance::*; pub use acc_xtzh::*; -// 新增协议导出(具体类型,避免 Result 类型冲突) + // ACC-1410: 分区代币协议 pub use acc1410::{ Acc1410, Acc1410Error, ExtendedGNACS, GNACSExtension, PartitionInfo, PartitionType, OperatorManager, TransferManager, PartitionManager, }; -// ACC-1400: 证券代币协议(继承自 acc1410,直接导出 Acc1400 结构体) +// ACC-1400: 证券代币协议 pub use acc1400::Acc1400; // ACC-1594: 收益分配协议 pub use acc1594::{