> For the complete documentation index, see [llms.txt](https://bubblegum-reality.gitbook.io/bubblegum-reality-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bubblegum-reality.gitbook.io/bubblegum-reality-docs/architecture/swap-execution.md).

# Swap Execution

Non-custodial, wallet-signed, exact-allowance. The server never touches a key and never broadcasts.

## Flow

```
 1  balance check                       insufficient → stop with the reason
 2  allowance read                      allowance ≥ required → skip to 5
 3  exact-amount approve                to issues.allowance.spender only
 4  await approval receipt              never assume success
 5  fresh firm /quote                   indicative prices are never signed
 6  reconfirm material changes          user re-approves if terms moved
 7  re-validate returned tx             chain, taker, tokens, amounts
 8  submit to / data / value            through the wallet
 9  track states                        pending → confirmed | reverted | replaced
10  Blockscout link + refresh balances
```

## Approval rules

* **Exact amount, every time.** `src/lib/swap-exec.ts` exports `NEVER_UNLIMITED` as a documented constant precisely to mark that `maxUint256` is not used as an approval value.
* **Spender is `issues.allowance.spender` from the 0x response** — never the Settler contract address, and never a hardcoded address.
* Token, spender, amount, and network are displayed before the signature request.

```ts
needsApproval(allowance, required); // undefined allowance → true (fail closed)
approveArgs(spender, amount);       // { spender, amount }
```

An unknown allowance returns `true`. Treating "we could not read it" as "it is sufficient" would produce a failed transaction the user paid gas for.

## Firm quote re-validation

The transaction returned by 0x is checked against what was requested before it is handed to the wallet:

| Check                             | Rejects                         |
| --------------------------------- | ------------------------------- |
| `chainId === 4663`                | A quote for another chain       |
| `taker` matches connected account | A quote payable to someone else |
| sell/buy token match request      | Substituted tokens              |
| amounts within requested bounds   | Silent size changes             |
| `simulationComplete`              | Unverified execution paths      |

## Execution disabled states

Each renders the specific reason, not a greyed-out button:

* asset inactive or halted
* no liquidity for this pair/size
* stale quote
* incomplete simulation
* wallet on the wrong chain
* insufficient token balance or insufficient gas
* eligibility not established
* backend routing secret not configured

## What never happens

* No simulated or optimistic success. Confirmation requires a receipt.
* No unlimited approvals.
* No server-side signing, key storage, or custody.
* No retry of a failed gateway call against a different endpoint.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bubblegum-reality.gitbook.io/bubblegum-reality-docs/architecture/swap-execution.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
