Skip to content

Liquidity#535

Open
TYDev01 wants to merge 3 commits into
floxxih:masterfrom
TYDev01:liquidity
Open

Liquidity#535
TYDev01 wants to merge 3 commits into
floxxih:masterfrom
TYDev01:liquidity

Conversation

@TYDev01
Copy link
Copy Markdown

@TYDev01 TYDev01 commented Jun 1, 2026

Closed #507


feat(liquidity): add pool health and reserve drift monitoring (#507)

Introduce snapshot-based health tracking for liquidity pools. Each
reserve reading is persisted and compared against a 24-hour baseline to
detect ratio drift. Pools are classified as healthy, warning, or
critical based on reserve imbalance and drift thresholds, with the
signal surfaced through new API endpoints and Prometheus gauges.

Title: feat(liquidity): add pool health and reserve drift monitoring (#507)


Summary

Liquidity pools can silently enter unhealthy states — one reserve nearly depleted, a rapid ratio swing from a large swap, or slow drift from impermanent loss — with no signal to operators or routers. This PR wires up the full monitoring stack for issue #507.

What was added:

  • Time-series reserve snapshots stored per pool (liquidity_pool_snapshots)
  • Latest computed health record per pool (liquidity_pool_health)
  • A 24-hour drift window: ratio at ingest is compared to the oldest snapshot in the window; percentage change drives the severity tier
  • Imbalance detection independent of drift: if reserve_a / reserve_b falls outside configured bounds, the pool is flagged regardless of how gradually it arrived there
  • Prometheus gauges updated on every snapshot ingest so Grafana/alertmanager can page on degraded pools without polling the API
  • Four REST endpoints under /api/v1/liquidity/ for ingest and read
  • An Alembic migration that creates both tables with appropriate indexes

Health Classification

Condition | Status -- | -- ratio < 0.1 or ratio > 10.0 | critical drift from 24h baseline ≥ 30% | critical ratio < 0.25 or ratio > 4.0 | warning drift from 24h baseline ≥ 10% | warning reserve_b == 0 (division undefined) | critical Everything else | healthy

health_status encodes 0 = healthy, 1 = warning, 2 = critical. A Grafana alert on chainbridge_pool_health_status == 2 is all that's needed to page on critical pools.


Files Changed

backend/app/models/pool.py                                    (new)
backend/app/schemas/pool.py                                   (new)
backend/app/services/pool_health.py                           (new)
backend/app/observability/pool_metrics.py                     (new)
backend/app/routes/liquidity.py                               (new)
backend/alembic/versions/20260601_0007_add_pool_health_tables.py  (new)
backend/tests/test_pool_health.py                             (new)
backend/app/models/__init__.py                                (modified)
backend/app/routes/__init__.py                                (modified)
backend/alembic/env.py                                        (modified)

Testing

Unit tests cover:

  • _safe_ratio — zero denominator, equal reserves, zero numerator
  • _classify — all threshold boundaries (warn drift, critical drift, warn ratio low/high, critical ratio low/high, None ratio, priority ordering)
  • get_pool_health — not-found returns None, found returns record
  • list_pool_health — empty list, multi-pool list
  • get_pool_snapshots — populated and empty results
  • Route layer — 404 on unknown pool, 422 on path/body pool_id mismatch, correct healthy/warning/critical counts in summary

Checklist

  •  Acceptance criterion 1 — reserves tracked over time via liquidity_pool_snapshots
  •  Acceptance criterion 2 — pools flagged as warning / critical on imbalance or drift
  •  Acceptance criterion 3 — health signal surfaced via REST endpoints and Prometheus gauges
  •  No breaking changes to existing routes or models
  •  Migration has a downgrade() path
  •  Snapshot table is capped at 500 rows per pool to prevent unbounded growth

Title: feat(liquidity): add pool health and reserve drift monitoring (#507)


Summary

Liquidity pools can silently enter unhealthy states — one reserve nearly depleted, a rapid ratio swing from a large swap, or slow drift from impermanent loss — with no signal to operators or routers. This PR wires up the full monitoring stack for issue #507.

What was added:

  • Time-series reserve snapshots stored per pool (liquidity_pool_snapshots)
  • Latest computed health record per pool (liquidity_pool_health)
  • A 24-hour drift window: ratio at ingest is compared to the oldest snapshot in the window; percentage change drives the severity tier
  • Imbalance detection independent of drift: if reserve_a / reserve_b falls outside configured bounds, the pool is flagged regardless of how gradually it arrived there
  • Prometheus gauges updated on every snapshot ingest so Grafana/alertmanager can page on degraded pools without polling the API
  • Four REST endpoints under /api/v1/liquidity/ for ingest and read
  • An Alembic migration that creates both tables with appropriate indexes

Health Classification

Condition | Status -- | -- ratio < 0.1 or ratio > 10.0 | critical drift from 24h baseline ≥ 30% | critical ratio < 0.25 or ratio > 4.0 | warning drift from 24h baseline ≥ 10% | warning reserve_b == 0 (division undefined) | critical Everything else | healthy

health_status encodes 0 = healthy, 1 = warning, 2 = critical. A Grafana alert on chainbridge_pool_health_status == 2 is all that's needed to page on critical pools.


Files Changed

backend/app/models/pool.py                                    (new)
backend/app/schemas/pool.py                                   (new)
backend/app/services/pool_health.py                           (new)
backend/app/observability/pool_metrics.py                     (new)
backend/app/routes/liquidity.py                               (new)
backend/alembic/versions/20260601_0007_add_pool_health_tables.py  (new)
backend/tests/test_pool_health.py                             (new)
backend/app/models/__init__.py                                (modified)
backend/app/routes/__init__.py                                (modified)
backend/alembic/env.py                                        (modified)

Testing

Unit tests cover:

  • _safe_ratio — zero denominator, equal reserves, zero numerator
  • _classify — all threshold boundaries (warn drift, critical drift, warn ratio low/high, critical ratio low/high, None ratio, priority ordering)
  • get_pool_health — not-found returns None, found returns record
  • list_pool_health — empty list, multi-pool list
  • get_pool_snapshots — populated and empty results
  • Route layer — 404 on unknown pool, 422 on path/body pool_id mismatch, correct healthy/warning/critical counts in summary

Checklist

  •  Acceptance criterion 1 — reserves tracked over time via liquidity_pool_snapshots
  •  Acceptance criterion 2 — pools flagged as warning / critical on imbalance or drift
  •  Acceptance criterion 3 — health signal surfaced via REST endpoints and Prometheus gauges
  •  No breaking changes to existing routes or models
  •  Migration has a downgrade() path
  •  Snapshot table is capped at 500 rows per pool to prevent unbounded growth

@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Jun 1, 2026

@TYDev01 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Liquidity] Add pool health and reserve drift monitoring

1 participant