Contract 552024b2eb69e1db20a71a52407fa975dd737f55372b7a3cfb6ced29669805ff

← Back to Index 📥 Download WASM

Meta

cliver 25.0.0#
rssdkver 23.4.1#e671b396f8bacf1370925f722df158b31c0baae5
rsver 1.91.0-nightly

Instances

  • CDXPL4AG42BD2JCTSQALQ3KDJ2WZ6Q3DBMZ7JUDWMGDFEQ5YVKTL5RJ4

Interface

Initialize the lending pool contract

Arguments

  • env - The Soroban environment
  • pool_admin - Address with pool admin privileges
  • emergency_admin - Address with emergency admin privileges
  • price_oracle - Address of the price oracle contract
  • treasury - Address of the treasury (receives protocol fees)
  • dex_router - Address of DEX router (Soroswap router)
fn initialize(
    env: soroban_sdk::Env,
    pool_admin: soroban_sdk::Address,
    emergency_admin: soroban_sdk::Address,
    price_oracle: soroban_sdk::Address,
    treasury: soroban_sdk::Address,
    dex_router: soroban_sdk::Address,
    incentives_contract: Option,
) -> Result<(), KineticRouterError>

Supply assets to the protocol

Arguments

  • env - The Soroban environment
  • caller - The address calling this function
  • asset - The address of the underlying asset to supply
  • amount - The amount to be supplied
  • on_behalf_of - The address that will receive the aTokens
  • _referral_code - Code used to register the integrator (unused for now)

Returns

  • Ok(()) - Supply successful
  • Err(KineticRouterError) - Supply failed due to validation or cap limits

Cap Enforcement

This function enforces supply caps if configured. Caps are stored as whole tokens and converted to smallest units during enforcement to maximize the effective range.

fn supply(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    amount: u128,
    on_behalf_of: soroban_sdk::Address,
    referral_code: u32,
) -> Result<(), KineticRouterError>
fn withdraw(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    amount: u128,
    to: soroban_sdk::Address,
) -> Result
fn swap_collateral(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    from_asset: soroban_sdk::Address,
    to_asset: soroban_sdk::Address,
    amount: u128,
    min_amount_out: u128,
    swap_handler: Option,
) -> Result

Set DEX router address (admin only)

