From 4ea59c8f063b6e36a44d8cb99d7a30f0087766e1 Mon Sep 17 00:00:00 2001 From: direkturcrypto Date: Mon, 30 Mar 2026 23:57:27 +0700 Subject: [PATCH] =?UTF-8?q?fix:=20WS=20fill=20signal=20no=20longer=20sets?= =?UTF-8?q?=20pos.filled=20=E2=80=94=20prevents=20partial=20fill=20false-p?= =?UTF-8?q?ositive?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WS handler was marking a side as 'filled' for any fill event regardless of share size. A 2-share partial fill (target: 5) would set pos.no.filled=true, causing the monitoring loop to enter limbo: both sides 'filled' but onchain balance below the 0.5x merge threshold, so no merge ever triggered. WS events now only serve as a wake-up signal for waitForFillOrTimeout. Onchain balance (getTokenBalance) is the sole source of truth for filled flags. --- src/services/makerRebateExecutor.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/services/makerRebateExecutor.js b/src/services/makerRebateExecutor.js index 8a82de5..6f6fcac 100644 --- a/src/services/makerRebateExecutor.js +++ b/src/services/makerRebateExecutor.js @@ -337,12 +337,14 @@ async function monitorUntilFilled(pos, tag, label) { // Side filter removed: RTDS may report side from taker perspective (SELL), // not our maker perspective. We're already gated by proxyWallet + tokenId. const onWsFill = (event) => { + // WS is used only as a wake-up signal — do NOT set pos.filled here. + // Setting filled=true from WS on a partial fill (e.g. 2 of 5 shares) would + // make the loop think the side is done and skip the onchain balance check, + // leaving the position stuck. Onchain balance is the sole source of truth. if (event.tokenId === pos.yes.tokenId) { - pos.yes.filled = true; logger.money(`MakerMM${tag}: YES fill signal (WS) ${event.size?.toFixed(2) || '?'} @ $${event.price?.toFixed(3) || pos.yes.buyPrice.toFixed(3)}`); } if (event.tokenId === pos.no.tokenId) { - pos.no.filled = true; logger.money(`MakerMM${tag}: NO fill signal (WS) ${event.size?.toFixed(2) || '?'} @ $${event.price?.toFixed(3) || pos.no.buyPrice.toFixed(3)}`); } };