FiraMarket
FiraMarket is the BT/FW AMM — it holds reserves, executes swaps, manages LP tokens, and maintains TWAP oracle state.
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
totalBtandtotalFware never affected by direct transfersExchange rate is always >= 1.0 (BT trades at a discount to FW)
address(0)andaddress(this)never have reward or balance accountingSwaps and mints revert after expiry; burns work at any time
Last updated