hodlmm-inventory-balancer/SKILL.md
Detects HODLMM LP inventory drift (token-ratio imbalance from one-sided swap flow) and restores the target ratio via a corrective Bitflow swap plus a hodlmm-move-liquidity redeploy, gated by the 4h per-pool cooldown.
npx skillsauth add aibtcdev/skills hodlmm-inventory-balancerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Detects inventory drift — the silent token-ratio imbalance that builds up in a HODLMM LP position when swap flow repeatedly drains one side of the pair even while the active bin holds its price. Computes a price-weighted exposure ratio across every user bin (price × liquidity share, not raw token counts, handling bins below/at/above the active bin correctly), compares it to an operator-configured target (default 50:50), and when the absolute deviation exceeds --min-drift-pct (default 5%) executes a corrective swap via the Bitflow SDK and a redeploy via hodlmm-move-liquidity run --confirm.
Without this skill an agent that wanted symmetric sBTC/STX exposure ends up directionally pulled by swap flow — 70/30 instead of 50/50 — while still appearing "in range." Symmetric-exposure management is what separates a real market maker from a passive directional position-taker. This skill closes the gap hodlmm-move-liquidity doesn't: it fixes inventory drift where move-liquidity only fixes price drift.
--skip-redeploy) an atomic bin-to-bin redeploy via hodlmm-move-liquidity CLI (which itself calls the DLMM router's multi-move family). Mainnet only. Proven end-to-end on dlmm_1 across 2 full cycles: swap cd71c8a5… + redeploy 0349cbb0…, then swap 134df5e1… + redeploy 9cbe5903….run requires --confirm=BALANCE. Without it, the command exits with the computed plan in dry-run form.--min-drift-pct default 5%. Below that, no-op. Avoids thrashing on noise.--max-correction-sats caps a single balancing swap. Prevents an outsized correction during extreme flow events.--max-quote-staleness-seconds default 45s (one full 15–19s pipeline cycle of margin on top of freshness floor).minimum-output computed from a slippage budget. Default 0.5%, overridable via env var INVENTORY_BALANCER_SLIPPAGE_BPS (integer bps) or --slippage-bps flag.~/.hodlmm-move-liquidity-state.json and refuses to start a cycle that would have the redeploy step blocked (unless --skip-redeploy is passed, in which case the swap-only correction still writes a state marker for later redeploy resumption).PostConditionMode.Allow with a dual-pin envelope on every chain-writing leg. Each leg is sided per-token (skip the asset whose total is 0) and routes STX vs FT through resolveTokenAsset() so the two codepaths cannot drift apart.
swap-simple-multi pattern: Pc.principal(sender).willSendLte(amount_in) on the input token + Pc.principal(pool.pool_contract).willSendGte(min_out) on the output token. min_out is the same value passed to the router's min-received uint argument (ERR_MINIMUM_RECEIVED fires internally if undersold). Live proof tx 0xf4f49328…: post_condition_mode: allow, 2 post-conditions (sender lte 6,468 sbtc-token + pool gte 4,993,915 usdcx-token), 2 fungible_token_asset events, tx_status: success.Pc.principal(sender).willSendLte(total_shares).ft(pool.pool_contract, 'pool-token') (DLP burn cap) + Pc.principal(pool.pool_contract).willSendGte(total_min_x_raw) + …willSendGte(total_min_y_raw) (X/Y receive floors). Asset name pool-token verified live on tx 0x89315a8b… burn event; uniform across all DLMM pools (single template deployer). These pins ride alongside the contract-level aggregate min-x-amount-total / min-y-amount-total floors and per-bin min-x / min-y on each position tuple — four-layer safety envelope on a single tx.Pc.principal(sender).willSendLte(total_x_raw × 1.05) + …willSendLte(total_y_raw × 1.05). The 5% headroom matches the per-tuple max-(x|y)-liquidity-fee ceiling in the function args.bin-liquidity-fee accruals and protocol fees route inside dlmm-core's unclaimed-protocol-fees map / bin balances and don't always emit FT transfer events.hodlmm-move-liquidity CLI invocation) inherits its own contract-level slippage (max-liquidity-fee ≤ 5%; min-dlp handled upstream with bin-price-aware semantics).--skip-redeploy not passed.Installs the Stacks SDK packages the executor needs. Idempotent.
bun run hodlmm-inventory-balancer/hodlmm-inventory-balancer.ts install-packs
Pre-flight: wallet readable, Bitflow App + Quotes APIs reachable, at least one HODLMM pool with a user position, move-liquidity cooldown status surfaced as minutes remaining, prior state-marker inspected for unresolved cycles, wallet STX gas reserve sufficient.
bun run hodlmm-inventory-balancer/hodlmm-inventory-balancer.ts doctor
Read-only. Per eligible pool: current effective token ratio, target ratio, absolute deviation, active bin, cooldown minutes remaining, last cycle outcome from the state marker.
bun run hodlmm-inventory-balancer/hodlmm-inventory-balancer.ts status [--pool <id>]
Dry-run of the full cycle: computes the corrective swap plan (direction, amount_in, minimum_out) and the redeploy plan (via hodlmm-move-liquidity CLI --dry-run). Prints JSON without broadcasting. Useful as a pre-check before run.
bun run hodlmm-inventory-balancer/hodlmm-inventory-balancer.ts recommend [--pool <id>] [--target-ratio 50:50] [--min-drift-pct 5]
Core execution. Requires --confirm=BALANCE (the word BALANCE, not just any value). Without it, behaves like recommend. Full cycle: cooldown check → corrective swap → state marker → redeploy → state marker cleared. If --skip-redeploy is passed, executes the swap only and leaves a swap_done_redeploy_pending marker so a later run picks up from the redeploy step without re-swapping.
bun run hodlmm-inventory-balancer/hodlmm-inventory-balancer.ts run \
--confirm=BALANCE \
[--pool <id>] \
[--target-ratio 50:50] \
[--min-drift-pct 5] \
[--max-correction-sats 500000] \
[--max-quote-staleness-seconds 45] \
[--slippage-bps 50] \
[--skip-redeploy] \
[--force-direction "X->Y" | "Y->X"] \
[--force-amount-in-raw <n>] \
[--allow-rebalance-withdraw] \
[--max-slice-bps <0..8000>]
Wallet password is read from the WALLET_PASSWORD env var. There is no --password CLI flag by design — an argv entry would surface in /proc/<pid>/cmdline and ps auxww for the process lifetime (same exposure class @arc0btc/@diegomey flagged on the child-process invocation of hodlmm-move-liquidity).
--allow-rebalance-withdrawv1's swap + move-liquidity-multi redeploy is value-conserving and bin-to-bin — it cannot convert one LP side into the other when a position is sprawled. Setting --allow-rebalance-withdraw on run switches the executor to a 3-tx flow:
dlmm-liquidity-router-v-1-1.withdraw-relative-liquidity-same-multi. Picks the largest overweight bin, withdraws a share fraction sized to shift |current − target| × total_value back to wallet (capped at --max-slice-bps, default 80%).swap-simple-multi path as the default mode, sized to convert 100% of the withdraw proceeds to the underweight token.dlmm-liquidity-router-v-1-1.add-relative-liquidity-same-multi at active ± 1 bin, placing the swap output on the underweight side (X above active, Y below). active-bin-tolerance is noneCV() — a tolerance value would race-abort with ERR_ACTIVE_BIN_TOLERANCE (u5008) on the resume path where the broadcast-to-inclusion gap can be hours, and on high-volume pools the active bin can move arbitrarily far in that window. Wallet-side bounds (per-bin x/y-amount, max-liquidity-fee at 5%, min-dlp ≥ 1) preserve fund safety.The redeposit replaces the move-liquidity CLI invocation in this path — the 3-leg flow IS the redeploy. Use default mode (swap + move-liquidity recenter) for in-range small-drift corrections; use --allow-rebalance-withdraw when the position is sprawled or the deviation is too large for the swap alone.
Resume on partial failure. If a 3-leg cycle is interrupted between legs (process killed, network blip, gas shortfall mid-cycle), the state file captures last_cycle_status plus a rebalance_pending_details snapshot of the swap + redeposit plans at the moment leg 1 succeeds. Re-running run --pool <id> --allow-rebalance-withdraw --confirm BALANCE picks up where the prior cycle stopped:
withdraw_done_swap_pending → verifies the withdraw landed success on-chain via probeTxStatus, then broadcasts legs 2 + 3 from the snapshot.withdraw_done_swap_done_redeposit_pending → verifies the swap landed success, then broadcasts leg 3 from the snapshot.If the prior tx aborted (status ≠ success), the resume is refused and the operator is pointed at the explorer + reset-marker. If the snapshot is missing (state file from before this fix shipped, or manually edited), the resume is also refused with the same reset-marker hint — the planner re-plans against the current ratio after the marker is cleared.
--force-direction + --force-amount-in-raw are an operator escape hatch for cases the planner refuses (e.g. wallet holds the under-weight side while the over-weight side is fully in the LP). Both flags must be supplied together.
Operator escape hatch for stuck cycles. Clears the per-pool entry from ~/.hodlmm-inventory-balancer-state.json so the next run starts fresh and re-plans against the current ratio. Use when:
rebalance_pending_details snapshot is missing (legacy marker from a pre-fix state file)bun run hodlmm-inventory-balancer/hodlmm-inventory-balancer.ts reset-marker --pool <id> --confirm
--confirm is required (irreversible). On success, returns the cleared entry in data.cleared so the operator has a record of what was discarded.
Every command emits a single-line JSON object to stdout:
{ "status": "success" | "error" | "blocked", "action": "run" | "recommend" | ..., "data": { }, "error": null }
The data object on a successful run includes:
pool_id, pairratio_before, ratio_after, target_ratio, deviation_before, deviation_afterswap: { direction, amount_in, minimum_out, tx_id, explorer }redeploy: { tx_id, explorer } (null when --skip-redeploy)state_marker: { path, status }Errors are { "error": "message" }, never a raw stack trace.
hodlmm-move-liquidity's 4h per-pool cooldown regardless of drift magnitude.move-liquidity-multi is bin-to-bin and does not deposit newly-swapped wallet tokens into the LP. Meaningful second-cycle correction would require a withdraw-all → swap-to-target → redeposit flow, which is v2 scope.Winner of AIBTC x Bitflow Skills Pay the Bills competition. Original author: @cliqueengagements Competition PR: https://github.com/BitflowFinance/bff-skills/pull/494
development
Web of Trust operations for Nostr pubkeys — trust scoring, sybil detection, trust path analysis, neighbor discovery, follow recommendations, and network health. Free tier (wot.klabo.world, 50 req/day) with paid fallback (maximumsats.com, 100 sats via L402). Covers 52K+ pubkeys and 2.4M+ zap-weighted trust edges. Use --key-source to select nip06 (default), taproot, or stacks derivation path.
data-ai
BTC ordinals marketplace operations via Magic Eden — browse active listings, list inscriptions for sale via PSBT flow, submit signed listings, buy inscriptions, and cancel active listings. BTC ordinals only (not Solana). Mainnet-only.
testing
Pay-per-call access to LunarCrush social and market intelligence (Galaxy Score, AltRank, market cap rank, price, 24h change) via x402 on Stacks. USD-pegged pricing recomputed hourly from live STX/USD. Mainnet endpoint live; testnet supported.
development
On-chain intelligence for DOG•GO•TO•THE•MOON rune — forensic analysis, LTH vs STH metrics, multi-chain whale tracking, multi-exchange markets, cross-chain data, and airdrop analytics powered by DOG DATA's Bitcoin full node.