Octane
Octane Security Adversarial Engagement
Auditor: Octane Security Engagement type: Adversarial Research Engagement (proof-of-concept driven) Audit: March 2026 Remediation verified: May 22, 2026 Status: All findings resolved
Summary
Octane Security ran a deep adversarial engagement against the KairosSwap core protocol: the full swap lifecycle from creation through settlement and liquidation, LP pool accounting and share pricing, oracle integration, the Morpho Vault V2 adapter layer, and the permissionless settlement and liquidation mechanics.
The engagement surfaced 20 findings. Every one was reproduced with a runnable proof-of-concept, and every one has been fixed and re-verified against the latest codebase. Nothing was accepted on description alone, and nothing was left open.
Critical
1
✅
High
3
✅
Medium
7
✅
Low
8
✅
Informational
1
✅
Total
20
20
The audit was conducted at commit 1c7f9f29. Because the contracts were substantially refactored during remediation, each finding was re-located by its underlying code semantics and confirmed resolved against the latest commit b0e76c0d.
For degens
Octane tried to break KairosSwap, with strong incentive to find anything that could lose user funds. They probed every place where money moves: how positions are opened and closed, how liquidity providers are paid, how the protocol reads interest rates, and how it talks to integrations like Morpho vaults.
They found issues, which is the point of an audit. What matters is the outcome: the most serious issue (a single Critical that could have frozen vault funds under a specific settlement ordering) and all 19 others were fixed, and Octane re-checked the fixes against the live code rather than taking our word for it.
A few of the fixes intentionally keep certain behaviors. For example, LP deposits and withdrawals now refuse to execute if the protocol can't read a valid interest rate, rather than guessing at a price. That's by design: it protects LPs from entering or exiting at the wrong value. We've called those out explicitly below so nothing is hidden behind a "fixed" label.
For developers
What was in scope
SwapCore, Utils, SwapFormulas, RateIndexLib, Admin, the KairosBuyerAdapter / KairosMarketAdapter layer and their factories, the oracle factory and SimpleOracle, and the read-only Views contract.
Methodology
Three phases: an analytical foundation (architecture mapping, threat modeling, fund-flow analysis, invariant identification, historical exploit research), the Octane platform's directed analysis across protocol-specific attack surfaces, and an exploitation phase where every candidate finding was confirmed or discarded by a dedicated PoC. In total, 20 PoC files with 155 passing test functions.
Finding classes and what changed
The 20 findings collapsed into 9 structural classes. Fixes were applied at the class level where possible, not just patched per-instance.
Adapter and external balance accounting — Added a sweep action and an escrow-claim path to KairosBuyerAdapter; deallocate now forwards recorded proceeds on an already-settled swap instead of reverting. The out-of-band stranding vector (the Critical) is closed. realAssets() still counts genuine out-of-band settlement proceeds by design, and donated tokens are now recoverable by sweep rather than permanently stuck.
Transaction-ordering share price manipulation — Bucket mark-to-market is now capped to actually posted collateral, removing the uncapped-vs-capped gap the deposit-settle-withdraw extraction relied on. supplyCollateral / withdrawCollateral gained minSharesOut / minCollateralOut guards, and a one-block LP vest blocks atomic deposit-then-exit cycles.
Accounting path inconsistency — The buyer-liquidation branch now zeroes swap.collateralBalance before crediting the pool, matching the other two settlement paths. Token Balance Solvency invariant holds.
Non-binding preview / missing slippage — previewEarlyExitSettlement was removed; exitSwapEarly now enforces a per-swap minExitAmount against the realized payout. buySwap gained a core-level rateBound and maxMarkup, so slippage protection no longer depends on the adapter.
Algebraic time-window mismatch — Both bucket MtM and normal settlement now resolve the floating rate from the index at expiry over a fixed term, so settlement timing no longer leaks post-expiry rate drift into payouts.
Oracle integration gaps — Decimal normalization applied consistently via the batched tenor-rate interface; the base oracle is read only when needed; RateIndexLib.update() now fails closed on invalid oracles rather than returning a stale index; cumulative oracles always re-sample the live index; and the view-based NAV path projects a fresh index instead of reading the stored one.
LP dilution via share price floor — supplyCollateral reverts at MIN_SHARE_PRICE when the pool has active swaps, blocking opportunistic floor deposits while keeping genuine rescue deposits possible when no active swaps exist.
Blacklistable token interaction — Settlement and liquidation payouts route through _transferOrEscrow, which escrows for later claim if the transfer reverts. A blacklisted recipient can no longer brick settlement or lock pool collateral.
Inconsistent rate source — Early-exit settlement and MtM now both read the tenor-aware oracle for the same market, eliminating the spot-vs-tenor divergence on non-flat curves.
By-design residuals (called out for transparency)
LP ops fail closed on an invalid oracle when the pool has active swaps. Pricing shares against open MtM exposure without a valid rate would let LPs enter or exit at the wrong NAV, so this is intended, not a residual DoS.
realAssets()still includes rawbalanceOf. It must count genuine settlement proceeds. A donation can only transiently pressure a curator-configured finite cap until swept, which is recoverable self-funded griefing rather than a permanent condition.The global raw-balance collateral cap was removed entirely, eliminating the donation-DoS surface rather than patching it.
Bottom line
The protocol went through an adversarial, proof-driven review, came out with a full set of reproduced findings, and every finding was remediated and independently re-verified against the live code. The full report, including each PoC and the per-finding remediation detail, is linked above.
Last updated