The keeper’s arb scanner runs every 15 seconds. For each market × side, it evaluates two paths and picks the more profitable. All four end in cUSDC at the keeper or CLP vault.Documentation Index
Fetch the complete documentation index at: https://continuum-ec12e897.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
The four cycles
1. Single-side mint + sell (pool > NAV)
Triggered when one side’s pool price > NAV by more thanpool_fee_bps + slip/2.
2. Single-side buy + redeem (pool < NAV)
Triggered when one side’s pool price < NAV by more thanpool_fee_bps + slip/2.
3. Paired mint + sell (combined_dex > combined_nav)
Triggered when(L_pool_price + S_pool_price) > (L_NAV + S_NAV) + threshold.
4. Paired buy + redeem (combined_dex < combined_nav)
Triggered when(L_pool_price + S_pool_price) < (L_NAV + S_NAV) - threshold.
actual_L and actual_S are read at execution time, not pre-computed as min_amount_out - otherwise the slippage buffer leaks as residual synth.
Path selection
Each scan tick:- Compute single-side profit estimate for each side independently.
- Compute paired profit estimate.
- Pick the largest expected profit.
- Execute that one.
- Single-side closes per-side divergence directly.
- Paired arb only fires when both sides are spread in the same combined direction (rarer).
- Single-side is fee-free at the protocol layer. Paired arb pays
mint_fee_bps + redeem_fee_bps(≈ 20 bps round-trip) in addition to pool fees.
Threshold
pool_fee_bpsis the bin-step base fee (0.10% for index ETFs, 0.20–0.25% for equities).slippage_bufferisMAX_SLIPPAGE_BPS / 2(default 25 bps).
MAX_SLIPPAGE_BPS) catch more arbs but also more false positives.
Profit accounting: actual vs expected
expected_profit is an upper bound - it ignores worst-case quoting, real-time bin-curve slippage, and other slippage sources. The keeper measures actual profit:
- Favorable-slippage runs don’t over-deposit. If the swap returned more than expected (slippage was negative),
actual_delta > expected_profit, and onlyexpected_profitis sent to global. The remainder stays in the keeper wallet, smoothing future bursts. - Unprofitable runs don’t drain the keeper. If
actual_delta ≤ 0,deposit_amount = 0. The keeper absorbs the loss; it doesn’t compound by sending negative profit to global.
Trade sizing
keeper_balance cap disappears (the borrow covers the trade); pool depth governs.
End-of-cycle residual sweep
After every arb, the keeper:- Reads its post-swap L and S balances.
- If both sides have stock →
redeem_paired(L_bal, S_bal). - Else (asymmetric residue) →
keeper_redeem_singleon whichever side has stock.
Boot-time sweep
On startup, before any new arb runs, the keeper does the same residual sweep on whatever was left from the prior process. Crashes during an arb cycle leave non-zero L or S in the keeper wallet - boot-time sweep redeems them.LS-pool path (deprecated)
An earlier prototype routed per-side divergence through a direct L↔S pool (triangular arb). Superseded by single-side keeper mint/redeem because:- Single-side is fee-free at the protocol layer.
- Single-side needs only one DEX leg vs LS arb’s two legs.
- LS arb paid both
mint_fee_bps + redeem_fee_bpsplus a worst-case quoting penalty (since it routed through user-facingmint_paired/redeem_paired).
LS_POOLS env var (unset in production). Re-enable only if a future market lacks a keeper-authority single-side path.
Execution: direct vs flash
| Config | Behavior |
|---|---|
| Flash-loan adapters configured (mainnet only) | Borrow cUSDC for the cycle; atomic single-tx execution |
| Flash-loan adapters missing (devnet) | Direct mode - sequential phases using keeper’s own cUSDC |
USE_JITO=true | Future: bundle via Jito for MEV protection (no-op currently) |
What you can compete on
If you run an external bot:- Paired arb (cycles 3, 4): no privilege required. You compete with the keeper directly. Profit is yours.
- Single-side arb (cycles 1, 2): keeper has fee-free privilege. You can do it via paired ixns + an extra leg, but you’ll pay
mint_fee_bps + redeem_fee_bps(~20 bps) the keeper avoids. Edge harder to capture.
See also
DLMM management
The other half of the keeper’s job.
Run a keeper
Config and deployment.

