> ## Documentation Index
> Fetch the complete documentation index at: https://digraphsas-docs-cli.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Token approvals for AI agents

> Agent decision rules for ERC-20 approvals on Velora: derive the spender from the quote response, check allowances before signing, and recover from approval mistakes.

Approvals are the single most common place agents get a Velora flow wrong. The mode you quote against decides the spender, and the spender is **never the same as the swap target**. This page holds the agent decision tables: which contract gets the `approve(spender, amount)` call, what to check before signing, and how to recover when an approval lands on the wrong contract. For how approvals and permits work conceptually, read [Approvals and permit](/resources/approvals).

## When to use this

* The user's source token is an ERC-20 and you're about to build a Market transaction, a Delta order, or an AugustusRFQ fill.
* You're deciding whether to ask the user for a separate `approve` transaction, or whether to bundle a `permit` / `permit2` payload into the build call instead.
* An earlier swap or order failed with an allowance error and you need to figure out which spender actually needed the approval.

If the user's source token is the chain's native asset, there is no approval step. Use the canonical placeholder `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` (mixed case) for `srcToken`; Delta moves native ETH as dETH without an approval. See [Native ETH (dETH)](/delta/native-eth).

## The rule (read this first)

| Execution mode                        | Spender to approve                           |
| ------------------------------------- | -------------------------------------------- |
| Delta Swap, Delta `LIMIT`, Delta TWAP | **Delta contract**                           |
| Market Swap                           | **Augustus v6.2**                            |
| AugustusRFQ (OTC/RFQ)                 | **AugustusRFQ** contract on the target chain |

