Developers
Program reference
Accounts, PDA seeds, instructions, events and error codes of the Shear Anchor program.
Shear is one Anchor 0.31.1 program. It holds TSLAx in Token-2022 accounts, issues vault shares and calls as legacy SPL tokens, runs the weekly USDC auction and settles each round against a Pyth close mark. This page lists its on-chain interface. The TypeScript SDK builds the same instructions, and the indexer API serves the decoded accounts and events.
Program ID#
The program ID is GG8Db3XMAfAaa4RT38e5uaeFSDjztEyaATpR6B3AxMcn. The IDL ships with the SDK as idl/shear.json; its address field carries the same ID.
Pinned addresses#
The program compares these addresses against compiled constants, in account constraints or in the handler, and rejects any other mint, oracle owner or feed. The SDK exports them under the names below.
| SDK constant | Address | Role |
|---|---|---|
| TSLA_X_MINT | XsDoVfqeBukxuZHWhdvWHBhgEHjGNst4MLodqsJHzoB | TSLAx mint. Token-2022, 8 decimals. Collateral, deposits and call payouts. |
| USDC_MINT | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v | USDC mint. Legacy SPL Token, 6 decimals. Bid escrow and premium. |
| PYTH_RECEIVER | rec2HHDDnjLfj4kE7VyEtFA1HPGQLK33259532cRyHp | Pyth receiver program. Price update accounts must be owned by it. |
| TSLA_FEED | 16dad506d7db8da01c87581c87ca897a012a153557d4d578c3b9c9e1bc0632f1 | Pyth feed ID of the regular-session TSLA price, 32 bytes in hex. |
| TOKEN_2022_PROGRAM_ID | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb | Token program of every TSLAx account, passed as asset_program. |
| TOKEN_PROGRAM_ID | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | Token program of shares, calls and USDC, passed as token_program. |
The program also pins the issuer keys on the TSLAx mint. Every instruction that reads the mint checks them, together with its extension set. See corporate actions and trust.
| Program constant | Address | Checked as |
|---|---|---|
| MINT_AUTHORITY | 7pt9tkctJPK7PPNQJ77GKg8ZffSF6QxoMiCFYHxrtaCj | Mint authority of TSLAx. |
| PAUSE_AUTHORITY | JDq14BWvqCRFNu1krb12bcRpbGtJZ1FLEakMw6FdxJNs | Freeze authority and Pausable extension authority. |
| ISSUER | 5aMNNLQJwAEeoemTEMkv5NVjqKwvvefRYCQ5Z67HFvEq | Confidential-transfer authority, permanent delegate, transfer-hook authority, metadata-pointer authority and token-metadata update authority. |
| MULTIPLIER_AUTHORITY | S7vYFFWH6BjJyEsdrPQpqpYTqLTrPRK6KW3VwsJuRaS | Authority of the ScaledUiAmount multiplier. |
The mint must carry exactly the Token-2022 extensions 4, 6, 12, 14, 18, 19, 25 and 26 (ConfidentialTransferMint, DefaultAccountState, PermanentDelegate, TransferHook, MetadataPointer, TokenMetadata, ScaledUiAmount, Pausable), with confidential auto-approve off, no auditor, no transfer-hook program and the token not paused.
Units#
All amounts are unsigned integers in base units. The program uses no floating point. TSLAx amounts are raw Token-2022 amounts, before the mint’s ScaledUiAmount multiplier.
| Quantity | Scale | One unit | Fields |
|---|---|---|---|
| TSLAx | 8 decimals | 100_000_000 = 1 TSLAx | amount, deposit, offered, snapshot_nav, payouts |
| Vault shares | 8 decimals | 100_000_000 = 1 share | shares, min_shares, pending_withdraw, withdraw |
| Calls | 8 decimals | 100_000_000 = 1 call on 1 TSLAx | quantity, sold, allocation, claimed_options |
| USDC | 6 decimals | 1_000_000 = 1 USDC | escrow, charge, premium_total, premium_credit |
| Premium price | 6 decimals per whole call | 1_000_000 = 1 USDC per call | limit_premium_micro, clearing, reserve_premium_micro |
| USD mark | 6 decimals per whole TSLAx | 1_000_000 = 1 USD | strike, settlement |
| Multiplier | 9 decimals | 1_000_000_000 = 1.0 | entry_multiplier, close_multiplier |
| Premium accumulator | 18 decimals | 10^18 = 1 micro-USDC per share atom | premium_index, premium_fraction |
| Basis points | 1/10,000 | 500 = 5% | otm_bps, max_confidence_bps |
| Time | Unix seconds | 1790971200 = 2026-10-02 20:00 UTC | open, close, expiry, auction_end, observed_at |
One call atom covers one raw TSLAx atom. A USD mark is the value of one whole raw TSLAx token: the Pyth TSLA price at 6 decimals times the mint multiplier. See oracle.
Constants#
| Constant | Value | Meaning |
|---|---|---|
MAX_BIDS | 16 | Bids per round. |
DISPUTE_SECONDS | 900 | Window after observe_expiry for challenge_expiry; settle_round waits for it to pass. |
| Observation window | 3600 | observe_expiry and challenge_expiry run from expiry to expiry + 3600. |
| Timeout | 604800 | timeout_settle opens 7 days after expiry. |
| Strike mark age | 60 | start_round needs a Pyth update published within the last 60 seconds. |
| Corporate-action window | 900 | Mint reads fail within 900 seconds of a scheduled multiplier activation. |
PREMIUM_SCALE | 1_000_000_000_000_000_000 | Scale of the premium accumulator. |
MULTIPLIER_SCALE | 1_000_000_000 | Scale of the multiplier. |
UNSTAKE_SECONDS | 604800 | Wait from request_unstake to the earliest withdraw_stake. |
STAKE_DECIMALS | 6 | Decimals the bidder stake mint must have. |
Accounts#
Eight account types. Each starts with Anchor’s 8-byte discriminator. Field names below are the Rust names; decoded TypeScript objects use camelCase, so share_mint becomes shareMint.
Vault#
One per underlying mint, created by initialize. The vault PDA is the authority of the share mint, custody and premium accounts.
| Field | Type | Meaning |
|---|---|---|
| admin | Pubkey | Signer of initialize, or the account that later accepted the role. Registers sessions, authorizes bidders and sets the bidder stake. |
| underlying | Pubkey | TSLAx mint. |
| share_mint | Pubkey | Share mint. Legacy SPL Token, 8 decimals. |
| custody | Pubkey | Token-2022 TSLAx account holding assets between rounds. |
| premium | Pubkey | USDC account holding auction premium until claimed. |
| bump | u8 | PDA bump. |
| config | VaultConfig | Parameters set at initialize. |
| premium_index | u128 | Cumulative premium, micro-USDC per share atom scaled by 10^18. |
| round_index | u64 | Index of the latest round. 0 before the first round. |
| active | bool | True from start_round until close_round. |
| pending_admin | Pubkey | Named by set_admin; becomes admin when it signs accept_admin. Default key when none. |
VaultConfig is fixed at initialize. See parameters.
| Field | Type | Bounds | Meaning |
|---|---|---|---|
| otm_bps | u16 | 100 to 5000 | Strike offset above the entry mark. |
| max_confidence_bps | u16 | 1 to 500 | Largest accepted Pyth confidence, as a share of price. |
| auction_seconds | u32 | 300 to 7200 | Auction length. |
| reserve_premium_micro | u64 | above 0 | Lowest bid, micro-USDC per whole call. |
Session#
One regular market session, committed by the vault admin with register_session. Sessions are immutable. See calendar.
| Field | Type | Meaning |
|---|---|---|
| vault | Pubkey | Vault the session belongs to. |
| open | i64 | Session open, Unix seconds. |
| close | i64 | Session close, Unix seconds. Also a PDA seed. |
| calendar_hash | [u8; 32] | Non-zero commitment to the calendar the session came from. |
| weekly_expiry | bool | Whether a round may expire at this close. |
Bidder#
One per wallet per vault, created by authorize_bidder or stake_bidder. A wallet can bid when allowed is true, or when it holds a stake with unlock_at 0. Approval is checked first, so an approved wallet’s bids never count against its stake. See bidder stake.
| Field | Type | Meaning |
|---|---|---|
| vault | Pubkey | Vault. |
| owner | Pubkey | Bidder wallet. |
| allowed | bool | Approved by the vault admin. |
| stake | u64 | Stake mint atoms held in the escrow at ["stake", bidder]. 0 without a stake. |
| unlock_at | i64 | 0 while the stake is active. After request_unstake, the earliest withdraw_stake, Unix seconds. |
| open_bids | u16 | Bids placed through the stake and not yet claimed. |
StakeConfig#
One per vault, created by the first set_bidder_stake. The mint is fixed by that call.
| Field | Type | Meaning |
|---|---|---|
| vault | Pubkey | Vault. |
| mint | Pubkey | Stake mint: legacy SPL Token, 6 decimals, no mint or freeze authority. |
| amount | u64 | Atoms each new stake locks. 0 stops new stakes; earlier stakes keep what they locked. |
| bump | u8 | PDA bump. |
Position#
One per owner per vault. Its shares sit in a vault-owned token account at ["position-shares", position] and move only through program instructions. See premium.
| Field | Type | Meaning |
|---|---|---|
| vault | Pubkey | Vault. |
| owner | Pubkey | Owner wallet. |
| shares | u64 | Share atoms held. Must equal the position share account balance. |
| pending_withdraw | u64 | Share atoms locked by an open withdrawal ticket. |
| premium_index | u128 | Vault premium_index at the last checkpoint. |
| premium_credit | u64 | Credited premium not yet claimed, micro-USDC. |
| premium_fraction | u128 | Remainder below one micro-USDC, scaled by 10^18. |
Round#
One per weekly round, created by start_round. The round PDA is the authority of the round’s collateral, deposits, reserve, bid escrow and call mint.
| Field | Type | Meaning |
|---|---|---|
| vault | Pubkey | Vault. |
| index | u64 | Round number, from 1. |
| bump | u8 | PDA bump. |
| phase | Phase | Current phase. |
| expiry | i64 | Close of the expiry session, Unix seconds. The settlement mark is the second before. |
| auction_end | i64 | End of bidding: start time plus auction_seconds. |
| strike | u64 | Strike, micro-USD per whole TSLAx. |
| entry_multiplier | u64 | TSLAx multiplier at start_round, 9 decimals. |
| offered | u64 | TSLAx atoms moved into collateral. Equal to the call atoms offered. |
| sold | u64 | Call atoms allocated by the auction. |
| clearing | u64 | Clearing premium, micro-USDC per whole call. 0 when nothing sold. |
| premium_total | u64 | Premium charged to all bids, micro-USDC. |
| option_mint | Pubkey | Call mint of this round. |
| bid_count | u8 | Bids placed, at most 16. |
| claimed_bids | u8 | Bids settled through claim_bid. |
| bids | [BidRecord; 16] | Bid book. Entries past bid_count are zeroed. |
| pending_tickets | u32 | Tickets opened and not yet processed. |
| settlement | u64 | Settlement mark: Pyth close times close_multiplier, micro-USD per whole TSLAx. |
| close_multiplier | u64 | TSLAx multiplier at the close second, 9 decimals. |
| observed_at | i64 | Time observe_expiry ran. The dispute window starts here. |
| oracle_publish | i64 | Publish time of the observed Pyth update. |
| oracle_price | i64 | Raw Pyth price of the observed update. |
| oracle_exponent | i32 | Pyth exponent of the observed update. |
| reserve_total | u64 | TSLAx atoms moved to the reserve at settlement. |
| claimed_options | u64 | Call atoms burned through claim_option. |
| snapshot_nav | u64 | Custody TSLAx after settlement. Tickets use it. |
| snapshot_supply | u64 | Share supply at settlement. Tickets use it. |
| fallback | bool | True when timeout_settle settled the round. |
BidRecord is one entry of Round.bids:
| Field | Type | Meaning |
|---|---|---|
| owner | Pubkey | Bidder wallet. |
| quantity | u64 | Call atoms bid for. |
| limit | u64 | Limit premium, micro-USDC per whole call. |
| allocation | u64 | Call atoms filled. Set by finalize_auction. |
| charge | u64 | Premium owed, micro-USDC. Set by finalize_auction. |
Ticket#
One per owner per round. Holds at most one queued deposit and one queued withdrawal. See deposits.
| Field | Type | Meaning |
|---|---|---|
| round | Pubkey | Round. |
| owner | Pubkey | Owner wallet. |
| position | Pubkey | Owner’s position. |
| initialized | bool | Set on first use. Counts toward pending_tickets. |
| processed | bool | Set by process_ticket. |
| deposit | u64 | TSLAx atoms queued. |
| min_shares | u64 | Fewest share atoms the owner accepts for the deposit. |
| withdraw | u64 | Share atoms queued for withdrawal. |
Bid#
One per bidder per round. Receipt for the escrow; the bid terms live in Round.bids.
| Field | Type | Meaning |
|---|---|---|
| round | Pubkey | Round. |
| owner | Pubkey | Bidder wallet. |
| index | u8 | Slot in Round.bids. |
| escrow | u64 | USDC escrowed, micro-USDC. |
| claimed | bool | Set by claim_bid. |
| staked | bool | Placed through a stake rather than an approval. Its claim lowers Bidder.open_bids. |
Phase#
Borsh enum on Round.phase. The decoded TypeScript value is an object with one key, such as { Active: {} }. See settlement.
| Variant | Index | Meaning | Leaves by |
|---|---|---|---|
| Auction | 0 | Bids accepted until auction_end. | finalize_auction to Active. |
| Active | 1 | Calls outstanding until expiry. | observe_expiry to Observed. settle_round to Settled when nothing sold. timeout_settle to Settled. |
| Observed | 2 | Close mark recorded; dispute window open. | challenge_expiry to Disputed. settle_round to Settled. |
| Settled | 3 | Reserve set aside and NAV snapshot taken. Tickets process; calls are claimable. | close_round to Closed. |
| Closed | 4 | Round finished and vault inactive. Calls stay claimable. | Final. |
| Disputed | 5 | Conflicting authenticated close marks. | timeout_settle to Settled. |
PDAs#
Seeds are a UTF-8 string followed by 32-byte public keys or little-endian integers: index as u64, close as i64. Seeds below are exactly those in the account contexts.
| Account | Seeds | Holds |
|---|---|---|
| Vault | "vault", underlying_mint | Vault state. |
| Share mint | "shares", vault | Legacy SPL mint, 8 decimals, mint authority vault. |
| Custody | "custody", vault | Token-2022 TSLAx account, authority vault. |
| Premium | "premium", vault | USDC account, authority vault. |
| Session | "session", vault, close (i64 LE) | Session state. |
| Bidder | "bidder", vault, owner | Approval and stake of one wallet. |
| Stake escrow | "stake", bidder | Stake mint token account, authority bidder. |
| Stake config | "stake-config", vault | Stake mint and amount. |
| Position | "position", vault, owner | Position state. |
| Position shares | "position-shares", position | Share token account, authority vault. |
| Round | "round", vault, index (u64 LE) | Round state. |
| Collateral | "collateral", round | Token-2022 TSLAx account under the calls, authority round. |
| Deposits | "deposits", round | Token-2022 TSLAx account for queued deposits, authority round. |
| Reserve | "reserve", round | Token-2022 TSLAx account paying calls after settlement, authority round. |
| Bid escrow | "bids", round | USDC account, authority round. |
| Call mint | "options", round | Legacy SPL mint, 8 decimals, mint authority round. |
| Ticket | "ticket", round, owner | Queue entry. |
| Bid | "bid", round, owner | Bid receipt. |
import { PublicKey } from '@solana/web3.js';
const PROGRAM = new PublicKey('GG8Db3XMAfAaa4RT38e5uaeFSDjztEyaATpR6B3AxMcn');
const TSLAX = new PublicKey('XsDoVfqeBukxuZHWhdvWHBhgEHjGNst4MLodqsJHzoB');
const pda = (...seeds: Buffer[]) => PublicKey.findProgramAddressSync(seeds, PROGRAM)[0];
const u64 = (n: bigint) => { const b = Buffer.alloc(8); b.writeBigUInt64LE(n); return b; };
const vault = pda(Buffer.from('vault'), TSLAX.toBuffer());
const round = pda(Buffer.from('round'), vault.toBuffer(), u64(1n));
const ticket = pda(Buffer.from('ticket'), round.toBuffer(), owner.toBuffer());For the pinned TSLAx mint the vault-level addresses are:
| Account | Address |
|---|---|
| Vault | 9Q5nHgxW9864oE6q8JLjp6GioUkkQF1f3EsUcSgVYru9 |
| Share mint | E61GhHfpx832wdG5BneKCzsujGP8au7FfKcaUyvv3NR7 |
| Custody | JAVt8HP5aphQPnxisZhXedRHeRCREdcQL2mzUZKDDELe |
| Premium | 7N1ieKGMaJXfhuZnJd5wSWx343iahVLZRT9EXDafd98j |
Instructions#
Names here are the Rust snake_case names. The Anchor TypeScript client and ShearClient.instruction use camelCase for instruction, argument and account names: fund_ready is fundReady, min_shares is minShares, position_shares is positionShares. Each table lists the checks in the handler. Account constraints (PDA seeds, has_one, token mints and authorities) apply as well; account lists are under instruction accounts.
Instructions marked mint check read the TSLAx mint. They fail with UnsupportedMint or UnsupportedExtension if its authorities or extensions differ from the pinned set, with IssuerPaused while the issuer has paused the token, and with CorporateActionWindow within 900 seconds of a scheduled multiplier activation. observe_expiry reads the multiplier at expiry - 1 and also fails if an activation falls between that second and the observation. See corporate actions.
Owner-signed#
Signed by the position owner, who pays rent for any account the instruction creates. claim_option is signed by whoever holds the calls and needs no position.
| Instruction | Arguments | Requires | Effect |
|---|---|---|---|
| create_position | — | No position for this owner yet. | Creates the Position and its share token account, starting at the current premium_index. |
| fund_ready | amount: u64, min_shares: u64 | Vault inactive. amount above 0. Share supply is 0 or custody above 0. Minted shares above 0 and at least min_shares. Mint check. | Moves amount TSLAx from source to custody and mints shares at the custody ratio. |
| redeem_ready | shares: u64, min_assets: u64 | Vault inactive. shares above 0 and at most the position’s shares. No pending withdrawal. Assets at least min_assets. Mint check. | Burns shares and sends their pro-rata custody TSLAx to destination. |
| queue_deposit | amount: u64, min_shares: u64 | amount above 0. Vault active and round is its current round, in Auction, Active or Observed. No deposit on this ticket yet. Mint check. | Moves amount TSLAx into the round’s deposits account and records it on the owner’s ticket. |
| request_withdrawal | shares: u64 | shares above 0. Same round condition as queue_deposit. No withdrawal on the ticket or position yet. shares at most the position’s shares. | Locks shares on the position and records them on the owner’s ticket. |
| transfer_shares | shares: u64 | shares above 0. Recipient position differs from the sender. shares at most sender shares minus pending_withdraw. Any phase. | Moves shares to another position of the vault, checkpointing premium on both. |
| claim_premium | — | Credited premium above 0 after the checkpoint. Any phase. | Checkpoints the position and sends its whole premium_credit in USDC to destination. |
| claim_option | quantity: u64 | Round Settled or Closed. quantity above 0. claimed_options + quantity at most sold. Mint check. | Burns quantity calls and pays payout(claimed + quantity) - payout(claimed) TSLAx from the reserve; after a fallback settlement, quantity atoms. |
- A second deposit on the same ticket fails with
DuplicateRequest; a second withdrawal withInvalidAmount. min_shareson a queued deposit is checked against the settlement snapshot inprocess_ticket. A deposit that would mint fewer shares is refunded to the owner.- A queued withdrawal keeps earning the round’s premium. Its shares stay locked against
transfer_sharesuntil the ticket is processed. - Between owners, shares move only through
transfer_shares, and the recipient must already have a position. Calls are ordinary SPL tokens and move freely.
Bidder#
Signed by the bidder wallet, which pays rent for what it creates. A wallet bids after the vault admin approves it with authorize_bidder, or after it locks the bidder stake with stake_bidder. See bidding and bidder stake.
| Instruction | Arguments | Requires | Effect |
|---|---|---|---|
| place_bid | quantity: u64, limit_premium_micro: u64 | Round in Auction and before auction_end. Bidder allowed, or holding a stake with unlock_at 0. quantity above 0 and at most offered. Limit at least reserve_premium_micro. Fewer than 16 bids. No earlier bid from this wallet in the round. | Creates the Bid and escrows ceil(quantity × limit_premium_micro / 10^8) USDC from source. A bid through the stake sets staked and raises open_bids. |
| claim_bid | — | Round past Auction. Bid not claimed. Signer is the bid owner. | Refunds escrow minus charge to refund in USDC and mints the allocated calls to options. Lowers open_bids for a staked bid. |
| stake_bidder | — | StakeConfig amount above 0. Wallet holds no stake in this vault. | Creates the Bidder if needed and the stake escrow, and moves amount of the stake mint from source into it. |
| request_unstake | — | Stake above 0 and unlock_at 0. | Sets unlock_at to now plus UNSTAKE_SECONDS. The stake no longer qualifies the wallet to bid. |
| withdraw_stake | — | Stake above 0 and unlock_at set. Now at or after unlock_at. open_bids is 0. | Sends the whole escrow to destination, closes the escrow to the signer and clears the stake. |
Permissionless#
Any wallet can send these; the keeper sends them on schedule. Only start_round names a signer, keeper, which pays rent for the new round accounts. The others need only a fee payer.
| Instruction | Arguments | Requires | Effect |
|---|---|---|---|
| start_round | index: u64 | Vault inactive. index equals round_index + 1. Share supply above 0. Now inside the strike session. Expiry session is a weekly expiry closing 1 to 8 days from now. Fully verified Pyth TSLA update published inside the strike session within the last 60 seconds, confidence within limit. Auction ends no later than the strike session close. Custody above 0. Mint check. | Creates the round and its five token accounts, sets the strike, moves all custody TSLAx to collateral and opens the auction. |
| finalize_auction | — | Round in Auction. Now at or after auction_end. | Clears the auction, moves the charged premium to the vault premium account, raises premium_index and sets the round Active. |
| observe_expiry | — | Round Active with sold above 0. Now within one hour after expiry. Fully verified Pyth update published at exactly expiry - 1, previous publish time earlier, confidence within limit. Mint check. | Records the settlement mark and sets the round Observed. |
| challenge_expiry | — | Round Observed. Within 900 seconds of observed_at and one hour of expiry. A valid update for the same second with a different price or exponent. | Sets the round Disputed. |
| settle_round | — | Round Active with sold 0, or Observed for at least 900 seconds. Collateral at least offered. Mint check. | Moves the call liability to the reserve, returns the rest to custody, records the NAV snapshot and sets the round Settled. |
| timeout_settle | — | Round Active or Disputed. Now at least expiry plus 7 days. Collateral at least offered. Mint check. | Reserves one TSLAx atom per sold call atom, returns the rest, sets fallback and sets the round Settled. |
| process_ticket | — | Round Settled. Ticket initialized and not processed. Mint check. | Pays the withdrawal at the snapshot ratio, then admits the deposit at the snapshot ratio or refunds it below min_shares. |
| close_round | — | Round Settled. pending_tickets is 0. Round is the vault’s current round. | Sets the round Closed and the vault inactive. |
| reclaim_option_dust | — | Round Closed. Every bid claimed. claimed_options equals sold. Call supply 0. Reserve balance 0. | Verifies that the round’s call liability is extinguished. Moves no tokens. |
Admin#
initialize is signed by the program’s upgrade authority, which becomes the vault admin. accept_admin is signed by the account set_admin named. The rest are signed by the vault admin, which pays rent for what they create. See trust, calendar and governance.
| Instruction | Arguments | Requires | Effect |
|---|---|---|---|
| initialize | config: VaultConfig | Signer is the upgrade authority recorded in the program’s ProgramData. USDC mint has 6 decimals. otm_bps 100 to 5000, max_confidence_bps 1 to 500, auction_seconds 300 to 7200, reserve_premium_micro above 0. Mint check. | Creates the vault, share mint, custody and premium accounts. |
| register_session | open: i64, close: i64, calendar_hash: [u8; 32], weekly_expiry: bool | Signer is the vault admin. close more than one hour away. open before close. Length 12,600 to 23,400 seconds. close falls on a Monday to Friday UTC date. Hash not all zero. No session with this close yet. | Creates an immutable Session. |
| authorize_bidder | allowed: bool | Signer is the vault admin. | Creates or updates the Bidder entry for owner and sets allowed. Leaves any stake as it is. |
| set_admin | new_admin: Pubkey | Signer is the vault admin. | Sets pending_admin. The default key cancels a pending handover. |
| accept_admin | — | Signer is pending_admin, which is not the default key. | Makes the signer the vault admin and clears pending_admin. |
| set_bidder_stake | amount: u64 | Signer is the vault admin. On the first call, mint is a legacy SPL mint with 6 decimals, supply above 0, no mint authority and no freeze authority; afterwards it must be the recorded mint. | Creates StakeConfig if needed and sets amount for new stakes. |
Instructions that create an account with init fail when it already exists: a second create_position, a second place_bid from one wallet in a round, a second register_session for the same close, or a second stake_bidder while the escrow is open.
Formulas#
Integer formulas in the handlers. Division rounds as listed; checked arithmetic fails with Arithmetic on overflow.
| Value | Formula | Rounding |
|---|---|---|
| Pyth mark | price scaled from its exponent to 6 decimals | Down. Exponent -12 to 0; result 1 to 10^15. |
| Effective price | mark × multiplier / 10^9 | Down. |
| Strike | effective_price × (10000 + otm_bps) / 10000 | Up. |
| Bid escrow | quantity × limit_premium_micro / 10^8 | Up. |
| Bid charge | allocation × clearing / 10^8 | Up. |
| Premium index step | premium_total × 10^18 / share_supply | Down. |
| Premium checkpoint | (shares × (index - position_index) + fraction) / 10^18 | Down, added to premium_credit; the remainder stays in premium_fraction. |
| Call payout | q × (settlement - strike) / settlement, or 0 if settlement ≤ strike | Down. |
| fund_ready shares | amount if supply is 0, else amount × supply / custody | Down. |
| redeem_ready assets | shares × custody / supply | Down. |
| Ticket withdrawal | withdraw × snapshot_nav / snapshot_supply | Down. |
| Ticket deposit shares | deposit × snapshot_supply / snapshot_nav, or 0 if NAV is 0 | Down. |
Auction clearing sorts bids by limit, highest first, with ties broken by ascending owner public-key bytes, and fills them in order up to offered. If total demand exceeds offered, the clearing premium is the limit of the last bid that received a fill; otherwise it is reserve_premium_micro. Every filled bid pays the clearing premium. With nothing sold, clearing is 0.
Calls are claimed against cumulative liability: a claim of q pays payout(claimed + q) - payout(claimed). Any split of claims pays out exactly the reserve, and claim order moves an individual payout by at most one atom.
Instruction accounts#
Accounts in IDL order. Pass every one; the SDK builds with accountsStrict and resolves none. Token accounts named source, destination, refund and options belong to the signer, except the destination of process_ticket, which belongs to the ticket owner.
| Instruction | Signer | Accounts |
|---|---|---|
| initialize | admin | admin, self_program, program_data, underlying_mint, usdc_mint, vault, share_mint, custody, premium, asset_program, token_program, system_program |
| register_session | admin | admin, vault, session, system_program |
| authorize_bidder | admin | admin, vault, owner, bidder, system_program |
| set_admin | admin | admin, vault |
| accept_admin | new_admin | new_admin, vault |
| set_bidder_stake | admin | admin, vault, stake_config, mint, system_program |
| stake_bidder | owner | owner, vault, stake_config, mint, bidder, escrow, source, token_program, system_program |
| request_unstake | owner | owner, vault, bidder |
| withdraw_stake | owner | owner, vault, bidder, escrow, destination, token_program |
| create_position | owner | owner, vault, share_mint, position, position_shares, token_program, system_program |
| fund_ready | owner | owner, vault, underlying_mint, share_mint, custody, position, position_shares, source, asset_program, token_program |
| redeem_ready | owner | owner, vault, underlying_mint, share_mint, custody, position, position_shares, destination, asset_program, token_program |
| queue_deposit | owner | owner, vault, round, position, ticket, underlying_mint, deposits, source, asset_program, system_program |
| request_withdrawal | owner | owner, vault, round, position, ticket, underlying_mint, deposits, source, asset_program, system_program |
| transfer_shares | owner | owner, vault, share_mint, sender, recipient, sender_shares, recipient_shares, token_program |
| claim_premium | owner | owner, vault, position, premium, destination, token_program |
| claim_option | owner | owner, vault, round, underlying_mint, option_mint, options, reserve, destination, asset_program, token_program |
| place_bid | owner | owner, vault, round, bidder, bid, bids, source, token_program, system_program |
| claim_bid | owner | owner, round, bid, bidder, bids, refund, option_mint, options, token_program |
| start_round | keeper | keeper, vault, underlying_mint, usdc_mint, share_mint, custody, strike_session, expiry_session, price_update, round, collateral, deposits, reserve, bids, option_mint, asset_program, token_program, system_program |
| finalize_auction | — | vault, round, share_mint, bids, premium, token_program |
| observe_expiry | — | vault, round, underlying_mint, price_update |
| challenge_expiry | — | vault, round, underlying_mint, price_update |
| settle_round | — | vault, round, underlying_mint, share_mint, custody, collateral, reserve, asset_program |
| timeout_settle | — | vault, round, underlying_mint, share_mint, custody, collateral, reserve, asset_program |
| process_ticket | — | vault, round, ticket, position, underlying_mint, share_mint, custody, deposits, position_shares, destination, asset_program, token_program |
| close_round | — | vault, round |
| reclaim_option_dust | — | vault, round, underlying_mint, option_mint, reserve, custody, asset_program |
request_withdrawalshares its account context withqueue_deposit, so it takesdepositsand a TSLAxsourcealthough it moves no tokens.program_datais the program’s ProgramData account under the upgradeable BPF loader.price_updateis a PythPriceUpdateV2account owned by the receiver, with full verification. See oracle.strike_sessionandexpiry_sessionare Session PDAs of the vault, derived from theirclose.- In
transfer_shares,senderis the signer’s position andrecipientthe position of the receiving owner.
Events#
Anchor events, written as Program data: log lines. Decode them with the IDL or with decodeEvent from the SDK. Units follow the account fields.
| Event | Emitted by | Fields |
|---|---|---|
| VaultInitialized | initialize | vault: Pubkey, admin: Pubkey |
| SessionRegistered | register_session | vault: Pubkey, open: i64, close: i64, calendar_hash: [u8; 32] |
| SharesFunded | fund_ready | vault: Pubkey, owner: Pubkey, assets: u64, shares: u64 |
| ReadyRedeemed | redeem_ready | vault: Pubkey, owner: Pubkey, shares: u64, assets: u64 |
| RoundStarted | start_round | vault: Pubkey, round: Pubkey, index: u64, strike: u64, expiry: i64, offered: u64 |
| DepositQueued | queue_deposit | round: Pubkey, owner: Pubkey, amount: u64 |
| WithdrawalQueued | request_withdrawal | round: Pubkey, owner: Pubkey, shares: u64 |
| BidPlaced | place_bid | round: Pubkey, owner: Pubkey, quantity: u64, limit: u64 |
| AuctionFinalized | finalize_auction | round: Pubkey, sold: u64, clearing: u64, premium: u64 |
| BidClaimed | claim_bid | round: Pubkey, owner: Pubkey, options: u64, refund: u64 |
| ExpiryObserved | observe_expiry | round: Pubkey, settlement: u64, publish_time: i64, dispute_until: i64 |
| ExpiryDisputed | challenge_expiry | round: Pubkey |
| RoundSettled | settle_round | round: Pubkey, reserved: u64, nav: u64, supply: u64 |
| OracleFailureSettled | timeout_settle | round: Pubkey, reserved: u64, nav: u64, supply: u64 |
| TicketProcessed | process_ticket | round: Pubkey, owner: Pubkey, withdrawal: u64, deposit: u64, minted_shares: u64, deposit_refunded: bool |
| RoundClosed | close_round | round: Pubkey, index: u64 |
| PremiumClaimed | claim_premium | vault: Pubkey, owner: Pubkey, amount: u64 |
| OptionClaimed | claim_option | round: Pubkey, owner: Pubkey, quantity: u64, payout: u64 |
| AdminProposed | set_admin | vault: Pubkey, admin: Pubkey, pending: Pubkey |
| AdminAccepted | accept_admin | vault: Pubkey, admin: Pubkey |
| BidderStakeSet | set_bidder_stake | vault: Pubkey, mint: Pubkey, amount: u64 |
| BidderStaked | stake_bidder | vault: Pubkey, owner: Pubkey, amount: u64 |
| UnstakeRequested | request_unstake | vault: Pubkey, owner: Pubkey, amount: u64, unlock_at: i64 |
| StakeWithdrawn | withdraw_stake | vault: Pubkey, owner: Pubkey, amount: u64 |
create_position, authorize_bidder, transfer_shares and reclaim_option_dust emit no event. In TicketProcessed, minted_shares is 0 when deposit_refunded is true, and deposit_refunded is also true for a ticket that queued no deposit.
Errors#
Custom errors start at 6000 in declaration order and appear in logs as custom program error: 0x1770 and up. Constraints without a custom error, such as PDA seeds, has_one and token mint or authority checks, fail with Anchor’s built-in codes below 6000.
| Code | Hex | Name | Message |
|---|---|---|---|
| 6000 | 0x1770 | Arithmetic | Checked integer arithmetic failed |
| 6001 | 0x1771 | InvalidConfig | Invalid vault parameters |
| 6002 | 0x1772 | UnsupportedMint | Only the verified Token-2022 TSLAx mint is supported |
| 6003 | 0x1773 | UnsupportedExtension | Mint extension or issuer authority differs from supported policy |
| 6004 | 0x1774 | IssuerPaused | Issuer paused the underlying token |
| 6005 | 0x1775 | InvalidMultiplier | Invalid fixed-point corporate-action multiplier |
| 6006 | 0x1776 | CorporateActionWindow | Corporate-action activation or historical multiplier ambiguity |
| 6007 | 0x1777 | InvalidOracleOwner | Pyth update has an unexpected program owner |
| 6008 | 0x1778 | InvalidOracle | Invalid Pyth account, feed, or price |
| 6009 | 0x1779 | UnverifiedOracle | Pyth update must have full guardian verification |
| 6010 | 0x177a | OracleConfidence | Pyth confidence interval exceeds vault limit |
| 6011 | 0x177b | WrongOracleTimestamp | Pyth timestamp differs from immutable session mark |
| 6012 | 0x177c | ObservationWindow | Close observation must occur within one hour after regular session |
| 6013 | 0x177d | NoConflict | No conflicting authenticated close mark supplied |
| 6014 | 0x177e | WrongPhase | Instruction unavailable in current round phase |
| 6015 | 0x177f | InvalidSession | Invalid or uncommitted regular-session calendar window |
| 6016 | 0x1780 | MarketClosed | Operation requires an open regular market session |
| 6017 | 0x1781 | EmptyVault | Vault has no assets or shares |
| 6018 | 0x1782 | InvalidAmount | Amount must be positive and within owned balance |
| 6019 | 0x1783 | DuplicateRequest | Duplicate round request |
| 6020 | 0x1784 | Unauthorized | Signer or account is not authorized |
| 6021 | 0x1785 | WithdrawalLocked | Requested shares are locked for round withdrawal |
| 6022 | 0x1786 | Slippage | Minimum share output was not met |
| 6023 | 0x1787 | ShareMismatch | Position share ledger differs from custody account |
| 6024 | 0x1788 | InvalidBid | Bid is outside whitelist or auction bounds |
| 6025 | 0x1789 | AuctionFull | Auction supports at most sixteen bidders |
| 6026 | 0x178a | CustodyShortfall | Issuer removed underlying collateral |
| 6027 | 0x178b | PendingTickets | Round tickets must be processed before next round |
| 6028 | 0x178c | NothingToClaim | Position has no whole premium units to claim |
| 6029 | 0x178d | OutstandingOptions | Option liabilities must be extinguished before dust reclaim |
| 6030 | 0x178e | StakeUnavailable | Vault takes no new bidder stakes |
| 6031 | 0x178f | InvalidStakeMint | Stake mint must be a fixed-supply six-decimal SPL token without a freeze authority |
| 6032 | 0x1790 | AlreadyStaked | Wallet already holds a stake in this vault |
| 6033 | 0x1791 | NotStaked | Wallet has no stake in the required state |
| 6034 | 0x1792 | StakeLocked | Stake is locked until the wait ends and every staked bid is claimed |