Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions hodlmm-bin-guardian/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,7 @@ All outputs are strict JSON to stdout.
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.
16 changes: 16 additions & 0 deletions hodlmm-bin-guardian/hodlmm-bin-guardian.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,23 @@ async function runGuardian(wallet?: string, poolId?: string): Promise<{

const canRebalance = refusals.length === 0;

// ── Grid-edge / pinning detection (2026-07-15 field audit F-5) ──────────────
// The DLMM active bin cannot move past the grid edge (dlmm-core: it only
// decrements while bin-id > MIN_BIN_ID, mirrored at MAX). At the edge the
// pool price freezes while the market keeps moving, so pool-vs-market
// "slippage" becomes STRUCTURAL — the slippage gate can never clear
// (observed live: 1.4–4.8% divergence for ~36h on dlmm_3, 2026-07-13, while
// the pool sat at unsigned bin 0). There is no official pinned signal
// anywhere in the Bitflow API surface; this detection is derived.
// Unsigned grid: 0 = raw −500 floor, 1000 = raw +500 ceiling.
const atGridEdge = active_bin_id <= 0 || active_bin_id >= 1000;
const pinned = atGridEdge && !slippageResult.ok;

let action: string;
if (inRange === null) {
action = `CHECK — ${positionNote}`;
} else if (pinned && !inRange) {
action = `PINNED — pool is at the grid edge (active bin ${active_bin_id}) with structural pool-vs-market divergence ${slippageResult.pct.toFixed(2)}%. 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.`;
} else if (inRange) {
action = `HOLD — position in range at active bin ${active_bin_id}. APR (24h): ${apr24h.toFixed(2)}%.`;
} else if (!canRebalance) {
Expand All @@ -378,6 +392,8 @@ async function runGuardian(wallet?: string, poolId?: string): Promise<{
data: {
in_range: inRange,
active_bin: active_bin_id,
at_grid_edge: atGridEdge,
pinned: pinned,
user_bin_range: userBinRange,
can_rebalance: canRebalance,
refusal_reasons: refusals.length > 0 ? refusals : null,
Expand Down
Loading