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:
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>
fn backstop(env: soroban_sdk::Env) -> Option
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:
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>
Set the Blend backstop module address used by is_healthy to read the
pool's real insurance coverage. Required for the backstop coverage gate
to be active; until set, is_healthy runs utilization-only.
fn set_backstop(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
backstop: 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>