fn admin(env: soroban_sdk::Env) -> soroban_sdk::Address
Pause the router's entry paths. Exits stay open, and so does everything underneath — a
paused router removes convenience, never access. Users can still reach Sr::deposit,
SrMarket::swap_* and Yield::redeem_py directly, which is the property that makes this
switch safe to flip on suspicion rather than on proof.
fn pause(env: soroban_sdk::Env)
Recover tokens donated to the router — never user funds in flight, because there are none: every entry point drains before it returns. Admin-gated and sent to the admin.
fn sweep(env: soroban_sdk::Env, tokenc: soroban_sdk::Address) -> i128
fn expiry(env: soroban_sdk::Env) -> u64
fn market(env: soroban_sdk::Env) -> soroban_sdk::Address
fn unpause(env: soroban_sdk::Env)
fn version(env: soroban_sdk::Env) -> soroban_sdk::String
fn pt_token(env: soroban_sdk::Env) -> soroban_sdk::Address
fn sr_token(env: soroban_sdk::Env) -> soroban_sdk::Address
fn timelock(env: soroban_sdk::Env) -> u64
fn code_hash(env: soroban_sdk::Env) -> soroban_sdk::BytesN<32>
fn is_paused(env: soroban_sdk::Env) -> bool
Wire the router to a market, reading everything else back from the chain.
The caller supplies one address. Engine, SR, PT, underlying and expiry are all read from the
market and the contracts it names, so a fat-fingered deploy cannot produce a router pointed
at a market for one series and an engine for another. This is the same construction that
makes tofix.md #24 inexpressible in the vault.
fn initialize(env: soroban_sdk::Env, market: soroban_sdk::Address)
fn underlying(env: soroban_sdk::Env) -> soroban_sdk::Address
fn accept_admin(env: soroban_sdk::Env)
fn set_timelock(env: soroban_sdk::Env, secs: u64)
fn __constructor(env: soroban_sdk::Env, admin: soroban_sdk::Address)
fn apply_upgrade(env: soroban_sdk::Env)
fn pending_admin(env: soroban_sdk::Env) -> Option
fn propose_admin(env: soroban_sdk::Env, new_admin: soroban_sdk::Address)
fn cancel_upgrade(env: soroban_sdk::Env)
fn yield_contract(env: soroban_sdk::Env) -> soroban_sdk::Address
fn pending_upgrade(env: soroban_sdk::Env) -> Option
Buy PT with USDC, exact input. Spends exactly usdc_in; reverts below min_pt_out.
min_pt_out is the user's only protection here and it is a real one: it is denominated in
PT, so it bounds the whole route — a bad wrap rate and a bad swap price both show up in
the same number.
fn buy_pt_with_usdc(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
usdc_in: i128,
min_pt_out: i128,
deadline_ledger: u32,
) -> i128
Buy YT with plain USDC, one signature. Delivers exactly yt_out, wrapping exactly
usdc_in; anything the market does not need comes back as SR.
usdc_in is an input rather than something we work outThis is the tightest path in the protocol for transaction budget: a Blend supply, a curve
solve, a mint_py and three transfers, all in one transaction. An earlier version priced
the trade itself — quote_buy_yt, then two rate conversions — and failed on live testnet
with Error(Budget, ExceededLimit) while fitting comfortably against the local Blend
fixture, which is far lighter than the real pool. Every cross-contract call it could shed
was the difference between a path that exists and one that does not.
So the pricing moved off chain, where it is free. The caller quotes with
[Self::quote_buy_yt_with_usdc], pads for index drift, and passes the result. This costs
nothing in safety: usdc_in is a user-supplied number, which is exactly what the one
rule in the module docs demands
fn buy_yt_with_usdc(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
yt_out: i128,
usdc_in: i128,
deadline_ledger: u32,
) -> i128
fn schedule_upgrade(env: soroban_sdk::Env, wasm_hash: soroban_sdk::BytesN<32>) -> u64
Sell PT for USDC. Exact input; reverts below min_usdc_out.
fn sell_pt_for_usdc(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
pt_in: i128,
min_usdc_out: i128,
deadline_ledger: u32,
) -> i128
Sell YT for USDC. Exact input; reverts below min_usdc_out.
The seller's accrued interest is settled by the YT transfer in the first line — the engine's
before_yt_change hook credits it to them before the balance moves, so selling YT never
forfeits yield already earned. It stays claimable afterwards via claim_yield_to_usdc.
fn sell_yt_for_usdc(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
yt_in: i128,
min_usdc_out: i128,
deadline_ledger: u32,
) -> i128
USDC a claim_yield_to_usdc would pay right now, net of the protocol's yield fee.
fn quote_claim_yield(env: soroban_sdk::Env, user: soroban_sdk::Address) -> i128
Redeem principal to USDC, at face value, through the engine rather than the market.
sell_pt_for_usdc stops working exactly where this starts mattering.py_amount of both PT and YT. Useful
to unwind a full position without paying the spread twice, and priced at face by
definition — but it needs both legs, which is why the UI offers it separately.Deliberately not pausable-gated beyond the router's own switch: this is an exit path.
fn redeem_py_for_usdc(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
py_amount: i128,
min_usdc_out: i128,
) -> i128
Claim accrued YT yield straight to USDC.
This is the piece that makes YT legible to a normal user. Holding YT earns SR continuously; without this the holder has to claim SR, then unwrap it, then work out which of the two numbers was their actual return. Here it is one call and one number, in the unit they deposited.
The redirect to this contract is why the engine grew redeem_due_interest_to: claiming to
the user and pulling the proceeds back would require the router to name an amount only known
on chain inside a user-signed transfer — the forbidden shape from the module docs.
Returns the USDC paid. Claiming zero is not an error; it returns 0 and touches nothing.
fn claim_yield_to_usdc(
env: soroban_sdk::Env,
user: soroban_sdk::Address,
min_usdc_out: i128,
) -> i128
fn cancel_admin_transfer(env: soroban_sdk::Env)
PT out for a given USDC input.
fn quote_buy_pt_with_usdc(env: soroban_sdk::Env, usdc_in: i128) -> i128
USDC needed for a given YT output. Pad this by the user's slippage tolerance and pass the
padded figure as max_usdc_in; the pad is refunded.
fn quote_buy_yt_with_usdc(env: soroban_sdk::Env, yt_out: i128) -> i128
USDC out for a given PT input.
fn quote_sell_pt_for_usdc(env: soroban_sdk::Env, pt_in: i128) -> i128
USDC out for a given YT input.
fn quote_sell_yt_for_usdc(env: soroban_sdk::Env, yt_in: i128) -> i128
USDC a redeem_py_for_usdc of py_amount would pay — face value, no curve.
fn quote_redeem_py_for_usdc(env: soroban_sdk::Env, py_amount: i128) -> i128