Skip to content

Configurable Parameters

This section outlines the configurable parameter set for an Alula market and its pools. It distinguishes between health and risk parameters (solvency and liquidation rules), fee schedule parameters (user-facing operation fees), and market-wide constraints. Every parameter update is validated.

Governance and Update Logic

Markets maintain per-asset pools tracked in pool state and governed by pool config. New pools are created and existing pools are updated through the same administrative flow: parameters are queued via queue_in_pool_set (for managed pools) and applied through apply_pool_set. The queue_in_pool_set function serves dual purpose — it is used both for creating new pools and for updating the configuration of existing pools. This keeps risk isolated at the pool level. The separation is especially important for permissioned or RWA-heavy pools, where participation may be gated through allow-lists and policy-aligned settings.

All parameters below follow the market's update rules.

  • Owned markets only: Pool configuration and market-level updates are only possible on owned markets where a market admin role is defined.
  • Timed queue execution: Both pool config updates (queue_in_pool_setapply_pool_set) and market config updates (queue_in_market_updateapply_market_update) must be queued into a time-lock. They cannot be applied instantly, which gives users time to exit if they disagree with the change. The time-lock duration (update_in_queue_period) is configured at deployment and cannot be changed later.
  • Unified pool set: The same queue_in_pool_set function is used both to create new pools and to update existing pool configurations. New pool creation does not require an owned market; updating an existing pool does.
  • Immutability: Markets deployed without ownership enabled are ungoverned; their pool and market parameters cannot be changed.
  • Authorization: All updates must be authorized by the market admin.

Market-Wide Configuration

These are global parameters affecting the entire market contract and all obligations within it. They are managed via the time-locked queue_in_market_updateapply_market_update flow on owned markets.

ParameterTypeUnitDescription
max_positionsu32CountMaximum number of distinct assets (collateral + borrows) a single obligation can hold (2–25). This prevents resource exhaustion during liquidation and health checks.
min_collateral_value_centsi128USD centsMinimum collateral value (e.g., 500 = $5.00) required for an obligation to begin receiving positive borrowing capacity. This helps guarantee liquidation viability.

INFO

insolvency_ltv_bps is a market-level parameter set at construction time. It cannot be updated after deployment.

Health and Risk Configuration

These parameters are managed via PoolConfig.health_config. Updates must go through the time-locked pool set flow.

ParameterTypeUnitDescription
supply_limiti128Token amountHard cap on total liquidity (available + borrowed). 0 implies unlimited.
utilization_ratio_limit_bpsi128BPSUtilization threshold (e.g., 9000 = 90%) that triggers the withdrawal throttle. Above this threshold, borrows are prohibited and withdrawal limits and throttle fees apply.
withdraw_scarcity_limit_bpsi128BPSMaximum percentage of the pool's total supply that can be withdrawn in a single transaction while the withdrawal throttle is active.
withdraw_scarcity_cooldown_su64SecondsMinimum time required between consecutive withdrawals from the same obligation while the withdrawal throttle is active.
open_ltv_bpsi128BPSOpen LTV used when computing borrowing capacity (e.g., 7000 = 70%).
close_ltv_bpsi128BPSClose LTV used to determine whether an obligation is eligible for liquidation (e.g., 8000 = 80%).
liability_factor_bpsi128BPSMultiplier applied to debt value (10000–20000; 10000 = 1×). Used to conservatively inflate debt value for riskier borrowed assets and reduce borrowing capacity.
liquidation_close_factor_bpsi128BPSMaximum percentage of a single debt position that a liquidator can repay in one liquidation transaction.
max_liquidation_incentive_bpsi128BPSMaximum collateral discount awarded to liquidators (e.g., 500 = 5%).

Pool Status Flags

Each pool has a PoolStatus bitfield that controls which operations are allowed at the pool level, independent of the market-wide status. Managed via update_pool_status on owned markets.

BitValueOperation
01Deposit enabled
12Borrow enabled
24Add collateral enabled
38Flash loan enabled

Setting flags = u32::MAX enables all operations. Setting flags = 0 disables all.

Operation Fees

These parameters are managed via PoolConfig.fee_config. Updates must go through the time-locked pool set flow.

