Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
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
25 changes: 25 additions & 0 deletions hodlmm-bin-guardian/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,3 +232,28 @@ 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.

### Example PINNED output (fields added 2026-07-15; both `run` examples above predate `at_grid_edge`/`pinned`)

```json
{
"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`.
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