Deployed addresses for each spender, per chain: [Chains & contracts → Addresses by chain](/resources/chains-and-contracts#addresses-by-chain). Delta and AugustusRFQ are not deployed everywhere; code should read availability at runtime via [`/resources/contracts.json`](/resources/contracts.json) keyed by `chainId`.

<Warning>
  Spenders are mode-specific and **never interchangeable**. An approval to Augustus does not authorize a Delta order. An approval to the Delta contract does not authorize a Market swap. Re-quoting under a different mode changes the spender; re-check the allowance before signing.
</Warning>

Agent rules:

* Take the spender from the execution mode of the quote response, not from the user's natural-language intent. If the quote response carries a top-level `delta` object, the Delta contract is the spender. If it carries a top-level `market` object, Augustus v6.2 is the spender.
* If the user asked for a Delta or RFQ flow on a chain without that contract, surface the limitation and offer the available alternatives. Do not silently fall back to a different mode.

## Permit and Permit2: agent rules

When the token supports EIP-2612 Permit or Permit2, you can collect a signature instead of a separate on-chain `approve` transaction. [Approvals and permit](/resources/approvals#approve-or-sign-a-permit) covers how the payload is passed into the Delta and Market build calls.

* Detect Permit/Permit2 capability **before** asking the user for an on-chain `approve`; collect the signature instead when supported.
* A Permit/Permit2 signature is a user authorization, not a free no-op. Confirm with the user before requesting the signature, the same way you would confirm an on-chain approval.
* Permit/Permit2 signatures bind to a specific spender, amount, deadline, and (for Permit2) nonce. If you requote into a different mode, the existing signature is **not transferable**: collect a new one for the new spender.
* Delta `LIMIT` orders and TWAP rest or settle over time, so a permit's nonce or deadline expires before settlement. Use an on-chain approval for these, not a permit. See [Limit Orders and TWAP use on-chain approval](/resources/approvals#limit-orders-and-twap-use-on-chain-approval).

## Allowance checks before signing

| Allowance state                                                                         | Agent action                                                                                                                                                                        |
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowance >= amount` for the correct spender on the correct chain                      | Skip the approval step. Proceed to build → sign → submit.                                                                                                                           |
| `allowance < amount` for the correct spender                                            | Ask the user to approve at least `amount` (or `MaxUint256` if your UX prefers infinite). If the token supports Permit/Permit2, prefer a signed payload over a separate transaction. |
| `allowance` was set for a **different spender** (different mode)                        | Do not retry against the wrong spender. Ask for a fresh approval to the correct spender for the current quote's mode.                                                               |
| `allowance` is non-zero but you need to lower it for a non-standard ERC-20 (USDT-style) | Approve `0` first, then the new amount. Only required for the small set of tokens that reject non-zero → non-zero. Most modern ERC-20s accept it directly.                          |
| Connected chain differs from quote chain                                                | Stop. The chain used for quote, approval, signature, and execution must match. Ask the user to switch network before reading allowance or sending an approve.                       |

Agent rule: never request an approval before the quote response is final and you know the spender. Approvals to the wrong contract are not refunded by the user's wallet; they leave a stale allowance behind and confuse the next flow.

## Failure modes

| Symptom                                                                                           | Likely cause                                                                                             | Agent recovery                                                                                                                                                                                                                                               |
| ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Approval transaction confirms but the next swap/order still reverts with `insufficient allowance` | Approval was granted to the wrong spender (e.g., Augustus instead of the Delta contract, or vice versa). | Re-read the quote response, identify the correct spender from the spender matrix above, and request a fresh approval to that contract. See the [Delta orders/build failure modes](/api-reference/troubleshooting) row for "Approval reverts before signing". |
| Approval confirms on chain A but the swap is on chain B                                           | Wallet was on a different network when the approve was signed.                                           | Ask the user to switch to the quote's chain and re-approve there. Allowances are per-chain.                                                                                                                                                                  |
| `400 Invalid srcToken` on quote or build for native ETH                                           | Sent `0x0` or lowercase `0xeee...e` instead of the canonical placeholder.                                | Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` (mixed case) and requote.                                                                                                                                                                                   |
| `400 Permit / Permit2 required` from `POST /v2/delta/orders/build`                                | Token requires Permit/Permit2 and no payload was attached.                                               | Collect the signed Permit or Permit2 payload up front and include it in the build request. Falling back to a separate `approve` transaction is not supported for these tokens.                                                                               |
| User approved infinite (`MaxUint256`) to one mode's spender, now wants the other mode             | Each mode has its own spender. The first allowance is fine but does not authorize the second mode.       | Read allowance against the new mode's spender and request a separate approval. Do not treat the existing infinite allowance as universal.                                                                                                                    |
| User rejects the approve transaction or the Permit/Permit2 signature                              | Explicit user refusal.                                                                                   | Stop. Do not retry automatically. Surface the rejection and ask how to proceed: a different source token, a different mode, or abort.                                                                                                                        |

## Examples

### Branching by quote response

```text theme={null}
1. GET /v2/quote?mode=ALL with chainId, srcToken, destToken, amount, partner
2. If response has top-level `delta`:
   - spender = 0x0000000000bbf5c5fd284e657f01bd000933c96d (Delta contract)
3. Else if response has top-level `market`:
   - spender = 0x6a000f20005980200259b80c5102003040001068 (Augustus v6.2)
4. Else:
   - Stop. No route. Do not request an approval.
5. If srcToken is native placeholder:
   - Skip approval. Proceed to build.
6. Else:
   - Read allowance(srcToken, owner=user, spender)
   - If allowance < amount:
     - If srcToken supports Permit/Permit2: collect signature, attach to build
     - Else: request approve(spender, amount) on the quote's chainId
   - Wait for approval confirmation before continuing
7. Continue to build → sign → submit
```

### Switching modes mid-flow

If the user accepts a quote, the approval lands on the matching spender, then they ask to switch from Delta to Market (or vice versa) before signing:

* Requote in the new mode.
* Recheck allowance against the **new** spender. The previous approval does not carry over.
* Either approve again to the new spender, or attach a fresh Permit/Permit2 signature to the new build request.
* Confirm the user understands they're approving a second contract.

## Guardrails

* Take the spender from the **quote response shape**, not from natural language.
* Never approve Augustus for a Delta order. Never approve the Delta contract for a Market swap.
* Skip ERC-20 approval entirely for native source tokens; use the canonical mixed-case placeholder.
* Detect Permit/Permit2 capability before requesting a separate `approve` transaction.
* Use an on-chain approval, never a permit, for Delta `LIMIT` orders and TWAP.
* Re-check allowance against the new spender any time the execution mode changes.
* Treat Permit/Permit2 signatures as one-shot authorizations bound to spender, amount, and deadline; they do not transfer across modes or builds.
* Never assume an infinite allowance to one spender covers another.

<CardGroup cols={2}>
  <Card title="Approvals and permit" icon="signature" href="/resources/approvals">
    How approvals and permits work: spenders, Permit vs Permit2, native ETH.
  </Card>

  <Card title="Decision tables" icon="route" href="/for-agents/decision-tables">
    Route user intent and wallet state to the next agent action.
  </Card>

  <Card title="Five-call recipe" icon="repeat" href="/for-agents/five-call-recipe">
    The canonical agent loop: quote, build, authorize, submit, track.
  </Card>

  <Card title="Chains & contracts" icon="link" href="/resources/chains-and-contracts">
    Per-chain contract addresses for Delta, Augustus v6.2, and AugustusRFQ.
  </Card>
</CardGroup>