ParameterTypeUnitDescription
borrow_fee_bpsu32BPSOperation fee charged atomically on new borrows. Added to the debt principal.
flash_loan_fee_bpsu32BPSOperation fee charged on flash loan principal.
deposit_fee_bpsu32BPSOperational friction fee on deposits (if enabled). Deducted from the deposit amount.
withdraw_fee_bpsu32BPSOperational friction fee on withdrawals (usually 0). Deducted from the receivable amount.
withdraw_max_scarcity_fee_bpsu32BPSMaximum value of an additional fee (accumulating linearly from 0) when the pool's utilization ratio exceeds utilization_ratio_limit_bps after the withdrawal. Discourages exits during a liquidity crunch.
add_collateral_fee_bpsu32BPSFriction fee on adding collateral (usually 0).
remove_collateral_fee_bpsu32BPSFriction fee on removing collateral (usually 0).
repay_fee_bpsu32BPSFriction fee on repayment (usually 0).

Fee Routing and Splits

This configuration defines how revenue is routed to beneficiaries. Take-rate and operation-fee beneficiaries are configured per-pool via set_take_rate_fees_beneficiaries and set_operation_fees_beneficiaries. Referrers are configured in PoolFeeConfig.referrers.

Take Rate

ParameterSourceDescription
take_rate_bpsPoolFeeConfigPercentage of borrower interest diverted as protocol revenue (e.g., 1000 = 10%).
take_rate_beneficiariesPoolFeeConfigOption<Map<Address, u32>> — beneficiaries and their share (in bps, must sum to 10,000). Set via set_take_rate_fees_beneficiaries.

Operation Fees

ParameterSourceDescription
operation_fee_beneficiariesPoolFeeConfigOption<Map<Address, u32>> — beneficiaries and their share (in bps, must sum to 10,000). Set via set_operation_fees_beneficiaries.
referrersPoolFeeConfigOption<Map<Address, u32>> — allowed referrers and their immediately received percentage of the origination fee. Total must not exceed 10,000 bps.

Interest Rate and Accrual Models

Model configuration is part of PoolConfig and goes through the time-locked pool set flow.

Accrual Model

rust
pub enum AccrualModel {
    Compounded,    // Compound interest (default, currently the only option)
}

Interest Rate Model

The interest rate curve is managed via InterestRateModel. The current implementation uses a kinked utilization-based model.

rust
pub enum InterestRateModel {
    Kinked(KinkedIRConfig),
}
ParameterTypeUnitDescription
base_apr_bpsi128BPSMinimum borrow APR accrued regardless of utilization.
kink1_ur_bpsi128BPSFirst utilization kink threshold where the slope increases (e.g., 70%).
kink1_apr_bpsi128BPSBorrow APR exactly at kink1_ur_bps.
kink2_ur_bpsi128BPSSecond utilization kink threshold for high-demand pricing (e.g., 80%).
kink2_apr_bpsi128BPSBorrow APR exactly at kink2_ur_bps.
max_apr_bpsi128BPSMaximum borrow APR when utilization reaches 100%.

Reactive Interest Rate Modifier

In addition to the base interest rate curve, each pool has a reactive interest rate modifier that dynamically adjusts borrowing costs based on how far the actual utilization deviates from the target utilization.

ParameterTypeUnitDescription
ir_reactivity_constantu320–100Controls how aggressively the interest rate modifier reacts to utilization deviations. Part of PoolConfig.
target_utilization_ratio_bpsi128BPSThe target utilization ratio the pool tries to maintain. Stored on the Pool struct.
interest_rate_modifieri128BPSCurrent modifier value (bounded between 0.1× and 10×, i.e. 1,000–100,000 bps). Stored on the Pool struct.

The modifier creates a feedback loop:

  • When actual utilization exceeds the target, the modifier decreases (reducing borrowing costs to encourage utilization)
  • When actual utilization is below the target, the modifier increases (raising borrowing costs to discourage excess supply)
  • The final borrow APR is: base_borrow_apr × interest_rate_modifier / 10,000
  • The modifier is bounded between 0.1× (1,000 bps) and 10× (100,000 bps)