@@ -771,17 +771,24 @@ fn ahm_transfer_of_dot_via_xtokens_to_sibling_parachain() {
771771 let sibling_sovereign_account_on_asset_hub = sovereign_account_on_sibling ( SIBLING_PARA_ID ) ;
772772
773773 TestNet :: reset ( ) ;
774-
775- // Before the migration => Everything goes as always, transfers are possible and the reserve is
776- // Polkadot
774+ // Fund sovereign accounts
777775 PolkadotNet :: execute_with ( || {
778776 assert_ok ! ( polkadot_runtime:: Balances :: transfer(
779777 polkadot_runtime:: RuntimeOrigin :: signed( ALICE . into( ) ) ,
780778 sp_runtime:: MultiAddress :: Id ( interlay_sovereign_account_on_polkadot( ) ) ,
781779 10 * DOT . one( )
782780 ) ) ;
783781 } ) ;
782+ AssetHub :: execute_with ( || {
783+ assert_ok ! ( polkadot_asset_hub_runtime:: Balances :: force_set_balance(
784+ polkadot_asset_hub_runtime:: RuntimeOrigin :: root( ) ,
785+ sp_runtime:: MultiAddress :: Id ( interlay_sovereign_account_on_asset_hub. clone( ) ) ,
786+ 10 * DOT . one( )
787+ ) ) ;
788+ } ) ;
784789
790+ // Before the migration => Everything goes as always, transfers are possible and the reserve is
791+ // Polkadot
785792 Interlay :: execute_with ( || {
786793 assert_eq ! (
787794 AbsoluteReserveProviderMigrationPhase :: <Runtime >:: reserve( & concrete_fungible( MultiLocation :: parent( ) ) ) ,
@@ -852,21 +859,13 @@ fn ahm_transfer_of_dot_via_xtokens_to_sibling_parachain() {
852859
853860 // Before executing the transfer, we need to set the sibling's migration status to Completed.
854861 // It's runtime is Interlay's runtime anyway, so it should be able to recognize AH as the
855- // reserve. Additionally we need to fund Interlay's sovereign account on AH
862+ // reserve.
856863 Sibling :: execute_with ( || {
857864 assert_ok ! ( XTokens :: set_migration_phase(
858865 RuntimeOrigin :: root( ) ,
859866 MigrationPhase :: Completed
860867 ) ) ;
861868 } ) ;
862- // Fund sovereign accounts on AH
863- AssetHub :: execute_with ( || {
864- assert_ok ! ( polkadot_asset_hub_runtime:: Balances :: force_set_balance(
865- polkadot_asset_hub_runtime:: RuntimeOrigin :: root( ) ,
866- sp_runtime:: MultiAddress :: Id ( interlay_sovereign_account_on_asset_hub. clone( ) ) ,
867- 10 * DOT . one( )
868- ) ) ;
869- } ) ;
870869
871870 Interlay :: execute_with ( || {
872871 assert_eq ! (
@@ -910,6 +909,346 @@ fn ahm_transfer_of_dot_via_xtokens_to_sibling_parachain() {
910909 } ) ;
911910}
912911
912+ #[ test]
913+ fn ahm_transfer_dot_from_polkadot_to_interlay ( ) {
914+ TestNet :: reset ( ) ;
915+
916+ // Pre migration -> Everything's ok
917+ PolkadotNet :: execute_with ( || {
918+ assert_ok ! ( polkadot_runtime:: XcmPallet :: reserve_transfer_assets(
919+ polkadot_runtime:: RuntimeOrigin :: signed( ALICE . into( ) ) ,
920+ Box :: new( Parachain ( INTERLAY_PARA_ID ) . into_versioned( ) ) ,
921+ Box :: new( Junction :: AccountId32 { id: BOB , network: None } . into_versioned( ) ) ,
922+ Box :: new( ( Here , DOT . one( ) ) . into( ) ) ,
923+ 0
924+ ) ) ;
925+ } ) ;
926+
927+ Interlay :: execute_with ( || {
928+ let bob = Tokens :: free_balance ( Token ( DOT ) , & AccountId :: from ( BOB ) ) ;
929+ assert ! ( bob > 0 ) ;
930+ assert ! ( bob < DOT . one( ) ) ;
931+
932+ // Change the migration status
933+ assert_ok ! ( XTokens :: set_migration_phase(
934+ RuntimeOrigin :: root( ) ,
935+ MigrationPhase :: InProgress
936+ ) ) ;
937+ } ) ;
938+
939+ // During the migration, the extrinsic's ok in Polkadot but the balance doesn't get to BOB.
940+ // NOTE: This is Ok here because this Polkadot version's not aware of the migration. In
941+ // production, this extrinsic will be directly blocked on Polkadot. But this proves that
942+ // Interlay's reserve is deactivated.
943+ PolkadotNet :: execute_with ( || {
944+ assert_ok ! ( polkadot_runtime:: XcmPallet :: reserve_transfer_assets(
945+ polkadot_runtime:: RuntimeOrigin :: signed( ALICE . into( ) ) ,
946+ Box :: new( Parachain ( INTERLAY_PARA_ID ) . into_versioned( ) ) ,
947+ Box :: new( Junction :: AccountId32 { id: BOB , network: None } . into_versioned( ) ) ,
948+ Box :: new( ( Here , DOT . one( ) ) . into( ) ) ,
949+ 0
950+ ) ) ;
951+ } ) ;
952+
953+ Interlay :: execute_with ( || {
954+ let bob = Tokens :: free_balance ( Token ( DOT ) , & AccountId :: from ( BOB ) ) ;
955+ assert ! ( bob > 0 ) ;
956+ assert ! ( bob < DOT . one( ) ) ;
957+
958+ // Coomplete the migration
959+ assert_ok ! ( XTokens :: set_migration_phase(
960+ RuntimeOrigin :: root( ) ,
961+ MigrationPhase :: Completed
962+ ) ) ;
963+ } ) ;
964+
965+ // After the migration, reserve transfer from Polkadot doesn't work as the reserve is now AH.
966+ PolkadotNet :: execute_with ( || {
967+ assert_ok ! ( polkadot_runtime:: XcmPallet :: reserve_transfer_assets(
968+ polkadot_runtime:: RuntimeOrigin :: signed( ALICE . into( ) ) ,
969+ Box :: new( Parachain ( INTERLAY_PARA_ID ) . into_versioned( ) ) ,
970+ Box :: new( Junction :: AccountId32 { id: BOB , network: None } . into_versioned( ) ) ,
971+ Box :: new( ( Here , DOT . one( ) ) . into( ) ) ,
972+ 0
973+ ) ) ;
974+ } ) ;
975+
976+ Interlay :: execute_with ( || {
977+ let bob = Tokens :: free_balance ( Token ( DOT ) , & AccountId :: from ( BOB ) ) ;
978+ assert ! ( bob > 0 ) ;
979+ assert ! ( bob < DOT . one( ) ) ;
980+ } )
981+ }
982+
983+ #[ test]
984+ fn ahm_transfer_dot_from_interlay_to_polkadot ( ) {
985+ TestNet :: reset ( ) ;
986+ PolkadotNet :: execute_with ( || {
987+ assert_ok ! ( polkadot_runtime:: Balances :: force_set_balance(
988+ polkadot_runtime:: RuntimeOrigin :: root( ) ,
989+ sp_runtime:: MultiAddress :: Id ( interlay_sovereign_account_on_polkadot( ) ) ,
990+ 10 * DOT . one( )
991+ ) ) ;
992+ } ) ;
993+ AssetHub :: execute_with ( || {
994+ assert_ok ! ( polkadot_asset_hub_runtime:: Balances :: force_set_balance(
995+ polkadot_asset_hub_runtime:: RuntimeOrigin :: root( ) ,
996+ sp_runtime:: MultiAddress :: Id ( sovereign_account_on_sibling( INTERLAY_PARA_ID ) ) ,
997+ 10 * DOT . one( )
998+ ) ) ;
999+ } ) ;
1000+
1001+ // Before the migration -> Everything ok
1002+ Interlay :: execute_with ( || {
1003+ assert_ok ! ( XTokens :: transfer(
1004+ RuntimeOrigin :: signed( ALICE . into( ) ) ,
1005+ Token ( DOT ) ,
1006+ 2 * DOT . one( ) ,
1007+ Box :: new( MultiLocation :: new( 1 , X1 ( Junction :: AccountId32 { id: BOB , network: None } ) ) . into( ) ) ,
1008+ WeightLimit :: Unlimited
1009+ ) ) ;
1010+ } ) ;
1011+
1012+ PolkadotNet :: execute_with ( || {
1013+ let bob = polkadot_runtime:: Balances :: free_balance ( AccountId :: from ( BOB ) ) ;
1014+ assert ! ( bob > 0 ) ;
1015+ assert ! ( bob < 2 * DOT . one( ) ) ;
1016+ } ) ;
1017+
1018+ // During the migration => Extrinsic blocked as expected
1019+ Interlay :: execute_with ( || {
1020+ assert_ok ! ( XTokens :: set_migration_phase(
1021+ RuntimeOrigin :: root( ) ,
1022+ MigrationPhase :: InProgress
1023+ ) ) ;
1024+
1025+ assert_noop ! (
1026+ XTokens :: transfer(
1027+ RuntimeOrigin :: signed( ALICE . into( ) ) ,
1028+ Token ( DOT ) ,
1029+ DOT . one( ) ,
1030+ Box :: new(
1031+ MultiLocation :: new(
1032+ 1 ,
1033+ X2 (
1034+ Junction :: Parachain ( SIBLING_PARA_ID ) ,
1035+ Junction :: AccountId32 { id: BOB , network: None }
1036+ )
1037+ )
1038+ . into( )
1039+ ) ,
1040+ WeightLimit :: Unlimited
1041+ ) ,
1042+ orml_xtokens:: Error :: <Runtime >:: AssetHasNoReserve
1043+ ) ;
1044+ } ) ;
1045+
1046+ // After the migration => Extrinsic succeed
1047+ Interlay :: execute_with ( || {
1048+ assert_ok ! ( XTokens :: set_migration_phase(
1049+ RuntimeOrigin :: root( ) ,
1050+ MigrationPhase :: Completed
1051+ ) ) ;
1052+
1053+ assert_ok ! ( XTokens :: transfer(
1054+ RuntimeOrigin :: signed( ALICE . into( ) ) ,
1055+ Token ( DOT ) ,
1056+ 2 * DOT . one( ) ,
1057+ Box :: new( MultiLocation :: new( 1 , X1 ( Junction :: AccountId32 { id: BOB , network: None } ) ) . into( ) ) ,
1058+ WeightLimit :: Unlimited
1059+ ) ) ;
1060+ } ) ;
1061+
1062+ // **BUT** Polkadot doesn't receive the tokens perse. This is because Polkadot is teleporter
1063+ // of DOT, so the reserve (AH) doesn't forward the reserve transfer message. Tokens can be found in AH tho
1064+ PolkadotNet :: execute_with ( || {
1065+ let bob = polkadot_runtime:: Balances :: free_balance ( AccountId :: from ( BOB ) ) ;
1066+ assert ! ( bob > 0 ) ;
1067+ assert ! ( bob < 2 * DOT . one( ) ) ;
1068+ } ) ;
1069+ AssetHub :: execute_with ( || {
1070+ let bob = polkadot_asset_hub_runtime:: Balances :: free_balance ( AccountId :: from ( BOB ) ) ;
1071+ assert ! ( bob > 0 ) ;
1072+ assert ! ( bob < 2 * DOT . one( ) ) ;
1073+ } ) ;
1074+ }
1075+
1076+ #[ test]
1077+ fn ahm_transfer_dot_from_asset_hub_to_interlay ( ) {
1078+ TestNet :: reset ( ) ;
1079+
1080+ // Pre migration -> The DOT reserve is Interlay, so AH isn't trusted
1081+ AssetHub :: execute_with ( || {
1082+ assert_ok ! ( polkadot_asset_hub_runtime:: PolkadotXcm :: reserve_transfer_assets(
1083+ polkadot_asset_hub_runtime:: RuntimeOrigin :: signed( ALICE . into( ) ) ,
1084+ Box :: new( MultiLocation :: new( 1 , Parachain ( INTERLAY_PARA_ID ) ) . into( ) ) ,
1085+ Box :: new( Junction :: AccountId32 { id: BOB , network: None } . into_versioned( ) ) ,
1086+ Box :: new( ( MultiLocation :: parent( ) , DOT . one( ) ) . into( ) ) ,
1087+ 0
1088+ ) ) ;
1089+ } ) ;
1090+
1091+ Interlay :: execute_with ( || {
1092+ let bob = Tokens :: free_balance ( Token ( DOT ) , & AccountId :: from ( BOB ) ) ;
1093+ assert ! ( bob == 0 ) ;
1094+
1095+ // Change the migration status
1096+ assert_ok ! ( XTokens :: set_migration_phase(
1097+ RuntimeOrigin :: root( ) ,
1098+ MigrationPhase :: InProgress
1099+ ) ) ;
1100+ } ) ;
1101+
1102+ // During the migration, the extrinsic's ok in PolkadotAssetHub but the balance doesn't get to BOB.
1103+ // NOTE: This is Ok here because this Polkadot version's not aware of the migration. In
1104+ // production, this extrinsic will be directly blocked on Polkadot. But this proves that
1105+ // Interlay's reserve is deactivated.
1106+ AssetHub :: execute_with ( || {
1107+ assert_ok ! ( polkadot_asset_hub_runtime:: PolkadotXcm :: reserve_transfer_assets(
1108+ polkadot_asset_hub_runtime:: RuntimeOrigin :: signed( ALICE . into( ) ) ,
1109+ Box :: new( MultiLocation :: new( 1 , Parachain ( INTERLAY_PARA_ID ) ) . into( ) ) ,
1110+ Box :: new( Junction :: AccountId32 { id: BOB , network: None } . into_versioned( ) ) ,
1111+ Box :: new( ( MultiLocation :: parent( ) , DOT . one( ) ) . into( ) ) ,
1112+ 0
1113+ ) ) ;
1114+ } ) ;
1115+
1116+ Interlay :: execute_with ( || {
1117+ let bob = Tokens :: free_balance ( Token ( DOT ) , & AccountId :: from ( BOB ) ) ;
1118+ assert ! ( bob == 0 ) ;
1119+
1120+ // Coomplete the migration
1121+ assert_ok ! ( XTokens :: set_migration_phase(
1122+ RuntimeOrigin :: root( ) ,
1123+ MigrationPhase :: Completed
1124+ ) ) ;
1125+ } ) ;
1126+
1127+ // After the migration, reserve transfer works because AH is the right reserve.
1128+ // **NOTE**: This shouldn't be called on production, AH will disallow this call, so it'll
1129+ // result in paying fees for nothing. Use `transfer_assets_using_type_and_the` instead, we
1130+ // didn't use it here cause it's not available on this AH version
1131+ AssetHub :: execute_with ( || {
1132+ assert_ok ! ( polkadot_asset_hub_runtime:: PolkadotXcm :: reserve_transfer_assets(
1133+ polkadot_asset_hub_runtime:: RuntimeOrigin :: signed( ALICE . into( ) ) ,
1134+ Box :: new( MultiLocation :: new( 1 , Parachain ( INTERLAY_PARA_ID ) ) . into( ) ) ,
1135+ Box :: new( Junction :: AccountId32 { id: BOB , network: None } . into_versioned( ) ) ,
1136+ Box :: new( ( MultiLocation :: parent( ) , DOT . one( ) ) . into( ) ) ,
1137+ 0
1138+ ) ) ;
1139+ } ) ;
1140+
1141+ Interlay :: execute_with ( || {
1142+ let bob = Tokens :: free_balance ( Token ( DOT ) , & AccountId :: from ( BOB ) ) ;
1143+ assert ! ( bob > 0 ) ;
1144+ assert ! ( bob < DOT . one( ) ) ;
1145+ } )
1146+ }
1147+
1148+ #[ test]
1149+ fn ahm_transfer_dot_from_interlay_to_asset_hub ( ) {
1150+ TestNet :: reset ( ) ;
1151+ PolkadotNet :: execute_with ( || {
1152+ assert_ok ! ( polkadot_runtime:: Balances :: force_set_balance(
1153+ polkadot_runtime:: RuntimeOrigin :: root( ) ,
1154+ sp_runtime:: MultiAddress :: Id ( interlay_sovereign_account_on_polkadot( ) ) ,
1155+ 10 * DOT . one( )
1156+ ) ) ;
1157+ } ) ;
1158+ AssetHub :: execute_with ( || {
1159+ assert_ok ! ( polkadot_asset_hub_runtime:: Balances :: force_set_balance(
1160+ polkadot_asset_hub_runtime:: RuntimeOrigin :: root( ) ,
1161+ sp_runtime:: MultiAddress :: Id ( sovereign_account_on_sibling( INTERLAY_PARA_ID ) ) ,
1162+ 10 * DOT . one( )
1163+ ) ) ;
1164+ } ) ;
1165+
1166+ // Before the migration -> Everything ok
1167+ Interlay :: execute_with ( || {
1168+ assert_ok ! ( XTokens :: transfer(
1169+ RuntimeOrigin :: signed( ALICE . into( ) ) ,
1170+ Token ( DOT ) ,
1171+ 2 * DOT . one( ) ,
1172+ Box :: new(
1173+ MultiLocation :: new(
1174+ 1 ,
1175+ X2 (
1176+ Junction :: Parachain ( POLKADOT_ASSET_HUB_PARA_ID ) ,
1177+ Junction :: AccountId32 { id: BOB , network: None }
1178+ )
1179+ )
1180+ . into( )
1181+ ) ,
1182+ WeightLimit :: Unlimited
1183+ ) ) ;
1184+ } ) ;
1185+
1186+ // **BUT** AH doesn't receive the tokens perse. This is because Polkadot forwards the message
1187+ // BUT isn't reserve of DOT for AH, so funds remains locked on AH child account. Note this is
1188+ // different from the case when we reserve transfer DOT from Interlay to Polkadot with AH being
1189+ // the reserve.
1190+ AssetHub :: execute_with ( || {
1191+ let bob = polkadot_asset_hub_runtime:: Balances :: free_balance ( AccountId :: from ( BOB ) ) ;
1192+ assert ! ( bob == 0 ) ;
1193+ } ) ;
1194+
1195+ PolkadotNet :: execute_with ( || {
1196+ let ah_sovereign_account = polkadot_runtime:: Balances :: free_balance ( ah_sovereign_account_on_polkadot ( ) ) ;
1197+ assert ! ( ah_sovereign_account > 0 ) ;
1198+ assert ! ( ah_sovereign_account < 2 * DOT . one( ) ) ;
1199+ } ) ;
1200+
1201+ // During the migration => Extrinsic blocked as expected
1202+ Interlay :: execute_with ( || {
1203+ assert_ok ! ( XTokens :: set_migration_phase(
1204+ RuntimeOrigin :: root( ) ,
1205+ MigrationPhase :: InProgress
1206+ ) ) ;
1207+
1208+ assert_noop ! (
1209+ XTokens :: transfer(
1210+ RuntimeOrigin :: signed( ALICE . into( ) ) ,
1211+ Token ( DOT ) ,
1212+ DOT . one( ) ,
1213+ Box :: new(
1214+ MultiLocation :: new(
1215+ 1 ,
1216+ X2 (
1217+ Junction :: Parachain ( SIBLING_PARA_ID ) ,
1218+ Junction :: AccountId32 { id: BOB , network: None }
1219+ )
1220+ )
1221+ . into( )
1222+ ) ,
1223+ WeightLimit :: Unlimited
1224+ ) ,
1225+ orml_xtokens:: Error :: <Runtime >:: AssetHasNoReserve
1226+ ) ;
1227+ } ) ;
1228+
1229+ // After the migration => OK
1230+ Interlay :: execute_with ( || {
1231+ assert_ok ! ( XTokens :: set_migration_phase(
1232+ RuntimeOrigin :: root( ) ,
1233+ MigrationPhase :: Completed
1234+ ) ) ;
1235+
1236+ assert_ok ! ( XTokens :: transfer(
1237+ RuntimeOrigin :: signed( ALICE . into( ) ) ,
1238+ Token ( DOT ) ,
1239+ 2 * DOT . one( ) ,
1240+ Box :: new( MultiLocation :: new( 1 , X1 ( Junction :: AccountId32 { id: BOB , network: None } ) ) . into( ) ) ,
1241+ WeightLimit :: Unlimited
1242+ ) ) ;
1243+ } ) ;
1244+
1245+ AssetHub :: execute_with ( || {
1246+ let bob = polkadot_asset_hub_runtime:: Balances :: free_balance ( AccountId :: from ( BOB ) ) ;
1247+ assert ! ( bob > 0 ) ;
1248+ assert ! ( bob < 2 * DOT . one( ) ) ;
1249+ } ) ;
1250+ }
1251+
9131252// Other tokens aren't affected by the migration
9141253#[ test]
9151254fn ahm_transfer_with_xtokens_not_dot ( ) {
0 commit comments