Router Architecture
The Fira Router uses a diamond-like proxy pattern where each function selector maps to a specialized action facet via delegatecall.
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.
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.
How it works
Call routing
When a user calls any function on the router:
The
fallback()function readsmsg.sig(the 4-byte function selector)Looks up the registered facet address in
CoreStorage.selectorToFacet[msg.sig]If no facet is registered, reverts with
INVALID_SELECTOROtherwise,
delegatecalls 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
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):
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 usingMarketApproxLibV2with a hint provided by the caller. More gas-efficient for complex operations.On-chain approximation (
guessOffchain == 0) — Closed-form approximation usingMarketApproxLibOnchain. Simpler code path, lower gas cost, used automatically when no hint is provided and no limit orders are present.
Related contracts
FiraRouterV4.sol— Router contract detailsRouter Facets — Individual facet documentation
Contract Deployments — Deployed facet addresses
Last updated