Contract 9a8eb38e99807dcc0c0fb35977c40e62391a77576674cb12ecfed2d89f5a0af8

← Back to Index 📥 Download WASM

Meta

cliver 27.0.0#5a7c5fe76530bf4248477ac812fc757146b98cc4
rssdkver 26.1.0#175aa41306f383057a8cdfc84b68d931664fc34e
rsver 1.96.0

Instances

  • CBMB52N4XDAFRQRQ4MYGRPFUS3DDREWYY45VWWXEJSPITE5XH7DXEHBX

Interface

Pulls sy_amount SY from from into escrow and mints equal PT and YT, denominated in asset units: face = sy_amount * rate / WAD. At rate 1.00 this equals sy_amount. PT is the fixed principal claim; YT is the yield claim. The escrow holds the SY shares; their asset value at the current rate equals the PT face exactly at mint, which is the coverage invariant.

fn split(
    env: soroban_sdk::Env,
    from: soroban_sdk::Address,
    sy_amount: i128,
) -> Result<(i128, i128), soroban_sdk::Error>
fn config(env: soroban_sdk::Env) -> Result
fn maturity(env: soroban_sdk::Env) -> Result

PT and YT balances the holder currently owns, read from the token contracts.

fn position(
    env: soroban_sdk::Env,
    holder: soroban_sdk::Address,
) -> Result

Burns equal PT and YT (asset units) from from and returns principal in SY shares: pt_amount * WAD / rate, capped to the holder's pro-rata share of escrow under a shortfall (identical cap to redeem_at_maturity). Burning the YT settles the holder's accrued yield first (the YT burn hook banks it into the holder's claim ledger), so recombine returns only principal and the banked yield stays owed and covered by the remaining escrow. Never reverts on collateralization: a shortfall is priced as a haircut, matching Pendle.

fn recombine(
    env: soroban_sdk::Env,
    from: soroban_sdk::Address,
    pt_amount: i128,
    yt_amount: i128,
) -> Result
fn initialize(
    env: soroban_sdk::Env,
    admin: soroban_sdk::Address,
    sy_token: soroban_sdk::Address,
    pt_token: soroban_sdk::Address,
    yt_token: soroban_sdk::Address,
    maturity: u64,
) -> Result<(), soroban_sdk::Error>
fn is_matured(env: soroban_sdk::Env) -> Result

Pays holder their accrued YT yield in SY out of escrow, capped so PT principal is always senior to banked YT yield, and returns the SY amount paid. Allowed any time, including after maturity, so a holder can always collect yield earned over the term.

PT-senior surplus cap. The YT contract settles the holder and reports the banked total owed WITHOUT zeroing it (settle). The tokenizer then pays only min(owed, surplus), where surplus = max(0, escrow_shares - pt_face_reservation) and pt_face_reservation = ceil(pt_supply * WAD / rate) is the SY escrow needed to redeem every outstanding PT at its face at rate. The reservation is rounded UP, so PT is never shorted by a rounding notch and the surplus is the conservative (smaller) amount. It then consumes exactly pay from the YT ledger and pushes pay SY. Anything owed beyond pay stays banked in the YT ledger, claimable later once the rate recovers (a transient sub-stroop dip) or, under a permanent slash, capped there forever by the short escrow:

fn claim_yield(
    env: soroban_sdk::Env,
    holder: soroban_sdk::Address,
) -> Result

SY the tokenizer custodies, equal to the outstanding PT (and YT) supply.

fn escrowed_sy(env: soroban_sdk::Env) -> Result

Permissionless: before maturity, read the live SY rate and record it as the latest observation the maturity freeze may use. Every mutating operation records one as a side effect; this poke exists so anyone (a keeper, or a YT holder who wants the freeze to credit yield accrued right up to maturity) can refresh the observation on an otherwise idle market without moving tokens. Returns the observed rate.

fn observe_rate(env: soroban_sdk::Env) -> Result

The frozen maturity rate, or 0 if not yet snapshotted.

fn maturity_rate(env: soroban_sdk::Env) -> Result

PT and YT minted for sy_amount SY at the current rate, in asset units.

fn preview_split(
    env: soroban_sdk::Env,
    sy_amount: i128,
) -> Result<(i128, i128), soroban_sdk::Error>

SY shares returned for recombining equal PT and YT (asset units) at the current rate. This is the principal only; any accrued YT yield is settled separately into the holder's claim ledger. Mirrors recombine exactly, including the pro-rata escrow cap, so the preview never overquotes during a rate-regression shortfall.

Point-in-time read of the live Blend SY rate: if the rate moves between this quote and submission, the executed recombine share count can differ. The underlying value redeemed does not — recombine always returns pt_face worth of principal regardless of rate, so a moved rate changes the SY share count, not what it's worth. recombine has no on-chain min_sy_out floor by design; a caller needing an exact share count should compare this preview to its bound client-side before submitting.

fn preview_recombine(
    env: soroban_sdk::Env,
    pt_amount: i128,
    yt_amount: i128,
) -> Result

After maturity, burns pt_amount PT (asset units) from from and returns principal in SY shares: pt_amount * WAD / rate, capped to the holder's pro-rata share of escrow.

Insolvency guard: if a rate regression (negative yield, a slash) has left the escrow unable to cover all PT principal, the payout is capped to escrow_shares * pt_amount / pt_supply, so PT holders share the shortfall pro-rata rather than letting the first redeemers drain the escrow at the expense of the last. When solvent, the ideal payout is the smaller of the two, so this pays principal in full. Capping preserves the escrow/PT ratio, keeping every later redeemer's share fair.

The rate read here is the current SY rate; Phase 3 step 9 snapshots a maturity rate so post-maturity rate moves do not change redemption.

fn redeem_at_maturity(
    env: soroban_sdk::Env,
    from: soroban_sdk::Address,
    pt_amount: i128,
) -> Result

Permissionless: after maturity, snapshot and return the SY rate used for all redemption. Any caller may poke this so the maturity rate is captured promptly; redemption also snapshots it lazily on first use. Idempotent once set. The snapshot is the last rate observed at or before maturity, never a live post-maturity read (see effective_rate), so the timing of this call cannot move value between PT and YT.

fn freeze_maturity_rate(env: soroban_sdk::Env) -> Result

Imports

WebAssembly Text (WAT) ▶