mcpField
H
hodlmm-bin-guardian

hodlmm-bin-guardian

github.com/aibtcdevOther1146 installsUpdated 1d ago
Repository

About hodlmm-bin-guardian

HODLMM Bin Guardian is a read-only skill for monitoring Bitflow HODLMM liquidity positions. It compares a wallet’s bins with the active pool bin and applies volume, slippage, gas, and cooldown checks before indicating whether rebalancing is eligible.

Key features

  1. 01Compare wallet bins with the active bin
  2. 02Read pool volume, TVL, APR, and prices
  3. 03Check slippage, gas, and cooldown gates
  4. 04Detect out-of-range positions and grid-edge states
  5. 05Return strict JSON results

Use cases

  1. 01Check whether an LP position is earning fees
  2. 02Review conditions before a human-approved rebalance
  3. 03Identify a pinned pool requiring escalation

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/aibtcdev/skills --skill hodlmm-bin-guardian

After installing, type/hodlmm-bin-guardianin Claude Code to confirm it loaded.

Bundled filesAGENT.mdhodlmm-bin-guardian.ts

Details

From the project README

HODLMM Bin Guardian

Monitors Bitflow HODLMM (DLMM) bins to keep LP positions in the active earning range.

What it does

Fetches live Bitflow HODLMM pool state, the user's actual LP position bins (via wallet address), and compares the user's bin range against the active bin to determine if the position is earning fees. Volume, TVL, APR, and token prices are sourced directly from Bitflow's HODLMM app API — no external oracles. Slippage is measured as the deviation between the HODLMM active-bin price and Bitflow's own reported token price. Also checks estimated gas cost and cooldown before recommending REBALANCE.

Why agents need it

HODLMM positions stop earning fees the moment the market price moves outside the deposited bin range. This skill gives an autonomous agent a reliable, safe-to-run check that surfaces out-of-range positions and flags them for human-approved rebalancing — without ever spending funds autonomously.

Safety notes

  • Read-only. No transactions are submitted.
  • Mainnet-only. Bitflow HODLMM API does not support testnet.
  • Refuses to recommend rebalance if 24h pool volume < $10,000 USD.
  • Refuses to recommend rebalance if slippage > 0.5% (HODLMM bin price vs Bitflow app price).
  • Any actual rebalance (add/withdraw liquidity) requires explicit human approval before execution.
  • All price data sourced from Bitflow APIs only — no external oracles.

Commands

doctor

Checks all data sources: Bitflow HODLMM API, Bitflow Bins API, Bitflow App Pools API, and Hiro Stacks API.

bun run hodlmm-bin-guardian/hodlmm-bin-guardian.ts doctor
install-packs

No additional packs required — uses Bitflow and Hiro public HTTP APIs directly.

bun run hodlmm-bin-guardian/hodlmm-bin-guardian.ts install-packs
run

Checks the LP position in the default sBTC HODLMM pool (dlmm_1) and outputs a recommendation. Pass --wallet to enable the real in-range check against actual position bins.

# Full check with wallet (recommended)
bun run hodlmm-bin-guardian/hodlmm-bin-guardian.ts run --wallet SP1234...
bun run hodlmm-bin-guardian/hodlmm-bin-guardian.ts run --wallet SP1234... --pool-id dlmm_1

# Pool-only check (no position check — in_range will be null)
bun run hodlmm-bin-guardian/hodlmm-bin-guardian.ts run

Live terminal output

