@@ -315,36 +315,58 @@ impl PoolProfiler {
315315 . simulate_swap_through_ticks ( amount_specified, zero_for_one, sqrt_price_limit_x96, true )
316316 . map_err ( |e| Self :: wrap_liquidity_error ( e, location) ) ?;
317317
318- self . apply_swap_quote ( & swap_quote) ;
318+ let tick_mismatch = swap. tick != swap_quote. tick_after ;
319+ let liquidity_mismatch = swap. liquidity != swap_quote. liquidity_after ;
320+ let sqrt_mismatch = swap. sqrt_price_x96 != swap_quote. sqrt_price_after_x96 ;
321+ let structural_mismatch = tick_mismatch || liquidity_mismatch;
322+ if structural_mismatch && !swap_quote. crossed_ticks . is_empty ( ) {
323+ log:: warn!(
324+ "Replay swap simulation diverged after crossing {} ticks on block {}; anchoring event state without simulated tick-cross mutations" ,
325+ swap_quote. crossed_ticks. len( ) ,
326+ swap. block
327+ ) ;
328+ self . apply_swap_quote_without_crossed_ticks ( & swap_quote) ;
329+ } else {
330+ self . apply_swap_quote ( & swap_quote) ;
331+ }
319332
320333 // Verify simulation against event data - correct with event values if mismatch detected
321- if swap . tick != self . state . current_tick {
334+ if tick_mismatch {
322335 log:: warn!(
323336 "Inconsistency in swap processing: Current tick mismatch: simulated {}, event {} on block {}" ,
324- self . state . current_tick ,
337+ swap_quote . tick_after ,
325338 swap. tick,
326339 swap. block
327340 ) ;
341+ }
342+
343+ if swap. tick != self . state . current_tick {
328344 self . state . current_tick = swap. tick ;
329345 }
330346
331- if swap . liquidity != self . tick_map . liquidity {
347+ if liquidity_mismatch {
332348 log:: warn!(
333349 "Inconsistency in swap processing: Active liquidity mismatch: simulated {}, event {} on block {}" ,
334- self . tick_map . liquidity ,
350+ swap_quote . liquidity_after ,
335351 swap. liquidity,
336352 swap. block
337353 ) ;
354+ }
355+
356+ if swap. liquidity != self . tick_map . liquidity {
338357 self . tick_map . liquidity = swap. liquidity ;
339358 }
340359
341- if swap . sqrt_price_x96 != self . state . price_sqrt_ratio_x96 {
360+ if sqrt_mismatch {
342361 log:: warn!(
343362 "Inconsistency in swap processing: Sqrt price mismatch: simulated {}, event {} on block {}" ,
344- self . state . price_sqrt_ratio_x96 ,
363+ swap_quote . sqrt_price_after_x96 ,
345364 swap. sqrt_price_x96,
346365 swap. block
347366 ) ;
367+ }
368+
369+ if swap. sqrt_price_x96 != self . state . price_sqrt_ratio_x96 {
348370 self . state . price_sqrt_ratio_x96 = swap. sqrt_price_x96 ;
349371 }
350372
@@ -641,13 +663,7 @@ impl PoolProfiler {
641663 self . state . current_tick = swap_quote. tick_after ;
642664 self . state . price_sqrt_ratio_x96 = swap_quote. sqrt_price_after_x96 ;
643665
644- if swap_quote. zero_for_one ( ) {
645- self . state . fee_growth_global_0 = swap_quote. fee_growth_global_after ;
646- self . state . protocol_fees_token0 += swap_quote. protocol_fee ;
647- } else {
648- self . state . fee_growth_global_1 = swap_quote. fee_growth_global_after ;
649- self . state . protocol_fees_token1 += swap_quote. protocol_fee ;
650- }
666+ self . apply_swap_quote_fee_state ( swap_quote) ;
651667
652668 for crossed in & swap_quote. crossed_ticks {
653669 let liquidity_net =
@@ -669,6 +685,23 @@ impl PoolProfiler {
669685 ) ;
670686 }
671687
688+ fn apply_swap_quote_without_crossed_ticks ( & mut self , swap_quote : & SwapQuote ) {
689+ self . state . current_tick = swap_quote. tick_after ;
690+ self . state . price_sqrt_ratio_x96 = swap_quote. sqrt_price_after_x96 ;
691+ self . apply_swap_quote_fee_state ( swap_quote) ;
692+ self . analytics . total_swaps += 1 ;
693+ }
694+
695+ fn apply_swap_quote_fee_state ( & mut self , swap_quote : & SwapQuote ) {
696+ if swap_quote. zero_for_one ( ) {
697+ self . state . fee_growth_global_0 = swap_quote. fee_growth_global_after ;
698+ self . state . protocol_fees_token0 += swap_quote. protocol_fee ;
699+ } else {
700+ self . state . fee_growth_global_1 = swap_quote. fee_growth_global_after ;
701+ self . state . protocol_fees_token1 += swap_quote. protocol_fee ;
702+ }
703+ }
704+
672705 /// Wraps a low-level [`LiquidityMathError`](super::error::LiquidityMathError) into a
673706 /// [`PoolProfilerError`] carrying the supplied event location, leaving non-liquidity
674707 /// errors untouched.
0 commit comments