@@ -29,7 +29,7 @@ import {
29
29
makeCustomTransport ,
30
30
} from "./utils" ;
31
31
import assert from "assert" ;
32
- import { TOKEN_SYMBOLS_MAP } from "@across-protocol/constants" ;
32
+ import { CHAIN_IDs , TOKEN_SYMBOLS_MAP } from "@across-protocol/constants" ;
33
33
import { EMPTY_MESSAGE , ZERO_ADDRESS } from "../src/constants" ;
34
34
import { SpokePool } from "@across-protocol/contracts" ;
35
35
import { QueryBase , QueryBase__factory } from "../src/relayFeeCalculator" ;
@@ -280,6 +280,121 @@ describe("RelayFeeCalculator", () => {
280
280
assert . equal ( client . capitalFeePercent ( "0" , "ZERO_CUTOFF_WBTC" ) . toString ( ) , Number . MAX_SAFE_INTEGER . toString ( ) ) ;
281
281
assert . equal ( client . capitalFeePercent ( "0" , "WBTC" ) . toString ( ) , Number . MAX_SAFE_INTEGER . toString ( ) ) ;
282
282
} ) ;
283
+
284
+ it ( "destinationChainOverrides" , ( ) => {
285
+ // Create a client with destination chain and route overrides
286
+ const token = TOKEN_SYMBOLS_MAP . USDC ;
287
+
288
+ const customCapitalCostsConfig = {
289
+ [ token . symbol ] : {
290
+ default : {
291
+ lowerBound : toBNWei ( "0.0003" ) . toString ( ) ,
292
+ upperBound : toBNWei ( "0.002" ) . toString ( ) ,
293
+ cutoff : toBNWei ( "15" ) . toString ( ) ,
294
+ decimals : token . decimals ,
295
+ } ,
296
+ destinationChainOverrides : {
297
+ // Override for destination chain ARBITRUM
298
+ [ CHAIN_IDs . ARBITRUM ] : {
299
+ lowerBound : toBNWei ( "0.0005" ) . toString ( ) ,
300
+ upperBound : toBNWei ( "0.003" ) . toString ( ) ,
301
+ cutoff : toBNWei ( "10" ) . toString ( ) ,
302
+ decimals : token . decimals ,
303
+ } ,
304
+ } ,
305
+ routeOverrides : {
306
+ // Override for route MAINNET->ARBITRUM
307
+ [ CHAIN_IDs . MAINNET ] : {
308
+ [ CHAIN_IDs . ARBITRUM ] : {
309
+ lowerBound : toBNWei ( "0.0007" ) . toString ( ) ,
310
+ upperBound : toBNWei ( "0.004" ) . toString ( ) ,
311
+ cutoff : toBNWei ( "8" ) . toString ( ) ,
312
+ decimals : token . decimals ,
313
+ } ,
314
+ } ,
315
+ } ,
316
+ } ,
317
+ } ;
318
+
319
+ const client = new RelayFeeCalculator ( {
320
+ queries,
321
+ capitalCostsConfig : customCapitalCostsConfig ,
322
+ } ) ;
323
+
324
+ // Get config values for cleaner assertions
325
+ const defaultConfig = customCapitalCostsConfig [ token . symbol ] . default ;
326
+ const chainOverride = customCapitalCostsConfig [ token . symbol ] . destinationChainOverrides [ CHAIN_IDs . ARBITRUM ] ;
327
+ const routeOverride = customCapitalCostsConfig [ token . symbol ] . routeOverrides [ CHAIN_IDs . MAINNET ] [ CHAIN_IDs . ARBITRUM ] ;
328
+
329
+ // Test using default config (no routes specified)
330
+ const defaultFee = client . capitalFeePercent ( toBNWei ( "1" , token . decimals ) , token . symbol ) ;
331
+ assert . ok ( toBN ( defaultFee ) . gte ( toBN ( defaultConfig . lowerBound ) ) , "Default fee should be at least the lower bound" ) ;
332
+ assert . ok ( toBN ( defaultFee ) . lt ( toBN ( defaultConfig . upperBound ) ) , "Default fee should be less than the upper bound" ) ;
333
+
334
+ // Test using destination chain override (only destination specified)
335
+ const destinationFee = client . capitalFeePercent (
336
+ toBNWei ( "1" , token . decimals ) ,
337
+ token . symbol ,
338
+ undefined ,
339
+ CHAIN_IDs . ARBITRUM . toString ( )
340
+ ) ;
341
+ assert . ok (
342
+ toBN ( destinationFee ) . gte ( toBN ( chainOverride . lowerBound ) ) ,
343
+ "Destination override fee should be at least its lower bound"
344
+ ) ;
345
+ assert . ok (
346
+ toBN ( destinationFee ) . lt ( toBN ( chainOverride . upperBound ) ) ,
347
+ "Destination override fee should be less than its upper bound"
348
+ ) ;
349
+
350
+ // Test using route-specific override (both origin and destination specified)
351
+ const routeFee = client . capitalFeePercent (
352
+ toBNWei ( "1" , token . decimals ) ,
353
+ token . symbol ,
354
+ CHAIN_IDs . MAINNET . toString ( ) ,
355
+ CHAIN_IDs . ARBITRUM . toString ( )
356
+ ) ;
357
+ assert . ok (
358
+ toBN ( routeFee ) . gte ( toBN ( routeOverride . lowerBound ) ) ,
359
+ "Route override fee should be at least its lower bound"
360
+ ) ;
361
+ assert . ok (
362
+ toBN ( routeFee ) . lt ( toBN ( routeOverride . upperBound ) ) ,
363
+ "Route override fee should be less than its upper bound"
364
+ ) ;
365
+
366
+ // Test fallback to destination chain override when a route is not specifically overridden
367
+ const fallbackToDestFee = client . capitalFeePercent (
368
+ toBNWei ( "1" , token . decimals ) ,
369
+ token . symbol ,
370
+ CHAIN_IDs . OPTIMISM . toString ( ) ,
371
+ CHAIN_IDs . ARBITRUM . toString ( )
372
+ ) ;
373
+ assert . ok (
374
+ toBN ( fallbackToDestFee ) . gte ( toBN ( chainOverride . lowerBound ) ) ,
375
+ "Fallback to destination fee should be at least the destination lower bound"
376
+ ) ;
377
+ assert . ok (
378
+ toBN ( fallbackToDestFee ) . lt ( toBN ( chainOverride . upperBound ) ) ,
379
+ "Fallback to destination fee should be less than the destination upper bound"
380
+ ) ;
381
+
382
+ // Test fallback to default when route doesn't match and no destination chain override exists
383
+ const fallbackToDefaultFee = client . capitalFeePercent (
384
+ toBNWei ( "1" , token . decimals ) ,
385
+ token . symbol ,
386
+ CHAIN_IDs . OPTIMISM . toString ( ) ,
387
+ CHAIN_IDs . POLYGON . toString ( )
388
+ ) ;
389
+ assert . ok (
390
+ toBN ( fallbackToDefaultFee ) . gte ( toBN ( defaultConfig . lowerBound ) ) ,
391
+ "Fallback to default fee should be at least the default lower bound"
392
+ ) ;
393
+ assert . ok (
394
+ toBN ( fallbackToDefaultFee ) . lt ( toBN ( defaultConfig . upperBound ) ) ,
395
+ "Fallback to default fee should be less than the default upper bound"
396
+ ) ;
397
+ } ) ;
283
398
} ) ;
284
399
285
400
describe ( "RelayFeeCalculator: Composable Bridging" , function ( ) {
0 commit comments