doctor (all 4 sources reachable)
{
  "status": "ok",
  "checks": [
    { "name": "Bitflow HODLMM API",      "ok": true, "detail": "8 pools found, dlmm_1 active bin: 504" },
    { "name": "Bitflow Bins API (dlmm_1)", "ok": true, "detail": "active_bin_id=504, 1001 bins" },
    { "name": "Bitflow App Pools API",   "ok": true, "detail": "dlmm_1 TVL: $77,142.99, vol_24h: $126,045, APR: 17.72%" },
    { "name": "Hiro Stacks API (fees)",  "ok": true, "detail": "2 µSTX/byte" }
  ],
  "message": "All data sources reachable. Ready to run."
}
run --wallet (wallet has no dlmm_1 position, slippage gate active)
{
  "status": "success",
  "action": "HOLD — position out of range but rebalance blocked: price slippage 1.86% > 0.5% cap.",
  "data": {
    "in_range": false,
    "active_bin": 504,
    "user_bin_range": null,
    "can_rebalance": false,
    "refusal_reasons": [ "price slippage 1.86% > 0.5% cap" ],
    "slippage_ok": false,
    "slippage_pct": 1.8595,
    "bin_price_raw": 66459654464,
    "pool_price_usd": 66459.65,
    "market_price_usd": 65246.37,
    "slippage_source": "bitflow-app-price-vs-hodlmm-active-bin",
    "gas_ok": true,
    "gas_estimated_stx": 0.0144,
    "cooldown_ok": true,
    "cooldown_remaining_h": 0,
    "last_rebalance_at": null,
    "volume_ok": true,
    "volume_24h_usd": 126045,
    "liquidity_usd": 77143,
    "apr_24h_pct": 17.72,
    "pool_id": "dlmm_1",
    "pool_name": "sBTC-USDCx-LP",
    "fee_bps": 30,
    "position_note": "No position found for SP219TWC8G12CSX5AB093127NC82KYQWEH8ADD1AY in pool dlmm_1."
  },
  "error": null
}
run --wallet (active position in range, all gates pass)
{
  "status": "success",
  "action": "HOLD — position in range at active bin 504. APR (24h): 17.72%.",
  "data": {
    "in_range": true,
    "active_bin": 504,
    "user_bin_range": { "min": 500, "max": 508, "count": 3, "bins": [500, 504, 508] },
    "can_rebalance": true,
    "refusal_reasons": null,
    "slippage_ok": true,
    "slippage_pct": 0.04,
    "bin_price_raw": 66459654464,
    "pool_price_usd": 66459.65,
    "market_price_usd": 66433.0,
    "slippage_source": "bitflow-app-price-vs-hodlmm-active-bin",
    "gas_ok": true,
    "gas_estimated_stx": 0.0144,
    "cooldown_ok": true,
    "cooldown_remaining_h": 0,
    "last_rebalance_at": null,
    "volume_ok": true,
    "volume_24h_usd": 126045,
    "liquidity_usd": 77143,
    "apr_24h_pct": 17.72,
    "pool_id": "dlmm_1",
    "pool_name": "sBTC-USDCx-LP",
    "fee_bps": 30
  },
  "error": null
}

Output contract

All outputs are strict JSON to stdout.

FieldTypeDescription
status"success" | "error"Overall result
actionstringHOLD, REBALANCE, PINNED, or CHECK with reason
data.in_rangeboolean | nullnull if no wallet provided
data.active_binnumberPool's current active bin ID
data.at_grid_edgebooleanActive bin at the grid edge (unsigned 0 or 1000); only true when the bins read verifiably carried the active bin
data.pinnedbooleanAt grid edge AND slippage gate failing — structural divergence; see PINNED
data.user_bin_range{min,max,count,bins} | nullUser's liquidity bin range
data.can_rebalancebooleanWhether all safety gates pass
data.refusal_reasonsstring[] | nullWhy REBALANCE is blocked
data.slippage_okbooleanWhether price deviation is within cap
data.slippage_pctnumber|hodlmm_price − bitflow_price| / bitflow_price × 100
data.bin_price_rawnumberRaw active bin price from Bitflow bins API
data.pool_price_usdnumber | nullHODLMM derived USD price: (bin_price_raw / 1e8) × 10^(xDec − yDec)
data.market_price_usdnumber | nullBitflow app reported token price in USD
data.slippage_sourcestringPrice source identifier
data.gas_okbooleanWhether estimated gas is within limit
data.gas_estimated_stxnumberEstimated STX for 2-txn rebalance
data.cooldown_okbooleanWhether cooldown has elapsed
data.cooldown_remaining_hnumberHours until next rebalance allowed
data.last_rebalance_atstring | nullISO timestamp of last recorded rebalance
data.volume_okbooleanWhether 24h volume meets minimum
data.volume_24h_usdnumber24h pool volume in USD
data.liquidity_usdnumberPool TVL in USD
data.apr_24h_pctnumber24h fee APR from Bitflow app API
data.pool_idstringPool identifier
data.pool_namestringHuman-readable pool name
data.fee_bpsnumberPool fee in basis points
data.position_notestring?Present when position state needs explanation

