Overview
Kairos Protocol Documentation
Kairos is a decentralized interest rate swap AMM. Traders open positions that pay or receive a stream of interest payments indexed to an on-chain rate oracle; LPs supply the collateral that backs the other side of those payments.
This documentation is written for the people who interact with the protocol on-chain:
Traders / buyers — how to open a swap, manage it, settle it at expiry, or exit early.
LPs — how the shared pool works, how shares are priced, and what gates sit in front of deposits and withdrawals.
Market creators — how to create a BUY_FIXED / BUY_FLOATING market pair and manage ownership over time.
Integrators — how the
onBehalfOfauthorization pattern lets bundlers, routers, wrappers, and vault adapters act on behalf of end users.Keepers / liquidators — what to watch for and how to settle or liquidate positions.
Indexers — the events emitted across every lifecycle transition.
SwapCore
SwapCore.sol is the heart of Kairos. It owns the full lifecycle of an interest rate swap: market creation, liquidity provisioning, opening positions, settlement, early exit, and liquidation. Everything a user, LP, keeper, or integrator does on-chain flows through one of its ~28 external functions.
This chapter is a function-by-function reference. Start here for the mental model, then jump to the page that matches your role.
What SwapCore does
Kairos is a decentralized interest rate swap AMM. Traders enter positions that pay or receive a stream of interest payments indexed to an on-chain rate oracle, and LPs supply the collateral that backs the other side of those payments.
Every rate market that SwapCore creates is actually a pair:
BUY_FIXED — the buyer pays a locked-in fixed rate and receives the floating rate (from the reference rate oracle). Useful for hedging variable-rate exposure or speculating that rates will rise.
BUY_FLOATING — the buyer pays the floating rate and receives a locked-in fixed rate. Useful for locking in a yield or speculating that rates will fall.
Both sides of the pair share the same reference rate oracle, base rate oracle, collateral token, swap term, and leverage multiplier. LPs supply collateral to a single, share-based pool per market; buyers post their own collateral when they open a swap. The pool uses time buckets (numBuckets × bucketInterval) to aggregate mark-to-market P&L so share prices stay tractable even with many open positions.
Three inputs determine the all-in rate a buyer locks in at buySwap:
Base rate from the base swap rate oracle (tenor-dependent)
Utilization fee — a kinked curve integrated over the range
[uPre, uPost]as the swap consumes pool capacityRisk premium — an optional oracle-supplied markup, different per side of the pair
Actors
Market owner
Creates a market pair, optionally manages an LP whitelist, can terminate the market (stop new swaps). Receives a share of protocol fees if creator fee is configured.
Liquidity Provider (LP)
Deposits the market's collateral token into the pool, receives shares priced at the pool's current mark-to-market value, earns yield from swap fees and settlement inflows.
Buyer
Opens a swap by posting collateral, holds the position until expiry, and receives the net payment (or pays it) at settlement. Can transfer or (if enabled) exit early.
Keeper
Permissionless role. Settles swaps at expiry in batches to keep the pool's accounting current. Anyone can do this — there is no keeper whitelist.
Liquidator
Permissionless role. Calls liquidateSwap on an underwater position to recover the shortfall and collect the market's liquidationIncentive.
Integrator / bundler
Contracts that act on behalf of end users (vault adapters, wrappers, routers). Must be pre-authorized by the end user via setAuthorization for any onBehalfOf call.
setAuthorization, all onBehalfOf entry points
End-to-end lifecycle
A swap's life runs through five phases. The function names below link to their reference entries.
1. Market setup
The market owner calls createMarket with oracle addresses, collateral token, leverage, swap term, fee-curve parameters, bucket configuration, and optional whitelist flag. SwapCore deploys both sides of the market pair (BUY_FIXED + BUY_FLOATING) atomically, charges the protocol's market creation fee (if configured in Admin), and initializes the pool, buckets, and rate index for each side.
Ownership can be handed off later via transferMarketOwnership + acceptMarketOwnership (2-step), or the market can be permanently closed to new swaps via terminateMarket.
2. LP provisioning
LPs call supplyCollateral to deposit the market's collateral token. Shares are minted at the current mark-to-market share price (floor WAD for an empty pool, getPoolSharePrice(marketId) otherwise). A 1-block deposit lock prevents same-block deposit+withdraw flash-loan attacks.
Withdrawals happen through withdrawCollateral, which burns shares and transfers the proportional amount of underlying collateral. The withdrawal is blocked if the pool has expired unsettled swaps (because the share price would be stale) or if the pool has active swaps and is underwater at MIN_SHARE_PRICE (to prevent dilution attacks).
The last LP cannot take the pool's share count to zero while there are still active swaps — a single share is retained to keep accounting alive.
3. Opening a swap
A buyer calls buySwap with the target market, notional amount, and two slippage guards:
rateBound— ceiling on the locked-in rate for BUY_FIXED, floor on the base rate for BUY_FLOATING. Passtype(int256).maxto disable.maxMarkup— ceiling onutilFee + riskPremium. Pass0to disable.
SwapCore reads the base rate and reference rate from their oracles, computes the utilization fee by integrating the kinked fee curve across the capacity the new swap consumes, adds the risk premium, and produces the final swapRate. It then derives the required buyer collateral (sized to cover the buyer's maximum payment) and LP collateral backing (sized to cover the LP's maximum payment), checks that both are at least minCollateral, pulls the buyer's collateral in, and reserves the LP backing from pool.lockedCollateral.
The new swap is assigned to a time bucket ((entryTimestamp / bucketInterval) % numBuckets) so that future share-price calculations only need to iterate over buckets instead of all open swaps.
4. Swap management (during the term)
getSwapNetAmount/getFreshSwapNetAmount— query the net payment obligation at any time.updateMarketRateIndex— permissionlessly refresh the on-chain rate index. Anyone can call this before reading P&L or settling.transferSwapPosition— reassign ownership of an open swap to another address.
5. Swap closure
Three paths take a swap to settled = true. All three release collateral, zero out the bucket slot, decrement the expiry-epoch counter, and emit SwapClosed:
Normal expiry —
makePayment. Permissionless. Called afterentryTimestamp + swapTerm. Computes the fixed and floating legs over the full term, nets them, and transfers the net to the winner. If the buyer's token transfer fails (e.g. blacklisted address), the payout is held inescrowedCollateral[swapId]and can be pulled later viaclaimEscrow.makePaymentaccepts an array of swap IDs — keepers batch.Early exit —
exitSwapEarly. Only the swap owner (or an authorized delegate). Requiresmarket.earlyExitAllowed = true. Settles using the current index, applies the market'searlyExitFee, and enforces per-swapminExitAmountslippage protection.Liquidation —
liquidateSwap. Permissionless. Triggered when accrued (not projected) payments exceed the buyer's collateral balance or the LP's pool backing. The liquidator receives the market'sliquidationIncentiveout of the liquidated side's remaining collateral.
After closure the buyer can call claimEscrow if their settlement transfer failed. Funds always go back to the original swap.userAddress — no admin can redirect them.
Happy-path sequence
Data structures you'll see in this chapter
All defined in Types.sol:
Market— full market config: oracles, pool, fee curve, risk settings, whitelist flag, market owner, termination flagPool—(totalShares, totalCollateral, lockedCollateral)SwapPosition— the swap record: marketId, owner, settled + isEarlyExit flags, collateral, notional, rates, entry timestamp, entry index, bucket backing, utilFee, riskPremiumLpPosition—(shares, lastDepositBlock)Bucket— per-bucket aggregates (lpNotional, weighted rates/entry time/inverse index, weighted fees, totalBuyerCollateral, totalPoolBacking)ExitRequest—(swapId, minExitAmount)input toexitSwapEarlySettlementResult—(settlementAmount, netRecipient)returned bymakePayment/exitSwapEarlyRateConvention— how the reference rate oracle reports data:Cumulative,SpotRate, orSpotCompoundRateRateType—BUY_FIXED = 0,BUY_FLOATING = 1
Chapter layout
createMarket, transferMarketOwnership, acceptMarketOwnership, terminateMarket, setMarketLpWhitelist, getAllMarketIds
supplyCollateral, withdrawCollateral, and all LP/pool view functions
buySwap, makePayment, exitSwapEarly, liquidateSwap, transferSwapPosition, claimEscrow
setAuthorization, isAuthorized, and the onBehalfOf pattern
Read-only P&L, liquidity, oracle-index, and mapping getters
Integrator-facing events emitted across the lifecycle
Last updated