30 instructions, no price feed.
Every instruction, account, error and event in the Still program, generated from its IDL. Build on it directly: /idl/still.json is the Anchor IDL of the build on mainnet (sha256 e321b004…8ddee8, checked hourly). Program BJZ2V2tZKZaS4dyhGfkuFJi8skib48dyyqnvwyLbAaP.
signswrittenreadan account ending in ? is optional
Borrowers
list(amount: u64, ask: u64, cap: u64, term_secs: i64)
Put a bag in escrow and offer it: ask USDC now for cap USDC to take it back, any time before term_secs after funding. Open to lenders for the config's listing window.
cancel
Take a listing off the market. The borrower can do it any time before funding; anyone can once the listing window has passed. The collateral goes back to the borrower.
repay
Pay the cap before the end of the term. The collateral is then the borrower's to take back with reclaim, in the same transaction or any time later.
reclaim
Take the collateral back after paying the cap.
Wallet lenders
fund_direct
A wallet funds the whole ask. The borrower receives the ask less the origination fee; the repayment, if it comes, waits in the loan's own USDC account for the lender to collect.
claim
A wallet lender takes the collateral once the term is over and the cap was not paid.
collect
A wallet lender collects a repayment.
Vault depositors
deposit(amount: u64)
Deposit USDC for vault shares at the current share price.
withdraw(shares: u64)
Redeem shares for USDC at the current share price, paid at once from the vault's free cash.
claim_recovery(index: u8)
Take this position's part of a slot's recovered collateral.
Vault managers and funders
create_vault(args: VaultArgs)
fund_vault
A vault funds the whole ask, signed by its funder key, only if the listing meets every published rule.
set_rules(rules: Rules)
Tighter rules apply at once. Looser ones wait RULE_DELAY_SECS in public and then anyone can activate them, unless the vault has no depositors yet, when there is nobody to protect and every rule applies at once.
activate_rules
set_slot(index: u8, line_cap: u64)
Give a slot a collateral mint, or change the most its line may be. Lowering applies at once (and pulls the line down with it); raising, including a new mint's first cap, waits RULE_DELAY_SECS, unless the vault has no depositors yet.
activate_slot(index: u8)
set_line(index: u8, line: u64, until: i64)
The funder posts how much the vault lends per unit of a slot's collateral, never above the manager's cap, good until until (at most MAX_LINE_TTL_SECS ahead). A stale line funds nothing.
set_vault_flags(funding_open: bool, paused: bool)
set_vault_keys(funder: pubkey)
Anyone
settle_repaid
Book a repaid vault loan once its term is over. Anyone can. Its principal and return go to the vault's cash and the performance fee is paid; the return was already counted in the share price over the term.
settle_default
Write off an unpaid vault loan once its term is over. Anyone can. It leaves the share price at once, and its collateral is credited to the shares that held it at this moment, claimable in kind. The books never wait on the collateral: an issuer can pause or freeze an xStock, and a frozen escrow must not stop the vault's deposits, withdrawals and loans. The bag itself moves into the vault with sweep_default, whenever it can move.
sweep_default
Move a written-off loan's collateral from its escrow into the vault, where its holders of record claim it. Anyone can, once the bag can move; until then the claims wait and nothing else does.
Admin
initialize(args: ParamsArgs)
propose_admin(next: pubkey)
accept_admin
set_collateral(lane: u8, enabled: bool)
Admit a mint as collateral, or stop new listings against it. Mints that take a fee on transfer, cannot move, or freeze new accounts by default are refused.
set_destinations
set_holder_perk(holder_min: u64, holder_fee_bps: u16)
Holding at least holder_min of the token when listing lowers that loan's origination fee to holder_fee_bps.
set_params(args: ParamsArgs)
set_paused(paused: bool)
Stops new listings and fundings. Everything already listed or running keeps every exit.
Errors
What a failed simulation or transaction reports as custom program error. The MCP and SDK simulations return these messages as they are.
| Code | Name | Means |
|---|---|---|
| 6000 · 0x1770 | NotUpgradeAuthority | only the program's upgrade authority can initialize |
| 6001 · 0x1771 | NotAdmin | not the admin |
| 6002 · 0x1772 | NotManager | not the vault's manager |
| 6003 · 0x1773 | NotFunder | not the vault's funder |
| 6004 · 0x1774 | BadParams | parameter out of bounds |
| 6005 · 0x1775 | Paused | new listings and fundings are paused |
| 6006 · 0x1776 | UnsupportedMint | this mint is not accepted as collateral |
| 6007 · 0x1777 | CollateralClosed | this collateral is closed to new listings |
| 6008 · 0x1778 | BadTerms | amount, ask and cap must be positive and the cap above the ask |
| 6009 · 0x1779 | BadTerm | term outside the allowed range |
| 6010 · 0x177a | WrongState | the loan is not in a state that allows this |
| 6011 · 0x177b | NotYours | only the borrower, or anyone after the listing window |
| 6012 · 0x177c | TermOver | the term is over: the cap can no longer be paid |
| 6013 · 0x177d | TermRunning | the term is still running |
| 6014 · 0x177e | WrongVault | wrong vault for this loan |
| 6015 · 0x177f | VaultClosed | the vault is closed to new loans |
| 6016 · 0x1780 | SettleFirst | an expired loan must be settled first |
| 6017 · 0x1781 | NotInVault | the vault does not lend against this collateral |
| 6018 · 0x1782 | LineStale | the vault's line for this collateral is stale |
| 6019 · 0x1783 | OverLine | the ask is above the vault's line for this much collateral |
| 6020 · 0x1784 | BelowFloor | the fixed cost is below the vault's floor |
| 6021 · 0x1785 | OverMaxLoan | the ask is above the vault's most per loan |
| 6022 · 0x1786 | OverTokenShare | the vault already lends its most against this collateral |
| 6023 · 0x1787 | NoCash | the vault does not have the cash |
| 6024 · 0x1788 | BelowBuffer | the loan would take the vault under its buffer |
| 6025 · 0x1789 | VaultFull | the vault holds its most loans |
| 6026 · 0x178a | SlotTaken | slot holds another mint |
| 6027 · 0x178b | NotYet | nothing is pending, or not yet |
| 6028 · 0x178c | OverLineCap | the line is above the manager's cap |
| 6029 · 0x178d | BelowMinimum | below the minimum |
| 6030 · 0x178e | BadAmount | bad amount |
| 6031 · 0x178f | LastHolder | the last holder cannot leave while loans are open |
| 6032 · 0x1790 | NothingOwed | nothing owed |
| 6033 · 0x1791 | Overflow | arithmetic overflow |
Events
Emitted in the program logs, so an indexer can follow every loan without polling accounts.
AdminChangedCancelledClaimedCollateralChangedCollectedDepositedDestinationsChangedFundedHolderPerkChangedLineSetListedParamsChangedPausedChangedReclaimedRecoveryClaimedRepaidRulesChangedSettledSlotChangedSweptVaultCreatedVaultFlagsVaultKeysWithdrew