@@ -314,6 +314,312 @@ fn execute_message_interchain_transfer_should_scale_the_amount_when_source_decim
314
314
) ;
315
315
}
316
316
317
+ #[ test]
318
+ fn execute_message_interchain_transfer_should_scale_correctly_in_3_chain_cycle ( ) {
319
+ let TestMessage {
320
+ source_its_contract,
321
+ ..
322
+ } = TestMessage :: dummy ( ) ;
323
+ let configs = vec ! [
324
+ (
325
+ "ethereum" . parse( ) . unwrap( ) ,
326
+ source_its_contract. clone( ) ,
327
+ Uint256 :: MAX . try_into( ) . unwrap( ) ,
328
+ u8 :: MAX ,
329
+ ) ,
330
+ (
331
+ "stellar" . parse( ) . unwrap( ) ,
332
+ source_its_contract. clone( ) ,
333
+ Uint256 :: from( u128 :: MAX ) . try_into( ) . unwrap( ) ,
334
+ 12 ,
335
+ ) ,
336
+ (
337
+ "sui" . parse( ) . unwrap( ) ,
338
+ source_its_contract. clone( ) ,
339
+ Uint256 :: from( u64 :: MAX ) . try_into( ) . unwrap( ) ,
340
+ 6 ,
341
+ ) ,
342
+ ] ;
343
+
344
+ let ( mut deps, TestMessage { router_message, .. } ) =
345
+ utils:: setup_multiple_chains ( configs. clone ( ) ) ;
346
+ let token_id = TokenId :: new ( [ 1 ; 32 ] ) ;
347
+ let deploy_token = DeployInterchainToken {
348
+ token_id,
349
+ name : "Test" . try_into ( ) . unwrap ( ) ,
350
+ symbol : "TST" . try_into ( ) . unwrap ( ) ,
351
+ decimals : 18 ,
352
+ minter : None ,
353
+ } ;
354
+ let hub_message = HubMessage :: SendToHub {
355
+ destination_chain : configs[ 1 ] . 0 . clone ( ) ,
356
+ message : deploy_token. clone ( ) . into ( ) ,
357
+ } ;
358
+ assert_ok ! ( utils:: execute_hub_message(
359
+ deps. as_mut( ) ,
360
+ CrossChainId {
361
+ source_chain: configs[ 0 ] . 0 . clone( ) ,
362
+ message_id: router_message. cc_id. message_id. clone( )
363
+ } ,
364
+ source_its_contract. clone( ) ,
365
+ hub_message,
366
+ ) ) ;
367
+
368
+ let hub_message = HubMessage :: SendToHub {
369
+ destination_chain : configs[ 2 ] . 0 . clone ( ) ,
370
+ message : deploy_token. clone ( ) . into ( ) ,
371
+ } ;
372
+ assert_ok ! ( utils:: execute_hub_message(
373
+ deps. as_mut( ) ,
374
+ CrossChainId {
375
+ source_chain: configs[ 0 ] . 0 . clone( ) ,
376
+ message_id: router_message. cc_id. message_id. clone( )
377
+ } ,
378
+ source_its_contract. clone( ) ,
379
+ hub_message,
380
+ ) ) ;
381
+
382
+ let amount: nonempty:: Uint256 = Uint256 :: from_u128 ( 1000000000000000000u128 )
383
+ . try_into ( )
384
+ . unwrap ( ) ;
385
+
386
+ // send from chain 0 to chain 1
387
+ let transfer = InterchainTransfer {
388
+ token_id,
389
+ source_address : HexBinary :: from ( [ 1 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
390
+ destination_address : HexBinary :: from ( [ 2 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
391
+ amount,
392
+ data : None ,
393
+ } ;
394
+ let hub_message = HubMessage :: SendToHub {
395
+ destination_chain : configs[ 1 ] . 0 . clone ( ) ,
396
+ message : transfer. into ( ) ,
397
+ } ;
398
+
399
+ assert_ok ! ( utils:: execute_hub_message(
400
+ deps. as_mut( ) ,
401
+ CrossChainId {
402
+ source_chain: configs[ 0 ] . 0 . clone( ) ,
403
+ message_id: router_message. cc_id. message_id. clone( )
404
+ } ,
405
+ source_its_contract. clone( ) ,
406
+ hub_message,
407
+ ) ) ;
408
+
409
+ let scaling_factor = Uint256 :: from_u128 ( 10 )
410
+ . checked_pow ( deploy_token. decimals . abs_diff ( configs[ 1 ] . 3 ) . into ( ) )
411
+ . unwrap ( ) ;
412
+ let scaled_amount = amount. clone ( ) . checked_div ( scaling_factor) . unwrap ( ) ;
413
+
414
+ // send back from destination to source
415
+ let transfer = InterchainTransfer {
416
+ token_id,
417
+ source_address : HexBinary :: from ( [ 2 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
418
+ destination_address : HexBinary :: from ( [ 1 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
419
+ amount : scaled_amount. try_into ( ) . unwrap ( ) ,
420
+ data : None ,
421
+ } ;
422
+
423
+ let hub_message = HubMessage :: SendToHub {
424
+ destination_chain : configs[ 2 ] . 0 . clone ( ) ,
425
+ message : transfer. into ( ) ,
426
+ } ;
427
+
428
+ assert_ok ! ( utils:: execute_hub_message(
429
+ deps. as_mut( ) ,
430
+ CrossChainId {
431
+ source_chain: configs[ 1 ] . 0 . clone( ) ,
432
+ message_id: router_message. cc_id. message_id. clone( )
433
+ } ,
434
+ source_its_contract. clone( ) ,
435
+ hub_message,
436
+ ) ) ;
437
+
438
+ let scaling_factor = Uint256 :: from_u128 ( 10 )
439
+ . checked_pow ( deploy_token. decimals . abs_diff ( configs[ 2 ] . 3 ) . into ( ) )
440
+ . unwrap ( ) ;
441
+ let scaled_amount = amount. clone ( ) . checked_div ( scaling_factor) . unwrap ( ) ;
442
+
443
+ // send back from destination to source
444
+ let transfer = InterchainTransfer {
445
+ token_id,
446
+ source_address : HexBinary :: from ( [ 2 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
447
+ destination_address : HexBinary :: from ( [ 1 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
448
+ amount : scaled_amount. try_into ( ) . unwrap ( ) ,
449
+ data : None ,
450
+ } ;
451
+
452
+ let hub_message = HubMessage :: SendToHub {
453
+ destination_chain : configs[ 0 ] . 0 . clone ( ) ,
454
+ message : transfer. into ( ) ,
455
+ } ;
456
+
457
+ let response_to_destination = assert_ok ! ( utils:: execute_hub_message(
458
+ deps. as_mut( ) ,
459
+ CrossChainId {
460
+ source_chain: configs[ 2 ] . 0 . clone( ) ,
461
+ message_id: router_message. cc_id. message_id. clone( )
462
+ } ,
463
+ source_its_contract,
464
+ hub_message,
465
+ ) ) ;
466
+
467
+ goldie:: assert_json!( response_to_destination) ;
468
+ }
469
+
470
+ #[ test]
471
+ fn execute_message_interchain_transfer_should_scale_correctly_in_3_chain_cycle_with_dust ( ) {
472
+ let TestMessage {
473
+ source_its_contract,
474
+ ..
475
+ } = TestMessage :: dummy ( ) ;
476
+ let configs = vec ! [
477
+ (
478
+ "ethereum" . parse( ) . unwrap( ) ,
479
+ source_its_contract. clone( ) ,
480
+ Uint256 :: MAX . try_into( ) . unwrap( ) ,
481
+ u8 :: MAX ,
482
+ ) ,
483
+ (
484
+ "stellar" . parse( ) . unwrap( ) ,
485
+ source_its_contract. clone( ) ,
486
+ Uint256 :: from( u128 :: MAX ) . try_into( ) . unwrap( ) ,
487
+ 12 ,
488
+ ) ,
489
+ (
490
+ "sui" . parse( ) . unwrap( ) ,
491
+ source_its_contract. clone( ) ,
492
+ Uint256 :: from( u64 :: MAX ) . try_into( ) . unwrap( ) ,
493
+ 6 ,
494
+ ) ,
495
+ ] ;
496
+
497
+ let ( mut deps, TestMessage { router_message, .. } ) =
498
+ utils:: setup_multiple_chains ( configs. clone ( ) ) ;
499
+ let token_id = TokenId :: new ( [ 1 ; 32 ] ) ;
500
+ let deploy_token = DeployInterchainToken {
501
+ token_id,
502
+ name : "Test" . try_into ( ) . unwrap ( ) ,
503
+ symbol : "TST" . try_into ( ) . unwrap ( ) ,
504
+ decimals : 18 ,
505
+ minter : None ,
506
+ } ;
507
+ let hub_message = HubMessage :: SendToHub {
508
+ destination_chain : configs[ 1 ] . 0 . clone ( ) ,
509
+ message : deploy_token. clone ( ) . into ( ) ,
510
+ } ;
511
+ assert_ok ! ( utils:: execute_hub_message(
512
+ deps. as_mut( ) ,
513
+ CrossChainId {
514
+ source_chain: configs[ 0 ] . 0 . clone( ) ,
515
+ message_id: router_message. cc_id. message_id. clone( )
516
+ } ,
517
+ source_its_contract. clone( ) ,
518
+ hub_message,
519
+ ) ) ;
520
+
521
+ let hub_message = HubMessage :: SendToHub {
522
+ destination_chain : configs[ 2 ] . 0 . clone ( ) ,
523
+ message : deploy_token. clone ( ) . into ( ) ,
524
+ } ;
525
+ assert_ok ! ( utils:: execute_hub_message(
526
+ deps. as_mut( ) ,
527
+ CrossChainId {
528
+ source_chain: configs[ 0 ] . 0 . clone( ) ,
529
+ message_id: router_message. cc_id. message_id. clone( )
530
+ } ,
531
+ source_its_contract. clone( ) ,
532
+ hub_message,
533
+ ) ) ;
534
+
535
+ let amount: nonempty:: Uint256 = Uint256 :: from_u128 ( 1000000000010000001u128 )
536
+ . try_into ( )
537
+ . unwrap ( ) ;
538
+
539
+ // send from chain 0 to chain 1
540
+ let transfer = InterchainTransfer {
541
+ token_id,
542
+ source_address : HexBinary :: from ( [ 1 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
543
+ destination_address : HexBinary :: from ( [ 2 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
544
+ amount,
545
+ data : None ,
546
+ } ;
547
+ let hub_message = HubMessage :: SendToHub {
548
+ destination_chain : configs[ 1 ] . 0 . clone ( ) ,
549
+ message : transfer. into ( ) ,
550
+ } ;
551
+
552
+ assert_ok ! ( utils:: execute_hub_message(
553
+ deps. as_mut( ) ,
554
+ CrossChainId {
555
+ source_chain: configs[ 0 ] . 0 . clone( ) ,
556
+ message_id: router_message. cc_id. message_id. clone( )
557
+ } ,
558
+ source_its_contract. clone( ) ,
559
+ hub_message,
560
+ ) ) ;
561
+
562
+ let scaling_factor = Uint256 :: from_u128 ( 10 )
563
+ . checked_pow ( deploy_token. decimals . abs_diff ( configs[ 1 ] . 3 ) . into ( ) )
564
+ . unwrap ( ) ;
565
+ let scaled_amount = amount. clone ( ) . checked_div ( scaling_factor) . unwrap ( ) ;
566
+
567
+ // send back from destination to source
568
+ let transfer = InterchainTransfer {
569
+ token_id,
570
+ source_address : HexBinary :: from ( [ 2 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
571
+ destination_address : HexBinary :: from ( [ 1 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
572
+ amount : scaled_amount. try_into ( ) . unwrap ( ) ,
573
+ data : None ,
574
+ } ;
575
+
576
+ let hub_message = HubMessage :: SendToHub {
577
+ destination_chain : configs[ 2 ] . 0 . clone ( ) ,
578
+ message : transfer. into ( ) ,
579
+ } ;
580
+
581
+ assert_ok ! ( utils:: execute_hub_message(
582
+ deps. as_mut( ) ,
583
+ CrossChainId {
584
+ source_chain: configs[ 1 ] . 0 . clone( ) ,
585
+ message_id: router_message. cc_id. message_id. clone( )
586
+ } ,
587
+ source_its_contract. clone( ) ,
588
+ hub_message,
589
+ ) ) ;
590
+
591
+ let scaling_factor = Uint256 :: from_u128 ( 10 )
592
+ . checked_pow ( deploy_token. decimals . abs_diff ( configs[ 2 ] . 3 ) . into ( ) )
593
+ . unwrap ( ) ;
594
+ let scaled_amount = amount. clone ( ) . checked_div ( scaling_factor) . unwrap ( ) ;
595
+
596
+ // send back from destination to source
597
+ let transfer = InterchainTransfer {
598
+ token_id,
599
+ source_address : HexBinary :: from ( [ 2 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
600
+ destination_address : HexBinary :: from ( [ 1 ; 32 ] ) . try_into ( ) . unwrap ( ) ,
601
+ amount : scaled_amount. try_into ( ) . unwrap ( ) ,
602
+ data : None ,
603
+ } ;
604
+
605
+ let hub_message = HubMessage :: SendToHub {
606
+ destination_chain : configs[ 0 ] . 0 . clone ( ) ,
607
+ message : transfer. into ( ) ,
608
+ } ;
609
+
610
+ let response_to_destination = assert_ok ! ( utils:: execute_hub_message(
611
+ deps. as_mut( ) ,
612
+ CrossChainId {
613
+ source_chain: configs[ 2 ] . 0 . clone( ) ,
614
+ message_id: router_message. cc_id. message_id. clone( )
615
+ } ,
616
+ source_its_contract,
617
+ hub_message,
618
+ ) ) ;
619
+
620
+ goldie:: assert_json!( response_to_destination) ;
621
+ }
622
+
317
623
#[ test]
318
624
fn execute_message_deploy_interchain_token_should_translate_decimals_when_max_uints_are_different ( )
319
625
{
0 commit comments