nav-loop
v0.2.1
Published
Strategy math for recursive borrow/buy looping against NAV-backed collateral. Leads with what the loop costs you, not what it levers you to.
Maintainers
Readme
nav-loop
Breadth-first buy+borrow bot and strategy math for NAV-backed collateral on oddballer.fun.
Unaudited. Opens leveraged positions with real funds. Dry-run by default.
The one number that matters
Exposure gained per unit of equity burned is constant in lap count:
| β | exposure per equity burned | max leverage | full-loop entry cost | |---|---|---|---| | 0.825 | 4.04x | 3.10x | 76.7% | | 0.99 | 10.28x | 5.33x | 51.9% |
Lapping does not get more efficient the more you lap. So lap count is a size dial, not an efficiency dial — there is no optimal number of laps to solve for. β, by contrast, moves the exchange rate 2.5x.
Why breadth-first
Depth-first (N laps, one meme) and breadth-first (one lap, N memes) have identical haircuts, identical exposure and identical equity burn. The only difference is that concentration is priced:
concentrationBps × CONCENTRATION_SLOPE_BPS(1000)
1 meme → +10.00% APR
10 memes → + 1.00% APRNine points of APR for routing alone, plus the bet is diversified and maturities stagger instead of cliffing. Depth-first is only right when conviction in one name outweighs 9% APR.
Use
npm i -g nav-loop
navloop plan --capital 0.1 --tokens 0xTOKEN_A,0xTOKEN_B
navloop run --capital 0.1 --tokens 0xTOKEN_A,0xTOKEN_B --executeNothing is signed without --execute and NAVLOOP_PRIVATE_KEY.
import { planBreadthFirst, exposurePerEquityBurned } from "nav-loop";
import { runBreadthFirst, readBetas } from "nav-loop/bot";
const memes = await readBetas(["0x…"]);
const plan = planBreadthFirst(memes, 0.1);
console.log(plan.entryCostFraction); // read this before the leverage numberConfig
file < env < explicit argument. Copy navloop.config.example.json.
| env | meaning |
|---|---|
| NAVLOOP_RPC_URL | chain endpoint |
| NAVLOOP_NAV_LEND / NAVLOOP_HOOK / NAVLOOP_ROUTER | contracts |
| NAVLOOP_MAX_LAPS | size dial (default 1 — breadth-first) |
| NAVLOOP_MIN_BETA | reject cheap-exchange-rate memes (default 0.8) |
| NAVLOOP_MAX_UTILISATION_BPS | stay under the kink (default 8000) |
| NAVLOOP_MAX_CONCENTRATION_BPS | cap one meme's share of OI |
| NAVLOOP_GAS_PRICE_WEI / NAVLOOP_GAS_PER_LAP | gas model |
| NAVLOOP_REFINANCE_BUFFER_SECONDS | rebuild before the 30-day term |
| NAVLOOP_PRIVATE_KEY | only read when --execute |
What can go wrong
- The entry cost is real and immediate. At β=0.825 a single lap costs 24.8% before the price moves.
- Loans mature at 30 days and are then closable by anyone at any LTV.
Refinance inside
refinanceBufferSeconds. - Collateral cannot fall in value (NAV is monotonic on-chain), so only interest can liquidate you — but interest is enough.
- Protocol constants are mirrored in
src/protocol.ts. If the contracts are redeployed with different parameters, every number here is confidently wrong. Verify against chain.
MIT.
