@@ -50,6 +50,7 @@ export interface CapitalCostConfigOverride {
50
50
default : CapitalCostConfig ;
51
51
routeOverrides ?: Record < ChainIdAsString , Record < ChainIdAsString , CapitalCostConfig > > ;
52
52
destinationChainOverrides ?: Record < ChainIdAsString , CapitalCostConfig > ;
53
+ originChainOverrides ?: Record < ChainIdAsString , CapitalCostConfig > ;
53
54
}
54
55
export type RelayCapitalCostConfig = CapitalCostConfigOverride | CapitalCostConfig ;
55
56
export interface BaseRelayFeeCalculatorConfig {
@@ -155,6 +156,8 @@ export class RelayFeeCalculator {
155
156
) ;
156
157
assert ( Object . keys ( this . capitalCostsConfig ) . length > 0 , "capitalCostsConfig must have at least one entry" ) ;
157
158
this . logger = logger || DEFAULT_LOGGER ;
159
+ // warn developer of any possible conflicting config overrides
160
+ this . checkAllConfigConflicts ( ) ;
158
161
}
159
162
160
163
/**
@@ -194,8 +197,11 @@ export class RelayFeeCalculator {
194
197
for ( const toChainIdRoutes of Object . values ( config . routeOverrides || { } ) ) {
195
198
Object . values ( toChainIdRoutes ) . forEach ( this . validateCapitalCostsConfig ) ;
196
199
}
200
+ // Validate origin chain overrides
201
+ Object . values ( config . originChainOverrides || { } ) . forEach ( this . validateCapitalCostsConfig ) ;
197
202
// Validate destination chain overrides
198
203
Object . values ( config . destinationChainOverrides || { } ) . forEach ( this . validateCapitalCostsConfig ) ;
204
+
199
205
return config ;
200
206
}
201
207
@@ -326,9 +332,26 @@ export class RelayFeeCalculator {
326
332
// bound to an upper bound. After the kink, the fee % increase will be fixed, and slowly approach the upper bound
327
333
// for very large amount inputs.
328
334
else {
329
- const destinationChainOverride = tokenCostConfig ?. destinationChainOverrides ?. [ _destinationRoute || "" ] ;
335
+ // Order of specificity (most specific to least specific):
336
+ // 1. Route overrides (both origin and destination)
337
+ // 2. Destination chain overrides
338
+ // 3. Origin chain overrides
339
+ // 4. Default config
330
340
const routeOverride = tokenCostConfig ?. routeOverrides ?. [ _originRoute || "" ] ?. [ _destinationRoute || "" ] ;
331
- const config : CapitalCostConfig = routeOverride ?? destinationChainOverride ?? tokenCostConfig . default ;
341
+ const destinationChainOverride = tokenCostConfig ?. destinationChainOverrides ?. [ _destinationRoute || "" ] ;
342
+ const originChainOverride = tokenCostConfig ?. originChainOverrides ?. [ _originRoute || "" ] ;
343
+ const config : CapitalCostConfig =
344
+ routeOverride ?? destinationChainOverride ?? originChainOverride ?? tokenCostConfig . default ;
345
+
346
+ // Check and log warnings for configuration conflicts
347
+ this . warnIfConfigConflicts (
348
+ _tokenSymbol ,
349
+ _originRoute || "" ,
350
+ _destinationRoute || "" ,
351
+ routeOverride ,
352
+ destinationChainOverride ,
353
+ originChainOverride
354
+ ) ;
332
355
333
356
// Scale amount "y" to 18 decimals.
334
357
const y = toBN ( _amountToRelay ) . mul ( toBNWei ( "1" , 18 - config . decimals ) ) ;
@@ -356,6 +379,88 @@ export class RelayFeeCalculator {
356
379
}
357
380
}
358
381
382
+ /**
383
+ * Checks for configuration conflicts across all token symbols and their associated chain configurations.
384
+ * This method examines the capital costs configuration for each token and identifies any overlapping
385
+ * or conflicting configurations between route overrides, destination chain overrides, and origin chain overrides.
386
+ * If conflicts are found, warnings will be logged via the warnIfConfigConflicts method.
387
+ */
388
+ private checkAllConfigConflicts ( ) : void {
389
+ for ( const [ tokenSymbol , tokenConfig ] of Object . entries ( this . capitalCostsConfig ) ) {
390
+ // Get all origin chains that have specific configurations
391
+ const originChains = new Set < string > ( Object . keys ( tokenConfig . originChainOverrides || { } ) ) ;
392
+ // Get all destination chains that have specific configurations
393
+ const destChains = new Set < string > ( Object . keys ( tokenConfig . destinationChainOverrides || { } ) ) ;
394
+
395
+ // Add all chains from route overrides
396
+ if ( tokenConfig . routeOverrides ) {
397
+ Object . keys ( tokenConfig . routeOverrides ) . forEach ( ( originChain ) => {
398
+ originChains . add ( originChain ) ;
399
+ Object . keys ( tokenConfig . routeOverrides ! [ originChain ] ) . forEach ( ( destChain ) => {
400
+ destChains . add ( destChain ) ;
401
+ } ) ;
402
+ } ) ;
403
+ }
404
+
405
+ // If there are no specific chain configurations, just check the default case
406
+ if ( originChains . size === 0 && destChains . size === 0 ) {
407
+ continue ;
408
+ }
409
+
410
+ // Check for conflicts between all combinations of origin and destination chains
411
+ for ( const originChain of Array . from ( originChains ) ) {
412
+ for ( const destChain of Array . from ( destChains ) ) {
413
+ const routeOverride = tokenConfig . routeOverrides ?. [ originChain ] ?. [ destChain ] ;
414
+ const destinationChainOverride = tokenConfig . destinationChainOverrides ?. [ destChain ] ;
415
+ const originChainOverride = tokenConfig . originChainOverrides ?. [ originChain ] ;
416
+
417
+ this . warnIfConfigConflicts (
418
+ tokenSymbol ,
419
+ originChain ,
420
+ destChain ,
421
+ routeOverride ,
422
+ destinationChainOverride ,
423
+ originChainOverride
424
+ ) ;
425
+ }
426
+ }
427
+ }
428
+ }
429
+
430
+ /**
431
+ * Log a warning if multiple configuration types apply to the same route
432
+ * @private
433
+ */
434
+ private warnIfConfigConflicts (
435
+ tokenSymbol : string ,
436
+ originChain : string ,
437
+ destChain : string ,
438
+ routeOverride ?: CapitalCostConfig ,
439
+ destinationChainOverride ?: CapitalCostConfig ,
440
+ originChainOverride ?: CapitalCostConfig
441
+ ) : void {
442
+ const overrideCount = [ routeOverride , destinationChainOverride , originChainOverride ] . filter ( Boolean ) . length ;
443
+
444
+ if ( overrideCount > 1 ) {
445
+ const configUsed = routeOverride
446
+ ? "route override"
447
+ : destinationChainOverride
448
+ ? "destination chain override"
449
+ : originChainOverride
450
+ ? "origin chain override"
451
+ : "default override" ;
452
+
453
+ this . logger . warn ( {
454
+ at : "RelayFeeCalculator" ,
455
+ message : `Multiple configurations found for token ${ tokenSymbol } from chain ${ originChain } to chain ${ destChain } ` ,
456
+ configUsed,
457
+ routeOverride,
458
+ destinationChainOverride,
459
+ originChainOverride,
460
+ } ) ;
461
+ }
462
+ }
463
+
359
464
/**
360
465
* Retrieves the relayer fee details for a deposit.
361
466
* @param deposit A valid deposit object to reason about
0 commit comments