Program Notes
Program Notes

The Accounts Involved in a Launchpad Curve Trade

Solana programs receive their world as an ordered list of accounts with flags attached. A launchpad trade names a dozen of them, and the program will refuse the call if any one is in the wrong position, missing a writable flag or derived from the wrong seeds. This note walks the list and explains what each slot is doing there.

IX-03 The Program Notes Desk 2151 words 10 min read Updated 13 August 2026

Summary of this note

Question
Which accounts a launchpad curve trade names, and what each one is for
Inputs
The account keys array of a confirmed transaction, with its signer and writable flags
Rule
Position is identity: the program reads slot four as the curve because slot four is defined to be the curve
Failure mode
Copying an account list from an old transaction after the program has been redeployed with a different shape

A launchpad curve trade names roughly a dozen accounts in a fixed order: a global configuration account, the fee destinations, the mint, the curve state account, the token account holding the curve's reserves, the buyer's token account, the signer, and the programs invoked along the way. Each slot carries a signer flag and a writable flag, and the program validates all of it before it moves a single lamport.

This is the part of an instruction that people skip, and it is the part that decides whether a transaction succeeds. Argument encoding errors are rare because the fields are simple. Account errors are common because the list is long, positional, and version-specific, and because an account that is correct in principle can still be wrong in the slot it was placed in.

The account model in one paragraph

Solana programs do not fetch state during execution. Every account an instruction will read or write must be declared up front, so the runtime can look at two transactions, see that they touch disjoint sets of accounts, and execute them in parallel. That single design decision explains why account lists are long, why they are explicit, and why they are part of the instruction rather than hidden inside the program. The account model is described in the official Solana documentation and is the stable foundation everything else here rests on.

The corollary is that the account list is a declaration of intent, readable by anyone. Before a transaction executes, its account list already says which state it plans to touch. After it executes, the pre and post balance arrays say what it actually changed. Comparing those two is one of the cleanest audits available on any chain.

The three flags that describe a slot

Each entry in an account list is a public key plus two booleans, and those two booleans carry most of the meaning. A signer flag means the transaction must carry a valid signature from that key. A writable flag means the program is permitted to modify the account, and that the runtime must treat it as contended for scheduling purposes.

  • Signer, writable. Almost always the trader's wallet: it authorises the trade and its lamport balance changes.
  • Not signer, writable. State the program owns and updates, such as the curve account and the token accounts on both sides of the trade.
  • Not signer, not writable. References: the mint, a global configuration account, and the program ids being invoked.
  • Signer, not writable. Rare in a trade. It appears where an authority has to approve something without its own balance changing.

Reading the flags first is a useful discipline when you open an unfamiliar transaction. The writable set is the blast radius: nothing outside it changed, no matter what the logs suggest. If an account you expected to move is not flagged writable, it did not move, and your model of the instruction is wrong.

The slots a curve trade names

The table below describes the shape seen in current launchpad traces of this kind. It is a description of a deployed version, not a specification, and the exact set has grown over time as programs added fee destinations and internal accounts.

SlotAccountFlagsWhy the program needs it
1Global configurationread onlyHolds program-wide settings such as fee parameters and initial reserve constants. Read, never written, by a trade.
2Fee recipientwritableReceives the protocol's share of the trade. Its address comes from the global configuration rather than from the sender.
3Mintread onlyIdentifies the token. Also supplies the decimals a decoder needs to turn base units into readable figures.
4Curve statewritableThe per-token account holding reserve figures and the completion flag. This is the account the whole instruction exists to update.
5Curve token accountwritableThe token account owned by the curve that holds the tokens still available on the curve side.
6Trader token accountwritableWhere the trader's tokens land or leave from. Created earlier in the same transaction if it does not exist.
7Trader walletsigner, writableAuthorises the trade and pays for it. Usually the fee payer as well, but not necessarily.
8System programread onlyInvoked to move lamports and, where relevant, to allocate accounts.
9Token programread onlyInvoked to move tokens. This is why token transfers show up as inner instructions rather than as top-level calls.
10Creator or secondary fee destinationwritablePresent in deployments that split fees further. Its presence and position have both changed across versions.
11Event authorityread onlyA derived account the program invokes itself through in order to write structured events into the log.
12The program itselfread onlyNamed so the program can perform the self-invocation that emits the event.

