> For the complete documentation index, see [llms.txt](https://docs.zama.org/protocol/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.zama.org/protocol/confidential-swap/reference/events-and-errors.md).

# Events and errors

The intent lifecycle events and the reverts worth handling when integrating with Confidential Swap.

## Events

These are the intent lifecycle events. Pair curation emits its own — `PairRegistered`, `PairActivated`, `PairDeactivated`, `PairFeeUpdated` — which is what you watch if you cache the pair list rather than reading it per intent.

### `IntentCreated`

```solidity
event IntentCreated(
    uint256 indexed intentId,
    address indexed maker,
    CandidateOrder[] orders,
    euint8 eRealIndex,
    euint64 eAmountOutMin,
    uint64 quotingEndsAtBlock,
    uint64 settlementEndsAtBlock,
    uint32 marketMakerCount,
    address marketMakerDecryptionAccess,
    address[] marketMakers,
    ebool eIsFunded
);
```

Everything an integration needs is on this one event. `orders` carries each candidate's `pairId`, snapshotted `feeShift`, direction, resolved input and output assets, and encrypted amount. `marketMakerDecryptionAccess` is the delegation context market makers pass when decrypting. `marketMakerCount` is how many distinct market makers must quote before the auction can resolve early. `marketMakers` is the restricted list when the maker set one, and empty when the intent is open to the full creation-time set. `eIsFunded` is publicly decryptable and is the only way to tell a live intent from a void one.

### `IntentQuoted`

```solidity
event IntentQuoted(uint256 indexed intentId, address indexed marketMaker, euint64[] eQuotes, euint8 eIndexMask);
```

One quote per candidate, in the bundle's order, each decryptable by the submitting market maker and compliance. `eIndexMask` is the submitting market maker's one-time pad, decryptable only by it, and reused across its subsequent quotes on the same intent.

### `IntentResolved`

```solidity
event IntentResolved(uint256 indexed intentId, eaddress eBestQuoter, euint8 eMaskedIndex, bool earlyResolved);
```

`eBestQuoter` and `eMaskedIndex` are both publicly decryptable. `eBestQuoter` decrypts to `address(0)` when no quote cleared the maker's floor — that is the no-winner signal, and a proof of that decryption is what `reclaimExpiredIntent` takes as `noWinnerProof`. The winner XORs `eMaskedIndex` with its own mask to recover which candidate was real; to everyone else it is a uniformly random byte, and it is the constant `0xFF` when there is no winner or when the intent is resolved after `settlementEndsAtBlock`. `earlyResolved` says whether the auction closed before its quoting window elapsed.

### `IntentSettled`

```solidity
event IntentSettled(
    uint256 indexed intentId,
    ebool eSucceed,
    address indexed maker,
    address indexed taker,
    address[] assets,
    euint64[] eAmountIns,
    euint64[] eAmountOuts
);
```

`taker` is the settling market maker — the one that called `settleIntent`. `assets` is every asset this intent touches — each candidate's sell asset and buy asset, each one listed once even when several candidates share it. The amount arrays line up with it position by position — `eAmountIns[i]` and `eAmountOuts[i]` both refer to `assets[i]`. To read one asset's amounts, find its index in `assets` and use that same index in both arrays.

The two arrays are non-zero at **different** positions. `eAmountIns` is what left the maker's escrow for the market maker, so it is encrypted zero except on the real order's sell asset. `eAmountOuts` is what the maker was paid, net of fee, so it is encrypted zero except on the real order's buy asset.

`eSucceed` is publicly decryptable; the amounts are decryptable by the maker, the settling market maker, and compliance.

### `IntentReclaimed`

```solidity
event IntentReclaimed(
    uint256 indexed intentId,
    address indexed maker,
    ebool eSucceed,
    address[] assets,
    euint64[] eTransferred
);
```

`assets` is the set of unique asset addresses the reclaim touches: the sell asset of each candidate, listed once. `eTransferred[i]` is the amount returned on `assets[i]`.

`eTransferred` is encrypted zero on every asset except the real order's. It is zero on all of them when the intent was already finalized by a settlement — the reclaim ran, but moved nothing. Decryptable by the maker and compliance.

{% hint style="warning" %}
**An emitted event is not proof of success.** Settlement and reclaim both emit whether or not anything moved. Public-decrypt `eSucceed`, or the `eIsFinalized` flag on the intent returned by `getIntent(intentId)`, before treating an intent as done.
{% endhint %}

## Errors

The complete set is in the ABI, and most reverts say what they mean: `ConfidentialSwap__AlreadyReclaimed`, `ConfidentialSwap__IntentNotResolved`, `ConfidentialSwap__SettlementPeriodExpired`, `ConfidentialSwap__InvalidIntentId` and the rest need no gloss. `EnforcedPause` means trading is paused; `AccessControlUnauthorizedAccount(account, role)` means the caller lacks the role.

These are the ones whose cause is not obvious from the name:

| Error                                                               | What it actually means                                                                                                                                                                              |
| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ConfidentialSwap__MarketMakerNotDelegated(intentId, marketMaker)`  | You are not delegated **on this intent**. Either the role was granted after the intent was created, or the intent is restricted to a different set. Holding `MARKET_MAKER_ROLE` today is not enough |
| `ConfidentialSwap__ConfidentialBalanceNotInitialized(token)`        | The settling market maker has no initialized balance on one of the bundle's assets — **every** asset it touches, not just the one being traded                                                      |
| `ConfidentialSwap__NotEnoughOrders(provided, minimum)`              | Fewer than two candidates. The decoys are the privacy mechanism, so a bundle below the minimum provides none                                                                                        |
| `ConfidentialSwap__TooManyOrders(provided, maximum)`                | More than six candidates. The cap is what settlement's FHE compute budget allows                                                                                                                    |
| `ConfidentialSwap__OrdersNotSorted(pairId, fromAsset0To1)`          | Candidates are not strictly ascending by `(pairId, fromAsset0To1)`. Strictness also rules out duplicate candidates                                                                                  |
| `ConfidentialSwap__MarketMakersNotStrictlyOrdered(marketMaker)`     | A restricted market-maker list must be sorted in strictly ascending address order. Strictness also rules out duplicates and the zero address                                                        |
| `ConfidentialSwap__ExpiredIntent(currentBlock, quotingEndsAtBlock)` | The **quoting** window closed, despite the generic name. Settlement expiry is a different error, `ConfidentialSwap__SettlementPeriodExpired`                                                        |
| `ConfidentialSwap__NoActiveMarketMaker()`                           | Nobody holds the role, so the intent could never be decrypted or filled. Intent creation depends on the maker set being non-empty                                                                   |
| `ConfidentialSwap__QuoteCountMismatch(provided, expected)`          | Not exactly one quote per candidate. You must price every order in the bundle, including the ones you believe are decoys                                                                            |

{% hint style="warning" %}
**Only the winner can settle, and a winner's settle can still fill nothing.** `settleIntent` reverts for any caller whose winner proof does not attest them. For the winner, absence of a revert is not a fill: a short balance moves zero and the encrypted success flag stays false — public-decrypt `eSucceed`.
{% endhint %}


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.zama.org/protocol/confidential-swap/reference/events-and-errors.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
