New DEX Integration Checklist

A pilot runs a pre-flight checklist before every takeoff. It doesn't matter if she's flown the same aircraft a thousand times. It doesn't matter if the weather is perfect and the runway is clear and the plane was just serviced yesterday. She walks through the checklist — fuel quantity, control surfaces, instruments, communications — because aviation learned decades ago that human memory is unreliable, that familiarity breeds shortcuts, and that shortcuts kill. The checklist doesn't make the pilot less skilled. It makes the pilot's skill consistently available.

I now have a checklist for integrating a new DEX. It takes me six integrations to build it.

The first integration has no checklist because I don't know what I don't know. Every problem is novel. The second integration has the ghost of a checklist — lessons from the first, carried in memory, applied inconsistently. By the fourth integration, I notice that the same categories of problems keep appearing, and I start writing things down. By the sixth, the list is formalized. Not because I'm disciplined, but because I'm tired of repeating the same mistakes.

This is how every useful checklist in every industry comes into existence. Nobody sits down on day one and writes a comprehensive pre-flight checklist from first principles. Checklists are compiled from failures. Each line item represents something that went wrong at least once — something that cost time, money, or in aviation's case, lives. A checklist is a scar registry. Each item is a scar.

The Shape of Recurring Mistakes

The mistakes that recur across DEX integrations are not random. They cluster into categories, and the categories are remarkably stable from one protocol to the next.

Some mistakes are about data layout — getting the byte-level structure of on-chain accounts wrong. Some are about instruction interfaces — passing the wrong accounts, in the wrong order, with the wrong permissions. Some are about error handling — misinterpreting what went wrong when a transaction fails. Some are about edge cases — things that work for one token pair but break for another, things that work in one direction but fail in the other.

These categories persist because they correspond to fundamental aspects of on-chain program integration. Every DEX program stores state in accounts with specific byte layouts. Every DEX program exposes instructions that require specific accounts in specific orders. Every DEX program has an error enum. Every DEX program has edge cases around token standards, fee application, and swap direction. The surface details change — the account names are different, the fee structures vary, the instruction formats diverge — but the categories of potential failure are the same.

This is the core insight behind the checklist: the categories are universal even when the specifics are not. I don't need a checklist that tells me "Whirlpool's tick array is at offset 44" because that's specific to one protocol. I need a checklist that tells me "verify the byte offset of every field you parse against actual on-chain data" because that applies to all of them.

The Checklist

1. Extract the Instruction Interface from Source Code

Before anything else, I need to know what instructions the program exposes and what accounts each instruction requires. This means reading the program's source code — not the documentation, not a blog post, not a Discord message from six months ago. The source code.

For Anchor-based programs, this means finding the #[derive(Accounts)] structs and the instruction handler functions. For native programs, it means finding the instruction processor and tracing the account deserialization logic. Either way, the output is the same: a complete list of every account an instruction expects, in order, with the correct is_signer and is_writable flags.

This sounds obvious. It is obvious. I still manage to get it wrong on nearly every integration until I make it an explicit checklist item. The failure mode is not "I forget to look at the source code." The failure mode is "I look at the source code, extract most of the accounts, and miss one because it's added by a wrapper function" or "I get the account list right but miss that one account needs to be writable." The checklist item isn't "look at the code." The checklist item is "extract the complete interface and write it down in a reference document before writing any integration code."

The difference is like the difference between glancing at a recipe and mise en place — the professional kitchen practice of measuring and preparing every ingredient before you start cooking. Glancing at a recipe means you realize halfway through searing the meat that you forgot to dice the onions. Mise en place means everything is ready before the burner lights. Extracting the complete interface before writing integration code is mise en place for DEX integration.

2. Cross-Verify Byte Offsets with On-Chain Data

Every piece of state I read from a DEX's on-chain accounts involves a byte offset. The pool's reserves are at offset X. The fee rate is at offset Y. The token mints are at offset Z. I derive these offsets from the source code — by reading the struct definitions and calculating where each field lands in the serialized binary layout.

The checklist requires that I verify every offset I plan to use against actual on-chain data. This means fetching a real account from the blockchain, decoding it manually at the offsets I've calculated, and confirming that the values make sense. If I think the token mint is at offset 72, I fetch a pool account, read 32 bytes starting at offset 72, and check whether the resulting public key matches a known token mint.

