block-quote On this pagechevron-down
GitBook Assistant Ask chevron-down Developers chevron-right Protocol Contracts chevron-right Core MarketMathCore MarketMathCore encodes the time-decaying pricing curve and trade execution math used by FiraMarket. OracleLib provides the TWAP ring buffer.
This library operates entirely on in-memory MarketState structs for gas efficiency. It never reads from or writes to storage directly.
The AMM prices BT relative to FW using a logit curve:
Copy 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.
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.
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
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