@@ -5,7 +5,7 @@ import { DynamoUnimindParametersRepository } from '../../../lib/repositories/uni
55import { DutchOrdersRepository } from '../../../lib/repositories/dutch-orders-repository'
66import { DutchV3OrderEntity , ORDER_STATUS } from '../../../lib/entities'
77import { OrderType } from '@uniswap/uniswapx-sdk'
8- import { DEFAULT_UNIMIND_PARAMETERS , UNIMIND_ALGORITHM_VERSION , UNIMIND_DEV_SWAPPER_ADDRESS , UNIMIND_UPDATE_THRESHOLD } from '../../../lib/util/constants'
8+ import { DEFAULT_UNIMIND_PARAMETERS , UNIMIND_ALGORITHM_VERSION , UNIMIND_DEV_SWAPPER_ADDRESS , UNIMIND_UPDATE_THRESHOLD , UNIMIND_CIRCUIT_BREAKER_MIN_ORDERS } from '../../../lib/util/constants'
99
1010const dynamoConfig = {
1111 convertEmptyValues : true ,
@@ -281,6 +281,90 @@ describe('updateParameters Test', () => {
281281 expect ( pairData ?. lastUpdatedAt ) . toBeDefined ( )
282282 } )
283283
284+ it ( 'should not trigger circuit breaker when fill rate is above threshold' , async ( ) => {
285+ const cbPair = '0xCB01-0xCB02-42161'
286+ const filledOrder : DutchV3OrderEntity = {
287+ ...mockOrder ,
288+ pair : cbPair ,
289+ orderStatus : ORDER_STATUS . FILLED ,
290+ fillBlock : 315641562 ,
291+ cosignerData : {
292+ ...mockOrder . cosignerData ,
293+ decayStartBlock : 315641558 ,
294+ } ,
295+ priceImpact : 0.5 ,
296+ usedUnimind : true ,
297+ }
298+
299+ // Insert UNIMIND_CIRCUIT_BREAKER_MIN_ORDERS filled orders
300+ const orders : DutchV3OrderEntity [ ] = [ ]
301+ for ( let i = 0 ; i < UNIMIND_CIRCUIT_BREAKER_MIN_ORDERS ; i ++ ) {
302+ const order = { ...filledOrder , orderHash : `0xCB_FILLED_${ i } ` }
303+ orders . push ( order )
304+ await ordersTable . putOrderAndUpdateNonceTransaction ( order )
305+ }
306+
307+ // Pair exists in early batch, no orders counted yet
308+ await unimindParametersRepository . put ( {
309+ pair : cbPair ,
310+ intrinsicValues : DEFAULT_UNIMIND_PARAMETERS ,
311+ count : 0 ,
312+ version : UNIMIND_ALGORITHM_VERSION ,
313+ batchNumber : 2 , // Within circuit breaker window (<= 5)
314+ lastUpdatedAt : Math . floor ( Date . now ( ) / 1000 ) ,
315+ } )
316+
317+ await updateParameters ( unimindParametersRepository , ordersTable , log )
318+
319+ const pairData = await unimindParametersRepository . getByPair ( cbPair )
320+ // Fill rate is 1.0 (100%), well above 25% threshold — circuit breaker should NOT fire
321+ expect ( pairData ?. batchNumber ) . toBe ( 2 ) // Unchanged — no update triggered
322+ expect ( pairData ?. count ) . toBe ( UNIMIND_CIRCUIT_BREAKER_MIN_ORDERS ) // Just incremented
323+
324+ // Cleanup
325+ await ordersTable . deleteOrders ( orders . map ( ( o ) => o . orderHash ) )
326+ } )
327+
328+ it ( 'should trigger circuit breaker when fill rate is below threshold' , async ( ) => {
329+ const cbPair = '0xCB03-0xCB04-42161'
330+ const expiredOrder : DutchV3OrderEntity = {
331+ ...mockOrder ,
332+ pair : cbPair ,
333+ orderStatus : ORDER_STATUS . EXPIRED ,
334+ fillBlock : undefined as any ,
335+ priceImpact : 0.5 ,
336+ usedUnimind : true ,
337+ }
338+
339+ // Insert UNIMIND_CIRCUIT_BREAKER_MIN_ORDERS expired orders
340+ const orders : DutchV3OrderEntity [ ] = [ ]
341+ for ( let i = 0 ; i < UNIMIND_CIRCUIT_BREAKER_MIN_ORDERS ; i ++ ) {
342+ const order = { ...expiredOrder , orderHash : `0xCB_EXPIRED_${ i } ` }
343+ orders . push ( order )
344+ await ordersTable . putOrderAndUpdateNonceTransaction ( order )
345+ }
346+
347+ // Pair exists in early batch, no orders counted yet
348+ await unimindParametersRepository . put ( {
349+ pair : cbPair ,
350+ intrinsicValues : DEFAULT_UNIMIND_PARAMETERS ,
351+ count : 0 ,
352+ version : UNIMIND_ALGORITHM_VERSION ,
353+ batchNumber : 2 ,
354+ lastUpdatedAt : Math . floor ( Date . now ( ) / 1000 ) ,
355+ } )
356+
357+ await updateParameters ( unimindParametersRepository , ordersTable , log )
358+
359+ const pairData = await unimindParametersRepository . getByPair ( cbPair )
360+ // Fill rate is 0.0, below 25% threshold — circuit breaker SHOULD fire
361+ expect ( pairData ?. batchNumber ) . toBe ( 3 ) // Incremented — update was triggered
362+ expect ( pairData ?. count ) . toBe ( 0 ) // Reset after update
363+
364+ // Cleanup
365+ await ordersTable . deleteOrders ( orders . map ( ( o ) => o . orderHash ) )
366+ } )
367+
284368 it ( 'should reset batchNumber to 0 on version mismatch' , async ( ) => {
285369 await unimindParametersRepository . put ( {
286370 pair : testPair ,
0 commit comments