286 lines
11 KiB
Rust
286 lines
11 KiB
Rust
// NAC RWA 全球资产上链法律要素抽象数据模型
|
||
// 版本:1.0.0
|
||
// 覆盖:资产类型、产权结构、合约要件、税收要素、跨境规则
|
||
//
|
||
// 架构层次:
|
||
// Layer 0: 金融合规层(AML/KYC)— nac-jurisdiction-rules 已实现
|
||
// Layer 1: 资产身份层(asset_types + ownership)— 本模块
|
||
// Layer 2: 产权登记层(ownership)— 本模块
|
||
// Layer 3: 合约模板层(contract_elements)— 本模块(抽象层),辖区适配器见各辖区模块
|
||
// Layer 4: 税收计算层(tax_elements)— 本模块
|
||
// Layer 5: 跨境规则层(cross_border)— 本模块
|
||
|
||
pub mod asset_types;
|
||
pub mod ownership;
|
||
pub mod contract_elements;
|
||
pub mod tax_elements;
|
||
pub mod cross_border;
|
||
|
||
// 重新导出核心类型,方便使用
|
||
pub use asset_types::{AssetCategory, RealEstateSubtype, MovablePropertySubtype, IPSubtype,
|
||
FinancialAssetSubtype, CommoditySubtype, DigitalAssetSubtype,
|
||
NaturalResourceSubtype};
|
||
pub use ownership::{LegalSystem, LegalEntityType, PropertyRightsBundle, OwnershipForm,
|
||
EncumbranceStatus};
|
||
pub use contract_elements::{ContractType, ContractCoreElements, ContractParty, PartyRole,
|
||
KycLevel, ContractFormRequirement, DisputeResolution,
|
||
ArbitrationBody, DisputeMechanism, DeliveryTerms,
|
||
RiskTransferPoint, RequiredDocument, DocumentType};
|
||
pub use tax_elements::{TaxType, TaxRateStructure, JurisdictionTaxRule, DoubleTaxationAgreement,
|
||
TaxpayerType, find_dta, get_major_dta_database};
|
||
pub use cross_border::{TradeAgreementType, TechnicalStandardSystem, BilateralCrossBorderRules,
|
||
TariffRule, find_bilateral_rules, get_bilateral_rules_database,
|
||
TradeControlType};
|
||
|
||
/// RWA 资产上链完整法律要素包
|
||
/// 这是一笔 RWA 资产上链所需的全部法律信息的聚合
|
||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||
pub struct RWALegalPackage {
|
||
/// 资产类别
|
||
pub asset_category: AssetCategory,
|
||
/// 产权束
|
||
pub property_rights: PropertyRightsBundle,
|
||
/// 资产所在辖区
|
||
pub asset_jurisdiction: String,
|
||
/// 资产持有人所在辖区
|
||
pub holder_jurisdiction: String,
|
||
/// 法律体系
|
||
pub legal_system: LegalSystem,
|
||
/// 适用合约类型列表
|
||
pub applicable_contracts: Vec<ContractType>,
|
||
/// 必要文件清单
|
||
pub required_documents: Vec<contract_elements::RequiredDocument>,
|
||
/// 适用税收规则
|
||
pub applicable_taxes: Vec<JurisdictionTaxRule>,
|
||
/// 适用双边税收协定
|
||
pub applicable_dta: Option<DoubleTaxationAgreement>,
|
||
/// 跨境规则(如涉及跨境交易)
|
||
pub cross_border_rules: Option<BilateralCrossBorderRules>,
|
||
/// 是否需要伊斯兰合规
|
||
pub sharia_compliance_required: bool,
|
||
/// 验证状态
|
||
pub validation_status: ValidationStatus,
|
||
}
|
||
|
||
/// 验证状态
|
||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
|
||
pub enum ValidationStatus {
|
||
/// 未验证
|
||
Pending,
|
||
/// 验证通过
|
||
Approved,
|
||
/// 验证失败
|
||
Rejected(String),
|
||
/// 需要人工审核
|
||
ManualReviewRequired(String),
|
||
}
|
||
|
||
impl RWALegalPackage {
|
||
/// 执行基础验证
|
||
pub fn validate(&self) -> ValidationStatus {
|
||
// 检查产权是否可以上链
|
||
if let Err(reason) = self.property_rights.can_be_tokenized() {
|
||
return ValidationStatus::Rejected(reason);
|
||
}
|
||
|
||
// 检查是否有适用合约
|
||
if self.applicable_contracts.is_empty() {
|
||
return ValidationStatus::Rejected("未指定适用合约类型".to_string());
|
||
}
|
||
|
||
// 检查伊斯兰合规
|
||
if self.sharia_compliance_required {
|
||
let has_sharia_contract = self.applicable_contracts.iter().any(|c| {
|
||
matches!(
|
||
c,
|
||
ContractType::MurabahaContract
|
||
| ContractType::IjaraContract
|
||
| ContractType::SukukContract
|
||
| ContractType::MusharakaContract
|
||
| ContractType::MudarabaContract
|
||
)
|
||
});
|
||
if !has_sharia_contract {
|
||
return ValidationStatus::ManualReviewRequired(
|
||
"需要伊斯兰合规合约,但未指定".to_string(),
|
||
);
|
||
}
|
||
}
|
||
|
||
ValidationStatus::Approved
|
||
}
|
||
|
||
/// 获取适用的 DTA(如涉及跨境)
|
||
pub fn lookup_dta(&self) -> Option<DoubleTaxationAgreement> {
|
||
if self.asset_jurisdiction != self.holder_jurisdiction {
|
||
find_dta(&self.asset_jurisdiction, &self.holder_jurisdiction)
|
||
} else {
|
||
None
|
||
}
|
||
}
|
||
|
||
/// 获取跨境规则
|
||
pub fn lookup_cross_border_rules(&self) -> Option<BilateralCrossBorderRules> {
|
||
if self.asset_jurisdiction != self.holder_jurisdiction {
|
||
find_bilateral_rules(&self.asset_jurisdiction, &self.holder_jurisdiction)
|
||
} else {
|
||
None
|
||
}
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
#[allow(unused_imports)]
|
||
use crate::ownership::{OwnershipRight, UsageRight, IncomeRight, DisposalRight};
|
||
|
||
fn make_clean_rights() -> PropertyRightsBundle {
|
||
PropertyRightsBundle::clean_freehold(LegalEntityType::NaturalPerson)
|
||
}
|
||
|
||
#[test]
|
||
fn test_rwa_package_cn_real_estate() {
|
||
let package = RWALegalPackage {
|
||
asset_category: AssetCategory::RealEstate(RealEstateSubtype::Residential),
|
||
property_rights: make_clean_rights(),
|
||
asset_jurisdiction: "CN".to_string(),
|
||
holder_jurisdiction: "CN".to_string(),
|
||
legal_system: LegalSystem::CivilLaw,
|
||
applicable_contracts: vec![ContractType::RealEstateSaleContract],
|
||
required_documents: vec![],
|
||
applicable_taxes: vec![],
|
||
applicable_dta: None,
|
||
cross_border_rules: None,
|
||
sharia_compliance_required: false,
|
||
validation_status: ValidationStatus::Pending,
|
||
};
|
||
|
||
let status = package.validate();
|
||
assert_eq!(status, ValidationStatus::Approved);
|
||
}
|
||
|
||
#[test]
|
||
fn test_rwa_package_ae_sharia_required() {
|
||
let package = RWALegalPackage {
|
||
asset_category: AssetCategory::FinancialAsset(FinancialAssetSubtype::Bond),
|
||
property_rights: make_clean_rights(),
|
||
asset_jurisdiction: "AE".to_string(),
|
||
holder_jurisdiction: "AE".to_string(),
|
||
legal_system: LegalSystem::ShariaLaw,
|
||
applicable_contracts: vec![ContractType::BondSubscriptionAgreement], // 普通债券,非 Sukuk
|
||
required_documents: vec![],
|
||
applicable_taxes: vec![],
|
||
applicable_dta: None,
|
||
cross_border_rules: None,
|
||
sharia_compliance_required: true, // 需要伊斯兰合规
|
||
validation_status: ValidationStatus::Pending,
|
||
};
|
||
|
||
let status = package.validate();
|
||
// 应该要求人工审核,因为没有伊斯兰合规合约
|
||
assert!(matches!(status, ValidationStatus::ManualReviewRequired(_)));
|
||
}
|
||
|
||
#[test]
|
||
fn test_rwa_package_ae_sukuk() {
|
||
let package = RWALegalPackage {
|
||
asset_category: AssetCategory::FinancialAsset(FinancialAssetSubtype::Sukuk),
|
||
property_rights: make_clean_rights(),
|
||
asset_jurisdiction: "AE".to_string(),
|
||
holder_jurisdiction: "AE".to_string(),
|
||
legal_system: LegalSystem::ShariaLaw,
|
||
applicable_contracts: vec![ContractType::SukukContract], // 正确的伊斯兰合约
|
||
required_documents: vec![],
|
||
applicable_taxes: vec![],
|
||
applicable_dta: None,
|
||
cross_border_rules: None,
|
||
sharia_compliance_required: true,
|
||
validation_status: ValidationStatus::Pending,
|
||
};
|
||
|
||
let status = package.validate();
|
||
assert_eq!(status, ValidationStatus::Approved);
|
||
}
|
||
|
||
#[test]
|
||
fn test_rwa_package_cross_border_lookup() {
|
||
let package = RWALegalPackage {
|
||
asset_category: AssetCategory::RealEstate(RealEstateSubtype::Commercial),
|
||
property_rights: make_clean_rights(),
|
||
asset_jurisdiction: "JP".to_string(),
|
||
holder_jurisdiction: "CN".to_string(), // 中国人买日本不动产
|
||
legal_system: LegalSystem::CivilLaw,
|
||
applicable_contracts: vec![ContractType::RealEstateSaleContract],
|
||
required_documents: vec![],
|
||
applicable_taxes: vec![],
|
||
applicable_dta: None,
|
||
cross_border_rules: None,
|
||
sharia_compliance_required: false,
|
||
validation_status: ValidationStatus::Pending,
|
||
};
|
||
|
||
// 查找 DTA
|
||
let dta = package.lookup_dta();
|
||
assert!(dta.is_some());
|
||
assert_eq!(dta.unwrap().dividend_withholding_rate, 10.0);
|
||
|
||
// 查找跨境规则
|
||
let rules = package.lookup_cross_border_rules();
|
||
assert!(rules.is_some());
|
||
assert_eq!(rules.unwrap().trade_agreement, TradeAgreementType::Rcep);
|
||
}
|
||
|
||
#[test]
|
||
fn test_seized_asset_rejected() {
|
||
let mut rights = make_clean_rights();
|
||
rights.encumbrance.has_seizure = true;
|
||
|
||
let package = RWALegalPackage {
|
||
asset_category: AssetCategory::RealEstate(RealEstateSubtype::Residential),
|
||
property_rights: rights,
|
||
asset_jurisdiction: "CN".to_string(),
|
||
holder_jurisdiction: "CN".to_string(),
|
||
legal_system: LegalSystem::CivilLaw,
|
||
applicable_contracts: vec![ContractType::RealEstateSaleContract],
|
||
required_documents: vec![],
|
||
applicable_taxes: vec![],
|
||
applicable_dta: None,
|
||
cross_border_rules: None,
|
||
sharia_compliance_required: false,
|
||
validation_status: ValidationStatus::Pending,
|
||
};
|
||
|
||
let status = package.validate();
|
||
assert!(matches!(status, ValidationStatus::Rejected(_)));
|
||
}
|
||
|
||
#[test]
|
||
fn test_ip_cross_border_cn_us() {
|
||
let package = RWALegalPackage {
|
||
asset_category: AssetCategory::IntellectualProperty(IPSubtype::InventionPatent),
|
||
property_rights: make_clean_rights(),
|
||
asset_jurisdiction: "CN".to_string(),
|
||
holder_jurisdiction: "US".to_string(),
|
||
legal_system: LegalSystem::CommonLaw,
|
||
applicable_contracts: vec![ContractType::PatentLicenseNonExclusive],
|
||
required_documents: vec![],
|
||
applicable_taxes: vec![],
|
||
applicable_dta: None,
|
||
cross_border_rules: None,
|
||
sharia_compliance_required: false,
|
||
validation_status: ValidationStatus::Pending,
|
||
};
|
||
|
||
// 验证通过
|
||
assert_eq!(package.validate(), ValidationStatus::Approved);
|
||
|
||
// 查找跨境规则(中美)
|
||
let rules = package.lookup_cross_border_rules();
|
||
assert!(rules.is_some());
|
||
// 中美之间有出口管制
|
||
let rules = rules.unwrap();
|
||
assert!(!rules.trade_controls.is_empty());
|
||
}
|
||
}
|