This step catches a surprisingly common class of errors: alignment assumptions. Struct layout in serialized form doesn't always match what you'd expect from reading the Rust source. Discriminators, padding bytes, enum variants with implicit size — these all shift offsets in ways that are easy to miscalculate. The source code tells you what the fields are. Only the actual on-chain data tells you where they are.

It's the same principle that makes surveyors physically measure property boundaries instead of relying solely on deed descriptions. The deed might say "forty feet from the old oak tree," but the old oak tree was removed in 1987 and the deed was never updated. The survey — the physical measurement — is the ground truth. On-chain data is my survey. The source code is my deed. I need both, but when they disagree, the on-chain data wins.

3. Map the Error Code Enum

Every on-chain program defines error codes. When a transaction fails, the error code is often the only diagnostic information available. If I can't decode that error code quickly and accurately, I'm debugging blind.

The checklist requires mapping the program's complete error enum before I write integration code. This means finding the #[error_code] block (in Anchor programs) or the equivalent error definitions (in native programs), and building a lookup table: number to variant name to human-readable description of what condition triggers that error.

But mapping the program's own errors isn't sufficient. I also need to identify every program that this program calls via CPI — cross-program invocation — because errors from those inner programs bubble up through the outer program's transaction logs. If Program A calls Program B internally, and Program B fails with error 6003, the transaction logs might not clearly attribute that error to Program B. If I only have Program A's error map, I'll decode 6003 against Program A's enum and get a completely wrong diagnosis.

This is a mistake I make more than once before it becomes a checklist item. The mapping step now explicitly includes: "Identify all CPI targets. Map their error enums too."

4. Test Both Swap Directions

A swap instruction is not symmetric. Swapping token A for token B and swapping token B for token A may use the same instruction with different parameters, or they may use different instructions entirely. Even when they use the same instruction, the account order might change. The source account and destination account swap positions. The fee might be applied differently depending on direction.

The checklist requires testing both directions as separate verification steps. Not "test one direction and assume the other works the same way." Test both. Explicitly. With real transactions or accurate simulations.

This catches bugs that are invisible in unidirectional testing. A swap that works perfectly from A to B might fail from B to A because the source token account index is hardcoded for one direction. Or because the fee deduction logic applies to the input token, and the fee parameters differ by direction. Or because one direction involves a token standard that the other doesn't.

It's the moving day equivalent of checking that furniture fits through the doorway in both directions. A couch that slides smoothly into a room might not come back out — the angles that work going in don't always work going out, especially around corners. Swap directions are the same. The instruction that works in one direction has a different geometry in the other.

5. Check Token-2022 Support and Dynamic Detection

Solana has two token programs: the original SPL Token Program and the newer Token-2022 (Token Extensions) program. They serve the same purpose — creating and managing tokens — but they are different programs with different program IDs. A token account belongs to one or the other, and the correct program ID must be specified in any instruction that touches that account.

The checklist requires determining, for each DEX, whether it supports Token-2022 tokens, and if so, how the integration code should detect which token program a given token uses.

Some DEX programs only support the original token program. For these, hardcoding the original program ID is correct and safe. Some support both but require explicit detection — the integration code must check each token's mint account to determine which program owns it, then pass the correct program ID in the instruction.

Getting this wrong produces confusing failures. The transaction doesn't fail with a clear "wrong token program" error. It fails with an ownership check failure or an account deserialization error — something that points you toward account misconfiguration rather than program ID mismatch. Without this checklist item, I spend time debugging account structures when the real problem is a single program ID.

The detection logic itself is straightforward: fetch the mint account, check its owner field, and the owner tells you which token program to use. The hard part isn't the logic — it's remembering to do it. The checklist is a reminder mechanism. I know how to detect the token program. I just need to be reminded that detection is necessary, because the failure mode of not detecting is subtle and time-consuming to diagnose.

6. Understand the Fee Structure

Every DEX charges fees, but fee structures vary dramatically. Some charge a flat percentage. Some use tiered fee schedules based on pool configuration. Some charge fees on the input amount before computing the swap. Some charge fees on the output amount after computing the swap. Some have protocol fees layered on top of trading fees. Some have dynamic fees that change based on volatility or volume.

