peard
Programs

Reference overview

Five programs, 64 instructions, joined by addresses and never by CPI.


Every page in this section is generated from target/idl/*.json, the IDL Anchor emits at build time. Names, accounts, arguments, PDA seeds, events and error codes are read off the artifact rather than recalled, so they are what the deployed bytes actually accept.

No CPI in any direction

The programs are joined by addresses and by hand-parsed account layouts, never by cross-program invocation. Three places in the source give the reason, and it is the same reason each time.

SeamHow it is joinedWhy not a CPI
peard_amm to pearda pool's fee_claimer is a market PDA; claim_fees transfers, sweep_fees credits"either program can be replaced without the other noticing"
peard_perps to peardsync_index reads a Pairable at fixed byte offsets, checking owner, id and addressa build dependency would make the two upgrade together
peard_tote to peardsettle_round reads the same layout the same wayas above
peard to peard_vaultsync_backing parses a Backing attestation with a magic and a version"a build dependency would make the two programs upgrade together and that is the coupling the attestation exists to avoid"

The cost is real and it is a crank. The benefit is that peard contains no AMM, and an AMM that turns out to be wrong can be swapped for a different address without a peard upgrade.

The byte offsets are load-bearing and invisible

Reading a foreign account by hand means the offsets matter and nothing in the type system checks them. peard_perps and peard_tote both declare theirs, and tests/peard_perps.ts asserts every one of them against a real account rather than trusting the comment.

pub const PB_ID: usize = 0;        // past the 8-byte discriminator
pub const PB_MAX_AGE: usize = 60;
pub const PB_TWAP: usize = 64;
pub const PB_LAST_TS: usize = 80;
pub const PB_FROZEN: usize = 88;
pub const PB_EXPIRES: usize = 105;
pub const PB_MIN_LEN: usize = 113;

The Backing attestation is pinned three ways instead: the program that owns the account, the address the market names, and the market the attestation names back. Plus a magic and a version, so a wrong or moved account fails loudly rather than parsing into something plausible.

pub const BACKING_MAGIC: u64 = 0x4241_434b_494e_4731; // "BACKING1"
pub const BACKING_VERSION: u8 = 1;

Fixed-point scales

Shared across the programs, and the ones that differ do so on purpose.

ConstantValueWhat it scales
USD_ONE1e6every dollar amount. USDC has 6 decimals, so a USD-e6 quantity and a USDC base-unit quantity are the same number and are never converted
UNIT_ONE1e9pairable units. Bottles are routinely fractional
ACC_ONE1e15the reward accumulator. 1e15 rather than 1e18 for u128 headroom
S_ONE1e6the coverage ratio. S_ONE means fully covered
ROLL_ONE1e12the cumulative roll index
BASE_ONE1e9peard_perps base size
FUNDING_ONE1e12peard_perps's cumulative funding index
BPS10,000everything in basis points

Caps and floors written into the programs

ConstantValueWhere
protocol_fee_bpsmax 2,000peard::init_global, set_protocol_fee
MAX_CONVERT_BOUNTY_BPS500peard, the inbox bounty
MAX_ROLL_FACTOR100x either waypeard::roll_market
MAX_FEE_BPS500peard_amm::create_pool
fee_bpsmax 1,000peard_tote::open_round
breaker_bps1 to 9,000peard::register_pairable and peard_vault::open_reserve

Instructions no privileged role gates

Worth listing, because "anyone may call it" is a design decision each time rather than an oversight. Most of these carry no signer at all in their accounts struct; liquidate signs only because the caller is the one collecting the fee.

InstructionProgramWhy nobody needs permission
sweep_feespeardit credits holders from money already in their vault
sync_positionpeardit can only ever raise the named holder's own earning balance
roll_marketpeardthe outcome is fully determined by the two pairables
sync_backingpeardthe address was pinned first, twice
expire_fulfillmentpeardan agent going dark must not hold a holder's units hostage
withdraw_protocol_feespeardthe destination is fixed, so there is no discretion to guard
claim_feespeard_ammthe destination was written once at creation and has no setter
sync_reservespeard_amma pool that has been reached into should show it before somebody sells into it
sync_index, settle_fundingpeard_perpsa market nobody cranks is a frozen number
settle_market, settle_positionpeard_perpsexpiry is a fact rather than a decision, and everyone leaves at the same number
liquidatepeard_perpsthe fee is the only reason anyone would run a liquidator
settle_round, void_round, claim, withdraw_feepeard_totethe pot answers the question and the protocol never takes a side
open_roundpeard_toteanybody may ask a question; governance pins which registry may be quoted, not which questions are interesting
close_epoch, mark_item, settle_carrypeard_vaultmarking and carry are bookkeeping over numbers an appraiser already signed