Slots eleven and twelve surprise people. A program that emits structured events using a cross-program invocation has to name itself and an authority account in the instruction, which is why a trade instruction appears to reference the program it is already calling. It is not redundancy; it is how the event ends up in the inner instruction record rather than only in free-text logs.

Which accounts are derived, and from what

Several of those slots are program derived addresses: computed from seeds plus the program id, with no private key, so the program itself can sign for them. Derivation is deterministic, which has a useful consequence for anyone reading activity rather than producing it. Given a mint, you can compute where its curve state lives, and given a wallet and a mint you can compute where that wallet's tokens live, without a single lookup.

AccountDerived fromWhat that lets you do
Curve stateA fixed seed string plus the mint, under the launchpad programLook up any token's curve state from the mint alone, with no index or API
Curve token accountThe curve state address plus the mint, under the associated token account rulesRead the curve's remaining token balance directly
Trader token accountThe wallet plus the mint, under the same rulesCheck whether a wallet already holds a token before its transaction confirms
Event authorityA fixed seed under the launchpad programRecognise the self-invocation that carries the structured trade event

The associated token account derivation is a published standard rather than a launchpad convention, documented alongside the token program in the Solana program library reference. The launchpad-specific seeds are not a standard, and a redeployment can change them, which is the recurring theme of this note.

Why the order is part of the contract

Accounts arrive positionally. The program's account struct maps index zero to its first declared field, index one to its second, and so on, then applies constraints: this account must be owned by this program, this one must be the derived address for that mint, this one must be a signer. If the buyer's token account and the curve's token account are swapped, the constraint on ownership fails and the instruction aborts.

That is the good outcome, and it is worth stating plainly because the alternative sounds worse than it is. A well-constrained program does not quietly do the wrong thing when given a scrambled list; it refuses. The cost is the transaction fee and the slot, not the funds. Programs that lack those constraints are a different and much more serious problem, and they are not the subject here.

A practical implication for anyone reading transactions: you can often tell a hand-built instruction from a generated one by how tidy the account list is. Generated clients place accounts in canonical order and include exactly the required set. Lists with unexpected extra accounts, or with duplicated entries, usually indicate something assembled by hand or by an older client version.

Rent, and who pays for what

Every Solana account must hold enough lamports to be rent exempt, proportional to its data size. For a token account this is a small fixed deposit; for a curve state account it is slightly larger. The deposit is not a fee. It stays in the account and is recoverable if the account is closed, which is why some operators close empty token accounts to reclaim it.

Two rent-related facts matter when reading traces. First, a wallet's first purchase of any token is more expensive than its later ones because it includes the deposit. Second, the funder of that deposit is recorded, and it does not have to be the account owner. A single address funding the token accounts of a dozen wallets in the same slot is one of the clearest structural signals available, and it needs no inference to observe. It does need care to interpret, which is covered in the note on how each bot class looks in a trace.

The fee accounts

A launchpad trade usually routes value to more than one destination: the curve itself, a protocol fee account, and in newer deployments a creator-linked account. The addresses for those destinations come from program state rather than from the sender, which is an important detail. The sender does not choose where fees go, and cannot; the program reads the destination from its own configuration and enforces it.

That is why a fee destination appearing in the account list is not evidence of anything about the sender. It is evidence about the deployed program. The only sender-controlled costs in the transaction are the base fee, the priority fee implied by the compute unit price, and any rent deposits the transaction funds. Everything else is protocol behaviour.

Fee percentages, splits and destinations have all changed across launchpad deployments, and a note that quoted a rate would be wrong within a release. If you need the current figure, read the global configuration account or compute it from the balance deltas of a recent confirmed trade. Both methods survive an upgrade; a memorised number does not.

What a wrong account list looks like

Account errors surface as failed transactions with recognisable causes, and learning the small set of them turns an opaque failure into a two-minute diagnosis.

  • A constraint error naming a seed. A derived address was computed with the wrong seeds, usually because the client was written against a different program version.
  • An owner check failure. An account was supplied that exists but belongs to the wrong program, classically a system account where a token account was required.
  • A missing signature. A slot that requires the signer flag was passed without it, which means the transaction was assembled with the wrong meta rather than with the wrong key.
  • An uninitialised account. The token account was never created, because the creation instruction was omitted or ran after the trade rather than before it.
  • An account count mismatch. The program expected more or fewer accounts than it received, which is the classic symptom of a program upgrade that added a slot.