Data sources

SourceDataEndpoint
Bitflow HODLMM APIPool list, active binbff.bitflowapis.finance/api/quotes/v1/pools
Bitflow Bins APIPer-bin prices (raw, for slippage)bff.bitflowapis.finance/api/quotes/v1/bins/{poolId}
Bitflow App Pools APITVL, 24h volume, APR, token prices, decimalsbff.bitflowapis.finance/api/app/v1/pools
Bitflow Position APIUser's position binsbff.bitflowapis.finance/api/app/v1/users/{addr}/positions/{pool}/bins
Hiro Stacks APISTX fee estimateapi.mainnet.hiro.so/v2/fees/transfer

v2 changelog (fixes from day-1 review)

In-range check — was fake, now real

Before: inRange = isFinite(pool.active_bin) && pool.active_bin > 0 — always true.

After: Real HTTP call to GET /api/app/v1/users/{address}/positions/{poolId}/bins. Filters bins where user_liquidity > 0, checks if active_bin_id is in that set.

Slippage — was hardcoded, now live and fully Bitflow-native

Before: Constant value, always passed.

After: (bin_price_raw / 1e8) × 10^(xDec − yDec) vs Bitflow app API token price. No external oracles — all data from Bitflow endpoints.

Gas estimate — was a made-up constant, now live

Before: gas_estimated_stx: 0.006 — hardcoded.

After: Hiro /v2/fees/transfer × 500 bytes × 2 txns × 3× contract multiplier × 1.2 safety buffer.

Cooldown — was not tracked, now persistent

Before: No state file, cooldown always passing.

After: Reads/writes ~/.hodlmm-guardian-state.json. Returns cooldown_remaining_h on each run.

Frontmatter — stale dependency removed

Before: requires: [bitflow] — referenced a non-existent dependency.

After: requires: "" — fully self-contained, all data from public HTTP APIs.

Origin

Winner of AIBTC x Bitflow Skills Pay the Bills competition. Original author: @cliqueengagements Competition PR: https://github.com/BitflowFinance/bff-skills/pull/39

PINNED detection (2026-07-15 field audit F-5)

When the pool's active bin is at the grid edge (unsigned 0 or 1000) AND pool-vs-market divergence exceeds the slippage cap, the guardian emits a distinct PINNED action (plus at_grid_edge / pinned data fields) instead of an unpassable slippage HOLD. While pinned, pool price is frozen by contract design and the divergence is structural — do not rebalance or blind-swap; route to the exit/withdraw path (withdraw minimums remain enforceable) or escalate. There is no official pinned signal in the Bitflow API; this is derived from contract behavior. Observed live on dlmm_3 (2026-07-13): 1.4–4.8% structural divergence for ~36h that deadlocked slippage-gated automation.

Example PINNED output (fields added 2026-07-15; both run examples above predate at_grid_edge/pinned)
{
  "status": "success",
  "action": "PINNED — pool is at the grid edge (active bin 0) with structural pool-vs-market divergence 2.74%. The slippage gate cannot clear while pinned. Do NOT rebalance or blind-swap; route to the exit/withdraw path (withdraw minimums remain enforceable while pinned) or escalate to a human.",
  "data": {
    "in_range": false,
    "active_bin": 0,
    "at_grid_edge": true,
    "pinned": true,
    "can_rebalance": false,
    "refusal_reasons": ["price slippage 2.74% > 0.5% cap"],
    "slippage_ok": false,
    "slippage_pct": 2.74
  }
}

Normal (non-pinned) run output now also carries "at_grid_edge": false, "pinned": false.

Comments

Markdown supported