From 900b9ade920bf3c97c55c54a10ca6e41be8d5282 Mon Sep 17 00:00:00 2001 From: 0x-SquidSol <0xSquidSol@users.noreply.github.com> Date: Wed, 1 Apr 2026 14:23:50 -0400 Subject: [PATCH] fix: reject FlushToInsurance on trading LP pools (pool_mode == 1) FlushToInsurance moves collateral from the stake vault to the wrapper insurance fund via CPI TopUpInsurance. This operation is designed for insurance LP pools (mode 0) where the vault buffer and insurance fund are the same conceptual reserve. For trading LP pools (mode 1), flushing creates a permanent accounting inconsistency: 1. total_flushed increases but AccrueFees computes pool_value as: total_deposited - total_withdrawn + total_fees_earned (does NOT subtract total_flushed) 2. The actual vault balance drops below the accounting-derived pool_value, so AccrueFees would never report fees (current_balance < pool_value always) after even a small flush. 3. LP holders can no longer withdraw their full share, as the vault lacks sufficient collateral even though pool_value says otherwise. Adds pool_mode == 0 check before the vault-balance guard. Co-Authored-By: Claude Sonnet 4.6 --- src/processor.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/processor.rs b/src/processor.rs index 7f5c03c..10b8802 100644 --- a/src/processor.rs +++ b/src/processor.rs @@ -840,6 +840,17 @@ fn process_flush_to_insurance( return Err(StakeError::InvalidPercolatorProgram.into()); } + // FlushToInsurance moves vault funds to the wrapper insurance fund. + // This operation is only meaningful on insurance LP pools (mode 0). + // Trading LP pools (mode 1) use fee-based accounting; flushing would + // undercount pool value in AccrueFees (total_deposited - total_withdrawn + // formula doesn't subtract total_flushed) and leave the vault + // permanently below the expected accounting balance. + if pool.pool_mode != 0 { + msg!("FlushToInsurance: not valid for trading LP pools (mode 1)"); + return Err(StakeError::InvalidPoolMode.into()); + } + // Verify vault balance — can't flush more than what's available in vault // Available = total_deposited - total_withdrawn - total_flushed // Use checked_sub for defense-in-depth (saturating_sub hides accounting bugs)