> For the complete documentation index, see [llms.txt](https://docs.fira.money/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fira.money/developers/architecture/router-architecture.md).

# Router Architecture

## Overview

The `FiraRouterV4` is the single entry point for all user-facing protocol operations. It extends OpenZeppelin's `Proxy` and uses a selector-to-facet mapping to delegate every call to the appropriate action contract.

{% hint style="info" %}
Since the proxy uses `delegatecall`, all facets share the same storage. `RouterStorage` uses ERC-7201 storage namespacing (a hashed storage slot) to avoid collisions with any facet's own storage layout.
{% endhint %}

## How it works

### Call routing

When a user calls any function on the router:

1. The `fallback()` function reads `msg.sig` (the 4-byte function selector)
2. Looks up the registered facet address in `CoreStorage.selectorToFacet[msg.sig]`
3. If no facet is registered, reverts with `INVALID_SELECTOR`
4. Otherwise, `delegatecall`s into the facet contract

### Initialization

The constructor takes two arguments: the owner address and the `ActionStorageV4` facet address. It hard-wires the `setSelectorToFacets` and `selectorToFacet` selectors to the storage facet so the owner can configure all other mappings post-deployment.

### Upgrading

The owner can update selector-to-facet mappings at any time via `ActionStorageV4.setSelectorToFacets`. This allows:

* **Adding new features** — Register new selectors pointing to new facet contracts
* **Fixing bugs** — Point existing selectors to updated facet implementations
* **Removing features** — Set a selector's facet to `address(0)` to disable it

No state migration is needed because all facets share the router's storage via `delegatecall`.

## Facet contracts

| Facet                    | Responsibility                                              |
| ------------------------ | ----------------------------------------------------------- |
| **ActionSwapBTV3**       | BT swaps — token/FW to/from BT                              |
| **ActionSwapCTV3**       | CT swaps — synthesized via BT pool + mint/redeem            |
| **ActionAddRemoveLiqV3** | Liquidity operations — dual, single-sided, keep-CT variants |
| **ActionMiscV3**         | FW/BC minting, position exits, multicall, simulate          |
| **ActionBorrow**         | Fixed-rate borrow and repay via lending markets             |
| **ActionSimple**         | Gas-optimized operations using on-chain approximation       |
| **ActionCallbackV3**     | Flash-style swap callbacks from the market                  |
| **ActionStorageV4**      | Admin — ownership transfer, selector management             |

## CT swap synthesis

CT is not directly traded in the AMM (the pool only has BT and FW). CT swaps are synthesized using the flash-callback pattern:

**Buy CT (FW → CT):**

```mermaid
sequenceDiagram
  participant Router
  participant Market as FiraMarket
  participant CT as CouponToken

  Router->>Market: swapExactBtForFw (flash)
  Market-->>Router: FW out (sent first)
  Router->>CT: deposit FW, mintBC
  CT-->>Router: BT + CT minted
  Router->>Market: repay BT (callback)
  Router-->>Router: keep CT as output
```

**Sell CT (CT → FW):** The reverse — buy BT from market with FW, pair with user's CT, redeem BT+CT for FW.

## On-chain vs off-chain approximation

The router supports two modes for calculating swap amounts:

* **Off-chain hint** (`guessOffchain != 0`) — Binary search using `MarketApproxLibV2` with a hint provided by the caller. More gas-efficient for complex operations.
* **On-chain approximation** (`guessOffchain == 0`) — Closed-form approximation using `MarketApproxLibOnchain`. Simpler code path, lower gas cost, used automatically when no hint is provided and no limit orders are present.

## Related contracts

* [`FiraRouterV4.sol`](/developers/protocol-contracts/router.md) — Router contract details
* [Router Facets](/developers/protocol-contracts/router.md) — Individual facet documentation
* [Contract Deployments](/developers/deployment.md) — Deployed facet addresses


---

# 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://docs.fira.money/developers/architecture/router-architecture.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.
