Developers
Simulated yield
The per-Position yield model behind '1 month = 10 min'.
The rule
Every Position earns, from the moment it opens, linear yield on its own Principal (no compounding), on every chain:
yield(t) = principal * apy * simulated_elapsed(t) / year
simulated_elapsed = real_elapsed * speedup // speedup = 4,380apy is the Position's own rate_bps, set at open from the pool. A speedup of 4,380 makes one simulated month (1/12 year) take exactly 600 real seconds, and an Advance of N months, which is principal * apy * N / 12, is repaid in exactly N * 10 minutes for every Position. The decision and the rejected alternatives (a compounding rate would reach about 7,000 SOL per simSOL by 12 October and overflow u64 within weeks) are in ADR 0005 and docs/yield-model.md.
| Token | Chain | Yearly rate | Speedup |
|---|---|---|---|
| simSOL (sim_lst) | Solana devnet | 7% | 4,380x |
| simETH (SimLST) | Ethereum Hoodi | 5% | 4,380x |
| simHYPE (SimLST) | HyperEVM testnet | 5% | 4,380x |
How yield becomes real tokens
The exchange rate of the LST is constant. Yield is minted into each Position's vault instead of read off a growing rate.
- Solana.
accrue_native_yield(permissionless; the keeper cranks it) computesprincipal * apy_bps * dt * speedup / (10_000 * 31_536_000)SOL units since the custody'slast_accrual_ts, converts to shares at the constant rate, and CPIssim_lst::mint_yield. That instruction can be called only by the recorded yield authority, the tesoro_core PDA["yield"], which the sim_lst admin registered once. If the floor gives zero shares, the timestamp does not advance, so time carries over. Accrual stops at Unlock. - EVM.
SimLSThas a frozen rate and aminter(the vault). The vault'saccrue(id)runs at the start ofreportYieldand mints the same formula into itself. The real-wstETH vault has no minter and keeps real wstETH yield.
Custody accounting is unchanged: accrued = vault_shares * rate - principal + redeemed. Because the rate is constant, accrued grows only through minting, so every unit of accrued yield is a share in the vault and a Redeem is always covered. Tokens sent straight into a vault are not yield (audit F-05).
The reserve
Minted yield shares are not backed by deposited SOL or ETH. Withdrawals are paid from a reserve the team funds (fund_reserve on Solana, ETH sent to SimLST). While Debt is outstanding, a Position's total reserve claim is bounded by principal * apy * horizon_months / 12; at 7% and a one-month Advance that is 0.58% of Principal. A Position that stays Locked after its Debt reaches zero keeps accruing, and that free yield is drawn from the reserve only if the owner withdraws it. Faucets mint unbacked test tokens at 10 per hour per address.
Where it lives
- One function in the app,
app/src/lib/chain/yield.ts, gives accrued yield from(principal, rateBps, elapsed, speedup). The quote, Unlock Estimate, projected Debt and charts all use it. programs/sim_lst,programs/tesoro_core/src/ledger/native.rs,contracts/src/SimLST.sol,contracts/src/PositionVault.sol.
The security consequences (faucet sybils, reserve drain, admin-set rates) are accepted for testnets and listed in Security.