The last one deserves emphasis because it is the failure mode that arrives without warning. A client that worked yesterday starts failing on every transaction, with no change on the sender's side, because the deployed program now expects an additional account. There is nothing to debug in the client; the shape simply moved.

Auditing an account list from a trace

Reading somebody else's account list is a reliable way to understand what their software does, and it needs no cooperation from them. The sequence below works on any confirmed launchpad transaction in a public explorer.

  1. List the account keys and mark which are flagged signer and which writable. The writable set bounds everything that changed.
  2. Identify the programs by their known ids: system, token, associated token account, compute budget, and the launchpad itself.
  3. Find the mint, then derive the expected curve state address from it and confirm the transaction names that exact account.
  4. Derive the expected token account for the trading wallet and confirm it appears. If it does not, the wallet was not the recipient.
  5. Check whether the fee payer equals the trading wallet. A difference means a funding structure rather than an individual.
  6. Read the pre and post balances for every writable account and reconcile them against the trade you think happened.

Do that on a handful of transactions and the class of software behind a wallet becomes fairly obvious. It is also the honest way to evaluate a tool: an operator who routes flow through many wallets with a volume bot on Solana DEXs can point at the resulting signatures and let anyone reconcile them the same way, which is a stronger form of evidence than any dashboard figure.

Account lists drift

The single most important thing to carry away is that account lists are versioned artefacts. They have grown as launchpad programs added fee logic, and they will keep changing, because the programs are upgradeable and their operators use that capability. Any table, including the one above, is a snapshot.

The durable method is derivation rather than memorisation. Learn how derived addresses are computed, learn which programs perform which invocations, learn to read flags, and you can reconstruct an account list from a recent confirmed transaction whenever the shape moves. That takes about as long as looking up a table and does not go stale.

Questions this note keeps getting

What are launchpad program accounts?

They are the Solana accounts a launchpad program requires to be passed into an instruction so it can read and write the state that instruction needs. A curve trade typically names a global configuration account, the token mint, the curve state account for that mint, the token accounts on both sides of the trade, the signer, the fee destinations, and the programs invoked along the way.

Why does a Solana program need accounts passed in explicitly?

Because programs on Solana cannot look accounts up during execution. Every account an instruction will read or write has to be declared in advance so the runtime can schedule transactions that touch disjoint account sets in parallel. That requirement is what makes the account list part of the instruction rather than an implementation detail hidden inside the program.

What is a program derived address in this context?

It is an address computed from a set of seeds and a program id, with no private key behind it, which allows a program to sign for the account itself. A launchpad uses derived addresses for per-mint state, for the token account holding the curve reserves, and usually for an internal event authority, so anyone can compute where a given token state lives from the mint alone.

Does the order of accounts in an instruction matter?

Yes, completely. Accounts are passed positionally, not by name, so the program reads a specific index and asserts that the account there matches what it expects. A swapped pair almost always produces a constraint error rather than an unintended trade, which is a safe failure, but the transaction fee is still spent and the opportunity is gone.

Who pays for the token account that gets created?

The account named as funder in the creation instruction, which is normally the transaction fee payer. It is a rent-exempt deposit rather than a fee, so the lamports sit in the account and can be recovered if the account is later closed. When one address funds token accounts for many wallets, that funding relationship is visible in the transaction and is a structural fact about how those wallets are operated.

Can I rely on a published account table for a launchpad?

Not for long. Launchpad programs are deployed behind upgrade authorities and their required account lists have changed across versions, including additions for new fee destinations. Treat any published table, including the one on this page, as a description of a version, and confirm the current shape against a recent confirmed transaction before relying on it.

Filed under Instructions. Account lists, discriminators and program constants described here belong to the program version that was live when the note was written, and a launchpad deployment can change any of them without warning. If a signature you are looking at disagrees with this page, the signature is right: send it to the desk and the page gets corrected in the open.

Read next