The checklist requires documenting three things about each DEX's fee structure: what the fee rate is (or how it's determined), where the fee is applied in the swap calculation (input side vs. output side), and where the fee parameters live on-chain (which account, which field, which offset).

This matters because the arbitrage bot needs to compute expected swap outputs accurately. If the fee model is wrong — if I'm deducting fees from the output when the program deducts them from the input, or if I'm using a 0.3% fee when the actual pool charges 0.25% — the computed expected output will differ from the actual output. The bot will overestimate or underestimate profits. It will take trades that aren't profitable, or skip trades that are.

Fee modeling errors are insidious because they don't cause transactions to fail. They cause transactions to succeed with different results than expected. The swap works. The amounts are just wrong. You don't get an error code to debug. You get a gradual realization that your profit estimates don't match reality, and you have to work backwards from the discrepancy to find the modeling error.

It's like calculating the cost of a road trip using the wrong gas mileage for your car. You don't run out of gas — you just stop for gas more often than planned. The trip happens. The budget doesn't work out. And pinpointing "I used the wrong MPG number" requires reviewing assumptions you thought were correct.

7. Compare Simulation Against On-Chain Results

Before routing real value through a new DEX integration, the checklist requires running the same swap through two paths: the bot's local computation and the actual on-chain execution. The local computation uses the math model — the fee structure, the AMM curve, the reserve values. The on-chain execution uses the deployed program. If the two produce the same output amount for the same input, the model is correct. If they diverge, something in the model is wrong.

This comparison step catches every category of modeling error: wrong fee rate, wrong fee application point, wrong curve math, wrong reserve values, wrong decimal handling. It's a single verification that covers multiple potential failures.

The key is that the comparison must use identical inputs and identical state. If the pool's reserves change between the local computation and the on-chain execution, the outputs will differ for legitimate reasons. The comparison needs to happen against a frozen snapshot of state — either by using a local simulation environment or by executing the on-chain swap immediately after fetching the state used for local computation, before any other transactions can change the pool.

8. Verify Program ID Inclusion for CPI Calls

When my program calls another program via CPI, the called program's ID must be included in the instruction's account list. This is a Solana runtime requirement — the runtime needs to verify that the program being invoked is the program you intend to invoke, and it does this by checking that the program ID appears in the transaction's account list.

This is easy to forget because the program ID isn't an "account" in any intuitive sense. It's not a token account or a pool account or a configuration account. It's the address of the program itself. But Solana's account model treats everything as an account — programs, data accounts, token accounts, system accounts. The program ID goes in the account list like everything else.

Missing a program ID produces a runtime error that says the program is not part of the transaction. The error message is clear once you know what it means. Before you know what it means, it's baffling — you can see the program address in your CPI call, you know the program exists on-chain, and yet the runtime says it's not there. It's not there because you didn't include it in the accounts array, and the runtime won't look for things you didn't include.

The surgical team doesn't assume that the scalpel is on the tray because someone used it in the last operation. The prep checklist says "verify scalpel is on the tray" and someone physically confirms it. The program ID inclusion check works the same way. I know CPI needs the program ID. I've included it before. The checklist ensures I include it this time.

Why the Checklist Is Necessary But Insufficient

Eight items. That's the current list. It covers the categories of problems I've encountered repeatedly across six integrations. It catches known mistakes — the ones I've made before and don't want to make again.

It doesn't catch unknown mistakes. Each new DEX brings surprises that no checklist could anticipate. A program that uses a novel account ownership pattern. A fee structure that doesn't fit any of the models I've seen before. An instruction that behaves differently depending on which cluster it's deployed on. A custom serialization format that doesn't follow Anchor conventions or Borsh standards. These are the problems that require investigation, not checking boxes.

The checklist is a floor, not a ceiling. It guarantees that I don't waste time on problems I already know how to avoid. It doesn't guarantee that I won't waste time on new problems. The pre-flight checklist ensures the pilot doesn't take off with the parking brake engaged — it doesn't prepare her for the microburst at two thousand feet that nobody predicted.

