Deposit amount USDC; supply it to the yield source; mint amount PT + amount YT to
user; record a new position. Returns the new position id.
fn mint(env: soroban_sdk::Env, user: soroban_sdk::Address, amount: i128) -> u64
The current admin (for the frontend / monitoring).
fn admin(env: soroban_sdk::Env) -> soroban_sdk::Address
fn pause(env: soroban_sdk::Env)
fn unpause(env: soroban_sdk::Env)
Human-readable semver of the source build (informational; an upgrade can't rewrite this, so
for verifiable on-chain identity use [Self::code_hash]).
fn version(env: soroban_sdk::Env) -> soroban_sdk::String
fn maturity(env: soroban_sdk::Env) -> u64
fn pt_token(env: soroban_sdk::Env) -> soroban_sdk::Address
The protocol-wide solvency figures, for the public dashboard (plan §11.5):
returns (blend_position_value, total_principal, total_unclaimed_yield). The invariant is
blend_position_value >= total_principal + total_unclaimed_yield.
fn solvency(env: soroban_sdk::Env) -> (i128, i128, i128)
The current upgrade timelock delay (seconds).
fn timelock(env: soroban_sdk::Env) -> u64
fn yt_token(env: soroban_sdk::Env) -> soroban_sdk::Address
The live deployed WASM hash (32-byte SHA-256) of the code actually running — read from the host, so it always reflects the current build even across upgrades. Lets anyone verify on chain which build is live and confirm an upgrade landed.
fn code_hash(env: soroban_sdk::Env) -> soroban_sdk::BytesN<32>
fn is_paused(env: soroban_sdk::Env) -> bool
Redeem amount PT for amount USDC 1:1, allowed only at/after maturity (SCF: principal
covered by the grown Blend position). Burns the PT.
fn redeem_pt(env: soroban_sdk::Env, position_id: u64, amount: i128) -> i128
One-shot setup, gated to the constructor-set admin (SCF #7 + front-run-proof). Wires the
strategy + PT/YT SACs + maturity. Must be the legit admin (set atomically at deploy).
strategy — the YieldStrategy adapter (Blend). Its underlying() becomes our USDC.pt_token / yt_token — pre-deployed SACs whose admin is this wrapper (so we can
mint/burn). The deploy script wires these up; the contract asserts it can mint.maturity — unix seconds; PT redeems 1:1 only at/after this.fn initialize(
env: soroban_sdk::Env,
strategy: soroban_sdk::Address,
pt_token: soroban_sdk::Address,
yt_token: soroban_sdk::Address,
maturity: u64,
)
The underlying deposit/settlement asset (USDC SAC), cached from the strategy at init. Lets contracts built on top of the wrapper (e.g. the Fixed-Rate Vault) discover it.
fn underlying(env: soroban_sdk::Env) -> soroban_sdk::Address
Claim accrued yield for a position. Settles, never burns YT (SCF #6). Yield is measured
from the position's own settled_rate (SCF #4/#5). Returns USDC paid out.
fn claim_yield(env: soroban_sdk::Env, position_id: u64) -> i128
Accept a pending admin proposal (step 2 of 2). Must be called by the proposed admin.
fn accept_admin(env: soroban_sdk::Env)
fn get_position(env: soroban_sdk::Env, position_id: u64) -> Position
Set the upgrade timelock delay (seconds), bounded to [1h, 30d]. Current admin only.
fn set_timelock(env: soroban_sdk::Env, secs: u64)
Atomic deploy-time constructor (mainnet-readiness: no deploy→init front-run). Runs as
part of contract creation, so it cannot be front-run: it binds the admin the moment the
contract exists. The remaining setup ([Self::initialize]) is then admin-gated, so even
though it's a separate call, only this admin can complete it — a front-runner can never
hijack the wrapper by racing the init.
admin — operational admin (pause/upgrade/governance; cannot move user funds).fn __constructor(env: soroban_sdk::Env, admin: soroban_sdk::Address)
Apply a scheduled upgrade (only at/after its eta). Current admin only.
fn apply_upgrade(env: soroban_sdk::Env)
Permissionless TTL keep-alive (mainnet-readiness #5). Extends a position entry's storage
TTL to comfortably exceed the market maturity (+grace), clamped to the network max. Anyone
may call it — it only prolongs an entry, never mutates accounting — so a long-dated bond that
is simply held (never claimed) for months can't archive before it matures. No auth, no pause
gate (keeping state alive is always safe). Panics PositionNotFound for an unknown id.
fn bump_position(env: soroban_sdk::Env, position_id: u64)
The pending (proposed, not-yet-accepted) admin, if any.
fn pending_admin(env: soroban_sdk::Env) -> Option
Propose a new admin (step 1 of 2). Current admin authorizes; the new admin must then call
accept_admin to take control — so a typo'd/dead address can never gain power.
fn propose_admin(env: soroban_sdk::Env, new_admin: soroban_sdk::Address)
Cancel a scheduled upgrade before it is applied. Current admin only.
fn cancel_upgrade(env: soroban_sdk::Env)
Live value of a position: principal + currently-claimable yield.
fn position_value(env: soroban_sdk::Env, position_id: u64) -> PositionValue
The currently-scheduled upgrade (wasm hash + eta), if any.
fn pending_upgrade(env: soroban_sdk::Env) -> Option
Schedule a contract upgrade to wasm_hash. Applyable only after the timelock elapses, so
users get a window to exit before the code under their funds changes. Returns the eta.
fn schedule_upgrade(env: soroban_sdk::Env, wasm_hash: soroban_sdk::BytesN<32>) -> u64
Transfer a whole position to a new owner, carrying settled_rate (SCF #5: the new owner
can only claim yield accrued after the transfer). Also moves the PT+YT SAC balances so
the position and the tokens stay reconciled.
fn transfer_position(env: soroban_sdk::Env, position_id: u64, to: soroban_sdk::Address)
Combine equal PT+YT and redeem principal anytime (before maturity too). Auto-claims
yield first so none is silently lost, then burns amount PT + amount YT and returns
amount USDC. Returns (principal_returned, yield_claimed).
fn combine_and_redeem(
env: soroban_sdk::Env,
position_id: u64,
amount: i128,
) -> (i128, i128)
Cancel a pending admin proposal. Current admin only.
fn cancel_admin_transfer(env: soroban_sdk::Env)