# What is Fira

Fira is a fixed-rate lending and borrowing protocol. It introduces maturity-based credit as a native onchain primitive — something DeFi has lacked since inception.

## The Problem: DeFi Has No Time Dimension

Over $60B sits in onchain lending markets. More than 99% of that exposure is floating-rate. Rates change every block. No maturities. No yield curve.

This creates three structural gaps:

* **Borrowers** cannot lock in their cost of capital
* **Lenders** cannot predict returns with certainty
* **Treasuries** cannot match assets to future obligations

Traditional credit markets operate on $145T of fixed-rate instruments — mortgages, corporate bonds, sovereign debt. These work because they have defined terms and known rates. DeFi has none of this.

## What Fira Does

Fira adds the missing dimension to onchain credit: **time**.

Every Fira loan has a defined maturity, a fixed rate locked at origination, and composable tokens that represent the position:

* **Bond Tokens (BTs)** represent the claim on principal at maturity. They trade at a discount before maturity and redeem 1:1 at term.
* **Coupon Tokens (CTs)** represent the yield portion. They accrue interest over time and can be sold for upfront yield.
* **FiraWrapped (FW)** tokens standardize yield-bearing collateral assets for use across Fira markets.

These tokens are tradable and composable. They create an onchain yield curve — a rate structure across maturities that DeFi has never had.

## How It Works

1. **Deposit collateral** into a Fira market
2. **Borrow at a fixed rate** — the rate is locked at origination, visible before execution
3. **At maturity**, BTs redeem 1:1. The borrower repays principal plus the accrued fee. The lender receives their principal back.

No variable rates. No surprise costs. The terms are set at entry.

> [Detailed mechanics](/getting-started/how-it-works)

## Markets

Fira is infrastructure, not a single product. Each **market** is an independent instance with its own collateral, loan token, parameters, and risk profile.

> [Markets Overview](/guides/overview)

## Security

Six independent audits before launch. Up to $500K bug bounty. Immutable interest rate contracts.

> [Security overview](/security-and-risk/security-overview) · [Audits](/security-and-risk/audits) · [Bug bounty](/security-and-risk/bug-bounty)

## Links

* [App](https://app.fira.money)
* [Simulator](https://simulator.fira.money)
* [DeFiLlama](https://defillama.com/protocol/tvl/fira)
* [Dune Dashboard](https://dune.com/usual_team/fira)


# How It Works

Fira is a fixed-rate lending protocol. Borrowers lock a rate for a defined period. Lenders earn predictable yield through Bond Tokens (BTs). Every position has a maturity date and a rate set at origination.

## The Core Loop

1. **Deposit collateral** — A borrower deposits an accepted collateral asset into a Fira market.
2. **Borrow at a fixed rate** — The protocol mints Bond Tokens (BTs) and Coupon Tokens (CTs). The borrower receives the loan token. The rate is locked.
3. **Maturity** — At the end of the term, BTs redeem 1:1. The borrower repays principal + accrued fee. The lender receives their principal back.

This loop runs the same way in every Fira market. The collateral, loan token, rate, and maturity change — the structure does not.

## Fixed Rates vs. Floating Rates

|                     | Floating-rate DeFi lending               | Fira                                               |
| ------------------- | ---------------------------------------- | -------------------------------------------------- |
| **Rate**            | Changes every block based on utilization | Fixed at origination for the full term             |
| **Term**            | Open-ended — no maturity                 | Defined maturity date                              |
| **Predictability**  | None — rates can spike 10x in a day      | Full — cost and yield known at entry               |
| **Position tokens** | Vault/Market Tokens                      | BT (principal) + CT (yield) — composable, tradable |

## Key Concepts

### Bond Token (BT)

Represents a claim on principal at maturity. Analogous to a zero-coupon bond. Trades at a discount before maturity and redeems 1:1 at term.

### Coupon Token (CT)

Represents the yield portion of a lending position. Accrues interest over time. Can be sold early for upfront yield or held to maturity.

### FiraWrapped (FW)

Wrapped yield-bearing tokens that standardize different collateral assets for use in Fira markets. FW tokens make any yield-bearing asset compatible with Fira's lending infrastructure.

### Markets

Each Fira market is an independent instance defined by a collateral asset, a loan asset, and a set of parameters (LTV, oracle, fee, maturity).

> [Full token mechanics](/protocol/token-mechanics) · [Architecture overview](/protocol/architecture-overview)

## For Different Users

**Borrowers** borrow at a known cost. No surprise rate hikes. The total cost of the loan is visible before execution.

> [Borrower Guide](/guides/borrower-guide)

**Lenders** earn predictable yield by purchasing BTs at a discount. The return is set at purchase — not subject to utilization changes.

> [Lender Guide](/guides/lender-guide)

**LPs** provide liquidity to the rate discovery AMM and earn trading fees plus rehypothecation yield.

> [LP Guide](/guides/lp-guide)


# FAQ

## General

### What is Fira?

Fira is a lending and borrowing protocol that brings fixed-rate, maturity-based credit markets onchain. It adds the missing dimension to DeFi lending: time.

### Why does DeFi need fixed rates?

Variable-rate lending requires constant monitoring. Rates shift with every block. Fira enables borrowers to lock a rate at entry and know their cost upfront — the same certainty that defines traditional credit markets, built natively onchain.

### Who built Fira?

Fira was initiated by Steady Labs.

### How does Fira work?

Fira decomposes yield-bearing assets into tradable components — Bond Tokens (BT) for principal and Coupon Tokens (CT) for yield. The discount at which BT trades determines the implied fixed rate. See [How It Works](/getting-started/how-it-works) for the full mechanism.

### Which blockchain is Fira deployed on?

Ethereum mainnet. Contract addresses are listed on the [Contracts & Addresses](/resources/contracts-addresses) page.

## Features

### How does fixed-rate borrowing work?

Post collateral, borrow BT, and swap BT for the underlying asset. The exchange rate at the time of the swap locks your effective borrow cost. The router handles all steps in a single transaction. See the [Borrower Guide](/guides/borrower-guide).

### Can I lend at a fixed rate?

Yes — in V1 fixed-rate markets. Lenders swap the underlying for BT at a discount. At maturity, BT redeems 1:1, and the discount is the lender's fixed yield.

### Does Fira offer variable-rate markets?

Yes. Fira offers variable-rate markets which it calls Floating-Rate Markets. These markets have similar mechanics to other onchain credit protocols such that the rates are spot rates and rely on utilization of the supplied assets to the market.

## Security

### Is Fira audited?

Six independent external audits were completed before launch — by Sherlock (×2), Spearbit/Cantina, yAudit (×2), and Hexens. All findings were resolved before deployment. Full reports are available on the [Security](/security-and-risk/security-overview) page.

### Is there a bug bounty?

Yes. Fira maintains a live bug bounty program through Sherlock with rewards up to $500K for critical vulnerabilities. See [Bug Bounty](/security-and-risk/bug-bounty).

### Where can I verify the smart contracts?

All deployed contracts are verified on Etherscan. Addresses are listed on the [Contracts & Addresses](/resources/contracts-addresses) page.

## Support

### Where can I get help?

* **Documentation**: This GitBook covers all protocol mechanics, features, and risk information. Further, for a full explanation of all mechanics, see the [Whitepaper](/resources/whitepaper).
* **Email**: <support@fira.money> for direct support
* **Security issues**: Report through the [Sherlock Bug Bounty](/security-and-risk/bug-bounty) platform


# Markets Overview

Fira is modular lending infrastructure. Each **market** is an independent instance with its own collateral, loan token, parameters, and risk profile.

## What Defines a Market

Every Fira market is defined by:

| Parameter                   | Description                                                          |
| --------------------------- | -------------------------------------------------------------------- |
| **Collateral asset**        | The token deposited by borrowers                                     |
| **Loan asset**              | The token borrowed against collateral                                |
| **Max LTV (Loan-to-Value)** | Maximum borrowing ratio                                              |
| **LLTV**                    | Liquidation LTV — the threshold at which positions can be liquidated |
| **Oracle**                  | Price feed determining collateral value                              |
| **Maturity**                | Term length for fixed-rate positions                                 |
| **Protocol fee**            | Fee charged by the protocol (in APR)                                 |
| **IRM**                     | Interest Rate Model governing rate discovery                         |

This modular design means Fira can support any pair of assets — stablecoins, yield-bearing tokens, LSTs, or governance tokens — each with parameters calibrated to the specific risk profile of that pair.

## V1 Market Types

Fira V1 introduces three market types, each serving different credit needs:

### Fixed-Rate Markets

Borrowers and lenders lock rates for a defined maturity via Bond Tokens (BTs). BTs trade at a discount before maturity on the fixed-rate AMM. The discount determines the implied rate.

> [Fixed-Rate Markets — Protocol](/protocol/fixed-rate-markets)

### Floating-Rate Markets

Variable-rate borrowing and lending without maturity constraints. Rates adjust dynamically based on utilization — similar to existing DeFi lending protocols, but integrated into Fira's infrastructure.

> [Floating-Rate Markets — Protocol](/protocol/floating-rate-markets)

### Dynamic Lending

LPs provide liquidity to the fixed-rate AMM while unused liquidity is rehypothecated to floating-rate vaults. LPs earn both trading fees and lending yield. Coupon Tokens (CTs) represent the yield portion and are tradable.

> [Rehypothecation](/protocol/rehypothecation) · [Fixed-Rate Markets — Protocol](/protocol/fixed-rate-markets) · [Floating-Rate Markets — Protocol](/protocol/floating-rate-markets)

## Related

* [Architecture Overview](/protocol/architecture-overview) — How markets connect to the broader system
* [Token Mechanics](/protocol/token-mechanics) — BT, CT, and FW token mechanics
* [Risk Framework](/security-and-risk/risk-framework) — How risk is assessed per market


# Borrower Guide

## The Problem with Variable Rates

On Aave or Compound, your borrowing rate changes every block. You open a position at 3% and wake up to 15%. There is no way to plan, budget, or manage the cost of capital over time.

In traditional finance, $145 trillion of credit operates at fixed rates. In DeFi, less than 1% does. Fira closes this gap.

## How Fira Fixes Your Rate

Fira uses **Bond Tokens (BT)** — zero-coupon bonds that trade at a discount before maturity and converge to par (face value) at maturity.

The borrowing cost is not an interest rate applied on top of your loan. It is embedded in the discount at which you receive liquidity.

**The discount IS the rate. There is no hidden interest.**

### How It Works

1. You post collateral
2. The protocol mints BT against your collateral
3. You swap BT for USDC (via FW-USDC) at a discount
4. At maturity, you repay the BT at par value to unlock your collateral

The difference between what you received and what you repay is your total, fixed cost of borrowing — known from the moment you open the position.

## Concrete Example: Fixed-Rate Borrowing

**Scenario:** You want to borrow USDC against collateral on the June 25, 2026 maturity market.

| Step | Action                                            | Amount                        |
| ---- | ------------------------------------------------- | ----------------------------- |
| 1    | Post collateral (e.g., PT-reUSD)                  | Sufficient for desired borrow |
| 2    | Mint 100 BT-USDC                                  | 100 BT-USDC                   |
| 3    | Swap 100 BT-USDC for FW-USDC, then unwrap to USDC | Receive \~95 USDC             |
| 4    | At maturity (June 25), repay 100 BT-USDC          | Repay 100 USDC equivalent     |

**Result:**

* You received 95 USDC today
* You repay 100 at maturity
* **Fixed cost = 5 USDC, known from day 1**
* Annualized: approximately 5.26% on a \~4-month term — locked at origination

No rate changes. No surprises. No variable rate volatility.

## V1: New Features for Borrowers

### Pendle PT Collateral

V1 introduces **Pendle PT tokens** as accepted collateral for fixed-rate borrowing:

If you already hold Pendle PTs, you can now borrow at a fixed rate against them on Fira — no need to sell your PT position.

### Multiple Maturities

V1 launches with the ability to add any set of maturity markets:

Choose the maturity that matches your investment horizon. Shorter maturities carry lower duration risk. Longer maturities may offer different implied rates.

### Fixed-Rate Markets

V1 fixed-rate markets use market-discovered rates. You choose a maturity, the AMM discovers the rate through supply and demand. The rate you get at the moment of your swap is your fixed rate for the duration.

### Floating-Rate Markets

Floating rate markets are available on Fira as well and are designed similarly to other protocols. These rates are spot and floating as they can dynamically changes based on the utilization of supplied assets in the market.

## Fira Fixed Rate vs. Variable Rate Protocols

| Feature                 | Fira (Fixed Rate)                                                  | Aave / Compound (Variable Rate)                                     |
| ----------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
| **Rate predictability** | Fixed at origination. Known from day 1.                            | Changes every block based on utilization.                           |
| **Rate mechanism**      | Discount on zero-coupon bond (BT). No explicit interest charge.    | Utilization curve. Interest accrues continuously at variable rate.  |
| **Cost visibility**     | Total cost known upfront in USDC terms.                            | Total cost unknown until position is closed.                        |
| **Maturity**            | Defined.                                                           | None. Open-ended.                                                   |
| **Early repayment**     | Possible at any time. Effective rate may differ from initial rate. | Always at current variable rate.                                    |
| **Rate spikes**         | Position is immune to rate spikes after origination.               | Exposed to sudden rate increases (can jump 3% to 15% in one block). |

## Risk Disclosure

Borrowing on Fira carries material risks. Read this section carefully before committing capital.

### Liquidation Risk

If the health factor of your position drops below 1, your collateral becomes eligible for liquidation. The health factor depends on the Loan-to-Value ratio relative to the Liquidation LTV threshold.

* **V1 fixed-rate markets:** Collateral value depends on oracle pricing. PT collateral carries price exposure. Market movements can trigger liquidation before maturity.

Liquidators receive a bonus (Liquidation Incentive Factor up to 1.15x depending on LLTV), meaning you lose more collateral than the debt repaid. For full liquidation mechanics, see [Liquidations](/protocol/liquidations).

### Early Repayment Does Not Lock the Fixed Rate

The fixed rate is only realized **if you hold the position to maturity**. If you repay early:

* You still repay the original BT amount (no reduction in principal)
* But the effective rate may be higher or lower than the rate at origination, depending on the BT/FW-USDC exchange rate at the time of early repayment

Early repayment always costs less than or equal to the maximum cost at maturity, but the effective annualized rate is unpredictable.

### Smart Contract Risk

Fira is a newly deployed protocol. Despite six independent external audits, an extended internal review, and a bug bounty program up to $500K, residual risk of bugs, exploits, or loss of funds remains. For audit details, see [Audits](/security-and-risk/audits).

### Additional Risks

* **Slippage risk:** Large swaps on the AMM may incur price impact, especially in low-liquidity conditions
* **Oracle risk:** V1 markets rely on external price feeds (Chainlink, Redstone) for collateral valuation
* **One-way migration:** Positions migrated from Euler to Fira cannot be sent back

For the complete risk framework, see [Risk Framework](/security-and-risk/risk-framework).

## Related

* [Fixed Rate Markets](/protocol/fixed-rate-markets) - Detailed explanation of the mechanics behind fixed rate markets
* [Floating Rate Markets](/protocol/floating-rate-markets) - Detailed explanation of the mechanics behind floating rate markets
* [Liquidations](/protocol/liquidations) — Position health and liquidation mechanics

*This document is for informational purposes only and does not constitute financial advice. DeFi participation carries risk of partial or total loss of funds. All parameters are subject to governance approval.*


# Lender Guide

## The Missing Piece in DeFi Lending

On existing DeFi lending platforms, your yield changes every block. You deposit at 5% APR and a week later it is 2%. Or 12%. There is no way to know what you will earn over a defined period.

Global fixed-income markets represent $145 trillion. DeFi lending holds approximately $64 billion — roughly 0.04% penetration. The gap is not yield. It is predictability.

Fira introduces fixed-rate lending onchain, where the return is known at the moment of purchase, not revealed after the fact.

## How Fixed-Rate Lending Works on Fira

Fira uses **Bond Tokens (BT)** — zero-coupon bonds that trade at a discount before maturity and redeem at par (face value) when the maturity date is reached.

As a lender, you buy BT at a discount. At maturity, each BT redeems for 1 unit of the underlying asset. **The discount is your fixed yield.**

There is no interest rate that accrues daily. There is no utilization curve. You buy below par, you redeem at par. The difference is your return, known in advance.

### Step-by-Step

1. Wrap USDC into FW-USDC (Fira Wrapped USDC)
2. Use FW-USDC to buy BT-USDC on the fixed-rate AMM at a discount
3. Hold BT-USDC until maturity
4. At maturity, redeem BT-USDC for FW-USDC at par (1:1)
5. Unwrap FW-USDC back to USDC

The yield is locked at step 2 — the moment you purchase BT at its market price.

## Concrete Example: Lending at a Fixed Rate

**Scenario:** You want to earn a fixed return on the May 14, 2026 maturity market.

| Step | Action                     | Amount                              |
| ---- | -------------------------- | ----------------------------------- |
| 1    | Wrap 95 USDC into FW-USDC  | 95 FW-USDC (at 1:1 initial rate)    |
| 2    | Buy 100 BT-USDC on the AMM | Pay 95 FW-USDC, receive 100 BT-USDC |
| 3    | Hold until maturity        | —                                   |
| 4    | Redeem 100 BT-USDC at par  | Receive 100 FW-USDC                 |
| 5    | Unwrap FW-USDC to USDC     | Receive \~100 USDC                  |

**Result:**

* You deposited 95 USDC
* You received 100 USDC at maturity
* **Fixed yield = 5 USDC, known at the moment of purchase**
* Annualized: approximately 5.26% on a \~2-month term

The return is determined by the BT price at purchase. Once bought, rate movements in the broader market do not affect your position. You hold to maturity, you receive par.

## BT: A Composable Fixed-Income Primitive

BT-USDC is not locked or staked. It is a standard **ERC-20 token** that can be:

* **Held to maturity** for the fixed yield
* **Sold before maturity** on the Fira AMM at the current market price
* **Transferred** to any Ethereum address
* **Used as collateral** in other DeFi protocols that accept ERC-20 tokens
* **Integrated** into structured strategies (e.g., fixed-rate tranches, hedging instruments)

BT is the onchain equivalent of a zero-coupon bond. It is the building block for fixed-income strategies in DeFi. For full token mechanics, see [Token Mechanics](/protocol/token-mechanics).

## Two Ways to Lend

### Option 1: Fixed Rates - Direct BT Purchase

Buy BT-USDC directly on the fixed-rate AMM. You choose the maturity, you see the price, you know the return. Full control over entry timing and maturity selection.

**Best for:** Advanced users, DAO treasuries with specific maturity targets, investors who want to manage duration actively.

**Token received:** BT-USDC — a tradable ERC-20 token. BT can be held, sold on the AMM before maturity (at market price), or used in other DeFi strategies. It is composable.

### Option 2: Floating Rates (Supply to Market/Vault)

Deposit USDC into a **floating rate market or** **curated vault.** By depositing directly into a market, the user earns the lending rate from that market and is exposed to any risk associated with that market (bad debt risk). On the other hand, the curated vault has a professional curator allocates capital across floating-rate markets on your behalf. The curator manages maturity selection, rate optimization, and risk parameters within DAO-approved constraints.

**How it works:**

* Deposit USDC into the market or vault
* *Curated vault*: The curator allocates across available maturities and market types
* The market or vault share appreciates as yield accrues
* Withdraw at any time (subject to vault liquidity)

For more on curation and floating rate markets, see [Curation Vaults](/protocol/curation-vaults) or [Floating Rate Markets](/protocol/floating-rate-markets).

## What Fira Is Not

To set expectations accurately:

| Misconception                          | Reality                                                                                                                                 |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| "Fixed yield means no risk"            | Fixed rate means the return is predictable **if held to maturity**. Other risks (smart contract, bad debt) remain.                      |
| "I can exit anytime at the fixed rate" | Exiting before maturity means selling BT at market price. The effective yield may be higher or lower than the implied rate at purchase. |
| "The rate is set by the protocol"      | Rates are discovered by market supply and demand in the AMM. The protocol does not set rates.                                           |
| "This is a savings account"            | This is a DeFi lending position with smart contract risk, bad debt risk, and market risk.                                               |

## Risk Disclosure

Lending on Fira carries material risks. Read this section carefully before depositing capital.

### Fixed Rate Applies Only at Maturity

The fixed rate is the return you receive **if you hold BT to maturity and redeem at par**. If you sell BT before maturity:

* You sell at the current AMM market price
* The effective yield may be higher or lower than the rate implied at purchase
* In a rising-rate environment, BT prices drop (you sell at a loss relative to par)
* In a falling-rate environment, BT prices rise (you realize a gain before maturity)

**The word "fixed" does not mean "risk-free." It means the return is known in advance if held to the defined maturity.**

### Bad Debt Risk

If borrowers' collateral cannot be liquidated for enough value to cover outstanding loans, the shortfall is socialized among lenders. This reduces the FW-USDC/USDC exchange rate, meaning your redemption at maturity may return less than par.

Bad debt can originate from:

* Fixed-rate borrowers whose collateral drops in value faster than liquidation can execute
* Rehypothecated reserves in variable-rate vaults

Overcollateralization and liquidation incentives (LIF up to 1.15x) reduce but do not eliminate this risk. For details, see [Bad Debt Risk](/security-and-risk/risk-framework/bad-debt-risk).

### Smart Contract Risk

Fira is a newly deployed protocol. Despite six independent external audits, an extended internal review, and a bug bounty program up to $500K, residual risk of bugs, exploits, or vulnerabilities remains. Participation in any DeFi protocol carries the risk of partial or total loss of funds. For audit details, see [Audits](/security-and-risk/audits).

### Liquidity Risk

A portion of FW-USDC reserves is rehypothecated into variable-rate vaults. If a large withdrawal coincides with high vault utilization, temporary withdrawal restrictions may apply until the rehypothecation module rebalances. The reserve ratio target is 90%, with only approximately 10% of reserves rehypothecated at any time. For more, see [Liquidity Risk](/security-and-risk/risk-framework/liquidity-risk).

## Related

* [Fixed-Rate Markets](/protocol/fixed-rate-markets) — How the fixed-rate AMM works
* [Token Mechanics](/protocol/token-mechanics) — BT, CT, and FW token design
* [Curation Vaults](/protocol/curation-vaults) — Curated vault architecture
* [Rehypothecation](/protocol/rehypothecation) — How FW-USDC reserves generate yield
* [Audits](/security-and-risk/audits) — Six independent external audits
* [Risk Framework](/security-and-risk/risk-framework) — Full risk overview

*This document is for informational purposes only and does not constitute financial advice. Returns described are projections based on market mechanics and are not assured. DeFi participation carries risk of partial or total loss of funds. All parameters are subject to governance approval.*


# LP Guide

## The LP's Structural Role

On Fira, the liquidity provider is not a traditional lender. The LP provides the capital that makes fixed-rate markets function. Without LPs, there is no pool, no BT/FW exchange, and no market-discovered rates.

DeFi lending today holds approximately $64 billion. Global fixed-rate debt exceeds $145 trillion. The structural gap is not yield — it is time. Fira introduces maturity-based markets where rates are discovered through supply and demand, not dictated by utilization curves. LPs are the actors who make this rate discovery possible.

An LP position on Fira is a dynamic portfolio of FW-USDC (cash equivalent) and BT-USDC (fixed-maturity bonds). The LP earns from three independent yield sources. All LP operations — minting, swapping, redeeming, migrating — carry **zero fees**.

## Key Parameters

| Parameter                      | Value                                   |
| ------------------------------ | --------------------------------------- |
| Base asset                     | USDC                                    |
| Wrapped asset                  | FW-USDC (Fira Wrapped USDC)             |
| Market type                    | Fixed-rate AMM (BT-USDC / FW-USDC)      |
| V1 maturities                  | May 7, 2026 · May 27, 2026 (USDG)       |
| Borrower collateral            | Pendle PTs (PT-USDe, PT-sUSDe, PT-USDG) |
| Projected LP yield             | 6-14% APR                               |
| Fees charged to LP             | 0% on all operations                    |
| Rehypothecation reserve target | 90% (bounds: 89.89% min, 91% max)       |
| Chain                          | Ethereum Mainnet                        |

## How It Works

### 1. Entry

Deposit USDC into Fira. The protocol mints FW-USDC (Fira Wrapped USDC) at the current exchange rate. Then deposit FW-USDC into a fixed-rate market by selecting a specific maturity.

Upon deposit, FW-USDC is decomposed according to the pool's current composition:

```
1 FW-USDC --> proportional BT-USDC (stays in pool) + CT-USDC (LP receives)
```

The LP receives an **LP token** representing their share of the pool. Any CT-USDC minted during this process belongs to the LP and can be managed independently.

### 2. Yield Accrual

The LP token accrues value over time from three distinct yield sources (detailed below). Yield is realized upon redemption — the LP token appreciates in price as the pool accumulates fees and interest.

### 3. Rolling Maturities

If a market matures before the LP's desired exit date, the LP redeems their position and redeposits into a subsequent maturity market. This roll must be completed within 48 hours of the prior market's maturity. Multiple rolls are possible across V1's available maturities.

### 4. Exit

The LP redeems the LP token and receives FW-USDC and BT-USDC proportional to the pool's composition at withdrawal.

* **At maturity:** BT-USDC redeems 1:1 for the underlying asset. No slippage. Full value returned.
* **Before maturity:** BT-USDC trades at a discount to FW-USDC. Selling BT-USDC on the AMM incurs slippage proportional to time remaining and available liquidity. The LP may alternatively hold BT-USDC until maturity to avoid slippage — BT converges to par as maturity approaches.

After collecting FW-USDC, the LP unwraps it to USDC at the current exchange rate.

## Three Yield Sources

LP yield on Fira is a composite of three independent sources. Each has distinct drivers and risk profiles.

### Source 1: Swap Fees

Every trade in the BT-USDC / FW-USDC AMM generates fees collected by LPs. Swap fee revenue is a direct function of trading volume in the pool — borrower entries, lender purchases, arbitrage activity, and rollovers all contribute.

**Driver:** Trade volume.

### Source 2: Net Lending Interest

When borrowers mint and swap BT-USDC in the AMM, the LP's pool composition shifts toward holding more BT-USDC. At maturity, each BT-USDC redeems 1:1 for the underlying asset. The difference between the discounted acquisition price in the pool and the par redemption value is the net lending interest earned.

**Driver:** The implied fixed rate of the pool. Higher rates produce larger BT discounts, which translate to higher lending interest at settlement.

### Source 3: Rehypothecation Yield

Fira deploys a portion of FW-USDC reserves into variable-rate vaults (SisuVault). These vaults lend USDC against crypto collateral (WBTC, WETH) on Fira's floating-rate markets. The interest earned accrues to CT-USDC holders and flows through to the FW-USDC exchange rate. For the reserve allocation model and rebalancing mechanics, see [Rehypothecation](/protocol/rehypothecation).

**Driver:** Variable-rate borrowing demand and utilization in the rehypothecation vaults.

**Reserve allocation:** The protocol maintains a 90% target reserve ratio, with bounds at 89.89% (min) and 91% (max). When the ratio drifts outside these bounds, the protocol rebalances automatically. Only approximately 10% of reserves are rehypothecated at any time.

### Yield Summary

| Component                        | Driver                                                   |
| -------------------------------- | -------------------------------------------------------- |
| Swap fees + Net lending interest | Trading volume and implied fixed rate in the AMM         |
| Rehypothecation yield            | Variable-rate borrowing demand in rehypothecation vaults |

**Projected combined yield: 5-13% APR** (swap fees + net lending interest + rehypothecation yield).

## Token Mechanics

Fira's fixed-rate markets operate with four token types. The fundamental invariant:

$$
1 \hspace{0.1cm} \text{FW} = \mu\_{s}(t) \hspace{0.1cm} \text{BT} + \mu\_s(t) \hspace{0.1cm} \text{CT}
$$

| Token        | Role                           | Behavior                                                                                                                                           |
| ------------ | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| **FW-USDC**  | Wrapped USDC (cash equivalent) | Mintable and redeemable for USDC at any time. Exchange rate appreciates over time as rehypothecation generates yield. ERC-20 / ERC-4626 compliant. |
| **BT-USDC**  | Zero-coupon bond (principal)   | Trades at a discount to FW-USDC before maturity. Redeems 1:1 at expiry with the underlying. The discount reflects the implied fixed rate.          |
| **CT-USDC**  | Yield token (interest)         | Accrues rehypothecation yield from FW-USDC reserves. Tradable before maturity.                                                                     |
| **LP Token** | Pool share                     | Represents the LP's proportional claim on the AMM pool (mix of BT-USDC and FW-USDC). Accrues swap fees and lending interest.                       |

For detailed token design, wrapping rate mechanics, and decomposition/reconstruction formulas, see [Token Mechanics](/protocol/token-mechanics).

### CT Optionality: The LP's Strategic Choice

When depositing FW-USDC, the pool decomposes it into BT-USDC and CT-USDC. The CT-USDC is returned to the LP. Two options:

**Option A — Hold CT to maturity.** Collect all rehypothecation yield accrued over the period. The yield flows from the variable-rate vault interest, distributed proportionally to CT holders.

**Option B — Sell CT immediately.** Monetize the present value of expected future rehypothecation yield upfront. Selling CT returns FW-USDC to the pool, increasing available liquidity. This is economically equivalent to locking in a yield rate today rather than bearing floating-rate exposure.

CT is a hybrid instrument: its cash flows depend on floating-rate markets (rehypothecation), but it trades in a fixed-rate market. A pricing equilibrium exists where the market price of CT equals the discounted expected value of its remaining rehypothecation yield.

## LP Behavior Under Rate Changes

An LP position is not a pure fixed-rate lending position. It is a dynamic portfolio of cash (FW-USDC) and bonds (BT-USDC). As market rates evolve:

* **Rates stay low:** Portfolio holds proportionally more FW-USDC (cash)
* **Rates increase:** Portfolio shifts toward more BT-USDC at lower prices

This rebalancing is economically similar to impermanent loss on Curve: the portfolio adjusts as the market moves.

### The Critical Difference

Unlike Curve impermanent loss, **this unrealized loss is only realized if the LP withdraws before maturity.** If the LP holds until maturity, BT-USDC converges to par, offsetting the unrealized loss from rate changes.

### LP vs. Lender: Rate Spike Comparison

A fixed-rate lender holding pure BT-USDC has concentrated exposure to interest rate movements. An LP holds a diversified portfolio of cash and bonds, which naturally dampens the impact.

**Scenario: entry at 4% implied rate, rate spikes to 10%**

| Actor                       | Exposure                   | Max drawdown           |
| --------------------------- | -------------------------- | ---------------------- |
| **Lender** (pure BT holder) | Full rate exposure         | \~5x higher than LP    |
| **LP** (BT + FW portfolio)  | Dampened by cash component | \~5x lower than lender |

The LP's diversified composition absorbs rate shocks. The lender's concentrated BT position amplifies them.

## Zero Operational Fees

| Operation                            | Fee                     |
| ------------------------------------ | ----------------------- |
| FW-USDC minting (USDC wrapping)      | 0%                      |
| FW-USDC redemption (USDC unwrapping) | 0%                      |
| LP deposit (FW decomposition)        | 0%                      |
| LP withdrawal (FW reconstruction)    | 0%                      |
| AMM swaps                            | Swap fee accrues to LPs |
| Rehypothecation                      | 0%                      |

All protocol-level operations are fee-free for LPs. Swap fees generated by trading activity accrue entirely to the LP pool. Standard Ethereum gas costs apply.

## Risk Factors

### 1. Duration Risk

Exiting before maturity means the LP redeems the LP token for FW-USDC and BT-USDC proportional to the pool's current composition. Selling BT-USDC for FW-USDC before maturity incurs slippage correlated to time remaining. Longer maturities carry higher duration risk.

**Mitigation:** Select maturities aligned with the investment horizon. Hold to maturity to eliminate duration risk. BT converges to par as maturity approaches — illiquidity does not imply loss.

### 2. Bad Debt Risk

LPs can incur bad debt from two sources:

* **Fixed-rate borrowers:** If collateral liquidation does not cover outstanding loans (extreme price decline, insufficient liquidation incentive), LPs absorb the shortfall. Bad debt reduces the FW-USDC/USDC exchange rate.
* **Rehypothecated reserves:** Variable-rate vault borrowers (WBTC/USDC, WETH/USDC) may also generate bad debt, similarly reducing the FW-USDC exchange rate.

**Mitigation:** All borrowing is overcollateralized. LLTV is set at conservative levels for variable-rate markets. Liquidation incentives (LIF up to 1.15x) compensate liquidators. Variable-rate vault caps ($5M per market) limit rehypothecation exposure. However, extreme market conditions can bypass these protections. For details, see [Bad Debt Risk](/security-and-risk/risk-framework/bad-debt-risk).

### 3. Liquidity Risk

Reserve rehypothecation means not all USDC backing FW-USDC is liquid at all times. If a large withdrawal coincides with high vault utilization, the LP may face temporary withdrawal restrictions until the rehypothecation module rebalances.

**Mitigation:** Reserve ratio maintained at 90% target with automatic rebalancing. Only approximately 10% of reserves are rehypothecated. Variable-rate vault caps ($5M each) limit total exposure. See [Liquidity Risk](/security-and-risk/risk-framework/liquidity-risk).

### 4. Smart Contract Risk

Fira is a newly deployed protocol. Smart contract risk includes coding errors, bugs, and potential exploits that could lead to partial or total loss of deposited funds.

**Mitigation:** Six independent external audits (Sherlock ×2, Spearbit/Cantina, yAudit ×2, Hexens), an extended internal review, and a bug bounty program up to $500K. Contracts deployed with transparent proxies on Ethereum Mainnet. These measures reduce but do not eliminate smart contract risk. For details, see [Audits](/security-and-risk/audits).

### 5. Rehypothecation Risk

A portion of FW-USDC reserves is lent through variable-rate vaults. The yield from this activity accrues to CT holders, but the underlying loans carry their own risk profile. If variable-rate borrowers default and liquidation proceeds are insufficient, the resulting bad debt reduces the FW-USDC exchange rate for all holders.

**Mitigation:** Conservative reserve parameters (90% target ratio). Vault caps of $5M per market. DAO governance over all rehypothecation parameters. See [Rehypothecation](/protocol/rehypothecation).

## Related

* [Fixed-Rate Markets](/protocol/fixed-rate-markets) — AMM mechanics and pricing
* [Token Mechanics](/protocol/token-mechanics) — BT, CT, FW, and LP token design
* [Rehypothecation](/protocol/rehypothecation) — Reserve allocation model
* [Curation Vaults](/protocol/curation-vaults) — Curated vault architecture
* [Liquidations](/protocol/liquidations) — Position health and liquidation mechanics
* [Contracts & Addresses](/resources/contracts-addresses) — Deployed contract addresses
* [UZR Simulator](https://simulator.fira.money/) — Stress-test market parameters

*This document is for informational purposes only and does not constitute financial advice. Projected yields are estimates based on modeling assumptions and are not assured. DeFi participation carries risk of partial or total loss of funds. All parameters are subject to governance approval.*


# Architecture Overview

Fira is a modular protocol composed of independent layers that combine to deliver fixed-rate, floating-rate, and curated lending. Each layer handles one responsibility. The layers connect through shared token standards and a unified router.

## System Layers

```
┌─────────────────────────────────────────────────────┐
│                   Router (Zapper)                   │
│         Multi-step user flows in one transaction    │
├──────────────┬───────────────┬──────────────────────┤
│  Fixed-Rate  │ Floating-Rate │     Curation         │
│    AMM       │   Lending     │      Vaults          │
│ (FiraMarket) │(LendingMarket)│   (SisuVault)        │
├──────────────┴───────────────┴──────────────────────┤
│                 Token Layer                         │
│           BT · CT · FW · LP Token                   │
├─────────────────────────────────────────────────────┤
│              Rehypothecation Module                 │
│          Reserve allocation between layers          │
├─────────────────────────────────────────────────────┤
│           Oracles · Interest Rate Models            │
│         Price feeds · Utilization-based IRM         │
└─────────────────────────────────────────────────────┘
```

## Token Layer

Three tokens form the foundation of every Fira market:

| Token  | Full Name    | Role                                                                                                                                                             |
| ------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **FW** | FiraWrapped  | Wrapped yield-bearing representation of the underlying asset (e.g., FW-USDC wraps USDC). Exchange rate appreciates over time as rehypothecation generates yield. |
| **BT** | Bond Token   | Principal token. Redeems 1:1 for the underlying at maturity. Trades at a discount before maturity — the discount is the implied fixed rate.                      |
| **CT** | Coupon Token | Yield token. Accrues rehypothecation yield from FW reserves. Tradable before maturity.                                                                           |

The core invariant across all markets:

$$
\mu(t) \hspace{0.1cm} \text{Underlying} = 1 \hspace{0.1cm} \text{FW} = \mu\_{s}(t) \hspace{0.1cm} \text{BT} + \mu\_s(t) \hspace{0.1cm} \text{CT}
$$

FW decomposes into BT + CT on deposit. BT + CT recombine into FW on redemption. All three are standard ERC-20 tokens.

For full token specifications, see [Token Mechanics](/protocol/token-mechanics).

## Fixed-Rate AMM

**FiraMarket** is the automated market maker for BT/FW trading. It is the mechanism through which fixed rates are discovered.

* LPs deposit FW into the pool, which decomposes into BT (stays in pool) + CT (returned to LP)
* Borrowers swap BT for FW — the exchange rate determines the fixed borrow rate
* Lenders swap FW for BT — the discount determines the fixed lending yield
* LP token holders earn swap fees and lending interest

The AMM uses an exchange-rate-based pricing formula that adjusts dynamically. As maturity approaches, BT price converges to par. Key parameters include `scalarRoot` (liquidity concentration) and `rateAnchor` (tracks the most recent implied rate).

For rate mechanics, see [Fixed-Rate Markets](/protocol/fixed-rate-markets).

## Lending Market

**LendingMarket** is the core lending engine, managing collateral, borrowing, interest accrual, and liquidation across multiple markets. It handles:

* **Supply and borrow** — Positions tracked per market, per user
* **Collateral management** — LTV and LLTV enforcement per market configuration
* **Interest accrual** — Continuous, per-second interest calculation
* **Liquidation** — Third-party liquidators repay debt and seize collateral at a bonus
* **Flash loans** — Atomic borrow-and-repay within a single transaction
* **Post-maturity settlement** — Forced liquidation of expired positions

Each market is defined by a collateral asset, a loan asset (as BT), an oracle, and risk parameters (LTV, LLTV, liquidation incentives). The same LendingMarket contract serves both fixed-rate and floating-rate markets.

For liquidation mechanics, see [Liquidations](/protocol/liquidations).

## Rehypothecation Module

The **RehypothecationModule** attaches to each FW token implementation and controls how idle reserves are allocated between liquid holdings and variable-rate vaults.

Three parameters govern the allocation:

* **φ\_min** — Below this ratio, reserves are withdrawn from the vault
* **φ\_max** — Above this ratio, excess reserves are deposited into the vault
* **φ\_target** — The ratio restored on every rebalance

Rebalancing triggers on every FW deposit or redemption, or manually by the FW owner. Yield from rehypothecated reserves accrues to CT holders.

For the full mechanism, see [Rehypothecation](/protocol/rehypothecation).

## Curation Vaults (SisuVault)

**SisuVault** is an ERC-4626 vault that allocates pooled capital across LendingMarket instances. It supports role-based access:

| Role          | Responsibility                                        |
| ------------- | ----------------------------------------------------- |
| **Owner**     | Top-level vault governance                            |
| **Curator**   | Defines strategy, supply caps, and market eligibility |
| **Allocator** | Executes capital deployment across markets            |
| **Guardian**  | Emergency controls and parameter timelocks            |

Curators set per-market supply caps and risk constraints. Allocators rebalance capital within those constraints. Configuration changes are subject to timelocks.

For vault mechanics, see [Curation Vaults](/protocol/curation-vaults).

## Router

**FiraRouter** is the protocol's transaction aggregator. It dispatches user calls to modular action contracts, combining multi-step flows into single transactions:

| Action Module          | Function                                              |
| ---------------------- | ----------------------------------------------------- |
| **ActionBorrow**       | Collateral deposit → BT borrow → swap to output token |
| **ActionSimple**       | Direct swaps between tokens, BT, and CT               |
| **ActionAddRemoveLiq** | LP deposits and withdrawals                           |
| **ActionSwapCT**       | Complex swaps involving Coupon Tokens                 |
| **ActionMisc**         | FW minting, reward redemption, utility operations     |

From the user's perspective, the router is the single entry point. Complex operations — deposit collateral, borrow, swap, and receive USDC — execute in one transaction.

## Interest Rate Models

Fira supports two interest rate strategies:

| Model                       | Used For              | Behavior                                              |
| --------------------------- | --------------------- | ----------------------------------------------------- |
| **Fixed Rate (address(0))** | Markets like UZR      | No interest accrual — rate is embedded in BT discount |
| **AdaptiveCurveIRM**        | Variable-rate markets | Dynamically adjusts borrow rate based on utilization  |

The AdaptiveCurveIRM uses a rate target that evolves over time, combined with a utilization curve that steepens above target utilization. For the full IRM specification, see [Floating-Rate Markets](/protocol/floating-rate-markets).

## Oracles

Price oracles feed collateral valuations into the LendingMarket for LTV checks and liquidation triggers:

| Oracle Type                    | Use Case                                       |
| ------------------------------ | ---------------------------------------------- |
| **Chainlink / Redstone feeds** | Market-priced collateral (ETH, BTC, PT tokens) |
| **Exchange rate oracles**      | Wrapped or rebasing tokens (stETH/ETH)         |
| **Fixed-price oracles**        | Pegged pairs (USD0/bUSD0 at 1:1)               |

For how oracles interact with liquidations, see [Liquidations](/protocol/liquidations).

## Liquidity Injector

The **LiquidityInjector** is a protocol-controlled contract that can mint BT on demand and supply it to the LendingMarket. This seeds fixed-rate lending markets without relying on external capital at launch. Only the authorized multisig can operate this contract. The injector can also withdraw and burn BT to reduce supply.

## How the Layers Connect

A typical fixed-rate borrowing flow illustrates how layers interact:

1. **Token Layer** — User wraps USDC into FW-USDC
2. **LendingMarket** — User supplies collateral, borrows BT
3. **Fixed-Rate AMM** — User swaps BT for FW-USDC at a discount
4. **Token Layer** — User unwraps FW-USDC to USDC
5. **Rehypothecation** — Idle FW reserves earn floating yield in variable-rate vaults
6. **Curation** — Curated vaults may allocate capital across multiple markets and maturities

The router compresses steps 1–4 into a single transaction.

## Related

* [Fixed-Rate Markets](/protocol/fixed-rate-markets) — BT/FW AMM mechanics and rate discovery
* [Floating-Rate Markets](/protocol/floating-rate-markets) — Variable-rate lending and IRM
* [Rehypothecation](/protocol/rehypothecation) — Reserve allocation and CT yield
* [Liquidations](/protocol/liquidations) — Enforcement and oracle integration
* [Curation Vaults](/protocol/curation-vaults) — Multi-layer capital allocation
* [Token Mechanics](/protocol/token-mechanics) — BT, CT, FW specifications
* [Contracts & Addresses](/resources/contracts-addresses) — Deployed contract addresses


# Token Mechanics

Complete reference for Fira's core tokens — Bond Token (BT), Coupon Token (CT), and FiraWrapped (FW)

Comprehensive reference for Fira's core token types. Fira's fixed-rate markets operate with three primary tokens — BT, CT, and FW — governed by the fundamental invariant: $$1 \hspace{0.1cm} \text{FW} = \mu\_{s}(t) \hspace{0.1cm} \text{BT} + \mu\_s(t) \hspace{0.1cm} \text{CT}$$.

## Token Overview

| Token       | Full Name              | Role                                                                                                                                                                                                                                     |
| ----------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **FW-XXXX** | **Fira Wrapped Asset** | Standard asset wrapped within Fira. Mintable and redeemable frictionlessly at any time. Each FW can be deconstructed into one BT and one CT, separating principal and interest components of a fixed-rate position.                      |
| **BT-XXXX** | **Bond Token**         | Zero-coupon bond representing a borrowed position that must be repaid at or before maturity. BT trades at a discount to FW — the discount reflects the fixed interest cost. At maturity, BT redeems 1:1 for the underlying asset.        |
| **CT-XXXX** | **Coupon Token**       | <p>Yield token representing the present value of unrealized interest. When BT is borrowed and swapped for FW at a discount, CT captures the remaining value. CT holders accrue interest and rewards from the</p><p>underlying yield.</p> |

***

## Wrapping Rate

All tokens are connected by a single fundamental invariant:

$$
\mu(t) \hspace{0.1cm} \text{Underlying} = 1 \hspace{0.1cm} \text{FW} = \mu\_{s}(t) \hspace{0.1cm} \text{BT} + \mu\_s(t) \hspace{0.1cm} \text{CT}
$$

The wrapping rate $$\mu(t)$$ specifically relates to the relationship between the underlying asset and the wrapped version (FW). We then have a modified version of this rate which is gross of bad debt loss. These two rates are computed as follows:

$$
\mu (t) = \frac{Reserve(t)}{Supplied(t)}
$$

Such that $$\mu(t)$$ is initialized at 1 and grows based on the earnings from rehypothecation (see [Rehypothecation](#rehypothecation)).

As bad debt is incurred, $$\mu(t)$$ will decrease in value as FW is redeemable for less of the underlying asset. However, the modified wrapping rate $$\mu \_s(t)$$ will not decrease. This is computed as follows:

$$
\mu\_s(t) = max(\mu(t),\mu\_s(t))
$$

Therefore the modified wrapping rate does not decrease. Specifically we do this for the accounting of yield distributed to CT (see [Rehypothecation](#rehypothecation)) as well as adapting the exchange rate from BT to FW based on this value (see [Fixed Rate Markets](/protocol/fixed-rate-markets)). See the [Whitepaper](/resources/whitepaper) for a full explanation.

***

## Bond Token (BT)

### Overview

BT (Bond Token) is an ERC-20 token representing the principal component of a fixed-rate position. Each BT redeems 1:1 into the underlying asset at expiry.

### Key Properties

* **Standard**: ERC-20 (based on `FiraERC20.sol` -- reentrancy-safe ERC20 base)
* **Redemption**: 1:1 for the underlying asset at maturity
* **Minting**: Only the corresponding CT contract or the LiquidityInjector can mint or burn BT
* **Trading**: Traded in the FiraMarket AMM, borrowed/lent in the lending market
* **Stored data**: Associated yield-token address (`FW`), expiry date
* **Contract**: [BondToken.sol](https://github.com/usual-dao/fira/blob/master/src/fira_bonding/core/YieldContracts/BondToken.sol)

### Price Behavior

BT trades at a discount to FW before maturity. The discount reflects the implied fixed yield (see [Fixed Rate Markets](/protocol/fixed-rate-markets)).

As maturity approaches, BT price converges toward 1:1 with the underlying. This convergence mechanism is what creates the fixed-rate dynamic:

* Borrowers sell BT at a discount now and repay at par later (the discount is their interest cost)
* Lenders buy BT at a discount and redeem at par later (the discount is their fixed yield)

> For the full mathematical treatment of fixed-rate pricing, see [Whitepaper](/resources/whitepaper).

### Creation Methods

1. **Deconstruction from FW**: Depositing FW into a Fira yield contract splits it into equal quantities of BT + CT
2. **Collateralized borrowing**: Borrowing BT through the LendingMarket against collateral (e.g. WBTC, WETH)
3. **LiquidityInjector minting**: Protocol-authorized contract that can mint BT to seed fixed-rate lending markets, ensuring market liquidity without relying on external actors

***

## Coupon Token (CT)

### Overview

CT (Coupon Token) is an ERC-20 token that tracks all interest and yield due on a given BT line. CT holders accrue interest and rewards from the underlying yield.

### Key Properties

* **Standard**: ERC-20 (based on `FiraERC20.sol`)
* **Function**: Represents the right to yield generated by the principal until maturity
* **Parent contract**: `InterestManagerCT.sol` -- handles calculation and distribution of yield from FW based on its exchange rate
* **Contract**: [CouponToken.sol](https://github.com/usual-dao/fira/blob/master/src/fira_bonding/core/YieldContracts/CouponToken.sol)
* **Interest Manager**: [InterestManagerCT.sol](https://github.com/usual-dao/fira/blob/master/src/fira_bonding/core/YieldContracts/InterestManagerCT.sol)

### Yield Mechanics

CT increases in value as FW accrues yield (i.e., as the redemption value of FW > 1 underlying). CT holders can:

* Hold CT until maturity and redeem for FW gains
* Sell CT earlier if market conditions are favorable

### Value Proposition

CT represents the present value of unrealized gains from fixed-rate loans. When BT tokens are borrowed and exchanged for their corresponding wrapped assets at a discount, CT tokens can be sold to realize the difference -- capturing the portion of value that was not initially extracted in the BT swap.

***

## FiraWrapped Token (FW)

### Overview

FW (FiraWrapped) is a yield-bearing wrapper for the underlying asset. For example, FW-USDC (also written `USDCFW`) wraps USDC.

### Key Properties

* **Standard**: ERC-20 / ERC-4626 compliant
* **Minting**: Users deposit the base asset (e.g. USDC) to mint FW tokens
* **Redemption**: FW can be redeemed back for the base asset at any time (frictionless)
* **Decomposition**: Each FW can be split into 1 BT + 1 CT via yield contracts
* **Exchange rate**: Tracks an exchange rate reflecting yield earned -- 1 FW gradually represents more underlying over time as interest accrues
* **Contract**: [USDCFW.sol](https://github.com/usual-dao/fira/blob/master/src/fira_bonding/StandardizedYield/implementations/USDCFW.sol)

### Rehypothecation

FW tokens internally invest a portion of deposited assets to earn yield via the **RehypothecationModule**. Idle USDC from FW is rehypothecated into variable-rate markets to generate yield. The rehypothecation is governed by three parameters:

| Parameter   | Description                           |
| ----------- | ------------------------------------- |
| `phiMin`    | Minimum allowed idle ratio            |
| `phiMax`    | Maximum allowed idle ratio            |
| `phiTarget` | Target idle ratio to rebalance toward |

The rebalancing logic moves deposited USDC between two states:

* **Idle** USDC held in the FW contract (readily redeemable)
* **Invested** USDC as shares in a **SisuVault**, where it earns variable yield by supplying to LendingMarkets

Rehypothecation is triggered on FW deposit or redeem function calls, and can also be triggered manually by the FW owner.

> For the formal treatment of rehypothecation mechanics, see [Rehypothecation](/protocol/rehypothecation) and the [Whitepaper](/resources/whitepaper).

### Role in the AMM

FW serves as the quote asset in the FiraMarket AMM. The AMM pricing of BT relative to FW determines the implied fixed interest rate for a given expiry.

***

## Token Strategy Summary

| Token  | Exposure           | Strategy                                                                                             |
| ------ | ------------------ | ---------------------------------------------------------------------------------------------------- |
| **BT** | Fixed yield        | Buy at discount, hold to maturity, redeem 1:1. No exposure to future rate changes.                   |
| **CT** | Floating yield     | Benefits from rising interest/yield rates. Value increases as FW accrues yield.                      |
| **FW** | Underlying + yield | Passive yield from rehypothecation. Can be split into BT+CT for more targeted strategies.            |
| **LP** | BT + FW (AMM)      | Exposure to both fixed-yield assets (BT) and yield-bearing tokens (FW), plus trading fee collection. |

***

## Contract Reference

| Component     | Contract            | Role                                                 |
| ------------- | ------------------- | ---------------------------------------------------- |
| BondToken     | `BondToken.sol`     | ERC-20 zero-coupon bond, matures 1:1 with underlying |
| CouponToken   | `CouponToken.sol`   | ERC-20 yield token, accrues interest from FW         |
| FiraWrapped   | `USDCFW.sol`        | Yield-bearing wrapper with rehypothecation           |
| FiraMarket    | `FiraMarket.sol`    | AMM for BT/FW trading and rate discovery             |
| LendingMarket | `LendingMarket.sol` | Core lending vault, collateral, liquidations         |
| SisuVault     | `SisuVault.sol`     | ERC-4626 vault for rehypothecation                   |

***

## Further Reading

* [Contracts & Addresses](/resources/contracts-addresses) — Deployed contract addresses on Ethereum Mainnet
* [Whitepaper](/resources/whitepaper) — Full mathematical treatment


# Fixed-Rate Markets

Fixed-rate markets are the core innovation in Fira. Borrowers lock a rate at origination. Lenders earn predictable yield. Both sides know their terms before executing.

The mechanism is built on zero-coupon bond mechanics: Bond Tokens (BTs) trade at a discount before maturity and converge to par at term. The discount is the rate.

## How Fixed-Rate Borrowing Works

1. **Post collateral** — The borrower deposits an approved collateral asset.
2. **Mint BTs** — The protocol creates Bond Tokens backed by that collateral. Each BT has a face value of 1 unit of the loan token.
3. **Swap BT for loan token** — The borrower swaps BTs for FiraWrapped tokens (FW) through the AMM, then unwraps FW into the underlying asset (e.g., USDC).
4. **Repay at maturity** — The borrower returns the same number of BTs borrowed, regardless of how much they received at origination.

The interest cost is not charged explicitly. It is embedded in the discount at which BTs trade. A borrower who receives 0.95 USDC per BT and repays 1.00 USDC per BT at maturity has paid a fixed rate proportional to that 5% spread over the holding period.

### Fixed-Rate Guarantee

This mechanism delivers a fixed-rate loan **when held to maturity**. Both the repayment amount and the maturity date are set at origination.

Early repayment is always possible but does not guarantee the same effective rate — the BT/USDC exchange rate fluctuates before maturity, so closing early may result in a higher or lower realized cost.

## How Fixed-Rate Lending Works

Lenders provide the other side of the AMM. By supplying FiraWrapped tokens (FW) to the liquidity pool, they enable borrowers to swap BTs for loan tokens.

When FW enters the pool, it is decomposed into its two components:

$$
1 \hspace{0.1cm} \text{FW} = \mu\_{s}(t) \hspace{0.1cm} \text{BT} + \mu\_s(t) \hspace{0.1cm} \text{CT}
$$

* **BT** remains in the pool to facilitate borrowing
* **CT** (Coupon Token) goes to the LP and represents the yield portion

Lenders who buy BTs at a discount and hold to maturity earn the difference — a fixed yield locked at purchase.

## Rate Discovery

Rates are not set by governance. They emerge from supply and demand in the BT/FW AMM. We define a BT/FW exchange rate (exchange rate expressed as BT acquired per 1 FW) as follows:

$$
\text{exchangeRate}(t)
\=
\mu\_s(t)\cdot\left( \frac{\ln!\left( \tfrac{p(t)}{1 - p(t)} \right)}{\text{rateScalar}(t)}
\+ \text{rateAnchor}(t) \right)
$$

Where:

* $$\mu\_s (t)$$ is the modified wrapping rate (see [Token Mechanics](/protocol/token-mechanics)).
* $$p(t) =n\_{\text{BT}}(t) /(n\_{\text{BT}}(t) + n\_{\text{FW}}(t))$$, such that $$n\_{BT}(t) , \space n\_{FW}(t)$$ are the number of BT and FW in the pool.
* $$rateScalar(t)=rootScalar / timeToExpiry(t)$$, such that $$rootScalar$$ is a DAO set concentration parameter (and $$timeToExpiry(t)$$ is the time to expiry, in years, for the fixed-rate market at time $$t$$).
* $$rateAnchor(t)$$ is a DAO set concentration parameter that drifts with the realized implied fixed-rate of the AMM (see [Whitepaper](/resources/whitepaper)).

Using the AMM, borrowers can swap to FW from BT (or vice versa for lenders). Using FW, they can then unwrap to the underlying asset at the wrapping rate:

$$
1 \hspace{0.1cm} \text{FW-USDC}=  \mu (t)\hspace{0.1cm} \text{USDC}
$$

Therefore the full conversion rate from BT to the underlying asset is:

$$
conversionRate(t)=\mu(t)\cdot exchangeRate(t)^{-1}=\frac{\mu(t)}{\mu\_s(t)}\left(\frac{\ln!\left( \tfrac{p(t)}{1 - p(t)} \right)}{\text{rateScalar}(t)}
\+ \text{rateAnchor}(t)\right)
$$

Meaning the implied fixed borrowing/lending rate is:

$$
impliedRate(t)=\left( conversionRate(t)^{-1} -1 \right) ^{\frac{1}{timeToExpiry(t)}}
$$

#### Settlement at Maturity

To simplify loan repayment at maturity, users can mint BT-USDC using USDC (via FW-USDC). Conversely, holders of BT-USDC can redeem their tokens for USDC (also via FW-USDC) after maturity. This creates a robust primary market for loan settlement and avoids potential inefficiencies\
or liquidity shortages that might arise from relying solely on secondary market pricing through the AMM.

However, it should be noted that the wrapping rate is modified after maturity and is fixed based on the last wrapping rate before maturity. Therefore the loan technically accrues some minimal interest while users wait to repay after maturity. This comes from the difference between the actual wrapping rate (from USDC to FW-USDC) and the now fixed modified wrapping rate (from FW-USDC to BT-USDC and CT-USDC).

## FiraWrapped Tokens (FW)

FW tokens wrap the underlying loan asset (e.g., FW-USDC wraps USDC). The wrapping rate is not constant — it reflects the total reserve value relative to FW supply:

$$
\mu (t) = \frac{Reserve(t)}{Supply\_{FW}(t)}
$$

At protocol initialization, 1 FW = 1 USDC. Over time, as reserves earn yield through [rehypothecation](/protocol/rehypothecation), the rate increases. This means FW gradually represents more underlying per token.

Borrowers receive FW and unwrap it to USDC. To repay, they rewrap USDC into FW before settlement.

## Coupon Token (CT) Trading

CTs represent the yield component of decomposed FW. They are tradable in the fixed-rate market through flash loan mechanisms:

* **Buy CT**: Flash-borrow FW → decompose into BT + CT → swap BT back to FW to repay the loan → keep CT
* **Sell CT**: Flash-borrow BT → combine with CT to reconstruct FW → swap portion to BT to repay → keep remaining FW

These operations execute atomically. LPs can also sell their CT positions early to realize yield upfront while adding liquidity to the pool.

## Maturity Settlement

At maturity, BTs redeem 1:1 for the underlying asset (via FW). Holders can:

* Redeem BT for USDC through FW
* Mint BT using USDC (via FW) to repay loans

This primary market settlement avoids dependence on secondary AMM liquidity at maturity.

## Related

* [Floating-Rate Markets](/protocol/floating-rate-markets) — Variable-rate borrowing without maturity
* [Token Mechanics](/protocol/token-mechanics) — BT, CT, and FW token reference
* [Rehypothecation](/protocol/rehypothecation) — How idle reserves earn yield
* [Whitepaper](/resources/whitepaper) — Full mathematical treatment


# Floating-Rate Markets

Floating-rate markets provide variable-rate borrowing and lending without maturity constraints. Rates adjust continuously based on utilization. These markets serve two purposes in Fira: standalone variable-rate lending, and the foundation for [rehypothecation](/protocol/rehypothecation) of fixed-rate market reserves.

## How It Works

* Lenders deposit assets into a pool and earn variable yield
* Borrowers post collateral and borrow from the pool, accruing interest continuously
* Both sides can enter and exit at any time — no maturity date
* Rates move with utilization: more borrowing means higher rates

### Lend Rate

$$
Lend\_{APR} = Borrow\_{rate}\times Utilization
$$

Because both rates are volatile, floating-rate markets suit short- to medium-term positions.

## Interest Rate Model (IRM)

The borrow rate is determined by a utilization-based Interest Rate Model. The core formula:

$$
r(t)=r\_T(t)\times curve(u(t))
$$

Where:

* $$r(t)$$ is the instantaneous spot borrowing rate
* $$r\_T(t)$$ is the rate target — the rate when utilization equals the target
* $$curve(u(t))$$ shapes how rates respond to utilization deviations

### Utilization

Represented as the fraction of supplied liquidity currently borrowed.

$$
u(t)=\frac{Borrowed(t)}{Supplied(t)}
$$

Further, using utilization, we compute an abstract value from our utility function $$e(u)$$.

$$
e(u) = \begin{cases} \dfrac{u - u\_{\text{target}}}{u\_{\text{target}}} & \text{if } u \leq u\_{\text{target}} \\\[8pt] \dfrac{u - u\_{\text{target}}}{1 - u\_{\text{target}}} & \text{if } u > u\_{\text{target}} \end{cases}
$$

### Rate Target

The rate target starts at a configured value and evolves dynamically:

$$
r\_T(t) = r\_T(t\*) × exp(k\_p × e(u) × (t-t\*))
$$

When utilization exceeds the target, the rate target increases — making borrowing more expensive and encouraging repayment. When utilization is below target, the rate target decreases — making borrowing cheaper and encouraging demand.

The utility function $$e(u)$$ symmetrically scales deviations above and below the target utilization $$u\_{target}$$.

### Utilization Curve

The curve function adds a second layer of rate responsiveness. Below target utilization, rates decrease gradually. Above target, rates increase sharply — creating natural pressure to keep utilization near the target.

$$
\text{curve}(u) = \begin{cases} \left(1 - \dfrac{1}{k\_d}\right) \cdot e(u) + 1 & \text{if } u \leq u\_{\text{target}} \\\[8pt] (k\_d - 1) \cdot e(u) + 1 & \text{if } u > u\_{\text{target}} \end{cases}
$$

The slope is controlled by $$k\_d$$, the curve steepness parameter.

### Rate Bounds

Rates are bounded between $$r\_{min}$$ and $$r\_{max}$$ to prevent extreme values:

$$
r(t) = \max!\bigl(\min!\bigl(r\_T(t) \cdot \text{curve}(u(t)),; r\_{\max}\bigr),; r\_{\min}\bigr)
$$

## Parameters

All IRM parameters are global across floating-rate markets and governed by the DAO:

| Parameter                   | Description                          |
| --------------------------- | ------------------------------------ |
| $$u\_{target}$$             | Target utilization ratio             |
| $$k\_p$$                    | Speed of rate target adjustment      |
| $$k\_d$$                    | Steepness of the utilization curve   |
| $$r\_T(0)$$                 | Initial rate target at market launch |
| $$r\_{min}$$ , $$r\_{max}$$ | Rate floor and ceiling               |

## Role in Fira's Architecture

Floating-rate markets integrate with the rest of Fira through:

* **Rehypothecation** — Idle reserves from fixed-rate markets (FW tokens) are deployed into floating-rate vaults to earn yield, which flows to CT holders
* **Curation** — Curated vaults can allocate capital across both fixed-rate and floating-rate markets
* **Composability** — The same collateral types and oracle infrastructure serve both market types

## Related

* [Fixed-Rate Markets](/protocol/fixed-rate-markets) — Maturity-based borrowing with locked rates
* [Rehypothecation](/protocol/rehypothecation) — How fixed-rate reserves earn floating yield
* [Curation Vaults](/protocol/curation-vaults) — Multi-layer capital allocation
* [Whitepaper](/resources/whitepaper) — Full mathematical treatment


# Rehypothecation

Rehypothecation is Fira's mechanism for making idle reserves productive. A portion of FW-USDC held in fixed-rate market pools is allocated to a variable-rate vault, where it earns floating yield. That yield flows to Coupon Token (CT) holders.

This creates the bridge between Fira's fixed-rate and floating-rate layers: LPs provide liquidity to the fixed-rate AMM, and the unused portion earns floating-rate yield in the background.

## Reserve Allocation Model

The system manages reserves through a **reserve ratio φ** — the fraction of liquid (unrehypothecated) reserves relative to total FW-USDC in the pool:

$$
\varphi = \frac{\text{USDC}*{\text{reserve}}}{\text{FW-USDC}*{\text{pool}}}\
$$

Three parameters control the allocation:

| Parameter              | Role                                                                    |
| ---------------------- | ----------------------------------------------------------------------- |
| $$\varphi \_{min}$$    | Minimum reserve ratio — below this, the system withdraws from the vault |
| $$\varphi \_{max}$$    | Maximum reserve ratio — above this, the system deposits into the vault  |
| $$\varphi \_{target}$$ | Target ratio — rebalancing restores φ to this value                     |

Currently, these are respectively set to 89.89%, 91% and 90%.

### How Rebalancing Works

The reserve ratio is checked on every market swap. If φ falls outside \[φ\_min, φ\_max]:

* $$\varphi < \varphi \_{min}$$ — Too much capital is rehypothecated. The system withdraws FW-USDC from the variable-rate vault back to liquid reserves.
* $$\varphi > \varphi \_{max}$$ — Too much capital sits idle. The system deposits excess FW-USDC into the variable-rate vault.

In both cases, the system restores φ to φ\_target.

## How CT Holders Earn Yield

All interest earned by rehypothecated liquidity is distributed to outstanding Coupon Token (CT) holders. The mechanism:

1. Rehypothecated USDC earns floating yield in the variable-rate vault
2. This yield increases the FW wrapping rate μ(t) — each FW represents more underlying over time
3. CT holders can claim the difference between the current and previous wrapping rates

### Claimable Yield

$$
\text{CT}*{\text{claim}}(t) = \left(1 - \frac{\mu\_s(t^\*)}{\mu\_s(t)}\right) \times \frac{\text{Balance}*{\text{CT}}(t)}{\mu\_s (t\*)}
$$

Where $$\mu \_s(t)$$ is the modified wrapping rate (see [Token Mechanics](/protocol/token-mechanics)) at the last update and μ(t) is the current rate. The yield is distributed proportionally to CT balances, paid in FW-USDC.

After maturity, CT no longer accrues rehypothecation yield — only active markets generate returns.

## CT Price Dynamics

CT is a hybrid instrument: its cash flows come from a floating-rate source, but it trades in the fixed-rate market. Regardless, a natural price equilibrium can be achieved:

* **CT overpriced** relative to expected future yield → holders sell → FW supply increases in pool → more capital for rehypothecation → higher future yields for remaining CT → price adjusts down
* **CT underpriced** → buyers enter → FW supply decreases → less rehypothecation → lower future yields → price adjusts up

In equilibrium, the CT market price equals the discounted expected value of remaining rehypothecation yield.

## Governance

All rehypothecation parameters (φ\_min, φ\_max, φ\_target) are set by the DAO. Key principles:

* **Liquidity first** — The DAO prioritizes redemption availability over yield maximization
* **Conservative by design** — Parameters are chosen through stress testing to ensure sufficient liquidity under adverse conditions
* **Manual updates** — Parameters are not automated; updates happen no more than monthly or quarterly
* **Future delegation** — The DAO may delegate parameter management to a curator

## Related

* [Fixed-Rate Markets](/protocol/fixed-rate-markets) — Where rehypothecated reserves originate
* [Floating-Rate Markets](/protocol/floating-rate-markets) — Where rehypothecated capital earns yield
* [Token Mechanics](/protocol/token-mechanics) — CT token properties and behavior
* [Whitepaper](/resources/whitepaper) — Full mathematical treatment


# Liquidations

Liquidation is the enforcement mechanism that keeps Fira's lending markets solvent. When a borrower's collateral value drops below the required threshold relative to their debt, the position becomes eligible for liquidation. Third-party liquidators repay the debt and receive the borrower's collateral at a bonus.

## When Liquidation Happens

Every borrowing position has two key ratios:

* **LTV (Loan-to-Value)** — Current debt divided by collateral value
* **LLTV (Liquidation LTV)** — The threshold set by the market. If LTV exceeds LLTV, the position is liquidatable.

Each market also enforces a **Max LTV** — the maximum ratio at which borrowing is allowed. Max LTV is set slightly below LLTV to provide a built-in safety buffer against immediate liquidation.

### Health Factor

$$
H=\frac{LLTV}{LTV}
$$

* **Health factor >= 1** — Position is healthy
* **Health factor < 1** — Position is liquidatable

A position's health changes when collateral value moves (via oracle price updates) or when debt grows (via interest accrual).

### Current Market Parameters

#### Fixed-Rate Markets

| Collateral | Maturity     | LLTV   | Max LTV | Liquidation Penalty |
| ---------- | ------------ | ------ | ------- | ------------------- |
| PT-USDe    | May 7, 2026  | 90%    | 89%     | 3.1%                |
| PT-sUSDe   | May 7, 2026  | 90%    | 89%     | 3.1%                |
| PT-USDG    | May 27, 2026 | 94.75% | 94%     | 1%                  |

#### Floating-Rate Markets

| Collateral | Debt Token | LLTV | Max LTV | Liquidation Penalty |
| ---------- | ---------- | ---- | ------- | ------------------- |
| wstETH     | USDC       | 89%  | 87%     | 3.4%                |
| cbBTC      | USDC       | 90%  | 88%     | 3.1%                |

The liquidation penalty is the net cost borne by the borrower when liquidated — it corresponds to the bonus received by liquidators through the LIF formula below.

## Oracles

Each market is configured with an oracle that prices collateral relative to the debt asset. Fira supports three oracle types:

| Oracle Type       | Description                                        | Example            |
| ----------------- | -------------------------------------------------- | ------------------ |
| **Price Feed**    | External price feeds (Chainlink, Redstone)         | ETH/USDC, BTC/USDC |
| **Exchange Rate** | Deterministic rates for wrapped or rebasing tokens | stETH/ETH          |
| **Fixed Price**   | Constant price — no fluctuation                    | USD0/bUSD0 (1:1)   |

### Bond Token Oracle

In fixed-rate markets, Bond Tokens (BTs) are priced at face value for liquidation purposes. A Fixed-Price Oracle values 1 BT-USDC = 1 USDC, regardless of the current market discount. This means collateral is always valued in units of the underlying debt asset.

## Liquidation Incentive Factor (LIF)

Liquidators receive a bonus on the collateral they seize, calculated by the LIF formula:

$$
\text{LIF} = \min!\left(\text{LIF}\_{\max},; \frac{1}{\delta \cdot \text{LLTV} + (1 - \delta)}\right)
$$

| Parameter      | Current Value | Description             |
| -------------- | ------------- | ----------------------- |
| $$LIF\_{max}$$ | 1.15          | Maximum bonus (15% cap) |
| $$\delta$$     | 0.3           | Sensitivity to LLTV     |

Higher LLTV markets produce lower LIF — the bonus is calibrated to the risk of each market.

### Collateral Seized

$$
Collateral\_{seized}=min\left(Collateral,LIF\times\frac{Debt\_{repaid}}{Price\_{Oracle}}\right)
$$

The liquidator repays part or all of the debt and receives collateral worth the repaid amount multiplied by the LIF. Any remaining collateral is returned to the borrower.

## Bad Debt

Bad debt occurs when seized collateral is worth less than the outstanding debt after accounting for execution costs (slippage, fees, price impact). The remaining debt which is not liquidated is realized as a bad debt loss. The shortfall is socialized among lenders.

### Fixed-Rate Markets

Bad debt reduces the FW wrapping rate μ(t). The modified wrapping rate μ\_s(t) used for BT/CT decomposition remains at the pre-loss level, socializing the loss across LPs and token holders.

### Floating-Rate Markets

Bad debt reduces the vault share price proportional to how much bad debt loss is realized post liquidation.

## Fixed-Rate vs Floating-Rate Liquidations

Liquidation mechanics apply to both market types, but with key differences:

|                        | Fixed-Rate Markets                                         | Floating-Rate Markets                                         |
| ---------------------- | ---------------------------------------------------------- | ------------------------------------------------------------- |
| **Trigger**            | LTV exceeds LLTV                                           | LTV exceeds LLTV                                              |
| **Interest accrual**   | No explicit interest — cost is embedded in the BT discount | Continuous variable interest accrual increases debt over time |
| **Maturity**           | Yes — positions have a defined expiry date                 | No — positions are open-ended                                 |
| **Forced liquidation** | Yes — DAO can force-liquidate after maturity               | No — only standard health-based liquidation                   |
| **Grace period**       | 24 hours after maturity before forced liquidation          | N/A                                                           |

## Forced Liquidation at Maturity

Fira supports **forced liquidation at maturity for fixed-rate markets**, triggerable by the DAO even if a position is otherwise healthy. This is by design: when collateral reaches its maturity date, all remaining positions can be closed to enable collateral redemption. Such positions are also subject to LIF values determined per market independently of LLTV.

### Maturity Grace Period

After the BT expiry date, borrowers have a **24-hour grace period** to repay their debt and recover their collateral before forced liquidation becomes enforceable. During this window:

* The position is not yet eligible for forced liquidation
* Borrowers can repay via the standard repayment flow (mint BT using USDC via FW)
* After the 24-hour window, the DAO can trigger forced liquidation regardless of position health

{% hint style="warning" %}
Borrowers should close positions **before** the maturity date. The 24-hour grace period is a safety buffer, not a recommended strategy. Open positions past the grace period may be force-liquidated at any time regardless of their health factor.
{% endhint %}

## Related

* [Risk Framework](/security-and-risk/risk-framework) — How risk is assessed per market
* [Liquidation Risk](/security-and-risk/risk-framework/liquidation-risk) — Risks specific to liquidation mechanics
* [Bad Debt Risk](/security-and-risk/risk-framework/bad-debt-risk) — Bad debt scenarios and mitigation
* [Whitepaper](/resources/whitepaper) — Full mathematical treatment


# Curation Vaults

Curation is how lender capital gets allocated across Fira's floating rate markets. Lenders deposit assets into curated vaults. A designated curator decides where that capital goes — which markets, what allocation, under what constraints. Depositors earn yield passively. Curators earn fees for their oversight.

## Curators

A curator manages one or more vaults with the objective of optimizing risk-adjusted returns for depositors. The role is strategic, not operational:

| Responsibility            | Description                                                                                                |
| ------------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Strategy definition**   | Establishing the vault's mandate — which assets, markets, and strategies are eligible                      |
| **Risk framework**        | Setting exposure caps, concentration limits, and risk constraints                                          |
| **Allocator appointment** | Designating who executes portfolio adjustments within the strategy. The curator may also act as allocator. |
| **Vault parameters**      | Defining fee structures, access controls, and compliance requirements                                      |

Curator-initiated changes are subject to a **timelock**. Depositors have time to review proposed changes and withdraw if they disagree.

## How Vaults Work

1. **Depositor** provides assets (e.g., USDC) to a curated vault
2. **Curator** defines the allocation strategy across eligible markets
3. **Allocator** executes capital deployment according to the strategy
4. **Yield** accrues from multiple sources — trading fees, fixed-rate spreads, floating-rate interest, rehypothecation
5. **Depositor** can withdraw at any time, subject to available liquidity

The vault issues shares representing the depositor's proportional claim on the total assets under management.

## Related

* [Floating-Rate Markets](/protocol/floating-rate-markets) — Variable-rate lending
* [Whitepaper](/resources/whitepaper) — Complete description


# Security Overview

Fira treats security as a structural requirement. Before any user funds were accepted, Fira smart contracts underwent six independent external audits, an extended internal security review, and a live bug bounty program was established. Every deployed contract is verified on Etherscan.

## Audit Coverage

Six independent audits were conducted on Fira contracts between November 2025 and March 2026:

| Audit                | Auditor            | Date          | Type                    |
| -------------------- | ------------------ | ------------- | ----------------------- |
| Fira UZR Audit Nov25 | Sherlock           | November 2025 | Competitive audit       |
| Fira UZR Audit Nov25 | Spearbit / Cantina | November 2025 | Focused security review |
| Fira UZR Audit Dec25 | yAudit             | December 2025 | Independent assessment  |
| Fira V1 Audit Feb26  | Sherlock           | February 2026 | Competitive audit       |
| Fira V1 Audit Feb26  | Hexens             | February 2026 | Independent audit       |
| Fira V1 Audit Mar26  | yAudit             | March 2026    | Independent assessment  |

All findings were addressed before deployment. Full reports and methodology details are on the [Audits](/security-and-risk/audits) page.

In addition, the Steady Labs engineering team conducted an extended internal security review covering code quality, deployment procedures, parameter configurations, access controls, and operational security.

## Bug Bounty

Fira maintains a live bug bounty program through Sherlock with rewards up to **$500K** for critical vulnerabilities. The program covers all deployed Fira V1 contracts on Ethereum mainnet.

For the full scope, reward tiers, and submission process, see the [Bug Bounty](/security-and-risk/bug-bounty) page.

## Smart Contract Architecture

Fira's system is composed of three core modules:

* **Lending Market** — Core lending vault, collateral management, liquidations, interest accrual, and ERC-4626 curation vaults
* **Fixed-Rate AMM and Tokenization** — BT/CT/FW token system, fixed-rate price discovery AMM, and rehypothecation module
* **Router** — Diamond-style proxy dispatching to modular action contracts for single-transaction user flows

Access control is enforced through role-based permissions and multisig governance. For the full architecture, see [Architecture Overview](/protocol/architecture-overview).

## Risk Framework

Fira documents six primary risk categories:

1. [Interest Rate Risk](/security-and-risk/risk-framework/interest-rate-risk)
2. [Liquidation Risk](/security-and-risk/risk-framework/liquidation-risk)
3. [Bad Debt Risk](/security-and-risk/risk-framework/bad-debt-risk)
4. [Collateral Risk](/security-and-risk/risk-framework/collateral-risk)
5. [Liquidity Risk](/security-and-risk/risk-framework/liquidity-risk)
6. [Smart Contract Risk](/security-and-risk/risk-framework/smart-contract-risk)

For the full risk index, see [Risk Framework](/security-and-risk/risk-framework). For legal disclaimers, see [Risk Disclaimers](/security-and-risk/risk-disclaimers).

## Key Principle

Audits, reviews, and bounties reduce certain risks but do not eliminate them. Fira is experimental software. Users should understand all risk categories before interacting with the protocol.


# Audits

Fira has undergone a comprehensive security review process consisting of six independent external audits and an extended internal review. These audits focused on the Fira smart contracts and associated lending/borrowing infrastructure deployed on Ethereum mainnet.

## External Audits

### 1. Sherlock — "Fira UZR Audit Nov25"

* **Auditor:** Sherlock
* **Audit Name:** Fira UZR Audit Nov25
* **Date:** November 2025
* **Scope:** Fira UZR module smart contracts
* **Status:** Done
* **Description:** Sherlock conducted a competitive audit of the Fira UZR contracts, leveraging their community of independent security researchers to identify vulnerabilities across the codebase. The audit covered the core lending vault, oracle adapters, interest rate models, and supporting infrastructure contracts.

{% file src="/files/UoUZjJqAQ8KjPGO6i0nt" %}

***

### 2. Spearbit / Cantina — "Cantina code - Fira UZR Audit Nov25"

* **Auditor:** Spearbit (via Cantina platform)
* **Audit Name:** Cantina code - Fira UZR Audit Nov25
* **Date:** November 2025
* **Scope:** Fira UZR module smart contracts
* **Status:** Done
* **Description:** Spearbit conducted a focused security review through the Cantina platform. The audit examined the Fira UZR codebase for logic errors, access control issues, economic attack vectors, and integration risks.

{% file src="/files/TjS2VmRZuOfzg661jWcu" %}

***

### 3. yAudit — "Fira UZR Audit Dec 25"

* **Auditor:** yAudit
* **Audit Name:** Fira UZR Audit Dec 25
* **Date:** December 2025
* **Scope:** Fira UZR module smart contracts
* **Status:** Done
* **Description:** yAudit performed an independent security assessment of the Fira UZR contracts. This audit provided a third perspective on the codebase, focusing on edge cases, mathematical precision, and potential exploit paths that may not have been covered by the earlier reviews.

{% file src="/files/K4rYY3BtAArsOM8QbT59" %}

***

### 4. Sherlock — "Fira V1 Audit Feb26"

* **Auditor:** Sherlock
* **Audit Name:** Fira V1 Audit Feb26
* **Date:** February 2026
* **Scope:** Fira V1 full protocol (fixed-rate markets, variable-rate lending, AMM, router, tokens, rehypothecation, oracles)
* **Status:** Done
* **Description:** Sherlock conducted a comprehensive competitive audit of the full Fira V1 protocol, covering the complete system including FiraLendingMarket, VariableLendingMarket, FiraMarket AMM, FiraRouterV4, token layer (BT/CT/FW), RehypothecationModule, oracle pipeline, and LiquidityInjector.

***

### 5. Hexens — "Fira V1 Audit Feb26"

* **Auditor:** Hexens
* **Audit Name:** Fira V1 Audit Feb26
* **Date:** February 2026
* **Scope:** Fira V1 full protocol
* **Status:** Done
* **Description:** Hexens performed an independent security audit of the Fira V1 smart contracts, providing deep analysis of the protocol's fixed-rate and variable-rate lending infrastructure, curation vaults, and associated components.

{% file src="/files/dSkzT9sxsbKlZ5fDXQsu" %}

***

### 6. yAudit — "Fira V1 Audit Mar26"

* **Auditor:** yAudit
* **Audit Name:** Fira V1 Audit Mar26
* **Date:** March 2026
* **Scope:** Fira V1 full protocol
* **Status:** Done
* **Description:** yAudit performed a follow-up independent assessment of the complete Fira V1 protocol, building on their earlier UZR-focused review to cover the expanded system including variable-rate markets, curation vaults, and the full oracle pipeline.

***

## Internal Review

### Steady Labs Internal Review

* **Reviewer:** Steady Labs engineering team
* **Duration:** Approximately one month
* **Scope:** Full Fira codebase and deployment configuration
* **Description:** In addition to the six external audits, the Steady Labs team conducted an extended month-long internal security review. This review covered code quality, deployment procedures, parameter configurations, access control setups, and operational security considerations. The internal review complemented the external audits by providing deep domain-specific knowledge of the protocol's intended behavior and design assumptions.

***

## Summary

| Audit                               | Auditor            | Date                | Type                      |
| ----------------------------------- | ------------------ | ------------------- | ------------------------- |
| Fira UZR Audit Nov25                | Sherlock           | November 2025       | External (competitive)    |
| Cantina code - Fira UZR Audit Nov25 | Spearbit / Cantina | November 2025       | External (focused review) |
| Fira UZR Audit Dec 25               | yAudit             | December 2025       | External (independent)    |
| Fira V1 Audit Feb26                 | Sherlock           | February 2026       | External (competitive)    |
| Fira V1 Audit Feb26                 | Hexens             | February 2026       | External (independent)    |
| Fira V1 Audit Mar26                 | yAudit             | March 2026          | External (independent)    |
| Internal Review                     | Steady Labs        | Nov 2025 – Mar 2026 | Internal                  |

All audit reports and findings have informed the final deployed versions of the Fira contracts on Ethereum mainnet. The combination of six independent external audits plus an extended internal review represents a thorough security review process for the protocol's smart contract infrastructure.


# Bug Bounty

## Introduction

Steady Labs is launching a bug bounty program for **Fira** deployed on **Ethereum mainnet**. Fira is a modular lending protocol that combines fixed-rate markets, floating-rate lending, curated vaults, tokenized market primitives (BT, CT, FW), rehypothecation, a multi-layer oracle infrastructure, and protocol-controlled liquidity seeding into a single system.

Fira is composed of the following independent layers:

* **Router (FiraRouterV4):** Diamond-style proxy that dispatches user calls to modular Action contracts (facets), combining multi-step operations into a single transaction.
* **Fixed-Rate AMM (FiraMarket):** Pendle-style AMM supporting BT/FW trading and fixed-rate price discovery.
* **Lending Markets:** Two separate lending contracts — **FiraLendingMarket** for fixed-rate markets with post-maturity settlement and liquidation logic, and **VariableLendingMarket** for variable-rate lending with collateral management, interest accrual, liquidation, and flash loans.
* **Curation Vault (SisuVault):** ERC-4626 vault that allocates pooled capital across variable-rate markets using curator, allocator, and guardian roles with timelocked configuration changes.
* **Token Layer:** BT (Bond Token), CT (Coupon Token), FW (FiraWrapped), and LP tokens — ERC-20 tokens implementing fixed-rate yield separation and AMM liquidity positions.
* **Rehypothecation Module:** Controls the ratio of idle vs. invested reserves within the FW contract, rebalancing between liquid USDC and variable-rate vault positions.
* **Oracle Pipeline:** Multi-layer oracle stack including ChainlinkOracleV2, AaveToChainlinkAdapters, FiraSolvencyOracles, and a BCLpOracle for LP pricing.
* **Interest Rate Models:** AdaptiveCurveIrm for variable-rate markets (utilization-based) and `address(0)` for fixed-rate markets (no IRM — rate is determined by AMM pricing).
* **Liquidity Injector:** Protocol-controlled contract that mints BT and supplies it to fixed-rate lending markets. Only the LiquidityInjector can supply BT to these markets (whitelist-gated).

This bug bounty covers vulnerabilities in the **Fira smart contracts and associated protocol-owned components** that could compromise funds, accounting integrity, solvency, liquidation safety, or protocol availability. Only contracts currently deployed on Ethereum mainnet and listed below are in scope. All deployed contracts are verified on Etherscan. Ownership is assigned to designated multisig addresses at three security tiers (9/15, 5/10, and 4/9 threshold schemes).

## Reward Amounts

**Critical:** Up to **$500,000** maximum payout, not to exceed **10% of the funds at risk at the time of submission**. Critical findings result in a definite and significant loss of funds or an irreversible locking of funds on a systemic level. Minimum payout for a valid Critical issue: **$50,000**.

**High:** Discretionary. Steady Labs determines High-severity payouts on a case-by-case basis considering impact and severity.

**Medium:** Discretionary. Steady Labs determines Medium-severity payouts on a case-by-case basis considering impact and severity.

### General Notes

All reporters should consult **Sherlock's Criteria for Issue Validity** for general guidance on severity and out-of-scope issues.

A working **Proof of Concept (PoC)** exploit is highly recommended and may be required for complex issues. Include clear reproduction steps and any setup instructions necessary for validation.

All standard **Sherlock Bug Bounty Platform Rules** and safe harbor provisions apply to this program.

## Scope

### Chain

**Ethereum mainnet only.** Smart contracts deployed on any other network, testnet, sidechain, or staging environment are out of scope.

### In-Scope Contracts (Ethereum Mainnet)

All currently deployed and verified Fira contracts listed below are in scope, including associated implementations and proxies where applicable. Can also be found here: [Contracts & Addresses | Fira Docs](https://docs.fira.money/resources/contracts-addresses)

### Core Protocol

| Contract                              | Address                                      |
| ------------------------------------- | -------------------------------------------- |
| FiraLendingMarket (fixed-rate)        | `0x280ddD897F39C33fEf1CbF863B386Cb9a8e53a0e` |
| VariableLendingMarket (variable-rate) | `0xc8Db629192a96D6840e88a8451F17655880A2e4D` |
| FiraMarket (AMM)                      | `0xde00b5edb255078dd42ee94fd97f473d1c9c055d` |
| FiraRouterV4                          | `0xFF615E63aAF2d1B1EE4AdFD34a5840747185d8A0` |
| LiquidityInjector                     | `0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5` |

### Router Facets

FiraRouterV4 dispatches calls to modular Action contracts via selector-based routing:

| Facet                | Address                                      |
| -------------------- | -------------------------------------------- |
| ActionSwapBTV3       | `0xab2383692ed8e0836e25b71988c925dfd94ed2fe` |
| ActionSwapCTV3       | `0xdb7a722ae7baf83d3d8b9e812952916326d6656b` |
| ActionAddRemoveLiqV3 | `0x286bbc5519cd421011e7e1c092e1d6a72edb4d30` |
| ActionCallbackV3     | `0x2dead5b19935d7299d7077c52f2e2860370278a5` |
| ActionSimple         | `0x4474886d003abcb53c307324894c074ce5176f75` |
| ActionMiscV3         | `0x967234d7a4416380107da653e5d3afc9c7bf8874` |
| ActionBorrow         | `0x66f5853cf6c36b97e754f074397d00b78253ef03` |
| ActionStorageV4      | `0x0386685eA7d37c61dDb8F2e2E8c45f6a81d4A3C8` |

### Vault

| Contract                      | Address                                      | Description                                                                                 |
| ----------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------- |
| SisuVault (Markov USDC Prime) | `0x50791a5cA041b9D6Dd03e64E3Fa0e34a376759AC` | ERC-4626 vault curated by Markov Labs, allocating USDC across variable-rate lending markets |

### Token Layer

| Token             | Address                                      | Decimals |
| ----------------- | -------------------------------------------- | -------- |
| FW-USDC (USDCFW)  | `0x62F5366C9E21A95326C461a098a408e034e017b3` | 18       |
| BT (Bond Token)   | `0x57FFbb88f0c69283531a751BE6FF0741348371bA` | 6        |
| CT (Coupon Token) | `0x93635d34fAd5A9fA7065a645691100b2E23C93cd` | 6        |

BT and CT share the same expiry (May 7, 2026 — unix `1778112000`) and are minted/burned in pairs via the YieldContractFactory.

### Modules

| Contract              | Address                                      |
| --------------------- | -------------------------------------------- |
| RehypothecationModule | `0xad332515d9c82438BBa0e9FAA9486B52A33a7Ac8` |
| YieldContractFactory  | `0xcdB83Abb9121c04589567A4106C3cFaf65DB68Be` |

### Oracles

**Fixed-rate markets** use a 4-layer oracle pipeline:

```
Chainlink Price Feed → AaveToChainlinkAdapter → ChainlinkOracleV2 → FiraSolvencyOracle → FiraLendingMarket
```

| Layer                  | PT-USDe Market                               | PT-sUSDe Market                              |
| ---------------------- | -------------------------------------------- | -------------------------------------------- |
| AaveToChainlinkAdapter | `0xc42F003F9eCD3DdDF704556E82Cdd9271818171F` | `0x3d7346578be9B82E0227D027bd86F6De59BA3C91` |
| ChainlinkOracleV2      | `0x2ED527087B740530562754EFCd608290eCCdBe2e` | `0xD6f5D9102007A737D9EDE6543262516d5c2fc8f8` |
| FiraSolvencyOracle     | `0xeB30b33A1aC175e0305853636D0eF3898eb530f3` | `0xB9bAA3D58E1431776218F39919fd21AeD3e69aBb` |

FiraSolvencyOracle contracts are immutable after deployment — no admin functions, no owner.

**Variable-rate markets:**

| Market      | Oracle                                       | Type                                         |
| ----------- | -------------------------------------------- | -------------------------------------------- |
| wstETH/USDC | `0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2` | Morpho oracle (pre-deployed)                 |
| cbBTC/USDC  | `0x698253A24CC4926090f841B38D31d6342A00a82C` | ChainlinkOracleV2 (BTC/USD + USDC/USD feeds) |

**Other:**

| Contract   | Address                                      |
| ---------- | -------------------------------------------- |
| BCLpOracle | `0xfEAAEC9124FB007d7c44Ed704A08d24b264de921` |

### Interest Rate Models

| Contract         | Address                                      | Used By                                   |
| ---------------- | -------------------------------------------- | ----------------------------------------- |
| AdaptiveCurveIrm | `0x73C288826347af3718e6F09c2A24AaFDA77684cD` | Variable-rate markets (utilization-based) |

Fixed-rate markets use `address(0)` as their IRM. The borrowing rate is determined at the time of BT issuance through AMM pricing, not through an interest rate model.

### Live Fixed-Rate Markets

All live fixed-rate markets operate on the **FiraLendingMarket** at `0x280ddD897F39C33fEf1CbF863B386Cb9a8e53a0e`. BT is the loan token. Only the LiquidityInjector can supply BT (whitelist-gated). Both markets expire **May 7, 2026**.

**PT-USDe / BT Market**

| Field                 | Value                                                                |
| --------------------- | -------------------------------------------------------------------- |
| Market ID             | `0xC48C055110D1692EDA1D45975BD80C75EE5E4D0AB6A5B6FFB949F2252C1B7791` |
| Loan Token            | BT — `0x57FFbb88f0c69283531a751BE6FF0741348371bA`                    |
| Collateral            | PT-USDe (May 7 2026) — `0xAeBf0Bb9f57E89260d57f31AF34eB58657d96Ce0`  |
| Oracle                | FiraSolvencyOracle — `0xeB30b33A1aC175e0305853636D0eF3898eb530f3`    |
| IRM                   | `0x0000000000000000000000000000000000000000` (none — fixed rate)     |
| LTV / LLTV            | 89% / 90%                                                            |
| Liquidation Incentive | 3.1%                                                                 |
| Whitelist             | LiquidityInjector — `0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5`     |
| Maturity Grace Period | 86400 (24h)                                                          |

**PT-sUSDe / BT Market**

| Field                 | Value                                                                |
| --------------------- | -------------------------------------------------------------------- |
| Market ID             | `0xCA309C3ECE0FA3341779D8319F28BD9E08D3E08889E8AC58B4AC9001FBE458F3` |
| Loan Token            | BT — `0x57FFbb88f0c69283531a751BE6FF0741348371bA`                    |
| Collateral            | PT-sUSDe (May 7 2026) — `0x3de0ff76E8b528C092d47b9DaC775931cef80F49` |
| Oracle                | FiraSolvencyOracle — `0xB9bAA3D58E1431776218F39919fd21AeD3e69aBb`    |
| IRM                   | `0x0000000000000000000000000000000000000000` (none — fixed rate)     |
| LTV / LLTV            | 89% / 90%                                                            |
| Liquidation Incentive | 3.1%                                                                 |
| Whitelist             | LiquidityInjector — `0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5`     |
| Maturity Grace Period | 86400 (24h)                                                          |

### Live Variable-Rate Markets

All live variable-rate markets operate on the **VariableLendingMarket** at `0xc8Db629192a96D6840e88a8451F17655880A2e4D`.

**wstETH / USDC**

| Field      | Value                                                                |
| ---------- | -------------------------------------------------------------------- |
| Market ID  | `0xB3152AC00687CC9502B78AB452956F85CC89AC210DEEFDA5DBFF09F7F167B544` |
| Loan Token | USDC — `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`                  |
| Collateral | wstETH — `0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0`                |
| Oracle     | `0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2` (Morpho wstETH/USDC)    |
| IRM        | AdaptiveCurveIrm — `0x73C288826347af3718e6F09c2A24AaFDA77684cD`      |
| LTV / LLTV | 87% / 89%                                                            |

**cbBTC / USDC**

| Field      | Value                                                                       |
| ---------- | --------------------------------------------------------------------------- |
| Market ID  | `0x39D3BDD30BF4BCF4A4D3547F2484ABE1E30A2DCD41ED83788B40E2720357AB76`        |
| Loan Token | USDC — `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`                         |
| Collateral | cbBTC — `0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf`                        |
| Oracle     | `0x698253A24CC4926090f841B38D31d6342A00a82C` (ChainlinkOracleV2 cbBTC/USDC) |
| IRM        | AdaptiveCurveIrm — `0x73C288826347af3718e6F09c2A24AaFDA77684cD`             |
| LTV / LLTV | 88% / 90%                                                                   |

### Critical / High / Medium Eligibility

Critical findings typically affect the **core, live, value-bearing layers** of Fira:

* FiraLendingMarket and VariableLendingMarket
* FiraMarket (AMM)
* FiraRouterV4 and Action facets
* Token layer accounting and redemption logic (BT, CT, FW)
* RehypothecationModule
* Oracle pipeline (FiraSolvencyOracle, ChainlinkOracleV2, adapters)
* SisuVault with user funds
* LiquidityInjector, where a flaw could directly compromise live assets or protocol solvency

### Only Eligible for High / Medium

The following are in scope but findings are generally capped at **High** or **Medium** unless they directly compromise live funds in a core deployed market:

| Contract                 | Address                                      |
| ------------------------ | -------------------------------------------- |
| YieldContractFactory     | `0xcdB83Abb9121c04589567A4106C3cFaf65DB68Be` |
| FiraMarketFactory        | `0xBF1EfC2199ae9EE1B6f5060a45D4440157E49744` |
| SisuVaultFactory         | `0xe77E0f97A864558e5513209323e4169FcEAC6981` |
| ChainlinkOracleV2Factory | `0x7783fF7bE856C7A82bC5497Fb3CC8F7E8802D8dC` |

Deployment and configuration helper contracts, and non-custodial support contracts that do not themselves hold or control meaningful live value, are also capped at High or Medium.

### Scope Note

This bounty covers **Fira contracts and protocol-owned infrastructure only**. Other products, protocols, or systems outside the Fira deployment are out of scope unless the vulnerability arises from Fira's own on-chain logic or integration handling.

## Out of Scope

No rewards will be awarded for reports that fall solely into the following categories.

### Undeployed or Non-Mainnet Code

Code, contracts, modules, or features **not currently deployed on Ethereum mainnet** are out of scope. This includes draft code, future upgrades, staging deployments, local testing contracts, and testnets.

### Previously Known Issues

Issues already identified in prior audits (Sherlock, Spearbit/Cantina, Hexens, yAudit), internal reviews, documentation, or acknowledged by Steady Labs before submission are not eligible.

### Frontend, Website, and UI

Issues limited to the web application, user interface, dashboards, websites, or other frontend layers are out of scope.

### Third-Party Protocol or Token Risks

Vulnerabilities in third-party systems that Fira interacts with but does not control are out of scope. This includes bugs or failures in external protocols, vaults, bridges, or token implementations.

Examples of external dependencies not in scope:

* **USDC** (Circle)
* **wstETH** (Lido)
* **cbBTC** (Coinbase)
* **USDe / sUSDe** (Ethena)
* **USDG** (Paxos)
* **PT-USDe / PT-sUSDe / PT-USDG** (Pendle)
* Any third-party wrapped asset, oracle, or off-chain issuer
* **Oracles** not deployed and maintained by the Protocol Team itself, e.g. Chainlink Feeds.

If a report depends on these systems failing rather than on a flaw in Fira's own smart contract logic or validation, it is not in scope.

### External Oracle Failures

Pure failures of third-party oracle infrastructure, feed operators, or data providers are out of scope unless the vulnerability is specifically in **Fira's oracle integration, validation, or fallback logic** — including the AaveToChainlinkAdapter, ChainlinkOracleV2, or FiraSolvencyOracle contracts.

### Off-Chain, Legal, or Custodial Risks

Issues arising purely from off-chain custody, legal enforceability, issuer solvency, governance coordination outside the contracts, or real-world asset processes are out of scope.

### Intended Admin or Multisig Powers

Behavior that requires proper use of intended administrative, governance, curator, allocator, or multisig permissions is out of scope.

Examples of authorized actions, when performed by properly authorized actors:

* Adjusting LTV, LLTV, or fee parameters
* Pausing or unpausing contracts (USDCFW pause flags: `depositPaused`, `withdrawPaused`, `transferPaused`)
* Updating supply caps on SisuVault markets
* Rebalancing vault allocations within configured permissions and timelocks
* Operating the LiquidityInjector (minting/burning BT, supplying/withdrawing from lending markets)
* Executing timelocked curator or allocator actions
* Triggering manual rehypothecation via `forceRehypothecation`

However, **bypassing or impersonating those permissions** is in scope.

### Protocol-Intended Behaviors

The following behaviors are not vulnerabilities when they occur according to design:

* Liquidation of unhealthy positions according to configured **LTV / LLTV** and the 3.1% liquidation incentive
* Forced post-maturity settlement or liquidation of expired positions (after the 24-hour grace period)
* BT/FW convergence to par near maturity
* AMM pricing, slippage, or discount/premium behavior consistent with the FiraMarket pricing model
* Reserve rebalancing by the RehypothecationModule according to configured `phiMin`, `phiMax`, and `phiTarget` ratios
* Yield accruing to CT holders as designed (via InterestManagerCT)
* Vault allocation and reallocation inside configured caps and timelocks
* Router execution that follows the documented action flow and Diamond-style facet dispatch

### Pure Economic Attacks Without a Code Vulnerability

Pure market behavior or economic outcomes that do not rely on a contract bug are out of scope:

* Market manipulation within intended protocol rules
* Liquidity withdrawal by users
* Slippage or adverse execution under expected market conditions
* Rate movement, basis trading, or maturity-driven repricing
* Honest liquidations after genuine collateral price moves
* Losses caused solely by external market volatility

### Minor Gas, Efficiency, or Documentation Issues

The following are out of scope unless they create a real and material security impact:

* Gas optimizations
* Minor inefficiencies
* Cosmetic or documentation issues
* NatSpec mismatches, comment or spelling errors
* Minor rounding or precision issues with no material effect on funds or solvency

### Theoretical or Unrealistic Attacks

Attacks that require impractical brute force, extreme assumptions, or unrealistic coordination are out of scope. Reports must describe a credible and reproducible exploit path.

If you are unsure whether a finding is in scope, focus on **technical, on-chain vulnerabilities in the deployed Fira contracts and live market infrastructure**.

## Protocol Resources

| Resource                          | Location                                                                                     |
| --------------------------------- | -------------------------------------------------------------------------------------------- |
| Fira Documentation                | [docs.fira.money](https://docs.fira.money)                                                   |
| Contracts & Audits                | [docs.fira.money/security-and-risk/audits](https://docs.fira.money/security-and-risk/audits) |
| Source Code (fira)                | [github.com/usual-dao/fira](https://github.com/usual-dao/fira)                               |
| Source Code (fira-lending-market) | [github.com/usual-dao/fira-lending-market](https://github.com/usual-dao/fira-lending-market) |

The ultimate scope of this bounty is defined by the **deployed Ethereum mainnet contracts** listed above.

## Judging and Severity Assessment

Sherlock's security team triages and validates all submissions. Sherlock coordinates issue verification and determines validity and severity based on the criteria in this program and Sherlock's platform rules.

Steady Labs may be consulted during validation. **Sherlock makes the final determination** on issue validity, severity, and payout eligibility.

In case of dispute or ambiguity, Sherlock's assessment is the deciding factor.

## Disclosure Policy

This bounty follows Sherlock's standard disclosure policy with additional requirements for serious vulnerabilities.

Critical and high-impact findings must **not** be disclosed publicly or to any third party until all of the following conditions are met:

1. Steady Labs has been notified through the official submission process
2. The issue has been acknowledged
3. A fix or mitigation has been deployed, or explicit written permission to disclose has been granted
4. Sherlock has completed or approved the disclosure process

Premature disclosure of an exploit path or a live unpatched vulnerability may disqualify the submission from any reward.

Report vulnerabilities **promptly** — ideally within **24 hours of discovery** — through the official Sherlock submission flow.

Do not exploit vulnerabilities on the live network. Do not steal funds, manipulate users, destroy data, or disrupt service. Any exploit activity beyond what is strictly necessary to demonstrate a vulnerability in a controlled manner may lead to disqualification and possible legal consequences.

If you believe a vulnerability is already being exploited or may soon be exploited, notify Sherlock and Steady Labs immediately through the approved reporting process. Do not make it public.

Steady Labs may, at its discretion, offer additional bonuses for especially novel, impactful, or responsibly handled reports.

## Eligibility

To be eligible for a reward, you must meet all of the following conditions:

* **No sanctions:** You are not located in a sanctioned jurisdiction and are not on any prohibited party list.
* **No affiliation with Steady Labs:** You are not a current or former employee, core contributor, or immediate family member of someone directly affiliated with Steady Labs or the Fira development effort.
* **Legal capacity:** You are legally able to participate in bug bounty programs and receive rewards in your jurisdiction.
* **No prior paid audit conflict:** You have not been paid to audit or review this exact codebase in an official capacity, and you did not materially contribute to the in-scope contracts. You may request an exception directly from Steady Labs.
* **Follow program rules:** You agree to follow all program rules, scope restrictions, disclosure requirements, and platform terms.

By submitting a report, you affirm that you meet these eligibility requirements. Steady Labs and Sherlock reserve the right to verify eligibility and disqualify participants who do not meet these conditions.

## Testing Guidelines and Safe Harbor

### Do Not Test Destructively on Mainnet

Do not perform destructive testing on Ethereum mainnet. Use a **local environment, simulation, or mainnet fork** to test exploit scenarios. All in-scope contracts are verified on Etherscan. Researchers can reproduce behavior using **Foundry** or **Hardhat**.

### Use Accounts You Control

Use only wallets, keys, and accounts you control. Do not interfere with other users' positions, balances, or funds.

### No Mainnet Denial of Service

Do not spam, grief, or attempt denial-of-service against live contracts, users, or infrastructure. Demonstrate any blocking or service-degradation vulnerability in a controlled environment.

### Maintain Confidentiality

Do not share exploit details outside the official submission process before a fix is deployed and disclosure is authorized.

### No Social Engineering or Off-Chain Intrusion

This bounty covers smart contract and technical security issues only. Social engineering, phishing, credential attacks, or attempts to gain access through non-technical means are strictly prohibited.

### Responsible Testing

Avoid high-volume or risky testing on live systems. If a testing approach might affect real funds or real users, do not perform it on mainnet.

As long as you act in good faith, stay within these rules, and report vulnerabilities responsibly, Steady Labs intends for this program to operate under a safe-harbor framework for legitimate security research.

## Closing

Steady Labs values the work of independent security researchers and the broader white-hat community. Your efforts strengthen the safety and resilience of Fira's fixed-rate, floating-rate, and curated lending infrastructure.

Thank you for participating in the **Fira Bug Bounty**.

Happy Hunting!


# Risk Framework

Fira risk management is structured around six primary user-facing risk categories plus legal and operational disclaimers.

## Risk Categories

1. Interest rate risk
2. Liquidation risk
3. Bad debt risk
4. Collateral risk
5. Liquidity risk
6. Smart contract risk

## Mitigation Layers

* Multi-auditor security process
* Live bug bounty coverage
* Conservative collateral and liquidation parameters
* Oracle controls and fallback logic
* Governance-based parameter updates
* Progressive rollout strategy for new product surfaces

## Read By Category

* [Interest Rate Risk](/security-and-risk/risk-framework/interest-rate-risk)
* [Liquidation Risk](/security-and-risk/risk-framework/liquidation-risk)
* [Bad Debt Risk](/security-and-risk/risk-framework/bad-debt-risk)
* [Collateral Risk](/security-and-risk/risk-framework/collateral-risk)
* [Liquidity Risk](/security-and-risk/risk-framework/liquidity-risk)
* [Smart Contract Risk](/security-and-risk/risk-framework/smart-contract-risk)
* [Risk Disclaimers](/security-and-risk/risk-disclaimers)

## Security References

* [Security Overview](/security-and-risk/security-overview)
* [Audits](/security-and-risk/audits)
* [Bug Bounty](/security-and-risk/bug-bounty)

## Important

Risk cannot be eliminated in DeFi systems. This framework helps users assess tradeoffs and failure modes, but does not constitute financial, legal, or tax advice.


# Interest Rate Risk

## Overview

Fira's fixed-maturity and floating-rate markets face exposure to interest rate volatility. This disclosure is not exhaustive and should be read alongside broader risk disclosures.

## Fixed-Maturity Markets

The "fixed" rate operates through market-driven pricing of BT (Bond Token) relative to underlying assets. Market conditions — including liquidity, borrowing demand, and risk appetite — can widen or tighten the discount. Users who exit before maturity may experience realized rates that differ significantly from entry rates.

## Floating-Rate Markets

Borrowing rates depend directly on utilization (borrowed liquidity divided by supplied liquidity). Supply or demand shocks can cause utilization to spike rapidly, potentially increasing borrowing costs sharply and keeping them elevated until conditions normalize.

## Risk Manifestation

* Early exits from fixed-maturity positions may yield higher or lower realized rates than anticipated
* Floating-rate markets can experience rapid and material rate increases when large liquidity withdrawals or borrowing spikes occur

## Mitigations (With Limitations)

* Fixed-maturity markets employ liquidity concentration around reasonable rate ranges, though slippage and material movements remain possible
* Floating-rate markets rely on curator-managed liquidity reserves and parameters, but curators may be unable to respond adequately during stress

## Key Warnings

* Users should not assume fixed-maturity rates remain locked before maturity
* Anticipate potential rate spikes in floating markets
* Displayed rates are indicative and may not reflect actual execution prices


# Liquidation Risk

## Core Risk

Borrowing on Fira, whether in fixed-maturity or floating-rate markets, requires collateral and carries material liquidation risk. Liquidations can proceed rapidly, automatically, and without notice, potentially resulting in substantial or complete loss of collateral holdings.

## How Liquidations Occur

Positions become vulnerable when a borrower's Loan-to-Value (LTV) ratio exceeds the Liquidation LTV (LLTV) threshold. This triggers eligibility for liquidators to seize collateral in exchange for debt repayment.

### Triggers

* Collateral value declines
* Borrowed asset appreciation
* Volatility shifts
* Pricing disruptions

## Real-World Scenarios

Liquidation materializes quickly in these circumstances:

* Sharp market movements
* Liquidity constraints
* Network congestion
* Oracle failures
* Cascading liquidations during broader market stress

## Mitigation Strategies (With Caveats)

Users may employ defensive tactics:

* Conservative initial leverage
* Active position monitoring
* Partial debt repayment
* Independent risk assessment

These are not guarantees. Interface warnings and any automated features provide indicative guidance only and may fail during stressed conditions.

## Fixed-Rate Maturity Risk

In fixed-rate markets, borrowers face an additional liquidation vector: **forced liquidation at maturity**. When collateral (BTs) reaches expiry, the DAO can force-liquidate all remaining positions — even healthy ones — to enable collateral redemption.

A **24-hour grace period** after maturity allows borrowers to repay before forced liquidation is triggered. Borrowers who do not close their positions before or during this window risk forced liquidation regardless of their health factor.

## Current Market Parameters

| Market Type   | Collateral | LLTV   | Max LTV | Penalty |
| ------------- | ---------- | ------ | ------- | ------- |
| Fixed-rate    | PT-USDe    | 90%    | 89%     | 3.1%    |
| Fixed-rate    | PT-sUSDe   | 90%    | 89%     | 3.1%    |
| Fixed-rate    | PT-USDG    | 94.75% | 94%     | 1%      |
| Floating-rate | wstETH     | 89%    | 87%     | 3.4%    |
| Floating-rate | cbBTC      | 90%    | 88%     | 3.1%    |

## Key Takeaway

Liquidation represents an inherent feature of collateralized borrowing. Users should not assume timely intervention opportunities exist during extreme volatility.


# Bad Debt Risk

## Definition

Bad debt emerges when a borrower's collateral cannot be liquidated for enough value to fully repay the outstanding debt. The shortfall between liquidation proceeds (minus execution costs) and outstanding obligations becomes the bad debt burden.

## Triggers

* Swift collateral value declines exceeding liquidation speed
* Market depth deterioration causing substantial slippage during asset sales
* Liquidations becoming economically unviable due to fees, MEV, or thin liquidity
* Network disruptions preventing timely liquidation or inflating transaction costs

## Loss Distribution

Bad debt typically affects lenders through socialized losses across liquidity providers rather than concentrating on single parties. This reduces total available assets or diminishes realized yields.

## Mitigations

Fira employs liquidation thresholds and exposure caps using conservative, data-informed methodologies based on historical price volatility and execution data.

### Limitations

* Extreme price gaps can bypass protections
* Sudden liquidity disappearance
* Oracle failures
* Smart contract issues

## Key Risk

Lenders face credit-like risk comparable to borrower defaults, with losses most likely during stress periods when market volatility peaks and liquidity contracts simultaneously.


# Collateral Risk

## Definition

Collateral risk represents a subset of bad debt risk involving the potential decline in value and/or liquidity of collateral to levels that cannot adequately secure outstanding borrowing positions.

## Risk Mechanisms

### Price and Liquidity Deterioration

Collateral risk primarily arises from adverse price movements and/or liquidity shortfalls under standard market conditions. Even when liquidation-eligible, positions may clear at unfavorable prices due to market friction, resulting in protocol bad debt.

### Asset-Specific Failures

Certain assets — particularly stablecoins, wrapped tokens, and bridged assets — face idiosyncratic risks. Triggering events include:

* Smart contract exploits
* Governance failures
* Issuer misconduct
* Redemption halts
* Blacklisting
* Structural weaknesses

Such scenarios can cause collateral value to deteriorate rapidly and potentially irreversibly.

## Specific Risk Scenarios

1. Sharp price crashes between oracle updates
2. Liquidity disappearance despite maintained pricing
3. Stablecoin de-pegging or redemption impairment
4. Issuer-enforced blacklisting preventing asset transfers

## Mitigation

Fira implements a conservative collateral selection framework emphasizing blue-chip assets evaluated for:

* Liquidity
* Price history
* Redemption mechanisms
* Smart contract security
* Governance
* Protocol resilience

## Limitations

"Blue-chip" designation provides no guarantee against severe drawdowns. Due diligence cannot predict all failure modes, and external dependencies remain uncontrollable. Lenders may bear losses from resulting bad debt, even in conservatively collateralized markets.


# Liquidity Risk

## Definition

Liquidity risk is the potential inability to enter, exit, repay, or unwind a position at a reasonable price within expected timeframes due to insufficient market liquidity.

## Three Primary Risk Categories

### Fixed-Maturity Borrowing

Early loan settlement through AMM swaps may result in unfavorable pricing due to slippage and price impact, or complete inability to execute, potentially forcing holders to wait until maturity.

### Floating-Rate Lending

Lenders can withdraw unutilized assets, but redemptions may become dependent on borrowers repaying, creating potential withdrawal delays when utilization is high.

### Liquidity Providers

Reserve rehypothecation means not all reserves may be liquid at all times, potentially causing temporary withdrawal restrictions.

## Risk Scenarios

* AMM liquidity depletion during volatility
* Rapid withdrawal runs causing utilization spikes
* Rehypothecation lockups
* Correlated stress events that simultaneously impact multiple risk factors

## Mitigations (With Caveats)

Fira employs liquidity incentives and rate responses, but these are not guarantees and may not work under stress. Alternative settlement pathways exist but become costly or unavailable during stress conditions.

## Key Warnings

* Assume liquidity can disappear rapidly
* Treat fixed-maturity early exits as risky
* Recognize that floating-rate withdrawals lack guaranteed timing
* Avoid relying on interface estimates during market stress


# Smart Contract Risk

## Core Risk

Fira operates as a blockchain protocol with inherent smart contract vulnerabilities. Code may contain vulnerabilities, bugs, design flaws, or unintended behaviors potentially resulting in complete asset loss.

## Risk Sources

* Implementation errors
* Faulty assumptions about external integrations (tokens, oracles, bridges, DEXs)
* Market edge cases
* Permissioning mechanisms
* Governance decisions
* Cross-contract interactions

On-chain transactions are irreversible, meaning losses may be permanent.

## Mitigations

### Third-Party Audits

Fira has engaged security firms (Sherlock, Spearbit Cantina, yAudit) for code review. Audits do not guarantee secure or defect-free code — vulnerabilities can persist undetected.

### Operational Controls

The system may pause or restrict functions during suspected incidents. Tradeoffs include service disruption, reduced liquidity, and withdrawal delays.

### Recovery Attempts

Fira may investigate incidents and pursue recovery actions, but any recovery is uncertain and potentially impossible.

## User Acknowledgment

Users must recognize that:

* Fira represents experimental and adversarial environments
* The protocol may malfunction
* Assets face total loss risk
* No safety guarantees exist absent written commitments


# Risk Disclaimers

## Risks and Security Considerations

### Important Notice

This section highlights material risks associated with using Fira and interacting with Fira smart contracts. **Fira is experimental and involves significant risk**, including the risk of **partial or total loss of funds**. This section is provided for informational purposes only, is **not exhaustive**, and does not constitute financial, legal, tax, or other professional advice. You should only use Fira if you understand decentralized finance ("DeFi"), smart contracts, and collateralized lending/borrowing, and if you can bear the risk of losing all funds you provide or receive through the protocol.

Fira is **non-custodial**: users control their own wallets and private keys. Transactions executed on a blockchain are generally **irreversible**, and losses may be permanent.

### Risk Summary (Non-Exhaustive)

Using Fira may expose you to one or more of the following categories of risk:

* **Smart contract and technical risk**
* **Blockchain/network and infrastructure risk**
* **Third-party dependency risk** (tokens, oracles, DEX liquidity, RPC providers, bridges, etc.)
* **Interest rate risk** (fixed-maturity and floating-rate markets)
* **Liquidity and exit risk** (slippage, inability to unwind or withdraw)
* **Liquidation risk** (including maturity-driven liquidation mechanics)
* **Bad debt risk / lender loss risk**
* **Collateral and asset-specific risk** (volatility, centralization, issuer/admin controls)
* **Stablecoin and wrapping risk** (e.g., USDC and wrapped representations)
* **AMM pricing / market manipulation risk**
* **Coupon token and yield-trading risk** (CT dynamics, valuation uncertainty, illiquidity)
* **Rehypothecation / strategy risk** (reserve allocation to variable-rate vaults)
* **Governance and parameter-change risk**
* **MEV and transaction execution risk** (front-running, sandwich attacks)
* **Regulatory, legal, and tax risk**

The subsections below describe these risks in more detail. **No single mitigation eliminates risk**, and multiple risks can materialize simultaneously, especially during periods of market stress.

***

### Smart Contract and Technical Risk

Fira relies on smart contracts and supporting software. Smart contracts may contain **vulnerabilities, bugs, logic errors, design flaws, or unintended behaviors**, whether known or unknown at the time of deployment. Any such issue, whether exploited by third parties or triggered by unforeseen conditions, may result in **partial or total loss of funds**, including loss, theft, misallocation, inability to withdraw, forced liquidations, or broader disruption of protocol operations.

Fira also relies on complex flows related to fixed-maturity lending/borrowing, including the issuance and exchange of protocol-specific tokens and market interactions, which may increase implementation and integration risk. Fira's fixed-maturity design involves **BT** (bond tokens) that trade at a discount and converge toward par at maturity, and **CT** (coupon tokens) representing claims on yield, with additional mechanisms for CT trading and reserve management. These mechanisms may introduce additional attack surfaces and edge cases. (See Fira Litepaper for a conceptual overview.)

**Mitigations (not guarantees)** may include audits, testing, monitoring, and (where supported) operational controls such as pausing or restricting certain functions. **Audits and reviews do not guarantee safety**, and recovery of funds after an incident may be impossible or incomplete.

***

### Blockchain, Network, and Infrastructure Risk

Fira runs on public blockchains and depends on their continued operation. Networks may experience congestion, reorgs, forks, downtime, censorship, or changes in operating rules. Such events can cause failed or delayed transactions, unexpected execution outcomes, inability to refinance or repay in time, and increased liquidation risk. Users bear the risk of adverse network conditions, including elevated transaction fees ("gas").

***

### Third-Party Dependency Risk (Tokens, Oracles, DEXs, RPCs, Bridges)

Fira may depend on third-party systems and assets, including stablecoins (e.g., USDC), collateral tokens, oracles, DEX liquidity, RPC infrastructure, and potentially bridges (if deployed across networks). Third-party dependencies can fail, be compromised, change their rules, pause functionality, become insolvent, or restrict transfers (e.g., blacklisting/freezing), which can result in losses or disruptions to Fira users. Fira generally cannot control or guarantee the availability, correctness, or resilience of third-party systems.

***

### Interest Rate Risk (Fixed-Maturity and Floating-Rate Markets)

Fira markets, both fixed-maturity ("fixed-rate") and floating-rate, are exposed to interest rate volatility.

* In **fixed-maturity markets**, "fixed" borrowing costs are **implied by market pricing**, primarily through the relative price (discount) of **BT** versus its underlying asset (e.g., FW-USDC). Because BT pricing is market-driven, the implied fixed rate may change over time. Borrowers who settle or unwind **before maturity** may realize a different effective rate than expected at origination.
* In **floating-rate markets**, borrowing rates typically depend on **utilization** (borrowed vs. supplied liquidity). Sudden shifts in supply or demand, such as large withdrawals or borrowing spikes, can cause utilization (and rates) to increase sharply, potentially leading to abrupt and sustained increases in borrowing costs.

Mitigations such as liquidity concentration, parameterization, and curated liquidity management may reduce (not eliminate) extreme outcomes. **Rates can still move materially**, especially under stress.

***

### Liquidity and Exit Risk

Liquidity conditions can change rapidly. Users may be unable to enter, exit, repay, or unwind positions at reasonable prices or within expected timeframes.

* In fixed-maturity markets, early settlement often requires accessing liquidity (e.g., exchanging cash for BT) and may be costly or impractical when liquidity is thin, leading to high slippage or unfavorable implied rates.
* In floating-rate markets, lender withdrawals may be constrained if liquidity becomes highly utilized; withdrawals may depend on borrower repayments.
* Liquidity providers may face additional constraints if any reserves are allocated elsewhere as part of protocol design.

Liquidity risk may be amplified during volatility, depegs, network congestion, oracle disruptions, or when participants de-risk simultaneously.

***

### Liquidation Risk (Borrowers)

Borrowers must post collateral and maintain sufficient collateralization. If a borrower's risk metrics breach protocol-defined thresholds (e.g., LTV/LLTV), the position may become liquidatable. Liquidations may occur **rapidly and without notice**, especially during volatile markets or when network conditions prevent timely management of positions.

Fira's fixed-maturity design includes maturity-based mechanics in which positions that are not repaid by maturity may be subject to liquidation, potentially resulting in forced execution at unfavorable times. Borrowers may lose some or all of their collateral, and liquidation costs, penalties, slippage, MEV, and transaction fees can materially worsen outcomes.

***

### Bad Debt Risk (Lenders)

Bad debt occurs when seized collateral cannot be liquidated for sufficient value to cover outstanding debt (net of execution costs). Bad debt may result in **losses for lenders** in affected markets and can reduce lender principal and/or realized yield. Bad debt risk is higher during extreme volatility, liquidity evaporation, oracle failures, or network congestion that prevents profitable or timely liquidations.

***

### Collateral and Asset-Specific Risk

Collateral assets may experience sharp price declines, liquidity collapse, depegs, or protocol/issuer failures. Certain assets may have centralization or administrative controls (e.g., blacklist/freeze/upgrade authorities), creating risks that are not present in fully permissionless assets. A collateral asset can "break" suddenly for idiosyncratic reasons (exploit, governance capture, regulatory action, redemption impairment), leaving insufficient time for orderly liquidation and increasing bad debt risk.

***

### Stablecoin and Wrapping Risk (e.g., USDC and FW-USDC)

Fira may use a stablecoin unit (e.g., USDC) and may wrap it into an internal unit of account (e.g., FW-USDC). Stablecoins may lose their peg, experience redemption impairment, be frozen/blacklisted, or be impacted by issuer, banking, or regulatory risks. Wrapping introduces additional smart-contract and operational dependencies, and any failure in wrap/unwrap mechanisms may cause loss, delays, or inability to exit.

***

### AMM Pricing and Market Manipulation Risk

Fira's implied fixed rates rely on market pricing (e.g., BT/FW exchange dynamics) which may be affected by liquidity conditions and trading behavior. AMMs can be subject to slippage, price impact, and manipulation, particularly in thin liquidity conditions. Attackers may attempt to manipulate prices around critical moments (settlements, liquidations, large trades), potentially harming borrowers, lenders, and liquidity providers.

***

### Coupon Token and Yield-Trading Risk (CT)

Fira may support yield-trading via coupon tokens ("CT"), which represent an economic claim on interest/coupon components. CT value may be highly sensitive to assumptions about rates, time to maturity, liquidity, and protocol behavior. CT markets may be thin, volatile, or illiquid, and users may be unable to buy or sell CT at expected prices. Any mechanisms that enable CT trading (including advanced transaction flows) may introduce additional technical and execution risks.

***

### Rehypothecation / Strategy Risk (Reserve Allocation)

Fira may allocate ("rehypothecate") a portion of liquidity reserves into variable-rate strategies or vaults to enhance the economics of holding CT and/or improve capital efficiency. Rehypothecation introduces additional risks, including:

* strategy or vault losses (smart-contract, market, or operational failures),
* delayed liquidity return when users seek to exit,
* dependency on third-party protocols or integrations, and
* increased complexity and attack surface.

Any returns from rehypothecation are **not guaranteed**, and rehypothecation may increase the likelihood of liquidity stress during adverse conditions.

***

### Governance and Parameter-Change Risk

Protocol parameters (collateral eligibility, risk thresholds, caps, reserve allocation targets, fee parameters, etc.) may change through governance or authorized roles, where applicable. Changes may alter the risk profile of markets, affect liquidity, or trigger unintended consequences. Governance processes can be attacked, captured, or mismanaged, and administrative keys or role permissions can introduce additional risk.

***

### MEV and Transaction Execution Risk

On public blockchains, transactions can be front-run, sandwiched, or otherwise exploited (MEV). This can lead to worse execution prices, higher slippage, failed transactions, and increased costs, especially for swaps, liquidations, and large trades. Users may not be able to reliably predict execution outcomes at the time they submit transactions.

***

### Regulatory, Legal, and Tax Risk

The legal and regulatory treatment of DeFi and crypto-assets is evolving and may change rapidly. Fira may not be available in all jurisdictions, and users are responsible for compliance with applicable laws (including sanctions and restrictions). Users are also responsible for determining and meeting tax reporting and payment obligations arising from their activities (including swaps, interest/coupon income, and gains/losses).

***

### No Guarantee; Risk Mitigation Is Not Assurance

Fira may implement security and risk controls (e.g., audits, monitoring, parameter constraints, curated liquidity practices). **These measures reduce certain risks but do not eliminate them.** Users should assume that adverse events, including exploits, depegs, liquidity runs, and rapid market moves, can occur and may result in **complete loss**.

**You should not use Fira unless you fully understand the risks and can bear the loss of all funds you supply, borrow, or otherwise expose to the protocol.**

***

## General Disclaimer

By accessing Fira, you interact with a **non-custodial DeFi protocol** (smart contracts) enabling **variable-rate lending/borrowing** and **fixed-maturity "fixed-rate" borrowing** via Fira tokens.

* **Risk of total loss:** bugs/exploits, user errors, cyberattacks, oracle or network failures, and market events may result in partial or total loss of funds. **On-chain transactions are irreversible.**
* **Liquidation:** borrower positions may be liquidated if collateral value drops and **may be automatically liquidated at maturity** if not repaid.
* **"Fixed rate" mechanics:** the cost is linked to the **BT/FW discount**; **early repayment** may change the effective cost (no guarantee of a "fixed rate" unless repaid at maturity).
* Fira provides **no advice** (financial/legal/tax), offers **no yield guarantee**, and **does not custody** your funds. **Network (gas) fees** and/or third-party fees may apply.
* You confirm you are **of legal age**, not subject to **sanctions**, not in a **restricted jurisdiction**, and you accept the documents below.
* You confirm that you have read the documents relating to **Risks & Security and accept the consequences.**


# Tech Hub

Technical documentation for developers building on or integrating with Fira Protocol — a modular fixed-rate and variable-rate lending infrastructure on Ethereum.

## Start Here

{% content-ref url="/pages/h8h5jd3R8zmYnGHOnJqO" %}
[Protocol Primer](/developers/fira-protocol-primer)
{% endcontent-ref %}

## Explore

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Features</strong></td><td>Fixed-rate lending, variable-rate lending, BT/CT/FW tokens, AMM, rehypothecation, and liquidity injection</td><td><a href="/pages/VKGvABWZC6u3CSSBtDgy">/pages/VKGvABWZC6u3CSSBtDgy</a></td></tr><tr><td><strong>Architecture</strong></td><td>System layers, module dependencies, reentrancy, access control, and upgradability</td><td><a href="/pages/Pqz0M2fHYTAOAHDns2O2">/pages/Pqz0M2fHYTAOAHDns2O2</a></td></tr><tr><td><strong>Smart Contracts</strong></td><td>Protocol contracts, token contracts, utility contracts, oracles, and math libraries</td><td><a href="/pages/6b8r6WHUTXTodZ7Pqxdl">/pages/6b8r6WHUTXTodZ7Pqxdl</a></td></tr><tr><td><strong>User Flows</strong></td><td>Step-by-step transaction flows for borrowing, lending, LPing, and trading</td><td><a href="/pages/U7HfoStAndzJVgarkh7G">/pages/U7HfoStAndzJVgarkh7G</a></td></tr><tr><td><strong>Deployment</strong></td><td>All mainnet addresses, market IDs, oracle pipelines, router facets, and key roles</td><td><a href="/pages/JPdKyzSBx0Myl9d5TlzB">/pages/JPdKyzSBx0Myl9d5TlzB</a></td></tr><tr><td><strong>Events &#x26; Indexing</strong></td><td>On-chain event reference and position measurement methodology</td><td><a href="/pages/WGc28WvmDi7502CG9c7Q">/pages/WGc28WvmDi7502CG9c7Q</a></td></tr><tr><td><strong>Integrations</strong></td><td>Interfaces and integration patterns for building on Fira</td><td><a href="/pages/27R3xazml42u2wLTufXK">/pages/27R3xazml42u2wLTufXK</a></td></tr><tr><td><strong>Security &#x26; Audits</strong></td><td>Security design principles, six independent audits, and bug bounty</td><td><a href="/pages/p6FTB9KfRqtDEmU6Zzsk">/pages/p6FTB9KfRqtDEmU6Zzsk</a></td></tr></tbody></table>

## Quick Reference

| Resource                  | Link                                                                                         |
| ------------------------- | -------------------------------------------------------------------------------------------- |
| **Mainnet Contracts**     | [Deployment](/developers/deployment)                                                         |
| **Source Code**           | [github.com/usual-dao/fira](https://github.com/usual-dao/fira)                               |
| **Lending Market Source** | [github.com/usual-dao/fira-lending-market](https://github.com/usual-dao/fira-lending-market) |
| **Bug Bounty**            | [Sherlock Program](/security-and-risk/bug-bounty)                                            |
| **Glossary**              | [Developer Glossary](/developers/glossary)                                                   |
| **Whitepaper**            | [Fira Whitepaper](/resources/whitepaper)                                                     |

## Key Facts

| Parameter                | Value                                        |
| ------------------------ | -------------------------------------------- |
| Chain                    | Ethereum Mainnet                             |
| Router                   | `0xFF615E63aAF2d1B1EE4AdFD34a5840747185d8A0` |
| FW-USDC                  | `0x62F5366C9E21A95326C461a098a408e034e017b3` |
| BT Expiry (V1)           | May 7, 2026 · May 27, 2026 (USDG)            |
| Fixed-Rate Collateral    | PT-USDe, PT-sUSDe, PT-USDG                   |
| Variable-Rate Collateral | wstETH, cbBTC                                |
| Audits                   | 6 independent external + internal review     |


# Protocol Primer

A high-level introduction to the Fira protocol — what it does, why it exists, and how the pieces fit together.

## What is Fira? (ELI5 version)

Fira is a DeFi protocol that lets you **split yield-bearing assets into separate fixed-rate and floating-rate components**, and then **trade, lend, and provide liquidity** with those components on Ethereum.

Think of it this way: if you have a yield-bearing stablecoin (like USDC deposited in a vault), Fira wraps it into a standardized token called **FW** (Fira Wrapped), then lets you split that FW into two pieces:

* **Bond Token (BT)** — a fixed-rate principal claim. You know exactly what it's worth at maturity.
* **Coupon Token (CT)** — a floating-yield claim. Its value depends on how much yield the underlying asset generates.

### Why does this matter?

In traditional finance, separating principal from yield is a well-established concept (zero-coupon bonds, interest rate strips). Fira brings this to DeFi, enabling:

* **Fixed-rate borrowing** — Borrowers get predictable costs instead of volatile variable rates.
* **Yield speculation** — Traders can go long or short on future yield without holding the full underlying asset.
* **Capital efficiency** — LPs can provide liquidity in the BT/FW pool while simultaneously earning floating yield via CT.

### The core elements of Fira

#### **FW (Fira Wrapped)**

FW tokens are ERC-20 wrappers around yield-bearing assets. They expose a standardized deposit/redeem interface so the rest of the protocol doesn't need to know the specifics of the underlying vault. The first implementation is **USDCFW**, which wraps USDC through an ERC-4626 vault.

**Key features:**

* Standardized interface for any yield-bearing asset
* Exchange rate increases as yield accrues
* Rehypothecation — idle liquidity is deployed to vaults for yield while maintaining enough reserves for redemptions

#### **Bond Token (BT)**

BT is the fixed-rate side of the yield split. Each BT represents a claim on 1 unit of underlying at maturity. Before maturity, BT trades at a discount — the discount is the implied fixed rate.

**Key features:**

* Fixed-rate principal claim
* Trades at a discount to FW in the AMM
* Used as the loan token in fixed-rate lending markets

#### **Coupon Token (CT)**

CT is the floating-rate side. Holding CT entitles you to the yield generated by the underlying FW between now and expiry.

**Key features:**

* Floating yield exposure
* Interest accrues automatically and can be claimed at any time
* Post-expiry, remaining yield flows to the protocol treasury

#### **Fira Market (AMM)**

The AMM is a specialized BT/FW pool with time-decaying implied-rate pricing based on a logit curve. As maturity approaches, BT converges toward FW in value.

**Key features:**

* BT/FW trading pool with LP tokens
* TWAP oracle for pricing BT, CT, and LP tokens
* Swaps and mints revert after expiry; burns work at any time

#### **Fixed-Rate Lending**

Borrowers post collateral (e.g., Pendle PT tokens) and borrow BT at a fixed rate. The router automatically swaps BT to FW and then to USDC, so borrowers receive stablecoins in a single transaction.

#### **Variable-Rate Lending**

A separate lending market (powered by SisuVault, an ERC-4626 vault) allows standard variable-rate borrowing with collateral like wstETH and cbBTC.

#### **Router**

The router is the single entry point for all user operations. It uses a diamond-like proxy pattern where each function is delegated to a specialized facet contract. Users never interact with the underlying contracts directly — everything goes through the router.


# Features

The Fira protocol provides a comprehensive set of features for yield tokenization, fixed-rate lending, and liquidity provisioning on Ethereum.

<table data-card-size="large" data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>FW (Fira Wrapped)</strong></td><td><a href="/pages/6kX3Equu7qzo7BH5ShJT">/pages/6kX3Equu7qzo7BH5ShJT</a></td></tr><tr><td align="center"><strong>Bond Token (BT)</strong></td><td><a href="/pages/USLZ8hHn1lUDPIKpwGvr">/pages/USLZ8hHn1lUDPIKpwGvr</a></td></tr><tr><td align="center"><strong>Coupon Token (CT)</strong></td><td><a href="/pages/omohXHLuMjgpiKnIMkVa">/pages/omohXHLuMjgpiKnIMkVa</a></td></tr><tr><td align="center"><strong>Fira Market (AMM)</strong></td><td><a href="/pages/nIj6ywkL7QAL2KH3qDan">/pages/nIj6ywkL7QAL2KH3qDan</a></td></tr><tr><td align="center"><strong>Fixed-Rate Lending</strong></td><td><a href="/pages/8vFJHSafnmxAtpP7to6p">/pages/8vFJHSafnmxAtpP7to6p</a></td></tr><tr><td align="center"><strong>Variable-Rate Lending</strong></td><td><a href="/pages/ON0nKMn1jWkOnVihgOIa">/pages/ON0nKMn1jWkOnVihgOIa</a></td></tr><tr><td align="center"><strong>Rehypothecation</strong></td><td><a href="/pages/6n1dV9ty7VJY09xCqeX9">/pages/6n1dV9ty7VJY09xCqeX9</a></td></tr><tr><td align="center"><strong>Liquidity Injector</strong></td><td><a href="/pages/dG7f67WnrNSX7xrhF0Ew">/pages/dG7f67WnrNSX7xrhF0Ew</a></td></tr></tbody></table>


# Fixed-Rate Lending

Fira enables fixed-rate borrowing through a lending market where BT serves as the loan token, giving borrowers predictable costs.

## Overview

Fira's fixed-rate lending allows borrowers to post collateral and borrow at a known, fixed rate. The mechanism works by using **Bond Token (BT)** as the loan token in a dedicated lending market. Since BT is redeemable for a known value at maturity, the borrowing cost is determined by the BT discount at the time of borrowing.

{% hint style="info" %}
The fixed-rate lending market has **no interest rate model** (`IRM = address(0)`). The rate is implicit in the BT discount — the difference between the BT price at borrow time and its face value at maturity is the borrower's fixed cost.
{% endhint %}

## How it works

### Borrowing

The router's `supplyAndBorrowSingleToken` function handles the full flow in a single transaction:

1. **Supply collateral** — Collateral tokens (e.g., Pendle PT tokens) are deposited into the lending market
2. **Borrow BT** — BT is borrowed from the lending market (supplied by the LiquidityInjector)
3. **Swap BT → FW** — BT is swapped to FW via the Fira Market AMM
4. **Redeem FW → USDC** — FW is redeemed for the desired output token

The borrower receives USDC (or another token) and holds a fixed-rate debt position denominated in BT.

### Repaying

**Pre-expiry:** Input token → FW (mint) → BT (AMM swap) → repay lending market.

**Post-expiry:** Input token → FW (mint) → BT+CT (mint via CT contract) → repay with BT. CT is minted but has zero economic value post-expiry.

### Collateral types

Fixed-rate markets currently support Pendle Principal Tokens (PT) as collateral:

* **PT-USDe** (Ethena USDe, May 7 2026 expiry)
* **PT-sUSDe** (Ethena sUSDe, May 7 2026 expiry)
* **PT-USDG** (Paxos USDG, May 27 2026 expiry)

### Liquidation

Positions that fall below the liquidation LTV (`LLTV`) can be liquidated. The liquidator repays part of the debt and receives collateral plus a liquidation incentive.

## Key features

* **Predictable costs** — Fixed rate determined at borrow time
* **Single-transaction flow** — Collateral supply, BT borrow, swap, and redemption in one call
* **Whitelist-gated supply** — Only the LiquidityInjector can supply BT to fixed-rate markets
* **Maturity grace period** — 24-hour grace period after BT expiry before liquidations are enforced

## Related pages

* [Borrow at Fixed Rate (User Flow)](/developers/user-flows/borrow-fixed-rate)
* [Repay Fixed-Rate Debt (User Flow)](/developers/user-flows/repay-fixed-rate)
* [Liquidity Injector](/developers/features/liquidity-injector)
* [ActionBorrow](/developers/protocol-contracts/router/action-borrow)


# Variable-Rate Lending

Fira supports variable-rate lending and borrowing through the SisuVault and a standard lending market with oracle-enforced LTV.

## Overview

Fira's variable-rate market operates alongside the fixed-rate system. Borrowers post collateral (wstETH, cbBTC) and borrow USDC at a variable rate that adjusts based on utilization. Lenders deposit USDC into the **SisuVault** (an ERC-4626 vault) to earn variable yield.

{% hint style="info" %}
FW tokens rehypothecate part of their underlying into the variable-rate market on the supply side. This means FW depositors indirectly earn variable-rate lending yield in addition to any other yield sources.
{% endhint %}

## How it works

### Lending (supplying)

Users deposit USDC into the SisuVault and receive vault shares (`mkUSDC`). The vault aggregates deposits and supplies them across lending markets. Yield accrues as borrowers pay interest, increasing the vault's share price over time.

### Borrowing

Borrowers interact directly with the Variable Rate LendingMarket:

1. **Approve** collateral token to the lending market
2. **Supply collateral** via `supplyCollateral(marketParams, amount, user, "")`
3. **Borrow** via `borrow(marketParams, usdcToBorrow, 0, user, receiver)`

Interest accrues continuously based on the `AdaptiveCurveIrm` interest rate model, which adjusts rates based on utilization.

### Repaying

Borrowers approve USDC to the lending market and call `repay(marketParams, assets, 0, user, "")`. The position's borrow balance is reduced accordingly.

### Supported collateral

| Collateral | LTV | LLTV | Oracle                                 |
| ---------- | --- | ---- | -------------------------------------- |
| wstETH     | 87% | 89%  | Morpho wstETH/USDC                     |
| cbBTC      | 88% | 90%  | ChainlinkOracleV2 (BTC/USD + USDC/USD) |

## Key features

* **Variable yield for lenders** — Earn yield proportional to vault share ownership
* **Multiple collateral types** — wstETH and cbBTC supported
* **Adaptive interest rates** — Rates adjust based on market utilization
* **Permissionless** — No whitelist required for variable-rate markets
* **ERC-4626 vault** — Standard vault interface for composability

## Related pages

* [Variable-Rate Lending (User Flow)](/developers/user-flows/variable-rate-lending)
* [Repay Variable-Rate Debt (User Flow)](/developers/user-flows/repay-variable-rate)
* [Lending Contracts](/developers/protocol-contracts/lending)


# Bond Token (BT)

Bond Token (BT) is the fixed-rate principal token in Fira's yield tokenization system.

## Overview

BT represents a fixed-rate claim on the underlying asset. Each BT is redeemable for 1 unit of underlying at maturity. Before maturity, BT trades at a discount in the AMM — the discount reflects the implied fixed rate.

{% hint style="info" %}
BT and CT are always minted and burned in pairs. You cannot create BT without also creating CT, and vice versa. This ensures the total claims always match the underlying FW.
{% endhint %}

## How it works

### Minting

BT is created through the CouponToken's `mintBC` function. FW is deposited into the CT contract, and equal amounts of BT and CT are minted based on the current BC Index. The conversion rate ensures that `BT amount + CT amount` always equals the underlying value of the FW deposited.

### Redemption

**Pre-expiry:** Both BT and CT must be provided. They are burned together and FW is returned.

**Post-expiry:** Only BT is required. The CT is not burned (it has zero economic value post-expiry). FW is returned at the current BC Index rate, with any post-expiry yield accrual going to the protocol treasury.

### Trading

BT trades against FW in the Fira Market AMM. As expiry approaches, the BT/FW exchange rate converges toward 1:1 (at the BC Index rate), since BT becomes redeemable for full underlying value at maturity.

## Key features

* **Fixed-rate principal** — Predictable value at maturity
* **Strict access control** — Only the paired CouponToken and the LiquidityInjector can mint or burn BT
* **Used as loan token** — In fixed-rate lending markets, borrowers receive BT which is swapped to USDC via the router
* **Immutable references** — FW address, factory, and expiry are set at creation and cannot be changed

## Related contracts

* [`BondToken.sol`](/developers/protocol-contracts/yield-contracts/bond-token) — Contract details
* [`CouponToken.sol`](/developers/protocol-contracts/yield-contracts/coupon-token) — Paired CT contract
* [`YieldContractFactory.sol`](/developers/protocol-contracts/yield-contracts/yield-contract-factory) — Factory that deploys BT/CT pairs


# Coupon Token (CT)

Coupon Token (CT) is the floating-yield token in Fira's yield tokenization system, representing a claim on variable yield generated by the underlying asset.

## Overview

CT represents the floating-yield component of the yield split. Holding CT entitles you to the yield generated by the underlying FW between the time of minting and expiry. Interest accrues automatically and can be claimed at any time.

{% hint style="info" %}
CT is the stateful contract that drives the entire BT/CT lifecycle. It manages minting, redemption, interest accounting, and post-expiry behavior.
{% endhint %}

## How it works

### Interest accrual

CT uses a per-user interest tracking system. On every CT transfer (including mints and burns), interest is distributed to both sender and receiver. The interest formula is:

```
interest = principal × (currentIndex - prevIndex) / (prevIndex × currentIndex)
```

Users can claim accrued interest at any time via `redeemDueInterestAndRewards`. A configurable `interestFeeRate` is deducted at claim time and sent to the treasury.

### BC Index caching

If `doCacheIndexSameBlock` is enabled, the BC Index is only updated once per block. This prevents sandwich attacks where the FW exchange rate is manipulated within a block to extract value from CT holders.

### Post-expiry behavior

On the first interaction after expiry, the CT contract snapshots the BC Index and freezes it. After this point:

* **Interest index is frozen** — No new yield accrues to CT holders
* **Post-expiry yield flows to treasury** — Any yield generated after expiry belongs to the protocol
* **CT is not burned on redemption** — Post-expiry, only BT is required for redemption; CT has zero economic value

## Key features

* **Floating yield exposure** — Earn variable yield from the underlying asset
* **Automatic interest tracking** — Interest is distributed on every transfer
* **Post-expiry treasury sweep** — Unclaimed post-expiry yield can be swept to treasury
* **Reentrancy protected** — All external mutating functions use `nonReentrant`

## Related contracts

* [`CouponToken.sol`](/developers/protocol-contracts/yield-contracts/coupon-token) — Contract details
* [`InterestManagerCT.sol`](/developers/protocol-contracts/yield-contracts/coupon-token) — Interest accrual logic
* [`BondToken.sol`](/developers/protocol-contracts/yield-contracts/bond-token) — Paired BT contract


# FW (FiraWrapped)

FW (Fira Wrapped) tokens are ERC-20 wrappers around yield-bearing assets that provide the base layer for the entire Fira protocol.

## Overview

FW tokens wrap yield-bearing assets (e.g., USDC in an ERC-4626 vault) into a standardized ERC-20 interface. The FW token is the foundation of the protocol — BT and CT are minted from FW, and the AMM trades BT against FW.

{% hint style="info" %}
The first FW implementation is **USDCFW**, which wraps USDC through the SisuVault (an ERC-4626 vault). The FW exchange rate increases over time as yield accrues from the underlying vault.
{% endhint %}

## How it works

### Deposit

Users deposit a supported token (e.g., USDC) and receive FW shares. The number of shares depends on the current exchange rate. Deposits are validated against `isValidTokenIn` and protected by a `minSharesOut` slippage guard.

### Redeem

Users burn FW shares and receive the underlying token. The amount returned depends on the current exchange rate, which increases as yield accrues. Redemptions are validated against `isValidTokenOut` and protected by a `minTokenOut` slippage guard.

### Exchange rate

The FW exchange rate is the ratio of total underlying assets to total FW shares. It monotonically increases as the underlying vault generates yield. This property is critical: it ensures that BT+CT always represent at least as much underlying as the FW used to create them.

## Key features

* **Standardized interface** — Any yield-bearing asset can be wrapped into FW, allowing the rest of the protocol to work with a uniform API.
* **Yield accrual** — The exchange rate increases over time as the underlying vault earns yield.
* **Pause controls** — Three independent pause mechanisms: deposits-only, redemptions-only, or global pause (blocks all transfers).
* **Rehypothecation** — Underlying tokens are split between idle reserves (for instant redemptions) and vault deployment (for yield). See [Rehypothecation](/developers/features/rehypothecation).

## BC Index

The **BC Index** is derived from the FW exchange rate and is used throughout the protocol for yield tokenization. It is defined as:

```
BCIndex = max(FW.exchangeRate(), previousBCIndex)
```

The BC Index is monotonically non-decreasing, which guarantees that BT+CT always represent at least as much underlying as the FW that was used to create them, even if the FW exchange rate temporarily dips.

## Related contracts

* [`FWBase.sol`](/developers/token-contracts/fw-tokens) — Abstract base contract
* [`USDCFW.sol`](/developers/token-contracts/fw-tokens) — USDC implementation
* [`BCIndex.sol`](/developers/utility-contracts/libraries/helpers) — Type wrapper and conversion functions


# Fira Market AMM

The Fira Market is a specialized AMM for trading Bond Tokens against Fira Wrapped tokens, with time-decaying implied-rate pricing.

## Overview

The Fira Market is a BT/FW liquidity pool with a pricing curve specifically designed for fixed-rate instruments. As expiry approaches, BT converges toward FW in value — the AMM's logit-based curve naturally handles this convergence.

{% hint style="info" %}
Each Fira Market is specific to a single BT and curve configuration (`scalarRoot`, `initialAnchor`, `lnFeeRateRoot`). Markets are deployed via the FiraMarketFactory using CREATE2 for deterministic addresses.
{% endhint %}

## How it works

### Adding liquidity

Liquidity providers deposit BT and FW in the correct ratio and receive LP tokens. On the first deposit, `MINIMUM_LIQUIDITY` (1000 wei) is locked to `address(1)` to prevent the first-depositor rounding attack. Subsequent deposits mint LP proportional to the limiting token.

Tokens must be transferred to the market before calling `mint` — the contract does not pull tokens.

### Removing liquidity

LP tokens are burned in exchange for proportional BT and FW. LP must be sent to the market before calling `burn`. This works both pre- and post-expiry.

### Swaps

The market supports two swap directions:

* **`swapExactBtForFw`** — Sell BT for FW. Uses a flash-callback pattern: the market sends FW first, then verifies BT repayment.
* **`swapFwForExactBt`** — Buy BT with FW. Sends BT out first, calls back, and checks FW repayment.

Both swap functions are gated by `notExpired` — no swaps are allowed after the BT expiry date.

### TWAP Oracle

Every state write records a new observation in a ring buffer (if the block timestamp differs from the last). The `observe(secondsAgos)` function returns cumulative `ln(impliedRate)` values for time-weighted average price calculations. Anyone can pre-allocate observation slots via `increaseObservationsCardinalityNext` to support longer TWAP windows.

## Key features

* **Time-decaying pricing** — Logit curve ensures BT converges to FW value as expiry approaches
* **Flash-callback swaps** — Tokens are sent before verification, enabling atomic multi-step operations
* **Built-in TWAP oracle** — Ring buffer of implied rate observations for external price feeds
* **Reserve fees** — A portion of swap fees goes to the protocol treasury
* **Immutable markets** — Once deployed, market parameters cannot be changed (fee overrides are managed by the factory)

## Invariants

* Internal `totalBt` and `totalFw` are never affected by direct transfers — `skim()` sends excess to treasury
* Exchange rate is always >= 1.0 (BT trades at a discount to FW)
* Swaps and mints revert after expiry; burns work at any time

## Related contracts

* [`FiraMarket.sol`](/developers/protocol-contracts/core/fira-market) — AMM contract details
* [`FiraMarketFactory.sol`](/developers/protocol-contracts/core/fira-market-factory) — Factory contract
* [`MarketMathCore.sol`](/developers/protocol-contracts/core/market-math-core) — Pricing math


# Rehypothecation

The Rehypothecation Module controls how FW tokens balance between idle reserves and yield-generating vault deployments.

## Overview

FW tokens hold their underlying assets in two places: **idle reserves** (for instant redemptions) and an **ERC-4626 vault** (for yield generation). The RehypothecationModule defines the parameters that govern this balance.

{% hint style="info" %}
Rehypothecation ensures FW always has enough idle liquidity for redemptions while maximizing yield by deploying the rest into the underlying vault.
{% endhint %}

## How it works

The RehypothecationModule defines three parameters (in basis points):

| Parameter   | Purpose                                                                        |
| ----------- | ------------------------------------------------------------------------------ |
| `phiMin`    | Minimum idle ratio — if idle drops below this, assets are withdrawn from vault |
| `phiMax`    | Maximum idle ratio — if idle exceeds this, excess is deposited into vault      |
| `phiTarget` | Target idle ratio — used by `forceRehypothecation()` to rebalance              |

### Triggering rebalance

* **`triggerRehypothecation()`** — Callable by anyone. Deposits excess to vault if `idleRatio > phiMax`, or withdraws from vault if `idleRatio < phiMin`. No-ops if the ratio is within bounds.
* **`forceRehypothecation()`** — Owner-only. Always rebalances to `phiTarget` regardless of current ratio.

### Example

If `phiMin = 10%`, `phiMax = 30%`, `phiTarget = 20%`:

* FW holds 100 USDC total, 5 USDC idle (5% idle ratio → below `phiMin`)
* Anyone calls `triggerRehypothecation()` → vault withdraws USDC to bring idle up
* After rebalance: \~20 USDC idle, \~80 USDC in vault

## Key features

* **Automatic yield optimization** — Excess idle funds are deployed for yield
* **Redemption guarantees** — Minimum idle ratio ensures users can always redeem
* **Permissionless triggers** — Anyone can call `triggerRehypothecation()` when out of bounds
* **Owner-controlled force rebalance** — Protocol can rebalance to target at any time

## Related contracts

* [`RehypothecationModule.sol`](/developers/protocol-contracts/rehypothecation-module) — Contract details
* [`FWBase.sol`](/developers/token-contracts/fw-tokens) — FW base contract that uses the module


# Liquidity Injector

The Liquidity Injector bootstraps fixed-rate lending markets by minting and supplying BT as initial liquidity.

## Overview

Fixed-rate lending markets need BT as the loan token, but BT can normally only be created by splitting FW through the yield tokenization process. The Liquidity Injector solves this chicken-and-egg problem by having a special privilege to mint BT directly, without backing FW.

{% hint style="info" %}
The "unbacked" BT minted by the Liquidity Injector is safe because the lending market requires borrowers to post collateral. When borrowers repay their loans, the BT is burned. The injector is simply the bootstrap mechanism.
{% endhint %}

## How it works

### Inject liquidity

`injectLiquidity(params, amount)`:

1. Validates the market is a fixed-rate market (`params.irm == address(0)`)
2. Mints BT via `BondToken.mintByLI()` — the only way to create BT outside the normal FW→BT+CT path
3. Supplies the BT to the lending market via `lendingMarket.supply()`
4. Tracks the injection amount in `marketStats[marketId]`

### Withdraw liquidity

`withdrawLiquidity(params, amount)`:

1. Checks available liquidity (total supply minus total borrows)
2. Withdraws BT from the lending market
3. Burns the BT via `BondToken.burnByLI()`
4. Updates `marketStats[marketId]`

The available liquidity check prevents withdrawal from disrupting existing borrows.

## Key features

* **Owner-only operation** — Only the protocol owner can inject or withdraw
* **No resting state** — BT is either in the lending market or burned; the injector never holds BT idly
* **Per-market tracking** — `marketStats` records net injected amounts per market
* **Self-balancing** — Borrowers must repay BT, which is then burned, closing the loop

## Risk considerations

The unbacked BT creates a soft protocol liability: if the underlying FW exchange rate rises significantly, BT becomes more valuable than when it was minted. However, since borrowers must post collateral and repay in BT, the system is self-balancing.

## Related contracts

* [`LiquidityInjector.sol`](/developers/protocol-contracts/liquidity-injector) — Contract details
* [`BondToken.sol`](/developers/protocol-contracts/yield-contracts/bond-token) — BT contract with `mintByLI`/`burnByLI`


# Architecture

An overview of Fira's system architecture, module dependencies, and cross-cutting design decisions.

## System overview

The Fira protocol is organized into a layered architecture where each module has a clear responsibility and well-defined dependencies.

```mermaid
%%{init: {'flowchart': {'curve': 'monotoneY', 'rankSpacing': 60, 'nodeSpacing': 40, 'padding': 24}}}%%
flowchart TB
  subgraph userLayer ["  User Layer  "]
    Router["<b>FiraRouterV4</b><br/>Diamond Proxy"]
  end

  subgraph coreLayer ["  Core Protocol  "]
    LM["<b>LendingMarket</b><br/>Fixed + Variable Rate"]
    Market["<b>FiraMarket</b><br/>BT/FW AMM"]
    YC["<b>YieldContracts</b><br/>BT + CT"]
  end

  subgraph baseLayer ["  Base Layer  "]
    FW["<b>FW</b><br/>Fira Wrapped"]
    Vault["<b>SisuVault</b><br/>ERC-4626 Vault"]
  end

  subgraph supportLayer ["  Support  "]
    LI["<b>LiquidityInjector</b>"]
    Oracles["<b>Oracles</b><br/>TWAP · Solvency"]
    Rehyp["<b>Rehypothecation</b><br/>Module"]
  end

  Router --> LM
  Router --> Market
  Router --> YC
  Market --> YC
  YC --> FW
  FW --> Vault
  LI -.-> LM
  LI -.-> YC
  Oracles -.-> Market
  Rehyp -.-> FW

  linkStyle default stroke-width:2.5px,stroke:#475569
  linkStyle 6,7,8,9 stroke:#7c3aed,stroke-width:2px

  style userLayer fill:#dbeafe,stroke:#2563eb,stroke-width:2px
  style coreLayer fill:#fef3c7,stroke:#d97706,stroke-width:2px
  style baseLayer fill:#d1fae5,stroke:#059669,stroke-width:2px
  style supportLayer fill:#ede9fe,stroke:#7c3aed,stroke-width:2px

  style Router fill:#2563eb,stroke:#1d4ed8,color:#fff,stroke-width:2px
  style LM fill:#d97706,stroke:#b45309,color:#fff,stroke-width:2px
  style Market fill:#d97706,stroke:#b45309,color:#fff,stroke-width:2px
  style YC fill:#d97706,stroke:#b45309,color:#fff,stroke-width:2px
  style FW fill:#059669,stroke:#047857,color:#fff,stroke-width:2px
  style Vault fill:#059669,stroke:#047857,color:#fff,stroke-width:2px
  style Oracles fill:#7c3aed,stroke:#6d28d9,color:#fff,stroke-width:2px
  style LI fill:#7c3aed,stroke:#6d28d9,color:#fff,stroke-width:2px
  style Rehyp fill:#7c3aed,stroke:#6d28d9,color:#fff,stroke-width:2px
```

Solid arrows = primary dependencies. Dashed purple arrows = support modules.

## Module dependency graph

The dependency flow is: **Router → Market + YieldContracts → FW → Underlying Vault**

* The **Router** holds no state of its own (beyond selector mappings). Each action facet reads market and yield contract state, orchestrates token transfers, and calls into the market or CT contract to execute operations.
* The **Market** depends on CT for the BC index (needed for pricing) and on the factory for fee configuration.
* **CT** depends on FW for the exchange rate (to compute the BC index) and on BT for mint/burn gating.
* **FW** tokens wrap external yield sources (ERC-4626 vaults) and expose a standardized deposit/redeem interface.
* The **RehypothecationModule** controls how much of FW's underlying sits idle vs. deployed in the vault.

## Cross-cutting concerns

### Reentrancy

Every external entry point uses `nonReentrant` from `FiraERC20`. The router relies on the market and CT contracts for reentrancy protection — the router itself has no reentrancy guard because it delegates all state-changing calls to contracts that do.

### Access control

| Component         | Owner controls                               |
| ----------------- | -------------------------------------------- |
| Factory           | Market fee configuration                     |
| CT Factory        | Interest fee configuration, treasury address |
| FW                | Pausing, rehypothecation module assignment   |
| Router            | Selector-to-facet mappings                   |
| LiquidityInjector | BT injection and withdrawal                  |

### Upgradability

* **Markets and yield contracts** are **not upgradeable** — deployed via factories and immutable once created.
* The **Router** is pseudo-upgradeable — the owner can point selectors at new facet addresses, effectively upgrading logic without migrating state.
* **FW tokens** use `BoringOwnableUpgradeable` and the `initializer` pattern for proxy-based upgradability.

## Related pages

* [Router Architecture](/developers/architecture/router-architecture) — Diamond proxy pattern details
* [Features](/developers/features) — Individual feature descriptions
* [Protocol Contracts](/developers/protocol-contracts) — Contract-level documentation


# 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.

{% 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) — Router contract details
* [Router Facets](/developers/protocol-contracts/router) — Individual facet documentation
* [Contract Deployments](/developers/deployment) — Deployed facet addresses


# Protocol Contracts

Protocol contracts form the core logic of the Fira protocol — the AMM, yield tokenization, router, lending markets, and supporting modules.

<table data-card-size="large" data-view="cards"><thead><tr><th align="center"></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td align="center"><strong>Core (AMM + Math)</strong></td><td><a href="/pages/8y46hAi3IVo4tosMUqdq">/pages/8y46hAi3IVo4tosMUqdq</a></td></tr><tr><td align="center"><strong>Yield Contracts (BT + CT)</strong></td><td><a href="/pages/lxTo3gz8vZzVkoFrFNaE">/pages/lxTo3gz8vZzVkoFrFNaE</a></td></tr><tr><td align="center"><strong>Router (Action Facets)</strong></td><td><a href="/pages/uPJSQJaXYu0CFcVDYBql">/pages/uPJSQJaXYu0CFcVDYBql</a></td></tr><tr><td align="center"><strong>Lending Markets</strong></td><td><a href="/pages/2kqpJmKhv9er4RTkFeCy">/pages/2kqpJmKhv9er4RTkFeCy</a></td></tr><tr><td align="center"><strong>Liquidity Injector</strong></td><td><a href="/pages/T0wRHPaGYPpjqFfdTQ9F">/pages/T0wRHPaGYPpjqFfdTQ9F</a></td></tr><tr><td align="center"><strong>Rehypothecation Module</strong></td><td><a href="/pages/1sOTRDrev1o7F537Ttg3">/pages/1sOTRDrev1o7F537Ttg3</a></td></tr></tbody></table>


# Core

The core directory contains the AMM trading infrastructure and yield tokenization system — the two pillars of the Fira protocol.

The core module houses the contracts users interact with (through the router) to trade, provide liquidity, and split yield into fixed and floating components.

## How Market and YieldContracts interact

The two subsystems are tightly coupled. A `FiraMarket` is parameterized by a BT address, and every swap queries the associated CT contract for the current BC index (via `CT.newIndex()`). The BC index determines how BT (denominated in asset units) should price against FW.

When the BC index rises (because the underlying vault earns yield), BT becomes cheaper in FW terms. The AMM incorporates this automatically: `getMarketPreCompute` converts FW reserves to asset terms before computing the exchange rate, so the pricing curve always reflects the current yield environment.

At expiry, the market freezes: swaps and new deposits revert. Burns still work, letting LPs exit. Post-expiry exits go through `CT.redeemBC()` rather than AMM swaps.

## State management pattern

Both the market and yield contracts use a **read-modify-write pattern** with in-memory structs. The market loads `MarketState` into memory via `readState`, mutates it through `MarketMathCore` library calls, and persists it through `_writeState`. This avoids repeated SLOAD/SSTORE operations and keeps the math library pure.

## Contracts

* [FiraMarket](/developers/protocol-contracts/core/fira-market) — BT/FW AMM with LP tokens
* [FiraMarketFactory](/developers/protocol-contracts/core/fira-market-factory) — Split-code CREATE2 market deployment
* [MarketMathCore](/developers/protocol-contracts/core/market-math-core) — Pricing curve and trade execution math


# FiraMarket

FiraMarket is the BT/FW AMM — it holds reserves, executes swaps, manages LP tokens, and maintains TWAP oracle state.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/Market/v3/FiraMarket.sol`
{% endhint %}

## Contract summary

`FiraMarket` extends `FiraERC20` — the LP token *is* the market contract itself. It holds BT and FW reserves and tracks internal balances separately from actual token balances to prevent interference from direct transfers.

Key state is packed into `MarketStorage` for gas: `totalBt`, `totalFw` (int128), `lastLnImpliedRate` (uint96), and oracle observation indices (uint16 each).

## Functionality

### Mint (add liquidity)

`mint(receiver, netFwDesired, netBtDesired)` loads state into memory, calls `MarketMathCore.addLiquidity`, and writes back. On first deposit it locks `MINIMUM_LIQUIDITY` (1000 wei of LP) to `address(1)` to prevent the first-depositor rounding attack. Subsequent deposits mint LP proportional to the limiting token.

Tokens must be transferred to the market before calling `mint` — the contract does not pull.

### Burn (remove liquidity)

`burn(receiverFw, receiverBt, netLpToBurn)` burns LP from `address(this)`, computes proportional FW and BT outputs, and transfers them out. LP must be sent to the market before calling. Works both pre- and post-expiry.

### Swaps

* **`swapExactBtForFw`** — Flash-callback pattern: sends FW out first, then verifies BT repayment via callback.
* **`swapFwForExactBt`** — Sends BT out first, calls back, checks FW repayment.

Both swap functions send the reserve fee portion to the treasury and are gated by `notExpired`.

### Oracle

Every call to `_writeState` writes a new observation to the `OracleLib` ring buffer. `observe(secondsAgos)` returns cumulative `ln(impliedRate)` values for TWAP calculations. `increaseObservationsCardinalityNext` lets anyone pre-allocate observation slots.

### Skim

`skim()` sends any excess BT or FW (above internal totals) to the treasury. This prevents direct transfers from affecting pool pricing.

## Invariants

* Internal `totalBt` and `totalFw` are never affected by direct transfers
* Exchange rate is always >= 1.0 (BT trades at a discount to FW)
* `address(0)` and `address(this)` never have reward or balance accounting
* Swaps and mints revert after expiry; burns work at any time


# FiraMarketFactory

FiraMarketFactory deploys FiraMarket instances via split-code CREATE2 and manages fee configuration.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/Market/v3/FiraMarketFactory.sol`
{% endhint %}

## Contract summary

Deploys markets using split-code CREATE2 (because `FiraMarket` exceeds the 24KB EVM contract size limit). Markets are keyed by `BT + scalarRoot + initialAnchor + lnFeeRateRoot` — creating the same combination twice reverts.

## Functionality

### Market creation

The factory validates that the BT comes from the registered `YieldContractFactory` and is not expired, then deploys the market using the split-code pattern (bytecode is split across two storage contracts and concatenated at deploy time).

### Fee management

The factory stores:

* **Treasury address** — Receives reserve fees from swaps
* **Reserve fee percent** — Portion of swap fees sent to treasury
* **Router-specific fee overrides** — Must be strictly less than the market's base fee

`getMarketConfig(market, router)` is called by the market on every `readState` to load treasury, fee overrides, and reserve percent. This means fee changes take effect on the next trade without redeployment.

### Duplicate prevention

Markets are uniquely identified by their BT address and curve parameters. Attempting to create a duplicate reverts.


# MarketMathCore

MarketMathCore encodes the time-decaying pricing curve and trade execution math used by FiraMarket. OracleLib provides the TWAP ring buffer.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/Market/MarketMathCore.sol`, `src/fira_bonding/core/Market/OracleLib.sol`
{% endhint %}

## MarketMathCore

This library operates entirely on in-memory `MarketState` structs for gas efficiency. It never reads from or writes to storage directly.

### Pricing model

The AMM prices BT relative to FW using a logit curve:

```
exchangeRate = ln(proportion / (1 - proportion)) / rateScalar + rateAnchor
```

Where `proportion = totalBt / (totalBt + totalAsset)` and `totalAsset` is FW reserves converted to underlying asset units via the BC index.

* **`rateScalar`** scales inversely with time-to-expiry (`scalarRoot × 365 days / timeToExpiry`), making the curve steeper near maturity.
* **`rateAnchor`** is recalculated after each trade so that the current pool proportion yields the last recorded implied rate.

### Liquidity math

* **First deposit:** Mints `sqrt(fw × bt) - MINIMUM_LIQUIDITY` LP tokens, locking 1000 wei permanently.
* **Subsequent deposits:** Mints proportional to the limiting token.
* **Removal:** Returns proportional shares of both reserves.

### Trade execution

`executeTradeCore` loads pre-computed values, calculates the FW amount from the exchange rate, applies fees, and updates state. Fees are split between the swapper (as worse pricing) and the reserve (as a percentage of the fee). The post-trade implied rate is recalculated and stored.

### Key invariants

* Exchange rate is always >= 1e18 (reverts otherwise)
* BT proportion cannot exceed `MAX_MARKET_PROPORTION` (96%)
* Implied rate is always > 0 after a trade
* `MINIMUM_LIQUIDITY` prevents the first-depositor attack

## OracleLib

Adapted from Uniswap V3's oracle. Stores `Observation` structs (timestamp + cumulative `ln(impliedRate)` + initialized flag) in a fixed-size array of 65,535 slots.

* **`write()`** — Appends a new observation if the block timestamp differs from the last
* **`grow()`** — Pre-initializes storage slots to reduce gas during swaps
* **`observe()`** — Returns cumulative values at requested time offsets using binary search
* **TWAP** is computed by the caller as `(cumulative[now] - cumulative[ago]) / duration`


# Lending

Fira's lending infrastructure includes separate markets for fixed-rate (BT-denominated) and variable-rate (USDC-denominated) lending.

## Overview

Fira uses two lending market deployments:

### FiraLendingMarket (Fixed-Rate)

* **Loan token:** BT (Bond Token)
* **Collateral:** Pendle PT tokens (PT-USDe, PT-sUSDe, PT-USDG)
* **Interest rate model:** None (`IRM = address(0)`) — the rate is implicit in the BT discount
* **Supply:** Whitelist-gated to the LiquidityInjector only
* **Oracle:** FiraSolvencyOracle (3-layer oracle pipeline)

### VariableLendingMarket (Variable-Rate)

* **Loan token:** USDC
* **Collateral:** wstETH, cbBTC
* **Interest rate model:** AdaptiveCurveIrm (adjusts based on utilization)
* **Supply:** Permissionless via SisuVault (ERC-4626)
* **Oracle:** Morpho wstETH/USDC, ChainlinkOracleV2 for cbBTC/USDC

## SisuVault

The SisuVault is an ERC-4626 vault that aggregates USDC deposits and supplies them to variable-rate lending markets. It is managed by a curator and allocator (Markov Labs) who control market allocation.

Vault shares (`mkUSDC`) represent proportional claims on the underlying USDC plus accrued interest.

## Key functions

| Function                                             | Description                            |
| ---------------------------------------------------- | -------------------------------------- |
| `supplyCollateral(params, amount, user, data)`       | Deposit collateral                     |
| `borrow(params, assets, shares, user, receiver)`     | Borrow loan token                      |
| `repay(params, assets, shares, onBehalf, data)`      | Repay debt                             |
| `withdrawCollateral(params, amount, user, receiver)` | Withdraw collateral                    |
| `liquidate(params, borrower, seizedAssets)`          | Liquidate undercollateralized position |
| `getUserPosition(params, user)`                      | View full position details             |
| `accrueInterest(params)`                             | Update interest state                  |

## Related pages

* [Fixed-Rate Lending (Feature)](https://github.com/Pi-2lavega/fira-gitbook-sync-final/blob/main/developers/smart-contracts/overview/features/fixed-rate-lending.md)
* [Variable-Rate Lending (Feature)](https://github.com/Pi-2lavega/fira-gitbook-sync-final/blob/main/developers/smart-contracts/overview/features/variable-rate-lending.md)
* [Contract Deployments](https://github.com/Pi-2lavega/fira-gitbook-sync-final/blob/main/developers/smart-contracts/protocol-contracts/contract-deployments.md)


# Router

The Fira Router is a diamond-like proxy that delegates user calls to specialized action facets via selector-to-facet mappings.

The router is the single entry point for all user-facing protocol operations. It uses a diamond-like proxy pattern where each function selector maps to an action facet contract via `delegatecall`.

{% hint style="info" %}
Since all facets share storage via `delegatecall`, `RouterStorage` uses ERC-7201 storage namespacing to avoid collisions.
{% endhint %}

## FiraRouterV4

Extends OpenZeppelin's `Proxy` and overrides `_implementation()` to look up `CoreStorage.selectorToFacet[msg.sig]`. If no facet is registered, it reverts with `INVALID_SELECTOR`.

The constructor hard-wires the `setSelectorToFacets` and `selectorToFacet` selectors to the `ActionStorageV4` facet, allowing the owner to configure all other mappings post-deployment.

## Facet contracts

* [ActionBorrow](/developers/protocol-contracts/router/action-borrow) — Fixed-rate borrow and repay
* [ActionSwapBT](/developers/protocol-contracts/router/action-swap-bt) — BT swap operations
* [ActionSwapCT](/developers/protocol-contracts/router/action-swap-ct) — Synthesized CT swaps
* [ActionAddRemoveLiq](/developers/protocol-contracts/router/action-add-remove-liq) — Liquidity operations
* [ActionMisc](/developers/protocol-contracts/router/action-misc) — FW/BC minting, exits, multicall
* [ActionSimple](/developers/protocol-contracts/router/action-simple) — Gas-optimized on-chain approximation

## Shared base contracts

All facets inherit from `ActionBase`, which provides:

* FW mint/redeem orchestration
* BT/CT swap orchestration with limit order support
* Flash-callback encoding/decoding via `CallbackHelper`
* Delegation to `ActionSimple` when on-chain approximation suffices


# ActionSwapBT

ActionSwapBTV3 provides entry points for swapping tokens or FW to/from Bond Tokens via the Fira Market AMM.

{% hint style="info" %}
**Source:** `src/fira_bonding/router/ActionSwapBTV3.sol`
{% endhint %}

## Functions

* **`swapExactTokenForBt`** — User token → FW (mint) → FW sent to market → swap for BT
* **`swapExactFwForBt`** — FW → BT via market swap
* **`swapExactBtForToken`** — BT → FW (market swap) → redeem to user token
* **`swapExactBtForFw`** — BT → FW via market swap

## Swap amount calculation

The FW→BT direction uses `MarketApproxBtOutLibV2.approxSwapExactFwForBtV2` with binary search and an off-chain hint (`guessOffchain`). This is needed because the market only supports exact-output BT swaps (`swapFwForExactBt`), so the approximation library finds the BT amount that uses exactly the available FW.

## On-chain fallback

If `guessOffchain == 0` and no limit orders are present, the facet delegates to `ActionSimple` which uses `MarketApproxLibOnchain` for a closed-form approximation instead.


# ActionSwapCT

ActionSwapCTV3 synthesizes CT swaps through the BT/FW AMM using a flash-callback pattern with BT+CT minting/redeeming.

{% hint style="info" %}
**Source:** `src/fira_bonding/router/ActionSwapCTV3.sol`
{% endhint %}

## Overview

CT is not directly traded in the AMM — the pool only has BT and FW. CT swaps are synthesized:

### Buy CT (FW → CT)

Send FW to CT contract → mint BT+CT → sell BT back to market for FW → net output is CT. The callback mechanism handles this atomically: the market sends FW to the router first (flash-loan style), the router mints BT+CT using that FW to repay the BT debt.

### Sell CT (CT → FW)

Buy BT from the market using FW → pair with user's CT → redeem BT+CT for FW → net output is FW minus the BT cost.

## Functions

* **`swapExactTokenForCt`** — User token → FW → CT (via synthesis)
* **`swapExactFwForCt`** — FW → CT
* **`swapExactCtForToken`** — CT → FW → user token
* **`swapExactCtForFw`** — CT → FW

## Callback handling

The flash-style swaps use `ActionCallbackV3` to handle the market's callback. The callback data encodes the action type and parameters, and the callback contract performs the BT+CT minting or redemption needed to settle the flash swap.


# ActionAddRemoveLiq

ActionAddRemoveLiqV3 supports 10 liquidity operation variants — dual-sided, single-sided, and keep-CT strategies for providing and removing liquidity.

{% hint style="info" %}
**Source:** `src/fira_bonding/router/ActionAddRemoveLiqV3.sol`
{% endhint %}

## Add liquidity variants

| Function                        | Input      | Strategy                                    |
| ------------------------------- | ---------- | ------------------------------------------- |
| `addLiquidityDualTokenAndBt`    | Token + BT | Mint FW from token, add with BT             |
| `addLiquidityDualFwAndBt`       | FW + BT    | Direct dual-sided add                       |
| `addLiquiditySingleToken`       | Token only | Mint FW, swap portion to BT, add both       |
| `addLiquiditySingleBt`          | BT only    | Swap portion to FW, add both                |
| `addLiquiditySingleFw`          | FW only    | Swap portion to BT, add both                |
| `addLiquiditySingleTokenKeepCt` | Token only | Mint FW, mint BT+CT, use BT for LP, keep CT |
| `addLiquiditySingleFwKeepCt`    | FW only    | Same keep-CT strategy                       |

### Keep-CT strategy

Instead of swapping FW to BT, the router mints BT+CT from FW. BT goes to the market for liquidity, CT goes to the user. This way the user gets LP exposure plus floating yield from CT simultaneously.

## Remove liquidity variants

| Function                        | Output                                                     |
| ------------------------------- | ---------------------------------------------------------- |
| `removeLiquidityDualFwAndBt`    | FW + BT separately                                         |
| `removeLiquidityDualTokenAndBt` | Token (from FW redeem) + BT                                |
| `removeLiquiditySingleBt`       | BT only (FW swapped to BT)                                 |
| `removeLiquiditySingleFw`       | FW only (BT swapped to FW, or redeemed via CT post-expiry) |
| `removeLiquiditySingleToken`    | Token (everything converted)                               |

### Post-expiry removal

Since the market doesn't allow swaps post-expiry, single-FW removal sends BT to the CT contract and redeems via `CT.redeemBC()`.

## Core mechanics

All add operations ultimately call `FiraMarket.mint(receiver, netFwUsed, netBtUsed)`. Single-sided adds use approximation libraries to calculate how much to swap before depositing both sides. All remove operations call `FiraMarket.burn`.


# ActionBorrow

ActionBorrow integrates with the lending market for fixed-rate borrowing and repayment in a single transaction.

{% hint style="info" %}
**Source:** `src/fira_bonding/router/ActionBorrow.sol`
{% endhint %}

## Functions

### `supplyAndBorrowSingleToken`

Supply collateral → borrow BT → swap BT to FW → redeem FW to desired token. All in one transaction.

### `borrowSingleToken`

Same flow but assumes collateral is already supplied.

### `repay`

Converts input token to BT and repays the lending market:

* **Pre-expiry:** Input token → FW (mint) → BT (AMM swap) → repay. Refunds excess BT.
* **Post-expiry:** Input token → FW (mint) → BT+CT (via `CT.mintBC`) → repay with BT. CT is minted but has zero value post-expiry.

## Key details

* The borrow position is owned by `msg.sender`, but the router is the token receiver — BT is held transiently and swapped immediately.
* `tokensToRepay` must be ≤ current debt, otherwise reverts with `"AB: repay too much"`.
* Requires the user to have authorized the router on the LendingMarket (`setAuthorization(router, true)`).


# ActionSimple

ActionSimple provides gas-optimized swap and liquidity functions using on-chain approximation instead of off-chain hints.

{% hint style="info" %}
**Source:** `src/fira_bonding/router/ActionSimple.sol`
{% endhint %}

## Overview

A parallel set of swap and liquidity functions that use `MarketApproxLibOnchain` instead of the off-chain binary search approximation. These are called internally by the main action facets when `guessOffchain == 0` and no limit orders are present.

## When it's used

The main facets (ActionSwapBTV3, ActionSwapCTV3, etc.) check `canUseOnchainApproximation()` in `ActionDelegateBase`. If true, they delegate to `ActionSimple` via `address(this).delegatecall(...)`, which runs ActionSimple's code in the router's storage context.

## Functions

* `swapExactFwForBtSimple` — FW → BT using on-chain closed-form approximation
* `swapExactTokenForBtSimple` — Token → FW → BT
* `swapExactTokenForCtSimple` / `swapExactCtForTokenSimple` — CT swaps
* `addLiquiditySingleBtSimple` / `addLiquiditySingleFwSimple` — Single-sided LP
* `addLiquiditySingleTokenSimple` / `addLiquiditySingleTokenKeepCtSimple` — Token-based LP

## Trade-offs

On-chain approximation provides a simpler code path with lower gas cost for straightforward operations, at the expense of slightly less precise swap amounts compared to the off-chain binary search method.


# ActionMisc

ActionMiscV3 handles FW and BT+CT minting/redemption, position exits, multicall batching, and transaction simulation.

{% hint style="info" %}
**Source:** `src/fira_bonding/router/ActionMiscV3.sol`
{% endhint %}

## Functions

### BT+CT lifecycle

* **`mintBcFromToken` / `mintBcFromFw`** — Convert tokens or FW into equal BT + CT
* **`redeemBcToToken` / `redeemBcToFw`** — Recombine BT + CT back to tokens or FW

### Position exits

* **`exitPreExpToToken` / `exitPreExpToFw`** — Exit all positions (LP + BT + CT) pre-expiry. First matches BT with CT for direct redemption (cheapest path), then swaps any remaining unmatched tokens via the AMM.
* **`exitPostExpToToken` / `exitPostExpToFw`** — Post-expiry exit. Burns LP, sends BT to CT contract, redeems via `CT.redeemBC()`. CT is not burned post-expiry.

### Utility

* **`multicall`** — Batches multiple router calls via `delegatecall` to self. Each sub-call can be marked `allowFailure`.
* **`simulate`** — Executes a call and reverts with the result bytes. Used by off-chain code to preview transaction outcomes without sending a real transaction.

### Rewards

* **`redeemDueInterestAndRewardsV2`** — Collects interest from CT + rewards from FW + rewards from markets, optionally swapping reward tokens via an aggregator.


# Yield Contracts

Yield contracts split FW into a fixed-rate principal token (BT) and a floating-yield token (CT), minted and redeemed at the BC index rate.

Yield contracts are the mechanism by which FW is split into its fixed-rate and floating-rate components. BT/CT pairs are minted 1:1 at the BC index rate and can be recombined to recover FW until (and after) expiry.

## Contracts

* [BondToken](/developers/protocol-contracts/yield-contracts/bond-token) — Fixed-rate principal claim, mintable/burnable by CT and LiquidityInjector
* [CouponToken](/developers/protocol-contracts/yield-contracts/coupon-token) — Floating-yield leg with interest tracking and post-expiry handling
* [YieldContractFactory](/developers/protocol-contracts/yield-contracts/yield-contract-factory) — Creates BT/CT pairs per FW + expiry


# Bond Token

BondToken is the fixed-rate principal token — intentionally minimal, with strict access control limiting minting to CT and the LiquidityInjector.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/YieldContracts/BondToken.sol`
{% endhint %}

## Contract summary

BondToken is intentionally minimal. It stores immutable references to FW, factory, and expiry. The CT address is set once during `initialize()`, and the LiquidityInjector address is stored as a configurable variable.

## Access control

* **`mintByCT` / `burnByCT`** — Only the paired CouponToken can call these
* **`mintByLI` / `burnByLI`** — Only the LiquidityInjector can call these
* No other address can mint or burn BT

This strict access prevents principal inflation outside the yield-split lifecycle.

## Expiry

`isExpired()` delegates to `MiniHelpers.isCurrentlyExpired`. BT has no post-expiry logic itself — all post-expiry behavior lives in the CouponToken contract.

## Inherited contracts

* `FiraERC20` — ERC-20 with reentrancy guard


# Coupon Token

CouponToken is the stateful contract driving the BT/CT lifecycle — minting, redemption, interest accounting, and post-expiry behavior.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/YieldContracts/CouponToken.sol`, `src/fira_bonding/core/YieldContracts/InterestManagerCT.sol`
{% endhint %}

## Contract summary

CT extends `InterestManagerCT` and `FiraERC20`. Like BT, the FW, BT, factory, expiry, and `doCacheIndexSameBlock` fields are all immutable. All external mutating functions use `nonReentrant`.

## Minting BT+CT

`mintBC(receiverBT, receiverCT)` takes FW that has been pre-transferred to the CT contract, converts the FW amount to underlying asset units via the BC index, and mints equal BT and CT. The BC index is `max(FW.exchangeRate(), storedIndex)` — monotonically non-decreasing.

`mintBCMulti` does the same for multiple receivers in one call.

## Redeeming BT+CT

`redeemBC(receiver)` burns BT from `address(this)` (must be pre-transferred) and burns CT if not expired. FW is returned based on the current BC index.

**Post-expiry:** The redeemable FW amount is calculated at the *current* BC index, but the excess between the post-expiry first index and the current index accrues as treasury interest. Post-expiry yield goes to the protocol, not to redeemers.

## Interest accounting

`InterestManagerCT` tracks per-user interest via `UserInterest { index, accrued }`. On every CT transfer (`_beforeTokenTransfer`), interest is distributed to both sender and receiver:

```
interest = principal × (currentIndex - prevIndex) / (prevIndex × currentIndex)
```

Claims go through `_doTransferOutInterest`, which deducts `interestFeeRate` and sends the fee to treasury.

### Key design decisions

* Interest is based on CT balance, not FW balance
* Protocol fees are taken at claim time, not at accrual time
* `_distributeInterestForTwo` skips `address(0)` and `address(this)` to avoid phantom accounting

## BC index caching

If `doCacheIndexSameBlock` is true, the BC index is only updated once per block. This prevents sandwich attacks where the FW exchange rate is manipulated within a block to extract value from CT holders.

## Post-expiry state

`_setPostExpiryData()` is called on the first interaction after expiry. It snapshots the BC index and reward indices. After this, the interest index is frozen to `postExpiry.firstBCIndex`, and all subsequent yield flows to treasury.

`redeemInterestAndRewardsPostExpiryForTreasury()` sweeps all post-expiry interest to the treasury.

## Inherited contracts

* `InterestManagerCT` — Per-user interest tracking
* `FiraERC20` — ERC-20 with reentrancy guard


# YieldContractFactory

YieldContractFactory creates BT/CT pairs for a given FW and expiry, using split-code deployment for CT.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/YieldContracts/YieldContractFactory.sol`
{% endhint %}

## Contract summary

Creates BT/CT pairs for a given FW and expiry. BT is deployed with `Create2`, CT with the split-code factory pattern (because CT bytecode exceeds 24KB).

## Validations

* Expiry must be in the future and divisible by `expiryDivisor`
* Duplicate FW+expiry pairs revert

## Storage

After deployment, the factory stores lookup mappings:

* `getBT[FW][expiry]` / `getCT[FW][expiry]` — Address discovery
* `isBT[addr]` / `isCT[addr]` — Validation

## Fee configuration

* `interestFeeRate` and `rewardFeeRate` (max 20% each)
* `treasury` address for fee collection
* `liquidityInjector` address, propagated to BT on creation

## Initialization

After deployment, BT is initialized with the CT address, establishing the one-to-one pairing.


# Rehypothecation Module

RehypothecationModule defines the idle/vault ratio parameters that control how FW tokens balance reserves and yield deployment.

{% hint style="info" %}
**Source:** `src/fira_bonding/RehypothecationModule.sol`
{% endhint %}

## Contract summary

A configuration contract that stores three parameters (in basis points) controlling the FW idle ratio:

| Parameter   | Purpose                                                    |
| ----------- | ---------------------------------------------------------- |
| `phiMin`    | Minimum idle ratio — triggers vault withdrawal if breached |
| `phiMax`    | Maximum idle ratio — triggers vault deposit if breached    |
| `phiTarget` | Target idle ratio — used by `forceRehypothecation()`       |

## How it's used

FW tokens reference this module when `triggerRehypothecation()` or `forceRehypothecation()` is called. The FW contract reads `phiMin`, `phiMax`, and `phiTarget` from the module and rebalances accordingly.

The module is set on the FW token by the owner. Setting it to `address(0)` disables rehypothecation entirely.

## Related pages

* [Rehypothecation (Feature)](/developers/features/rehypothecation)
* [FW Tokens](/developers/token-contracts/fw-tokens)


# Liquidity Injector

LiquidityInjector mints unbacked BT to bootstrap fixed-rate lending markets with initial loan token supply.

{% hint style="info" %}
**Source:** `src/liquidityInjector/LiquidityInjector.sol`
{% endhint %}

## Contract summary

The LiquidityInjector has a special privilege to call `BondToken.mintByLI()` to create BT without backing FW. This is the only way BT can be minted outside the normal FW→BT+CT yield-split path.

## Functions

### `injectLiquidity(params, amount)`

1. Validates `params.irm == address(0)` (fixed-rate market identifier)
2. Calls `BondToken.mintByLI(address(this), amount)` to create BT
3. Approves and supplies BT to the lending market via `lendingMarket.supply()`
4. Increments `marketStats[marketId]`

### `withdrawLiquidity(params, amount)`

1. Checks available liquidity (total supply − total borrows, capped by balance)
2. Withdraws BT from the lending market
3. Burns BT via `BondToken.burnByLI()`
4. Decrements `marketStats[marketId]`

## Invariants

* Owner-only for inject and withdraw
* BT is never held in a resting state — always in the lending market or burned
* `marketStats` tracks net injected amount per market
* Available liquidity check prevents disrupting existing borrows


# Token Contracts

Token contracts define the ERC-20 tokens used throughout the Fira protocol, including FW wrappers, BT, CT, and the custom FiraERC20 base.

* [FW Tokens](/developers/token-contracts/fw-tokens) — FW base contracts and USDCFW implementation
* [BondToken](/developers/token-contracts/bond-token) — BT token contract
* [CouponToken](/developers/token-contracts/coupon-token) — CT token contract
* [FiraERC20](/developers/token-contracts/fira-erc20) — Custom ERC-20 base with reentrancy guard and permit


# FiraERC20

FiraERC20 is the custom ERC-20 base used by every token in the protocol, providing a built-in reentrancy guard and transfer hooks.

{% hint style="info" %}
**Source:** `src/fira_bonding/erc20/FiraERC20.sol`, `FiraERC20Permit.sol`, `FiraERC20Upg.sol`, `FiraERC20PermitUpg.sol`
{% endhint %}

## Variants

| Contract             | Permit   | Upgradeable         | Used by             |
| -------------------- | -------- | ------------------- | ------------------- |
| `FiraERC20`          | No       | No                  | BT, FiraMarket (LP) |
| `FiraERC20Permit`    | EIP-2612 | No                  | —                   |
| `FiraERC20Upg`       | No       | Yes (Initializable) | —                   |
| `FiraERC20PermitUpg` | EIP-2612 | Yes (Initializable) | FW tokens           |

## Reentrancy guard

A `_reentrancyStatus` slot flips between `_NOT_ENTERED` (1) and `_ENTERED` (2). The `nonReentrant` modifier is available to all contracts that inherit `FiraERC20`. This means `FiraMarket` (which extends `FiraERC20` as its LP token) gets reentrancy protection without extra inheritance.

## Transfer hooks

* `_beforeTokenTransfer` — Virtual, overridden by CT (distributes interest) and FW (enforces pause)
* `_afterTokenTransfer` — Virtual, available for derived contracts

## Permit (EIP-2612)

`FiraERC20Permit` adds gasless approvals via `permit(owner, spender, value, deadline, v, r, s)`. Uses EIP-712 typed data for domain separation. The `DOMAIN_SEPARATOR` is computed at construction time and cached.

## Design decisions

* No `receive` or `fallback` — only contracts that need ETH (FWBase, Router) add `receive()`
* Storage layout matches between upgradeable and non-upgradeable variants


# Bond Token

BondToken (BT) is the fixed-rate principal ERC-20 token with strict minting restricted to CouponToken and LiquidityInjector.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/YieldContracts/BondToken.sol`
{% endhint %}

## Token details

| Property | Value              |
| -------- | ------------------ |
| Standard | ERC-20 (FiraERC20) |
| Symbol   | BT                 |
| Decimals | 6                  |
| Permit   | No                 |

## Minting and burning

* `mintByCT(receiver, amount)` — Only callable by the paired CouponToken
* `burnByCT(user, amount)` — Only callable by the paired CouponToken
* `mintByLI(receiver, amount)` — Only callable by the LiquidityInjector
* `burnByLI(amount)` — Only callable by the LiquidityInjector

No other address can create or destroy BT.

## Immutable references

* `FW` — The Fira Wrapped token address
* `factory` — The YieldContractFactory that created this BT
* `expiry` — Unix timestamp when BT matures

## Related pages

* [BondToken (Protocol Contract)](/developers/protocol-contracts/yield-contracts/bond-token)
* [Bond Token (Feature)](/developers/features/bond-token-bt)


# Coupon Token

CouponToken (CT) is the floating-yield ERC-20 token with built-in interest tracking and post-expiry treasury sweep.

{% hint style="info" %}
**Source:** `src/fira_bonding/core/YieldContracts/CouponToken.sol`
{% endhint %}

## Token details

| Property | Value              |
| -------- | ------------------ |
| Standard | ERC-20 (FiraERC20) |
| Symbol   | CT                 |
| Decimals | 6                  |
| Permit   | No                 |

## Key view functions

| Function              | Returns                                          |
| --------------------- | ------------------------------------------------ |
| `bcIndexStored()`     | Last cached BC index                             |
| `bcIndexCurrent()`    | Current BC index (may trigger update)            |
| `isExpired()`         | Whether BT/CT have expired                       |
| `FW()`                | Associated FW token address                      |
| `BT()`                | Associated BT token address                      |
| `getPostExpiryData()` | Snapshot data from first post-expiry interaction |

## Interest tracking

Interest is distributed on every transfer via `_beforeTokenTransfer`. Users claim via `redeemDueInterestAndRewards`. The `interestFeeRate` is deducted at claim time.

## Related pages

* [CouponToken (Protocol Contract)](/developers/protocol-contracts/yield-contracts/coupon-token)
* [Coupon Token (Feature)](/developers/features/coupon-token-ct)


# FW Tokens

FW token base contracts and the USDCFW implementation that wraps USDC through an ERC-4626 vault for yield generation.

{% hint style="info" %}
**Source:** `src/fira_bonding/StandardizedYield/FWBase.sol`, `src/fira_bonding/StandardizedYield/implementations/USDCFW.sol`
{% endhint %}

## FWBase

Abstract base that all FW tokens inherit. Extends `FiraERC20Permit`, `TokenHelper`, `BoringOwnableUpgradeable`, and `Pausable`.

### Deposit flow

1. Validate input token via `isValidTokenIn`
2. Transfer tokens in via `_transferIn`
3. Call `_deposit(tokenIn, amount)` — abstract, implemented by derived contracts
4. Mint FW shares to receiver
5. Check `minSharesOut` slippage guard

### Redeem flow

1. Validate output token via `isValidTokenOut`
2. Burn FW shares (or from `address(this)` if `burnFromInternalBalance`)
3. Call `_redeem(receiver, tokenOut, shares)` — abstract
4. Check `minTokenOut` slippage guard

### Pause controls

Three independent mechanisms: `depositsPaused`, `redemptionsPaused`, and global `pause()` (blocks all transfers).

## USDCFW

The production FW implementation. Wraps USDC and earns yield by deploying a portion into an ERC-4626 vault.

### State

* `yieldToken` — USDC address (immutable)
* `vault` — ERC-4626 vault (immutable)
* `idleAssets` / `vaultShares` — Tracked explicitly to prevent donation-based manipulation

### Exchange rate

```
exchangeRate = totalUnderlying / totalSupply
```

Where `totalUnderlying = idleAssets + vault.convertToAssets(vaultShares)`.

### Deposit

USDC deposits are added to `idleAssets`. Vault share deposits are converted to equivalent USDC. First deposit mints 1:1. The market is seeded on deployment to prevent ERC-4626 inflation attacks.

### Redeem

Draws from idle USDC first, then from the vault if needed, minimizing gas costs.

### Rehypothecation

`triggerRehypothecation()` (permissionless) and `forceRehypothecation()` (owner-only) rebalance between idle and vault based on the RehypothecationModule parameters.


# Utility Contracts

Utility contracts include the oracle infrastructure for pricing BT, CT, and LP tokens, and the shared math and helper libraries.

* [Oracles](/developers/utility-contracts/oracles) — TWAP pricing for BT, CT, LP tokens and solvency checks
* [Libraries](/developers/utility-contracts/libraries) — Math, token helpers, error definitions, and deployment utilities


# Oracles

Oracle contracts provide manipulation-resistant TWAP pricing for BT, CT, and LP tokens, consumed by lending markets and external integrators.

* [BC Oracle](/developers/utility-contracts/oracles/bc-oracle) — TWAP pricing for BT and CT tokens
* [LP Oracle](/developers/utility-contracts/oracles/lp-oracle) — LP token pricing via hypothetical rebalancing
* [Solvency Oracle](/developers/utility-contracts/oracles/solvency-oracle) — FW solvency-adjusted pricing for lending markets


# Solvency Oracle

FiraSolvencyOracle is the top layer of the fixed-rate lending oracle pipeline, providing collateral pricing to the FiraLendingMarket.

{% hint style="info" %}
**Source:** `src/fira_bonding/oracles/FiraSolvencyOracle.sol`
{% endhint %}

## Overview

The FiraSolvencyOracle provides collateral-to-loan-token pricing for fixed-rate lending markets. It sits at the top of a 3-layer oracle pipeline:

```
AaveToChainlinkAdapter → ChainlinkOracleV2 → FiraSolvencyOracle → FiraLendingMarket
```

## Oracle pipeline

| Layer                      | Purpose                                                            |
| -------------------------- | ------------------------------------------------------------------ |
| **AaveToChainlinkAdapter** | Adapts Aave/Pendle price feeds to a Chainlink-compatible interface |
| **ChainlinkOracleV2**      | Combines two Chainlink feeds to produce a collateral/USDC price    |
| **FiraSolvencyOracle**     | Adjusts the price for BT solvency and provides to lending market   |

## Deployed instances

| Market      | FiraSolvencyOracle                                                                         |
| ----------- | ------------------------------------------------------------------------------------------ |
| PT-USDe/BT  | [`0xeB30b33A...`](https://etherscan.io/address/0xeB30b33A1aC175e0305853636D0eF3898eb530f3) |
| PT-sUSDe/BT | [`0xB9bAA3D5...`](https://etherscan.io/address/0xB9bAA3D58E1431776218F39919fd21AeD3e69aBb) |
| PT-USDG/BT  | [`0x90d0d6fd...`](https://etherscan.io/address/0x90d0d6fdf9fe93777085e8b4baf3aab4285bac6b) |

## Related pages

* [Contract Deployments](/developers/deployment) — Full oracle pipeline addresses


# LP Oracle

LpOracleLib computes TWAP-based LP token prices by simulating a hypothetical rebalancing trade at the oracle-implied rate.

{% hint style="info" %}
**Source:** `src/fira_bonding/oracles/LpOracleLib.sol`
{% endhint %}

## Overview

LP token pricing is more complex than BT/CT because LP represents a share of a pool with two assets (BT + FW) in varying proportions.

## Pricing method

The library simulates a hypothetical rebalancing trade:

1. Compute the market's current `rateScalar` and `rateAnchor`
2. Compute `cParam = exp(rateScalar × (rateOracle - rateAnchor))` — where the pool "should" be according to the oracle
3. Calculate the hypothetical trade size to move the pool to the oracle-implied proportion
4. Sum total asset value after the trade: FW reserves (in asset terms) plus BT reserves, adjusted by post-trade rates
5. Divide by total LP supply

The hypothetical trade rate is the average of the oracle TWAP rate and the last trade rate, dampening the impact of stale oracle data.

### Post-expiry

LP pricing simplifies: 1 BT = 1 asset, so `LP value = (totalBt + fwToAsset(totalFw)) / totalLp`.


# BC Oracle

BCOracleLib computes TWAP-based prices for Bond Tokens and Coupon Tokens from the FiraMarket's implied rate observations.

{% hint style="info" %}
**Source:** `src/fira_bonding/oracles/BCOracleLib.sol`, `src/fira_bonding/oracles/BCLpOracle.sol`
{% endhint %}

## BCOracleLib

### BT pricing

Pre-expiry, BT price is derived from the TWAP `ln(impliedRate)`:

```
btToAssetRate = 1 / exp(lnImpliedRate × timeToExpiry / YEAR)
```

This is the present value of 1 unit of underlying, discounted at the TWAP implied rate. Post-expiry, BT is worth exactly 1 asset unit.

### CT pricing

CT value is `1 - btToAssetRate`. Since BT + CT = 1 asset unit by construction, CT captures the remainder.

### FW solvency adjustment

If the FW exchange rate drops below the BC index, the FW wrapper is insolvent. In this case, BT and CT rates are scaled down by `fwIndex / bcIndex`, preventing the oracle from reporting prices that assume full solvency.

### TWAP calculation

`getMarketLnImpliedRate(market, duration)` queries two cumulative observations, takes the difference, and divides by duration for a manipulation-resistant time-weighted average.

## BCLpOracle

A convenience contract wrapping both `BCOracleLib` and `LpOracleLib` as external view functions. Deployed once per chain to save bytecode in contracts that need oracle prices.

Provides `getOracleState(market, duration)` to check whether a market has enough observation cardinality for the requested TWAP window and whether the oldest observation is old enough.


# Libraries

Shared utility and math libraries used across the Fira protocol for arithmetic, token transfers, error handling, and deployment patterns.

* [Math](/developers/utility-contracts/libraries/math) — Fixed-point arithmetic (PMath) and logarithm/exponentiation (LogExpMath)
* [Helpers](/developers/utility-contracts/libraries/helpers) — Token transfers, error definitions, ownership, and deployment utilities


# Math

Fixed-point arithmetic libraries operating at 1e18 scale — the arithmetic backbone of the Fira protocol.

{% hint style="info" %}
**Source:** `src/fira_bonding/libraries/math/PMath.sol`, `src/fira_bonding/libraries/math/LogExpMath.sol`
{% endhint %}

## PMath

Core fixed-point math used throughout the protocol. Constants: `ONE = 1e18`, `IONE = int256(1e18)`.

### Key operations

| Function                | Description                           | Rounding                            |
| ----------------------- | ------------------------------------- | ----------------------------------- |
| `mulDown(a, b)`         | `(a × b) / 1e18`                      | Toward zero (conservative for user) |
| `divDown(a, b)`         | `(a × 1e18) / b`                      | Toward zero                         |
| `rawDivUp(a, b)`        | `(a + b - 1) / b`                     | Up (conservative for protocol)      |
| `abs(a)`                | Absolute value of int256              | —                                   |
| `neg(a)`                | Negation (BT/FW flows are signed)     | —                                   |
| `subNoNeg(a, b)`        | `a - b`, reverts if negative          | —                                   |
| `sqrt(x)`               | Babylonian method integer square root | —                                   |
| `Int()` / `Uint()`      | Safe int256 ↔ uint256 casting         | —                                   |
| `Int128()` / `Uint96()` | Narrowing casts for storage packing   | —                                   |

## LogExpMath

Ported from Balancer's math library. Implements `ln(x)` and `exp(x)` for signed 256-bit integers at 1e18 scale.

### Usage in the protocol

* **`exp(x)`** — Converts between implied rates and exchange rates: `exchangeRate = exp(lnImpliedRate × timeToExpiry / YEAR)`
* **`ln(x)`** — After computing a post-trade exchange rate, converts back to log-space implied rate for storage and TWAP tracking

Both functions use lookup tables and polynomial approximations. They revert on out-of-bounds inputs (e.g., `ln(0)` or overflow in `exp`). Precision is critical — rounding errors in `exp` compound over many trades and could allow arbitrage.


# Helpers

Helper libraries for token transfers, error definitions, ownership patterns, and the split-code deployment factory for contracts exceeding the 24KB limit.

{% hint style="info" %}
**Source:** `src/fira_bonding/libraries/`
{% endhint %}

## Errors.sol

Central registry of all custom error types. Errors are prefixed by module (`Market*`, `YC*`, `FW*`, `Router*`). Using custom errors instead of string reverts saves gas and makes off-chain decoding straightforward.

## TokenHelper.sol

Safe ERC20 transfer wrappers with native ETH handling:

* `_transferIn(token, from, amount)` — Handles ETH by checking `msg.value` and wrapping via WETH
* `_transferOut(token, to, amount)` — Handles ETH by unwrapping WETH
* `_selfBalance(token)` — Balance accounting for native ETH
* `_safeApproveInf(token, spender)` — Infinite approval only if current allowance is low

The `NATIVE` sentinel address (`0x000...000`) represents ETH in `TokenInput`/`TokenOutput` structs.

## BoringOwnableUpgradeable.sol

Two-step ownership transfer: `transferOwnership(newOwner, direct, renounce)` either transfers immediately or sets a pending owner who must call `claimOwnership()`. Used by FW tokens and factories.

## BaseSplitCodeFactory / CodeDeployer

Works around the 24KB EVM contract size limit (EIP-170):

1. At factory deployment, creation bytecode is split into two chunks, each deployed as a "code storage" contract
2. At creation time, bytecode is concatenated in memory and deployed via CREATE2

Used by both `FiraMarketFactory` and `YieldContractFactory` since `FiraMarket` and `CouponToken` exceed the size limit.

## Other helpers

* **`MiniHelpers.sol`** — `isCurrentlyExpired(expiry)`, `ensureNotExpired()` — used everywhere for pre/post-expiry gating
* **`ExpiryUtilsLib.sol` / `StringLib.sol`** — Generate deterministic token names like `FW-USDC-BT-07MAY2026` from symbols and expiry timestamps
* **`ArrayLib.sol`** — `create(a, b)` returns a 2-element `address[]`; `sum(arr)` sums a `uint256[]`


# Contract Deployments

Mainnet contract addresses, market configurations, oracle pipelines, router facets, and key roles for the Fira Protocol deployment.

**Network:** Ethereum Mainnet\
**Initial Deployment:** March 13–15, 2026\
**Bond Token Expiries:** May 7, 2026 · May 27, 2026

***

## External tokens

| Token                    | Symbol    | Decimals | Address                                                                                                                 |
| ------------------------ | --------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| USDC                     | USDC      | 6        | [`0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`](https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48) |
| Wrapped stETH            | wstETH    | 18       | [`0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0`](https://etherscan.io/address/0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0) |
| Coinbase Wrapped BTC     | cbBTC     | 8        | [`0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf`](https://etherscan.io/address/0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf) |
| PT Ethena USDe 7MAY2026  | PT-USDe   | 18       | [`0xAeBf0Bb9f57E89260d57f31AF34eB58657d96Ce0`](https://etherscan.io/address/0xAeBf0Bb9f57E89260d57f31AF34eB58657d96Ce0) |
| PT Ethena sUSDe 7MAY2026 | PT-sUSDe  | 18       | [`0x3de0ff76E8b528C092d47b9DaC775931cef80F49`](https://etherscan.io/address/0x3de0ff76E8b528C092d47b9DaC775931cef80F49) |
| PT Paxos USDG 27MAY2026  | PT-USDG   | 18       | [`0x9db38D74a0D29380899aD354121DfB521aDb0548`](https://etherscan.io/address/0x9db38D74a0D29380899aD354121DfB521aDb0548) |
| PT Apyx apxUSD 18JUN2026 | PT-apxUSD | 18       | [`0x92a6a01b07984de46c24e8eba248449beb8b1dcb`](https://etherscan.io/address/0x92a6a01b07984de46c24e8eba248449beb8b1dcb) |

## Fira tokens

| Token                         | Symbol  | Decimals | Address                                                                                                                 |
| ----------------------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| Fira Wrapped USDC             | FW-USDC | 18       | [`0x62F5366C9E21A95326C461a098a408e034e017b3`](https://etherscan.io/address/0x62F5366C9E21A95326C461a098a408e034e017b3) |
| Bond Token                    | BT      | 6        | [`0x57FFbb88f0c69283531a751BE6FF0741348371bA`](https://etherscan.io/address/0x57FFbb88f0c69283531a751BE6FF0741348371bA) |
| Coupon Token                  | CT      | 6        | [`0x93635d34fAd5A9fA7065a645691100b2E23C93cd`](https://etherscan.io/address/0x93635d34fAd5A9fA7065a645691100b2E23C93cd) |
| Markov USDC Prime (SisuVault) | mkUSDC  | 18       | [`0x50791a5cA041b9D6Dd03e64E3Fa0e34a376759AC`](https://etherscan.io/address/0x50791a5cA041b9D6Dd03e64E3Fa0e34a376759AC) |

### May 27, 2026 Expiry

| Token                | Symbol | Decimals | Address                                                                                                                 |
| -------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| Bond Token (27MAY)   | BT     | 6        | [`0x88dd7069cb9d8b7cc6eebd23b82ed1e9a75d9734`](https://etherscan.io/address/0x88dd7069cb9d8b7cc6eebd23b82ed1e9a75d9734) |
| Coupon Token (27MAY) | CT     | 6        | [`0x17eA07Eb87bf7B091070999a0D313556D4ac580B`](https://etherscan.io/address/0x17eA07Eb87bf7B091070999a0D313556D4ac580B) |

### June 18, 2026 Expiry

| Token                | Symbol | Decimals | Address                                                                                                                 |
| -------------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| Bond Token (18JUN)   | BT     | 6        | [`0x33fd40eD7744c961b61a086A87F83787bd9606eE`](https://etherscan.io/address/0x33fd40eD7744c961b61a086A87F83787bd9606eE) |
| Coupon Token (18JUN) | CT     | 6        | [`0x33b6bf0390A84fe0f27979f9B52d78bfE1c6156F`](https://etherscan.io/address/0x33b6bf0390A84fe0f27979f9B52d78bfE1c6156F) |

BT and CT are minted/burned in pairs via the YieldContractFactory. Multiple expiry series can coexist.

## Core protocol contracts

| Contract              | Address                                                                                                                 | Description                                     |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| FiraRouterV4          | [`0xFF615E63aAF2d1B1EE4AdFD34a5840747185d8A0`](https://etherscan.io/address/0xFF615E63aAF2d1B1EE4AdFD34a5840747185d8A0) | Main entry point for all user operations        |
| USDCFW (FW)           | [`0x62F5366C9E21A95326C461a098a408e034e017b3`](https://etherscan.io/address/0x62F5366C9E21A95326C461a098a408e034e017b3) | Wrapped Standardized Yield token for USDC       |
| SisuVault             | [`0x50791a5cA041b9D6Dd03e64E3Fa0e34a376759AC`](https://etherscan.io/address/0x50791a5cA041b9D6Dd03e64E3Fa0e34a376759AC) | ERC-4626 vault aggregating yield across markets |
| LiquidityInjector     | [`0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5`](https://etherscan.io/address/0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5) | Sole BT supplier to fixed-rate markets          |
| RehypothecationModule | [`0xad332515d9c82438BBa0e9FAA9486B52A33a7Ac8`](https://etherscan.io/address/0xad332515d9c82438BBa0e9FAA9486B52A33a7Ac8) | Controls phi ratios for rebalancing             |
| YieldContractFactory  | [`0xcdB83Abb9121c04589567A4106C3cFaf65DB68Be`](https://etherscan.io/address/0xcdB83Abb9121c04589567A4106C3cFaf65DB68Be) | Deploys BT/CT pairs                             |
| FiraMarketFactory     | [`0xBF1EfC2199ae9EE1B6f5060a45D4440157E49744`](https://etherscan.io/address/0xBF1EfC2199ae9EE1B6f5060a45D4440157E49744) | Deploys AMM markets                             |
| BCLpOracle            | [`0xfEAAEC9124FB007d7c44Ed704A08d24b264de921`](https://etherscan.io/address/0xfEAAEC9124FB007d7c44Ed704A08d24b264de921) | Oracle for BC/LP pricing                        |
| AdaptiveCurveIrm      | [`0x73C288826347af3718e6F09c2A24AaFDA77684cD`](https://etherscan.io/address/0x73C288826347af3718e6F09c2A24AaFDA77684cD) | Interest rate model for variable-rate markets   |
| FIRA Yield Treasury   | [`0x97fD565B913b439Ff16774Da152B1f71F05A82F1`](https://etherscan.io/address/0x97fD565B913b439Ff16774Da152B1f71F05A82F1) | Fee recipient                                   |

## Lending markets

| Contract              | Address                                                                                                                 | Description                                       |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| VariableLendingMarket | [`0xc8Db629192a96D6840e88a8451F17655880A2e4D`](https://etherscan.io/address/0xc8Db629192a96D6840e88a8451F17655880A2e4D) | Variable-rate lending (wstETH, cbBTC collateral)  |
| FiraLendingMarket     | [`0x280ddD897F39C33fEf1CbF863B386Cb9a8e53a0e`](https://etherscan.io/address/0x280ddD897F39C33fEf1CbF863B386Cb9a8e53a0e) | Fixed-rate lending (PT collateral, BT loan token) |

## AMM markets

### FiraMarket — May 7, 2026

| Field         | Value                                                                                                                   |
| ------------- | ----------------------------------------------------------------------------------------------------------------------- |
| FiraMarket    | [`0xde00b5edb255078dd42ee94fd97f473d1c9c055d`](https://etherscan.io/address/0xde00b5edb255078dd42ee94fd97f473d1c9c055d) |
| BT            | [`0x57FFbb88f0c69283531a751BE6FF0741348371bA`](https://etherscan.io/address/0x57FFbb88f0c69283531a751BE6FF0741348371bA) |
| FW            | [`0x62F5366C9E21A95326C461a098a408e034e017b3`](https://etherscan.io/address/0x62F5366C9E21A95326C461a098a408e034e017b3) |
| Expiry        | May 7, 2026 (`1778112000`)                                                                                              |
| scalarRoot    | `102406700000000000000`                                                                                                 |
| initialAnchor | `1008276800000000000`                                                                                                   |
| lnFeeRateRoot | `2996000000000000`                                                                                                      |

### FiraMarket — May 27, 2026

| Field      | Value                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------- |
| FiraMarket | [`0x7083cfc87e7f6ebb858cc39b72d9c7605d368729`](https://etherscan.io/address/0x7083cfc87e7f6ebb858cc39b72d9c7605d368729) |
| BT         | [`0x88dd7069cb9d8b7cc6eebd23b82ed1e9a75d9734`](https://etherscan.io/address/0x88dd7069cb9d8b7cc6eebd23b82ed1e9a75d9734) |
| FW         | [`0x62F5366C9E21A95326C461a098a408e034e017b3`](https://etherscan.io/address/0x62F5366C9E21A95326C461a098a408e034e017b3) |
| Expiry     | May 27, 2026                                                                                                            |

### FiraMarket — June 18, 2026

| Field      | Value                                                                                                                   |
| ---------- | ----------------------------------------------------------------------------------------------------------------------- |
| FiraMarket | [`0x400922e37d608620672dc1f1b7a25ecbaabb57f8`](https://etherscan.io/address/0x400922e37d608620672dc1f1b7a25ecbaabb57f8) |
| BT         | [`0x33fd40eD7744c961b61a086A87F83787bd9606eE`](https://etherscan.io/address/0x33fd40eD7744c961b61a086A87F83787bd9606eE) |
| FW         | [`0x62F5366C9E21A95326C461a098a408e034e017b3`](https://etherscan.io/address/0x62F5366C9E21A95326C461a098a408e034e017b3) |
| Expiry     | June 18, 2026                                                                                                           |

## Variable-rate markets

### wstETH / USDC

| Field            | Value                                                                                                                                        |
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Lending Market   | [`0xc8Db629192a96D6840e88a8451F17655880A2e4D`](https://etherscan.io/address/0xc8Db629192a96D6840e88a8451F17655880A2e4D)                      |
| Market ID        | `0xB3152AC00687CC9502B78AB452956F85CC89AC210DEEFDA5DBFF09F7F167B544`                                                                         |
| Loan Token       | USDC ([`0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`](https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48))               |
| Collateral Token | wstETH ([`0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0`](https://etherscan.io/address/0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0))             |
| Oracle           | [`0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2`](https://etherscan.io/address/0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2) (Morpho wstETH/USDC) |
| IRM              | [`0x73C288826347af3718e6F09c2A24AaFDA77684cD`](https://etherscan.io/address/0x73C288826347af3718e6F09c2A24AaFDA77684cD) (AdaptiveCurveIrm)   |
| LTV              | 87%                                                                                                                                          |
| LLTV             | 89%                                                                                                                                          |
| Whitelist        | None (permissionless)                                                                                                                        |

### cbBTC / USDC

| Field            | Value                                                                                                                                                  |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Lending Market   | [`0xc8Db629192a96D6840e88a8451F17655880A2e4D`](https://etherscan.io/address/0xc8Db629192a96D6840e88a8451F17655880A2e4D)                                |
| Market ID        | `0x39D3BDD30BF4BCF4A4D3547F2484ABE1E30A2DCD41ED83788B40E2720357AB76`                                                                                   |
| Loan Token       | USDC ([`0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`](https://etherscan.io/address/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48))                         |
| Collateral Token | cbBTC ([`0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf`](https://etherscan.io/address/0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf))                        |
| Oracle           | [`0x698253A24CC4926090f841B38D31d6342A00a82C`](https://etherscan.io/address/0x698253A24CC4926090f841B38D31d6342A00a82C) (ChainlinkOracleV2 cbBTC/USDC) |
| IRM              | [`0x73C288826347af3718e6F09c2A24AaFDA77684cD`](https://etherscan.io/address/0x73C288826347af3718e6F09c2A24AaFDA77684cD) (AdaptiveCurveIrm)             |
| LTV              | 88%                                                                                                                                                    |
| LLTV             | 90%                                                                                                                                                    |
| Whitelist        | None (permissionless)                                                                                                                                  |

## Fixed-rate markets

All fixed-rate markets use the FiraLendingMarket at [`0x280ddD897F39C33fEf1CbF863B386Cb9a8e53a0e`](https://etherscan.io/address/0x280ddD897F39C33fEf1CbF863B386Cb9a8e53a0e). BT is the loan token. Only the LiquidityInjector can supply BT (whitelist-gated).

### PT-USDG / BT (May 27 Expiry)

| Field                 | Value                                                                                                                                        |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Loan Token            | BT 27MAY ([`0x88dd7069cb9d8b7cc6eebd23b82ed1e9a75d9734`](https://etherscan.io/address/0x88dd7069cb9d8b7cc6eebd23b82ed1e9a75d9734))           |
| Collateral Token      | PT-USDG ([`0x9db38D74a0D29380899aD354121DfB521aDb0548`](https://etherscan.io/address/0x9db38D74a0D29380899aD354121DfB521aDb0548))            |
| Oracle                | [`0x90d0d6fdf9fe93777085e8b4baf3aab4285bac6b`](https://etherscan.io/address/0x90d0d6fdf9fe93777085e8b4baf3aab4285bac6b) (FiraSolvencyOracle) |
| IRM                   | `0x0000000000000000000000000000000000000000` (none — fixed rate)                                                                             |
| LTV                   | 94%                                                                                                                                          |
| LLTV                  | 94.75%                                                                                                                                       |
| Whitelist             | [`0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5`](https://etherscan.io/address/0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5) (LiquidityInjector)  |
| Maturity Grace Period | 86400 (24h)                                                                                                                                  |
| Liquidation Incentive | 1%                                                                                                                                           |

### PT-USDe / BT

| Field                 | Value                                                                                                                                        |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Loan Token            | BT ([`0x57FFbb88f0c69283531a751BE6FF0741348371bA`](https://etherscan.io/address/0x57FFbb88f0c69283531a751BE6FF0741348371bA))                 |
| Collateral Token      | PT-USDe ([`0xAeBf0Bb9f57E89260d57f31AF34eB58657d96Ce0`](https://etherscan.io/address/0xAeBf0Bb9f57E89260d57f31AF34eB58657d96Ce0))            |
| Oracle                | [`0xeB30b33A1aC175e0305853636D0eF3898eb530f3`](https://etherscan.io/address/0xeB30b33A1aC175e0305853636D0eF3898eb530f3) (FiraSolvencyOracle) |
| IRM                   | `0x0000000000000000000000000000000000000000` (none — fixed rate)                                                                             |
| LTV                   | 89%                                                                                                                                          |
| LLTV                  | 90%                                                                                                                                          |
| Whitelist             | [`0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5`](https://etherscan.io/address/0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5) (LiquidityInjector)  |
| Maturity Grace Period | 86400 (24h)                                                                                                                                  |
| Liquidation Incentive | 3.1%                                                                                                                                         |
| BT Liquidity          | 350 BT supplied by LI                                                                                                                        |

### PT-sUSDe / BT

| Field                 | Value                                                                                                                                        |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Loan Token            | BT ([`0x57FFbb88f0c69283531a751BE6FF0741348371bA`](https://etherscan.io/address/0x57FFbb88f0c69283531a751BE6FF0741348371bA))                 |
| Collateral Token      | PT-sUSDe ([`0x3de0ff76E8b528C092d47b9DaC775931cef80F49`](https://etherscan.io/address/0x3de0ff76E8b528C092d47b9DaC775931cef80F49))           |
| Oracle                | [`0xB9bAA3D58E1431776218F39919fd21AeD3e69aBb`](https://etherscan.io/address/0xB9bAA3D58E1431776218F39919fd21AeD3e69aBb) (FiraSolvencyOracle) |
| IRM                   | `0x0000000000000000000000000000000000000000` (none — fixed rate)                                                                             |
| LTV                   | 89%                                                                                                                                          |
| LLTV                  | 90%                                                                                                                                          |
| Whitelist             | [`0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5`](https://etherscan.io/address/0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5) (LiquidityInjector)  |
| Maturity Grace Period | 86400 (24h)                                                                                                                                  |
| Liquidation Incentive | 3.1%                                                                                                                                         |
| BT Liquidity          | 350 BT supplied by LI                                                                                                                        |

### PT-apxUSD / BT (June 18 Expiry)

**Market ID**

```
0xfe8dbea27393d8703f2835c536630828d3742d4434fcb0a295d6a4cb0685d0ac
```

| Field                 | Value                                                                                                                                        |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Loan Token            | BT 18JUN ([`0x33fd40eD7744c961b61a086A87F83787bd9606eE`](https://etherscan.io/address/0x33fd40eD7744c961b61a086A87F83787bd9606eE))           |
| Collateral Token      | PT-apxUSD ([`0x92a6a01b07984de46c24e8eba248449beb8b1dcb`](https://etherscan.io/address/0x92a6a01b07984de46c24e8eba248449beb8b1dcb))          |
| Oracle                | [`0x5ccdbef28bc15d306ddb949f6b43bb0e3002cea6`](https://etherscan.io/address/0x5ccdbef28bc15d306ddb949f6b43bb0e3002cea6) (FiraSolvencyOracle) |
| IRM                   | `0x0000000000000000000000000000000000000000` (none — fixed rate)                                                                             |
| LTV                   | 88% (sentinel `0`: maxLTV == LLTV)                                                                                                           |
| LLTV                  | 88%                                                                                                                                          |
| Whitelist             | [`0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5`](https://etherscan.io/address/0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5) (LiquidityInjector)  |
| Maturity Grace Period | 86400 (24h)                                                                                                                                  |
| Liquidation Incentive | 3.73%                                                                                                                                        |

## Oracle pipeline

### Variable-rate oracles

| Market      | Oracle                                                                                                                  | Type                                         |
| ----------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| wstETH/USDC | [`0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2`](https://etherscan.io/address/0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2) | Morpho v1 oracle (pre-deployed, reused)      |
| cbBTC/USDC  | [`0x698253A24CC4926090f841B38D31d6342A00a82C`](https://etherscan.io/address/0x698253A24CC4926090f841B38D31d6342A00a82C) | ChainlinkOracleV2 (BTC/USD + USDC/USD feeds) |

### Fixed-rate oracle pipeline (May 7 Expiry)

PT-USDe and PT-sUSDe markets use a 3-layer oracle stack:

```
AaveToChainlinkAdapter → ChainlinkOracleV2 → FiraSolvencyOracle → FiraLendingMarket
```

| Layer                  | PT-USDe                                                                                                                 | PT-sUSDe                                                                                                                |
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| AaveToChainlinkAdapter | [`0xc42F003F9eCD3DdDF704556E82Cdd9271818171F`](https://etherscan.io/address/0xc42F003F9eCD3DdDF704556E82Cdd9271818171F) | [`0x3d7346578be9B82E0227D027bd86F6De59BA3C91`](https://etherscan.io/address/0x3d7346578be9B82E0227D027bd86F6De59BA3C91) |
| ChainlinkOracleV2      | [`0x2ED527087B740530562754EFCd608290eCCdBe2e`](https://etherscan.io/address/0x2ED527087B740530562754EFCd608290eCCdBe2e) | [`0xD6f5D9102007A737D9EDE6543262516d5c2fc8f8`](https://etherscan.io/address/0xD6f5D9102007A737D9EDE6543262516d5c2fc8f8) |
| FiraSolvencyOracle     | [`0xeB30b33A1aC175e0305853636D0eF3898eb530f3`](https://etherscan.io/address/0xeB30b33A1aC175e0305853636D0eF3898eb530f3) | [`0xB9bAA3D58E1431776218F39919fd21AeD3e69aBb`](https://etherscan.io/address/0xB9bAA3D58E1431776218F39919fd21AeD3e69aBb) |

### Fixed-rate oracle pipeline (May 27 Expiry — PT-USDG)

The PT-USDG market uses a MetaOracleDeviationTimelock with primary/backup oracle redundancy:

```
MetaOracleDeviationTimelock → FiraSolvencyOracle → FiraLendingMarket
```

| Layer                       | Address                                                                                                                 | Description                      |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| MetaOracleDeviationTimelock | [`0xEA268c588072e2639448E3a9433AB92E871335E2`](https://etherscan.io/address/0xEA268c588072e2639448E3a9433AB92E871335E2) | Deviation threshold: 0.5%        |
| Primary Oracle              | [`0x8ec85C167a43EBe4EB183e8d9B876D1cdad9A9fB`](https://etherscan.io/address/0x8ec85C167a43EBe4EB183e8d9B876D1cdad9A9fB) | 1:1 USDG peg + Pendle TWAP       |
| Backup Oracle               | [`0x8A01940D89CF95D9F6e92a90B17C0Ca5C953fE73`](https://etherscan.io/address/0x8A01940D89CF95D9F6e92a90B17C0Ca5C953fE73) | Chainlink USDG/USD + Pendle TWAP |
| FiraSolvencyOracle          | [`0x90d0d6fdf9fe93777085e8b4baf3aab4285bac6b`](https://etherscan.io/address/0x90d0d6fdf9fe93777085e8b4baf3aab4285bac6b) | Final solvency check             |

### Fixed-rate oracle pipeline (June 18 Expiry — PT-apxUSD)

The PT-apxUSD market reuses the Morpho-listed `MorphoChainlinkOracleV2` directly. Two BASE feeds (Pendle PT-apxUSD TWAP × Apyx Capped CR) are combined and divided by the USDC/USD QUOTE feed:

```
MorphoChainlinkOracleV2 → FiraSolvencyOracle → FiraLendingMarket
```

| Layer                          | Address                                                                                                                 | Description                |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | -------------------------- |
| MorphoChainlinkOracleV2        | [`0x4DFceF82eaEE9eA817bEb1279336F7D0Ebf2b685`](https://etherscan.io/address/0x4DFceF82eaEE9eA817bEb1279336F7D0Ebf2b685) | Reused from Morpho listing |
| BASE\_FEED\_1 (Pendle PT TWAP) | [`0xEfDB275FC9C7946f36E632bEF61379c5f5Ab4C86`](https://etherscan.io/address/0xEfDB275FC9C7946f36E632bEF61379c5f5Ab4C86) | PT-apxUSD TWAP feed        |
| BASE\_FEED\_2 (Apyx CR)        | [`0x2037a5Eb67aa9B2FBF50042B724D8c4dB80F23b4`](https://etherscan.io/address/0x2037a5Eb67aa9B2FBF50042B724D8c4dB80F23b4) | Apyx Capped CR feed        |
| QUOTE\_FEED\_1 (Chainlink)     | [`0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6`](https://etherscan.io/address/0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6) | USDC/USD                   |
| FiraSolvencyOracle             | [`0x5ccdbef28bc15d306ddb949f6b43bb0e3002cea6`](https://etherscan.io/address/0x5ccdbef28bc15d306ddb949f6b43bb0e3002cea6) | Final solvency check       |

### Chainlink feeds

| Feed     | Address                                                                                                                 |
| -------- | ----------------------------------------------------------------------------------------------------------------------- |
| BTC/USD  | [`0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c`](https://etherscan.io/address/0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c) |
| USDC/USD | [`0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6`](https://etherscan.io/address/0x8fFfFfd4AfB6115b954Bd326cbe7B4BA576818f6) |

## Router facets

The FiraRouterV4 uses a facet-based (diamond-like) architecture. All user-facing calls go through the Router, which delegates to the appropriate facet.

| Facet                | Address                                                                                                                 | Functions               |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| ActionSwapBTV3       | [`0xab2383692ed8e0836e25b71988c925dfd94ed2fe`](https://etherscan.io/address/0xab2383692ed8e0836e25b71988c925dfd94ed2fe) | BT swaps                |
| ActionSwapCTV3       | [`0xdb7a722ae7baf83d3d8b9e812952916326d6656b`](https://etherscan.io/address/0xdb7a722ae7baf83d3d8b9e812952916326d6656b) | CT swaps                |
| ActionAddRemoveLiqV3 | [`0x286bbc5519cd421011e7e1c092e1d6a72edb4d30`](https://etherscan.io/address/0x286bbc5519cd421011e7e1c092e1d6a72edb4d30) | Liquidity add/remove    |
| ActionCallbackV3     | [`0x2dead5b19935d7299d7077c52f2e2860370278a5`](https://etherscan.io/address/0x2dead5b19935d7299d7077c52f2e2860370278a5) | Internal swap callbacks |
| ActionSimple         | [`0x4474886d003abcb53c307324894c074ce5176f75`](https://etherscan.io/address/0x4474886d003abcb53c307324894c074ce5176f75) | Simple token transfers  |
| ActionMiscV3         | [`0x967234d7a4416380107da653e5d3afc9c7bf8874`](https://etherscan.io/address/0x967234d7a4416380107da653e5d3afc9c7bf8874) | FW/BC minting, simulate |
| ActionBorrow         | [`0x66f5853cf6c36b97e754f074397d00b78253ef03`](https://etherscan.io/address/0x66f5853cf6c36b97e754f074397d00b78253ef03) | Borrow/repay            |
| ActionStorageV4      | [`0x0386685eA7d37c61dDb8F2e2E8c45f6a81d4A3C8`](https://etherscan.io/address/0x0386685eA7d37c61dDb8F2e2E8c45f6a81d4A3C8) | Router admin            |

## Factory contracts

| Contract                 | Address                                                                                                                 |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| ChainlinkOracleV2Factory | [`0x7783fF7bE856C7A82bC5497Fb3CC8F7E8802D8dC`](https://etherscan.io/address/0x7783fF7bE856C7A82bC5497Fb3CC8F7E8802D8dC) |
| SisuVaultFactory         | [`0xe77E0f97A864558e5513209323e4169FcEAC6981`](https://etherscan.io/address/0xe77E0f97A864558e5513209323e4169FcEAC6981) |
| YieldContractFactory     | [`0xcdB83Abb9121c04589567A4106C3cFaf65DB68Be`](https://etherscan.io/address/0xcdB83Abb9121c04589567A4106C3cFaf65DB68Be) |
| FiraMarketFactory        | [`0xBF1EfC2199ae9EE1B6f5060a45D4440157E49744`](https://etherscan.io/address/0xBF1EfC2199ae9EE1B6f5060a45D4440157E49744) |

## Key roles

| Role                | Address                                                                                                                               |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| SisuVault Curator   | [`0xc02B0D1ca7B986E63cf1599F9c32e8A96c2D4Cff`](https://etherscan.io/address/0xc02B0D1ca7B986E63cf1599F9c32e8A96c2D4Cff) (Markov Labs) |
| SisuVault Allocator | [`0x4E700A14868620a9Bba0669721F1945c410c7571`](https://etherscan.io/address/0x4E700A14868620a9Bba0669721F1945c410c7571) (Markov Labs) |
| FIRA Yield Treasury | [`0x97fD565B913b439Ff16774Da152B1f71F05A82F1`](https://etherscan.io/address/0x97fD565B913b439Ff16774Da152B1f71F05A82F1)               |
| Deployer EOA        | [`0x7Da82CBD315923d75dbb2C62F099392705FF97f9`](https://etherscan.io/address/0x7Da82CBD315923d75dbb2C62F099392705FF97f9)               |


# User Flows

Step-by-step user flows for every major operation in the Fira protocol, with sequence diagrams, preconditions, views, and events.

These pages document the end-to-end transaction flows for each user-facing operation in the Fira protocol. Each flow includes a Mermaid sequence diagram, preconditions, relevant view functions, emitted events, and reward share formulas where applicable.

{% hint style="info" %}
All user operations go through the **FiraRouterV4** (except variable-rate lending, which interacts with the LendingMarket directly). Users must approve the relevant tokens to the router before calling.
{% endhint %}

## Common parameter structs

| Struct           | Fields                                                                               |
| ---------------- | ------------------------------------------------------------------------------------ |
| `MarketParams`   | `loanToken`, `collateralToken`, `oracle`, `irm`, `ltv`, `lltv`, `whitelist`          |
| `TokenInput`     | `tokenIn`, `netTokenIn`, `tokenMintFw`, `firaSwap`, `swapData`                       |
| `TokenOutput`    | `tokenOut`, `minTokenOut`, `tokenRedeemFw`, `firaSwap`, `swapData`                   |
| `LimitOrderData` | Pricing limits for BT/FW market swap (interface compat, not used in current version) |

## Flows

* [Borrow at Fixed Rate](/developers/user-flows/borrow-fixed-rate)
* [Repay Fixed-Rate Debt](/developers/user-flows/repay-fixed-rate)
* [Variable-Rate Lending](/developers/user-flows/variable-rate-lending)
* [Repay Variable-Rate Debt](/developers/user-flows/repay-variable-rate)
* [FW Deposit & Redeem](/developers/user-flows/fw-deposit-redeem)
* [Provide Liquidity](/developers/user-flows/provide-liquidity)
* [Remove Liquidity](/developers/user-flows/remove-liquidity)
* [Trade BT & CT](/developers/user-flows/trade-bt-ct)
* [Pre/Post-Expiry Exits](/developers/user-flows/pre-post-expiry-exits)


# Borrow Fixed Rate

Supply collateral and borrow at a fixed rate in a single transaction, receiving USDC via the BT→FW→token path.

```mermaid
sequenceDiagram
  actor User
  participant Router as Router (ActionBorrow)
  participant FRLM as Fixed Rate LendingMarket (FRLM)
  participant FM as FiraMarket (BT/FW/CT)
  participant FW as FW (StandardizedYield)

  Note over User,Router: User approves collateralToken to Router (ERC20 approve)
  User->>Router: supplyAndBorrowSingleToken(marketParams, FRLM, FM, collateral, btToBorrow, output, limit, receiver)
  Router->>Router: transferFrom(user, collateralToken, collateral)
  Router->>FRLM: approve(collateralToken, collateral)
  Router->>FRLM: supplyCollateral(marketParams, collateral, user, "")
  FRLM-->>Router: position updated (collateral credited to user)
  Router->>FRLM: borrow(marketParams, btToBorrow, 0, user, Router)
  FRLM-->>Router: transfer BT to Router (loanToken = BT, debt on user)
  Router->>FM: transfer BT to FM, swapExactBtForFw(Router, btBorrowed, "")
  FM-->>Router: FW out to Router
  Router->>FW: transfer FW to FW contract
  Router->>FW: redeem(Router, fwOut, tokenRedeemFw, 0, true)
  FW-->>Router: tokenOut (e.g., USDC)
  Router-->>User: transfer tokenOut to receiver
```

**Also available**: `borrowSingleToken` — same flow but skips the collateral supply step (assumes collateral already supplied).

**Key references**: `src/fira_bonding/router/ActionBorrow.sol::supplyAndBorrowSingleToken`, `borrowSingleToken`.

## Details

* **Goal**: Supply collateral and receive a target token in one transaction (via BT→FW→token path).
* **Preconditions**:
  * User approved `collateralToken` to the router.
  * `tokensToBorrow > 0`, `collateralAmount > 0`, `receiver != 0x0`.
  * Market is initialized; `firaMarket` and `lendingMarket` set.
  * User must have authorized the router on the LendingMarket (`setAuthorization(router, true)`).
* **Parameters** (high level):
  * `marketParams` (Fira Lending), `collateralAmount`, `tokensToBorrow` (BT),
  * `output` (TokenOutput: `tokenOut`, `tokenRedeemFw`, `minTokenOut`, `firaSwap`, `swapData`),
  * `limitOrderData` (kept for interface compatibility, orderbook not used in current version).

## Views and events

**Views**

* Lending: `getUserPosition(marketParams, user)` → `supplyAssets`, `supplyShares`, `borrowAssets`, `borrowShares`, `collateralAssets`.
* Lending: `position(id, user)`, `market(id)`.
* Market (fixed-rate): `readTokens()`, `isExpired()`.

**Events**

* Lending: `EventsLib.SupplyCollateral`, `EventsLib.Borrow`.
* Market: `Swap` (BT→FW), `UpdateImpliedRate`.
* FW: `Deposit` (tokenIn→FW), `Redeem` (FW→tokenOut).

## Reward share (fixed-rate borrow)

* Suggested formula: `userBorrowBT / totalBorrowBT` over the epoch (TWAP).
* Functions to call:
  * `LendingMarket.getUserPosition(marketParamsBT, user)` → `borrowAssets` (userBorrowBT)
  * `LendingMarket.market(idBT).totalBorrowAssets` → `totalBorrowBT` (consider `accrueInterest(marketParamsBT)` before reading)
  * `FiraMarket.readTokens()` → BT address; `FiraMarket.isExpired()`
* Events to index: `EventsLib.Borrow`, `FiraMarket.Swap` (BT→FW), `IFiraWrappedStandardized.Redeem`


# Repay Fixed Rate

Repay fixed-rate debt using any input token, with automatic BT acquisition via AMM swap (pre-expiry) or BT+CT minting (post-expiry).

```mermaid
sequenceDiagram
  actor User
  participant Router as Router (ActionBorrow)
  participant FRLM as Fixed Rate LendingMarket (FRLM)
  participant FM as FiraMarket
  participant FW as FW
  participant CT as CouponToken (CT)

  Note over User,Router: User approves input token to Router (ERC20 approve)
  User->>Router: repay(marketParams, FRLM, FM, tokensToRepay, input)
  alt BT not expired
    Router->>FW: mintFwFromToken (input token → FW)
    FW-->>Router: FW out
    Router->>FM: swapFwForExactBt (FW → BT via AMM)
    FM-->>Router: BT out
    Router->>FRLM: approve BT, repay(marketParams, btToRepay, 0, user, "")
    FRLM-->>Router: position updated (debt reduced)
    Router-->>User: refund excess BT (if any)
  else BT expired
    Router->>FW: mintFwFromToken (input token → FW, sent to CT contract)
    FW-->>CT: FW deposited
    Router->>CT: mintBC(Router, Router) — mints both BT and CT to Router
    CT-->>Router: BT + CT out (CT is minted but economically worthless post-expiry)
    Router->>FRLM: approve BT, repay(marketParams, btToRepay, 0, user, "")
    FRLM-->>Router: position updated (debt reduced)
    Router-->>User: refund excess BT (if any)
    Note over Router: CT minted post-expiry stays in Router (zero value, never burned)
  end
```

**Key references**: `ActionBorrow.repay`.

## Details

* **Goal**: Repay debt using an input token; router converts to BT as needed.
* **Preconditions**:
  * Existing borrow: else `"AB: no borrow"`.
  * `tokensToRepay` must be ≤ current debt: else `"AB: repay too much"`.
  * Input token approval to router.
* **Expiry handling**:
  * **Pre-expiry**: Input token → FW (mint) → BT (AMM swap via FiraMarket). Repay, refund excess BT.
  * **Post-expiry**: Input token → FW (mint to CT contract) → `CT.mintBC` produces BT + CT. Only BT is used for repayment. CT is minted but NOT burned — it stays in the router with zero economic value.

## Views and events

**Views**

* Lending: `getUserPosition` (pre/post), `position(id, user)`.
* Market: `isExpired()`.
* FW: `previewDeposit`, `bcIndexStored()` for estimation on expired paths.

**Events**

* Lending: `EventsLib.Repay` (assets, shares), possibly `EventsLib.AccrueInterest`.
* Router/Misc: `MintFwFromToken`, `MintBcFromFw` when conversions occur.


# Variable Rate Lending

Supply collateral and borrow USDC at a variable rate directly from the lending market, or lend USDC via the SisuVault for variable yield.

```mermaid
sequenceDiagram
  actor User
  participant VRLM as Variable Rate LendingMarket
  participant Oracle as Oracle

  Note over User,VRLM: User approves collateralToken to VRLM (ERC20 approve)
  User->>VRLM: supplyCollateral(marketParamsUSDC, collateral, user, "")
  VRLM-->>User: position updated (collateral credited)
  User->>VRLM: borrow(marketParamsUSDC, usdcToBorrow, 0, user, receiver)
  VRLM-->>User: USDC transferred to receiver
  Note over VRLM,Oracle: Interest accrues, LTV/LLTV enforced via oracle price
```

**Key references**: `src/LendingMarket.sol` (`supplyCollateral`, `borrow`, `getUserPosition`).

## Details

* **Goal**: Supply collateral and borrow variable-rate assets (e.g., USDC) directly from the lending market.
* **Preconditions**:
  * Market created with `loanToken = USDC`, appropriate `oracle`, `ltv/lltv` enabled.
  * Approvals for `collateralToken` to LendingMarket.
* **Notes**:
  * FW deposits may be rehypothecated into this market on the supply side, while borrowers take variable-rate loans.

## Views and events

**Views**

* Lending: `getUserPosition(marketParamsUSDC, user)` → `supplyAssets`, `supplyShares`, `borrowAssets`, `borrowShares`, `collateralAssets`.
* Lending: `position(id, user)`, `market(id)`.
* Oracle: `price()` (via marketParams' oracle) for health checks.

**Events**

* Lending: `EventsLib.SupplyCollateral`, `EventsLib.Borrow`, `EventsLib.AccrueInterest`.

## Reward share (variable-rate borrow)

* Formula: `userBorrowAssets / totalBorrowAssets` over the epoch (TWAP).
* Functions to call:
  * `LendingMarket.getUserPosition(marketParamsUSDC, user)` → `borrowAssets`
  * `LendingMarket.position(idUSDC, user)`, `LendingMarket.market(idUSDC)` (optional)
  * Index events: `EventsLib.Borrow`, `EventsLib.AccrueInterest`

## Reward share (variable-rate lend)

* Formula: `userVaultAssets / totalVaultAssets` over the epoch (TWAP).
* Functions to call:
  * `ISisuVault.balanceOf(user)`; `ISisuVault.convertToAssets(shares)` → `userVaultAssets`
  * `ISisuVault.totalAssets()` (denominator); `ISisuVault.totalSupply()` (optional)
  * Index events (optional): vault `Deposit`/`Withdraw` if exposed


# Repay Variable Rate

Repay variable-rate USDC debt directly on the lending market.

```mermaid
sequenceDiagram
  actor User
  participant VRLM as Variable Rate LendingMarket

  Note over User,VRLM: User approves USDC to VRLM (ERC20 approve)
  User->>VRLM: repay(marketParamsUSDC, usdcToRepay, 0, user, "")
  VRLM-->>User: position updated (borrow reduced)
```

## Details

* **Goal**: Repay outstanding variable-rate USDC debt.
* **Preconditions**: USDC approval to LendingMarket.

## Function call

```
repay(marketParamsUSDC, assets, shares, onBehalf, data)
```

* For asset-based repay: set `assets = usdcToRepay`, `shares = 0`, `onBehalf = user`, `data = ""`
* To repay max via shares: set `shares` to the user's borrow shares and `assets = 0`

## Views and events

**Views**

* `LendingMarket.getUserPosition(marketParamsUSDC, user)` (pre/post) → `borrowAssets`
* `LendingMarket.market(idUSDC)` → `totalBorrowAssets` (consider `accrueInterest(marketParamsUSDC)` before reading)
* `LendingMarket.position(idUSDC, user)` (optional)

**Events**

* `EventsLib.Repay` (assets, shares)
* `EventsLib.AccrueInterest` (optional, if triggered)


# Trade BT/CT

Mint BT+CT from tokens by splitting FW, and redeem BT+CT back to tokens with different handling pre- and post-expiry.

```mermaid
sequenceDiagram
  actor User
  participant Router as Router (ActionMiscV3)
  participant FW as FW
  participant CT as CouponToken (CT)
  participant BT as BondToken (BT)

  Note over User,Router: User approves token to Router (ERC20 approve)
  User->>Router: mintBcFromToken(receiver, CT, minBcOut, input)
  Router->>FW: mint FW from token (deposit to CT contract)
  FW-->>CT: FW deposited
  Router->>CT: mintBC(receiver, receiver)
  Note over CT: Mints equal BT and CT tokens from FW
  CT->>BT: mintByCT(receiver, amount) — BT minted
  CT-->>User: CT minted to receiver
  BT-->>User: BT minted to receiver

  alt Redeem pre-expiry (requires both BT + CT)
    User->>Router: redeemBcToToken(receiver, CT, netBcIn, output)
    Note over Router: Router pulls BT and CT from user
    Router->>CT: transfer BT from user to CT contract
    Router->>CT: transfer CT from user to CT contract
    Router->>CT: redeemBC(FW) — burns both BT and CT, returns FW
    CT-->>Router: FW out (single atomic operation, no AMM swap)
    Router->>FW: redeem FW → tokenOut
    FW-->>Router: tokenOut
    Router-->>User: tokenOut
  else Redeem post-expiry (requires only BT)
    User->>Router: redeemBcToToken(receiver, CT, netBcIn, output)
    Note over Router: Router pulls only BT from user (CT not needed)
    Router->>CT: transfer BT from user to CT contract
    Router->>CT: redeemBC(FW) — burns BT only, CT is NOT burned
    CT-->>Router: FW out (at bcIndex rate, not 1:1)
    Router->>FW: redeem FW → tokenOut
    FW-->>Router: tokenOut
    Router-->>User: tokenOut
    Note over CT: Post-expiry yield difference goes to treasury
  end
```

**Key references**: `IPActionMiscV3.mintBcFromToken`, `mintBcFromFw`, `redeemBcToToken`, `redeemBcToFw`.

## Details

* **Goal**: Split FW into BT + CT and later unwind back to base token.
* **Preconditions**:
  * Approvals for `tokenIn` to Router.
  * Set `minBcOut` / `minTokenOut` thresholds.
* **Minting**: `mintBcFromToken` / `mintBcFromFw` — always produces equal BT + CT, both pre- and post-expiry. Post-expiry uses frozen `postExpiry.firstBCIndex` for the conversion rate.
* **Redemption pre-expiry**: Both BT and CT must be provided. `CT.redeemBC()` burns both and returns FW. No AMM swap involved.
* **Redemption post-expiry**: Only BT is required. `CT.redeemBC()` burns BT only; CT is NOT burned. FW returned at the current `bcIndex`, and any post-expiry yield accrual goes to the treasury.

## Views and events

**Views**

* CT (`IBCToken`): `bcIndexStored()`, `bcIndexCurrent()`; `FW()`, `BT()`; `isExpired()`, `balanceOf(user)`.
* BT (`IBondToken`): `balanceOf(user)`, `FW()`, `CT()`, `expiry()`, `isExpired()`.
* FW: `previewDeposit`, `previewRedeem`.

**Events**

* Router: `MintBcFromToken`, `MintBcFromFw`, `RedeemBcToToken`, `RedeemBcToFw`.
* CT: `Mint`, `Burn`, `RedeemInterest`.

## Reward share (CT)

* Suggested formula: `userCt / totalCt` over the epoch (TWAP).
* Functions to call:
  * `IBCToken(CT).balanceOf(user)`, `IERC20(CT).totalSupply()`
  * Exclude expired CT. Post-expiry CT is minted but never burned, inflating `totalSupply()` — consider filtering by excluding known router/contract addresses.

## Reward share (BT)

* Suggested formula: `userBt / totalBt` where:
  * `userBt = IBondToken(BT).balanceOf(user) - getUserPosition(marketParamsBT, user).borrowAssets`
  * `totalBt = IERC20(BT).totalSupply() - IBondToken(BT).balanceOf(market) - IBondToken(BT).balanceOf(lendingMarket)`
* Over the epoch (TWAP).


# Provide Liquidity

Provide liquidity to the BT/FW market using dual-sided, single-sided, or keep-CT strategies and receive LP tokens.

```mermaid
sequenceDiagram
  actor User
  participant Router as Router (ActionAddRemoveLiqV3)
  participant FW as FW
  participant CT as CouponToken (CT)
  participant FM as FiraMarket (BT/FW/LP)

  Note over User,Router: User approves tokens to Router (ERC20 approve)
  User->>Router: addLiquidity*(receiver, FM, ...)
  alt Dual Token+BT (addLiquidityDualTokenAndBt)
    Router->>FW: mint FW from token input (deposit)
    FW-->>FM: FW sent to market
    Router->>FM: transferFrom(user, BT, netBtUsed) — BT from user to market
    Router->>FM: mint(receiver, netFwUsed, netBtUsed)
    FM-->>User: LP tokens to receiver
  else Dual FW+BT (addLiquidityDualFwAndBt)
    Router->>FM: transferFrom(user, FW, netFwUsed)
    Router->>FM: transferFrom(user, BT, netBtUsed)
    Router->>FM: mint(receiver, netFwUsed, netBtUsed)
    FM-->>User: LP tokens to receiver
  else Single Token (addLiquiditySingleToken)
    Router->>FW: mint FW from token input
    FW-->>FM: FW to market
    Router->>FM: swapFwForExactBt(market, btOut, "") — swap portion of FW to BT
    FM-->>FM: BT stays in market
    Router->>FM: mint(receiver, netFwLeft, netBtReceived)
    FM-->>User: LP tokens to receiver
  else Single Token Keep CT (addLiquiditySingleTokenKeepCt)
    Router->>FW: mint FW from token input (to Router)
    FW-->>Router: FW out
    Router->>CT: transfer portion of FW to CT contract
    Router->>FM: transfer remaining FW to market
    Router->>CT: mintBC(market, receiver) — BT to market, CT to receiver
    CT-->>FM: BT
    CT-->>User: CT tokens
    Router->>FM: mint(receiver, netFwAddLiquidity, netBtFromMint)
    FM-->>User: LP tokens to receiver
  end
```

**Key references**: `ActionAddRemoveLiqV3.addLiquidityDualTokenAndBt`, `addLiquidityDualFwAndBt`, `addLiquiditySingleToken`, `addLiquiditySingleBt`, `addLiquiditySingleFw`, `addLiquiditySingleTokenKeepCt`, `addLiquiditySingleFwKeepCt`.

## Details

* **Goal**: Provide liquidity to BT/FW market and receive LP.
* **Preconditions**:
  * Approvals for all inputs (`tokenIn`, `BT`, and/or `FW`).
  * Set `minLpOut` and approximation params when single-sided.
* **Additional entrypoints**:
  * `addLiquiditySingleBt` — BT only, swaps portion to FW.
  * `addLiquiditySingleFw` — FW only, swaps portion to BT.
  * `addLiquiditySingleFwKeepCt` — FW + keep CT variant.

## Views and events

**Views**

* Market: `readTokens()`, `isExpired()`, `readState(router)`, `observe(secondsAgos)`.
* LP: `balanceOf(user)`, `totalSupply()` (derive proportional share of `totalBt/totalFw`).

**Events**

* Router: `AddLiquidityDualTokenAndBt`, `AddLiquidityDualFwAndBt`, `AddLiquiditySingleBt`, `AddLiquiditySingleFw`, `AddLiquiditySingleToken`, `AddLiquiditySingleTokenKeepCt`, `AddLiquiditySingleFwKeepCt`.
* Market: `Mint`, `Swap` (during balancing), `UpdateImpliedRate`.

## Reward share (LP)

* Suggested formula: `lpBalance / totalSupply()` over the epoch (TWAP).
* Functions to call:
  * `IERC20(market).balanceOf(user)`, `IERC20(market).totalSupply()`
  * `FiraMarket.readState(router)` → `totalBt`, `totalFw`, `totalLp` (for underlying attribution)


# Remove Liquidity

Burn LP tokens to withdraw proportional BT and FW from the FiraMarket pool.

```mermaid
sequenceDiagram
  actor User
  participant Market as FiraMarket

  User->>Market: burn(receiverFw, receiverBt, lpToBurn)
  Market-->>User: FW out to receiverFw, BT out to receiverBt
```

**Key references**: `FiraMarket.burn`.

## Details

* **Goal**: Burn LP to withdraw proportional FW and BT.
* **Preconditions**: Transfer LP to market before calling `burn`; decide receivers for FW/BT.
* **Notes**: Router provides additional remove methods:
  * `removeLiquidityDualFwAndBt` / `removeLiquidityDualTokenAndBt`
  * `removeLiquiditySingleBt` / `removeLiquiditySingleFw` / `removeLiquiditySingleToken`
  * Single-FW removal post-expiry: BT is sent to CT contract and redeemed via `CT.redeemBC`.

## Views and events

**Views**

* Market: `readTokens()`, `isExpired()`.

**Events**

* Market: `Burn(receiverFw, receiverBt, netLpToBurn, netFwOut, netBtOut)`.


# FW Deposit & Redeem

Deposit tokens into FW to earn yield, and redeem FW shares back to underlying tokens.

```mermaid
sequenceDiagram
  actor User
  participant FW as FW (StandardizedYield e.g., USDCFW)

  User->>FW: deposit(receiver, tokenIn, amount, minSharesOut)
  FW-->>User: mint FW shares to receiver
  Note over FW: Exchange rate increases as yield accrues
  User->>FW: redeem(receiver, shares, tokenOut, minOut, burnFromInternalBalance)
  FW-->>User: transfer tokenOut to receiver
```

**Key references**: `FWBase.deposit`, `FWBase.redeem` (and `FWBaseUpg` variants).

## Details

* **Goal**: Earn yield via FW shares; redeem later for base tokens.
* **Preconditions**:
  * `isValidTokenIn(tokenIn)` and `isValidTokenOut(tokenOut)` must be true for the chosen FW.
  * Approve `tokenIn` to FW; set `minSharesOut` to guard slippage.
* **Notes**:
  * Exchange rate increases from underlying yield; shares track proportional claim.
  * FW rehypothecates liquidity; see specific implementation (e.g., `USDCFW`).

## Views and events

**Views**

* FW: `balanceOf(user)`, `totalSupply()`, `exchangeRate()`, `previewDeposit(tokenIn, amount)`, `previewRedeem(tokenOut, shares)`, `accruedRewards(user)`.

**Events**

* FW: `Deposit`, `Redeem`, `ClaimRewards`.


# Pre/Post Expiry Exits

Unwind LP, BT, and CT positions to a single token or FW in one transaction, with different strategies pre- and post-expiry.

```mermaid
sequenceDiagram
  actor User
  participant Router as Router (ActionMiscV3)
  participant Market as FiraMarket
  participant FW as FW
  participant CT as CouponToken (CT)
  participant BT as BondToken (BT)

  alt Pre-expiry exit (exitPreExpToToken/Fw)
    Note over User,Router: User approves LP/BT/CT tokens to Router
    User->>Router: exitPreExpToToken(receiver, market, netBtIn, netCtIn, netLpIn, output, limit)

    opt LP provided (netLpIn > 0)
      Router->>Market: transfer LP from user to market
      Router->>Market: burn(fwReceiver, Router, netLpIn)
      Market-->>Router: FW out (to fwReceiver), BT out (to Router)
    end

    opt Additional BT provided (netBtIn > 0)
      Router->>Router: pull BT from user
    end

    Note over Router: Match BT with CT for BC redemption (most efficient path)
    Note over Router: netBcRedeem = min(totalBt, netCtIn)
    opt netBcRedeem > 0
      Router->>CT: transfer BT to CT contract
      Router->>CT: transfer CT from user to CT contract
      Router->>CT: redeemBC(fwReceiver) — burns both BT + CT → FW
      CT-->>Router: FW from redemption
    end

    Note over Router: Handle remaining unmatched tokens
    opt Remaining BT (not matched with CT)
      Router->>Market: swapExactBtForFw — swap surplus BT → FW via AMM
      Market-->>Router: FW from swap
    end
    opt Remaining CT (not matched with BT)
      Router->>Market: swapExactCtForFw — swap surplus CT → FW via AMM
      Market-->>Router: FW from swap
    end

    Router->>FW: redeem all collected FW → tokenOut
    FW-->>Router: tokenOut
    Router-->>User: tokenOut to receiver

  else Post-expiry exit (exitPostExpToToken/Fw)
    Note over User,Router: User approves LP/BT tokens to Router
    User->>Router: exitPostExpToToken(receiver, market, netBtIn, netLpIn, output)

    opt LP provided (netLpIn > 0)
      Router->>Market: transfer LP from user to market
      Router->>Market: burn(fwReceiver, CT, netLpIn)
      Market-->>FW: FW out (to fwReceiver)
      Market-->>CT: BT out (sent to CT contract for redemption)
    end

    opt Additional BT provided (netBtIn > 0)
      Router->>CT: transfer BT from user directly to CT contract
    end

    Router->>CT: redeemBC(fwReceiver) — burns BT only, CT NOT burned
    CT-->>Router: FW from redemption (at bcIndex rate)

    Router->>FW: redeem all collected FW → tokenOut
    FW-->>Router: tokenOut
    Router-->>User: tokenOut to receiver
    Note over CT: Post-expiry yield difference accrues to treasury
  end
```

**Key references**: `IPActionMiscV3.exitPreExpToToken/Fw`, `exitPostExpToToken/Fw`.

## Details

* **Goal**: Unwind LP/BT/CT positions to a single token or FW.
* **Pre-expiry**: Router first matches BT with CT for redemption (cheaper than swapping), then swaps any remaining unmatched BT or CT to FW via the AMM. Finally redeems FW to desired token.
* **Post-expiry**: BT is sent to the CT contract. `CT.redeemBC()` burns only BT (not CT). FW returned at current `bcIndex` rate. Post-expiry yield accrual goes to treasury, not the redeemer.

{% hint style="info" %}
**Implementation note**: `exitPostExpToFw` has a parameter named `netFwOut` that should be `netBtIn` (naming bug in implementation, no functional impact).
{% endhint %}

## Views and events

**Views**

* Market: `isExpired()`, `readTokens()`, `observe(...)`.
* Lending: `getUserPosition` if exiting borrow-adjacent strategies.

**Events**

* Router: `ExitPreExpToToken`, `ExitPreExpToFw`, `ExitPostExpToToken`, `ExitPostExpToFw`.
* Market: `Burn`, subsequent `Swap` if executed.
* CT: `Burn` (for BC redemption step).


# Events & Indexing

Event tracking and position measurement across Fira markets, covering the 8 role buckets and their on-chain event sources.

Fira tracks user positions across **8 role buckets** using weekly time-weighted average (TWAP) exposures. Positions are piecewise-constant, updated on relevant on-chain events. This section documents the event-to-role mapping and position share formulas for analytics and integrations.

{% hint style="info" %}
Positions are piecewise-constant between events. The indexer must track each event to maintain an accurate TWAP of user exposure per role bucket over each epoch.
{% endhint %}

## Role buckets

| Bucket   | Full name            | Market        |
| -------- | -------------------- | ------------- |
| **BFR**  | Borrow Fixed Rate    | Fixed Rate    |
| **BT**   | Held BT              | Fixed Rate    |
| **CT**   | Coupon Token holders | Fixed Rate    |
| **LP**   | Liquidity Providers  | Fixed Rate    |
| **VRB**  | Variable Rate Borrow | Variable Rate |
| **VRL**  | Variable Rate Lend   | Variable Rate |
| **USLC** | USL Collateral       | USL Migrator  |
| **USLL** | USL Loan             | USL Migrator  |

## Source contracts

| Contract          | Events defined in                                     | Emitted by          |
| ----------------- | ----------------------------------------------------- | ------------------- |
| **LendingMarket** | `lib/fira-lending-market/src/libraries/EventsLib.sol` | `LendingMarket.sol` |
| **BondToken**     | ERC20 events via FiraERC20                            | `BondToken.sol`     |
| **CouponToken**   | Custom + ERC20 events                                 | `CouponToken.sol`   |
| **FiraMarket**    | `src/interfaces/IPMarket.sol`                         | `FiraMarket.sol`    |
| **SisuVault**     | ERC4626 Deposit/Withdraw                              | `SisuVault.sol`     |

## Pages

* [Event Table](/developers/events-and-indexing/event-table) — Corrected event-to-role mapping with issue analysis
* [Position Measurement](/developers/events-and-indexing/reward-measurement) — Per-role position share formulas and function calls


# Event Table

Corrected event-to-role mapping for the Fira incentive indexer, with analysis of issues found in the original table.

## Fixed Rate Market

| Role | Event          | Contract            | Purpose                                    |
| ---- | -------------- | ------------------- | ------------------------------------------ |
| BFR  | Borrow         | LendingMarket       | Position increase                          |
| BFR  | Repay          | LendingMarket       | Position decrease                          |
| BFR  | Liquidate      | LendingMarket       | Forced position closure                    |
| BFR  | Swap           | FiraMarket          | BFR qualification check                    |
| BT   | Transfer       | BondToken           | All balance changes (mint, burn, transfer) |
| BT   | Borrow         | LendingMarket       | For "subtract borrowed" rule               |
| BT   | Repay          | LendingMarket       | For "subtract borrowed" adjustment         |
| CT   | Transfer       | CouponToken (ERC20) | All balance changes (mint, burn, transfer) |
| CT   | RedeemInterest | CouponToken         | Interest redemption                        |
| LP   | Mint           | FiraMarket          | LP creation                                |
| LP   | Burn           | FiraMarket          | LP destruction                             |
| LP   | Transfer       | FiraMarket          | LP token transfers                         |

## Variable Rate Market

| Role | Event          | Contract      | Purpose                          |
| ---- | -------------- | ------------- | -------------------------------- |
| VRB  | Borrow         | LendingMarket | Position increase                |
| VRB  | Repay          | LendingMarket | Position decrease                |
| VRB  | AccrueInterest | LendingMarket | Shares-to-USDC conversion update |
| VRB  | Liquidate      | LendingMarket | Forced position closure          |
| VRL  | Deposit        | SisuVault     | Position increase (ERC4626)      |
| VRL  | Withdraw       | SisuVault     | Position decrease (ERC4626)      |
| VRL  | Transfer       | SisuVault     | Vault share transfers            |

## USL Migrator

| Role | Event              | Contract      | Purpose                 |
| ---- | ------------------ | ------------- | ----------------------- |
| USLC | SupplyCollateral   | LendingMarket | Position increase       |
| USLC | WithdrawCollateral | LendingMarket | Position decrease       |
| USLC | Liquidate          | LendingMarket | Collateral seizure      |
| USLL | Borrow             | LendingMarket | Position increase       |
| USLL | Repay              | LendingMarket | Position decrease       |
| USLL | Liquidate          | LendingMarket | Forced position closure |

## Issues found and corrected

| Change      | Detail                                                                    |
| ----------- | ------------------------------------------------------------------------- |
| **Removed** | BT / Mint / FiraMarket — wrong contract; FiraMarket.Mint is for LP tokens |
| **Removed** | BT / Burn / FiraMarket — wrong contract; same reason                      |
| **Removed** | CT / Mint / CouponToken — redundant with CT Transfer (from=0x0)           |
| **Removed** | CT / Burn / CouponToken — redundant with CT Transfer (to=0x0)             |
| **Added**   | BFR / Swap / FiraMarket — required for BFR qualification per spec         |
| **Added**   | BFR / Liquidate / LendingMarket                                           |
| **Added**   | LP / Transfer / FiraMarket                                                |
| **Added**   | VRB / Liquidate / LendingMarket                                           |
| **Added**   | VRL / Transfer / SisuVault                                                |
| **Added**   | USLC / Liquidate / LendingMarket                                          |
| **Added**   | USLL / Liquidate / LendingMarket                                          |

### Key corrections explained

**BT Mint/Burn: Wrong contract (Critical)** — The original table listed BT Mint/Burn on FiraMarket, but BT is created/destroyed by `CouponToken.mintBC()` / `CouponToken.redeemBC()`. FiraMarket `Mint`/`Burn` events are about LP tokens, not BT. The ERC20 `Transfer` event on BondToken already captures mints (`from = address(0)`), burns (`to = address(0)`), and transfers.

**BFR qualification requires Swap** — The spec states borrowers must be verified by tracking both the borrow event and a swap event plus USDC transfer. The `Swap` event from FiraMarket confirms the borrower actually swapped BT for USDC.

**Liquidate event missing** — `EventsLib.Liquidate` fires on forced position closure and impacts BFR, VRB, USLC, and USLL. Without it, the TWAP will be incorrect for liquidated users.

## Event signatures reference

### LendingMarket (EventsLib)

```solidity
event Borrow(Id indexed id, address caller, address indexed onBehalf, address indexed receiver, uint256 assets, uint256 shares);
event Repay(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets, uint256 shares);
event SupplyCollateral(Id indexed id, address indexed caller, address indexed onBehalf, uint256 assets);
event WithdrawCollateral(Id indexed id, address caller, address indexed onBehalf, address indexed receiver, uint256 assets);
event AccrueInterest(Id indexed id, uint256 prevBorrowRate, uint256 interest, uint256 feeShares);
event Liquidate(Id indexed id, address indexed caller, address indexed borrower, uint256 repaidAssets, uint256 repaidShares, uint256 seizedAssets, uint256 badDebtAssets, uint256 badDebtShares);
```

### BondToken / CouponToken (ERC20)

```solidity
event Transfer(address indexed from, address indexed to, uint256 value);
```

### CouponToken (IBCToken)

```solidity
event RedeemInterest(address indexed user, uint256 interestOut);
```

### FiraMarket (IPMarket)

```solidity
event Mint(address indexed receiver, uint256 netLpMinted, uint256 netFwUsed, uint256 netBtUsed);
event Burn(address indexed receiverFw, address indexed receiverBt, uint256 netLpBurned, uint256 netFwOut, uint256 netBtOut);
event Swap(address indexed caller, address indexed receiver, int256 netBtOut, int256 netFwOut, uint256 netFwFee, uint256 netFwToReserve);
```

### SisuVault (ERC4626)

```solidity
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares);
event Transfer(address indexed from, address indexed to, uint256 value);
```

## Implementation notes

* **Market ID filtering**: All LendingMarket events carry `Id indexed id`. The indexer must filter by the correct market IDs to distinguish BFR vs VRB vs USLL markets.
* **No double counting**: BT/CT held inside LP pool addresses or router addresses must be excluded from BT/CT buckets. Maintain a set of excluded addresses.
* **AccrueInterest for BFR/USLL**: If position value must reflect accrued interest (not just principal), add AccrueInterest to those roles.
* **CT in LP pools**: If external AMM pools exist for CT (not FiraMarket), additional pool-specific events would be needed.


# Position Measurement

Position measurement formulas and on-chain function calls for each role bucket. Technical reference for integrators tracking user exposure across Fira markets.

{% hint style="info" %}
This page describes how to measure user positions across Fira markets. These formulas are useful for analytics, dashboards, and integrations. **No token incentive program is currently active for Fira V1.** If a reward program is introduced in the future, these measurement methods would serve as the basis for allocation calculations.
{% endhint %}

## Fixed Rate Market

### BFR (Borrow Fixed Rate)

* **What to measure**: Net outstanding principal, expressed in USDC (par: 1 BT ≈ 1 USDC).
* **Qualification rule**: Must match a Fira Lending `Borrow` event AND a FiraMarket `Swap` BT→FW plus `FW.Redeem` to USDC in the borrow flow.
* **User value**: `userBorrowBT = LendingMarket.getUserPosition(marketParamsBT, user).borrowAssets`
* **Total value**: `totalBorrowBT = LendingMarket.market(idBT).totalBorrowAssets` (consider calling `accrueInterest(marketParamsBT)` before reading)
* **Reward share**: `userBorrowBT / totalBorrowBT`
* **Function calls**:
  * Lending: `getUserPosition(marketParamsBT, user)`, `position(idBT, user)`, `market(idBT)`; `idBT = marketParamsBT.id()`
  * Tokens/Market: `FiraMarket.readTokens()` → BT address; Market `isExpired()` for status
* **Events to index**: `EventsLib.Borrow`, `FiraMarket.Swap` (BT→FW), `IFiraWrappedStandardized.Redeem`

### BT (Held BT)

* **What to measure**: Net long BT held outside LP and lending markets; subtract borrowed BT; unit BT.
* **User value**: `userBt = IBondToken(BT).balanceOf(user) - LendingMarket.getUserPosition(marketParamsBT, user).borrowAssets`
* **Total value**: `totalBt = IERC20(BT).totalSupply() - IBondToken(BT).balanceOf(market) - IBondToken(BT).balanceOf(lendingMarket)` (exclude BT in LP and lending)
* **Reward share**: `userBt / totalBt` over the epoch (TWAP)
* **Function calls**:
  * Tokens: `IBondToken(BT).balanceOf(user)`, `IERC20(BT).totalSupply()`, `IBondToken(BT).balanceOf(market)`, `IBondToken(BT).balanceOf(lendingMarket)`
  * Lending: `getUserPosition(marketParamsBT, user).borrowAssets`

### CT (Traders and LPs)

* **What to measure**: Net long CT held outside LP/router addresses; unit CT.
* **User value**: `userCt = IBCToken(CT).balanceOf(user)` (subtract CT known to be held in LP/router escrows)
* **Total value**: `totalCt = IERC20(CT).totalSupply()`
* **Reward share**: `userCt / totalCt`
* **Function calls**:
  * Tokens: `IBCToken(CT).balanceOf(user)`, `IERC20(CT).totalSupply()`; `IBCToken(CT).bcIndexStored()` if including index context; `isExpired()` for status

{% hint style="warning" %}
Exclude expired CT. Post-expiry CT is minted but never burned, inflating `totalSupply()`. Consider filtering by excluding known router/contract addresses.
{% endhint %}

### LP (FiraMarket BT/FW pool)

* **What to measure**: LP tokens in BT/FW FiraMarket pools; unit LP (market LPT).
* **User value**: `lpUser = IERC20(market).balanceOf(user)` limited to `market` addresses
* **Total value**: `lpTotal = IERC20(market).totalSupply()` per market
* **Reward share**: `lpUser / lpTotal` (optionally weight by underlying share using `readState(router)` totals)
* **Function calls**:
  * Market: `FiraMarket.readTokens()`, `readState(router)` → totals; `observe(...)` if you need rate context; `isExpired()`
  * LP token: `IERC20(market).balanceOf(user)`, `IERC20(market).totalSupply()`

## Variable Rate Market

### VRB (Variable Rate Borrow)

* **What to measure**: USDC borrowed; unit USDC.
* **User value**: `userVrb = LendingMarket.getUserPosition(marketParamsUSDC, user).borrowAssets`
* **Total value**: `totalVrb = LendingMarket.market(idUSDC).totalBorrowAssets` (consider calling `accrueInterest(marketParamsUSDC)` before reading)
* **Reward share**: `userVrb / totalVrb`
* **Function calls**:
  * Lending (views): `getUserPosition(marketParamsUSDC, user)`, `position(idUSDC, user)`, `market(idUSDC)`; `idUSDC = marketParamsUSDC.id()`
  * Optional: `accrueInterest(marketParamsUSDC)` to update totals before reading `market(idUSDC)`
  * Oracle: `IOracle.price()` (used for health checks; optional for rewards)

### VRL (Variable Rate Lending via vault)

* **What to measure**: USDC lent into the variable-rate vault; unit USDC.
* **User value**: `userVrl = ISisuVault.convertToAssets(ISisuVault.balanceOf(user))`
* **Total value**: `totalVrl = ISisuVault.totalAssets()` (or Σ users' assets for sub-set accounting)
* **Reward share**: `userVrl / totalVrl`
* **Function calls**: `ISisuVault.balanceOf(user)`, `convertToAssets(shares)`, `totalAssets()`, `totalSupply()`

## Indexing notes

* Lending market functions use `MarketParams` and derive `Id` via `marketParams.id()` off-chain or in-contract; to query data you can use `idToMarketParams(id)`.
* For indexing, include `user` as indexed topic when available (e.g., FW `Deposit/Redeem`, Lending events include `onBehalf`/`borrower`).
* CT interface is `IBCToken` (not `IPYieldToken`). Key view functions: `bcIndexStored()`, `bcIndexCurrent()`, `isExpired()`, `getPostExpiryData()`.


# Integrations

A practical guide for protocols and front-ends integrating with Fira's on-chain contracts.

This section is aimed at developers who want to build on top of the Fira Protocol — whether you are a DeFi aggregator routing swaps, a lending protocol using Fira yield tokens as collateral, or a front-end displaying position data.

{% hint style="info" %}
All Fira contracts are deployed on Ethereum mainnet. See [Deployment](/developers/deployment) for addresses.
{% endhint %}

## Quick start

### 1. Identify the entry point

| Goal                            | Contract    | Key interface                   |
| ------------------------------- | ----------- | ------------------------------- |
| Wrap USDC into yield-bearing FW | USDCFW      | `IFiraWrappedStandardized`      |
| Swap BT ↔ FW                    | FiraMarket  | `IPMarket`                      |
| Mint / redeem BT + CT           | CouponToken | `IBCToken`                      |
| Add / remove LP liquidity       | FiraRouter  | `IPActionAddRemoveLiqV3`        |
| Borrow at fixed rate            | FiraRouter  | `IPActionBorrow`                |
| Read market state & oracle      | FiraMarket  | `IPMarket.readState`, `observe` |

### 2. Approve tokens

All Fira entry points pull tokens from `msg.sender` via `transferFrom`. Before calling any state-mutating function, approve the target contract (or the Router) for the relevant ERC-20.

### 3. Use the Router or call contracts directly

The **FiraRouter** aggregates most user-facing actions behind a single address with typed facet interfaces. Integrators can:

* Call **Router facets** for complex multi-step flows (swap + borrow, add liquidity with single-sided input, etc.).
* Call **individual contracts** (FiraMarket, USDCFW, CouponToken) directly for simpler interactions.

{% hint style="warning" %}
If calling FiraMarket swap functions directly (not via Router), you must implement the `IPMarketSwapCallback` interface. The market uses a flash-callback pattern: it transfers tokens to you first, then calls your callback to pull payment.
{% endhint %}

## Common patterns

### Reading prices and rates

```solidity
// Current FW exchange rate (1e18 scale)
uint256 rate = IFiraWrappedStandardized(fw).exchangeRate();

// Market state including implied rate, reserves, TWAP
MarketState memory state = IPMarket(market).readState(router);

// BC Index (yield accrual factor for CT)
uint256 bcIndex = IBCToken(ct).bcIndexCurrent();

// TWAP observations (array of secondsAgo offsets)
uint32[] memory secs = new uint32[](2);
secs[0] = 1800; // 30 min ago
secs[1] = 0;    // now
uint216[] memory cumRates = IPMarket(market).observe(secs);
```

### Previewing deposits and redeems

```solidity
// How many FW shares for a given USDC deposit
uint256 fwOut = IFiraWrappedStandardized(fw).previewDeposit(usdc, amount);

// How much USDC for redeeming a given amount of FW
uint256 usdcOut = IFiraWrappedStandardized(fw).previewRedeem(usdc, fwAmount);
```

### Checking expiry

```solidity
bool expired = IPMarket(market).isExpired();
uint256 expiryTs = IPMarket(market).expiry();
```

Post-expiry, BT redeems 1:1 for FW and CT stops accruing. LP positions should be exited before expiry for optimal value.

## Amount conventions

* **FW, BT, CT amounts** — Native token decimals (matching the underlying, e.g. 6 for USDC-backed FW).
* **Exchange rates, indices, proportions** — 1e18 fixed-point.
* **Signed integers (`int256`)** — Used for swap amounts. Negative = paying, positive = receiving.
* **Slippage** — Always the caller's responsibility via `minOut` / `minSharesOut` parameters. The contracts will revert if the minimum is not met.

## Pages

* [Interfaces & API Surface](/developers/integrations/interfaces) — Complete reference of all Fira interfaces, grouped by module


# Interfaces

Complete reference of all Fira Protocol Solidity interfaces, grouped by module, with key function signatures and type definitions.

All interfaces live in `src/interfaces/`. They are the canonical reference for integrators.

## FW (Fira Wrapped)

### IFiraWrappedStandardized

The yield-bearing wrapper token (e.g. USDCFW wrapping USDC into a SisuVault).

```solidity
function deposit(address receiver, address tokenIn, uint256 amountTokenToDeposit, uint256 minSharesOut)
    external payable returns (uint256 amountSharesOut);

function redeem(address receiver, uint256 amountSharesToRedeem, address tokenOut, uint256 minTokenOut, bool burnFromInternalBalance)
    external returns (uint256 amountTokenOut);

function exchangeRate() external view returns (uint256);
function previewDeposit(address tokenIn, uint256 amountTokenToDeposit) external view returns (uint256);
function previewRedeem(address tokenOut, uint256 amountSharesToRedeem) external view returns (uint256);
function claimRewards(address user) external returns (uint256[] memory);
function accruedRewards(address user) external view returns (uint256[] memory);
function getTokensIn() external view returns (address[] memory);
function getTokensOut() external view returns (address[] memory);
function assetInfo() external view returns (AssetType, address, uint8);
```

## Market

### IPMarket

The BT/FW AMM pool. Also an ERC-20 (LP token).

```solidity
function mint(address receiver, uint256 netFwDesired, uint256 netBtDesired)
    external returns (uint256 netLpOut, uint256 netFwUsed, uint256 netBtUsed);

function burn(address receiverFw, address receiverBt, uint256 netLpToBurn)
    external returns (uint256 netFwOut, uint256 netBtOut);

function swapExactBtForFw(address receiver, uint256 exactBtIn, bytes calldata data)
    external returns (uint256 netFwOut, uint256 netFwFee);

function swapFwForExactBt(address receiver, uint256 exactBtOut, bytes calldata data)
    external returns (uint256 netFwIn, uint256 netFwFee);

function readState(address router) external view returns (MarketState memory);
function readTokens() external view returns (IFiraWrappedStandardized, IBondToken, IBCToken);
function observe(uint32[] memory secondsAgos) external view returns (uint216[] memory);
function isExpired() external view returns (bool);
function expiry() external view returns (uint256);
```

### IPMarketFactoryV3

```solidity
function createNewMarket(address BT, int256 scalarRoot, int256 initialAnchor, uint80 lnFeeRateRoot)
    external returns (address market);
function isValidMarket(address market) external view returns (bool);
```

### IPMarketSwapCallback

Implement this if calling FiraMarket swap functions directly (not via Router).

```solidity
function swapCallback(int256 btToAccount, int256 fwToAccount, bytes calldata data) external;
```

## Yield contracts

### IBondToken

Fixed-rate principal token. ERC-20 with restricted mint/burn.

```solidity
function mint(address to, uint256 amount) external;
function burn(address from, uint256 amount) external;
```

### IBCToken (CouponToken)

Floating-yield token with interest accrual. Inherits `IPInterestManagerCT`.

```solidity
function mintBC(address receiverBT, address receiverCT) external returns (uint256 amountBCOut);
function redeemBC(address receiver) external returns (uint256 amountFwOut);
function redeemDueInterestAndRewards(address user, bool redeemInterest, bool redeemRewards)
    external returns (uint256 interestOut, uint256[] memory rewardsOut);
function bcIndexCurrent() external returns (uint256);
function bcIndexStored() external view returns (uint256);
function isExpired() external view returns (bool);
function expiry() external view returns (uint256);
function FW() external view returns (address);
function BT() external view returns (address);
```

### IBCContractFactory

```solidity
function createBCContract(address fw, uint256 expiry) external returns (address BT, address CT);
```

## Router facets

### IPActionSwapBTV3

```solidity
function swapExactBtForFw(address receiver, address market, uint256 exactBtIn, TokenOutput calldata output, LimitOrderData calldata limit)
    external returns (uint256 netFwOut, uint256 netFwFee);

function swapExactFwForBt(address receiver, address market, uint256 exactFwIn, ApproxParams calldata guessBtOut, TokenInput calldata input, LimitOrderData calldata limit)
    external returns (uint256 netBtOut, uint256 netFwFee);
```

### IPActionSwapCTV3

```solidity
function swapExactFwForCt(address receiver, address market, uint256 exactFwIn, TokenInput calldata input, ApproxParams calldata guessCTOut, LimitOrderData calldata limit)
    external returns (uint256 netCtOut, uint256 netFwFee);

function swapExactCtForFw(address receiver, address market, uint256 exactCtIn, TokenOutput calldata output, LimitOrderData calldata limit)
    external returns (uint256 netFwOut, uint256 netFwFee);
```

### IPActionAddRemoveLiqV3

```solidity
function addLiquidityDualFwAndBt(address receiver, address market, TokenInput calldata input, uint256 netBtDesired, uint256 minLpOut)
    external returns (uint256 netLpOut, uint256 netFwUsed, uint256 netBtUsed);

function removeLiquidityDualFwAndBt(address receiver, address market, uint256 netLpToRemove, TokenOutput calldata output, uint256 minBtOut)
    external returns (uint256 netFwOut, uint256 netBtOut);
```

### IPActionMiscV3

```solidity
function mintBcFromFw(address receiver, address CT, uint256 netFwIn, uint256 minBcOut)
    external returns (uint256 netBcOut);

function redeemBcToFw(address receiver, address CT, uint256 netBcIn, TokenOutput calldata output)
    external returns (uint256 netFwOut);

function redeemDueInterestAndRewards(address receiver, address[] calldata CTs, address[] calldata FWs, address[] calldata markets)
    external;

function exitPreExpiry(address receiver, address market, uint256 netBtIn, uint256 netCtIn, uint256 netLpIn, TokenOutput calldata output)
    external returns (uint256 totalFwOut);

function exitPostExpiry(address receiver, address market, uint256 netBtIn, uint256 netCtIn, uint256 netLpIn, TokenOutput calldata output)
    external returns (uint256 totalFwOut);

function multicall(bytes[] calldata data) external payable returns (bytes[] memory results);
```

### IPActionBorrow

```solidity
function borrow(address market, MarketParams calldata marketParams, uint256 amount, uint256 shares, address onBehalf, address receiver)
    external returns (uint256 assetsOut, uint256 sharesOut);

function repay(address market, MarketParams calldata marketParams, uint256 amount, uint256 shares, address onBehalf, bytes calldata data)
    external returns (uint256 assetsRepaid, uint256 sharesRepaid);
```

### IPActionSimple

On-chain approximation variants that avoid the need for off-chain `ApproxParams` computation.

```solidity
function swapExactFwForBtSimple(address receiver, address market, uint256 exactFwIn, uint256 minBtOut)
    external returns (uint256 netBtOut, uint256 netFwFee);

function addLiquiditySingleFwSimple(address receiver, address market, uint256 netFwIn, uint256 minLpOut)
    external returns (uint256 netLpOut);
```

## Shared types (IPAllActionTypeV3)

```solidity
struct TokenInput {
    address tokenIn;
    uint256 netTokenIn;
    address tokenMintFw;
    address firaSwap;
    SwapData swapData;
}

struct TokenOutput {
    address tokenOut;
    uint256 minTokenOut;
    address tokenRedeemFw;
    address firaSwap;
    SwapData swapData;
}

struct ApproxParams {
    uint256 guessMin;
    uint256 guessMax;
    uint256 guessOffchain;
    uint256 maxIteration;
    uint256 eps;
}

struct SwapData {
    SwapType swapType;
    address extRouter;
    bytes extCalldata;
    bool needScale;
}
```

## Utility interfaces

### IRehypothecationModule

```solidity
function rebalance() external;
function phiMin() external view returns (uint256);
function phiMax() external view returns (uint256);
function phiTarget() external view returns (uint256);
```

### ILiquidityInjector

```solidity
function injectLiquidity(uint256 btAmount, uint256 fwAmount) external returns (uint256 lpOut);
function withdrawLiquidity(uint256 lpAmount) external returns (uint256 fwOut, uint256 btOut);
```

### IOracle

```solidity
function price() external view returns (uint256);
```


# Security Practices

Security overview for the Fira Protocol, covering multi-layered defences baked into every contract layer.

## Security approach

### Multi-layered security strategy

1. **Secure development practices** — All Fira contracts follow battle-tested Solidity patterns from OpenZeppelin, with strict adherence to the checks-effects-interactions pattern and consistent use of custom errors for gas-efficient revert reasons.
2. **Access control** — Sensitive state changes are gated behind `BoringOwnableUpgradeable` ownership checks at the contract level and role-based function selectors in the Router facet architecture.
3. **Reentrancy protection** — State-mutating entry points in FWBase, FiraMarket, CouponToken, and the LiquidityInjector are protected by OpenZeppelin's `ReentrancyGuard` (`nonReentrant` modifier).
4. **Pause controls** — FW token contracts implement `whenNotPaused` guards, allowing the owner to freeze deposits and redemptions during incidents without requiring a contract upgrade.
5. **Upgrade mechanisms** — Contracts use the `Initializable` pattern with upgradeable proxies, enabling hotfixes while preserving storage layout. The Router uses a diamond-like facet system with versioned selectors.
6. **Oracle safety** — A multi-layer oracle pipeline (Aave → Chainlink adapter → Fira solvency oracle → BC/LP oracle) provides defence-in-depth for price feeds, with staleness checks at every layer.
7. **Continuous monitoring** — On-chain events are designed for real-time indexing, supporting anomaly detection across all role buckets (see [Events & Indexing](/developers/events-and-indexing)).

{% hint style="info" %}
For detailed information on each security mechanism and how it applies across the contract stack, see [Security Design](/developers/security-and-audits/security-practices).
{% endhint %}

## Pages

* [Security Design](/developers/security-and-audits/security-practices) — In-depth coverage of access control, reentrancy, pause, and upgrade patterns
* [Audits](/developers/security-and-audits/audits) — Chronological overview of completed security audits


# Security Design

In-depth coverage of the security patterns and invariants enforced across the Fira Protocol smart contract stack.

## Access control

### Ownership model

All privileged Fira contracts inherit `BoringOwnableUpgradeable`, which provides:

* Single `owner` with a two-step transfer (`transferOwnership` → `claimOwnership`) to prevent accidental misassignment.
* `onlyOwner` modifier gating admin functions (pause, parameter updates, upgrades).

### Router selector guards

The `FiraRouterV4` uses a diamond-like facet dispatch table. Each facet registers its function selectors during `initialize()`. Calls to unregistered selectors revert with `Errors.RouterInvalidAction`. This ensures that only explicitly whitelisted facets can be invoked through the Router.

### Minting privileges

BondToken and CouponToken restrict `mintBC()` and `redeemBC()` to the `YieldContractFactory` address set at initialization, preventing arbitrary minting.

The LiquidityInjector holds a separate minting privilege on BondToken via the `LIQUIDITY_INJECTOR` role, constrained by the `injectLiquidityLimit` cap.

## Reentrancy protection

Fira applies the `nonReentrant` modifier (OpenZeppelin `ReentrancyGuard`) to all external state-mutating functions across:

| Contract                  | Protected functions                                                 |
| ------------------------- | ------------------------------------------------------------------- |
| **FWBase**                | `deposit`, `redeem`, `claimRewards`                                 |
| **FiraMarket**            | `mint`, `burn`, `swapExactBtForFw`, `swapFwForExactBt`              |
| **CouponToken**           | `mintBC`, `redeemBC`, `redeemInterest`, `redeemInterestAndTransfer` |
| **LiquidityInjector**     | `injectLiquidity`, `withdrawLiquidity`                              |
| **RehypothecationModule** | `rebalance`                                                         |

The Router's `_safeTransferWithFeeExtraction` and callback patterns (flash swaps) are additionally protected by the facet-level lock state in `ActionStorageV4`.

## Pause controls

FW token contracts (`FWBase`, `USDCFW`) inherit OpenZeppelin's `PausableUpgradeable`:

* **`pause()`** — Owner freezes all deposit and redeem operations.
* **`unpause()`** — Owner resumes normal operations.
* **`whenNotPaused`** modifier — Applied to `deposit()`, `redeem()`, and related transfer functions.

{% hint style="warning" %}
Pause does not affect BT/CT trading on FiraMarket. Market operations remain available to allow users to exit positions even during an FW pause.
{% endhint %}

## Upgrade patterns

### Initializable contracts

All upgradeable contracts use OpenZeppelin's `Initializable` with `initializer` / `reinitializer(n)` modifiers to prevent double-initialization attacks.

### Router versioning

The Router facet system supports additive upgrades:

1. Deploy a new facet contract.
2. Call `Router.addToSelectorMapping(selectors, facetAddress)` to register new selectors.
3. Existing selectors can be overwritten to point to the new facet, enabling in-place upgrades without redeploying the Router proxy.

Old facets remain deployed on-chain but become unreachable once their selectors are reassigned.

### Storage layout safety

Upgradeable contracts follow the "storage gap" convention and use dedicated storage slots (e.g., `ActionStorageV4.STORAGE_SLOT`) to avoid slot collisions across upgrades.

## Oracle defence-in-depth

The Fira oracle pipeline stacks multiple validation layers:

```
Aave V3 Oracle
      ↓
AaveToChainlinkAdapter  (normalizes to Chainlink AggregatorV3 interface)
      ↓
ChainlinkOracleV2       (staleness check, sequencer-down check on L2)
      ↓
FiraSolvencyOracle      (solvency ratio validation)
      ↓
BCLpOracle              (fair LP token pricing using BT/FW spot + TWAP)
```

Each layer can reject stale or invalid data independently. `ChainlinkOracleV2` enforces a configurable `heartbeat` and reverts with `StalePrice` if the feed has not updated within the window.

## Fixed-point arithmetic safety

All yield and pricing math uses the `PMath` and `LogExpMath` libraries with 18-decimal fixed-point representation. Key invariants:

* **No division by zero** — All divisors are checked or guaranteed non-zero by prior validation.
* **Overflow protection** — Solidity 0.8.x built-in overflow checks apply; `LogExpMath` additionally validates input ranges before exponentiation.
* **Rounding direction** — Deposit/mint operations round against the user (ceiling); redeem/burn operations round in favor of the protocol (floor), preventing rounding exploits.

## Contract size management

Several Fira contracts approach the EIP-170 24 KB limit. The codebase uses two mitigation strategies:

1. **Library extraction** — Heavy logic is moved to external libraries (e.g., `MarketMathCore`, `MarketApproxPtInLib`) that are deployed separately and linked via `DELEGATECALL`.
2. **Split-code deployment** — The `FiraMarket` factory uses a two-part deployment (`MarketMathCore` + `FiraMarketV3`) to keep each deployment unit under the size limit.

## Invariants summary

| Invariant                                        | Enforced by                                      |
| ------------------------------------------------ | ------------------------------------------------ |
| FW exchange rate monotonically non-decreasing    | `FWBase._afterUpdateBCIndex` + rehyp rebalance   |
| BT total supply = minted via Factory + LI inject | `BondToken.mintBC` access control                |
| CT interest accrual ≥ 0                          | `CouponToken._updateAndDistributeInterest`       |
| LP pool BT + FW reserves ≥ total LP supply       | FiraMarket mint/burn invariant checks            |
| Rehyp ratio stays within `[phiMin, phiMax]`      | `RehypothecationModule.rebalance` bounds check   |
| Lending market solvency                          | LendingMarket liquidation + oracle health checks |


# Audits

For the complete list of audits, reports, and security review details, see the main audits page:

{% content-ref url="/pages/oenfd7rHc2cwBFvk47KD" %}
[Audits](/security-and-risk/audits)
{% endcontent-ref %}


# Glossary

Definitions of key terms, abbreviations, and concepts used throughout the Fira Protocol documentation.

## Protocol tokens

| Term                  | Definition                                                                                                                                                                                                            |
| --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **FW (Fira Wrapped)** | An ERC-20 yield-bearing wrapper token. FW wraps an underlying asset (e.g. USDC) through a SisuVault and appreciates over time as yield accrues. The canonical implementation is USDCFW.                               |
| **BT (Bond Token)**   | A fixed-rate principal token. Each BT is redeemable 1:1 for FW at expiry. Before expiry, BT trades at a discount on the FiraMarket AMM — the discount determines the implied fixed rate.                              |
| **CT (Coupon Token)** | A floating-yield token. CT holders receive the yield generated by the underlying FW between now and expiry. CT accrues interest continuously via the BC Index. BT and CT are always minted and burned in equal pairs. |
| **LP Token**          | The ERC-20 token representing a liquidity provider's share of a FiraMarket BT/FW pool.                                                                                                                                |
| **mkUSDC**            | The SisuVault share token (Markov USDC Prime). Represents a pro-rata claim on the vault's total USDC assets.                                                                                                          |

## Core concepts

| Term                                   | Definition                                                                                                                                                                                                                |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **BC Index**                           | The yield accrual factor for CT. It tracks the cumulative exchange rate growth of the underlying FW since the CT was created. `bcIndexCurrent()` returns the live value; `bcIndexStored()` returns the last cached value. |
| **Exchange rate**                      | The ratio of underlying assets to FW shares. Monotonically non-decreasing. `exchangeRate() = totalAssets / totalFwSupply`, scaled to 1e18.                                                                                |
| **Expiry**                             | The UNIX timestamp at which BT becomes redeemable 1:1 for FW and CT stops accruing yield. All BT, CT, and FiraMarket pools share the same expiry within a market set.                                                     |
| **Implied rate**                       | The annualised fixed rate implied by the BT/FW price on the AMM. Derived from the logit pricing curve. A lower BT price implies a higher fixed rate.                                                                      |
| **TWAP (Time-Weighted Average Price)** | A manipulation-resistant price average computed from on-chain oracle observations. FiraMarket stores cumulative `lnImpliedRate` observations that can be queried via `observe()`.                                         |

## Architecture

| Term                          | Definition                                                                                                                                                              |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **FiraRouter / FiraRouterV4** | The main entry point for users. A diamond-like proxy that delegates calls to specialised facets (swap, liquidity, borrow, misc).                                        |
| **Facet**                     | A standalone contract containing a subset of the Router's logic. The Router dispatches to facets based on function selector mappings.                                   |
| **FiraMarket**                | The BT/FW AMM pool. Uses a time-decaying logit pricing curve. Also serves as the LP token contract.                                                                     |
| **SisuVault**                 | An ERC-4626 vault that aggregates USDC across variable-rate lending markets and other yield sources. FW deposits are routed into the vault.                             |
| **YieldContractFactory**      | Deploys BT/CT pairs for a given FW token and expiry. Controls minting privileges and fee/treasury configuration.                                                        |
| **FiraMarketFactory**         | Deploys FiraMarket AMM pools and validates market addresses.                                                                                                            |
| **LiquidityInjector (LI)**    | Bootstraps fixed-rate markets by minting unbacked BT and pairing it with FW to provide initial AMM liquidity. The sole whitelisted BT supplier to FiraLendingMarket.    |
| **RehypothecationModule**     | Manages the split between idle reserves in FW and deployed capital in the SisuVault. Maintains the reserve ratio within `[phiMin, phiMax]` by triggering `rebalance()`. |

## Lending

| Term                       | Definition                                                                                                                                                                                                                   |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Fixed-rate lending**     | Borrowing where BT is the loan token. The borrower supplies Pendle PT tokens as collateral, borrows BT, swaps BT for FW, and redeems FW for USDC. The discount at which BT was acquired determines the effective fixed rate. |
| **Variable-rate lending**  | Borrowing USDC from the SisuVault at a floating rate set by the AdaptiveCurveIrm. Collateral types include wstETH and cbBTC.                                                                                                 |
| **LTV (Loan-to-Value)**    | The maximum ratio of borrowed value to collateral value. Exceeding LTV prevents new borrows.                                                                                                                                 |
| **LLTV (Liquidation LTV)** | The threshold at which a position becomes eligible for liquidation. Always slightly above LTV.                                                                                                                               |
| **MarketParams**           | A struct identifying a lending market: `(loanToken, collateralToken, oracle, irm, lltv)`. The market ID is the keccak256 hash of this struct.                                                                                |
| **AdaptiveCurveIrm**       | The interest rate model for variable-rate markets. Adjusts rates based on utilisation using a sigmoid curve.                                                                                                                 |
| **Maturity Grace Period**  | A window after BT expiry during which fixed-rate borrowers can repay without liquidation (24 hours).                                                                                                                         |

## Oracle

| Term                       | Definition                                                                                                                           |
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| **AaveToChainlinkAdapter** | Wraps an Aave V3 oracle price feed to expose the Chainlink `AggregatorV3Interface`, enabling reuse in the Fira oracle pipeline.      |
| **ChainlinkOracleV2**      | Consumes one or two Chainlink feeds, applies staleness checks and optional L2 sequencer-down checks, and returns a normalised price. |
| **FiraSolvencyOracle**     | Validates solvency ratios for fixed-rate markets. Sits between ChainlinkOracleV2 and the LendingMarket.                              |
| **BCLpOracle**             | Computes fair prices for BC (BT+CT) and LP tokens using FiraMarket spot and TWAP data.                                               |

## Math & utilities

| Term               | Definition                                                                                                                       |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| **PMath**          | Fira's fixed-point math library. Operates on 1e18-scaled `uint256` values for multiplication, division, and comparison.          |
| **LogExpMath**     | Provides `ln()` and `exp()` functions for 1e18-scaled integers. Used by the logit pricing curve in the AMM.                      |
| **MarketMathCore** | Core AMM math library implementing the time-decaying logit curve, swap calculations, and implied rate derivation.                |
| **scalarRoot**     | A market parameter controlling the steepness of the logit pricing curve. Higher values produce a flatter curve (tighter spread). |
| **initialAnchor**  | The initial anchor point for the logit curve, representing the implied exchange rate at market creation.                         |
| **lnFeeRateRoot**  | The natural log of the base swap fee rate. Applied to the FW side of every swap.                                                 |

## Events & indexing

| Term                            | Definition                                                                                                                                                                         |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Role bucket**                 | One of 8 position categories used to measure user exposure across Fira markets: BFR, BT, CT, LP, VRB, VRL, USLC, USLL. Used for analytics and potential future incentive programs. |
| **Epoch**                       | A time window (typically one week) over which TWAP exposures are measured for position tracking and analytics.                                                                     |
| **Piecewise-constant position** | A position value that remains constant between on-chain events. The indexer reconstructs the TWAP by integrating these constant segments over the epoch.                           |

## Standards

| Term                | Definition                                                                                                                                          |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ERC-20**          | The standard fungible token interface. All Fira tokens (FW, BT, CT, LP) implement ERC-20.                                                           |
| **ERC-4626**        | The tokenized vault standard. SisuVault implements ERC-4626, providing `deposit`, `withdraw`, `convertToAssets`, and `convertToShares`.             |
| **EIP-170**         | The 24 KB contract size limit. Fira uses library extraction and split-code deployment to stay within this limit.                                    |
| **Diamond pattern** | A proxy architecture (EIP-2535) where a single proxy delegates to multiple implementation contracts (facets). FiraRouter uses a simplified variant. |


# Whitepaper

The whitepaper is a full detailed explanation of the methodology, mechanics and motivation behind the protocol.

{% file src="/files/hF4xjK49F7m0m628v3XN" %}


# Contracts & Addresses

## Ethereum Mainnet Deployments

All smart contracts are deployed on Ethereum mainnet with verified source code. Contract ownership is assigned to designated multisig addresses for operational security.

### Core Protocol Addresses

| Role                     | Address                                      |
| ------------------------ | -------------------------------------------- |
| Deployer                 | `0x7Da82CBD315923d75dbb2C62F099392705FF97f9` |
| Treasury / Fee Recipient | `0x97fD565B913b439Ff16774Da152B1f71F05A82F1` |

## Core Contracts

### Lending Markets

| Contract                | Address                                      |
| ----------------------- | -------------------------------------------- |
| Variable LendingMarket  | `0xc8Db629192a96D6840e88a8451F17655880A2e4D` |
| Fixed FiraLendingMarket | `0x280ddD897F39C33fEf1CbF863B386Cb9a8e53a0e` |
| AdaptiveCurveIRM        | `0x73C288826347af3718e6F09c2A24AaFDA77684cD` |

### Router

| Contract      | Address                                      |
| ------------- | -------------------------------------------- |
| FiraRouterV4  | `0xFF615E63aAF2d1B1EE4AdFD34a5840747185d8A0` |
| ActionStorage | `0x0386685eA7d37c61dDb8F2e2E8c45f6a81d4A3C8` |

## Vaults

### Markov USDC Prime

| Field         | Value                                        |
| ------------- | -------------------------------------------- |
| Vault         | `0x50791a5cA041b9D6Dd03e64E3Fa0e34a376759AC` |
| Vault Factory | `0xe77E0f97A864558e5513209323e4169FcEAC6981` |
| Name          | Markov USDC Prime                            |
| Symbol        | mkUSDC                                       |
| Allocator     | `0x4E700A14868620a9Bba0669721F1945c410c7571` |
| Curator       | `0xc02B0D1ca7B986E63cf1599F9c32e8A96c2D4Cff` |
| Fee Recipient | `0x97fD565B913b439Ff16774Da152B1f71F05A82F1` |

## Token Contracts

### Wrapped Collateral Token

| Field                  | Value                                        |
| ---------------------- | -------------------------------------------- |
| Token                  | `0x62F5366C9E21A95326C461a098a408e034e017b3` |
| Name                   | Fira Wrapped USDC                            |
| Symbol                 | FW-USDC                                      |
| Rehypothecation Module | `0xad332515d9c82438BBa0e9FAA9486B52A33a7Ac8` |

## Factories

| Factory                  | Address                                      |
| ------------------------ | -------------------------------------------- |
| YieldContractFactory     | `0xcdB83Abb9121c04589567A4106C3cFaf65DB68Be` |
| FiraMarketFactory        | `0xBF1EfC2199ae9EE1B6f5060a45D4440157E49744` |
| ChainlinkOracleV2Factory | `0x7783fF7bE856C7A82bC5497Fb3CC8F7E8802D8dC` |

## Modules

| Module                | Address                                      |
| --------------------- | -------------------------------------------- |
| RehypothecationModule | `0xad332515d9c82438BBa0e9FAA9486B52A33a7Ac8` |
| LiquidityInjector     | `0x2104f638a839Ca7260180d9Ee7f4865C92Df4cE5` |

## Oracles

| Oracle       | Address                                      |
| ------------ | -------------------------------------------- |
| cbBTC / USDC | `0x698253A24CC4926090f841B38D31d6342A00a82C` |
| BCLpOracle   | `0xfEAAEC9124FB007d7c44Ed704A08d24b264de921` |
| bUSD0 UZR    | `0x30Da78355FcEA04D1fa34AF3c318BE203C6F2145` |

## Variable Rate Markets

### wstETH / USDC

Market ID

```
0xb3152ac00687cc9502b78ab452956f85cc89ac210deefda5dbff09f7f167b544
```

| Parameter        | Value                                        |
| ---------------- | -------------------------------------------- |
| LendingMarket    | `0xc8Db629192a96D6840e88a8451F17655880A2e4D` |
| Loan Token       | `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` |
| Collateral Token | `0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0` |
| Oracle           | `0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2` |
| IRM              | `0x73C288826347af3718e6F09c2A24AaFDA77684cD` |
| LTV              | 87%                                          |
| LLTV             | 89%                                          |

### cbBTC / USDC

Market ID

```
0x39d3bdd30bf4bcf4a4d3547f2484abe1e30a2dcd41ed83788b40e2720357ab76
```

| Parameter        | Value                                        |
| ---------------- | -------------------------------------------- |
| LendingMarket    | `0xc8Db629192a96D6840e88a8451F17655880A2e4D` |
| Loan Token       | `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48` |
| Collateral Token | `0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf` |
| Oracle           | `0x698253A24CC4926090f841B38D31d6342A00a82C` |
| IRM              | `0x73C288826347af3718e6F09c2A24AaFDA77684cD` |
| LTV              | 88%                                          |
| LLTV             | 90%                                          |

## Market ID Verification

Market IDs are computed deterministically using:

```solidity
bytes32 id = keccak256(
abi.encode(
    loanToken,
    collateralToken,
    oracle,
    irm,
    ltv,
    lltv,
    whitelist
));
```

Users can reproduce this calculation using Foundry (chisel) or other Solidity tooling to verify market identifiers.


# Glossary

## Protocol-Specific Terms

| Term                  | Definition                                                                                                                            |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| **BT (Bond Token)**   | ERC-20 zero-coupon bond that redeems 1:1 into the underlying asset at expiry. Traded in the AMM, borrowed/lent in the lending market. |
| **CT (Coupon Token)** | ERC-20 token that tracks all interest/yield due on a given BT line. CT holders accrue interest/rewards from the underlying yield.     |
| **FW (FiraWrapped)**  | Yield-bearing wrapper for underlying assets. The base unit of account in Fira markets. Mintable and redeemable frictionlessly.        |

## Technical Terms

| Term                             | Definition                                                                                              |
| -------------------------------- | ------------------------------------------------------------------------------------------------------- |
| **LTV (Loan-to-Value)**          | Ratio of debt to collateral value. UZR uses 88% LTV.                                                    |
| **LLTV (Liquidation LTV)**       | Threshold above which positions become eligible for liquidation.                                        |
| **IRM (Interest Rate Model)**    | Smart contract that determines borrowing rates. UZR uses a fixed rate IRM at 0.10% APR.                 |
| **AMM (Automated Market Maker)** | Decentralized exchange mechanism used for BT trading in Fira V1.                                        |
| **Maturity**                     | The date at which a BT redeems at par (1:1 with underlying).                                            |
| **Par Value**                    | The face value of a BT at maturity (1 underlying).                                                      |
| **Discount**                     | The difference between current BT price and par value. This discount represents the implied fixed rate. |
| **Rehypothecation**              | Reuse of deposited liquidity in secondary markets (variable-rate vaults).                               |
| **Health Factor**                | Metric indicating how close a position is to liquidation.                                               |


# Integrations

## Analytics and Dashboards

### DeFiLlama

Fira is listed on DeFiLlama for TVL tracking and protocol analytics.

### Dune Dashboard

Steady Labs maintains a dedicated Dune Analytics dashboard for Fira metrics and on-chain data:

* **Dune Dashboard**: <https://dune.com/usual_team/fira>

## Protocol Integrations

*This section will be expanded as additional DeFi integrations are established.*


# Terms of Use

**Version: 01/13/2026**

***

## 1. Purpose – Acceptance

**1.1** These Terms of Use (the "Terms") govern access to and use of:

* (i) the website
* (ii) the front-end application and/or APIs
* (iii) the content/documentation made available

(together, the "Services")

**1.2** By clicking "Accept", connecting a wallet, or using the Services, you acknowledge that you have read, understood, and accepted these Terms and the [Risks & Security](/security-and-risk/risk-disclaimers) documentation, which is incorporated by reference.

**1.3** If you do not agree, do not use the Services.

***

## 2. Definitions

| Term               | Definition                                                                                                  |
| ------------------ | ----------------------------------------------------------------------------------------------------------- |
| **Fira Protocol**  | The set of smart contracts deployed on one or more public blockchains enabling lending/borrowing operations |
| **Fira Interface** | The front-end and/or API that allows you to submit transactions to the Protocol                             |
| **USDC**           | A third-party stablecoin (issued and administered by a third party)                                         |
| **FW**             | The wrapped form used by Fira as the unit of account                                                        |
| **BT**             | Synthetic tokens associated with borrowing, designed to converge to 1 FW at maturity                        |
| **CT**             | Tokens representing an economic claim on the "interest/coupon" component arising from the pool structure    |
| **Maturity**       | The pool/market expiry at which certain conversions/redemptions may apply                                   |
| **User / You**     | Any person accessing or using the Services                                                                  |
| **Wallet**         | A self-custodial wallet (EOA or smart wallet) controlled by you                                             |

***

## 3. Services Description – Scope

**3.1** The Services primarily provide:

* (a) an interface to read information
* (b) a way to submit transactions to the Protocol through your Wallet

**3.2** **Non-custodial:** You retain control of your private keys and Wallet at all times. The Fira Interface Operator does not hold your assets, cannot initiate transactions on your behalf, and cannot reverse a transaction confirmed on a blockchain.

**3.3** **Protocol ≠ Operator:** Unless expressly stated, the Fira Interface Operator does not guarantee the continuous operation of any blockchain network, oracle, bridge, third-party token, or the availability of any smart contract.

**3.4** Information displayed (rates, prices, APY, health metrics, etc.) is indicative and may be delayed, inaccurate, or incomplete.

***

## 4. Nature of Information – No Advice

**4.1** Nothing in the Services constitutes financial, investment, credit, legal, tax, or accounting advice, nor any personalized recommendation.

**4.2** You are solely responsible for your decisions and your own risk assessment, including whether the Protocol is appropriate for you.

**4.3** You acknowledge that crypto-assets and DeFi involve volatility and risks that may not be suitable for all users.

***

## 5. Eligibility – Sanctions – Restricted Jurisdictions

**5.1** You represent that you are of legal age and have the legal capacity to use the Services.

**5.2** You represent that you are:

* Not located, resident, incorporated, or acting on behalf of a person located in a Restricted Jurisdiction
* Not subject to sanctions (OFAC, EU, UN, UK, etc.), and not listed on any sanctions list

:::danger\[Restricted Jurisdictions] Afghanistan, Albania, Angola, Azerbaijan, Bosnia Herzegovina, Bahamas, Barbados, Burma, Botswana, Burkina Faso, Burundi, Cambodia, Cameroon, Crimea (Ukraine), Chad, China, Congo, Democratic Republic of Congo, Cuba, Ethiopia, Eritrea, Fiji, Palau, Ghana, Guinea, Guinea-Bissau, Haiti, Iran, Iraq, Jamaica, Jordan, Lao People's Democratic Republic, Uganda, Liberia, Libya, Madagascar, Mali, Malta, Morocco, Mozambique, Nicaragua, Nigeria, North Korea, Pakistan, Panama, Philippines, Puerto Rico, Russia, Senegal, Somalia, Sri Lanka, Sudan, Syria, Tajikistan, Trinidad and Tobago, Turkey, Turkmenistan, **United States**, Uzbekistan, Vanuatu, Venezuela, Virgin Islands, Yemen, Zimbabwe, and any resident or national of a country otherwise subject to a U.S. Government embargo. :::

**5.3** Any attempt to circumvent restrictions (VPN, proxy, etc.) may result in restriction or suspension of access.

***

## 6. Economic Mechanics (Key Reminders)

**6.1** **Wrapping:** Fira V1 uses USDC and operates with FW-USDC (wrap/unwrap) for certain operations.

**6.2** **Borrowing:** Borrowing may involve minting BT-USDC against collateral and swapping BT-USDC→FW-USDC at a discount. The economic cost is embedded in that discount.

**6.3** **Fixed-maturity "fixed rate":** Predictability is designed for holding until maturity; early repayment may change the effective cost.

***

## 7. Fees

**7.1** **Network fees:** You pay blockchain transaction fees (gas), which are non-refundable.

**7.2** **Protocol/third-party fees:** Certain markets may include fees (swaps, liquidations, performance/management, bridges, etc.) set on-chain or by third parties.

**7.3** Any displayed fees/rates are indicative; you must verify details before signing.

***

## 8. Assumption of Risk

**8.1** By using the Services, you acknowledge and accept the risks described in [Risks & Security](/security-and-risk/risk-disclaimers).

**8.2** This documentation is not exhaustive; other known or unknown risks may exist.

***

## 9. User Obligations

**9.1** Secure your private keys/seed phrase, devices, access, and approvals.

**9.2** Verify smart contract addresses, networks, tokens, amounts, and recipients before signing.

**9.3** Do not use the Services for illegal activity (money laundering, terrorist financing, fraud, etc.).

**9.4** Do not attempt to attack, exploit, reverse engineer, or interfere with the Services/contracts.

***

## 10. Third-Party Services – Dependencies

**10.1** The Services may rely on third parties (RPCs, oracles, bridges, analytics, wallets, DEXs, protocols used for rehypothecation, etc.).

**10.2** Such third parties have their own terms and may fail, be compromised, or change rules. The Fira Interface Operator is not responsible for them.

***

## 11. Intellectual Property – License

**11.1** Unless otherwise indicated, the Interface content is protected (branding, UI, text, etc.).

**11.2** A limited, revocable, non-exclusive license is granted to you to use the Services in compliance with these Terms.

**11.3** Smart contracts may be open-source under specific licenses.

***

## 12. Disclaimer of Warranties

**12.1** The Services are provided "as is" and "as available."

**12.2** No warranties are given regarding error-free operation, uptime, security, performance, solvency, liquidity, or returns.

***

## 13. Limitation of Liability

**13.1** To the maximum extent permitted by law, the Fira Interface Operator will not be liable for indirect damages (loss of profit, data, opportunity, etc.).

***

## 14. Indemnification

You agree to indemnify and hold harmless the Fira Interface Operator from any claim arising out of:

* (i) your breach of these Terms
* (ii) your illegal use of the Services
* (iii) your violation of applicable law

***

## 15. Suspension – Termination

**15.1** You may stop using the Services at any time.

**15.2** The Fira Interface Operator may suspend/restrict access (including for sanctions compliance, illegal activity, security risk, or legal obligations).

***

## 16. Governing Law – Dispute Resolution

**16.1** **Governing law:** France

**16.2** **Jurisdiction/Arbitration:** France

***

## Contact

**Interface Operator:** Steady Labs

**Email:** <support@fira.money>


# Privacy Policy

**Last Updated: 01/14/2026**

***

## 1. Who We Are

**ADDU** (hereinafter "ADDU", "we", "us" or "our") is a **French non-profit association** (Association loi 1901) governed by French law, with its registered office at:

**10 rue de la Paix, 75002 Paris, France**

ADDU operates websites and interfaces enabling access to certain functionalities related to digital assets and smart contracts (the "Services"), in particular through:

* fira.money
* app.fira.money

(together, the "Site")

***

## 2. Purpose of This Privacy Policy

This Privacy Policy explains:

* What personal data we collect
* Why and on what legal basis we process it
* With whom we share it
* How long we retain it
* Your GDPR rights and how to exercise them

***

## 3. Definitions

| Term              | Definition                                                                                                                                                                  |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Personal Data** | Any information relating to an identified or identifiable natural person (e.g., email address, IP address, online identifier, a wallet address if it can identify a person) |
| **Processing**    | Any operation performed on personal data (collection, storage, consultation, deletion, etc.)                                                                                |
| **Controller**    | The entity that determines the purposes and means of the processing (ADDU for the processing described here, except for blockchain processing)                              |

***

## 4. Eligibility (Minors)

The Services are not intended for individuals under 18 and we do not knowingly collect personal data from children. If we become aware that a minor has provided us with personal data, we will delete it as soon as reasonably possible, subject to our legal obligations.

***

## 5. What Data Do We Collect?

### 5.1 Data You Provide to Us

* **Identity and contact data:** first and last name, email address, nationality (if provided)
* **Communications:** content of messages sent to our support (e.g., feedback, questions, job applications, requests)

### 5.2 Technical and Usage Data

* **Connection data:** IP address, logs, date/time, browser information
* **Device and configuration data:** version, time zone, settings, language
* **Audience and performance measurement:** technical errors, interactions with the Site, usage events

### 5.3 Web3-Related Data

Depending on how the dApp operates, we may process:

* Wallet address(es) (public key)
* Transaction identifiers (hash)
* Network
* Relevant smart contract(s)
* Data necessary for operations, security, and support

:::note Some of this information may also exist on-chain (see Section 10). :::

### 5.4 Cookies and Trackers

We use cookies and similar technologies (see Section 11).

***

## 6. Why Do We Process Your Data?

In accordance with the GDPR, we process personal data only when we have a legal basis.

### Main Purposes

| Purpose                                           | Data                                     | Legal Basis                                              |
| ------------------------------------------------- | ---------------------------------------- | -------------------------------------------------------- |
| Support and Communications                        | Name, email, communications content      | Performance of contract / Legitimate interests / Consent |
| Providing, Maintaining and Improving the Services | Technical data, logs, usage events       | Legitimate interests / Performance of contract           |
| Security, Fraud and Abuse Prevention              | Logs, IP address, technical signals      | Legitimate interests / Legal obligations                 |
| Legal and Regulatory Compliance                   | Any data necessary                       | Legal obligation                                         |
| Non-Essential Cookies                             | Cookie identifiers, audience measurement | Consent                                                  |

***

## 7. Who Do We Share Your Data With?

### 7.1 Internal Recipients

Access is restricted to personnel who need to know (support, engineering, security).

### 7.2 Processors (Service Providers)

We may share data with service providers acting as processors (hosting, support tools, analytics if enabled, security tooling, communications).

### 7.3 Authorities and Legal Requirements

We may disclose data where required to do so by law.

### 7.4 Partners

If personal data is shared with corporate partners, such sharing must be limited and framed.

***

## 8. International Transfers

Your data may be processed outside the European Economic Area. Where that happens, we implement appropriate safeguards:

* Standard Contractual Clauses approved by the European Commission
* Additional measures where required (encryption, minimization, access controls)

***

## 9. Data Retention

We retain personal data only as long as necessary for the purposes described above.

| Data Type                 | Retention Period                                |
| ------------------------- | ----------------------------------------------- |
| Support/communications    | As long as needed + up to 5 years for archiving |
| Account/relationship data | 5 years after account closure                   |
| Transaction-related data  | 5 years from transaction date                   |
| Security logs             | A few months (unless incident requires longer)  |

:::warning\[Blockchain Data] Data recorded on a public blockchain may be non-erasable. :::

***

## 10. Blockchain-Specific Notice

:::danger\[Important] Public blockchains provide transaction transparency. Some information (e.g., wallet addresses, amounts, transaction hashes) may be recorded **permanently** on-chain. :::

ADDU does not control public blockchains (decentralized networks) and is not responsible for processing carried out by such networks nor for on-chain persistence.

As a result, certain rights (in particular erasure and rectification) may be technically limited for on-chain data.

**Recommendation:** Do not insert directly identifying personal data (e.g., name, email) into public transaction fields or metadata.

***

## 11. Cookies and Similar Technologies

### 11.1 What is a Cookie?

A cookie/tracker is a file or identifier stored/read on your device to enable technical functionality, measure audience, store preferences, etc.

### 11.2 Strictly Necessary Cookies (No Consent Required)

We may use technical cookies essential to operate the Site (e.g., session management, security, load balancing).

### 11.3 Non-Essential Cookies (Consent Required)

Analytics, advanced personalization, or advertising cookies (if used) generally require your prior consent.

***

## 12. Security

We implement reasonable technical and organizational measures to protect your data:

* Access controls
* Minimization
* Logging
* Backups
* Application security

:::note No method provides absolute security, and a residual risk cannot be entirely eliminated. :::

***

## 13. Your GDPR Rights

Subject to legal conditions and limitations, you have the right to:

| Right                        | Description                                        |
| ---------------------------- | -------------------------------------------------- |
| **Access**                   | Access your data                                   |
| **Rectification**            | Rectify your data                                  |
| **Erasure**                  | Erase your data (in certain cases)                 |
| **Restriction**              | Restrict processing                                |
| **Object**                   | Object to processing based on legitimate interests |
| **Portability**              | Data portability (where applicable)                |
| **Withdraw Consent**         | Withdraw consent at any time                       |
| **Post-mortem Instructions** | Under French law                                   |

:::warning\[Blockchain Limitation] The exercise of certain rights may be limited for on-chain data. :::

***

## 14. How to Exercise Your Rights

You may contact us:

**By email:** <support@fira.money>

**By post:** ADDU – 10 rue de la Paix, 75002 Paris, France

***

## 15. Complaints with a Supervisory Authority

If you believe your rights are not respected, you may lodge a complaint with the **CNIL** (France):

**CNIL – 3 Place de Fontenoy – TSA 80715 – 75334 Paris Cedex 07**

***

## 16. Third-Party Links

The Site may contain links to third-party websites. We do not control those sites and this Privacy Policy does not apply to them.

***

## 17. Changes to This Privacy Policy

We may update this Privacy Policy at any time. Where changes are material, we will post a notice on the Site and the updated version will apply as of publication.

***

## 18. Contact

If you have any questions about privacy, please contact:

**<support@fira.money>**


