Developers
Program reference
Instructions, accounts and the checks each one makes.
Chord’s settlement program is written with Anchor 0.31.1 and supports the classic SPL Token program only. Its source is the authoritative contract; this page summarizes it.
#Instructions
| Instruction | Signed by | What it does |
|---|---|---|
initialize | Upgrade authority | Creates the one immutable config: auctioneer, treasury, chain domain, bond size |
register_solver | Solver | Creates the solver account with a bond of at least the config’s size, if the solver’s CHORD stake meets the minimum |
top_up_solver | Solver | Adds lamports to the bond |
withdraw_solver | Solver | Withdraws unlocked bond |
create_batch | Auctioneer | Opens a batch for an enabled market, with that market’s slot windows and order cap |
commit_batch | Auctioneer and solver | Writes the price and budgets, escrows reserves, locks a bond; the solver’s stake must meet the minimum |
settle_fill | Auctioneer, after the owner’s Ed25519 verification | Fills one signed order against the committed price |
finalize_batch | Anyone | Completes a fully filled batch; unlocks the bond, refunds reserves |
timeout_batch | Anyone | After the deadline with budget unfilled; slashes the bond, burns 10% of the solver’s stake, refunds reserves |
expire_uncommitted | Anyone | After the deadline, closes a batch that never committed |
claim_refund | Anyone | Retries a reserve refund once frozen accounts thaw |
cancel_nonce | Order owner | Writes a cancelled receipt for one nonce |
advance_nonce | Order owner | Raises the owner’s nonce floor |
initialize_staking | Upgrade authority | Creates the stake pool for a CHORD mint with no mint or freeze authority |
set_stake_authority | Pool authority | Hands parameter changes to a governance of the pool’s realm; any other account is refused |
set_stake_timing | Pool authority | Sets the unstaking cooldown and the vote window, each 1 to 365 days |
set_min_solver_stake | Pool authority | Sets the minimum stake to register and commit |
set_market | Pool authority | Lists, retimes or pauses a pair: windows, order cap, enabled |
stake | Staker | Moves CHORD into the staking vault |
unstake | Staker | Starts the cooldown; refused while the staker’s solver has a batch open |
withdraw_stake | Staker | Returns cooled-down CHORD |
update_voter_weight_record | Anyone | Writes a staker’s voting weight for one governance action, valid for one slot |
#Phases
Slots strictly increase through a batch: creation, then collection end, then solve end, then the settlement deadline. Quotes compete between collection end and solve end. Commit is allowed from solve end to the deadline, fills until the deadline, and timeout or expiry strictly after it.
#Errors
| Error | Meaning |
|---|---|
InvalidParameter | A zero or out-of-range value |
Unauthorized | The signer isn’t allowed to do this |
InsufficientBond | Not enough unlocked bond |
InvalidWindow | Batch slots don’t strictly increase, or don’t match the market’s windows |
InvalidPair | Tokens don’t match the batch pair |
WrongPhase | Not allowed in the batch’s current phase |
InsufficientReserve | Reserves don’t cover every gross output |
Expired | The order’s expiry slot has passed |
IntentMismatch | An account or the signed message doesn’t match the order |
TokenOwner | Source or destination isn’t the owner’s |
DelegationRevoked | The allowance was revoked or is too small |
NonceInvalidated | The nonce is below the owner’s floor |
Cancelled | The nonce was cancelled |
NonceAlreadyUsed | The nonce is bound to another order or batch |
Overfill | The fill exceeds the signed sell amount |
PartialForbidden | A partial fill of an order that doesn’t allow one |
LimitPrice | The rounded output misses the signed minimum |
BudgetExceeded | The fill exceeds the committed budget |
UnfilledBudget | Finalize was called before both budgets filled |
MathOverflow | Checked arithmetic failed |
SignatureInstruction | The Ed25519 verification before the fill isn’t the one canonical layout |
StaleFill | The receipt changed since the fill was prepared |
MarketDisabled | The pair has no enabled market |
OrderCap | The batch already filled its market’s order cap |
StakeTooLow | The solver’s stake is below the minimum |
StakeLocked | The solver has a committed batch that isn’t finished |
CooldownActive | Unstaked CHORD is still cooling down |
NothingToWithdraw | No cooled-down CHORD to withdraw |
InvalidProposal | The vote target isn’t a proposal voting with CHORD |
MintAuthority | The staked mint can still mint |
VoteWindowClosed | The vote comes after the pool’s vote window for that proposal |
#Arithmetic
All products are computed in u128 and checked back into u64. Outputs round down; minimums and reserves round up. Every rounding choice favours the trader’s limit or the escrow’s sufficiency, never the solver’s margin.
#Upgrade authority
The program is upgradeable, and its upgrade authority is a trust assumption like any upgradeable Solana program. The config is not: once initialized, its auctioneer, treasury, chain domain and bond size can’t change.
#Governance plugin
The program is the realm’s voter weight plugin on spl-governance. update_voter_weight_record writes a VoterWeightRecord for one action and target, expiring in the same slot, so it goes in the same transaction as the vote or proposal it serves. For a vote, the weight is the staker’s active stake less every deposit made in or after the proposal’s voting slot; for anything else, it is the active stake. CHORD in its cooldown never counts.