invest

Program docs

The staking vault is a single Anchor program. One vault per mint, one position per staker per term. Principal never leaves the position — the program can move rewards, and nothing else.

Accounts

AccountSeedsHolds
Vault["vault", mint]Reward accumulator, total weight, lifetime counters
Position["position", vault, owner, term]Amount, term, reward debt, settled lamports, unlock slot
Treasury["treasury", vault]SOL awaiting distribution, plus the LST float
Escrow["escrow", vault]Token account holding staked principal

Instructions

InstructionSignerEffect
initialize_vaultcreatorCreates the vault and locks the fee share. Callable once per mint.
stakeownerMoves tokens to escrow, opens a position, adds amount × multiplier to total weight.
claimownerPays out accrued lamports. Legal at any time, term or no term.
unstakeownerReturns principal. Before unlock, forfeits accrued rewards into the accumulator.
distributekeeperSweeps fees into the treasury and advances acc_reward_per_weight.
sweep_idlekeeperMoves treasury float in and out of the liquid staking position.

Reward accounting

Distribution is O(1) in staker count. The vault tracks a single monotonically increasing accumulator; a position stores the value it last settled against.

weight        = amount * multiplier
pending       = weight * (vault.acc_reward_per_weight - position.reward_debt)
              + position.settled_lamports

// distribute(lamports)
vault.acc_reward_per_weight += lamports / vault.total_weight

// unstake before unlock — forfeit accrued, never principal
recycled = pending * 0.9
vault.total_weight -= weight                 // exclude the leaver first
vault.acc_reward_per_weight += recycled / vault.total_weight

Note the ordering in the forfeit branch: weight is removed before redistribution, so the leaver cannot claim a share of what they just forfeited.

Term multipliers

TermMultiplierTier
7dFlexible
30d1.5×Committed
90d2.5×Conviction
365dFounder

Multipliers are stored in basis points on the position and cannot be changed after staking. Idle treasury float targets 7.8% via liquid staking.

Public API

Read-only, unauthenticated, cached at the edge. Amounts are decimal SOL unless the field name says lamports.

EndpointReturns
GET /api/launches?sort=&limit=All vaults with computed APY. sort: apy · marketCapUsd · volume24hUsd · stakedRatio · lifetimeFeesSol · createdAt
GET /api/launches/[mint]A single vault with its APY breakdown
GET /api/statsProtocol aggregates: average APY, staked value, 24h volume and yield
GET /api/positions?owner=Open positions for a wallet

Security notes

  • — The program has no withdrawal authority over escrow beyond returning principal to the position owner. There is no admin path to staked tokens.
  • distribute is keeper-signed but permissionlessly verifiable: it can only increase the accumulator, and only by lamports actually deposited in the same transaction.
  • — Rewards accrue against a snapshot, so staking immediately before a distribution earns nothing from it. This is what stops deposit-front-running of a known incoming sweep.
  • — Not yet audited. Verify the deployed program on Solscan against this source before committing real size.