fn set_dex_router(
    env: soroban_sdk::Env,
    router: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Get DEX router address

fn get_dex_router(env: soroban_sdk::Env) -> Option

Set DEX factory address (admin only)

fn set_dex_factory(
    env: soroban_sdk::Env,
    factory: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Get DEX factory address

fn get_dex_factory(env: soroban_sdk::Env) -> Option
fn borrow(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    amount: u128,
    interest_rate_mode: u32,
    referral_code: u32,
    on_behalf_of: soroban_sdk::Address,
) -> Result<(), KineticRouterError>
fn repay(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    amount: u128,
    rate_mode: u32,
    on_behalf_of: soroban_sdk::Address,
) -> Result

Liquidate a position

Arguments

  • collateral_asset - The address of the underlying asset used as collateral
  • debt_asset - The address of the underlying borrowed asset to be repaid
  • user - The address of the borrower getting liquidated
  • debt_to_cover - The debt amount of borrowed asset to liquidate
  • receive_a_token - True if liquidator receives aTokens, false for underlying asset
fn liquidation_call(
    env: soroban_sdk::Env,
    liquidator: soroban_sdk::Address,
    collateral_asset: soroban_sdk::Address,
    debt_asset: soroban_sdk::Address,
    user: soroban_sdk::Address,
    debt_to_cover: u128,
    receive_a_token: bool,
) -> Result<(), KineticRouterError>
fn set_flash_loan_premium(
    env: soroban_sdk::Env,
    premium_bps: u128,
) -> Result<(), KineticRouterError>

Set maximum flash loan premium allowed (admin only)

Arguments

  • max_premium_bps - Maximum premium in basis points (e.g., 100 = 1%)

Returns

  • Ok(()) if max premium updated successfully
  • Err(Unauthorized) if caller is not admin
fn set_flash_loan_premium_max(
    env: soroban_sdk::Env,
    max_premium_bps: u128,
) -> Result<(), KineticRouterError>
fn get_flash_loan_premium_max(env: soroban_sdk::Env) -> u128
fn set_hf_liquidation_threshold(
    env: soroban_sdk::Env,
    threshold: u128,
) -> Result<(), KineticRouterError>
fn get_hf_liquidation_threshold(env: soroban_sdk::Env) -> u128
fn set_min_swap_output_bps(
    env: soroban_sdk::Env,
    min_output_bps: u128,
) -> Result<(), KineticRouterError>
fn get_min_swap_output_bps(env: soroban_sdk::Env) -> u128
fn set_partial_liq_hf_threshold(
    env: soroban_sdk::Env,
    threshold: u128,
) -> Result<(), KineticRouterError>
fn get_partial_liq_hf_threshold(env: soroban_sdk::Env) -> u128
fn get_flash_loan_premium(env: soroban_sdk::Env) -> u128

Set extra premium charged for flash liquidations (admin only). This is on top of the regular protocol fee collected during liquidation. Set to 0 to disable the extra fee (default).

fn set_flash_liquidation_premium(
    env: soroban_sdk::Env,
    premium_bps: u128,
) -> Result<(), KineticRouterError>
fn get_flash_liquidation_premium(env: soroban_sdk::Env) -> u128

Sets the price tolerance for two-step liquidation execution (in basis points). Default is 300 (3%). Admin has full flexibility to set any value.

fn set_liquidation_price_tolerance(
    env: soroban_sdk::Env,
    tolerance_bps: u128,
) -> Result<(), KineticRouterError>

M-07

fn set_asset_staleness_threshold(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    threshold_seconds: u64,
) -> Result<(), KineticRouterError>

M-07

fn get_asset_staleness_threshold(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Option

Execute a flash loan

Flash loans are permissionless - anyone can initiate them. The receiver contract must implement execute_operation callback.

Parameters

  • initiator: Address initiating the flash loan (must authorize)
  • receiver: Contract that will receive the loan and execute callback
  • assets: Assets to borrow
  • amounts: Amounts to borrow for each asset
  • params: Arbitrary data passed to receiver

Receiver Callback

The receiver must implement execute_operation with the standard flash loan interface.

Authorization

Initiator must authorize the call, but anyone can be an initiator. The receiver handles its own authorization logic.

Errors

  • InvalidFlashLoanParams: Invalid parameters
  • InsufficientFlashLoanLiquidity: Not enough liquidity
  • FlashLoanExecutionFailed: Receiver callback failed
  • FlashLoanNotRepaid: Loan not fully repaid
fn flash_loan(
    env: soroban_sdk::Env,
    initiator: soroban_sdk::Address,
    receiver: soroban_sdk::Address,
    assets: soroban_sdk::Vec,
    amounts: soroban_sdk::Vec,
    params: soroban_sdk::Bytes,
) -> Result<(), KineticRouterError>

Prepare a liquidation - validates and stores authorization (TX1 of 2-step liquidation) This is the expensive validation step (~40M CPU) but can fail/retry safely.

Arguments

  • liquidator - Address executing the liquidation
  • user - Address being liquidated
  • debt_asset - Asset to repay
  • collateral_asset - Asset to seize
  • debt_to_cover - Amount of debt to repay
  • min_swap_out - Minimum acceptable swap output (slippage protection)
  • swap_handler - Optional custom swap handler address

Returns

  • LiquidationAuthorization - Authorization token for execute_liquidation
fn prepare_liquidation(
    env: soroban_sdk::Env,
    liquidator: soroban_sdk::Address,
    user: soroban_sdk::Address,
    debt_asset: soroban_sdk::Address,
    collateral_asset: soroban_sdk::Address,
    debt_to_cover: u128,
    min_swap_out: u128,
    swap_handler: Option,
) -> Result

Execute a prepared liquidation - atomic swap + debt repayment (TX2 of 2-step liquidation) Uses pre-validated data from prepare_liquidation (~60M CPU).

Arguments

  • liquidator - Address executing the liquidation (must match authorization)
  • user - Address being liquidated (must match authorization)
  • debt_asset - Asset to repay (must match authorization)
  • collateral_asset - Asset to seize (must match authorization)
  • deadline - Transaction deadline timestamp
fn execute_liquidation(
    env: soroban_sdk::Env,
    liquidator: soroban_sdk::Address,
    user: soroban_sdk::Address,
    debt_asset: soroban_sdk::Address,
    collateral_asset: soroban_sdk::Address,
    deadline: u64,
) -> Result<(), KineticRouterError>

Set treasury address for protocol fees (admin only)

Arguments

  • treasury - New treasury address for protocol fee collection

Returns

  • Ok(()) if treasury updated successfully
  • Err(Unauthorized) if caller is not admin
fn set_treasury(
    env: soroban_sdk::Env,
    treasury: soroban_sdk::Address,
) -> Result<(), KineticRouterError>
fn get_treasury(env: soroban_sdk::Env) -> Option

F-02 Safety net for when oracle precision changes without changing the oracle address.

fn flush_oracle_config_cache(env: soroban_sdk::Env) -> Result<(), KineticRouterError>

AC-01 Must be called once after contract upgrade to prevent whitelist/blacklist bypass.

fn sync_access_control_flags(env: soroban_sdk::Env) -> Result<(), KineticRouterError>
fn set_flash_liquidation_helper(
    env: soroban_sdk::Env,
    helper: soroban_sdk::Address,
) -> Result<(), KineticRouterError>
fn get_flash_liquidation_helper(env: soroban_sdk::Env) -> Option

Set pool configurator contract address (admin only)

Arguments

  • configurator - Pool configurator contract address

Returns

  • Ok(()) if configurator address updated successfully
  • Err(Unauthorized) if caller is not admin
fn set_pool_configurator(
    env: soroban_sdk::Env,
    configurator: soroban_sdk::Address,
) -> Result<(), KineticRouterError>
fn get_pool_configurator(env: soroban_sdk::Env) -> Option

Get available protocol reserves for an asset

Protocol reserves accumulate due to the reserve factor, which reduces supplier APY. Reserves = underlying_balance_in_atoken - total_withdrawable_supply

Arguments

  • asset - The address of the underlying asset

Returns

  • Ok(u128) - Available reserves in smallest units
  • Err - If reserve not found or calculation fails
fn get_protocol_reserves(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result
fn collect_protocol_reserves(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result

Cover accumulated bad debt deficit for a reserve. Permissionless: anyone can inject tokens to replenish pool liquidity. Returns the actual amount covered (capped at current deficit).

fn cover_deficit(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    amount: u128,
) -> Result

Get accumulated bad debt deficit for a reserve (0 if none).

fn get_reserve_deficit(env: soroban_sdk::Env, asset: soroban_sdk::Address) -> u128
fn set_user_use_reserve_as_coll(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    use_as_collateral: bool,
) -> Result<(), KineticRouterError>

Get user account data

Arguments

  • user - The address of the user
fn get_user_account_data(
    env: soroban_sdk::Env,
    user: soroban_sdk::Address,
) -> Result
fn get_reserve_data(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result
fn get_current_reserve_data(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result
fn get_current_liquidity_index(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result
fn get_current_var_borrow_idx(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result

Get incentives contract address

Arguments

  • env - The Soroban environment

Returns

  • Option<Address> - The incentives contract address if set, None otherwise
fn get_incentives_contract(env: soroban_sdk::Env) -> Option
fn set_incentives_contract(
    env: soroban_sdk::Env,
    incentives: soroban_sdk::Address,
) -> Result

Get user configuration

Arguments

  • user - The address of the user
fn get_user_configuration(
    env: soroban_sdk::Env,
    user: soroban_sdk::Address,
) -> UserConfiguration
fn get_reserves_list(env: soroban_sdk::Env) -> soroban_sdk::Vec

L-02

fn update_reserve_state(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result
fn is_paused(env: soroban_sdk::Env) -> bool
fn pause(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>
fn unpause(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Initialize a new reserve

Note

This function should be called by the pool configurator contract. The pool configurator should validate authorization before calling this function.

Arguments

  • underlying_asset - The address of the underlying asset
  • a_token_impl - The address of the aToken implementation
  • variable_debt_impl - The address of the variable debt token implementation
  • interest_rate_strategy - The address of the interest rate strategy
  • treasury - The address of the treasury
  • params - Reserve initialization parameters
fn init_reserve(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    underlying_asset: soroban_sdk::Address,
    a_token_impl: soroban_sdk::Address,
    variable_debt_impl: soroban_sdk::Address,
    interest_rate_strategy: soroban_sdk::Address,
    treasury: soroban_sdk::Address,
    params: InitReserveParams,
) -> Result<(), KineticRouterError>

Updates the supply cap for a reserve.

The supply cap limits the total amount that can be supplied to a reserve. Caps are stored as whole tokens (not smallest units) to maximize the effective range within the 32-bit storage limit.

Arguments

  • env: The Soroban environment
  • asset: The underlying asset address
  • supply_cap: New supply cap in whole tokens (0 = no cap, virtually unlimited)

Returns

  • Ok(()): Supply cap updated successfully
  • Err(KineticRouterError::InvalidAmount): Invalid cap value
  • Err(KineticRouterError::Unauthorized): Caller is not admin

Events

Emits (sup_cap, asset) event with the new supply cap value.

fn set_reserve_supply_cap(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    supply_cap: u128,
) -> Result<(), KineticRouterError>

Updates the borrow cap for a reserve.

The borrow cap limits the total amount that can be borrowed from a reserve. Caps are stored as whole tokens (not smallest units) to maximize the effective range within the 32-bit storage limit.

Arguments

  • env: The Soroban environment
  • asset: The underlying asset address
  • borrow_cap: New borrow cap in whole tokens (0 = no cap, virtually unlimited)

Returns

  • Ok(()): Borrow cap updated successfully
  • Err(KineticRouterError::InvalidAmount): Invalid cap value
  • Err(KineticRouterError::Unauthorized): Caller is not admin

Events

Emits (bor_cap, asset) event with the new borrow cap value.

fn set_reserve_borrow_cap(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    borrow_cap: u128,
) -> Result<(), KineticRouterError>

Sets the minimum remaining debt after partial liquidation for a reserve. Value is in whole tokens (same convention as borrow/supply caps). Prevents dust debt positions that are uneconomical to liquidate.

fn set_reserve_min_remaining_debt(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    min_remaining_debt: u32,
) -> Result<(), KineticRouterError>

Updates the debt ceiling for a reserve.

The debt ceiling limits the total amount of debt that can be borrowed across all users for a specific reserve. This is different from borrow cap which limits per-reserve borrowing. Debt ceiling is stored as whole tokens (not smallest units).

Arguments

  • env: The Soroban environment
  • asset: The underlying asset address
  • debt_ceiling: New debt ceiling in whole tokens (0 = no ceiling)

Returns

  • Ok(()): Debt ceiling updated successfully
  • Err(KineticRouterError::ReserveNotFound): Reserve does not exist
  • Err(KineticRouterError::Unauthorized): Caller is not admin

Events

Emits (set_cap, asset) event with (debt_ceil, debt_ceiling) value.

fn set_reserve_debt_ceiling(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    debt_ceiling: u128,
) -> Result<(), KineticRouterError>

Gets the debt ceiling for a reserve.

Arguments

  • asset: The underlying asset address

Returns

  • Ok(u128): Debt ceiling in whole tokens (0 = no ceiling)
  • Err(KineticRouterError::ReserveNotFound): Reserve does not exist
fn get_reserve_debt_ceiling(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> Result

Update reserve configuration (called by pool configurator)

Arguments

  • caller: The address calling this function (must be pool configurator)
  • asset: The underlying asset address
  • configuration: New reserve configuration
fn update_reserve_configuration(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    configuration: ReserveConfiguration,
) -> Result<(), KineticRouterError>
fn update_reserve_rate_strategy(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    interest_rate_strategy: soroban_sdk::Address,
) -> Result<(), KineticRouterError>
fn update_atoken_implementation(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    a_token_impl: soroban_sdk::BytesN<32>,
) -> Result<(), KineticRouterError>
fn update_debt_token_implementation(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    debt_token_impl: soroban_sdk::BytesN<32>,
) -> Result<(), KineticRouterError>
fn drop_reserve(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    asset: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Upgrade contract WASM (admin only)

Arguments

  • new_wasm_hash - Hash of new WASM binary

Errors

  • Unauthorized - Caller is not admin
fn upgrade(
    env: soroban_sdk::Env,
    new_wasm_hash: soroban_sdk::BytesN<32>,
) -> Result<(), KineticRouterError>
fn version(env: soroban_sdk::Env) -> u32
fn get_admin(env: soroban_sdk::Env) -> Result

Propose a new upgrade admin address (two-step transfer, step 1). Only the current admin can propose a new admin. The proposed admin must call accept_admin to complete the transfer.

fn propose_admin(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    pending_admin: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Accept upgrade admin role (two-step transfer, step 2). Only the pending admin can call this to finalize the transfer.

fn accept_admin(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Cancel a pending upgrade admin proposal. Only the current admin can cancel a pending proposal.

fn cancel_admin_proposal(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Get the pending upgrade admin address, if any.

fn get_pending_admin(
    env: soroban_sdk::Env,
) -> Result

Propose a new pool admin address (two-step transfer, step 1).

fn propose_pool_admin(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    pending_admin: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Accept pool admin role (two-step transfer, step 2).

fn accept_pool_admin(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Cancel a pending pool admin proposal.

fn cancel_pool_admin_proposal(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Get the pending pool admin address, if any.

fn get_pending_pool_admin(
    env: soroban_sdk::Env,
) -> Result

Propose a new emergency admin address (two-step transfer, step 1).

fn propose_emergency_admin(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    pending_admin: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Accept emergency admin role (two-step transfer, step 2).

fn accept_emergency_admin(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Cancel a pending emergency admin proposal.

fn cancel_emergency_admin_proposal(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), KineticRouterError>

Get the pending emergency admin address, if any.

fn get_pending_emergency_admin(
    env: soroban_sdk::Env,
) -> Result

Set reserve whitelist (admin only)

Arguments

  • caller - Pool admin address
  • asset - Underlying asset address
  • whitelist - Addresses allowed to interact with this reserve

Behavior

  • Empty whitelist: open access
  • Non-empty whitelist: restricted to listed addresses

** Note **: This function replaces the entire whitelist. To add/remove addresses, first get the current list, modify it, then set the complete new list.

Errors

  • Unauthorized - Caller is not admin
fn set_reserve_whitelist(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    whitelist: soroban_sdk::Vec,
) -> Result<(), KineticRouterError>
fn get_reserve_whitelist(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> soroban_sdk::Vec
fn is_whitelisted_for_reserve(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    address: soroban_sdk::Address,
) -> bool
fn set_liquidation_whitelist(
    env: soroban_sdk::Env,
    whitelist: soroban_sdk::Vec,
) -> Result<(), KineticRouterError>
fn get_liquidation_whitelist(
    env: soroban_sdk::Env,
) -> soroban_sdk::Vec
fn is_whitelisted_for_liquidation(
    env: soroban_sdk::Env,
    address: soroban_sdk::Address,
) -> bool
fn set_reserve_blacklist(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    blacklist: soroban_sdk::Vec,
) -> Result<(), KineticRouterError>
fn get_reserve_blacklist(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
) -> soroban_sdk::Vec
fn is_blacklisted_for_reserve(
    env: soroban_sdk::Env,
    asset: soroban_sdk::Address,
    address: soroban_sdk::Address,
) -> bool
fn set_liquidation_blacklist(
    env: soroban_sdk::Env,
    blacklist: soroban_sdk::Vec,
) -> Result<(), KineticRouterError>
fn get_liquidation_blacklist(
    env: soroban_sdk::Env,
) -> soroban_sdk::Vec
fn is_blacklisted_for_liquidation(
    env: soroban_sdk::Env,
    address: soroban_sdk::Address,
) -> bool

M-01 Only whitelisted handlers can be used for custom swaps. Empty whitelist = deny all custom handlers (only built-in DEX).

fn set_swap_handler_whitelist(
    env: soroban_sdk::Env,
    whitelist: soroban_sdk::Vec,
) -> Result<(), KineticRouterError>
fn get_swap_handler_whitelist(
    env: soroban_sdk::Env,
) -> soroban_sdk::Vec
fn is_swap_handler_whitelisted(
    env: soroban_sdk::Env,
    handler: soroban_sdk::Address,
) -> bool

WP-C1 + MEDIUM-1 fix: Validate sender HF and update bitmaps for aToken transfers. Called by aToken.transfer_internal() after computing balances but before writing them. Single cross-contract call replaces separate validate + finalize to save router size.

  1. HF check: if sender has debt, validate the transfer won't make them liquidatable
  2. Bitmap sync: clear sender's collateral bit if balance → 0, set receiver's if new position
fn validate_and_finalize_transfer(
    env: soroban_sdk::Env,
    underlying_asset: soroban_sdk::Address,
    from: soroban_sdk::Address,
    to: soroban_sdk::Address,
    amount: u128,
    from_balance_after: u128,
    to_balance_after: u128,
) -> Result<(), KineticRouterError>

Imports

WebAssembly Text (WAT) ▶