Lineagei
Frameworki
What's Anchor?
Batteries-included Rust framework. Ships account-validation codegen, 8-byte instruction discriminators, and an on-chain IDL — the program describes itself.
Bigger binary and higher rent in exchange for safety rails, introspection, and dev speed. The choice of a team optimizing for correctness over on-chain footprint.
Originally Coral (Armani Ferrante); now community-maintained.
What it is
The de facto standard. Rust macros (#[program], #[derive(Accounts)]) eliminate boilerplate: it auto-generates 8-byte account and instruction discriminators — SHA256("account:<Name>")[..8] and SHA256("global:<ix>")[..8] — handles Borsh (de)serialization, enforces account constraints declaratively (mut, has_one, seeds, init), and emits a JSON IDL that client libraries consume directly. The cost: Borsh copies data on every deserialize (not zero-copy), and the macro machinery adds binary bloat and compute overhead — irrelevant for ~99% of programs.
When to pick it
Building a new protocol, moving fast, or wanting maximum ecosystem compatibility. It's the beginner default and stays the right call for most production programs.
How it looks on-chain
The most recognizable framework. Every account it owns begins with an 8-byte discriminator, and the IDL is often published on-chain at a PDA derived from the program id. Both are strong, reliable fingerprints — this is the only framework we can label with confidence.
Others in the wild: Steel (Ore team — near-native performance on solana-program), Seahorse (Python → Anchor), and Poseidon & Quasar (TypeScript → Rust). Transpilers inherit their lowering target's fingerprint: a Quasar or Poseidon program that compiles down to Anchor will look like Anchor on-chain — discriminators and all.
Anchor docsFootprinti
Recovered architecturei
Reachi
Controli
What's upgrade authority?
The upgrade authority is the account allowed to replace a program's code after it's deployed.
If it's set (mutable), that key can push new bytecode at any time — including malicious code, the classic "rug" vector. If it's null (immutable / frozen), the code can never change; what 's on-chain is final. A Squads multisig sits in between — upgrades are possible but need M-of-N signers, not one hot wallet. So mutable + single hot-wallet = highest risk; immutable or multisig = stronger guarantees.
What's a verified build?
A verified build proves the program running on-chain was compiled from the public source you can read — nothing hidden.
Someone re-compiles the source in a deterministic (Docker) environment and checks the resulting bytecode is byte-for-byte identical to what's deployed; tools like solana-verify do this and record it with a verification service. "Not verified" isn't a red flag by itself — most programs simply never submit one. It just means you're trusting the deployed bytecode as-is, with no source cross-check.
Convictioni
Interface — the on-chain IDLi
6 of 11 instructions used · 5 never called in this window
Kamino AMM program
Instructions 11
deposit
- depositorsigner
- poolwritable
- swap_curve
- pool_authority
- token_a_mint
- token_b_mint
- token_a_vaultwritable
- token_b_vaultwritable
- pool_token_mintwritable
- token_a_user_atawritable
- token_b_user_atawritable
- pool_token_user_atawritable
- pool_token_program
- token_a_token_program
- token_b_token_program
- event_authority
- program
- pool_token_amountu64
- maximum_token_a_amountu64
- maximum_token_b_amountu64
initialize_pool
- adminsignerwritable
- poolwritable
- swap_curvewritable
- pool_authoritywritable
- token_a_mint
- token_b_mint
- token_a_vaultwritable
- token_b_vaultwritable
- pool_token_mintwritable
- token_a_fees_vaultwritable
- token_b_fees_vaultwritable
- admin_token_a_atawritable
- admin_token_b_atawritable
- admin_pool_token_atasignerwritable
- system_program
- pool_token_program
- token_a_token_program
- token_b_token_program
- event_authority
- program
- curve_parametersCurveUserParameters
- feesFees
- initial_supply_au64
- initial_supply_bu64
set_oracle_price
Sets the oracle price for the pool. Dispatched via program `fallback`.
- poolwritable
- oracle_signersigner
- _price_valueu128
- _price_expu64
swap
- core
- instruction_sysvar
- source_token_host_fees_accountwritableoptional
- scope_price_feedoptional
- amount_inu64
- minimum_amount_outu64
swap2
- core
- score_signersigner
- source_token_host_fees_accountwritableoptional
- scope_price_feedoptional
- amount_inu64
- minimum_amount_outu64
- scoreu8
swap2_v2
- core
- score_signersigner
- source_token_host_fees_accountwritableoptional
- scope_price_feedoptional
- event_authority
- program
- amount_inu64
- minimum_amount_outu64
- scoreu8
swap_v2
- core
- instruction_sysvar
- source_token_host_fees_accountwritableoptional
- scope_price_feedoptional
- event_authority
- program
- amount_inu64
- minimum_amount_outu64
transfer_pool_admin
- adminsigner
- poolwritable
- event_authority
- program
- new_adminpubkey
update_pool_config
- adminsignerwritable
- poolwritable
- swap_curvewritable
- event_authority
- program
- modeu16
- value[u8; 32]
withdraw
- withdrawersigner
- poolwritable
- swap_curve
- pool_authority
- token_a_mint
- token_b_mint
- token_a_vaultwritable
- token_b_vaultwritable
- pool_token_mintwritable
- token_a_fees_vaultwritable
- token_b_fees_vaultwritable
- token_a_user_atawritable
- token_b_user_atawritable
- pool_token_user_atawritable
- pool_token_program
- token_a_token_program
- token_b_token_program
- event_authority
- program
- pool_token_amountu64
- minimum_token_a_amountOption<u64>
- minimum_token_b_amountOption<u64>
withdraw_fees
- adminsignerwritable
- poolwritable
- pool_authority
- fees_mint
- fees_vaultwritable
- admin_fees_atawritable
- fees_token_program
- event_authority
- program
- requested_withdraw_amountu64
Accounts 1
SwapPool
no fields
Types 15
CurveUserParametersenum
- ConstantProduct
- ConstantPrice
- Offset
- Stable
- ConstantSpreadOracle
- InventorySkewOracle
Depositstruct
- poolpubkey
- userpubkey
- token_a_amountu64
- token_b_amountu64
- pool_token_amountu64
Feesstruct
- trade_fee_numeratoru64Trade fees are extra token amounts that are held inside the token accounts during a trade, making the value of liquidity tokens rise. Trade fee numerator
- trade_fee_denominatoru64Trade fee denominator
- owner_trade_fee_numeratoru64Owner trading fees are extra token amounts that are held inside the token accounts during a trade, with the equivalent in pool tokens minted to the owner of the program. Owner trade fee numerator
- owner_trade_fee_denominatoru64Owner trade fee denominator
- owner_withdraw_fee_numeratoru64Owner withdraw fees are extra liquidity pool token amounts that are sent to the owner on every withdrawal. Owner withdraw fee numerator
- owner_withdraw_fee_denominatoru64Owner withdraw fee denominator
- host_fee_numeratoru64Host fees are a proportion of the owner trading fees, sent to an extra account provided during the trade. Host trading fee numerator
- host_fee_denominatoru64Host trading fee denominator
InternalOraclePricestruct
- value_lou64
- value_hiu64
- expu64Price exponent: actual price = value / 10^exp.
- timestampi64Unix timestamp of the last update.
InternalOracleStalestruct
- poolpubkey
- age_secsu64
- max_age_secsu64
- fell_back_to_scopebool
InternalOracleUsedstruct
- poolpubkey
- price_valueu128
- price_expu64
- age_secsu64
PriceChainFetchedstruct
- poolpubkey
- chain_lengthu8Number of prices in the chain (1-4).
- price_indices[u16; 4]
- price_values[u64; 4]
- price_exponents[u64; 4]
- price_timestamps[u64; 4]
- combined_valueu128Product of `price_values`.
- combined_exponentu64Sum of `price_exponents`.
Swapstruct
- poolpubkey
- userpubkey
- token_in_amountu64
- token_out_amountu64
- trade_feeu64Trade fee — goes to LPs.
- owner_feeu64Owner / protocol fee.
- total_feesu64trade_fee + owner_fee + host fees.
SwapPoolstruct
- adminpubkeyCurrently the pool admin is the account that initialized the pool.
- pool_authoritypubkey
- pool_authority_bump_seedu8
- _bump_seed_padding[u8; 7]Padding to maintain alignment after the bump_seed `u64 -> u8` change.
- token_a_vaultpubkey
- token_b_vaultpubkey
- pool_token_mintpubkeyMinted on deposit; redeemable for the underlying A/B tokens on withdraw.
- token_a_mintpubkey
- token_b_mintpubkey
- token_a_fees_vaultpubkeyReceives trading and/or withdrawal fees.
- token_b_fees_vaultpubkey
- feesFees
- curve_typeu64Discriminates the swap curve account; deserialised via `CurveType::try_from`.
- swap_curvepubkey
- pool_mode_bitmapu64Pool mode bitmap: Lower half (bits 0-31): admin/lifecycle state - bit 0: withdrawals_only (pool only allows withdrawals, no swaps/deposits) Upper half (bits 32-63): operational config - bit 32: fallback_to_scope (use Scope price when internal oracle is stale/deviates) - bit 33: open_deposits (allow non-admin deposits/withdrawals)
- cumulative_volume_token_au64Cumulative volume in native token units.
- cumulative_volume_token_bu64
- scope_price_feedpubkeyScope oracle price feed account for oracle-based curves. Default pubkey for non-oracle curves.
- internal_oracle_priceInternalOraclePriceCached internal oracle price (from set_oracle_price instruction). When non-zero, swap uses this instead of reading Scope directly.
- oracle_signerpubkeyAuthorized signer for the set_oracle_price fallback instruction. Default pubkey means internal oracle is disabled (swap falls back to Scope).
- max_internal_oracle_age_secsu16Maximum age (in seconds) of a cached internal oracle price before it's considered stale. Must be set (> 0) via `UpdatePoolConfig` whenever `oracle_signer` is non-default; otherwise any cached price is treated as stale as soon as the block timestamp (Clock::unix_timestamp, 1s granularity) advances past the update timestamp. u16 max = 65535s (~18h).
- max_internal_oracle_deviation_bpsu16Maximum allowed deviation (in bps) between internal oracle and Scope price. Must be set (> 0, <= 10000) via `UpdatePoolConfig` whenever `oracle_signer` is non-default.
- _padding[u8; 12]
TransferPoolAdminstruct
- poolpubkey
- old_adminpubkey
- new_adminpubkey
UpdatePoolConfigstruct
- modeUpdatePoolConfigMode
- valueUpdatePoolConfigValue
UpdatePoolConfigModeenum
- WithdrawalsOnly
- PriceChain
- MaxAgeSecs
- PriceOffsetBps
- ScoreFactorBps
- OpenDeposits
- BaseSpreadBps
- SizeSpreadBps
- SkewBps
- InvEquilibrium
- InvMax
- QRef
- Alpha
- OracleSigner
- FallbackToScopeEnabled
- MaxInternalOracleAgeSecs
- MaxInternalOracleDeviationBps
UpdatePoolConfigValueenum
- Bool
- PriceChainArray
- MaxAgeSecs
- PriceOffsetBps
- ScoreFactorBps
- U64
- OracleSigner
Withdrawstruct
- poolpubkey
- userpubkey
- token_a_amountu64
- token_b_amountu64
- pool_token_amountu64
- token_a_feesu64
- token_b_feesu64
WithdrawFeesstruct
- withdraw_amountu64
Events 9
Deposit
no fields
InternalOracleStale
no fields
InternalOracleUsed
no fields
PriceChainFetched
no fields
Swap
no fields
TransferPoolAdmin
no fields
UpdatePoolConfig
no fields
Withdraw
no fields
WithdrawFees
no fields
Errors 32
- 6000InvalidProgramAddressInvalid program address generated from bump seed and key
- 6001EmptySupplyInput token account empty
- 6002IncorrectSwapAccountAddress of the provided swap token account is incorrect
- 6003IncorrectPoolMintAddress of the provided pool token mint is incorrect
- 6004CalculationFailureGeneral calculation failure due to overflow or underflow
- 6005RepeatedMintSwap input token accounts have the same mint
- 6006ExceededSlippageSwap instruction exceeds desired slippage limit
- 6007IncorrectFeeAccountPool fee token account incorrect
- 6008ZeroTradingTokensGiven pool token amount results in zero trading tokens
- 6009FeeCalculationFailureFee calculation failed due to overflow, underflow, or unexpected 0
- 6010ConversionFailureConversion to u64 failed with an overflow or underflow
- 6011InvalidFeeThe provided fee does not match the program owner's constraints
- 6012UnsupportedCurveTypeThe provided curve type is not supported by the program owner
- 6013InvalidCurveThe provided curve parameters are invalid
- 6014UnsupportedCurveOperationThe operation cannot be performed on the given curve
- 6015WithdrawalsOnlyModeThe operation cannot be performed because the pool is in withdrawals only mode
- 6016IncorrectTradingMintAddress of the provided trading token mint is incorrect
- 6017InsufficientPoolTokenFundsInsufficient funds in the pool token account
- 6018InvalidPoolAdminPool admin is not correct
- 6019InvalidTokenExtensionToken 2022 extension is not supported
- 6020InvalidOracleConfigInvalid oracle configuration
- 6021InvalidOraclePriceFeedInvalid oracle price feed
- 6022InvalidOraclePriceInvalid oracle price
- 6023OraclePriceTooOldOracle price is too old
- 6024InvalidInputInvalid input
- 6025InvalidSignerInvalid signer
- 6026InvalidAccountDataInvalid account data layout
- 6027PoolNotEmptyPool accounts must be empty before closing
- 6028OraclePriceDeviationInternal oracle price deviates too much from scope
- 6029InternalOraclePriceStaleInternal oracle price is stale
- 6030OracleTimestampRegressionClock timestamp is behind the last oracle update
- 6031RestrictedLiquidityActionDeposits/withdrawals are restricted to the pool admin
What's an IDL?
An IDL — Interface Description Language — is a JSON spec that describes how to talk to a program: its instructions, the accounts each one needs, argument and account types, events, and errors.
Anchor auto-generates it at build time. A program can publish it on-chain at a PDA derived from its id, so any client or explorer can decode the program's transactions without its source code.
Why it's often missing
Publishing is opt-in — a courtesy, not a requirement. Many programs never do, and non-Anchor frameworks (Pinocchio, native, Steel) don't produce one at all; their interface lives in an off-chain Shank/Codama artifact, or nowhere public. Absence means you can't auto-decode it — not that anything is wrong.
6 of 11 instructions used · 5 never called in this window · +3 more