Skip to content

fix: price impact scale normalization, batch concurrency/rate-limits, and anomaly NaN threshold - #1148

Open
ushpraise wants to merge 4 commits into
Stellar-split:mainfrom
ushpraise:fix/concurrency-amm-and-anomaly-fixes
Open

ushpraise wants to merge 4 commits into
Stellar-split:mainfrom
ushpraise:fix/concurrency-amm-and-anomaly-fixes

Conversation

@ushpraise

Copy link
Copy Markdown

What this fixes

  • Bug: AMM price impact compares decimal values at different scales #1011: In AMMCalculator.computePriceImpact(), spot price and effective price strings were parsed into scaled integers using differing scales (e.g. scale 1 for integer price strings without decimal points vs scale 10^12 for fractional price strings), resulting in incorrect price impact computations (e.g. reporting 0.00% instead of 9.00% for 100 swap on a 1000/1000 pool).
  • Bug: invalid invoice concurrency limits can stall batch processing #1010: InvoiceBatchProcessor accepted invalid concurrency limits (non-positive integers, fractional numbers, NaN, and ±Infinity) and launched worker loops unbounded up to maxConcurrent even when only a few invoices were queued, causing dispatch failures or stalling the event loop on huge limits.
  • Bug: batch workers can dispatch before the shared 429 pause expires #1009: InvoiceBatchProcessor allowed global 429 pause windows to be shortened if subsequent requests received smaller retryAfterMs values, workers sleeping on earlier deadlines did not recheck extended deadlines upon waking, and invalid/negative/non-finite retry and pause options were accepted.
  • Bug: NaN sensitivityThreshold silently disables anomaly alerts #1008: In AnomalyDetector, the sensitivityThreshold validation this.sensitivityThreshold <= 0 || this.sensitivityThreshold > 1 accepted NaN because comparison with NaN evaluates to false, which silently classified all anomaly scores as "normal".

What changed

  • src/ammCalculator.ts: Normalized spotScaled and effectiveScaled to a common scale before computing the percentage price impact.
  • src/invoiceBatchProcessor.ts:
    • Validated that maxConcurrent is an integer >= 1, throwing RangeError otherwise.
    • Capped the initial launch count to Math.min(maxConcurrent, invoiceIds.length).
    • Added isValidPauseMs validation and safe fallback in retryAfterMs for non-integer/negative values.
    • Validated rateLimitPauseMs as a non-negative integer.
    • Enforced monotonic rate-limit deadlines using Math.max(pausedUntil, nextPausedUntil) and implemented waitForGlobalPause() to re-check the global pause deadline after waking.
  • src/anomalyDetector.ts: Added !Number.isFinite(this.sensitivityThreshold) check to reject NaN and infinite values while preserving valid thresholds in (0, 1].
  • Added test suites:
    • test/ammCalculator.test.ts: Added normalization regression test for estimateSwapOutput.
    • test/invoiceBatchProcessor.concurrency.test.ts: Added tests for maxConcurrent validation and initial launch capping.
    • test/invoiceBatchProcessor.rateLimit.test.ts: Added tests for rateLimitPauseMs validation, malformed retry-after fallback, monotonic global pause enforcement, and wake-up pause re-checking.
    • test/anomalyDetector.nan.test.ts: Added tests for NaN sensitivity threshold rejection and upper boundary acceptance.

Testing

  • npx vitest run test/ammCalculator.test.ts: 13/13 tests passed.
  • npx vitest run test/invoiceBatchProcessor.concurrency.test.ts: 7/7 tests passed.
  • npx vitest run test/invoiceBatchProcessor.rateLimit.test.ts: 12/12 tests passed.
  • npx vitest run test/invoiceBatchProcessor.test.ts: 6/6 tests passed.
  • npx vitest run test/anomalyDetector.test.ts: 25/25 tests passed.
  • npx vitest run test/anomalyDetector.nan.test.ts: 2/2 tests passed.
  • All 65 related tests passed concurrently.
  • npm test: 110/110 tests passed across client, retry policy, and network environment suites.

Issues

closes #1008
closes #1009
closes #1010
closes #1011

@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@ushpraise 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

This branch has not been deployed

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

Labels

None yet

Projects

None yet

1 participant