Skip to content

Latest commit

 

History

History
52 lines (43 loc) · 5.34 KB

program.md

File metadata and controls

52 lines (43 loc) · 5.34 KB

Program reference: pot_index

Anchor 1.2.1, Solana CLI 4.3. Source: packages/pot-index/programs/pot_index/src. Tests: packages/pot-index/tests (LiteSVM, run with ./test.sh).

Accounts (PDAs)

Account Seeds Holds
Config ["config"] admin, pending admin, treasury, USDC mint, max_price_age_secs, protocol pause flag
Asset ["asset", mint] mint, decimals, Pyth feed id, enabled flag
Pot ["pot", index_mint] creator, name, symbol, legs (mint, weight_bps, vault, feed_id, decimals), cash vault, deposit cap, paused, finalized, rebalance state, created_at
Vaults ATAs owned by the Pot PDA one per leg + one USDC cash vault
Index mint keypair supplied by the creator (vanity Pot...) mint authority = Pot PDA, 6 decimals

Instructions

Instruction Signer Effect
init_config, set_config, accept_admin admin protocol settings (init_config by the upgrade authority only); admin change is two-step: set_config(new_admin) proposes, the new key accepts within ~1 hour (PENDING_ADMIN_TTL_SLOTS)
migrate_config admin one-off: grows a v1.1 Config to the current layout (see operations.md)
register_asset, update_asset admin allowlist of (mint, Pyth feed id); update_asset enables/disables an asset or repoints its feed for legs added from then on
create_pot(name, symbol, deposit_cap_usd, slippage_bps, max_trade_bps) creator creates Pot + index mint
add_leg(weight_bps) x 2..5 creator adds an asset with its vault
finalize_pot creator checks weights sum to 10,000 bps, locks the basket
set_index_metadata(uri) creator Metaplex metadata (name, symbol, uri) via CPI
set_pot_params(paused, deposit_cap_usd) creator the only two things a creator can change
deposit(amount, min_shares_out) + remaining accounts: Pyth price updates per leg anyone fee split, mint at NAV
exit(shares, min_usdc_out) holder burn, pro-rata transfer of cash + every leg
exit_usdc_open(shares, min_usdc_out) + remaining [vault_i, pyth_update_i, user_ata_i, mint_i] holder burn, cash share to the holder, legs to the holder's accounts, records the minimum USDC the sale must produce; requires exit_usdc_close later in the same transaction for the same Pot and USDC account
exit_usdc_close holder checks the holder's USDC grew by at least the minimum, transfers the 0.10% conversion fee to the treasury
rebalance_open(leg_out, leg_in, amount_out) keeper moves amount_out from the out-vault to the keeper, records expected min_in, requires a matching rebalance_close later in the same transaction (Instructions sysvar introspection)
rebalance_close keeper verifies the in-vault received at least min_in, closes the window

Limits (constants.rs)

  • Entry fee 30 bps: 40% referrer, 40% creator, 20% protocol. No referrer: referrer share goes to the creator.
  • Exit fee 50 bps, stays in the Pot; the last holder (burning the whole supply) pays none, since nobody is left for it to accrue to.
  • 2 to 5 legs. Index decimals 6. Minimum deposit 1 USDC.
  • Virtual shares/assets 1 token / $1 against first-depositor inflation.
  • Oracle: max confidence 2%, max age max_price_age_secs capped at 60 s (MAX_PRICE_AGE_SECS_LIMIT), update account posted within 150 slots. Pot values what it holds or gives at price + conf, what it receives at price - conf.
  • Rebalance: deadband 0.5% of NAV, cooldown 150 slots (asset→asset only; cash deployment has none), max slippage 1%, max trade 25% of NAV per transaction; only from an overweight leg (or cash) toward an underweight leg, never past target on either side.
  • Exit to USDC: minimum = Σ legs at (price − conf) × (1 − slippage_bps) − 0.10% conversion fee; the open/close window reuses Pot.rebalance with leg_out == EXIT_LEG (254), so no account layout change.

Errors

Unauthorized, ProtocolPaused, PotPaused, PotNotFinalized, PotAlreadyFinalized, TooManyLegs, TooFewLegs, WeightsDoNotSum, InvalidWeight, DuplicateLeg, AssetDisabled, NameTooLong, InvalidParams, RemainingAccountsMismatch, VaultMismatch, BadOracleOwner, StalePrice, OracleConfidence, NonPositivePrice, MathOverflow, DepositTooSmall, DepositCapExceeded, SlippageShares, SlippageAssets, ZeroShares, SelfReferral, TokenOwnerMismatch, TokenMintMismatch, RebalanceOpen, RebalanceNotOpen, RebalanceWrongSlot, CpiNotAllowed, MissingClose, InvalidLeg, NotOverweight, OvershootOut, OvershootIn, TradeTooLarge, RebalanceSlippage, ZeroAmount.

Common ones in the UI: StalePrice (stock feeds stop on weekends: deposits wait, exits work), DepositTooSmall (< 1 USDC), SlippageShares (price moved between quote and execution; retry).

Events

Deposited, Exited, ExitUsdcOpened, ExitUsdcClosed, RebalanceOpened, RebalanceClosed (camelCase in the Anchor event parser). The activity feed on each POTFolio page reads them.

Security notes

Full review log: security.md. No withdraw instruction. Exit cannot be paused and does not read the oracle. Keeper trades are atomic: an open without a close in the same transaction fails; under-delivery reverts both. Admin is two-step and will be a Squads multisig on mainnet. Known, accepted: a depositor can self-refer from a second wallet (mitigated later with registered referrers); keeper slippage up to 1% is the implicit rebalance cost.