fn owner(env: soroban_sdk::Env) -> soroban_sdk::Address
Pull a balance off a receiver this contract owns, back here. Owner only.
A receiver's owner is a contract, and a contract cannot sign, so
without this any token that ever landed on a receiver -- a mistaken
transfer, a plan cut short -- would have no way out. This contract is
the receiver's owner and its direct invoker here, so the receiver's
owner check is met by invoker authorization; withdraw then sweeps it
the rest of the way to the account.
fn sweep(
env: soroban_sdk::Env,
receiver: soroban_sdk::Address,
token: soroban_sdk::Address,
amount: i128,
)
Blend's flash-loan callback (moderc3156::FlashLoan). Called by the pool
after it has transferred the loan here and before it settles requests.
Runs the armed plan, then hands everything we hold of token back to
caller, whose Repay request the pool collects next. Anything above the
loan is profit and lands with the initiator too.
fn exec_op(
env: soroban_sdk::Env,
caller: soroban_sdk::Address,
token: soroban_sdk::Address,
amount: i128,
fee: i128,
)
Run a plan against funds this contract already holds. Owner only.
Cross-venue arbitrage without a flash loan, and the unwind path for a liquidation position.
fn execute(
env: soroban_sdk::Env,
steps: soroban_sdk::Vec,
) -> soroban_sdk::Vec
Replace this contract's code in place. Owner only.
Storage -- the owner and any held balances -- survives, so a fix ships without redeploying, re-funding and re-pointing the bot.
fn upgrade(env: soroban_sdk::Env, new_wasm_hash: soroban_sdk::BytesN<32>)
Arm the plan that the next exec_op will run, and record who the loan's
from will be. Owner only, single-use.
Callable by an initiator contract (owner == initiator, in one transaction) or by a wallet that owns this receiver directly and starts the flash loan itself in a following transaction -- Blend's canonical pattern, at the cost of a second ledger.
fn set_plan(
env: soroban_sdk::Env,
initiator: soroban_sdk::Address,
steps: soroban_sdk::Vec,
)
Sweep funds out. Owner only.
fn withdraw(
env: soroban_sdk::Env,
token: soroban_sdk::Address,
amount: i128,
to: soroban_sdk::Address,
)
fn set_owner(env: soroban_sdk::Env, new_owner: soroban_sdk::Address)
execute, for a looped plan: the first hard steps must succeed, and
each later step runs only while it pays (venues::run_steps_soft). A
later pass that would lose ends the plan there with the earlier passes
kept, instead of reverting all of them. Owner only. Returns the output
of every step that ran.
fn execute_soft(
env: soroban_sdk::Env,
steps: soroban_sdk::Vec,
hard: u32,
soft_min_gain: i128,
) -> soroban_sdk::Vec
Fill percent of user's liquidation auction on pool from funds this
contract holds, and come out flat in the same transaction. Owner only.
One submit does the whole Blend side: the fill puts the auction's
lot (collateral) and bid (debt) on our position; the repay legs
clear the debt from what we hold (Blend caps repayment at the debt,
so over-asking is safe); the withdraw legs pull the collateral out
(Blend caps a withdrawal at the position, so over-asking is safe
there too). Then steps sell the collateral for profit_token.
Two guards make it safe to send on a quote: the position must end
with no debt and no collateral, and our profit_token balance must
have grown by at least min_profit. Either failing reverts the lot.
Returns the gain in profit_token.
fn fill_auction(
env: soroban_sdk::Env,
pool: soroban_sdk::Address,
user: soroban_sdk::Address,
percent: u32,
repay: soroban_sdk::Vec,
withdraw: soroban_sdk::Vec,
steps: soroban_sdk::Vec,
profit_token: soroban_sdk::Address,
min_profit: i128,
) -> i128
owner is the only address that can arm a plan, start a flash loan, run
a plan from held funds, or withdraw.
fn __constructor(env: soroban_sdk::Env, owner: soroban_sdk::Address)
Borrow amount of asset from pool, have receiver run steps with
it, then let the pool settle requests against us. Owner only.
For a pure arbitrage, requests is a single Repay of amount plus a
hair (dToken rounding at non-unit rates; Blend caps repayment at the
outstanding debt, so over-asking is safe). For a liquidation it is the
auction fill plus repayment of the liquidated debt, and we exit holding a
healthy position to unwind later.
Returns the change in our asset balance: realised profit.
fn flash_execute(
env: soroban_sdk::Env,
pool: soroban_sdk::Address,
receiver: soroban_sdk::Address,
asset: soroban_sdk::Address,
amount: i128,
steps: soroban_sdk::Vec,
requests: soroban_sdk::Vec,
) -> i128
Replace a receiver's code. Owner only. The receiver's owner is this contract, which cannot sign, so this is the only way its code moves.
fn upgrade_receiver(
env: soroban_sdk::Env,
receiver: soroban_sdk::Address,
new_wasm_hash: soroban_sdk::BytesN<32>,
)
XOXNO's flash-loan callback. Called by its pool after it has sent the
loan here; on return the pool pulls amount + fee back with
transfer_from and reverts everything if it cannot.
Runs the armed plan with whatever this receiver holds (the loan, plus
any capital the initiator sent along), approves the pool for exactly
the repayment, and hands the rest to the initiator. Like exec_op it
does nothing unless the owner armed a plan in this same transaction
and initiator is the address that plan names.
fn execute_flash_loan(
env: soroban_sdk::Env,
initiator: soroban_sdk::Address,
asset: soroban_sdk::Address,
amount: i128,
fee: i128,
pool: soroban_sdk::Address,
data: soroban_sdk::Bytes,
)
Borrow amount of asset from XOXNO Lending (controller, market
hub_id), have receiver run steps with the loan plus own_amount
of our own balance, and keep what is left after the loan and its fee
are repaid. Owner only. Returns the change in our balance of asset,
and reverts everything unless that is at least min_profit: the steps'
own guards say what each swap must return, this says what the whole
transaction must leave us with, fee included.
fn flash_execute_xoxno(
env: soroban_sdk::Env,
controller: soroban_sdk::Address,
hub_id: u32,
receiver: soroban_sdk::Address,
asset: soroban_sdk::Address,
amount: i128,
own_amount: i128,
steps: soroban_sdk::Vec,
min_profit: i128,
) -> i128