This is a fundamental property of checklists in complex domains. Atul Gawande, in The Checklist Manifesto, distinguishes between errors of ignorance (we don't know) and errors of ineptitude (we know but we fail to apply what we know). Checklists address errors of ineptitude. They don't address errors of ignorance. DEX integration involves both kinds, and only the first kind is checklistable.

The practical implication: the checklist reduces integration time, but it doesn't eliminate it. It compresses the known part of the work, freeing more attention for the unknown part. The sixth integration is faster than the second, but it's not instant. It's faster because I spend zero time on offset verification mistakes (the checklist catches those) and all my time on whatever novel problem this particular DEX presents.

The Diminishing but Never-Vanishing Cost

There's a tempting narrative about expertise: the more you do something, the easier it gets, asymptotically approaching zero effort. This is true for some activities. It is not true for DEX integration.

The effort does decrease. The first integration is pure discovery — everything is new, every decision requires research, every failure requires root-cause investigation from scratch. The sixth integration benefits from pattern recognition, established tooling, and the checklist. The scaffolding is already built. The verification procedures are rehearsed. The mental models are calibrated.

But the effort never reaches zero because every DEX is different in ways that matter. Different account structures. Different math models. Different fee mechanics. Different instruction formats. Different error handling. The checklist handles the similarities. The differences require fresh work every time.

It's like being a general contractor who's built fifty houses. The fiftieth house goes faster than the second house — you know which subcontractors to call, what order to schedule them, where the city inspector is going to be picky, how much lumber to order. But the fiftieth house still takes months, because the foundation is different (every lot has different soil), the client wants a different floor plan, the building code changed since the forty-ninth house, and the lumber yard is backordered on the beam size you need. Experience makes you faster. It doesn't make the work trivial.

DEX integration follows the same curve. The checklist captures what's repeatable. But on-chain protocols are not standardized the way building materials are. There is no building code for DEX programs — no universal standard for account layouts, instruction formats, or error handling. Each program is its own specification. The checklist tells me what questions to ask. The answers are always different.

What the Checklist Teaches About the Domain

Looking at the checklist as a whole, it reveals something about the nature of on-chain integration work. Every item on the list is a verification step. Not a creation step — a verification step. Extract and verify the interface. Verify byte offsets. Verify error codes. Verify both directions. Verify token program support. Verify fee structure. Verify simulation accuracy. Verify program ID inclusion.

The work of DEX integration is not primarily about writing code. It's about verifying assumptions. The code itself is usually straightforward — construct an instruction, populate the accounts, serialize the data, send the transaction. What makes the work hard is not the coding but the knowing. Knowing exactly which accounts to pass. Knowing exactly where the reserves are stored. Knowing exactly how fees are applied. Knowing exactly which error means what.

The checklist is a formalization of this insight. It doesn't say "write the swap function." It says "make sure you have verified everything the swap function depends on before you write it." The writing is the easy part. The verifying is where the time goes.

This is why experience helps but never eliminates the work. Experienced pilots still run checklists. Experienced surgeons still run checklists. Experienced contractors still inspect the site before breaking ground. The expertise doesn't replace the verification — it makes the verification faster and more targeted. The pilot doesn't spend ten minutes on each checklist item the way a student pilot does. She moves through it quickly because she knows what she's looking for. But she still looks.

Six integrations in, I move through my checklist faster than I did on the third. I know which items are likely to surface problems for this particular type of DEX. I know where to look in the source code. I know what patterns in on-chain data indicate a correct offset versus a miscalculated one. The checklist takes less time, but it never takes zero time, and I never skip it.

The day I skip the checklist is the day I ship a hardcoded program ID from the previous integration and spend three hours debugging a transaction failure that the checklist would have caught in thirty seconds. That's not a hypothetical. That's what happened before the checklist existed. The checklist exists so it doesn't happen again.

That's all it needs to do.

Disclaimer

This article is for informational and educational purposes only and does not constitute financial, investment, legal, or professional advice. Content is produced independently and supported by advertising revenue. While we strive for accuracy, this article may contain unintentional errors or outdated information. Readers should independently verify all facts and data before making decisions. Company names and trademarks are referenced for analysis purposes under fair use principles. Always consult qualified professionals before making financial or legal decisions.