critical: Fix position close verification to prevent ghost positions
Problem: - Close transaction confirmed on-chain BUT Drift state takes 5-10s to propagate - Position Manager immediately checked position after close → still showed open - Continued monitoring with stale state → eventually ghost detected - Database marked 'SL closed' but position actually stayed open for 6+ hours - Position was UNPROTECTED during this time (no monitoring, no TP/SL backup) Root Cause: - Transaction confirmation ≠ Drift internal state updated - SDK needs time to propagate on-chain changes to internal cache - Position Manager assumed immediate state consistency Fix (2-layer verification): 1. closePosition(): After 100% close confirmation, wait 5s then verify - Query Drift to confirm position actually gone - If still exists: Return needsVerification=true flag - Log CRITICAL error with transaction signature 2. Position Manager: Handle needsVerification flag - DON'T mark position closed in database - DON'T remove from monitoring - Keep monitoring until ghost detection sees it's actually closed - Prevents premature cleanup with wrong exit data Impact: - Prevents 6-hour unmonitored position exposure - Ensures database exit data matches actual Drift closure - Ghost detection becomes safety net, not primary close mechanism - User positions always protected until VERIFIED closed Files: - lib/drift/orders.ts: Added 5s wait + position verification after close - lib/trading/position-manager.ts: Check needsVerification flag before cleanup Incident: Nov 16, 02:51 - Close confirmed but position stayed open until 08:51
This commit is contained in:
@@ -1202,6 +1202,17 @@ export class PositionManager {
|
||||
console.error(`❌ Failed to close ${trade.symbol}:`, errorMsg)
|
||||
return
|
||||
}
|
||||
|
||||
// CRITICAL: Check if position needs verification (Nov 16, 2025)
|
||||
// If close transaction confirmed but Drift still shows position open,
|
||||
// DON'T mark as closed yet - keep monitoring until Drift confirms
|
||||
if ((result as any).needsVerification) {
|
||||
console.log(`⚠️ Close transaction confirmed but position still exists on Drift`)
|
||||
console.log(` Keeping ${trade.symbol} in monitoring until Drift confirms closure`)
|
||||
console.log(` Ghost detection will handle final cleanup once Drift updates`)
|
||||
// Keep monitoring - ghost detection will eventually see it's closed
|
||||
return
|
||||
}
|
||||
|
||||
// Update trade state
|
||||
if (percentToClose >= 100) {
|
||||
|
||||
Reference in New Issue
Block a user