Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
443 changes: 233 additions & 210 deletions contracts/analytics/src/lib.rs

Large diffs are not rendered by default.

182 changes: 104 additions & 78 deletions contracts/compliance_registry/lib.rs

Large diffs are not rendered by default.

77 changes: 56 additions & 21 deletions contracts/fees/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ mod propchain_fees {
const MAX_CONGESTION_MULTIPLIER: u32 = 300; // 300% of base

#[derive(Debug, Clone, PartialEq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
pub struct FeeConfig {
/// Base fee per operation (in smallest unit)
pub base_fee: u128,
Expand All @@ -41,7 +44,10 @@ mod propchain_fees {

/// Single data point for congestion/demand history (reserved for future analytics)
#[derive(Debug, Clone, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
#[allow(dead_code)]
pub struct FeeHistoryEntry {
pub timestamp: u64,
Expand All @@ -51,7 +57,10 @@ mod propchain_fees {

/// Premium listing auction
#[derive(Debug, Clone, PartialEq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
pub struct PremiumAuction {
pub property_id: u64,
pub seller: AccountId,
Expand All @@ -65,7 +74,10 @@ mod propchain_fees {

/// Bid in a premium auction
#[derive(Debug, Clone, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
pub struct AuctionBid {
pub bidder: AccountId,
pub amount: u128,
Expand All @@ -74,7 +86,10 @@ mod propchain_fees {

/// Reward record for validators/participants
#[derive(Debug, Clone, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
pub struct RewardRecord {
pub account: AccountId,
pub amount: u128,
Expand All @@ -83,7 +98,10 @@ mod propchain_fees {
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
pub enum RewardReason {
ValidatorReward,
LiquidityProvider,
Expand All @@ -93,10 +111,13 @@ mod propchain_fees {

/// Fee report for transparency and dashboard
#[derive(Debug, Clone, PartialEq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
pub struct FeeReport {
pub config: FeeConfig,
pub congestion_index: u32, // 0-100
pub congestion_index: u32, // 0-100
pub recommended_fee: u128,
pub total_fees_collected: u128,
pub total_distributed: u128,
Expand All @@ -107,7 +128,10 @@ mod propchain_fees {

/// Fee estimate for a user (optimization recommendation)
#[derive(Debug, Clone, PartialEq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout))]
#[cfg_attr(
feature = "std",
derive(scale_info::TypeInfo, ink::storage::traits::StorageLayout)
)]
pub struct FeeEstimate {
pub operation: FeeOperation,
pub estimated_fee: u128,
Expand Down Expand Up @@ -242,11 +266,7 @@ mod propchain_fees {

impl FeeManager {
#[ink(constructor)]
pub fn new(
base_fee: u128,
min_fee: u128,
max_fee: u128,
) -> Self {
pub fn new(base_fee: u128, min_fee: u128, max_fee: u128) -> Self {
let caller = Self::env().caller();
let timestamp = Self::env().block_timestamp();
let default_config = FeeConfig {
Expand Down Expand Up @@ -275,7 +295,7 @@ mod propchain_fees {
validators: Mapping::default(),
validator_list: Vec::new(),
validator_share_bp: 5000, // 50% to validators
treasury_share_bp: 5000, // 50% to treasury
treasury_share_bp: 5000, // 50% to treasury
}
}

Expand All @@ -288,7 +308,9 @@ mod propchain_fees {

/// Get config for operation (operation-specific or default)
fn get_config(&self, op: FeeOperation) -> FeeConfig {
self.operation_config.get(op).unwrap_or(self.default_config.clone())
self.operation_config
.get(op)
.unwrap_or(self.default_config.clone())
}

/// Compute current congestion index (0-100) from recent activity
Expand All @@ -306,7 +328,10 @@ mod propchain_fees {
/// Demand factor in basis points (from recent volume)
fn demand_factor_bp(&self) -> u32 {
let ci = self.congestion_index();
self.default_config.demand_factor_bp.saturating_mul(ci).saturating_div(100)
self.default_config
.demand_factor_bp
.saturating_mul(ci)
.saturating_div(100)
}

// ========== Dynamic fee calculation ==========
Expand All @@ -329,7 +354,10 @@ mod propchain_fees {
from: AccountId,
) -> Result<(), FeeError> {
let _ = from;
self.recent_ops_count = self.recent_ops_count.saturating_add(1).min(CONGESTION_WINDOW);
self.recent_ops_count = self
.recent_ops_count
.saturating_add(1)
.min(CONGESTION_WINDOW);
let now = self.env().block_timestamp();
if now.saturating_sub(self.last_congestion_reset) > 3600 {
self.last_congestion_reset = now;
Expand Down Expand Up @@ -440,7 +468,10 @@ mod propchain_fees {
pub fn place_bid(&mut self, auction_id: u64, amount: u128) -> Result<(), FeeError> {
let caller = self.env().caller();
let now = self.env().block_timestamp();
let mut auction = self.auctions.get(auction_id).ok_or(FeeError::AuctionNotFound)?;
let mut auction = self
.auctions
.get(auction_id)
.ok_or(FeeError::AuctionNotFound)?;
if auction.settled {
return Err(FeeError::AlreadySettled);
}
Expand Down Expand Up @@ -478,7 +509,10 @@ mod propchain_fees {
#[ink(message)]
pub fn settle_auction(&mut self, auction_id: u64) -> Result<(), FeeError> {
let now = self.env().block_timestamp();
let mut auction = self.auctions.get(auction_id).ok_or(FeeError::AuctionNotFound)?;
let mut auction = self
.auctions
.get(auction_id)
.ok_or(FeeError::AuctionNotFound)?;
if auction.settled {
return Err(FeeError::AlreadySettled);
}
Expand Down Expand Up @@ -563,7 +597,8 @@ mod propchain_fees {
let per_validator = validator_total.saturating_div(validator_count as u128);
for acc in validator_list {
let current = self.pending_rewards.get(acc).unwrap_or(0);
self.pending_rewards.insert(acc, &current.saturating_add(per_validator));
self.pending_rewards
.insert(acc, &current.saturating_add(per_validator));
self.record_reward(acc, per_validator, RewardReason::ValidatorReward);
self.total_distributed = self.total_distributed.saturating_add(per_validator);
self.env().emit_event(RewardsDistributed {
Expand Down
1 change: 0 additions & 1 deletion contracts/fractional/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,3 @@ mod fractional {
}
}
}

18 changes: 12 additions & 6 deletions contracts/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,13 @@ mod propchain_contracts {
}

#[derive(
Debug, Clone, PartialEq, Eq, scale::Encode, scale::Decode, ink::storage::traits::StorageLayout,
Debug,
Clone,
PartialEq,
Eq,
scale::Encode,
scale::Decode,
ink::storage::traits::StorageLayout,
)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub struct FractionalInfo {
Expand Down Expand Up @@ -832,10 +838,7 @@ mod propchain_contracts {

/// Set the fee manager contract address (admin only)
#[ink(message)]
pub fn set_fee_manager(
&mut self,
fee_manager: Option<AccountId>,
) -> Result<(), Error> {
pub fn set_fee_manager(&mut self, fee_manager: Option<AccountId>) -> Result<(), Error> {
let caller = self.env().caller();
if caller != self.admin {
return Err(Error::Unauthorized);
Expand Down Expand Up @@ -2541,7 +2544,10 @@ mod propchain_contracts {
total_shares: u128,
) -> Result<(), Error> {
let caller = self.env().caller();
let property = self.properties.get(property_id).ok_or(Error::PropertyNotFound)?;
let property = self
.properties
.get(property_id)
.ok_or(Error::PropertyNotFound)?;
if caller != self.admin && caller != property.owner {
return Err(Error::Unauthorized);
}
Expand Down
14 changes: 5 additions & 9 deletions contracts/lib/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1819,14 +1819,8 @@ mod tests {
#[ink::test]
fn test_get_dynamic_fee_without_manager_returns_zero() {
let contract = PropertyRegistry::new();
assert_eq!(
contract.get_dynamic_fee(FeeOperation::RegisterProperty),
0
);
assert_eq!(
contract.get_dynamic_fee(FeeOperation::TransferProperty),
0
);
assert_eq!(contract.get_dynamic_fee(FeeOperation::RegisterProperty), 0);
assert_eq!(contract.get_dynamic_fee(FeeOperation::TransferProperty), 0);
}

#[ink::test]
Expand All @@ -1848,7 +1842,9 @@ mod tests {
let accounts = default_accounts();
set_caller(accounts.alice);
let mut contract = PropertyRegistry::new();
contract.set_fee_manager(Some(AccountId::from([0x42; 32]))).unwrap();
contract
.set_fee_manager(Some(AccountId::from([0x42; 32])))
.unwrap();
assert!(contract.set_fee_manager(None).is_ok());
assert_eq!(contract.get_fee_manager(), None);
}
Expand Down
Loading
Loading