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

# Pre/Post Expiry Exits

```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).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.fira.money/developers/user-flows/pre-post-expiry-exits.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
