Contract 307515b60bf06ce1d082936fb514cf65bb1b19443b9bc9940bf4b6bed6634601

← Back to Index 📥 Download WASM

Meta

cliver 25.2.0#28484880988199233a7e8e87c97cb12dac323cb3
rssdkver 25.3.0#dcbea44513feb7734af6b6c4aced2c4a7a2715d0
rsver 1.94.0

Instances

  • CBXXXSC6AZJEILPEVPP6NPVLJAMR3FIIRYS257AQ6YF24I3FKWVA4KOY

Interface

fn asset(env: soroban_sdk::Env) -> soroban_sdk::Address
fn pause(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), StrategyError>
fn vault(env: soroban_sdk::Env) -> soroban_sdk::Address

Deposit USDC into Blend pool via submit(SupplyCollateral).

Flow:

  1. Transfer USDC from vault to this contract
  2. Approve Blend pool to spend USDC
  3. Call blend_pool.submit() with SupplyCollateral request
  4. Update tracked balance
fn deposit(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    amount: i128,
) -> Result<(), StrategyError>

Claim BLND token emissions from the Blend pool. Claimed tokens land in this strategy contract; the rewards module sweeps them out via sweep_rewards. Callable by vault, admin, or the configured rewards_module (when bound).

fn harvest(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result
fn unpause(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), StrategyError>

Withdraw USDC from Blend pool via submit(WithdrawCollateral).

If requested amount exceeds tracked balance, withdraws up to the tracked balance and emits both amounts for auditability.

fn withdraw(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    amount: i128,
) -> Result
fn is_paused(env: soroban_sdk::Env) -> bool
fn set_vault(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    new_vault: soroban_sdk::Address,
) -> Result<(), StrategyError>
fn balance_of(env: soroban_sdk::Env) -> i128
fn blend_pool(env: soroban_sdk::Env) -> soroban_sdk::Address

Initialize with vault, asset, and Blend pool. Admin must prove identity via require_auth.

fn initialize(
    env: soroban_sdk::Env,
    admin: soroban_sdk::Address,
    vault: soroban_sdk::Address,
    asset: soroban_sdk::Address,
    blend_pool: soroban_sdk::Address,
) -> Result<(), StrategyError>

Pool utilization and backstop coverage health check.

Queries the Blend pool's reserve data to compute:

  1. Utilization = d_supply / b_supply (if > max_utilization -> unhealthy)
  2. Backstop credit ratio (if depleted -> unhealthy)

Returns true if the pool is within configured safety thresholds.

fn is_healthy(env: soroban_sdk::Env) -> bool

Accept admin role. Must be called by the pending admin.

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

Propose a new admin. Pending admin must call accept_admin.

fn propose_admin(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    new_admin: soroban_sdk::Address,
) -> Result<(), StrategyError>

Sweep the strategy's full balance of token to to. Used by the rewards module to extract claimed BLND emissions before swapping them to USDC and redepositing into the vault.

Refuses to sweep asset (USDC principal) — that path is reserved for withdraw / emergency_withdraw. Callable by vault, admin, or the configured rewards_module. Returns the swept amount; if the strategy holds zero of token, returns 0 without erroring.

fn sweep_rewards(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    token: soroban_sdk::Address,
    to: soroban_sdk::Address,
) -> Result

Cancel a scheduled upgrade.

fn cancel_upgrade(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), StrategyError>
fn rewards_module(env: soroban_sdk::Env) -> Option

Execute a previously scheduled upgrade after delay.

fn execute_upgrade(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result<(), StrategyError>

Schedule a WASM upgrade. Executes after configured delay.

fn schedule_upgrade(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    new_wasm_hash: soroban_sdk::BytesN<32>,
) -> Result<(), StrategyError>
fn set_upgrade_delay(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    delay: u64,
) -> Result<(), StrategyError>

Pull all funds from Blend back to vault. Callable by vault (normal flow) OR admin (emergency).

Uses actual pool position instead of tracked balance to handle cases where tracked balance drifted (e.g., partial liquidation).

fn emergency_withdraw(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
) -> Result

Bind the off-chain rewards module contract. Once set, the bound address can call harvest and sweep_rewards alongside vault/admin. Pass None to clear the binding (rolls back to vault/admin only).

fn set_rewards_module(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    new_module: Option,
) -> Result<(), StrategyError>

Available liquidity for immediate withdrawal, in underlying asset units.

What "available" actually means in a Blend pool: pool-wide free liquidity is total_supplied_underlying - total_borrowed_underlying, NOT b_supply - d_supply — those counts are in different token units (b_token vs d_token) with different accrual rates, and subtracting them directly was the bug behind the first failed redeem: on a pool at 37.6% utilization the raw b_supply - d_supply over-reported available by the (b_rate − d_rate) drift, the vault's waterfall happily asked for that much, and the pool rejected with BalanceError because it simply didn't have enough free underlying to deliver.

Correct formula:

pool_supplied = b_supply * b_rate / 1e12 pool_borrowed = d_supply * d_rate / 1e12 pool_available = pool_supplied - pool_borrowed our_cap = min(tracked, pool_available)

A 2-stroop safety margin is subtracted so exact-match withdraws don't race rounding on the b_token burn inside the pool — same trick the EVM

fn available_liquidity(env: soroban_sdk::Env) -> i128
fn set_approval_buffer(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    buffer: u32,
) -> Result<(), StrategyError>
fn set_max_utilization(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    bps: u32,
) -> Result<(), StrategyError>
fn set_min_backstop_coverage(
    env: soroban_sdk::Env,
    caller: soroban_sdk::Address,
    bps: u32,
) -> Result<(), StrategyError>

Imports

WebAssembly Text (WAT) ▶