Skip to content

Commit 7e4bd5f

Browse files
committed
Merge main into PR 1045
2 parents 03e8d15 + 8a02606 commit 7e4bd5f

16 files changed

Lines changed: 1362 additions & 40 deletions

File tree

AUDIT_LOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# 🛡️ Automated Security & Mutation Audit Log
2-
Generated on: Mon Aug 24 03:07:26 UTC 2026
2+
Generated on: Tue Aug 25 03:02:28 UTC 2026
33
---
44
## 📦 Dependency License & Advisory Checks (cargo-deny)
55
```text

Cargo.lock

Lines changed: 5 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

contracts/analytics/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use ink::prelude::string::String;
77
use ink::prelude::vec::Vec;
88

99
#[ink::contract]
10-
mod propchain_analytics {
10+
pub mod propchain_analytics {
1111
use super::*;
1212

1313
/// Market metrics representing aggregated property data.

contracts/database/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use ink::prelude::vec::Vec;
3131
use ink::storage::Mapping;
3232

3333
#[ink::contract]
34-
mod propchain_database {
34+
pub mod propchain_database {
3535
use super::*;
3636

3737
// Data types extracted to types.rs (Issue #101)
@@ -575,5 +575,7 @@ mod propchain_database {
575575
// UNIT TESTS
576576
// ========================================================================
577577

578-
// Unit tests extracted to tests.rs (Issue #101)
578+
// Include unit tests (extracted to tests.rs per Issue #101)
579+
#[cfg(test)]
580+
include!("tests.rs");
579581
}

contracts/fees/src/lib.rs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use propchain_traits::{DynamicFeeProvider, FeeOperation};
1717
// every test after every include isn't worth the structural churn, so
1818
// suppress the lint here.
1919
#[allow(clippy::items_after_test_module)]
20-
mod propchain_fees {
20+
pub mod propchain_fees {
2121
use super::*;
2222

2323
/// Basis points denominator (10000 = 100%)
@@ -413,18 +413,27 @@ mod propchain_fees {
413413
Ok(())
414414
}
415415

416+
/// Returns the premium listing auction with the given id, if it exists.
416417
#[ink(message)]
417418
pub fn get_auction(&self, auction_id: u64) -> Option<PremiumAuction> {
418419
self.auctions.get(auction_id)
419420
}
420421

422+
/// Returns the total number of premium listing auctions created so far.
423+
///
424+
/// Auction ids are assigned sequentially starting at 1, so this value is
425+
/// also the highest allocated auction id.
421426
#[ink(message)]
422427
pub fn get_auction_count(&self) -> u64 {
423428
self.auction_count
424429
}
425430

426431
// ========== Incentives and distribution ==========
427432

433+
/// Registers `account` as a fee validator eligible for reward distribution.
434+
///
435+
/// Caller requirement: admin only (`FeeError::Unauthorized` otherwise).
436+
/// Idempotent: registering an already-active validator is a no-op.
428437
#[ink(message)]
429438
pub fn add_validator(&mut self, account: AccountId) -> Result<(), FeeError> {
430439
self.ensure_admin()?;
@@ -436,6 +445,11 @@ mod propchain_fees {
436445
Ok(())
437446
}
438447

448+
/// Removes `account` from the fee validator set.
449+
///
450+
/// Caller requirement: admin only (`FeeError::Unauthorized` otherwise).
451+
/// Removing an address that was never registered succeeds silently.
452+
/// Any pending rewards for the removed validator remain claimable.
439453
#[ink(message)]
440454
pub fn remove_validator(&mut self, account: AccountId) -> Result<(), FeeError> {
441455
self.ensure_admin()?;
@@ -444,6 +458,12 @@ mod propchain_fees {
444458
Ok(())
445459
}
446460

461+
/// Sets how collected fees are split between validators and the treasury.
462+
///
463+
/// Both shares are expressed in basis points (1 bps = 0.01%, denominator
464+
/// 10_000). The two shares must not sum to more than 10_000 bps, otherwise
465+
/// `FeeError::InvalidConfig` is returned and nothing changes.
466+
/// Caller requirement: admin only (`FeeError::Unauthorized` otherwise).
447467
#[ink(message)]
448468
pub fn set_distribution_rates(
449469
&mut self,
@@ -525,6 +545,11 @@ mod propchain_fees {
525545
Ok(amount)
526546
}
527547

548+
/// Returns the reward amount currently claimable by `account`.
549+
///
550+
/// Balances accrue via `distribute_fees` (validator share) and are
551+
/// claimed with `claim_rewards`; accounts with no pending rewards
552+
/// report 0.
528553
#[ink(message)]
529554
pub fn pending_reward(&self, account: AccountId) -> u128 {
530555
self.pending_rewards.get(account).unwrap_or(0)
@@ -615,16 +640,30 @@ mod propchain_fees {
615640
rec
616641
}
617642

643+
/// Returns the admin account configured at deployment.
644+
///
645+
/// The admin is the sole caller allowed to change fee parameters,
646+
/// validator membership, and distribution rates.
618647
#[ink(message)]
619648
pub fn admin(&self) -> AccountId {
620649
self.admin
621650
}
622651

652+
/// Returns the fixed `FeeConfig` (base/min/max fee in planck units)
653+
/// captured at construction time.
654+
///
655+
/// This is the immutable baseline; live parameters are reflected in
656+
/// `get_fee_report` instead.
623657
#[ink(message)]
624658
pub fn default_config(&self) -> FeeConfig {
625659
self.default_config.clone()
626660
}
627661

662+
/// Returns the current unallocated treasury balance available for
663+
/// distribution.
664+
///
665+
/// Funds enter via `record_fee_collected` and leave when the admin
666+
/// calls `distribute_fees`.
628667
#[ink(message)]
629668
pub fn fee_treasury(&self) -> u128 {
630669
self.fee_treasury
@@ -696,6 +735,11 @@ mod propchain_fees {
696735
}
697736

698737
impl DynamicFeeProvider for FeeManager {
738+
/// Recommended fee for `operation` under the dynamic fee model.
739+
///
740+
/// Delegates to `calculate_fee`, which applies the configured base fee
741+
/// (bps), congestion multiplier, and the operation's max-fee cap (bps,
742+
/// denominator 10_000 in both cases). Read-only; any caller may query it.
699743
#[ink(message)]
700744
fn get_recommended_fee(&self, operation: FeeOperation) -> u128 {
701745
self.calculate_fee(operation)

contracts/identity/lib.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,11 @@ pub mod propchain_identity {
16621662
Ok(())
16631663
}
16641664

1665+
/// Revokes an account's verifier authorization.
1666+
///
1667+
/// Admin only (`IdentityError::Unauthorized` otherwise). Marks the
1668+
/// verifier as unauthorized in the mapping; revoking an address that
1669+
/// was never authorized succeeds silently.
16651670
#[ink(message)]
16661671
pub fn remove_authorized_verifier(
16671672
&mut self,
@@ -1674,6 +1679,11 @@ pub mod propchain_identity {
16741679
Ok(())
16751680
}
16761681

1682+
/// Adds a cross-chain id to the supported-chains list.
1683+
///
1684+
/// Admin only (`IdentityError::Unauthorized` otherwise). Adding a
1685+
/// chain that is already listed is a no-op; the registry is seeded
1686+
/// with chains 1–5 at construction.
16771687
#[ink(message)]
16781688
pub fn add_supported_chain(&mut self, chain_id: ChainId) -> Result<(), IdentityError> {
16791689
if self.env().caller() != self.admin {
@@ -1685,6 +1695,8 @@ pub mod propchain_identity {
16851695
Ok(())
16861696
}
16871697

1698+
/// Returns every chain id currently accepted for cross-chain
1699+
/// identity verification.
16881700
#[ink(message)]
16891701
pub fn get_supported_chains(&self) -> Vec<ChainId> {
16901702
self.supported_chains.clone()
@@ -1756,6 +1768,12 @@ pub mod propchain_identity {
17561768

17571769
// ===== Verification Provider Methods - Issue #283 =====
17581770

1771+
/// Registers an external KYC verification provider.
1772+
///
1773+
/// Admin only (`IdentityError::Unauthorized` otherwise). The provider
1774+
/// starts active with the given name (fixed 64-byte field),
1775+
/// `ProviderType`, and the tiers it may verify; a `provider_registered`
1776+
/// audit entry is recorded.
17591777
#[ink(message)]
17601778
pub fn register_verification_provider(
17611779
&mut self,
@@ -1791,6 +1809,11 @@ pub mod propchain_identity {
17911809
Ok(())
17921810
}
17931811

1812+
/// Deactivates a verification provider so it can no longer receive
1813+
/// or complete KYC requests.
1814+
///
1815+
/// Admin only (`IdentityError::Unauthorized` for non-admins);
1816+
/// unknown providers fail with `IdentityError::IdentityNotFound`.
17941817
#[ink(message)]
17951818
pub fn deactivate_provider(&mut self, provider_id: AccountId) -> Result<(), IdentityError> {
17961819
if self.env().caller() != self.admin {
@@ -1808,6 +1831,8 @@ pub mod propchain_identity {
18081831
Ok(())
18091832
}
18101833

1834+
/// Returns the registration record for a verification provider,
1835+
/// or `None` if the id was never registered.
18111836
#[ink(message)]
18121837
pub fn get_verification_provider(
18131838
&self,
@@ -1818,6 +1843,13 @@ pub mod propchain_identity {
18181843

18191844
// ===== KYC Tier Verification - Issue #282 & #283 =====
18201845

1846+
/// Opens a KYC verification request with a provider for the caller.
1847+
///
1848+
/// The provider must exist (`IdentityError::IdentityNotFound`) and be
1849+
/// active, and must support `requested_tier` (both failures return
1850+
/// `IdentityError::VerificationFailed`). Returns a sequential request
1851+
/// id starting at 1; the request starts in `Pending` status and an
1852+
/// audit entry is recorded.
18211853
#[ink(message)]
18221854
pub fn request_kyc_verification(
18231855
&mut self,
@@ -1871,6 +1903,14 @@ pub mod propchain_identity {
18711903
Ok(request_id)
18721904
}
18731905

1906+
/// Completes a KYC verification request (approve or reject).
1907+
///
1908+
/// Callable only by the provider the request was filed with
1909+
/// (`IdentityError::Unauthorized` otherwise); unknown request ids fail
1910+
/// with `IdentityError::IdentityNotFound` and non-pending requests
1911+
/// with `IdentityError::VerificationFailed`. On approval the
1912+
/// applicant's KYC tier is set to the requested tier; `result_metadata`
1913+
/// is stored verbatim on the request.
18741914
#[ink(message)]
18751915
pub fn complete_kyc_verification(
18761916
&mut self,
@@ -1965,16 +2005,23 @@ pub mod propchain_identity {
19652005
Ok(())
19662006
}
19672007

2008+
/// Returns the KYC tier granted to `account`, or `None` if the
2009+
/// account has never been verified.
19682010
#[ink(message)]
19692011
pub fn get_user_kyc_tier(&self, account: AccountId) -> Option<KycTier> {
19702012
self.user_kyc_tiers.get(&account)
19712013
}
19722014

2015+
/// Returns the privilege limits configured for `tier` (max
2016+
/// transaction value, daily transaction count, trading permission),
2017+
/// or `None` if the tier is not configured.
19732018
#[ink(message)]
19742019
pub fn get_kyc_tier_privileges(&self, tier: KycTier) -> Option<KycTierPrivileges> {
19752020
self.kyc_tier_privileges.get(&tier)
19762021
}
19772022

2023+
/// Returns the full KYC verification request with the given id,
2024+
/// or `None` if it does not exist.
19782025
#[ink(message)]
19792026
pub fn get_provider_verification_request(
19802027
&self,
@@ -1983,6 +2030,14 @@ pub mod propchain_identity {
19832030
self.provider_verification_requests.get(&request_id)
19842031
}
19852032

2033+
/// Checks whether `account`'s KYC tier permits a transaction of
2034+
/// `transaction_value`.
2035+
///
2036+
/// Accounts without a tier are treated as `Tier0Unverified`. Returns
2037+
/// `Ok(true)` when the value is within the tier's max transaction
2038+
/// value and the daily limit is not exhausted, `Ok(false)` when a
2039+
/// limit is exceeded, and `IdentityError::IdentityNotFound` if the
2040+
/// tier has no configured privileges.
19862041
#[ink(message)]
19872042
pub fn check_tier_privileges(
19882043
&self,

0 commit comments

Comments
 (0)