diff --git a/README.md b/README.md index 323b165..3d3cf3a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,16 @@ cargo test The release profile is tuned for small wasm output (`opt-level = "z"`, LTO, symbol stripping) — see [`Cargo.toml`](./Cargo.toml). +## Contract API reference + +Every public function under `soroban/src/` — arguments, authorization +requirements, and emitted events — is documented in +[`soroban/docs/API_REFERENCE.md`](./soroban/docs/API_REFERENCE.md), organized by +contract and grouped by what's actually compiled into the deployed contract +versus test-only or unreferenced code. The corresponding numeric error codes +are consolidated in [`soroban/docs/ERRORS.md`](./soroban/docs/ERRORS.md), +along with a check that each contract's codes are internally unique. + ## Benchmarks Resource-usage (CPU instructions, memory, ledger footprint) benchmarks for diff --git a/soroban/docs/API_REFERENCE.md b/soroban/docs/API_REFERENCE.md new file mode 100644 index 0000000..2647da0 --- /dev/null +++ b/soroban/docs/API_REFERENCE.md @@ -0,0 +1,7136 @@ +# Soroban Contract API Reference + +This is the per-contract API reference for the Soroban workspace under `soroban/src/`: every public function, its arguments, its authorization requirement, and any events it emits. Descriptions are derived from each function's `///` doc comment where one exists; where it doesn't, the description was written by reading the function body (noted inline, since nothing here is auto-generated by rustdoc). + +For the error codes referenced throughout (`RegistryError::AssetNotFound`, and so on), see [`ERRORS.md`](./ERRORS.md). + +## Compilation status + +This workspace's `soroban/src/` directory contains more source files than are actually compiled into the deployed contract. Before relying on any function below, check which part it's in: + +| Part | What it means | +| --- | --- | +| 1. Deployed contract | Compiled into `cargo build --release --target wasm32-unknown-unknown` — this is what actually ships. | +| 2. Logic modules | Compiled into the same release build; not a contract on its own, only reachable through Part 1's entry points. | +| 3. Relay contract | Compiled only by the relay integration/fuzz test binaries; fully tested, not part of the release wasm. | +| 4. Standalone experimental contracts | `#[cfg(test)]`-gated; compiled and tested by `cargo test`, excluded from the release wasm build. | +| 5. Unreferenced files | Not compiled by anything in this workspace today. | + +## Table of contents + +**Part 1 — Deployed contract (production wasm)** + +- [BridgeWatchContract (core contract)](#bridgewatchcontract-core-contract) +- [EmergencyFundRecovery](#emergencyfundrecovery) + +**Part 2 — Logic modules backing `BridgeWatchContract`** + +- [acl — Access Control List](#acl--access-control-list) +- [liquidity_pool — Liquidity Pool Monitor](#liquidity_pool--liquidity-pool-monitor) +- [migration — State Migration Helper](#migration--state-migration-helper) +- [operator_rotation — Operator Registry](#operator_rotation--operator-registry) +- [report_hash — Report Hashing](#report_hash--report-hashing) +- [source_blessing — Preferred Source Registry](#source_blessing--preferred-source-registry) +- [source_trust — Trusted Source Registry](#source_trust--trusted-source-registry) +- [state_export — State Export Views](#state_export--state-export-views) +- [threshold_window — Deviation Threshold Windows](#threshold_window--deviation-threshold-windows) +- [version_migration_helper — Enhanced Migration Helper](#version_migration_helper--enhanced-migration-helper) + +**Part 3 — Cross-Chain Relay contract (test-binary only)** + +- [CrossChainRelayContract](#crosschainrelaycontract) +- [relay::types — Relay Data Types](#relaytypes--relay-data-types) +- [relay::events — Relay Event Helpers](#relayevents--relay-event-helpers) + +**Part 4 — Standalone experimental contracts (`cfg(test)` only)** + +- [AnalyticsAggregatorContract](#analyticsaggregatorcontract) +- [AssetDeprecationContract](#assetdeprecationcontract) +- [AssetRegistryContract](#assetregistrycontract) +- [BatchQueryContract](#batchquerycontract) +- [CircuitBreakerContract](#circuitbreakercontract) +- [GovernanceContract](#governancecontract) +- [InsurancePoolContract](#insurancepoolcontract) +- [MultiSigTreasuryContract](#multisigtreasurycontract) +- [RateLimiterContract](#ratelimitercontract) +- [ReputationSystemContract](#reputationsystemcontract) +- [SidecarStateContract](#sidecarstatecontract) + +**Part 5 — Unreferenced source files (not compiled by any build target)** + +- [AlertSystemContract](#alertsystemcontract) +- [asset_ranking](#asset_ranking) +- [bridge_asset_metadata](#bridge_asset_metadata) +- [BridgeReserveVerifier](#bridgereserveverifier) +- [event_query](#event_query) +- [FeeDistributionContract](#feedistributioncontract) +- [rollup_flush](#rollup_flush) +- [source_priority](#source_priority) +- [submission_pause](#submission_pause) +- [submission_replay](#submission_replay) + +## Part 1 — Deployed contract (production wasm) + +These are the two `#[contract]` types that are unconditionally compiled into the release `wasm32-unknown-unknown` artifact. Both sets of methods are exported by the same compiled contract binary. + +### BridgeWatchContract (core contract) + +**Source:** [`soroban/src/lib.rs`](../src/lib.rs) + +**Contract type:** `BridgeWatchContract` + +The primary deployed contract. Tracks asset health/price/liquidity data submitted by trusted sources, enforces role-based access control (ACL), and re-exports the logic modules below as part of its public interface. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) +``` + +Initialize the contract with an admin address + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `submit_health` + +```rust +pub fn submit_health(env: Env, caller: Address, asset_code: String, health_score: u32, liquidity_score: u32, price_stability_score: u32, bridge_uptime_score: u32,) +``` + +Submit a health score for a monitored asset. + +`caller` must be the contract admin, a `SuperAdmin`, or a +`HealthSubmitter`. Backward compatible: the original admin address +requires no explicit role assignment. + +Additionally, if source trust is enabled, the caller must be a +registered trusted source. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `submit_health_batch` + +```rust +pub fn submit_health_batch(env: Env, caller: Address, records: Vec) +``` + +Submit health scores for multiple assets in a single transaction. + +`caller` must be the contract admin, a `SuperAdmin`, or a +`HealthSubmitter`. Accepts up to 20 records per call, all stamped with +the same ledger timestamp. A `health_up` event is emitted per asset. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** see description above + +#### `submit_price` + +```rust +pub fn submit_price(env: Env, caller: Address, asset_code: String, price: i128, source: String,) +``` + +Submit a price record for an asset. + +`caller` must be the contract admin, a `SuperAdmin`, or a +`PriceSubmitter`. The record is stored as the latest price and +also appended to the asset's historical price series for +time-range queries via [`get_price_history`]. + +Additionally, if source trust is enabled, the caller must be a +registered trusted source. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `get_health` + +```rust +pub fn get_health(env: Env, asset_code: String) -> Option +``` + +Get the latest health record for an asset + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_price` + +```rust +pub fn get_price(env: Env, asset_code: String) -> Option +``` + +Get the latest price record for an asset + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `register_signer` + +```rust +pub fn register_signer(env: Env, caller: Address, signer_id: String, public_key: BytesN<32>) +``` + +Register an authorized signer for edge data submissions. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `sgnr_reg` + +#### `remove_signer` + +```rust +pub fn remove_signer(env: Env, caller: Address, signer_id: String) +``` + +Remove a signer from active set (soft delete). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `sgnr_rem` + +#### `set_signature_threshold` + +```rust +pub fn set_signature_threshold(env: Env, caller: Address, threshold: u32) +``` + +Set the minimum required signatures for multi-sig verification. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `sig_thr` + +#### `get_signature_threshold` + +```rust +pub fn get_signature_threshold(env: Env) -> u32 +``` + +Get current signature threshold (defaults to 1 if not set). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `verify_signature` + +```rust +pub fn verify_signature(env: Env, message: Bytes, signature: SignerSignature) -> bool +``` + +Verify a single signature against a message and signer metadata. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `sig_ver` + +#### `verify_multi_sig` + +```rust +pub fn verify_multi_sig(env: Env, message: Bytes, signatures: Vec) -> bool +``` + +Verify a multi-signature submission. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `multi_sig` + +#### `submit_health_signed` + +```rust +pub fn submit_health_signed(env: Env, caller: Address, asset_code: String, health_score: u32, liquidity_score: u32, price_stability_score: u32, bridge_uptime_score: u32, signature: SignerSignature,) +``` + +Submit health data with cryptographic signature verification support. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `submit_price_signed` + +```rust +pub fn submit_price_signed(env: Env, caller: Address, asset_code: String, price: i128, source: String, signature: SignerSignature,) +``` + +Submit a price record with cryptographic signature verification support. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `submit_health_batch_signed` + +```rust +pub fn submit_health_batch_signed(env: Env, caller: Address, records: Vec, signatures: Vec,) +``` + +Submit a batch of health records with multi-sig support. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `register_asset` + +```rust +pub fn register_asset(env: Env, caller: Address, asset_code: String) +``` + +Return the latest health record for an asset + +`caller` must be the contract admin, a `SuperAdmin`, or an +`AssetManager`. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `asset_reg` + +#### `pause_asset` + +```rust +pub fn pause_asset(env: Env, caller: Address, asset_code: String) +``` + +Temporarily pause monitoring for an asset. + +`caller` must be the contract admin, a `SuperAdmin`, or an +`AssetManager`. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `asset_pau` + +#### `unpause_asset` + +```rust +pub fn unpause_asset(env: Env, caller: Address, asset_code: String) +``` + +Resume monitoring for a paused asset. + +`caller` must be the contract admin, a `SuperAdmin`, or an +`AssetManager`. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `asset_unp` + +#### `deregister_asset` + +```rust +pub fn deregister_asset(env: Env, caller: Address, asset_code: String) +``` + +Permanently deregister an asset while retaining historical data. + +`caller` must be the contract admin, a `SuperAdmin`, or an +`AssetManager`. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `asset_del` + +#### `lock_asset` + +```rust +pub fn lock_asset(env: Env, caller: Address, asset_code: String, reason: String) +``` + +Lock an asset to prevent operational changes during maintenance or review. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `asset_lck`, `lock_set` + +#### `unlock_asset` + +```rust +pub fn unlock_asset(env: Env, caller: Address, asset_code: String) +``` + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `asset_ulk`, `lock_clr` + +#### `get_asset_lock_state` + +```rust +pub fn get_asset_lock_state(env: Env, asset_code: String) -> Option +``` + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_asset_locked` + +```rust +pub fn is_asset_locked(env: Env, asset_code: String) -> bool +``` + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_asset_lock_history` + +```rust +pub fn get_asset_lock_history(env: Env, asset_code: String) -> Vec +``` + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_monitored_assets` + +```rust +pub fn get_monitored_assets(env: Env) -> Vec +``` + +Get all monitored assets + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `list_asset_state_snapshots` + +```rust +pub fn list_asset_state_snapshots(env: Env) -> Vec +``` + +List compact per-asset snapshots for off-chain sync (read-only). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `export_contract_data_snapshot` + +```rust +pub fn export_contract_data_snapshot(env: Env) -> state_export::StateExport +``` + +Export a versioned, compact snapshot of current contract data (read-only). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_deviation_threshold` + +```rust +pub fn set_deviation_threshold(env: Env, asset_code: String, low_bps: i128, medium_bps: i128, high_bps: i128,) +``` + +Set configurable deviation thresholds for an asset (admin only). + +All thresholds are expressed in basis points (1 bp = 0.01 %). +Defaults used when none are configured: Low 200 bps, Medium 500 bps, +High 1 000 bps. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `thresh_up` + +#### `set_deviation_threshold_override` + +```rust +pub fn set_deviation_threshold_override(env: Env, caller: Address, asset_code: String, low_bps: i128, medium_bps: i128, high_bps: i128, mode: ThresholdOverrideMode, expires_at: Option,) +``` + +Set a per-asset deviation threshold override. + +`caller` must be admin or have ACL `ManageConfig` permission. +Temporary overrides require a future `expires_at` timestamp. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `dev`, `thr_ovr` + +#### `get_deviation_threshold_override` + +```rust +pub fn get_deviation_threshold_override(env: Env, asset_code: String,) -> Option +``` + +Return the active per-asset deviation threshold override, if any. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `clear_dev_threshold_override` + +```rust +pub fn clear_dev_threshold_override(env: Env, caller: Address, asset_code: String) +``` + +Remove the per-asset deviation threshold override. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `dev`, `thr_clr` + +#### `check_price_deviation` + +```rust +pub fn check_price_deviation(env: Env, asset_code: String, current_price: i128,) -> Option +``` + +Compare `current_price` against the last recorded [`PriceRecord`] for +the asset and store a [`DeviationAlert`] when the deviation exceeds a +configured threshold. + +Returns the alert when a threshold is breached, `None` otherwise. +Severity levels (default thresholds): +- **Low** – deviation > 200 bps (2 %) +- **Medium** – deviation > 500 bps (5 %) +- **High** – deviation > 1 000 bps (10 %) + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `price_dev` + +#### `get_deviation_alerts` + +```rust +pub fn get_deviation_alerts(env: Env, asset_code: String) -> Option +``` + +Get the latest stored deviation alert for an asset. + +Returns `None` if no alert has been recorded. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_mismatch_threshold` + +```rust +pub fn set_mismatch_threshold(env: Env, threshold_bps: i128) +``` + +Set the global critical mismatch threshold in basis points (admin only). + +Mismatches at or above this value are flagged as critical. +Default is 10 bps (0.1 %). + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `mismatch`, `thresh_up` + +#### `set_mismatch_threshold_override` + +```rust +pub fn set_mismatch_threshold_override(env: Env, caller: Address, asset_code: String, threshold_bps: i128, mode: ThresholdOverrideMode, expires_at: Option,) +``` + +Set a per-asset mismatch threshold override in basis points. + +`caller` must be admin or have ACL `ManageConfig` permission. +Temporary overrides require a future `expires_at` timestamp. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `mm`, `thr_ovr` + +#### `get_mismatch_threshold_override` + +```rust +pub fn get_mismatch_threshold_override(env: Env, asset_code: String,) -> Option +``` + +Return the active per-asset mismatch threshold override, if any. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `clear_mm_threshold_override` + +```rust +pub fn clear_mm_threshold_override(env: Env, caller: Address, asset_code: String) +``` + +Remove the per-asset mismatch threshold override. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `mm`, `thr_clr` + +#### `record_supply_mismatch` + +```rust +pub fn record_supply_mismatch(env: Env, bridge_id: String, asset_code: String, stellar_supply: i128, source_chain_supply: i128,) +``` + +Record a supply mismatch for a bridge asset (admin only). + +Calculates `mismatch_bps` as +`|stellar_supply - source_chain_supply| * 10_000 / source_chain_supply` +and sets `is_critical` when the value meets or exceeds the configured +threshold (default 10 bps / 0.1 %). Each call appends to the bridge's +historical record, enabling trend analysis over time. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `supply_mm` + +#### `get_supply_mismatches` + +```rust +pub fn get_supply_mismatches(env: Env, bridge_id: String) -> Vec +``` + +Return all recorded supply mismatches for a bridge. Public read access. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_critical_mismatches` + +```rust +pub fn get_critical_mismatches(env: Env) -> Vec +``` + +Return all critical mismatches across every tracked bridge. Public read access. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `record_liquidity_depth` + +```rust +pub fn record_liquidity_depth(env: Env, asset_pair: String, total_liquidity: i128, depth_0_1_pct: i128, depth_0_5_pct: i128, depth_1_pct: i128, depth_5_pct: i128, sources: Vec,) +``` + +Record aggregated liquidity depth for a supported asset pair. + +This stores the latest cross-DEX liquidity snapshot as well as +appending it to the pair's historical series for trend analysis. + +Supported Phase 1 pairs are: +- `USDC/XLM` +- `EURC/XLM` +- `PYUSD/XLM` +- `FOBXX/USDC` + +# Panics +Panics when: +- the caller is not the contract admin +- the asset pair is not supported in Phase 1 +- any liquidity value is negative +- `sources` is empty +- liquidity depth levels are inconsistent + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `liq_chg` + +#### `get_aggregated_liquidity_depth` + +```rust +pub fn get_aggregated_liquidity_depth(env: Env, asset_pair: String) -> Option +``` + +Return the latest aggregated liquidity depth for an asset pair. + +Public read access. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_liquidity_history` + +```rust +pub fn get_liquidity_history(env: Env, asset_pair: String, from_timestamp: u64, to_timestamp: u64,) -> Vec +``` + +Return historical liquidity depth snapshots for an asset pair. + +Public read access. Returned records are ordered by insertion time and +filtered to the inclusive timestamp range `[from_timestamp, to_timestamp]`. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_all_liquidity_depths` + +```rust +pub fn get_all_liquidity_depths(env: Env) -> Vec +``` + +Return the latest aggregated liquidity depth for all tracked asset pairs. + +Public read access. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `grant_role` + +```rust +pub fn grant_role(env: Env, granter: Address, grantee: Address, role: AdminRole) +``` + +Grant a role to `grantee` (SuperAdmin or original admin only). + +Duplicate grants are silently ignored. The original admin address set +via `initialize()` is implicitly treated as SuperAdmin and does not +require an explicit role entry. + +- **Auth:** `granter` (`.require_auth()` called directly in this function) +- **Events:** `role_grnt` + +#### `revoke_role` + +```rust +pub fn revoke_role(env: Env, revoker: Address, target: Address, role: AdminRole) +``` + +Revoke a specific role from `target` (SuperAdmin or original admin only). + +- **Auth:** `revoker` (`.require_auth()` called directly in this function) +- **Events:** `role_revk` + +#### `set_expiration_policy` + +```rust +pub fn set_expiration_policy(env: Env, caller: Address, asset_ttl_secs: u64, price_ttl_secs: u64, deviation_ttl_secs: u64, mismatch_ttl_secs: u64, liquidity_ttl_secs: u64, preserve_latest_history: bool, version: u32,) +``` + +Configure global expiration TTLs for stored records. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `set_asset_expiration_ttl` + +```rust +pub fn set_asset_expiration_ttl(env: Env, caller: Address, asset_code: String, ttl_secs: u64) +``` + +Configure a per-asset TTL override for asset-bound records. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `get_expiration_policy` + +```rust +pub fn get_expiration_policy(env: Env) -> ExpirationPolicy +``` + +Return the current expiration policy. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_cleanup_stats` + +```rust +pub fn get_cleanup_stats(env: Env) -> Option +``` + +Return the most recent cleanup summary, if one exists. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `extend_expiration` + +```rust +pub fn extend_expiration(env: Env, caller: Address, asset_code: String, extra_secs: u64) +``` + +Manually extend current record expirations for an asset. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `cleanup_expired_data` + +```rust +pub fn cleanup_expired_data(env: Env, caller: Address, max_records: u32) -> CleanupStats +``` + +Cleanup expired records and trim expired historical entries. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `has_role` + +```rust +pub fn has_role(env: Env, address: Address, role: AdminRole) -> bool +``` + +Return `true` if `address` holds `role`. + +Public read — no authorisation required. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_admin_roles` + +```rust +pub fn get_admin_roles(env: Env) -> Vec +``` + +Return all active role assignments. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `acl_grant_role` + +```rust +pub fn acl_grant_role(env: Env, caller: Address, grantee: Address, role: Role, expires_at: u64,) +``` + +Grant `role` to `grantee`. + +`caller` must be the contract admin or hold `ManagePermissions`. +`expires_at` is a ledger timestamp; pass `0` for a non-expiring grant. +Granting the same role twice updates the expiry. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_grnt` + +#### `acl_revoke_role` + +```rust +pub fn acl_revoke_role(env: Env, caller: Address, grantee: Address, role: Role) +``` + +Revoke `role` from `grantee`. + +`caller` must be the contract admin or hold `ManagePermissions`. +No-ops silently if the grant does not exist. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_revk` + +#### `acl_grant_permission` + +```rust +pub fn acl_grant_permission(env: Env, caller: Address, grantee: Address, permission: Permission, expires_at: u64,) +``` + +Grant a direct `permission` to `grantee`. + +`caller` must be the contract admin or hold `ManagePermissions`. +`expires_at` is a ledger timestamp; pass `0` for a non-expiring grant. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_pgrn` + +#### `acl_revoke_permission` + +```rust +pub fn acl_revoke_permission(env: Env, caller: Address, grantee: Address, permission: Permission,) +``` + +Revoke a direct `permission` from `grantee`. + +`caller` must be the contract admin or hold `ManagePermissions`. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_prv` + +#### `acl_has_role` + +```rust +pub fn acl_has_role(env: Env, address: Address, role: Role) -> bool +``` + +Return `true` if `address` currently holds `role` (respects expiry). + +Public read — no authorisation required. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `acl_has_permission` + +```rust +pub fn acl_has_permission(env: Env, address: Address, permission: Permission) -> bool +``` + +Return `true` if `address` has `permission` via any active role or +direct grant (respects expiry and inheritance). + +Public read — no authorisation required. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `acl_get_role_grants` + +```rust +pub fn acl_get_role_grants(env: Env) -> Vec +``` + +Return all role grants (including expired ones for audit purposes). + +Public read — no authorisation required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `acl_get_permission_grants` + +```rust +pub fn acl_get_permission_grants(env: Env) -> Vec +``` + +Return all direct permission grants (including expired ones). + +Public read — no authorisation required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `acl_get_roles_for` + +```rust +pub fn acl_get_roles_for(env: Env, address: Address) -> Vec +``` + +Return all role grants for a specific `address` (including expired). + +Public read — no authorisation required. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `acl_get_permissions_for` + +```rust +pub fn acl_get_permissions_for(env: Env, address: Address) -> Vec +``` + +Return all direct permission grants for a specific `address`. + +Public read — no authorisation required. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `acl_bulk_grant_roles` + +```rust +pub fn acl_bulk_grant_roles(env: Env, caller: Address, entries: Vec) +``` + +Bulk-grant roles to multiple addresses in a single transaction. + +`caller` must be the contract admin or hold `ManagePermissions`. +Accepts up to 20 entries per call. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_grnt` + +#### `acl_bulk_revoke_roles` + +```rust +pub fn acl_bulk_revoke_roles(env: Env, caller: Address, entries: Vec) +``` + +Bulk-revoke roles from multiple addresses in a single transaction. + +`caller` must be the contract admin or hold `ManagePermissions`. +Accepts up to 20 entries per call. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_revk` + +#### `acl_bulk_grant_permissions` + +```rust +pub fn acl_bulk_grant_permissions(env: Env, caller: Address, entries: Vec,) +``` + +Bulk-grant direct permissions to multiple addresses in a single transaction. + +`caller` must be the contract admin or hold `ManagePermissions`. +Accepts up to 20 entries per call. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_pgrn` + +#### `acl_bulk_revoke_permissions` + +```rust +pub fn acl_bulk_revoke_permissions(env: Env, caller: Address, entries: Vec,) +``` + +Bulk-revoke direct permissions from multiple addresses. + +`caller` must be the contract admin or hold `ManagePermissions`. +Accepts up to 20 entries per call. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `acl_prv` + +#### `emergency_pause` + +```rust +pub fn emergency_pause(env: Env, caller: Address, reason: String) +``` + +Immediately halt all state-changing operations. + +`caller` must be the contract admin or the designated pause guardian. +A human-readable `reason` is stored on-chain and included in the emitted +event. Every call appends an entry to the immutable pause history log. + +After `emergency_pause()` succeeds, all write operations will panic +until `unpause()` is called **and** the configured timelock has elapsed +(default 24 hours / 86 400 seconds). + +# Panics +- `caller` is neither the admin nor the pause guardian. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `em_pause` + +#### `unpause` + +```rust +pub fn unpause(env: Env, caller: Address, reason: String) +``` + +Lift the global pause after the timelock has elapsed. + +Only the contract admin may call `unpause()`. The call panics if the +24-hour timelock set at pause-time has not yet expired, preventing +hasty re-activation in a still-live incident. + +# Panics +- `caller` is not the contract admin. +- The timelock (`unpause_available_at`) has not yet passed. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `em_unpaus` + +#### `set_pause_guardian` + +```rust +pub fn set_pause_guardian(env: Env, caller: Address, guardian: Address) +``` + +Designate a dedicated pause guardian address. + +The pause guardian can call `emergency_pause()` without holding an +admin role, but cannot call `unpause()`. Only the contract admin may +set or change the guardian. + +# Panics +- `caller` is not the contract admin. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `pg_set` + +#### `is_paused` + +```rust +pub fn is_paused(env: Env) -> bool +``` + +Return `true` when the contract is currently globally paused. + +Public read — no authorisation required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_asset_paused` + +```rust +pub fn is_asset_paused(env: Env, asset_code: String) -> bool +``` + +Return `true` when an asset is paused, either globally or per-asset. + +Public read — no authorisation required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_pause_status` + +```rust +pub fn get_pause_status(env: Env) -> GlobalPauseState +``` + +Return a full snapshot of the current global pause state. + +Public read — no authorisation required. Suitable for dashboards and +monitoring tooling. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_pause_history` + +```rust +pub fn get_pause_history(env: Env) -> Vec +``` + +Return the full ordered pause/unpause history log. + +Public read — no authorisation required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_emergency_contact` + +```rust +pub fn set_emergency_contact(env: Env, caller: Address, contact: String) +``` + +Store operator emergency contact information (e-mail, Telegram, etc.). + +Only the contract admin may update this value. The contact string is +included in the `get_pause_status()` response so monitoring tools can +surface it automatically when a pause is detected. + +# Panics +- `caller` is not the contract admin. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `em_cont` + +#### `propose_admin_transfer` + +```rust +pub fn propose_admin_transfer(env: Env, caller: Address, proposed_admin: Address) +``` + +Propose a transfer of the admin role to `proposed_admin`. + +The current admin initiates the two-step handover. The proposal expires +after 7 days (604 800 seconds); after that, the pending proposal is +automatically considered void and either party must restart the process. + +While a transfer is pending, the following admin-only write operations +are blocked: `grant_role`, `revoke_role`, `set_health_weights`, +`set_deviation_threshold`, `set_mismatch_threshold`. + +# Panics +- `caller` is not the current contract admin. +- A non-expired proposal already exists. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `adm_prop` + +#### `accept_admin_transfer` + +```rust +pub fn accept_admin_transfer(env: Env, caller: Address) +``` + +Accept an incoming admin transfer proposal. + +Must be called by the address that was nominated in +`propose_admin_transfer()`. On success the contract admin is atomically +updated to `caller` and the pending proposal is cleared. + +# Panics +- There is no pending proposal. +- The proposal has expired (older than 7 days). +- `caller` is not the nominated new admin. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `adm_acpt` + +#### `cancel_admin_transfer` + +```rust +pub fn cancel_admin_transfer(env: Env, caller: Address) +``` + +Cancel a pending admin transfer proposal. + +Only the current admin (the proposer) may cancel. This is the emergency +override path if the nominated address is compromised or the proposal +was sent in error. + +# Panics +- `caller` is not the current contract admin. +- There is no pending proposal to cancel. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `adm_cncl` + +#### `get_pending_transfer` + +```rust +pub fn get_pending_transfer(env: Env) -> Option +``` + +Return the current pending admin transfer proposal, if any. + +Returns `None` when there is no proposal or the proposal has expired. +Public read — no authorisation required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `propose_upgrade` + +```rust +pub fn propose_upgrade(env: Env, caller: Address, new_wasm_hash: BytesN<32>, emergency: bool, migration_callback: Option
, migration_payload: Option,) -> u64 +``` + +Propose a contract upgrade with governance approval and timelock. + +Standard proposals enforce a 48-hour timelock. Emergency proposals use +a higher governance threshold and may execute immediately. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `propose_rollback` + +```rust +pub fn propose_rollback(env: Env, caller: Address, emergency: bool, migration_callback: Option
, migration_payload: Option,) -> u64 +``` + +Propose a rollback using the tracked prior Wasm hash. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `approve_upgrade` + +```rust +pub fn approve_upgrade(env: Env, caller: Address, proposal_id: u64) -> u32 +``` + +Approve a pending upgrade proposal as a governance member. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `up_appr` + +#### `execute_upgrade` + +```rust +pub fn execute_upgrade(env: Env, caller: Address, proposal_id: u64) +``` + +Execute a pending upgrade once timelock and governance conditions pass. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `up_exec`, `up_migcb`, `up_migpl`, `up_roll` + +#### `cancel_upgrade` + +```rust +pub fn cancel_upgrade(env: Env, caller: Address, proposal_id: u64, reason: String) +``` + +Cancel a pending upgrade proposal. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `up_cncl` + +#### `get_pending_upgrade` + +```rust +pub fn get_pending_upgrade(env: Env) -> Option +``` + +Return the currently pending contract upgrade proposal, if any. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_upgrade_history` + +```rust +pub fn get_upgrade_history(env: Env) -> Vec +``` + +Return historical execution records for all completed upgrades. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_contract_version` + +```rust +pub fn get_contract_version(env: Env) -> u32 +``` + +Return the current semantic version counter. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_current_wasm_hash` + +```rust +pub fn get_current_wasm_hash(env: Env) -> Option> +``` + +Return the currently tracked active Wasm hash, if set. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_rollback_target` + +```rust +pub fn get_rollback_target(env: Env) -> Option> +``` + +Return the currently tracked rollback target hash, if available. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_retention_policy` + +```rust +pub fn set_retention_policy(env: Env, caller: Address, data_type: RetentionDataType, retention_secs: u64, trigger_interval_secs: u64, max_deletions_per_run: u32, archive_before_delete: bool, enabled: bool,) +``` + +Configure retention and cleanup policy for a historical data bucket. + +Admin-only. `retention_secs`, `trigger_interval_secs`, and +`max_deletions_per_run` must all be greater than zero. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ret_set` + +#### `get_retention_policy` + +```rust +pub fn get_retention_policy(env: Env, data_type: RetentionDataType) -> RetentionPolicy +``` + +Return retention policy for a given historical data bucket. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `list_retention_policies` + +```rust +pub fn list_retention_policies(env: Env) -> Vec +``` + +Return all retention policies. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_asset_retention_override` + +```rust +pub fn set_asset_retention_override(env: Env, caller: Address, asset_code: String, data_type: RetentionDataType, retention_secs: Option,) +``` + +Set or clear a per-asset retention override for a specific data bucket. + +When `retention_secs` is `Some(value)`, the override is upserted. +When `retention_secs` is `None`, the override is removed. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `ret_ovr` + +#### `get_asset_retention_override` + +```rust +pub fn get_asset_retention_override(env: Env, asset_code: String, data_type: RetentionDataType,) -> Option +``` + +Return per-asset retention override for a data bucket, if configured. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `cleanup_old_data` + +```rust +pub fn cleanup_old_data(env: Env, caller: Address, max_total_deletions: u32) -> CleanupResult +``` + +Run gradual historical cleanup across all retention-enabled data buckets. + +Admin-only. Cleanup never deletes currently active/latest records. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ret_cln`, `ret_done` + +#### `cleanup_data_type` + +```rust +pub fn cleanup_data_type(env: Env, caller: Address, data_type: RetentionDataType, max_deletions: u32,) -> CleanupDataTypeResult +``` + +Run gradual cleanup for a single data bucket. + +Admin-only. This is useful for operational bulk deletes when only one +historical collection should be processed. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ret_cln` + +#### `get_storage_stats` + +```rust +pub fn get_storage_stats(env: Env) -> StorageStats +``` + +Return current storage usage counters for retained and archived data. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_config` + +```rust +pub fn set_config(env: Env, caller: Address, category: ConfigCategory, name: String, value: i128, description: String,) +``` + +Store or update a single on-chain configuration parameter. + +# Access control +Only the contract admin or an address with the `SuperAdmin` role may +call this function. + +# Parameters +- `caller` – The address performing the update. Must be authorised. +- `category` – Parameter category (`Thresholds`, `Timeouts`, `Limits`). +- `name` – Parameter name, max 64 bytes. +- `value` – New numeric value. +- `description` – Human-readable description (required, max 256 bytes). + +# Validation +- `name` must be non-empty and ≤ 64 bytes. +- `description` must be non-empty and ≤ 256 bytes. +- For `Timeouts` category: `value` must be ≥ 1 (at least 1 second). +- For `Limits` category: `value` must be ≥ 1. +- For `Thresholds` category: `value` must be ≥ 0. + +# Events +Publishes a `("config_up", category_tag, name)` event with the new value. + +# Audit trail +Appends a `ConfigAuditEntry` to the parameter's audit log (capped at 50 +entries; oldest entries are dropped when the cap is reached). + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** see description above + +#### `get_config` + +```rust +pub fn get_config(env: Env, category: ConfigCategory, name: String) -> Option +``` + +Retrieve a single configuration parameter by category and name. + +Returns `None` when no value has been explicitly stored and no default +exists. Callers should apply their own application-layer defaults for +`None` responses. + +No authorisation required — read-only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_all_configs` + +```rust +pub fn get_all_configs(env: Env) -> AllConfigsExport +``` + +Retrieve all stored configuration parameters as a single export. + +Returns an `AllConfigsExport` containing every `ConfigEntry` currently +stored on-chain, the total count, and the ledger timestamp of the +export. + +No authorisation required — read-only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_config_audit_log` + +```rust +pub fn get_config_audit_log(env: Env, category: ConfigCategory, name: String,) -> Vec +``` + +Retrieve the full audit log for a specific configuration parameter. + +Returns an empty `Vec` when no changes have been recorded yet. + +No authorisation required — read-only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_config_bulk` + +```rust +pub fn set_config_bulk(env: Env, caller: Address, updates: Vec) +``` + +Apply multiple configuration updates atomically in a single transaction. + +Each update in `updates` follows the same validation rules as +`set_config()`. If any update fails validation the entire call panics +and no changes are written. + +# Access control +Only the contract admin or an address with the `SuperAdmin` role. + +# Limits +At most 20 updates per call to bound gas usage. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `init_default_config` + +```rust +pub fn init_default_config(env: Env, caller: Address) +``` + +Initialise configuration with the protocol's built-in default values. + +Safe to call multiple times: existing values are **not** overwritten, +only parameters that are absent are initialised. Intended to be called +once after `initialize()` to seed the on-chain configuration with +sensible defaults. + +# Default parameters + +**Thresholds** +| Name | Default | Unit | +|------------------------------|---------|---------------| +| `health_score_min` | 50 | score (0–100) | +| `price_deviation_low_bps` | 200 | basis points | +| `price_deviation_medium_bps` | 500 | basis points | +| `price_deviation_high_bps` | 1000 | basis points | +| `supply_mismatch_bps` | 10 | basis points | + +**Timeouts** +| Name | Default | Unit | +|---------------------------|---------|---------| +| `price_staleness_seconds` | 3600 | seconds | +| `health_staleness_seconds`| 3600 | seconds | +| `pause_timelock_seconds` | 300 | seconds | +| `admin_transfer_timeout` | 86400 | seconds | + +**Limits** +| Name | Default | Unit | +|------------------------|---------|-------| +| `max_monitored_assets` | 100 | count | +| `max_batch_size` | 50 | count | +| `max_signers` | 20 | count | +| `max_price_history` | 100 | count | + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `record_pool_state` + +```rust +pub fn record_pool_state(env: Env, pool_id: String, reserve_a: i128, reserve_b: i128, total_shares: i128, volume: i128, fees: i128, pool_type: PoolType,) +``` + +Record a new liquidity pool state snapshot (admin only). + +Writes the snapshot into a gas-optimised ring buffer, updates the +corresponding daily aggregation bucket, and emits events when +significant liquidity changes are detected. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** see description above + +#### `calculate_pool_metrics` + +```rust +pub fn calculate_pool_metrics(env: Env, pool_id: String, window_secs: u64) -> PoolMetrics +``` + +Calculate aggregated pool metrics over a time window. + +Returns volume, average depth, price change, fee APR, etc. +for the specified `window_secs` lookback period. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_pool_history` + +```rust +pub fn get_pool_history(env: Env, pool_id: String, from_timestamp: u64, to_timestamp: u64,) -> Vec +``` + +Retrieve historical pool snapshots within a time range. + +Public read access — no authorisation required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_impermanent_loss` + +```rust +pub fn calculate_impermanent_loss(env: Env, pool_id: String, entry_price: i128, initial_value: i128,) -> ImpermanentLossResult +``` + +Calculate impermanent loss for an LP position. + +Given the `entry_price` at which a position was opened and its +`initial_value`, returns the current IL percentage, position value, +and HODL comparison value. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_liquidity_depth` + +```rust +pub fn get_liquidity_depth(env: Env, pool_id: String) -> PoolLiquidityDepth +``` + +Get current liquidity depth information for a pool. + +Returns reserve amounts, total value locked, and a depth score +from 0 to 100. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_daily_history` + +```rust +pub fn get_daily_history(env: Env, pool_id: String, from_timestamp: u64, to_timestamp: u64,) -> Vec +``` + +Get daily aggregated buckets for a pool within a time range. + +Returns OHLC price data, volume, fees, and average reserves +per day. Public read access. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_registered_pools` + +```rust +pub fn get_registered_pools(env: Env) -> Vec +``` + +Get all registered liquidity pool IDs. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_health_weights` + +```rust +pub fn set_health_weights(env: Env, caller: Address, liquidity_weight: u32, price_stability_weight: u32, bridge_uptime_weight: u32, version: u32,) +``` + +Set configurable weights used by the automated health score calculation. + +`caller` must be the contract admin or a `SuperAdmin`. The three weights +must each be in the range 0–100 and must sum to exactly 100. The +`version` field tracks the methodology revision for auditability. + +# Panics +- Caller is not authorised. +- Any individual weight exceeds 100. +- The weights do not sum to 100. +- `version` is 0. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `wt_set` + +#### `get_health_weights` + +```rust +pub fn get_health_weights(env: Env) -> HealthWeights +``` + +Return the current health score calculation weights. + +Public read access — no authorisation required. Returns the +admin-configured weights or the defaults (30 / 40 / 30, version 1) +when none have been explicitly set. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_health_score` + +```rust +pub fn calculate_health_score(env: Env, liquidity_score: u32, price_stability_score: u32, bridge_uptime_score: u32,) -> HealthScoreResult +``` + +Pure calculation: compute a composite health score from component +scores using the stored (or default) weights. + +This function does **not** store any result on-chain; it is intended +for off-chain callers that want to preview the score before submitting. + +Formula: +```text +composite = (liquidity * liq_w + stability * stab_w + uptime * up_w) / 100 +``` + +All input scores must be in the 0–100 range. + +# Panics +- Any input score is greater than 100. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `submit_calculated_health` + +```rust +pub fn submit_calculated_health(env: Env, caller: Address, asset_code: String, liquidity_score: u32, price_stability_score: u32, bridge_uptime_score: u32, manual_override: Option,) +``` + +Submit a health score that is **automatically calculated** from the +supplied component scores using the stored weights. + +This is the recommended entry-point for Phase 1 MVP health scoring. It +combines `calculate_health_score()` with `submit_health()`, storing +both the `AssetHealth` record and the detailed `HealthScoreResult`. + +`caller` must be the contract admin, a `SuperAdmin`, or a +`HealthSubmitter`. The asset must be registered, active, and not paused. +All component scores must be in the 0–100 range. + +An optional `manual_override` score (0–100) can replace the calculated +composite score while still recording the underlying calculation for +transparency. + +# Panics +- Caller is not authorised. +- Asset is not registered, deregistered, or paused. +- Any component score is greater than 100. +- `manual_override` is provided and exceeds 100. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `health_up` + +#### `get_health_score_result` + +```rust +pub fn get_health_score_result(env: Env, asset_code: String) -> Option +``` + +Return the latest calculated health score result for an asset. + +Public read access — no authorisation required. Returns `None` if no +calculated score has been submitted for the asset. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_risk_score_config` + +```rust +pub fn set_risk_score_config(env: Env, caller: Address, health_weight_bps: u32, price_weight_bps: u32, volatility_weight_bps: u32, max_price_deviation_bps: u32, max_volatility_bps: u32, version: u32,) +``` + +Store configuration for deterministic risk score calculations. + +`caller` must be the contract admin or a `SuperAdmin`. The weights are +expressed in basis points and must sum to exactly 10,000. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `risk_cfg` + +#### `get_risk_score_config` + +```rust +pub fn get_risk_score_config(env: Env) -> RiskScoreConfig +``` + +Return the active risk score calculation configuration. + +Public read access — no authorisation required. Returns the configured +values or the defaults when no custom configuration has been stored. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_risk_score` + +```rust +pub fn calculate_risk_score(env: Env, health_score: u32, price_deviation_bps: u32, volatility_bps: u32,) -> RiskScoreResult +``` + +Pure deterministic calculation for the composite risk score. + +The output is normalized to basis points (0–10,000) and combines: +1. Inverted health score +2. Price deviation +3. Volatility + +Price and volatility inputs are clamped to the configured normalization +ceilings before the weighted average is computed. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_asset_risk_score` + +```rust +pub fn get_asset_risk_score(env: Env, asset_code: String, period: StatPeriod,) -> Option +``` + +Derive a risk score for an asset from stored health and price history. + +Public read access — no authorisation required. Returns `None` when the +asset has no stored health record. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_checkpoint_config` + +```rust +pub fn set_checkpoint_config(env: Env, caller: Address, interval_secs: u64, max_checkpoints: u32, format_version: u32,) +``` + +Update automatic checkpoint settings. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `chk_cfg` + +#### `get_checkpoint_config` + +```rust +pub fn get_checkpoint_config(env: Env) -> CheckpointConfig +``` + +Return the active checkpoint configuration. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `create_checkpoint` + +```rust +pub fn create_checkpoint(env: Env, caller: Address, label: String) -> CheckpointMetadata +``` + +Create a manual checkpoint of the current contract state. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `get_checkpoint` + +```rust +pub fn get_checkpoint(env: Env, checkpoint_id: u64) -> Option +``` + +Return a historical checkpoint snapshot by id. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `list_checkpoints` + +```rust +pub fn list_checkpoints(env: Env) -> Vec +``` + +Return ordered metadata for all stored checkpoints. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_latest_checkpoint` + +```rust +pub fn get_latest_checkpoint(env: Env) -> Option +``` + +Return metadata for the latest stored checkpoint. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `validate_checkpoint` + +```rust +pub fn validate_checkpoint(env: Env, checkpoint_id: u64) -> CheckpointValidation +``` + +Validate a stored checkpoint by recomputing its state hash. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compare_checkpoints` + +```rust +pub fn compare_checkpoints(env: Env, from_checkpoint_id: u64, to_checkpoint_id: u64,) -> CheckpointComparison +``` + +Compare two historical checkpoints and return high-level differences. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `restore_from_checkpoint` + +```rust +pub fn restore_from_checkpoint(env: Env, caller: Address, checkpoint_id: u64,) -> CheckpointMetadata +``` + +Restore current contract state from a historical checkpoint. + +A new restore checkpoint is created immediately after the state is +applied to preserve an audit trail. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `chk_rst` + +#### `calculate_average` + +```rust +pub fn calculate_average(_env: Env, values: Vec) -> i128 +``` + +Calculate simple moving average of a value series. + +Returns the arithmetic mean of the provided values. +Gas-efficient implementation for on-chain calculations. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `volume_weighted_avg` + +```rust +pub fn volume_weighted_avg(_env: Env, values: Vec, volumes: Vec) -> i128 +``` + +Calculate volume-weighted moving average. + +Each value is weighted by its corresponding volume. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_stddev` + +```rust +pub fn calculate_stddev(env: Env, values: Vec) -> i128 +``` + +Calculate standard deviation of a value series. + +Uses population standard deviation formula: sqrt(sum((x - mean)^2) / n) +Returns result scaled by PRECISION for fixed-point arithmetic. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_volatility` + +```rust +pub fn calculate_volatility(env: Env, prices: Vec, period_secs: u64) -> i128 +``` + +Calculate price volatility as annualized standard deviation. + +Returns volatility in basis points (1 bp = 0.01%). +Uses the standard deviation of price returns. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_min_max` + +```rust +pub fn calculate_min_max(_env: Env, values: Vec) -> (i128, i128) +``` + +Calculate min and max values in a series. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_median` + +```rust +pub fn calculate_median(env: Env, values: Vec) -> i128 +``` + +Calculate median value of a sorted series. + +For even-length series, returns average of two middle values. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_percentiles` + +```rust +pub fn calculate_percentiles(env: Env, values: Vec) -> (i128, i128, i128) +``` + +Calculate percentiles (25th and 75th) for a value series. + +Returns (p25, median, p75). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_statistics` + +```rust +pub fn compute_statistics(env: Env, caller: Address, asset_code: String, period: StatPeriod,) -> Statistics +``` + +Compute all statistics for an asset over a specified period. + +Calculates and stores: average, stddev, volatility, min/max, median, percentiles. +Requires at least 2 data points for meaningful statistics. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `stats_avg` + +#### `get_statistics` + +```rust +pub fn get_statistics(env: Env, asset_code: String, period: StatPeriod) -> Option +``` + +Get pre-computed statistics for an asset. + +Returns the most recent statistics for the specified period, or None +if no statistics have been computed. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_statistics_history` + +```rust +pub fn get_statistics_history(env: Env, asset_code: String) -> Vec +``` + +Get all historical statistics for an asset. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `trigger_periodic_stats` + +```rust +pub fn trigger_periodic_stats(env: Env, caller: Address) +``` + +Trigger periodic statistics calculation for all active assets. + +Intended to be called periodically (e.g., by an automation service) +to keep statistics up-to-date. Calculates daily statistics for all +assets with sufficient data. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `calculate_rolling_statistics` + +```rust +pub fn calculate_rolling_statistics(env: Env, values: Vec, window_size: u32, step: u32,) -> Vec +``` + +Calculate rolling window statistics over a series. + +Returns a vector of statistics, each computed over `window_size` data points, +sliding by `step` points each time. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_correlation` + +```rust +pub fn calculate_correlation(env: Env, x: Vec, y: Vec) -> i128 +``` + +Calculate correlation coefficient between two series. +Returns value between -10_000 and 10_000 (scaled by 10_000). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_ema` + +```rust +pub fn calculate_ema(_env: Env, values: Vec, smoothing_factor: i128) -> i128 +``` + +Calculate exponential moving average (EMA). + +`smoothing_factor` is a value between 0 and 10_000 representing +the smoothing constant alpha (where alpha = smoothing_factor / 10_000). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_stats_methods_docs` + +```rust +pub fn get_stats_methods_docs(env: Env) -> String +``` + +Document statistical methods available in the contract. + +Returns a string describing each statistical function and its usage. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `enter_recovery_mode` + +```rust +pub fn enter_recovery_mode(env: Env, caller: Address, reason: String) +``` + +Enter emergency recovery mode. + +Signals that the contract is in a degraded state and operators must +follow a manual recovery runbook. Only the contract admin may activate +recovery. The reason is stored on-chain for the audit trail. + +# Panics +- `caller` is not the contract admin. +- Recovery mode is already active. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `rec_entr` + +#### `exit_recovery_mode` + +```rust +pub fn exit_recovery_mode(env: Env, caller: Address) +``` + +Exit emergency recovery mode, returning the contract to normal operation. + +# Panics +- `caller` is not the contract admin. +- Recovery mode is not currently active. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `rec_exit` + +#### `record_recovery_step` + +```rust +pub fn record_recovery_step(env: Env, caller: Address, description: String) +``` + +Append a completed recovery step to the on-chain audit trail. + +Steps are immutable once written and serve as an ordered record of +actions taken during the recovery session. Capped at 50 steps per +session (reset when recovery mode is re-entered). + +# Panics +- `caller` is not the contract admin. +- Recovery mode is not currently active. +- The step log is already at 50 entries. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `get_recovery_state` + +```rust +pub fn get_recovery_state(env: Env) -> RecoveryState +``` + +Return a summary of the current recovery state. + +When recovery is not active, `active` is `false` and the `reason`, +`entered_at`, and `entered_by` fields reflect the last recovery session +(or zero-values if recovery has never been used). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_recovery_steps` + +```rust +pub fn get_recovery_steps(env: Env) -> Vec +``` + +Return the ordered list of recovery steps recorded in the current session. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_admin_activity` + +```rust +pub fn get_admin_activity(env: Env, limit: u32, offset: u32) -> AdminActivityPage +``` + +Retrieve a page of admin activity log entries (oldest-first). + +Returns up to `limit` entries starting at zero-indexed `offset`. +Maximum `limit` per call is 50. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_admin_activity_by_actor` + +```rust +pub fn get_admin_activity_by_actor(env: Env, actor: Address, limit: u32,) -> Vec +``` + +Retrieve admin activity entries for a specific actor (most-recent first). +Returns up to `limit` matching entries; maximum is 50. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `register_health_source` + +```rust +pub fn register_health_source(env: Env, caller: Address, source_id: String, weight_bps: u32) +``` + +Register a trusted health data source. + +Only the contract admin may register sources. `weight_bps` expresses the +source's relative influence in basis points (10 000 = 100 %). Multiple +sources need not sum to 10 000 — the aggregation normalises by total +weight of contributing sources. + +# Panics +- `caller` is not the contract admin. +- `weight_bps` is zero. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `src_reg` + +#### `revoke_health_source` + +```rust +pub fn revoke_health_source(env: Env, caller: Address, source_id: String) +``` + +Revoke trust for a health source (it can no longer submit data). + +# Panics +- `caller` is not the contract admin. +- Source with `source_id` is not registered. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `src_rev` + +#### `submit_health_multi_source` + +```rust +pub fn submit_health_multi_source(env: Env, caller: Address, source_id: String, asset_code: String, health_score: u32, liquidity_score: u32, price_stability_score: u32, bridge_uptime_score: u32,) +``` + +Submit health data from a named trusted source. + +The source must be registered and trusted (see `register_health_source`). +Each source keeps its own per-asset entry; `get_aggregated_health` then +combines all trusted sources into a weighted-average view. + +# Panics +- `caller` is not the contract admin or a HealthSubmitter. +- `source_id` is not a registered trusted source. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ms_hlth` + +#### `get_aggregated_health` + +```rust +pub fn get_aggregated_health(env: Env, asset_code: String) -> Option +``` + +Compute a weighted-average health view for an asset across all trusted sources. + +Sources with no entry for `asset_code` are skipped. Returns `None` if no +trusted source has submitted data for the asset. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_health_sources` + +```rust +pub fn get_health_sources(env: Env) -> Vec +``` + +Return the list of all registered health sources. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_replay_schema_version` + +```rust +pub fn get_replay_schema_version(_env: Env) -> u32 +``` + +Return the current event payload schema version. + +Off-chain consumers should call this after connecting to detect whether +a schema migration has occurred and rebuild their replay state if needed. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** see description above + +#### `get_replay_events` + +```rust +pub fn get_replay_events(env: Env, from_ordering_key: u64, limit: u32) -> EventReplayPage +``` + +Query replay-friendly event history ordered by ascending `ordering_key`. + +Returns up to `limit` entries whose `ordering_key` is ≥ +`from_ordering_key`. Pass `0` to start from the beginning of the log. +Maximum `limit` per call is 100. The returned `EventReplayPage` includes +the total log size so callers can implement cursor-based pagination. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** see description above + +#### `get_replay_log_size` + +```rust +pub fn get_replay_log_size(env: Env) -> u32 +``` + +Return the total number of entries in the event replay log. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** see description above + +#### `register_trusted_source` + +```rust +pub fn register_trusted_source(env: Env, caller: Address, source_address: Address, name: String,) +``` + +Register a new trusted source for contract submissions. + +Only admin or super admin can register sources. Trusted sources are +authorized to submit health scores, price updates, and other contract data. + +# Arguments + +* `caller` - The admin performing the registration +* `source_address` - The address to register as a trusted source +* `name` - Human-readable name/description for the source + +# Panics + +* If `caller` is not an admin or super admin +* If `name` is empty + +# Events + +Emits a `SourceRegisteredEvent` on success. + +# Example + +```ignore +contract.register_trusted_source( +env, +admin_address, +oracle_address, +"CoinGecko Price Oracle".into(), +); +``` + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** see description above + +#### `revoke_trusted_source` + +```rust +pub fn revoke_trusted_source(env: Env, caller: Address, source_address: Address) +``` + +Revoke a trusted source, preventing it from making further submissions. + +Only admin or super admin can revoke sources. The source record is +preserved for audit purposes but marked as inactive. + +# Arguments + +* `caller` - The admin performing the revocation +* `source_address` - The address to revoke + +# Panics + +* If `caller` is not an admin or super admin +* If `source_address` is not registered +* If `source_address` is already revoked + +# Events + +Emits a `SourceRevokedEvent` on success. + +# Example + +```ignore +contract.revoke_trusted_source(env, admin_address, oracle_address); +``` + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** see description above + +#### `is_trusted_source` + +```rust +pub fn is_trusted_source(env: Env, source_address: Address) -> bool +``` + +Check if an address is currently a trusted source. + +# Arguments + +* `source_address` - The address to check + +# Returns + +`true` if the address is registered and active, `false` otherwise. + +# Example + +```ignore +let is_trusted = contract.is_trusted_source(env, oracle_address); +if is_trusted { +// Allow submission +} +``` + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_trusted_source` + +```rust +pub fn get_trusted_source(env: Env, source_address: Address,) -> Option +``` + +Get detailed information about a trusted source. + +# Arguments + +* `source_address` - The address to query + +# Returns + +`Some(TrustedSource)` if the source is registered, `None` otherwise. + +# Example + +```ignore +if let Some(source) = contract.get_trusted_source(env, oracle_address) { +log!("Source: {}, Active: {}", source.name, source.is_active); +} +``` + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_all_trusted_sources` + +```rust +pub fn get_all_trusted_sources(env: Env) -> Vec +``` + +Get a list of all registered trusted sources (active and revoked). + +# Returns + +A vector of `SourceInfo` records for all registered sources. + +# Example + +```ignore +let all_sources = contract.get_all_trusted_sources(env); +for source in all_sources.iter() { +log!("Source: {}, Active: {}", source.name, source.is_active); +} +``` + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_active_trusted_sources` + +```rust +pub fn get_active_trusted_sources(env: Env) -> Vec +``` + +Get a list of only active trusted sources. + +# Returns + +A vector of `SourceInfo` records for active sources only. + +# Example + +```ignore +let active_sources = contract.get_active_trusted_sources(env); +log!("Active sources: {}", active_sources.len()); +``` + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### EmergencyFundRecovery + +**Source:** [`soroban/src/emergency_fund_recovery.rs`](../src/emergency_fund_recovery.rs) + +**Contract type:** `EmergencyFundRecovery` + +A second `#[contract]` type that is unconditionally compiled into the same release wasm artifact as `BridgeWatchContract` (see [Compilation status](#compilation-status)). Lets a timelocked admin recover stranded funds from the contract to a destination address. + +#### `initialize_recovery` + +```rust +pub fn initialize_recovery(env: Env, admin: Address, timelock_seconds: u64,) -> Result<(), RecoveryError> +``` + +Initialize emergency fund recovery with admin and timelock settings + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `enable_emergency_recovery` + +```rust +pub fn enable_emergency_recovery(env: Env, admin: Address) -> Result<(), RecoveryError> +``` + +Enable emergency fund recovery mode (requires admin authorization) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `emergency_recovery`, `timestamp` + +#### `disable_emergency_recovery` + +```rust +pub fn disable_emergency_recovery(env: Env, admin: Address) -> Result<(), RecoveryError> +``` + +Disable emergency fund recovery mode + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `emergency_recovery`, `timestamp` + +#### `add_recovery_authorizer` + +```rust +pub fn add_recovery_authorizer(env: Env, admin: Address, user: Address, can_initiate: bool, can_approve: bool, can_execute: bool, can_cancel: bool,) -> Result<(), RecoveryError> +``` + +Add an authorized recovery user with specific permissions + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `initiate_recovery` + +```rust +pub fn initiate_recovery(env: Env, initiator: Address, destination: Address, token_address: Address, amount: i128, reason: String,) -> Result +``` + +Initiate an emergency fund recovery + +- **Auth:** `initiator` (`.require_auth()` called directly in this function) +- **Events:** `amount`, `destination`, `emergency_recovery`, `initiator`, `recovery_id`, `timelock_until` + +#### `approve_recovery` + +```rust +pub fn approve_recovery(env: Env, approver: Address, recovery_id: u64,) -> Result<(), RecoveryError> +``` + +Approve an emergency fund recovery + +- **Auth:** `approver` (`.require_auth()` called directly in this function) +- **Events:** `approvals_count`, `approver`, `emergency_recovery`, `recovery_id` + +#### `execute_recovery` + +```rust +pub fn execute_recovery(env: Env, executor: Address, recovery_id: u64,) -> Result<(), RecoveryError> +``` + +Execute an approved emergency fund recovery + +- **Auth:** `executor` (`.require_auth()` called directly in this function) +- **Events:** `amount`, `destination`, `emergency_recovery`, `executor`, `recovery_id` + +#### `cancel_recovery` + +```rust +pub fn cancel_recovery(env: Env, canceller: Address, recovery_id: u64, reason: String,) -> Result<(), RecoveryError> +``` + +Cancel a pending recovery + +- **Auth:** `canceller` (`.require_auth()` called directly in this function) +- **Events:** `cancelled_by`, `emergency_recovery`, `reason`, `recovery_id` + +#### `get_recovery` + +```rust +pub fn get_recovery(env: Env, recovery_id: u64) -> Result +``` + +Get recovery details + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_total_recovered` + +```rust +pub fn get_total_recovered(env: Env) -> i128 +``` + +Get total funds recovered + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_recovery_history` + +```rust +pub fn get_recovery_history(env: Env) -> Vec +``` + +Get recovery history + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +**Error codes:** see [`RecoveryError` in ERRORS.md](./ERRORS.md#recoveryerror). + +## Part 2 — Logic modules backing `BridgeWatchContract` + +Free functions (not `#[contract]` types) that `BridgeWatchContract` calls into. They share the calling contract's storage and are only reachable through `BridgeWatchContract`'s own entry points, most of which wrap one of these functions directly — see the doc comment on the wrapping method in Part 1 for the exact user-facing signature. + +### acl — Access Control List + +**Source:** [`soroban/src/acl.rs`](../src/acl.rs) + +Role-based permission system (`Admin`, `SuperAdmin`, custom roles/permissions) backing `BridgeWatchContract`'s authorization checks. + +#### `role_permissions` + +```rust +pub fn role_permissions(role: &Role) -> &'static [Permission] +``` + +Returns the set of [`Permission`]s inherited by `role`. + +`SuperAdmin` is handled separately in [`has_permission_internal`] (it +passes every check unconditionally), so it is not listed here. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `has_role_internal` + +```rust +pub fn has_role_internal(env: &Env, address: &Address, role: &Role) -> bool +``` + +Return `true` if `address` currently holds `role` (respects expiry). + +- **Auth:** none (read-only query) +- **Events:** none + +#### `has_permission_internal` + +```rust +pub fn has_permission_internal(env: &Env, address: &Address, permission: &Permission) -> bool +``` + +Return `true` if `address` has `permission` via any active role or direct grant. + +Evaluation order: +1. `SuperAdmin` role → always passes. +2. Any role whose inherited permissions include `permission`. +3. Direct permission grant. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `require_permission` + +```rust +pub fn require_permission(env: &Env, caller: &Address, admin: &Address, permission: &Permission) +``` + +Require that `caller` holds `permission` (or is the contract admin). + +`admin` is the address stored under `DataKey::Admin` in the caller's +contract — passed in to avoid a cross-module storage dependency. + +Calls `caller.require_auth()` and panics with a descriptive message if the +check fails. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `grant_role_internal` + +```rust +pub fn grant_role_internal(env: &Env, grantee: &Address, role: &Role, granted_by: &Address, expires_at: u64,) +``` + +Internal: add a role grant (deduplicates by grantee+role, updates expiry). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `revoke_role_internal` + +```rust +pub fn revoke_role_internal(env: &Env, grantee: &Address, role: &Role) +``` + +Internal: remove a role grant. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `grant_permission_internal` + +```rust +pub fn grant_permission_internal(env: &Env, grantee: &Address, permission: &Permission, granted_by: &Address, expires_at: u64,) +``` + +Internal: add a direct permission grant (deduplicates, updates expiry). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `revoke_permission_internal` + +```rust +pub fn revoke_permission_internal(env: &Env, grantee: &Address, permission: &Permission) +``` + +Internal: remove a direct permission grant. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +### liquidity_pool — Liquidity Pool Monitor + +**Source:** [`soroban/src/liquidity_pool.rs`](../src/liquidity_pool.rs) + +Tracks liquidity pool states across Stellar DEXs, computing historical depth, impermanent-loss, and performance metrics. + +#### `record_pool_state` + +```rust +pub fn record_pool_state(env: &Env, pool_id: String, reserve_a: i128, reserve_b: i128, total_shares: i128, volume: i128, fees: i128, pool_type: PoolType,) +``` + +Record a new pool state snapshot. + +Writes the snapshot into the pool's ring buffer, updates (or creates) the +relevant daily bucket, and emits events when significant liquidity changes +are detected. + +# Panics +Caller must have already verified admin authorisation before invoking this. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `snapshot` + +#### `calculate_pool_metrics` + +```rust +pub fn calculate_pool_metrics(env: &Env, pool_id: String, window_secs: u64) -> PoolMetrics +``` + +Calculate aggregated pool metrics over a specified time window. + +Scans the ring buffer for snapshots within `[now − window_secs, now]` and +computes volume, average depth, price change, fees, and an annualised fee APR. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_pool_history` + +```rust +pub fn get_pool_history(env: &Env, pool_id: String, from_timestamp: u64, to_timestamp: u64,) -> Vec +``` + +Retrieve historical pool snapshots within a time range. + +Returns a `Vec` ordered oldest-first. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `calculate_impermanent_loss` + +```rust +pub fn calculate_impermanent_loss(env: &Env, pool_id: String, entry_price: i128, initial_value: i128,) -> ImpermanentLossResult +``` + +Calculate impermanent loss for a position entered at `entry_price`. + +Uses the standard IL formula: +```text +IL = 2 * sqrt(price_ratio) / (1 + price_ratio) − 1 +``` +We approximate `sqrt` via the integer Newton's method (Babylonian). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_liquidity_depth` + +```rust +pub fn get_liquidity_depth(env: &Env, pool_id: String) -> LiquidityDepth +``` + +Get current liquidity depth information for a pool. + +Computes a depth score (0–100) based on reserve sizes relative to a +baseline of 1 000 000 units (scaled by PRECISION). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_daily_history` + +```rust +pub fn get_daily_history(env: &Env, pool_id: String, from_timestamp: u64, to_timestamp: u64,) -> Vec +``` + +Get daily aggregated buckets for a pool within a time range. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_registered_pools` + +```rust +pub fn get_registered_pools(env: &Env) -> Vec +``` + +Get all registered pool IDs. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### migration — State Migration Helper + +**Source:** [`soroban/src/migration.rs`](../src/migration.rs) + +Tracks the contract's schema version and records migration audit entries. + +#### `get_version` + +```rust +pub fn get_version(env: &Env) -> MigrationVersion +``` + +Read the current schema version from persistent storage. +Returns `MigrationVersion { major: 0, minor: 0, patch: 0 }` when no +version has been written yet (fresh deployment). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_version` + +```rust +pub fn set_version(env: &Env, version: MigrationVersion) +``` + +Persist `version` as the current schema version. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `validate_upgrade` + +```rust +pub fn validate_upgrade(from: &MigrationVersion, to: &MigrationVersion,) -> Result<(), MigrationError> +``` + +Validate that migrating `from` → `to` is a forward-only upgrade. + +Rules: +- `to` must not equal `from` (that would be `AlreadyAtVersion`). +- `to` must be strictly greater than `from` in semver order (major +takes precedence, then minor, then patch). Any lower value is +`VersionDowngradeNotAllowed`. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `record_migration` + +```rust +pub fn record_migration(env: &Env, record: MigrationRecord) +``` + +Append `record` to the persistent migration history log. + +The history is stored as a `Vec`. If no history +exists yet a new single-element vector is created. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_history` + +```rust +pub fn get_history(env: &Env) -> Vec +``` + +Return the full migration history in insertion order (oldest first). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `emit_migration_event` + +```rust +pub fn emit_migration_event(env: &Env, from: &MigrationVersion, to: &MigrationVersion) +``` + +Publish a contract event so off-chain indexers can observe migrations. + +Event topics: `["migration", from_major, from_minor, from_patch]` +Event data: `[to_major, to_minor, to_patch]` + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `migration` + +### operator_rotation — Operator Registry + +**Source:** [`soroban/src/operator_rotation.rs`](../src/operator_rotation.rs) + +Admin-managed registry of operator addresses, with add/remove/reactivate semantics. + +#### `add_operator` + +```rust +pub fn add_operator(env: &Env, caller: &Address, operator_address: &Address, name: String) +``` + +Registers `operator_address` (or reactivates it if previously removed) under `name`. + +- **Auth:** the contract admin +- **Events:** `op_add` (operator_address, name, caller, now) + +#### `remove_operator` + +```rust +pub fn remove_operator(env: &Env, caller: &Address, operator_address: &Address) +``` + +Deactivates an operator. Refuses to remove the last remaining active operator. + +- **Auth:** the contract admin +- **Events:** `op_rem` (operator_address, caller, now) + +#### `is_operator` + +```rust +pub fn is_operator(env: &Env, operator_address: &Address) -> bool +``` + +Returns whether `operator_address` is currently an active operator. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_operator` + +```rust +pub fn get_operator(env: &Env, operator_address: &Address) -> Option +``` + +Returns the full operator record for `operator_address`, if any (active or removed). + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_all_operators` + +```rust +pub fn get_all_operators(env: &Env) -> Vec +``` + +Returns every operator ever registered, active and removed. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_active_operators` + +```rust +pub fn get_active_operators(env: &Env) -> Vec +``` + +Returns only the currently-active operators. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### report_hash — Report Hashing + +**Source:** [`soroban/src/report_hash.rs`](../src/report_hash.rs) + +Deterministic SHA-256 hashing of health/price/mismatch/liquidity report payloads, used to let off-chain submitters prove report integrity. + +#### `compute_report_hash` + +```rust +pub fn compute_report_hash(env: &Env, payload: &ReportPayload) -> ReportHashResult +``` + +Computes the SHA-256 hash of a generic `ReportPayload` (report type, asset code, value, timestamp, nonce). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `verify_report_hash` + +```rust +pub fn verify_report_hash(env: &Env, payload: &ReportPayload, expected_hash: &BytesN<32>) -> bool +``` + +Recomputes the hash of `payload` and compares it against `expected_hash`. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_health_report_hash` + +```rust +pub fn compute_health_report_hash(env: &Env, asset_code: &String, health_score: u32, liquidity_score: u32, price_stability_score: u32, bridge_uptime_score: u32, timestamp: u64, nonce: u64,) -> ReportHashResult +``` + +Builds a `"health"`-typed `ReportPayload` from the four health sub-scores and hashes it. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_price_report_hash` + +```rust +pub fn compute_price_report_hash(env: &Env, asset_code: &String, price: i128, source: &String, timestamp: u64, nonce: u64,) -> ReportHashResult +``` + +Builds a `"price"`-typed `ReportPayload` from a price and source, and hashes it. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_mismatch_report_hash` + +```rust +pub fn compute_mismatch_report_hash(env: &Env, bridge_id: &String, asset_code: &String, stellar_supply: i128, source_chain_supply: i128, timestamp: u64, nonce: u64,) -> ReportHashResult +``` + +Builds a `"mismatch"`-typed `ReportPayload` from the Stellar vs. source-chain supply difference, and hashes it. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_liquidity_report_hash` + +```rust +pub fn compute_liquidity_report_hash(env: &Env, asset_pair: &String, total_liquidity: i128, depth_0_1_pct: i128, depth_0_5_pct: i128, depth_1_pct: i128, depth_5_pct: i128, timestamp: u64, nonce: u64,) -> ReportHashResult +``` + +Builds a `"liquidity"`-typed `ReportPayload` from total liquidity and depth-at-percentage figures, and hashes it. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### source_blessing — Preferred Source Registry + +**Source:** [`soroban/src/source_blessing.rs`](../src/source_blessing.rs) + +Per-asset admin "blessing" of a preferred data source, independent of the trusted-source allow-list in `source_trust`. + +#### `bless_source` + +```rust +pub fn bless_source(env: &Env, caller: &Address, source_address: &Address, asset_code: String, name: String,) +``` + +Marks `source_address` as the admin-blessed (preferred) data source for `asset_code`, or reactivates a previously unblessed one. + +- **Auth:** the contract admin +- **Events:** `src_bls` (source_address, asset_code, name, caller, now) + +#### `unbless_source` + +```rust +pub fn unbless_source(env: &Env, caller: &Address, source_address: &Address, asset_code: String) +``` + +Revokes a source's blessing for a given asset. + +- **Auth:** the contract admin +- **Events:** `src_unb` (source_address, asset_code, caller, now) + +#### `is_source_blessed` + +```rust +pub fn is_source_blessed(env: &Env, source_address: &Address, asset_code: &String) -> bool +``` + +Returns whether `source_address` is actively blessed for `asset_code`. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_blessing` + +```rust +pub fn get_blessing(env: &Env, source_address: &Address, asset_code: &String,) -> Option +``` + +Returns the full blessing record for `(source_address, asset_code)`, if any. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_blessed_sources_for_asset` + +```rust +pub fn get_blessed_sources_for_asset(env: &Env, asset_code: &String) -> Vec +``` + +Returns every source ever blessed for `asset_code`, active or revoked. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_all_blessings` + +```rust +pub fn get_all_blessings(env: &Env) -> Vec +``` + +Returns every blessing record across all sources and assets. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_preferred_source_for_asset` + +```rust +pub fn get_preferred_source_for_asset(env: &Env, asset_code: &String) -> Option
+``` + +Returns the first currently-active blessed source for `asset_code`, or `None` if there isn't one. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### source_trust — Trusted Source Registry + +**Source:** [`soroban/src/source_trust.rs`](../src/source_trust.rs) + +Registry of addresses authorized to submit contract data; see [`TRUSTED_SOURCE_REGISTRY.md`](./TRUSTED_SOURCE_REGISTRY.md) for the full design writeup. + +#### `register_trusted_source` + +```rust +pub fn register_trusted_source(env: &Env, caller: &Address, source_address: &Address, name: String,) +``` + +Register a new trusted source or reactivate a previously revoked one. + +# Arguments + +* `env` - The contract environment +* `caller` - The admin performing the registration (must have admin permissions) +* `source_address` - The address to register as a trusted source +* `name` - Human-readable name/description for the source + +# Panics + +* If `caller` is not an admin or super admin +* If `name` is empty +* If `source_address` is the zero address + +# Events + +Emits a `SourceRegisteredEvent` on success. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `SourceRegisteredEvent`, `src_reg` + +#### `revoke_trusted_source` + +```rust +pub fn revoke_trusted_source(env: &Env, caller: &Address, source_address: &Address) +``` + +Revoke a trusted source, preventing it from making further submissions. + +# Arguments + +* `env` - The contract environment +* `caller` - The admin performing the revocation (must have admin permissions) +* `source_address` - The address to revoke + +# Panics + +* If `caller` is not an admin or super admin +* If `source_address` is not registered +* If `source_address` is already revoked + +# Events + +Emits a `SourceRevokedEvent` on success. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `SourceRevokedEvent`, `src_rev` + +#### `is_trusted_source` + +```rust +pub fn is_trusted_source(env: &Env, source_address: &Address) -> bool +``` + +Check if an address is currently a trusted source. + +# Arguments + +* `env` - The contract environment +* `source_address` - The address to check + +# Returns + +`true` if the address is registered and active, `false` otherwise. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_trusted_source` + +```rust +pub fn get_trusted_source(env: &Env, source_address: &Address) -> Option +``` + +Get detailed information about a trusted source. + +# Arguments + +* `env` - The contract environment +* `source_address` - The address to query + +# Returns + +`Some(TrustedSource)` if the source is registered, `None` otherwise. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_all_trusted_sources` + +```rust +pub fn get_all_trusted_sources(env: &Env) -> Vec +``` + +Get a list of all registered trusted sources (active and revoked). + +# Arguments + +* `env` - The contract environment + +# Returns + +A vector of `SourceInfo` records for all registered sources. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_active_trusted_sources` + +```rust +pub fn get_active_trusted_sources(env: &Env) -> Vec +``` + +Get a list of only active trusted sources. + +# Arguments + +* `env` - The contract environment + +# Returns + +A vector of `SourceInfo` records for active sources only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `require_trusted_source` + +```rust +pub fn require_trusted_source(env: &Env, caller: &Address) +``` + +Require that the caller is a trusted source, panicking if not. + +This is a convenience function for gating submissions. + +# Arguments + +* `env` - The contract environment +* `caller` - The address to check + +# Panics + +If `caller` is not an active trusted source. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +### state_export — State Export Views + +**Source:** [`soroban/src/state_export.rs`](../src/state_export.rs) + +Compact, exportable views of contract state for off-chain sync and auditing. + +#### `build_asset_snapshot_from_health` + +```rust +pub fn build_asset_snapshot_from_health(env: &Env, health: &AssetHealth) -> AssetStateSnapshot +``` + +Build a compact asset snapshot from on-chain health data. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_state_hash` + +```rust +pub fn compute_state_hash(env: Env, asset_code: &String, status: &String, risk_score: u32, timestamp: u64,) -> String +``` + +Generate deterministic state hash for audit trail. + +Uses SHA-256 over the same byte encoding as the other hash functions in +this file — `no_std` compatible, no `format!` macro required. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `build_empty_asset_snapshot` + +```rust +pub fn build_empty_asset_snapshot(env: &Env, asset_code: String) -> AssetStateSnapshot +``` + +Build a placeholder snapshot when no health record exists yet. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `sort_snapshots` + +```rust +pub fn sort_snapshots(env: &Env, snapshots: &mut Vec) +``` + +Sort snapshots by asset code for stable ordering. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_snapshots_hash` + +```rust +pub fn compute_snapshots_hash(env: &Env, snapshots: &Vec) -> String +``` + +Compute deterministic SHA-256 hash over the export payload. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `assemble_export` + +```rust +pub fn assemble_export(env: &Env, contract_address: Address, snapshots: Vec,) -> StateExport +``` + +Assemble the top-level export envelope. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `compare_strings` + +```rust +pub fn compare_strings(left: &String, right: &String) -> i32 +``` + +Lexicographic string comparison for stable asset ordering. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### threshold_window — Deviation Threshold Windows + +**Source:** [`soroban/src/threshold_window.rs`](../src/threshold_window.rs) + +Named, admin-configured windows that flag basis-point deviations between a reference and current value. + +#### `create_window` + +```rust +pub fn create_window(env: &Env, caller: &Address, window_id: String, length: u64, unit: WindowUnit, threshold_bps: u32,) +``` + +Creates a named deviation-threshold window (`length` in `unit`s, breach threshold in bps). Limited to `MAX_WINDOWS` (10) windows. + +- **Auth:** the contract admin +- **Events:** `win_crt` (window_id, length, threshold_bps) + +#### `update_window` + +```rust +pub fn update_window(env: &Env, caller: &Address, window_id: String, length: u64, unit: WindowUnit, threshold_bps: u32,) +``` + +Updates an existing window's length, unit, and threshold. + +- **Auth:** the contract admin +- **Events:** `win_upd` (window_id, length, threshold_bps) + +#### `remove_window` + +```rust +pub fn remove_window(env: &Env, caller: &Address, window_id: String) +``` + +Deletes a window. + +- **Auth:** the contract admin +- **Events:** `win_rem` (window_id) + +#### `get_window` + +```rust +pub fn get_window(env: &Env, window_id: &String) -> Option +``` + +Returns a window's configuration by ID, if it exists. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_all_windows` + +```rust +pub fn get_all_windows(env: &Env) -> Vec +``` + +Returns every configured window. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `evaluate_threshold` + +```rust +pub fn evaluate_threshold(env: &Env, window_id: &String, reference_value: i128, current_value: i128,) -> Option +``` + +Computes the basis-point deviation between `reference_value` and `current_value` and reports whether it breaches the window's configured threshold. A zero `reference_value` is treated as no breach. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_window_seconds` + +```rust +pub fn get_window_seconds(config: &WindowConfig) -> u64 +``` + +Converts a `WindowConfig`'s `length`/`unit` pair into seconds. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### version_migration_helper — Enhanced Migration Helper + +**Source:** [`soroban/src/version_migration_helper.rs`](../src/version_migration_helper.rs) + +A more complete migration system than `migration.rs`: semantic-versioned upgrades, pre/post validation checkpoints, state snapshots, and rollback. + +#### `initialize` + +```rust +pub fn initialize(env: &Env, admin: Address, initial_version: MigrationVersion,) -> Result<(), MigrationError> +``` + +Initializes the migration system with `admin` as the sole authorized migrator and a 1-hour default migration timeout. + +- **Auth:** `admin` +- **Events:** none + +#### `get_version` + +```rust +pub fn get_version(env: &Env) -> MigrationVersion +``` + +Returns the current contract schema version (defaults to `0.0.0` if never set). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `create_state_snapshot` + +```rust +pub fn create_state_snapshot(env: &Env, snapshot_by: Address, description: SorobanString, data: Map,) -> Result +``` + +Stores a state snapshot (with caller-supplied `data`) tagged with the current version, retained for 7 days for rollback. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `validate_upgrade` + +```rust +pub fn validate_upgrade(from: &MigrationVersion, to: &MigrationVersion,) -> Result<(), MigrationError> +``` + +Checks that `to` is a strictly forward version relative to `from` (major, then minor, then patch); returns `MigrationError::AlreadyAtVersion` or `VersionDowngradeNotAllowed` otherwise. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `begin_migration` + +```rust +pub fn begin_migration(env: &Env, migrator: Address, // Reserved for wiring into `validate_upgrade` in a future change. _target_version: MigrationVersion,) -> Result<(), MigrationError> +``` + +Starts a migration: verifies `migrator` is authorized and that no migration is already in progress, then sets the in-progress flag. + +- **Auth:** `migrator`, and must be in the authorized-migrators list +- **Events:** none + +#### `complete_migration` + +```rust +pub fn complete_migration(env: &Env, from_version: MigrationVersion, to_version: MigrationVersion, migrator: Address, notes: SorobanString,) -> Result<(), MigrationError> +``` + +Validates the upgrade path, advances the stored version to `to_version`, appends a `MigrationRecord`, and clears the in-progress flag. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `("migration", "completed")` with the from/to version tuples + +#### `validate_state` + +```rust +pub fn validate_state(env: &Env, checkpoint: ValidationCheckpoint, errors: Vec, warnings: Vec,) -> Result +``` + +Records a validation result for a checkpoint (Pre/PostMigration, RollbackPrep) and returns `MigrationError::ValidationFailed` if any errors were supplied. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_history` + +```rust +pub fn get_history(env: &Env) -> Vec +``` + +Returns every recorded migration. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_snapshots` + +```rust +pub fn get_snapshots(env: &Env) -> Vec +``` + +Returns every stored state snapshot. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `rollback_to_snapshot` + +```rust +pub fn rollback_to_snapshot(env: &Env, admin: Address, snapshot_hash: SorobanString,) -> Result<(), MigrationError> +``` + +Restores the stored version from a snapshot matched by `snapshot_hash`, if it exists, isn't expired, and is marked rollback-available. + +- **Auth:** `admin` +- **Events:** `("migration", "rollback")` with the snapshot hash + +#### `add_migrator` + +```rust +pub fn add_migrator(env: &Env, admin: Address, new_migrator: Address,) -> Result<(), MigrationError> +``` + +Adds `new_migrator` to the authorized-migrators list (no-op if already present). + +- **Auth:** `admin` +- **Events:** none + +#### `remove_migrator` + +```rust +pub fn remove_migrator(env: &Env, admin: Address, migrator: Address,) -> Result<(), MigrationError> +``` + +Removes `migrator` from the authorized-migrators list. + +- **Auth:** `admin` +- **Events:** none + +#### `emit_migration_event` + +```rust +pub fn emit_migration_event(env: &Env, from: &MigrationVersion, to: &MigrationVersion) +``` + +Publishes an off-chain-monitoring event for a version transition. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `("migration", from.major, from.minor, from.patch)` with the target version as data + +## Part 3 — Cross-Chain Relay contract (test-binary only) + +`soroban/src/relay/` is **not** declared as a module from `soroban/src/lib.rs`, so it is not part of the crate's `[lib]` target and is not included in the release wasm build. It is pulled in only by `soroban/tests/relay_contract_integration.rs` and `relay_contract_fuzz.rs` via `#[path = "../src/relay/mod.rs"]`, which is how its test suite runs in CI. Treat it as a separately-deployable contract that is fully implemented and tested, but not part of the current `BridgeWatchContract` release artifact. + +### CrossChainRelayContract + +**Source:** [`soroban/src/relay/mod.rs`](../src/relay/mod.rs) + +**Contract type:** `CrossChainRelayContract` + +Cross-chain message relay contract: multi-chain adapters, a priority queue for pending messages, relay-operator management, and state-proof verification. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address, default_ttl: u64) -> Result<(), RelayError> +``` + +Initialize relay contract. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `configure_chain` + +```rust +pub fn configure_chain(env: Env, config: ChainConfig) -> Result<(), RelayError> +``` + +Configure fee model and status for a target chain (admin only). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `register_relay_operator` + +```rust +pub fn register_relay_operator(env: Env, operator: Address, public_key: BytesN<32>,) -> Result<(), RelayError> +``` + +Register and whitelist a relay operator (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `deactivate_relay_operator` + +```rust +pub fn deactivate_relay_operator(env: Env, operator: Address) -> Result<(), RelayError> +``` + +Deactivate a relay operator (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `send_message` + +```rust +pub fn send_message(env: Env, source_chain: ChainId, dest_chain: ChainId, sender: Address, payload: Bytes, nonce: u64, priority: MessagePriority, ttl_override: u64, fee_paid: i128,) -> Result, RelayError> +``` + +Send a cross-chain message into the relay queue. + +`fee_paid` must be greater than or equal to the estimated relay fee. +`ttl_override` when set to 0 means use default TTL. + +- **Auth:** `sender` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `verify_message` + +```rust +pub fn verify_message(env: Env, message_id: BytesN<32>, proof: StateProof,) -> Result +``` + +Verify message and associated source-chain state proof. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `relay_message` + +```rust +pub fn relay_message(env: Env, operator: Address, message_id: BytesN<32>, signature: BytesN<64>,) -> Result +``` + +Relay a single verified/pending message by an active operator. + +Signature format: +`signature[0..32] == sha256(message_id || operator_public_key)` and +`signature[32..64] == sha256(message_id || operator_public_key)`. + +- **Auth:** `operator` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `verify_state_proof` + +```rust +pub fn verify_state_proof(env: Env, proof: StateProof) -> Result +``` + +Verify source chain state proof. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `batch_relay` + +```rust +pub fn batch_relay(env: Env, operator: Address, items: Vec,) -> Result +``` + +Relay a batch of messages for gas/cost efficiency. + +- **Auth:** `operator` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `get_sender_nonce` + +```rust +pub fn get_sender_nonce(env: Env, sender: Address) -> u64 +``` + +Return current sender nonce. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_message` + +```rust +pub fn get_message(env: Env, message_id: BytesN<32>) -> Option +``` + +Return current message by id. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_operator` + +```rust +pub fn get_operator(env: Env, operator: Address) -> Option +``` + +Return relay operator metadata by address. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_message_queue` + +```rust +pub fn get_message_queue(env: Env) -> Vec> +``` + +Return current pending message queue. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `peek_next_message` + +```rust +pub fn peek_next_message(env: Env) -> Option> +``` + +Return next message in queue (highest priority). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `estimate_fee` + +```rust +pub fn estimate_fee(env: Env, dest_chain: ChainId, payload: Bytes) -> Result +``` + +Estimate relay fee for a payload and destination chain. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `cleanup_expired_messages` + +```rust +pub fn cleanup_expired_messages(env: Env, max_items: u32) -> Result +``` + +Cleanup expired pending messages from queue. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_metrics` + +```rust +pub fn get_metrics(env: Env) -> Map +``` + +Return aggregated relay metrics. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +**Error codes:** see [`RelayError` in ERRORS.md](./ERRORS.md#relayerror). + +### relay::types — Relay Data Types + +**Source:** [`soroban/src/relay/types.rs`](../src/relay/types.rs) + +Data types shared across the relay contract (messages, operators, state proofs, fee estimates). + +_No public functions in this file (types/errors only)._ + +### relay::events — Relay Event Helpers + +**Source:** [`soroban/src/relay/events.rs`](../src/relay/events.rs) + +Typed helpers that publish relay events in a consistent `(topic, topic, ...)` + `data` shape. + +#### `emit_message_sent` + +```rust +pub fn emit_message_sent(env: &Env, message_id: &BytesN<32>, sender: &Address, dest_chain: &ChainId,) +``` + +Emitted when a new message is submitted. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `msg_sent` + +#### `emit_message_status_changed` + +```rust +pub fn emit_message_status_changed(env: &Env, message_id: &BytesN<32>, old_status: &MessageStatus, new_status: &MessageStatus,) +``` + +Emitted when a message status changes. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `msg_stat` + +#### `emit_message_relayed` + +```rust +pub fn emit_message_relayed(env: &Env, message_id: &BytesN<32>, operator: &Address) +``` + +Emitted when a message is relayed. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `msg_rly` + +#### `emit_operator_registered` + +```rust +pub fn emit_operator_registered(env: &Env, operator: &Address) +``` + +Emitted when a relay operator is registered. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `op_reg` + +#### `emit_operator_deactivated` + +```rust +pub fn emit_operator_deactivated(env: &Env, operator: &Address) +``` + +Emitted when a relay operator is deactivated. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `op_deact` + +#### `emit_state_proof_verified` + +```rust +pub fn emit_state_proof_verified(env: &Env, chain_id: &ChainId, block_number: u64) +``` + +Emitted when a state proof is verified. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `st_proof` + +#### `emit_batch_relayed` + +```rust +pub fn emit_batch_relayed(env: &Env, success_count: u32, failure_count: u32) +``` + +Emitted when a batch relay completes. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `batch` + +#### `emit_messages_cleaned` + +```rust +pub fn emit_messages_cleaned(env: &Env, count: u32) +``` + +Emitted when expired messages are cleaned up. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `cleaned` + +## Part 4 — Standalone experimental contracts (`cfg(test)` only) + +Each of these modules defines its own `#[contract]` type. `soroban/src/lib.rs` declares them with `#[cfg(test)]`, so they compile only when running `cargo test` on the native target — **not** for `cargo build --target wasm32-unknown-unknown`. The lib.rs comment above the module list explains why: several of these types would collide with `BridgeWatchContract`'s exported wasm symbols if compiled into the same release binary. Their test suites run in CI (`cargo test`) and pass, but none of them are part of the deployed contract today. + +### AnalyticsAggregatorContract + +**Source:** [`soroban/src/analytics_aggregator.rs`](../src/analytics_aggregator.rs) + +**Contract type:** `AnalyticsAggregatorContract` + +Time-bucketed (hourly/daily/weekly/monthly) metric aggregation with a small custom-formula engine. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) +``` + +Sets the contract admin and initializes empty metric registries. + +- **Auth:** `admin` +- **Events:** none + +#### `record_metric` + +```rust +pub fn record_metric(env: Env, caller: Address, metric: String, value: i128, timestamp: u64) +``` + +Accumulates `value` into the hourly, daily, weekly, and monthly buckets for `metric` at `timestamp`. + +- **Auth:** checks `caller == ` the stored admin address by comparison; does not call `require_auth` on `caller`. +- **Events:** `am_rcd` (metric, value, timestamp) + +#### `get_metric_history` + +```rust +pub fn get_metric_history(env: Env, metric: String, bucket: BucketType, limit: u32,) -> Vec +``` + +Returns up to `limit` (1..=168) historical bucket values for `metric` and `bucket` type, most recent first. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_custom_metric` + +```rust +pub fn set_custom_metric(env: Env, caller: Address, name: String, formula: String) +``` + +Registers a named formula (`"tvl_per_tx"` or `"avg_user_volume"`) for later evaluation via `compute_custom_metric`. + +- **Auth:** checks `caller == ` the stored admin address by comparison; does not call `require_auth` on `caller`. +- **Events:** `am_cst` (name, formula) + +#### `compute_custom_metric` + +```rust +pub fn compute_custom_metric(env: Env, name: String) -> i128 +``` + +Evaluates a previously registered formula against the current hourly bucket values. Panics if the formula name is unrecognized. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_dashboard_summary` + +```rust +pub fn get_dashboard_summary(env: Env) -> DashboardSummary +``` + +Returns a snapshot of `tvl`, `volume`, `user_count`, and `tx_count` for the current hourly bucket. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### AssetDeprecationContract + +**Source:** [`soroban/src/asset_deprecation.rs`](../src/asset_deprecation.rs) + +**Contract type:** `AssetDeprecationContract` + +Manages a controlled deprecation/migration path for an asset, redirecting clients to a replacement. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) -> Result<(), DeprecationError> +``` + +Initialize the contract with an admin address + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `deprecate_asset` + +```rust +pub fn deprecate_asset(env: Env, admin: Address, asset_code: String, replacement_asset: Option, migration_period_seconds: Option, reason: String,) -> Result<(), DeprecationError> +``` + +Deprecate an asset with an optional replacement and custom migration period + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `depr_init` + +#### `enable_read_only` + +```rust +pub fn enable_read_only(env: Env, admin: Address, asset_code: String,) -> Result<(), DeprecationError> +``` + +Enable read-only mode for a deprecated asset (blocks write operations) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `depr_ro` + +#### `get_replacement` + +```rust +pub fn get_replacement(env: Env, asset_code: String) -> Option +``` + +Get the replacement asset for a deprecated asset + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_deprecated` + +```rust +pub fn is_deprecated(env: Env, asset_code: String) -> bool +``` + +Check if an asset is deprecated + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_migration_expired` + +```rust +pub fn is_migration_expired(env: Env, asset_code: String) -> Result +``` + +Check if migration period has expired + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +**Error codes:** see [`DeprecationError` in ERRORS.md](./ERRORS.md#deprecationerror). + +### AssetRegistryContract + +**Source:** [`soroban/src/asset_registry.rs`](../src/asset_registry.rs) + +**Contract type:** `AssetRegistryContract` + +Registry of bridged assets: metadata, activation state, freezing, and deactivation. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) -> Result<(), RegistryError> +``` + +Initialize the asset registry with an admin address. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `register_asset` + +```rust +pub fn register_asset(env: Env, admin: Address, asset_code: String, name: String, symbol: String, issuer: String, decimals: u32, category: AssetCategory, description: String, url: String,) -> Result<(), RegistryError> +``` + +Register a new asset with initial metadata. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `ar_reg` + +#### `update_metadata` + +```rust +pub fn update_metadata(env: Env, admin: Address, asset_code: String, name: String, symbol: String, issuer: String, description: String, url: String, change_reason: String,) -> Result<(), RegistryError> +``` + +Update basic metadata fields for a registered asset (admin only). + +Automatically increments the version counter and stores a historical +snapshot. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `update_category` + +```rust +pub fn update_category(env: Env, admin: Address, asset_code: String, new_category: AssetCategory,) -> Result<(), RegistryError> +``` + +Update the asset category (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `update_risk` + +```rust +pub fn update_risk(env: Env, admin: Address, asset_code: String, risk_rating: RiskRating, risk_score_bps: u32,) -> Result<(), RegistryError> +``` + +Update risk classification and score (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ar_risk` + +#### `update_status` + +```rust +pub fn update_status(env: Env, admin: Address, asset_code: String, new_status: AssetStatus,) -> Result<(), RegistryError> +``` + +Transition the asset to a new lifecycle status (admin only). + +Valid transitions: +- PendingReview → Active +- Active → Paused +- Paused → Active +- Active → Deprecated +- Paused → Deprecated + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ar_stat` + +#### `deactivate_asset` + +```rust +pub fn deactivate_asset(env: Env, admin: Address, asset_code: String, reason: String,) -> Result<(), RegistryError> +``` + +Deactivate an active asset while preserving all historical data (admin only). + +Transitions an asset from Active to Deactivated state, recording the change in version +history. All asset metadata, chain links, compliance records, oracle feeds, and other +associations are preserved intact. A deactivated asset can be restored at any time +via [`restore_asset`]. + +# Arguments +* `env` — the contract environment +* `admin` — the caller, must be the contract admin +* `asset_code` — unique identifier for the asset to deactivate +* `reason` — human-readable explanation for deactivation + +# Returns +`Ok(())` if deactivation succeeds, or an error: +- `NotAuthorized` if caller is not admin +- `AssetNotFound` if the asset_code does not exist +- `AssetAlreadyActive` if the asset is not currently Active (already deactivated, paused, deprecated, or pending) + +# Events +Emits `(symbol_short!("asset_deact"), asset_code)` with admin address data. + +# State Continuity +All metadata fields except `status`, `version`, and `updated_at` are preserved unchanged. +The deactivation is recorded as a new version entry in the asset's history. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ast_dact` + +#### `restore_asset` + +```rust +pub fn restore_asset(env: Env, admin: Address, asset_code: String,) -> Result<(), RegistryError> +``` + +Restore a deactivated asset to Active state (admin only). + +Transitions an asset from Deactivated back to Active state, preserving all historical +metadata, chain links, compliance records, oracle feeds, and other associations. +The restoration is recorded as a new version entry. + +# Arguments +* `env` — the contract environment +* `admin` — the caller, must be the contract admin +* `asset_code` — unique identifier for the asset to restore + +# Returns +`Ok(())` if restoration succeeds, or an error: +- `NotAuthorized` if caller is not admin +- `AssetNotFound` if the asset_code does not exist +- `AssetNotDeactivated` if the asset is not currently Deactivated (e.g. already Active, Paused, Deprecated) + +# Events +Emits `(symbol_short!("asset_rest"), asset_code)` with admin address data. + +# State Continuity +All metadata fields except `status`, `version`, and `updated_at` are restored unchanged. +The entire asset history, including the deactivation event and prior versions, remains intact. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ast_rest` + +#### `update_compliance` + +```rust +pub fn update_compliance(env: Env, admin: Address, asset_code: String, status: ComplianceStatus, jurisdiction: String, framework: String, last_audit_date: u64, next_audit_date: u64, notes: String,) -> Result<(), RegistryError> +``` + +Update compliance status and add a compliance record (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ar_comp` + +#### `link_chain` + +```rust +pub fn link_chain(env: Env, admin: Address, asset_code: String, chain_id: String, contract_address: String, is_canonical: bool,) -> Result<(), RegistryError> +``` + +Link an asset to a chain with its contract address. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `link_bridge_contract` + +```rust +pub fn link_bridge_contract(env: Env, admin: Address, asset_code: String, bridge_id: String, contract_address: String, source_chain: String, dest_chain: String,) -> Result<(), RegistryError> +``` + +Associate a bridge contract with an asset (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `register_oracle_feed` + +```rust +pub fn register_oracle_feed(env: Env, admin: Address, asset_code: String, feed_id: String, provider: String, chain_id: String, contract_address: String,) -> Result<(), RegistryError> +``` + +Register an oracle price feed for an asset (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `add_liquidity_pool` + +```rust +pub fn add_liquidity_pool(env: Env, admin: Address, asset_code: String, pool_id: String, paired_asset: String,) -> Result<(), RegistryError> +``` + +Associate a liquidity pool with an asset (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `whitelist_add` + +```rust +pub fn whitelist_add(env: Env, admin: Address, asset_code: String,) -> Result<(), RegistryError> +``` + +Add an asset code to the whitelist (admin only). + +Whitelisted assets are the only ones that may be registered via +`register_asset`. Emits an `ar_wl_add` event on success. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `wl_add` + +#### `whitelist_remove` + +```rust +pub fn whitelist_remove(env: Env, admin: Address, asset_code: String,) -> Result<(), RegistryError> +``` + +Remove an asset code from the whitelist (admin only). + +Removing an already-registered asset from the whitelist does not +affect its existing registration — it only prevents future +re-registration under that code. Emits an `ar_wl_rm` event. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `wl_rm` + +#### `is_whitelisted` + +```rust +pub fn is_whitelisted(env: Env, asset_code: String) -> bool +``` + +Check whether an asset code is on the whitelist. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_whitelist` + +```rust +pub fn get_whitelist(env: Env) -> Vec +``` + +Return the full whitelist. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `freeze_asset` + +```rust +pub fn freeze_asset(env: Env, admin: Address, asset_code: String, reason: String,) -> Result<(), RegistryError> +``` + +Freeze an asset to prevent updates (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ar_frz` + +#### `unfreeze_asset` + +```rust +pub fn unfreeze_asset(env: Env, admin: Address, asset_code: String,) -> Result<(), RegistryError> +``` + +Unfreeze an asset to allow updates (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `ar_unfr` + +#### `is_asset_frozen` + +```rust +pub fn is_asset_frozen(env: Env, asset_code: String) -> bool +``` + +Check if an asset is currently frozen. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_frozen_state` + +```rust +pub fn get_frozen_state(env: Env, asset_code: String) -> Option +``` + +Get the frozen state of an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_asset` + +```rust +pub fn get_asset(env: Env, asset_code: String) -> Option +``` + +Get the full metadata for an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_all_assets` + +```rust +pub fn get_all_assets(env: Env) -> Vec +``` + +Get all registered asset codes. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_assets_by_category` + +```rust +pub fn get_assets_by_category(env: Env, category: AssetCategory) -> Vec +``` + +Get assets by category. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_assets_by_status` + +```rust +pub fn get_assets_by_status(env: Env, status: AssetStatus) -> Vec +``` + +Get assets by lifecycle status. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_chain_links` + +```rust +pub fn get_chain_links(env: Env, asset_code: String) -> Vec +``` + +Get chain links for an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_oracle_feeds` + +```rust +pub fn get_oracle_feeds(env: Env, asset_code: String) -> Vec +``` + +Get oracle feeds for an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_bridge_associations` + +```rust +pub fn get_bridge_associations(env: Env, asset_code: String) -> Vec +``` + +Get bridge associations for an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_pool_associations` + +```rust +pub fn get_pool_associations(env: Env, asset_code: String) -> Vec +``` + +Get liquidity pool associations for an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_compliance_records` + +```rust +pub fn get_compliance_records(env: Env, asset_code: String) -> Vec +``` + +Get compliance records for an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_metadata_versions` + +```rust +pub fn get_metadata_versions(env: Env, asset_code: String) -> Vec +``` + +Get the metadata version history for an asset. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_metadata_at_version` + +```rust +pub fn get_metadata_at_version(env: Env, asset_code: String, version: u32,) -> Option +``` + +Get a specific metadata version. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +**Error codes:** see [`RegistryError` in ERRORS.md](./ERRORS.md#registryerror). + +### BatchQueryContract + +**Source:** [`soroban/src/batch_query.rs`](../src/batch_query.rs) + +**Contract type:** `BatchQueryContract` + +Batch read helpers over registered assets, with test-only JSON serialization support. + +#### `initialize` + +```rust +pub fn initialize(env: Env) -> Result<(), BatchQueryError> +``` + +Initialize the contract + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `batch_query_assets` + +```rust +pub fn batch_query_assets(env: Env, asset_codes: Vec,) -> Result +``` + +Query multiple assets in a single call + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `bq_asset` + +#### `batch_query_bridges` + +```rust +pub fn batch_query_bridges(env: Env, bridge_ids: Vec,) -> Result +``` + +Query multiple bridges in a single call + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `bq_brdg` + +#### `store_asset` + +```rust +pub fn store_asset(env: Env, asset_code: String, name: String, symbol: String, issuer: String, status: String,) -> Result<(), BatchQueryError> +``` + +Store mock asset data for testing (would integrate with real registry in production) + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `store_bridge` + +```rust +pub fn store_bridge(env: Env, bridge_id: String, name: String, source_chain: String, dest_chain: String, status: String,) -> Result<(), BatchQueryError> +``` + +Store mock bridge data for testing (would integrate with real registry in production) + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +**Error codes:** see [`BatchQueryError` in ERRORS.md](./ERRORS.md#batchqueryerror). + +### CircuitBreakerContract + +**Source:** [`soroban/src/circuit_breaker.rs`](../src/circuit_breaker.rs) + +**Contract type:** `CircuitBreakerContract` + +Guardian-gated emergency pause system (global/bridge/asset scope) with a multisig recovery flow. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address, guardian_threshold: u32, recovery_delay_warning: u64, recovery_delay_partial: u64, recovery_delay_full: u64, max_whitelist_size: u32,) +``` + +Sets the admin, guardian approval threshold, per-severity recovery delays, and max whitelist size. + +- **Auth:** `admin` +- **Events:** none + +#### `add_guardian` + +```rust +pub fn add_guardian(env: Env, caller: Address, guardian: Address, role: GuardianRole) +``` + +Registers `guardian` with a `GuardianRole` (Standard/Emergency/Admin). + +- **Auth:** the contract admin +- **Events:** `cb_guardian_added` (guardian, role) + +#### `remove_guardian` + +```rust +pub fn remove_guardian(env: Env, caller: Address, guardian: Address) +``` + +Removes a previously-added guardian. + +- **Auth:** the contract admin +- **Events:** `cb_guardian_removed` (guardian) + +#### `get_guardians` + +```rust +pub fn get_guardians(env: Env) -> Vec +``` + +Returns all registered guardians. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `pause_global` + +```rust +pub fn pause_global(env: Env, caller: Address, reason: String) +``` + +Triggers a full, contract-wide pause. Requires `EmergencyGuardian` (or `AdminGuardian`) permission; the recovery deadline is `recovery_delay_full` seconds out. + +- **Auth:** a guardian with `EmergencyGuardian` role +- **Events:** `cb_pause_triggered` (pause_id, PauseScope::Global, PauseLevel::Full) + +#### `pause_bridge` + +```rust +pub fn pause_bridge(env: Env, caller: Address, bridge_id: String, reason: String) +``` + +Pauses a single bridge (`PauseLevel::Partial`). Requires `StandardGuardian` (or higher) permission; the recovery deadline is `recovery_delay_partial` seconds out. + +- **Auth:** a guardian with `StandardGuardian` role or higher +- **Events:** `cb_pause_triggered` (pause_id, PauseScope::Bridge, PauseLevel::Partial) + +#### `pause_asset` + +```rust +pub fn pause_asset(env: Env, caller: Address, asset_code: String, reason: String) +``` + +Pauses a single asset (`PauseLevel::Warning`). Requires `StandardGuardian` (or higher) permission; the recovery deadline is `recovery_delay_warning` seconds out. + +- **Auth:** a guardian with `StandardGuardian` role or higher +- **Events:** `cb_pause_triggered` (pause_id, PauseScope::Asset, PauseLevel::Warning) + +#### `request_recovery` + +```rust +pub fn request_recovery(env: Env, caller: Address, pause_id: u32) +``` + +Opens a recovery request for an active pause, requiring guardian approvals to reach the configured threshold before it can execute. + +- **Auth:** a guardian with `StandardGuardian` role or higher +- **Events:** `cb_recovery_requested` (pause_id, caller) + +#### `approve_recovery` + +```rust +pub fn approve_recovery(env: Env, caller: Address, pause_id: u32) +``` + +Adds one guardian approval to a pending recovery request. + +- **Auth:** a guardian with `StandardGuardian` role or higher +- **Events:** `cb_guardian_approved` (pause_id, caller, "recovery") + +#### `execute_recovery` + +```rust +pub fn execute_recovery(env: Env, caller: Address, pause_id: u32) +``` + +Executes a recovery request once its approval count meets the threshold, clearing the pause state. + +- **Auth:** a guardian with `StandardGuardian` role or higher +- **Events:** `cb_recovery_executed` (pause_id) + +#### `set_trigger_config` + +```rust +pub fn set_trigger_config(env: Env, caller: Address, alert_type: AlertType, threshold: i128, pause_level: PauseLevel, cooldown_period: u64,) +``` + +Configures the threshold, resulting pause level, and cooldown for an automated `AlertType` trigger. + +- **Auth:** the contract admin +- **Events:** `cb_trigger_updated` (alert_type, threshold, pause_level) + +#### `add_to_address_whitelist` + +```rust +pub fn add_to_address_whitelist(env: Env, caller: Address, address: Address) +``` + +Adds an address to the whitelist (bypasses pauses), up to `max_whitelist_size`. + +- **Auth:** the contract admin +- **Events:** `cb_whitelist_updated` ("address", address, true) + +#### `add_asset_to_whitelist` + +```rust +pub fn add_asset_to_whitelist(env: Env, caller: Address, asset_code: String) +``` + +Adds an asset code to the whitelist (bypasses pauses), up to `max_whitelist_size`. + +- **Auth:** the contract admin +- **Events:** `cb_whitelist_updated` ("asset", asset_code, true) + +#### `get_pause_state` + +```rust +pub fn get_pause_state(env: Env, pause_id: u32) -> PauseState +``` + +Returns the pause record for `pause_id`, or a default `PauseLevel::None` record if it doesn't exist. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_paused` + +```rust +pub fn is_paused(env: Env, scope: PauseScope) -> bool +``` + +Returns whether the given `PauseScope` (Global, a specific bridge, or a specific asset) is currently paused by any active pause record. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_whitelisted_address` + +```rust +pub fn is_whitelisted_address(env: Env, address: Address) -> bool +``` + +Returns whether `address` is on the address whitelist. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `is_whitelisted_asset` + +```rust +pub fn is_whitelisted_asset(env: Env, asset_code: String) -> bool +``` + +Returns whether `asset_code` is on the asset whitelist. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### GovernanceContract + +**Source:** [`soroban/src/governance.rs`](../src/governance.rs) + +**Contract type:** `GovernanceContract` + +Token-weighted (optionally quadratic) proposal/voting/timelock governance, plus a guardian multisig for emergency execution. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address, timelock_delay: u64, voting_period: u64, voting_delay: u64, quorum_bps: u32, pass_threshold_bps: u32, proposal_deposit: i128, use_quadratic: bool, guardian_threshold: u32,) +``` + +Sets the admin and the timelock/voting/quorum/threshold/deposit/guardian configuration (validated for sane ranges). + +- **Auth:** `admin` +- **Events:** `(gov, init)` with `GovernanceEventType::ConfigUpdated` + +#### `set_voting_power` + +```rust +pub fn set_voting_power(env: Env, voter: Address, power: i128) +``` + +Admin registers the voting-power snapshot for a voter (represents token balance). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `add_guardian` + +```rust +pub fn add_guardian(env: Env, guardian: Address) +``` + +Adds an address to the guardian set used for emergency multisig execution. + +- **Auth:** the contract admin +- **Events:** none + +#### `remove_guardian` + +```rust +pub fn remove_guardian(env: Env, guardian: Address) +``` + +Removes an address from the guardian set. + +- **Auth:** the contract admin +- **Events:** none + +#### `delegate_votes` + +```rust +pub fn delegate_votes(env: Env, delegator: Address, delegatee: Address) +``` + +Delegate all of caller's voting power to `delegatee`. + +- **Auth:** `delegator` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `undelegate_votes` + +```rust +pub fn undelegate_votes(env: Env, delegator: Address) +``` + +Remove caller's delegation and reclaim voting power. + +- **Auth:** `delegator` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `create_proposal` + +```rust +pub fn create_proposal(env: Env, proposer: Address, proposal_type: ProposalType, title: String, description: String, target_contract: Address, calldata: String,) -> u32 +``` + +Creates a proposal if `proposer`'s effective voting power meets the configured deposit; voting opens after `voting_delay` and runs for `voting_period`. Returns the new proposal ID. + +- **Auth:** `proposer` +- **Events:** none + +#### `activate_proposal` + +```rust +pub fn activate_proposal(env: Env, proposal_id: u32) +``` + +Transition Pending -> Active once the voting delay has passed. Anyone can call. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `cast_vote` + +```rust +pub fn cast_vote(env: Env, voter: Address, proposal_id: u32, choice: VoteChoice) +``` + +Casts a For/Against/Abstain vote while a proposal is `Active` and within its voting window; each voter may vote once. Applies quadratic weighting if the config enables it. + +- **Auth:** `voter` +- **Events:** none + +#### `finalize_proposal` + +```rust +pub fn finalize_proposal(env: Env, proposal_id: u32) +``` + +Tally votes and mark Passed or Failed. Anyone can call after end_time. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `queue_proposal` + +```rust +pub fn queue_proposal(env: Env, proposal_id: u32) +``` + +Queue a Passed proposal for timelock. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `execute_proposal` + +```rust +pub fn execute_proposal(env: Env, executor: Address, proposal_id: u32) +``` + +Execute a Queued proposal after the timelock expires. + +- **Auth:** `executor` (`.require_auth()` called directly in this function) +- **Events:** `exec`, `gov` + +#### `guardian_approve` + +```rust +pub fn guardian_approve(env: Env, guardian: Address, proposal_id: u32) +``` + +Records a guardian's approval toward the guardian-threshold needed for `guardian_execute`. + +- **Auth:** `guardian`, and must be a registered guardian +- **Events:** none + +#### `guardian_execute` + +```rust +pub fn guardian_execute(env: Env, executor: Address, proposal_id: u32) +``` + +Emergency execution — bypasses timelock, requires guardian threshold approvals. + +- **Auth:** `executor` (`.require_auth()` called directly in this function) +- **Events:** `gexec`, `gov` + +#### `cancel_proposal` + +```rust +pub fn cancel_proposal(env: Env, caller: Address, proposal_id: u32) +``` + +Cancel a proposal. Only the proposer or admin may cancel. + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `update_config` + +```rust +pub fn update_config(env: Env, timelock_delay: u64, voting_period: u64, voting_delay: u64, quorum_bps: u32, pass_threshold_bps: u32, proposal_deposit: i128, use_quadratic: bool, guardian_threshold: u32,) +``` + +Updates the governance configuration (timelock, voting period/delay, quorum, pass threshold, deposit, quadratic flag, guardian threshold) and emits a per-changed-field event. + +- **Auth:** the contract admin +- **Events:** `(gov, cfg_upd)`, plus one of `(gov, quorum)`, `(gov, thresh)`, `(gov, delay)`, `(gov, period)`, `(gov, tlock)` per changed field + +#### `get_proposal` + +```rust +pub fn get_proposal(env: Env, proposal_id: u32) -> Proposal +``` + +Returns a proposal by ID (panics if it doesn't exist). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_vote` + +```rust +pub fn get_vote(env: Env, proposal_id: u32, voter: Address) -> Option +``` + +Returns a voter's vote record for a proposal, if any. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_config` + +```rust +pub fn get_config(env: Env) -> GovernanceConfig +``` + +Returns the current governance configuration. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_voting_power` + +```rust +pub fn get_voting_power(env: Env, voter: Address) -> i128 +``` + +Returns a voter's effective voting power (own power plus anything delegated to them, minus what they've delegated away). + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_delegation` + +```rust +pub fn get_delegation(env: Env, delegator: Address) -> Option
+``` + +Returns the address a voter has delegated to, if any. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `proposal_count` + +```rust +pub fn proposal_count(env: Env) -> u32 +``` + +Returns the total number of proposals created. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_guardian` + +```rust +pub fn is_guardian(env: Env, addr: Address) -> bool +``` + +Returns whether an address is a registered guardian. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_guardian_approvals` + +```rust +pub fn get_guardian_approvals(env: Env, proposal_id: u32) -> u32 +``` + +Returns the number of guardian approvals recorded for a proposal. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `total_supply` + +```rust +pub fn total_supply(env: Env) -> i128 +``` + +Returns the total registered voting-power supply. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### InsurancePoolContract + +**Source:** [`soroban/src/insurance_pool.rs`](../src/insurance_pool.rs) + +**Contract type:** `InsurancePoolContract` + +Staker-funded coverage pools with premium accrual and a claims process. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) +``` + +Initializes insurance pool governance with an admin. + +Security assumptions: +- Admin key controls governance configuration and risk score updates. +- Approval threshold defaults to 1 and should be raised via configure_governance. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `configure_governance` + +```rust +pub fn configure_governance(env: Env, admin: Address, approvers: Vec
, approval_threshold: u32, withdrawal_delay_secs: u64,) +``` + +Sets multi-sig approvers and payout threshold for claim approval. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `create_pool` + +```rust +pub fn create_pool(env: Env, admin: Address, pool_id: String, asset_code: String, premium_rate_bps: u32, risk_score_bps: u32,) +``` + +Creates or updates a coverage pool for an asset. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `set_risk_score` + +```rust +pub fn set_risk_score(env: Env, admin: Address, pool_id: String, risk_score_bps: u32) +``` + +Updates risk score sourced from bridge health metrics (0..10000 bps). + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `stake_liquidity` + +```rust +pub fn stake_liquidity(env: Env, staker: Address, pool_id: String, amount: i128) +``` + +Stakes liquidity into a coverage pool. + +- **Auth:** `staker` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `request_withdrawal` + +```rust +pub fn request_withdrawal(env: Env, staker: Address, pool_id: String, amount: i128) -> u64 +``` + +Requests liquidity withdrawal and places it into a time-locked queue. + +- **Auth:** `staker` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `execute_withdrawal` + +```rust +pub fn execute_withdrawal(env: Env, staker: Address, pool_id: String, request_id: u64) -> i128 +``` + +Executes a matured withdrawal request and removes liquidity from the pool. + +- **Auth:** `staker` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `quote_premium` + +```rust +pub fn quote_premium(env: Env, pool_id: String, coverage_amount: i128, tier: CoverageTier,) -> i128 +``` + +Quotes premium using pool base rate, coverage tier and risk score. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `purchase_coverage` + +```rust +pub fn purchase_coverage(env: Env, buyer: Address, pool_id: String, coverage_amount: i128, tier: CoverageTier, premium_paid: i128,) -> i128 +``` + +Purchases coverage and distributes premium to stakers pro-rata. + +- **Auth:** `buyer` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `submit_claim` + +```rust +pub fn submit_claim(env: Env, claimant: Address, pool_id: String, amount: i128, evidence_hash: String,) -> u64 +``` + +Submits a claim against active coverage in a pool. + +- **Auth:** `claimant` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `verify_claim` + +```rust +pub fn verify_claim(env: Env, admin: Address, claim_id: u64, is_valid: bool, slash_bps: u32) +``` + +Verifies a claim. Invalid claims can be slashed as anti-fraud protection. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `approve_claim` + +```rust +pub fn approve_claim(env: Env, approver: Address, claim_id: u64) +``` + +Approves verified claims via multi-sig approver set. + +- **Auth:** `approver` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `execute_payout` + +```rust +pub fn execute_payout(env: Env, admin: Address, claim_id: u64) +``` + +Executes payout for approved claims and updates historical totals. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `claim_premium` + +```rust +pub fn claim_premium(env: Env, staker: Address, pool_id: String) -> i128 +``` + +Claims accrued premium rewards for a staker. + +- **Auth:** `staker` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `get_pool` + +```rust +pub fn get_pool(env: Env, pool_id: String) -> Option +``` + +Returns a coverage pool's info by ID, if it exists. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_claim` + +```rust +pub fn get_claim(env: Env, claim_id: u64) -> Option +``` + +Returns an insurance claim by ID, if it exists. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_staker_position` + +```rust +pub fn get_staker_position(env: Env, staker: Address, pool_id: String,) -> Option +``` + +Returns a staker's position (staked amount, accrued/claimed premium) in a pool, if any. + +- **Auth:** none (read-only query) +- **Events:** none + +### MultiSigTreasuryContract + +**Source:** [`soroban/src/multisig_treasury.rs`](../src/multisig_treasury.rs) + +**Contract type:** `MultiSigTreasuryContract` + +N-of-M multisig treasury: proposal, signature collection, and execution. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address, config: MultiSigConfig, initial_signers: Vec
, roles: Vec,) +``` + +Initialize the multi-sig treasury contract + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `propose_transaction` + +```rust +pub fn propose_transaction(env: Env, creator: Address, destination: Address, amount: i128, asset: Address, description: String, is_emergency: bool,) -> u64 +``` + +Propose a new transaction + +- **Auth:** `creator` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `sign_transaction` + +```rust +pub fn sign_transaction(env: Env, transaction_id: u64, signer: Address) +``` + +Sign a transaction + +- **Auth:** `signer` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `execute_transaction` + +```rust +pub fn execute_transaction(env: Env, transaction_id: u64, executor: Address) +``` + +Execute a transaction + +- **Auth:** `executor` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `cancel_transaction` + +```rust +pub fn cancel_transaction(env: Env, transaction_id: u64, canceller: Address) +``` + +Cancel a transaction + +- **Auth:** `canceller` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `add_signer` + +```rust +pub fn add_signer(env: Env, new_signer: Address, role: Role) +``` + +Add a new signer (admin only) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `remove_signer` + +```rust +pub fn remove_signer(env: Env, signer: Address) +``` + +Remove a signer (admin only) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `update_threshold` + +```rust +pub fn update_threshold(env: Env, new_threshold: u32) +``` + +Update threshold (admin only, requires multi-sig approval) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `whitelist_asset` + +```rust +pub fn whitelist_asset(env: Env, asset: Address, _whitelister: Address) +``` + +Whitelist an asset (admin only) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `remove_whitelisted_asset` + +```rust +pub fn remove_whitelisted_asset(env: Env, asset: Address) +``` + +Remove asset from whitelist (admin only) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `get_transaction` + +```rust +pub fn get_transaction(env: Env, transaction_id: u64) -> Option +``` + +Get transaction details + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_signer` + +```rust +pub fn get_signer(env: Env, signer_address: Address) -> Option +``` + +Get signer data + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_all_signers` + +```rust +pub fn get_all_signers(env: Env) -> Vec +``` + +Get all active signers + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_config` + +```rust +pub fn get_config(env: Env) -> MultiSigConfig +``` + +Get contract configuration + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_asset_whitelisted` + +```rust +pub fn is_asset_whitelisted(env: Env, asset: Address) -> bool +``` + +Check if asset is whitelisted + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_pending_transactions_count` + +```rust +pub fn get_pending_transactions_count(env: Env) -> u64 +``` + +Get pending transactions count + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### RateLimiterContract + +**Source:** [`soroban/src/rate_limiter.rs`](../src/rate_limiter.rs) + +**Contract type:** `RateLimiterContract` + +Per-user/per-asset rate limiting (daily value and count limits) with an emergency-mode override. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) -> Result<(), RateLimitError> +``` + +Initialize the rate limiter contract with an admin and default limits. + +Sets sensible defaults for global and per-user limits, circuit breaker, +cooldown duration, and emergency mode. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `check_limit` + +```rust +pub fn check_limit(env: Env, user: Address, amount: i128,) -> Result +``` + +Check whether a user can perform a transfer of `amount` without +actually consuming the limit. Returns a [`LimitCheckResult`]. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `consume_limit` + +```rust +pub fn consume_limit(env: Env, user: Address, amount: i128,) -> Result +``` + +Consume rate limit for a transfer of `amount`. Must be called when +the transfer is actually executed. + +Returns `Ok(ConsumeResult::Allowed)` on success. +Returns `Ok(ConsumeResult::Rejected(code))` when a limit is breached; +breach side-effects (cooldown, risk profile) are persisted. +Returns `Err(...)` only for hard errors (emergency mode, circuit +breaker, invalid input, or active cooldown) that do **not** require +persistent side-effects. + +- **Auth:** `user` (`.require_auth()` called directly in this function) +- **Events:** `rl_used` + +#### `update_user_limit` + +```rust +pub fn update_user_limit(env: Env, admin: Address, user: Address, limits: UserLimits,) -> Result<(), RateLimitError> +``` + +Set custom transfer limits for a specific user (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `update_global_limit` + +```rust +pub fn update_global_limit(env: Env, admin: Address, global_limits: GlobalLimits,) -> Result<(), RateLimitError> +``` + +Update global protocol limits (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `update_default_limits` + +```rust +pub fn update_default_limits(env: Env, admin: Address, limits: UserLimits,) -> Result<(), RateLimitError> +``` + +Update the default per-user limits (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `add_to_whitelist` + +```rust +pub fn add_to_whitelist(env: Env, admin: Address, user: Address) -> Result<(), RateLimitError> +``` + +Add a user to the trusted whitelist (admin only). + +Whitelisted users receive limits multiplied by [`WHITELIST_MULTIPLIER`]. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rl_wl` + +#### `remove_from_whitelist` + +```rust +pub fn remove_from_whitelist(env: Env, admin: Address, user: Address,) -> Result<(), RateLimitError> +``` + +Remove a user from the whitelist (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rl_wl` + +#### `is_whitelisted` + +```rust +pub fn is_whitelisted(env: Env, user: Address) -> bool +``` + +Check if a user is whitelisted. Public read. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `update_risk_score` + +```rust +pub fn update_risk_score(env: Env, admin: Address, user: Address, risk_score: u32,) -> Result<(), RateLimitError> +``` + +Update a user's risk score (admin only). + +The risk score (0–10 000 bps) influences the dynamic adjustment +factor which scales the user's effective limits up or down. + +- Score ≥ [`HIGH_RISK_THRESHOLD`] → limits reduced. +- Score ≤ [`LOW_RISK_THRESHOLD`] → limits can be increased. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rl_risk` + +#### `get_user_risk` + +```rust +pub fn get_user_risk(env: Env, user: Address) -> UserRiskProfile +``` + +Get a user's current risk profile. Public read. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `update_anomaly_score` + +```rust +pub fn update_anomaly_score(env: Env, admin: Address, anomaly_score: u32,) -> Result<(), RateLimitError> +``` + +Update the anomaly score (admin only). + +When the score exceeds [`CIRCUIT_BREAKER_THRESHOLD`] the circuit +breaker trips and all transfers are halted until manually reset. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rl_cb` + +#### `reset_circuit_breaker` + +```rust +pub fn reset_circuit_breaker(env: Env, admin: Address) -> Result<(), RateLimitError> +``` + +Reset the circuit breaker (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `get_circuit_breaker` + +```rust +pub fn get_circuit_breaker(env: Env) -> CircuitBreakerState +``` + +Get the current circuit breaker state. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_emergency_mode` + +```rust +pub fn set_emergency_mode(env: Env, admin: Address, enabled: bool,) -> Result<(), RateLimitError> +``` + +Enable emergency mode, halting all transfers (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rl_emrg` + +#### `emergency_reduce_limits` + +```rust +pub fn emergency_reduce_limits(env: Env, admin: Address, reduction_bps: u32,) -> Result<(), RateLimitError> +``` + +Reduce all default limits by a percentage (admin only, emergency use). + +`reduction_bps` is expressed in basis points (e.g. 5 000 = 50 % reduction). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rl_reduc` + +#### `set_cooldown_duration` + +```rust +pub fn set_cooldown_duration(env: Env, admin: Address, duration_secs: u64,) -> Result<(), RateLimitError> +``` + +Set the cooldown duration (admin only). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `clear_cooldown` + +```rust +pub fn clear_cooldown(env: Env, admin: Address, user: Address) -> Result<(), RateLimitError> +``` + +Clear a user's cooldown early (admin only, e.g. after investigation). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `get_user_usage` + +```rust +pub fn get_user_usage(env: Env, user: Address) -> UserUsage +``` + +Get the current usage state for a user. Public read. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_effective_limits` + +```rust +pub fn get_effective_limits(env: Env, user: Address) -> UserLimits +``` + +Get the effective limits for a user after dynamic adjustments. Public read. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_usage_history` + +```rust +pub fn get_usage_history(env: Env, user: Address) -> Vec +``` + +Get a user's usage history (daily records). Public read. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_global_usage` + +```rust +pub fn get_global_usage(env: Env) -> GlobalUsage +``` + +Get the global protocol usage. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_global_limits` + +```rust +pub fn get_global_limits(env: Env) -> GlobalLimits +``` + +Get the global limits. Public read. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `cross_contract_check` + +```rust +pub fn cross_contract_check(env: Env, user: Address, amount: i128, _contract_id: Address,) -> Result +``` + +Cross-contract limit check. Another contract can call this to verify +a user is within limits before executing a transfer. + +This is a read-only check; callers must also call `consume_limit` +after successful execution. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +**Error codes:** see [`RateLimitError` in ERRORS.md](./ERRORS.md#ratelimiterror). + +### ReputationSystemContract + +**Source:** [`soroban/src/reputation_system.rs`](../src/reputation_system.rs) + +**Contract type:** `ReputationSystemContract` + +Tracks a reputation score per submitter/operator based on submission accuracy history. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address, config: Config) +``` + +Initialize the reputation system contract + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `register_entity` + +```rust +pub fn register_entity(env: Env, entity_address: Address, entity_type: EntityType, stake_amount: i128,) +``` + +Register a new entity in the reputation system + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `record_performance` + +```rust +pub fn record_performance(env: Env, entity_address: Address, accuracy: u32, uptime: u32, response_time: u32, disputes_won: u32, disputes_lost: u32, total_operations: u32, successful_operations: u32,) +``` + +Record performance metrics for an entity + +- **Auth:** `entity_address` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `apply_penalty` + +```rust +pub fn apply_penalty(env: Env, entity_address: Address, penalty_amount: i128, _reason: String) +``` + +Apply penalty to an entity (admin only) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `grant_reward` + +```rust +pub fn grant_reward(env: Env, entity_address: Address, reward_amount: i128, _reason: String) +``` + +Grant reward to an entity (admin only) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `apply_time_decay` + +```rust +pub fn apply_time_decay(env: Env) +``` + +Calculate and apply time decay to all entities + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `get_reputation` + +```rust +pub fn get_reputation(env: Env, entity_address: Address) -> Option +``` + +Get reputation data for an entity + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_performance_history` + +```rust +pub fn get_performance_history(env: Env, entity_address: Address) -> Vec +``` + +Get performance history for an entity + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_leaderboard` + +```rust +pub fn get_leaderboard(env: Env, entity_type: EntityType, limit: u32) -> Vec +``` + +Get leaderboard for a specific entity type + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `check_access_control` + +```rust +pub fn check_access_control(env: Env, entity_address: Address, required_threshold: u32,) -> bool +``` + +Check if entity meets minimum reputation threshold for access control + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `update_config` + +```rust +pub fn update_config(env: Env, new_config: Config) +``` + +Update contract configuration (admin only) + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `get_config` + +```rust +pub fn get_config(env: Env) -> Config +``` + +Get current contract configuration + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### SidecarStateContract + +**Source:** [`soroban/src/sidecar_state.rs`](../src/sidecar_state.rs) + +**Contract type:** `SidecarStateContract` + +Generic key/value entity store with a consistency-check hook, used by off-chain sidecars. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) -> Result<(), SidecarError> +``` + +Initialize the contract with an admin address + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `store_sidecar` + +```rust +pub fn store_sidecar(env: Env, caller: Address, entry_id: String, entity_ref: String, entity_hash: String, data: String, metadata: String,) -> Result<(), SidecarError> +``` + +Store a new sidecar entry linked to an on-chain entity + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `sc_store` + +#### `update_sidecar` + +```rust +pub fn update_sidecar(env: Env, caller: Address, entry_id: String, new_entity_hash: String, new_data: String, new_metadata: String,) -> Result<(), SidecarError> +``` + +Update an existing sidecar entry + +- **Auth:** `caller` (`.require_auth()` called directly in this function) +- **Events:** `sc_upd` + +#### `check_consistency` + +```rust +pub fn check_consistency(env: Env, entry_id: String, current_entity_hash: String,) -> Result +``` + +Perform consistency check on a sidecar entry + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `query_by_entity` + +```rust +pub fn query_by_entity(env: Env, entity_ref: String) -> Vec +``` + +Query all sidecar entries for an entity + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `query_by_id` + +```rust +pub fn query_by_id(env: Env, entry_id: String) -> Result +``` + +Query a specific sidecar entry by ID + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_all_entities` + +```rust +pub fn get_all_entities(env: Env) -> Vec +``` + +Get all entities that have sidecar entries + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +**Error codes:** see [`SidecarError` in ERRORS.md](./ERRORS.md#sidecarerror). + +## Part 5 — Unreferenced source files (not compiled by any build target) + +**These files are not reachable from any `mod` declaration or `#[path]` include anywhere in the workspace** — not `soroban/src/lib.rs`, not any test binary, not the other crates. `cargo build`/`cargo test` never compiles them, so their inline test suites never run, and nothing here is verified by CI. They're documented below for completeness (the code is real, self-contained, and reads as production-quality), but verify against the source directly before relying on them — this reference is derived from source that a `cargo build` never actually type-checks. + +### AlertSystemContract + +**Source:** [`soroban/src/alert_system.rs`](../src/alert_system.rs) + +**Contract type:** `AlertSystemContract` + +Condition-based alerting: users register rules over metric thresholds and evaluate them against submitted metric values. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address) +``` + +Sets the contract admin and zeroes the rule and alert counters. + +- **Auth:** `admin` +- **Events:** none + +#### `register_rule` + +```rust +pub fn register_rule(env: Env, owner: Address, name: String, asset_code: String, conditions: Vec, condition_op: ConditionOp, priority: AlertPriority, cooldown_seconds: u64,) -> u64 +``` + +Registers a new alert rule for `owner` on `asset_code`, combining one or more `conditions` with `condition_op` (AND/OR). Returns the new rule ID. + +- **Auth:** `owner` +- **Events:** none + +#### `update_rule` + +```rust +pub fn update_rule(env: Env, rule_id: u64, name: String, conditions: Vec, condition_op: ConditionOp, priority: AlertPriority, cooldown_seconds: u64,) +``` + +Replaces the name, conditions, priority, and cooldown of an existing rule. + +- **Auth:** the rule's `owner` +- **Events:** none + +#### `set_rule_active` + +```rust +pub fn set_rule_active(env: Env, rule_id: u64, is_active: bool) +``` + +Enables or disables a rule. + +- **Auth:** the rule's `owner`, or the contract admin +- **Events:** none + +#### `evaluate_asset` + +```rust +pub fn evaluate_asset(env: Env, asset_code: String, metrics: Vec,) -> Vec +``` + +Evaluates every active rule for `asset_code` against the supplied `metrics`, records and returns any newly triggered alerts, and respects each rule's cooldown window. + +- **Auth:** admin +- **Events:** none + +#### `batch_evaluate` + +```rust +pub fn batch_evaluate(env: Env, asset_metrics: Vec<(String, Vec)>,) -> Vec +``` + +Runs the same evaluation as `evaluate_asset` for multiple `(asset_code, metrics)` pairs in a single call. + +- **Auth:** admin +- **Events:** none + +#### `get_rule` + +```rust +pub fn get_rule(env: Env, rule_id: u64) -> Option +``` + +Returns a stored alert rule by ID, if any. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_user_rules` + +```rust +pub fn get_user_rules(env: Env, owner: Address) -> Vec +``` + +Returns the rule IDs owned by `owner`. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_asset_alerts` + +```rust +pub fn get_asset_alerts(env: Env, asset_code: String) -> Vec +``` + +Returns the triggered-alert history for `asset_code` (most recent `MAX_EVENTS_PER_ASSET` = 100). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_rule_count` + +```rust +pub fn get_rule_count(env: Env) -> u64 +``` + +Returns the number of rules ever registered. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_alert_count` + +```rust +pub fn get_alert_count(env: Env) -> u64 +``` + +Returns the number of alerts ever triggered. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### asset_ranking + +**Source:** [`soroban/src/asset_ranking.rs`](../src/asset_ranking.rs) + +Ranks assets by a configurable scoring formula. + +#### `get_ranking_weights` + +```rust +pub fn get_ranking_weights(env: &Env) -> RankingWeights +``` + +Load ranking weights, returning defaults if none configured. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `set_ranking_weights` + +```rust +pub fn set_ranking_weights(env: &Env, caller: &Address, health_weight: u32, volume_weight: u32, liquidity_weight: u32,) +``` + +Set ranking weights. Admin only. + +Weights must each be 0-100 and sum to exactly 100. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rnk_wt` + +#### `compute_asset_rank` + +```rust +pub fn compute_asset_rank(env: &Env, asset_code: String, health_score: u32, price_stability_score: u32, liquidity_score: u32,) -> AssetRank +``` + +Compute the ranking score for a single asset. + +The score is calculated as: +score = (health_score * health_weight ++ price_stability_score * volume_weight ++ liquidity_score * liquidity_weight) / 100 + +Each component score is 0-100, so the result is also 0-100. + +Read-only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `compute_all_rankings` + +```rust +pub fn compute_all_rankings(env: &Env, assets: Vec,) -> Vec +``` + +Compute rankings for a batch of assets. + +Accepts pre-collected scores for each asset, computes weighted scores, +sorts descending by score, and assigns rank numbers starting from 1. +Assets with equal scores are ordered alphabetically by asset code. + +Read-only. Deterministic: same inputs always produce the same output. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### bridge_asset_metadata + +**Source:** [`soroban/src/bridge_asset_metadata.rs`](../src/bridge_asset_metadata.rs) + +Stores descriptive metadata for bridged assets. + +#### `get_metadata` + +```rust +pub fn get_metadata(env: Env, asset_code: String) -> Option +``` + +Read metadata for an asset. Returns `None` when no metadata has been set. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_metadata_history` + +```rust +pub fn get_metadata_history(env: Env, asset_code: String) -> Vec +``` + +Read metadata change history for an asset. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `update_metadata` + +```rust +pub fn update_metadata(env: Env, caller: Address, asset_code: String, name: String, symbol: String, description: String, url: String, change_reason: String,) -> BridgeAssetMetadata +``` + +Update asset metadata without recreating the asset registration entry. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** `meta_up` + +### BridgeReserveVerifier + +**Source:** [`soroban/src/bridge_reserve_verifier.rs`](../src/bridge_reserve_verifier.rs) + +**Contract type:** `BridgeReserveVerifier` + +Merkle-proof-based reserve verification for bridge operators, with a stake/slash/challenge mechanism. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address, challenge_period_ledgers: u32, slash_amount: i128, min_stake: i128,) +``` + +Sets the admin and the challenge period, slash amount, and minimum stake config. + +- **Auth:** `admin` +- **Events:** none + +#### `update_config` + +```rust +pub fn update_config(env: Env, challenge_period_ledgers: u32, slash_amount: i128, min_stake: i128,) +``` + +Updates the challenge period, slash amount, and minimum stake. + +- **Auth:** the contract admin +- **Events:** `(CONFIG, UPDATE)` with the new config + +#### `register_bridge` + +```rust +pub fn register_bridge(env: Env, bridge_id: String, operator: Address, initial_stake: i128,) +``` + +Registers `operator` for `bridge_id` with `initial_stake`, which must meet `min_stake`. + +- **Auth:** the contract admin +- **Events:** `(BRIDGE, REG)` with the bridge ID + +#### `commit_reserves` + +```rust +pub fn commit_reserves(env: Env, bridge_id: String, merkle_root: BytesN<32>, total_reserves: i128,) -> u64 +``` + +Returns the monotonic sequence number assigned to this commitment. + +- **Auth:** `operator` (`.require_auth()` called directly in this function) +- **Events:** `COMMIT`, `RESERVE` + +#### `verify_proof` + +```rust +pub fn verify_proof(env: Env, bridge_id: String, sequence: u64, proof: MerkleProof,) -> bool +``` + +Verifies a Merkle inclusion proof. Auto-advances status to Verified +once the challenge window has passed. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `PROOF`, `VERIFY` + +#### `batch_verify_proofs` + +```rust +pub fn batch_verify_proofs(env: Env, bridge_id: String, sequence: u64, proofs: Vec,) -> Vec +``` + +Verifies multiple proofs against the same commitment in one call. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** `BATCH`, `PROOF` + +#### `challenge_commitment` + +```rust +pub fn challenge_commitment(env: Env, bridge_id: String, sequence: u64, challenger: Address, disputed_proof: MerkleProof,) +``` + +Raises a challenge against a pending commitment within its challenge window. +The challenger must supply a proof that fails verification as evidence. + +- **Auth:** `challenger` (`.require_auth()` called directly in this function) +- **Events:** `CHAL`, `COMMIT` + +#### `resolve_challenge` + +```rust +pub fn resolve_challenge(env: Env, bridge_id: String, sequence: u64, commitment_valid: bool,) +``` + +Resolves a challenged commitment (admin only). +`commitment_valid = false` triggers a slash of the operator. + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** `COMMIT`, `RESOLVE` + +#### `slash_operator` + +```rust +pub fn slash_operator(env: Env, bridge_id: String) +``` + +Slashes the operator for `bridge_id` by the configured `slash_amount`, deactivating it if the remaining stake falls below `min_stake`. + +- **Auth:** the contract admin +- **Events:** `(OP, SLASH)` with (bridge_id, slash_count, remaining stake) + +#### `get_commitment` + +```rust +pub fn get_commitment(env: Env, bridge_id: String, sequence: u64,) -> Option +``` + +Returns a reserve commitment by bridge and sequence number, if any. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_operator` + +```rust +pub fn get_operator(env: Env, bridge_id: String) -> Option +``` + +Returns the registered operator record for `bridge_id`, if any. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_config` + +```rust +pub fn get_config(env: Env) -> Config +``` + +Returns the current contract configuration. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_registered_bridges` + +```rust +pub fn get_registered_bridges(env: Env) -> Vec +``` + +Returns every registered bridge ID. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_latest_sequence` + +```rust +pub fn get_latest_sequence(env: Env, bridge_id: String) -> u64 +``` + +Returns the latest commitment sequence number for `bridge_id` (0 if none). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +**Error codes:** see [`Error` in ERRORS.md](./ERRORS.md#error). + +### event_query + +**Source:** [`soroban/src/event_query.rs`](../src/event_query.rs) + +Read helpers for querying previously emitted contract events. + +#### `append_event` + +```rust +pub fn append_event(env: &Env, event_type: String, actor: Address, subject: String, value: i128,) +``` + +Append one event to the replay log (internal). + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** see description above + +#### `query_events` + +```rust +pub fn query_events(env: Env, filter: ContractEventFilter) -> ContractEventQueryResult +``` + +Query recent contract events with optional type and asset filters. + +Results are ordered by ascending `ordering_key` (oldest first within the page). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** see description above + +#### `get_replay_page` + +```rust +pub fn get_replay_page(env: Env, from_ordering_key: u64, limit: u32) -> EventReplayPage +``` + +Replay page helper (backward compatible with issue #296). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `log_size` + +```rust +pub fn log_size(env: &Env) -> u32 +``` + +Total number of entries in the replay log. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### FeeDistributionContract + +**Source:** [`soroban/src/fee_distribution.rs`](../src/fee_distribution.rs) + +**Contract type:** `FeeDistributionContract` + +Splits collected fees among configured recipients according to weighted shares. + +#### `initialize` + +```rust +pub fn initialize(env: Env, admin: Address, treasury: Address, staking_token: Address, ratios: DistributionRatios,) +``` + +Initialise the fee distribution contract. + +Must be called exactly once. The admin is the only address allowed to +invoke privileged operations (ratio updates, token registration, vesting +creation, emergency controls, etc.). + +# Parameters +- `admin` – privileged administrator address. +- `treasury` – receives the treasury slice of every distribution. +- `staking_token` – the single token users stake to earn fee rewards. +- `ratios` – initial allocation ratios (must sum to 10 000). + +- **Auth:** `admin` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `update_ratios` + +```rust +pub fn update_ratios(env: Env, ratios: DistributionRatios) +``` + +Update distribution ratios. The three values must sum to 10 000. +Admin only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `add_fee_token` + +```rust +pub fn add_fee_token(env: Env, token: Address) +``` + +Register a token as an accepted fee currency. Creates an empty +`FeePool` if one does not already exist. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `add_collector` + +```rust +pub fn add_collector(env: Env, collector: Address) +``` + +Authorise an address to call `collect_fees`. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `remove_collector` + +```rust +pub fn remove_collector(env: Env, collector: Address) +``` + +Remove a fee collector authorisation. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `set_distribution_interval` + +```rust +pub fn set_distribution_interval(env: Env, interval_secs: u64) +``` + +Set the minimum interval (seconds) between automatic distributions. +Pass `0` to disable automatic triggering. Admin only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `update_treasury` + +```rust +pub fn update_treasury(env: Env, new_treasury: Address) +``` + +Update the treasury address. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `collect_fees` + +```rust +pub fn collect_fees(env: Env, collector: Address, token: Address, amount: i128) +``` + +Collect fees from an authorised protocol service. + +Transfers `amount` of `token` from `collector` into this contract. +The collector must be either the admin or a registered fee collector. +Triggers an automatic distribution if the configured interval has elapsed. + +# Panics +- `amount` ≤ 0 +- `collector` is not authorised +- `token` is not a registered fee token +- contract is in emergency mode + +- **Auth:** `collector` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `distribute_fees` + +```rust +pub fn distribute_fees(env: Env, tokens: Vec
) +``` + +Distribute pending fees across all (or a specified subset of) tokens. + +Permissionless — any address may call this. Pass an empty `Vec` to +process every registered fee token. + +Each distribution: +- Updates `acc_fee_per_share` for stakers. +- Accrues governance allocation to `governance_pool`. +- Transfers the treasury slice directly to the treasury address. +- Writes an immutable `DistributionRecord` for historical tracking. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `stake_for_fees` + +```rust +pub fn stake_for_fees(env: Env, staker: Address, amount: i128, enable_compound: bool,) +``` + +Stake tokens to participate in fee distributions. + +Harvests pending rewards for the staker before adjusting their stake +weight so that the fair-share invariant is preserved. New stakers do +not receive fees distributed before this call. + +# Parameters +- `staker` – address staking; must sign. +- `amount` – units of the registered staking token to lock. +- `enable_compound` – if `true`, future claims re-stake rather than +transfer out. + +- **Auth:** `staker` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `unstake` + +```rust +pub fn unstake(env: Env, staker: Address, amount: i128) +``` + +Unstake tokens and harvest pending rewards. + +Returns `amount` of the staking token to `staker` after harvesting any +outstanding fee rewards. + +# Panics +- `amount` ≤ 0 or exceeds the staker's current balance. + +- **Auth:** `staker` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `claim_fees` + +```rust +pub fn claim_fees(env: Env, staker: Address, token: Address) +``` + +Claim accumulated fee rewards for a specific token. + +When compound mode is enabled the reward is added back to the staker's +stake weight (increasing their share of future distributions) rather +than transferred out. + +# Panics +- Nothing to claim. +- Contract is in emergency mode. + +- **Auth:** `staker` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `compound_rewards` + +```rust +pub fn compound_rewards(env: Env, staker: Address, token: Address) +``` + +Compound rewards for a staker without requiring their signature. + +The staker must have compound mode enabled. This allows keeper bots or +automation scripts to trigger compounding on behalf of opted-in stakers. + +# Panics +- Staker has not enabled compound mode. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `create_vesting_schedule` + +```rust +pub fn create_vesting_schedule(env: Env, beneficiary: Address, token: Address, amount: i128, duration_secs: u64, cliff_secs: u64,) +``` + +Create a governance-allocation vesting schedule. + +Draws `amount` from the specified token's `governance_pool` bucket and +locks it into a new linear vesting schedule. Admin only. + +# Parameters +- `beneficiary` – address that will claim the vested tokens. +- `token` – fee token being vested. +- `amount` – tokens to vest. +- `duration_secs` – total vesting window in seconds. +- `cliff_secs` – seconds that must pass before any tokens vest. + +# Panics +- `amount` > governance pool balance. +- `cliff_secs` > `duration_secs`. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `claim_vested` + +```rust +pub fn claim_vested(env: Env, vesting_id: u32) +``` + +Claim vested tokens from a vesting schedule. + +Releases all tokens vested since the last claim, subject to the cliff. +Any address may initiate the call, but the beneficiary address is the +one that must sign (via `require_auth`). + +# Panics +- Cliff period has not yet elapsed. +- Nothing has vested since the last claim. + +- **Auth:** `beneficiary` (`.require_auth()` called directly in this function) +- **Events:** none + +#### `set_emergency` + +```rust +pub fn set_emergency(env: Env, active: bool) +``` + +Activate or deactivate emergency mode. Admin only. + +While active, `collect_fees`, `distribute_fees`, `stake_for_fees`, and +`claim_fees` are all blocked so the admin can drain funds safely. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `emergency_withdraw` + +```rust +pub fn emergency_withdraw(env: Env, token: Address, recipient: Address, amount: i128) +``` + +Emergency withdrawal of any token to a specified recipient. + +Emergency mode must be active. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `get_ratios` + +```rust +pub fn get_ratios(env: Env) -> DistributionRatios +``` + +Return the current distribution ratios. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_fee_pool` + +```rust +pub fn get_fee_pool(env: Env, token: Address) -> Option +``` + +Return the fee pool state for `token`, or `None` if not registered. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_total_staked` + +```rust +pub fn get_total_staked(env: Env) -> i128 +``` + +Return the total staked units across all stakers. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_staker_amount` + +```rust +pub fn get_staker_amount(env: Env, staker: Address) -> i128 +``` + +Return the staked balance for `staker`. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_pending_rewards` + +```rust +pub fn get_pending_rewards(env: Env, staker: Address, token: Address) -> i128 +``` + +Return the harvestable reward balance for `staker` on `token`. + +Includes both previously harvested (stored) and live (unaccounted) +rewards based on the current `acc_fee_per_share`. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_distribution_record` + +```rust +pub fn get_distribution_record(env: Env, id: u32) -> Option +``` + +Return a distribution record by ID, or `None`. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_distribution_count` + +```rust +pub fn get_distribution_count(env: Env) -> u32 +``` + +Return the total number of distribution records ever written. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_vesting_schedule` + +```rust +pub fn get_vesting_schedule(env: Env, id: u32) -> Option +``` + +Return a vesting schedule by ID, or `None`. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_vesting_count` + +```rust +pub fn get_vesting_count(env: Env) -> u32 +``` + +Return the total number of vesting schedules ever created. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_supported_tokens` + +```rust +pub fn get_supported_tokens(env: Env) -> Vec
+``` + +Return all registered fee token addresses. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `is_emergency` + +```rust +pub fn is_emergency(env: Env) -> bool +``` + +Return whether emergency mode is currently active. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_admin` + +```rust +pub fn get_admin(env: Env) -> Address +``` + +Return the admin address. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_treasury` + +```rust +pub fn get_treasury(env: Env) -> Address +``` + +Return the treasury address. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### rollup_flush + +**Source:** [`soroban/src/rollup_flush.rs`](../src/rollup_flush.rs) + +Batches and flushes rolled-up state to reduce per-submission storage writes. + +#### `buffer_rollup_value` + +```rust +pub fn buffer_rollup_value(env: &Env, caller: &Address, asset_code: String, health_score: u32, price: i128,) +``` + +Add a data point to the rollup buffer for a given asset. + +Each call accumulates the health_score and price values. The flush +operation later computes averages from the accumulated totals. + +Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** none + +#### `flush_rollup` + +```rust +pub fn flush_rollup(env: &Env, caller: &Address) -> Vec +``` + +Flush all buffered rollup values, computing averages and storing results. + +Each buffered asset gets its average health score and price written to +a `FlushResult` record. The buffer is cleared after a successful flush. + +Returns the list of flush results. Admin only. + +If the buffer is empty, returns an empty list (no-op). + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `rlp_fl` + +#### `get_rollup_buffer` + +```rust +pub fn get_rollup_buffer(env: &Env) -> Vec +``` + +Return the current contents of the rollup buffer without flushing. + +Read-only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_buffered_asset_codes` + +```rust +pub fn get_buffered_asset_codes(env: &Env) -> Vec +``` + +Return the list of asset codes currently in the buffer. + +Read-only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_flush_result` + +```rust +pub fn get_flush_result(env: &Env, asset_code: String) -> Option +``` + +Return the last flush result for a specific asset. + +Read-only. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### source_priority + +**Source:** [`soroban/src/source_priority.rs`](../src/source_priority.rs) + +Assigns a priority ranking to data sources, used to pick the best candidate among several. + +#### `set_source_priority` + +```rust +pub fn set_source_priority(env: &Env, caller: &Address, source: &Address, priority: u32) +``` + +Set or update the priority level for a source address. + +Lower values indicate higher priority. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `src_pri` + +#### `get_source_priority` + +```rust +pub fn get_source_priority(env: &Env, source: &Address) -> u32 +``` + +Return the priority for a given source. + +Sources without an explicit priority return `u32::MAX`. + +- **Auth:** none (read-only query) +- **Events:** none + +#### `get_all_source_priorities` + +```rust +pub fn get_all_source_priorities(env: &Env) -> Vec +``` + +Return all configured source priority entries. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `resolve_priority` + +```rust +pub fn resolve_priority(env: &Env, sources: Vec
) -> Address +``` + +Resolve which source wins among a list of conflicting sources. + +Returns the source with the lowest priority value. When two sources share +the same priority, the one whose address is lexicographically smaller (by +raw `to_string()` representation) wins, guaranteeing deterministic output. + +Panics if the input list is empty. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +### submission_pause + +**Source:** [`soroban/src/submission_pause.rs`](../src/submission_pause.rs) + +Admin-controlled pause switch for data submissions. + +#### `is_paused` + +```rust +pub fn is_paused(env: &Env) -> bool +``` + +Returns `true` when contract-wide data submissions are paused. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `assert_not_paused` + +```rust +pub fn assert_not_paused(env: &Env) +``` + +Panics when submissions are globally paused. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `get_state` + +```rust +pub fn get_state(env: &Env) -> SubmissionPauseState +``` + +Read the current submission pause state. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `pause` + +```rust +pub fn pause(env: Env, caller: Address, reason: String) +``` + +Pause all mutating data submissions. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `sub_pau` + +#### `resume` + +```rust +pub fn resume(env: Env, caller: Address) +``` + +Resume data submissions. Admin only. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `sub_res` + +#### `get_history` + +```rust +pub fn get_history(env: Env) -> Vec +``` + +Return pause/unpause history (most recent last). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +### submission_replay + +**Source:** [`soroban/src/submission_replay.rs`](../src/submission_replay.rs) + +Records a replay log of submissions for audit purposes. + +#### `record_health_submission` + +```rust +pub fn record_health_submission(env: &Env, caller: &Address, asset_code: String, health_score: u32, liquidity_score: u32, price_stability_score: u32, bridge_uptime_score: u32,) +``` + +Record a health submission to the replay log. + +Called internally by the contract when a health submission is made. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `record_price_submission` + +```rust +pub fn record_price_submission(env: &Env, caller: &Address, asset_code: String, price: i128, source: String,) +``` + +Record a price submission to the replay log. + +Called internally by the contract when a price submission is made. + +- **Auth:** _not statically determined by this doc generator — check the source_ +- **Events:** none + +#### `preview_replay` + +```rust +pub fn preview_replay(env: &Env, from_timestamp: u64, to_timestamp: u64,) -> Vec +``` + +Preview submissions in a time range without applying them. + +Read-only. Returns entries ordered by `ordering_key` (ascending). + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none + +#### `execute_replay` + +```rust +pub fn execute_replay(env: &Env, caller: &Address, from_timestamp: u64, to_timestamp: u64,) -> ReplaySummary +``` + +Execute a replay of submissions in the given time range. + +Replays entries in `ordering_key` order (which preserves the original +submission sequence). Bounded by `MAX_REPLAY_BATCH` entries per call. + +Admin only. Returns a summary of the replay operation. + +- **Auth:** gated by a role/permission check — see description above for exactly who +- **Events:** `replay` + +#### `replay_log_size` + +```rust +pub fn replay_log_size(env: &Env) -> u32 +``` + +Return the total number of entries in the replay log. + +- **Auth:** none (no `Address` parameter present to authenticate) +- **Events:** none diff --git a/soroban/docs/ERRORS.md b/soroban/docs/ERRORS.md new file mode 100644 index 0000000..04855f0 --- /dev/null +++ b/soroban/docs/ERRORS.md @@ -0,0 +1,209 @@ +# Error Code Reference + +Every `#[contracterror]` numeric error code defined under `soroban/src/`, grouped by the contract that defines it. Soroban scopes error codes to the specific `#[contracterror]` enum a function returns — two contracts using the value `3` for different things is not a collision in the way it would be in a single flat global error space, since a caller always decodes the code against the ABI of the specific contract/function they invoked. This table exists so a human cross-referencing a raw numeric code (e.g. from an indexer or a transaction result, without the originating contract's ABI in hand) has one place to look, and so a reviewer can confirm each contract's own codes are internally unique and contiguous. + +## Contents + +- [`RelayError`](#relayerror) — CrossChainRelayContract (Part 3 — Relay contract (test-binary only)) +- [`RecoveryError`](#recoveryerror) — EmergencyFundRecovery (Part 1 — Deployed contract (production wasm)) +- [`DeprecationError`](#deprecationerror) — AssetDeprecationContract (Part 4 — Standalone experimental contract (cfg(test) only)) +- [`RegistryError`](#registryerror) — AssetRegistryContract (Part 4 — Standalone experimental contract (cfg(test) only)) +- [`BatchQueryError`](#batchqueryerror) — BatchQueryContract (Part 4 — Standalone experimental contract (cfg(test) only)) +- [`RateLimitError`](#ratelimiterror) — RateLimiterContract (Part 4 — Standalone experimental contract (cfg(test) only)) +- [`SidecarError`](#sidecarerror) — SidecarStateContract (Part 4 — Standalone experimental contract (cfg(test) only)) +- [`Error`](#error) — BridgeReserveVerifier (Part 5 — Unreferenced file (not compiled anywhere)) + +## `RelayError` + +**Contract:** CrossChainRelayContract — Part 3 — Relay contract (test-binary only) +**Source:** [`soroban/src/relay/errors.rs`](../src/relay/errors.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `AlreadyInitialized` | The contract has already been initialised. | +| 2 | `NotInitialized` | The contract has not been initialised. | +| 3 | `Unauthorized` | Caller is not the contract administrator. | +| 4 | `InvalidNonce` | The nonce supplied does not match the expected value. | +| 5 | `MessageExpired` | The message has expired. | +| 6 | `MessageNotFound` | The message was not found. | +| 7 | `InvalidMessageStatus` | The message is in an invalid state for this operation. | +| 8 | `OperatorNotActive` | The relay operator is not registered or is inactive. | +| 9 | `OperatorAlreadyRegistered` | The relay operator is already registered. | +| 10 | `InvalidSignature` | Signature verification failed. | +| 11 | `InvalidStateProof` | State proof verification failed. | +| 12 | `ChainNotEnabled` | The target chain is not enabled. | +| 13 | `ChainConfigNotFound` | The target chain configuration was not found. | +| 14 | `InsufficientFee` | Insufficient fee attached to the message. | +| 15 | `PayloadTooLarge` | The message payload exceeds the maximum allowed size. | +| 16 | `EmptyBatch` | The batch is empty. | +| 17 | `InvalidTtl` | The TTL value is invalid. | + +## `RecoveryError` + +**Contract:** EmergencyFundRecovery — Part 1 — Deployed contract (production wasm) +**Source:** [`soroban/src/emergency_fund_recovery.rs`](../src/emergency_fund_recovery.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `NotAuthorized` | _(no doc comment on the variant; name reads as: not authorized)_ | +| 2 | `InvalidAmount` | _(no doc comment on the variant; name reads as: invalid amount)_ | +| 3 | `InvalidDestination` | _(no doc comment on the variant; name reads as: invalid destination)_ | +| 4 | `RecoveryNotFound` | _(no doc comment on the variant; name reads as: recovery not found)_ | +| 5 | `AlreadyApproved` | _(no doc comment on the variant; name reads as: already approved)_ | +| 6 | `InsufficientApprovals` | _(no doc comment on the variant; name reads as: insufficient approvals)_ | +| 7 | `TimelockNotElapsed` | _(no doc comment on the variant; name reads as: timelock not elapsed)_ | +| 8 | `RecoveryAlreadyExecuted` | _(no doc comment on the variant; name reads as: recovery already executed)_ | +| 9 | `RecoveryAlreadyCancelled` | _(no doc comment on the variant; name reads as: recovery already cancelled)_ | +| 10 | `InvalidRecoveryState` | _(no doc comment on the variant; name reads as: invalid recovery state)_ | +| 11 | `EmergencyModeDisabled` | _(no doc comment on the variant; name reads as: emergency mode disabled)_ | +| 12 | `NoFundsToRecover` | _(no doc comment on the variant; name reads as: no funds to recover)_ | +| 13 | `TokenTransferFailed` | _(no doc comment on the variant; name reads as: token transfer failed)_ | +| 14 | `InvalidTimelock` | _(no doc comment on the variant; name reads as: invalid timelock)_ | + +## `DeprecationError` + +**Contract:** AssetDeprecationContract — Part 4 — Standalone experimental contract (cfg(test) only) +**Source:** [`soroban/src/asset_deprecation.rs`](../src/asset_deprecation.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `NotAuthorized` | _(no doc comment on the variant; name reads as: not authorized)_ | +| 2 | `AlreadyInitialized` | _(no doc comment on the variant; name reads as: already initialized)_ | +| 3 | `AssetNotFound` | _(no doc comment on the variant; name reads as: asset not found)_ | +| 4 | `AlreadyDeprecated` | _(no doc comment on the variant; name reads as: already deprecated)_ | +| 5 | `ReplacementNotFound` | _(no doc comment on the variant; name reads as: replacement not found)_ | +| 6 | `MigrationPeriodExpired` | _(no doc comment on the variant; name reads as: migration period expired)_ | +| 7 | `WriteOperationBlocked` | _(no doc comment on the variant; name reads as: write operation blocked)_ | + +## `RegistryError` + +**Contract:** AssetRegistryContract — Part 4 — Standalone experimental contract (cfg(test) only) +**Source:** [`soroban/src/asset_registry.rs`](../src/asset_registry.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `NotAuthorized` | _(no doc comment on the variant; name reads as: not authorized)_ | +| 2 | `AlreadyInitialized` | _(no doc comment on the variant; name reads as: already initialized)_ | +| 3 | `AssetAlreadyRegistered` | _(no doc comment on the variant; name reads as: asset already registered)_ | +| 4 | `AssetNotFound` | _(no doc comment on the variant; name reads as: asset not found)_ | +| 5 | `InvalidAssetData` | _(no doc comment on the variant; name reads as: invalid asset data)_ | +| 6 | `InvalidRiskRating` | _(no doc comment on the variant; name reads as: invalid risk rating)_ | +| 7 | `InvalidLifecycleTransition` | _(no doc comment on the variant; name reads as: invalid lifecycle transition)_ | +| 8 | `MaxChainsExceeded` | _(no doc comment on the variant; name reads as: max chains exceeded)_ | +| 9 | `MaxOracleFeedsExceeded` | _(no doc comment on the variant; name reads as: max oracle feeds exceeded)_ | +| 10 | `MaxBridgesExceeded` | _(no doc comment on the variant; name reads as: max bridges exceeded)_ | +| 11 | `MaxPoolsExceeded` | _(no doc comment on the variant; name reads as: max pools exceeded)_ | +| 12 | `DuplicateChainLink` | _(no doc comment on the variant; name reads as: duplicate chain link)_ | +| 13 | `DuplicateOracleFeed` | _(no doc comment on the variant; name reads as: duplicate oracle feed)_ | +| 14 | `DuplicateBridge` | _(no doc comment on the variant; name reads as: duplicate bridge)_ | +| 15 | `DuplicatePool` | _(no doc comment on the variant; name reads as: duplicate pool)_ | +| 16 | `AssetPaused` | _(no doc comment on the variant; name reads as: asset paused)_ | +| 17 | `AssetDeprecated` | _(no doc comment on the variant; name reads as: asset deprecated)_ | +| 18 | `AssetNotWhitelisted` | _(no doc comment on the variant; name reads as: asset not whitelisted)_ | +| 19 | `AssetAlreadyWhitelisted` | _(no doc comment on the variant; name reads as: asset already whitelisted)_ | +| 20 | `AssetFrozen` | _(no doc comment on the variant; name reads as: asset frozen)_ | +| 21 | `AssetAlreadyActive` | Attempted to deactivate an asset that is already in a non-restorable state or already active. Deactivation is only valid for Active assets. Check the asset's current status. | +| 22 | `AssetNotDeactivated` | Attempted to restore an asset that is not in a Deactivated state. Only deactivated assets can be restored. Use the asset's current status to determine next actions. | + +## `BatchQueryError` + +**Contract:** BatchQueryContract — Part 4 — Standalone experimental contract (cfg(test) only) +**Source:** [`soroban/src/batch_query.rs`](../src/batch_query.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `AlreadyInitialized` | _(no doc comment on the variant; name reads as: already initialized)_ | +| 2 | `BatchSizeExceeded` | _(no doc comment on the variant; name reads as: batch size exceeded)_ | +| 3 | `EmptyBatch` | _(no doc comment on the variant; name reads as: empty batch)_ | +| 4 | `InvalidQuery` | _(no doc comment on the variant; name reads as: invalid query)_ | + +## `RateLimitError` + +**Contract:** RateLimiterContract — Part 4 — Standalone experimental contract (cfg(test) only) +**Source:** [`soroban/src/rate_limiter.rs`](../src/rate_limiter.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `NotAuthorized` | _(no doc comment on the variant; name reads as: not authorized)_ | +| 2 | `AlreadyInitialized` | _(no doc comment on the variant; name reads as: already initialized)_ | +| 3 | `DailyValueLimitExceeded` | _(no doc comment on the variant; name reads as: daily value limit exceeded)_ | +| 4 | `WeeklyValueLimitExceeded` | _(no doc comment on the variant; name reads as: weekly value limit exceeded)_ | +| 5 | `MonthlyValueLimitExceeded` | _(no doc comment on the variant; name reads as: monthly value limit exceeded)_ | +| 6 | `DailyCountLimitExceeded` | _(no doc comment on the variant; name reads as: daily count limit exceeded)_ | +| 7 | `WeeklyCountLimitExceeded` | _(no doc comment on the variant; name reads as: weekly count limit exceeded)_ | +| 8 | `MonthlyCountLimitExceeded` | _(no doc comment on the variant; name reads as: monthly count limit exceeded)_ | +| 9 | `GlobalDailyLimitExceeded` | _(no doc comment on the variant; name reads as: global daily limit exceeded)_ | +| 10 | `GlobalWeeklyLimitExceeded` | _(no doc comment on the variant; name reads as: global weekly limit exceeded)_ | +| 11 | `CooldownActive` | _(no doc comment on the variant; name reads as: cooldown active)_ | +| 12 | `CircuitBreakerTripped` | _(no doc comment on the variant; name reads as: circuit breaker tripped)_ | +| 13 | `InvalidLimit` | _(no doc comment on the variant; name reads as: invalid limit)_ | +| 14 | `InvalidRiskScore` | _(no doc comment on the variant; name reads as: invalid risk score)_ | +| 15 | `UserNotFound` | _(no doc comment on the variant; name reads as: user not found)_ | +| 16 | `EmergencyModeActive` | _(no doc comment on the variant; name reads as: emergency mode active)_ | + +## `SidecarError` + +**Contract:** SidecarStateContract — Part 4 — Standalone experimental contract (cfg(test) only) +**Source:** [`soroban/src/sidecar_state.rs`](../src/sidecar_state.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `NotAuthorized` | _(no doc comment on the variant; name reads as: not authorized)_ | +| 2 | `AlreadyInitialized` | _(no doc comment on the variant; name reads as: already initialized)_ | +| 3 | `EntityNotFound` | _(no doc comment on the variant; name reads as: entity not found)_ | +| 4 | `SidecarNotFound` | _(no doc comment on the variant; name reads as: sidecar not found)_ | +| 5 | `MaxEntriesExceeded` | _(no doc comment on the variant; name reads as: max entries exceeded)_ | +| 6 | `ConsistencyCheckFailed` | _(no doc comment on the variant; name reads as: consistency check failed)_ | +| 7 | `InvalidReference` | _(no doc comment on the variant; name reads as: invalid reference)_ | + +## `Error` + +**Contract:** BridgeReserveVerifier — Part 5 — Unreferenced file (not compiled anywhere) +**Source:** [`soroban/src/bridge_reserve_verifier.rs`](../src/bridge_reserve_verifier.rs) + +| Code | Variant | Meaning | +| --- | --- | --- | +| 1 | `NotInitialized` | _(no doc comment on the variant; name reads as: not initialized)_ | +| 2 | `AlreadyInitialized` | _(no doc comment on the variant; name reads as: already initialized)_ | +| 3 | `Unauthorized` | _(no doc comment on the variant; name reads as: unauthorized)_ | +| 4 | `BridgeNotFound` | _(no doc comment on the variant; name reads as: bridge not found)_ | +| 5 | `BridgeAlreadyRegistered` | _(no doc comment on the variant; name reads as: bridge already registered)_ | +| 6 | `OperatorNotFound` | _(no doc comment on the variant; name reads as: operator not found)_ | +| 7 | `CommitmentNotFound` | _(no doc comment on the variant; name reads as: commitment not found)_ | +| 8 | `InvalidProof` | _(no doc comment on the variant; name reads as: invalid proof)_ | +| 9 | `ChallengePeriodActive` | _(no doc comment on the variant; name reads as: challenge period active)_ | +| 10 | `ChallengePeriodExpired` | _(no doc comment on the variant; name reads as: challenge period expired)_ | +| 11 | `InsufficientStake` | _(no doc comment on the variant; name reads as: insufficient stake)_ | +| 12 | `OperatorInactive` | _(no doc comment on the variant; name reads as: operator inactive)_ | +| 13 | `InvalidInput` | _(no doc comment on the variant; name reads as: invalid input)_ | +| 14 | `NotChallengeable` | _(no doc comment on the variant; name reads as: not challengeable)_ | +| 15 | `NotResolvable` | _(no doc comment on the variant; name reads as: not resolvable)_ | + +## Cross-contract uniqueness check + +Verified programmatically (by walking each `#[contracterror]` enum's declared discriminants) that: + +1. Every contract's own error codes are contiguous, starting at `1`, with no gaps or duplicate values. +2. No two `#[contracterror]` enums in the workspace share the same Rust type name, so there is no identifier collision even though several reuse the same *numeric* range (every enum here starts at 1). + +| Contract | Enum | Codes | Range check | +| --- | --- | --- | --- | +| CrossChainRelayContract | `RelayError` | 17 | contiguous 1..17 | +| EmergencyFundRecovery | `RecoveryError` | 14 | contiguous 1..14 | +| AssetDeprecationContract | `DeprecationError` | 7 | contiguous 1..7 | +| AssetRegistryContract | `RegistryError` | 22 | contiguous 1..22 | +| BatchQueryContract | `BatchQueryError` | 4 | contiguous 1..4 | +| RateLimiterContract | `RateLimitError` | 16 | contiguous 1..16 | +| SidecarStateContract | `SidecarError` | 7 | contiguous 1..7 | +| BridgeReserveVerifier | `Error` | 15 | contiguous 1..15 | + +## Non-numeric result errors + +Two modules define a `#[contracttype]` enum named `MigrationError` (not `#[contracterror]`, so these are ordinary Soroban data types returned inside `Result` — they do not carry a raw numeric error code the way the enums above do, and are decoded by variant name rather than by integer). They are **different types in different modules** (no compile-time collision), but share a name, which is worth knowing if you're importing both: + +| Module | Variants | +| --- | --- | +| `migration.rs` | `AlreadyAtVersion`, `VersionDowngradeNotAllowed`, `UnauthorizedMigrator`, `ValidationFailed`, `RollbackNotAvailable` | +| `version_migration_helper.rs` | `AlreadyAtVersion`, `VersionDowngradeNotAllowed`, `UnauthorizedMigrator`, `ValidationFailed`, `RollbackNotAvailable`, `InvalidStateSnapshot`, `SnapshotExpired`, `NoValidationResults`, `MigrationInProgress`, `StateIntegrityCheckFailed` | + +`version_migration_helper::MigrationError` is a superset of `migration::MigrationError` plus five additional variants (`InvalidStateSnapshot`, `SnapshotExpired`, `NoValidationResults`, `MigrationInProgress`, `StateIntegrityCheckFailed`) — see [`version_migration_helper` in API_REFERENCE.md](./API_REFERENCE.md#version_migration_helper--enhanced-migration-helper) for the fuller migration system these variants belong to.