FiraMarket

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

circle-info

Source: src/fira_bonding/core/Market/v3/FiraMarket.sol

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

Last updated