1
// Copyright 2024 Moonbeam foundation
2
// This file is part of Moonbeam.
3

            
4
// Moonbeam is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Moonbeam is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Moonbeam.  If not, see <http://www.gnu.org/licenses/>.
16

            
17
//! Unit testing
18
use {
19
	crate::mock::*,
20
	crate::{Error, Trader, XcmPaymentApiError},
21
	frame_support::pallet_prelude::Weight,
22
	frame_support::{assert_noop, assert_ok},
23
	sp_runtime::DispatchError,
24
	xcm::v5::{
25
		Asset, AssetId as XcmAssetId, Error as XcmError, Fungibility, Location, XcmContext, XcmHash,
26
	},
27
	xcm::{IntoVersion, VersionedAssetId},
28
	xcm_executor::traits::WeightTrader,
29
};
30

            
31
3
fn xcm_fees_account() -> <Test as frame_system::Config>::AccountId {
32
3
	<Test as crate::Config>::XcmFeesAccount::get()
33
3
}
34

            
35
#[test]
36
1
fn test_add_supported_asset() {
37
1
	new_test_ext().execute_with(|| {
38
1
		// Call with bad origin
39
1
		assert_noop!(
40
1
			XcmWeightTrader::add_asset(
41
1
				RuntimeOrigin::signed(EditAccount::get()),
42
1
				Location::parent(),
43
1
				1_000,
44
1
			),
45
1
			DispatchError::BadOrigin
46
1
		);
47

            
48
		// Call with invalid location
49
1
		assert_noop!(
50
1
			XcmWeightTrader::add_asset(
51
1
				RuntimeOrigin::signed(AddAccount::get()),
52
1
				Location::new(2, []),
53
1
				1_000,
54
1
			),
55
1
			Error::<Test>::XcmLocationFiltered
56
1
		);
57

            
58
		// Call with invalid price
59
1
		assert_noop!(
60
1
			XcmWeightTrader::add_asset(
61
1
				RuntimeOrigin::signed(AddAccount::get()),
62
1
				Location::parent(),
63
1
				0,
64
1
			),
65
1
			Error::<Test>::PriceCannotBeZero
66
1
		);
67

            
68
		// Call with the right origin
69
1
		assert_ok!(XcmWeightTrader::add_asset(
70
1
			RuntimeOrigin::signed(AddAccount::get()),
71
1
			Location::parent(),
72
1
			1_000,
73
1
		));
74

            
75
		// The account should be supported
76
1
		assert_eq!(
77
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
78
1
			Some(1_000),
79
1
		);
80

            
81
		// Check storage
82
1
		assert_eq!(
83
1
			crate::pallet::SupportedAssets::<Test>::get(&Location::parent()),
84
1
			Some((true, 1_000))
85
1
		);
86

            
87
		// Try to add the same asset twice (should fail)
88
1
		assert_noop!(
89
1
			XcmWeightTrader::add_asset(
90
1
				RuntimeOrigin::signed(AddAccount::get()),
91
1
				Location::parent(),
92
1
				1_000,
93
1
			),
94
1
			Error::<Test>::AssetAlreadyAdded
95
1
		);
96
1
	})
97
1
}
98

            
99
#[test]
100
1
fn test_edit_supported_asset() {
101
1
	new_test_ext().execute_with(|| {
102
1
		// Should not be able to edit an asset not added yet
103
1
		assert_noop!(
104
1
			XcmWeightTrader::edit_asset(
105
1
				RuntimeOrigin::signed(EditAccount::get()),
106
1
				Location::parent(),
107
1
				2_000,
108
1
			),
109
1
			Error::<Test>::AssetNotFound
110
1
		);
111

            
112
		// Setup (add a supported asset)
113
1
		assert_ok!(XcmWeightTrader::add_asset(
114
1
			RuntimeOrigin::signed(AddAccount::get()),
115
1
			Location::parent(),
116
1
			1_000,
117
1
		));
118
1
		assert_eq!(
119
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
120
1
			Some(1_000),
121
1
		);
122

            
123
		// Call with bad origin
124
1
		assert_noop!(
125
1
			XcmWeightTrader::edit_asset(
126
1
				RuntimeOrigin::signed(AddAccount::get()),
127
1
				Location::parent(),
128
1
				2_000,
129
1
			),
130
1
			DispatchError::BadOrigin
131
1
		);
132

            
133
		// Call with invalid price
134
1
		assert_noop!(
135
1
			XcmWeightTrader::edit_asset(
136
1
				RuntimeOrigin::signed(EditAccount::get()),
137
1
				Location::parent(),
138
1
				0,
139
1
			),
140
1
			Error::<Test>::PriceCannotBeZero
141
1
		);
142

            
143
		// Call with right origin and valid params
144
1
		assert_ok!(XcmWeightTrader::edit_asset(
145
1
			RuntimeOrigin::signed(EditAccount::get()),
146
1
			Location::parent(),
147
1
			2_000,
148
1
		),);
149

            
150
		// The account should be supported
151
1
		assert_eq!(
152
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
153
1
			Some(2_000),
154
1
		);
155

            
156
		// Check storage
157
1
		assert_eq!(
158
1
			crate::pallet::SupportedAssets::<Test>::get(&Location::parent()),
159
1
			Some((true, 2_000))
160
1
		);
161
1
	})
162
1
}
163

            
164
#[test]
165
1
fn test_pause_asset_support() {
166
1
	new_test_ext().execute_with(|| {
167
1
		// Should not be able to pause an asset not added yet
168
1
		assert_noop!(
169
1
			XcmWeightTrader::pause_asset_support(
170
1
				RuntimeOrigin::signed(PauseAccount::get()),
171
1
				Location::parent(),
172
1
			),
173
1
			Error::<Test>::AssetNotFound
174
1
		);
175

            
176
		// Setup (add a supported asset)
177
1
		assert_ok!(XcmWeightTrader::add_asset(
178
1
			RuntimeOrigin::signed(AddAccount::get()),
179
1
			Location::parent(),
180
1
			1_000,
181
1
		));
182
1
		assert_eq!(
183
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
184
1
			Some(1_000),
185
1
		);
186

            
187
		// Call with bad origin
188
1
		assert_noop!(
189
1
			XcmWeightTrader::pause_asset_support(
190
1
				RuntimeOrigin::signed(AddAccount::get()),
191
1
				Location::parent(),
192
1
			),
193
1
			DispatchError::BadOrigin
194
1
		);
195

            
196
		// Call with right origin and valid params
197
1
		assert_ok!(XcmWeightTrader::pause_asset_support(
198
1
			RuntimeOrigin::signed(PauseAccount::get()),
199
1
			Location::parent(),
200
1
		));
201

            
202
		// The asset should be paused
203
1
		assert_eq!(
204
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
205
1
			None,
206
1
		);
207

            
208
		// Check storage
209
1
		assert_eq!(
210
1
			crate::pallet::SupportedAssets::<Test>::get(&Location::parent()),
211
1
			Some((false, 1_000))
212
1
		);
213

            
214
		// Should not be able to pause an asset already paused
215
1
		assert_noop!(
216
1
			XcmWeightTrader::pause_asset_support(
217
1
				RuntimeOrigin::signed(PauseAccount::get()),
218
1
				Location::parent(),
219
1
			),
220
1
			Error::<Test>::AssetAlreadyPaused
221
1
		);
222

            
223
		// Should be able to udpate relative price of paused asset
224
1
		assert_ok!(XcmWeightTrader::edit_asset(
225
1
			RuntimeOrigin::signed(EditAccount::get()),
226
1
			Location::parent(),
227
1
			500
228
1
		));
229

            
230
		// The asset should still be paused
231
1
		assert_eq!(
232
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
233
1
			None,
234
1
		);
235

            
236
		// Check storage
237
1
		assert_eq!(
238
1
			crate::pallet::SupportedAssets::<Test>::get(&Location::parent()),
239
1
			Some((false, 500))
240
1
		);
241
1
	})
242
1
}
243

            
244
#[test]
245
1
fn test_resume_asset_support() {
246
1
	new_test_ext().execute_with(|| {
247
1
		// Setup (add a supported asset and pause it)
248
1
		assert_ok!(XcmWeightTrader::add_asset(
249
1
			RuntimeOrigin::signed(AddAccount::get()),
250
1
			Location::parent(),
251
1
			1_000,
252
1
		));
253
1
		assert_ok!(XcmWeightTrader::pause_asset_support(
254
1
			RuntimeOrigin::signed(PauseAccount::get()),
255
1
			Location::parent(),
256
1
		));
257
1
		assert_eq!(
258
1
			crate::pallet::SupportedAssets::<Test>::get(&Location::parent()),
259
1
			Some((false, 1_000))
260
1
		);
261

            
262
		// Call with bad origin
263
1
		assert_noop!(
264
1
			XcmWeightTrader::resume_asset_support(
265
1
				RuntimeOrigin::signed(AddAccount::get()),
266
1
				Location::parent(),
267
1
			),
268
1
			DispatchError::BadOrigin
269
1
		);
270

            
271
		// Call with invalid location
272
1
		assert_noop!(
273
1
			XcmWeightTrader::resume_asset_support(
274
1
				RuntimeOrigin::signed(ResumeAccount::get()),
275
1
				Location::new(2, []),
276
1
			),
277
1
			Error::<Test>::AssetNotFound
278
1
		);
279

            
280
		// Call with right origin and valid params
281
1
		assert_ok!(XcmWeightTrader::resume_asset_support(
282
1
			RuntimeOrigin::signed(ResumeAccount::get()),
283
1
			Location::parent(),
284
1
		));
285

            
286
		// The asset should be supported again
287
1
		assert_eq!(
288
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
289
1
			Some(1_000),
290
1
		);
291

            
292
		// Check storage
293
1
		assert_eq!(
294
1
			crate::pallet::SupportedAssets::<Test>::get(&Location::parent()),
295
1
			Some((true, 1_000))
296
1
		);
297

            
298
		// Should not be able to resume an asset already active
299
1
		assert_noop!(
300
1
			XcmWeightTrader::resume_asset_support(
301
1
				RuntimeOrigin::signed(ResumeAccount::get()),
302
1
				Location::parent(),
303
1
			),
304
1
			Error::<Test>::AssetNotPaused
305
1
		);
306
1
	})
307
1
}
308

            
309
#[test]
310
1
fn test_remove_asset_support() {
311
1
	new_test_ext().execute_with(|| {
312
1
		// Should not be able to remove an asset not added yet
313
1
		assert_noop!(
314
1
			XcmWeightTrader::remove_asset(
315
1
				RuntimeOrigin::signed(RemoveAccount::get()),
316
1
				Location::parent(),
317
1
			),
318
1
			Error::<Test>::AssetNotFound
319
1
		);
320

            
321
		// Setup (add a supported asset)
322
1
		assert_ok!(XcmWeightTrader::add_asset(
323
1
			RuntimeOrigin::signed(AddAccount::get()),
324
1
			Location::parent(),
325
1
			1_000,
326
1
		));
327
1
		assert_eq!(
328
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
329
1
			Some(1_000),
330
1
		);
331

            
332
		// Call with bad origin
333
1
		assert_noop!(
334
1
			XcmWeightTrader::remove_asset(
335
1
				RuntimeOrigin::signed(AddAccount::get()),
336
1
				Location::parent(),
337
1
			),
338
1
			DispatchError::BadOrigin
339
1
		);
340

            
341
		// Call with right origin and valid params
342
1
		assert_ok!(XcmWeightTrader::remove_asset(
343
1
			RuntimeOrigin::signed(RemoveAccount::get()),
344
1
			Location::parent(),
345
1
		));
346

            
347
		// The account should be removed
348
1
		assert_eq!(
349
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
350
1
			None,
351
1
		);
352

            
353
		// Check storage
354
1
		assert_eq!(
355
1
			crate::pallet::SupportedAssets::<Test>::get(&Location::parent()),
356
1
			None
357
1
		);
358

            
359
		// Should not be able to pause an asset already removed
360
1
		assert_noop!(
361
1
			XcmWeightTrader::remove_asset(
362
1
				RuntimeOrigin::signed(RemoveAccount::get()),
363
1
				Location::parent(),
364
1
			),
365
1
			Error::<Test>::AssetNotFound
366
1
		);
367
1
	})
368
1
}
369

            
370
#[test]
371
1
fn test_trader_native_asset() {
372
1
	new_test_ext().execute_with(|| {
373
1
		let weight_to_buy = Weight::from_parts(10_000, 0);
374
1
		let dummy_xcm_context = XcmContext::with_message_id(XcmHash::default());
375
1

            
376
1
		// Should not be able to buy weight with too low asset balance
377
1
		assert_eq!(
378
1
			Trader::<Test>::new().buy_weight(
379
1
				weight_to_buy,
380
1
				Asset {
381
1
					fun: Fungibility::Fungible(9_999),
382
1
					id: XcmAssetId(Location::here()),
383
1
				}
384
1
				.into(),
385
1
				&dummy_xcm_context
386
1
			),
387
1
			Err(XcmError::TooExpensive)
388
1
		);
389

            
390
		// Should not be able to buy weight with unsupported asset
391
1
		assert_eq!(
392
1
			Trader::<Test>::new().buy_weight(
393
1
				weight_to_buy,
394
1
				Asset {
395
1
					fun: Fungibility::Fungible(10_000),
396
1
					id: XcmAssetId(Location::parent()),
397
1
				}
398
1
				.into(),
399
1
				&dummy_xcm_context
400
1
			),
401
1
			Err(XcmError::AssetNotFound)
402
1
		);
403

            
404
		// Should not be able to buy weight without asset
405
1
		assert_eq!(
406
1
			Trader::<Test>::new().buy_weight(weight_to_buy, Default::default(), &dummy_xcm_context),
407
1
			Err(XcmError::AssetNotFound)
408
1
		);
409

            
410
		// Should be able to buy weight with just enough native asset
411
1
		let mut trader = Trader::<Test>::new();
412
1
		assert_eq!(
413
1
			trader.buy_weight(
414
1
				weight_to_buy,
415
1
				Asset {
416
1
					fun: Fungibility::Fungible(10_000),
417
1
					id: XcmAssetId(Location::here()),
418
1
				}
419
1
				.into(),
420
1
				&dummy_xcm_context
421
1
			),
422
1
			Ok(Default::default())
423
1
		);
424

            
425
		// Should not refund any funds
426
1
		let actual_weight = weight_to_buy;
427
1
		assert_eq!(
428
1
			trader.refund_weight(actual_weight, &dummy_xcm_context),
429
1
			None
430
1
		);
431

            
432
		// Should not be able to buy weight again with the same trader
433
1
		assert_eq!(
434
1
			trader.buy_weight(
435
1
				weight_to_buy,
436
1
				Asset {
437
1
					fun: Fungibility::Fungible(10_000),
438
1
					id: XcmAssetId(Location::here()),
439
1
				}
440
1
				.into(),
441
1
				&dummy_xcm_context
442
1
			),
443
1
			Err(XcmError::NotWithdrawable)
444
1
		);
445

            
446
		// Fees asset should be deposited into XcmFeesAccount
447
1
		drop(trader);
448
1
		assert_eq!(Balances::free_balance(&xcm_fees_account()), 10_000);
449

            
450
		// Should be able to buy weight with more native asset (and get back unused amount)
451
1
		let mut trader = Trader::<Test>::new();
452
1
		assert_eq!(
453
1
			trader.buy_weight(
454
1
				weight_to_buy,
455
1
				Asset {
456
1
					fun: Fungibility::Fungible(11_000),
457
1
					id: XcmAssetId(Location::here()),
458
1
				}
459
1
				.into(),
460
1
				&dummy_xcm_context
461
1
			),
462
1
			Ok(Asset {
463
1
				fun: Fungibility::Fungible(1_000),
464
1
				id: XcmAssetId(Location::here()),
465
1
			}
466
1
			.into())
467
1
		);
468

            
469
		// Should be able to refund unused weights
470
1
		let actual_weight = weight_to_buy.saturating_sub(Weight::from_parts(2_000, 0));
471
1
		assert_eq!(
472
1
			trader.refund_weight(actual_weight, &dummy_xcm_context),
473
1
			Some(Asset {
474
1
				fun: Fungibility::Fungible(2_000),
475
1
				id: XcmAssetId(Location::here()),
476
1
			})
477
1
		);
478

            
479
		// Fees asset should be deposited again into XcmFeesAccount (2 times cost minus one refund)
480
1
		drop(trader);
481
1
		assert_eq!(
482
1
			Balances::free_balance(&xcm_fees_account()),
483
1
			(2 * 10_000) - 2_000
484
1
		);
485
1
	})
486
1
}
487

            
488
#[test]
489
1
fn test_trader_parent_asset() {
490
1
	new_test_ext().execute_with(|| {
491
1
		let weight_to_buy = Weight::from_parts(10_000, 0);
492
1
		let dummy_xcm_context = XcmContext::with_message_id(XcmHash::default());
493
1

            
494
1
		// Setup (add a supported asset)
495
1
		assert_ok!(XcmWeightTrader::add_asset(
496
1
			RuntimeOrigin::signed(AddAccount::get()),
497
1
			Location::parent(),
498
1
			500_000_000,
499
1
		));
500
1
		assert_eq!(
501
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
502
1
			Some(500_000_000),
503
1
		);
504

            
505
		// Should be able to pay fees with registered asset
506
1
		let mut trader = Trader::<Test>::new();
507
1
		assert_eq!(
508
1
			trader.buy_weight(
509
1
				weight_to_buy,
510
1
				Asset {
511
1
					fun: Fungibility::Fungible(22_000_000_000_000),
512
1
					id: XcmAssetId(Location::parent()),
513
1
				}
514
1
				.into(),
515
1
				&dummy_xcm_context
516
1
			),
517
1
			Ok(Asset {
518
1
				fun: Fungibility::Fungible(2_000_000_000_000),
519
1
				id: XcmAssetId(Location::parent()),
520
1
			}
521
1
			.into())
522
1
		);
523

            
524
		// Should be able to refund unused weights
525
1
		let actual_weight = weight_to_buy.saturating_sub(Weight::from_parts(2_000, 0));
526
1
		assert_eq!(
527
1
			trader.refund_weight(actual_weight, &dummy_xcm_context),
528
1
			Some(Asset {
529
1
				fun: Fungibility::Fungible(4_000_000_000_000),
530
1
				id: XcmAssetId(Location::parent()),
531
1
			})
532
1
		);
533

            
534
		// Fees asset should be deposited into XcmFeesAccount
535
1
		drop(trader);
536
1
		assert_eq!(
537
1
			get_parent_asset_deposited(),
538
1
			Some((xcm_fees_account(), 20_000_000_000_000 - 4_000_000_000_000))
539
1
		);
540

            
541
		// Should not be able to buy weight if the asset is not a first position
542
1
		assert_eq!(
543
1
			Trader::<Test>::new().buy_weight(
544
1
				weight_to_buy,
545
1
				vec![
546
1
					Asset {
547
1
						fun: Fungibility::Fungible(10),
548
1
						id: XcmAssetId(Location::here()),
549
1
					},
550
1
					Asset {
551
1
						fun: Fungibility::Fungible(30_000),
552
1
						id: XcmAssetId(Location::parent()),
553
1
					}
554
1
				]
555
1
				.into(),
556
1
				&dummy_xcm_context
557
1
			),
558
1
			Err(XcmError::TooExpensive)
559
1
		);
560
1
	})
561
1
}
562

            
563
#[test]
564
1
fn test_query_acceptable_payment_assets() {
565
1
	new_test_ext().execute_with(|| {
566
1
		// By default, only native asset should be supported
567
1
		assert_eq!(
568
1
			XcmWeightTrader::query_acceptable_payment_assets(5),
569
1
			Ok(vec![VersionedAssetId::from(XcmAssetId(
570
1
				<Test as crate::Config>::NativeLocation::get()
571
1
			))])
572
1
		);
573

            
574
		// We should support XCMv3
575
1
		assert_eq!(
576
1
			XcmWeightTrader::query_acceptable_payment_assets(3),
577
1
			Ok(vec![VersionedAssetId::from(XcmAssetId(
578
1
				<Test as crate::Config>::NativeLocation::get()
579
1
			))
580
1
			.into_version(xcm::v3::VERSION)
581
1
			.expect("native location should be convertible to v3")])
582
1
		);
583

            
584
		// We should not support XCMv2
585
1
		assert_eq!(
586
1
			XcmWeightTrader::query_acceptable_payment_assets(2),
587
1
			Err(XcmPaymentApiError::UnhandledXcmVersion)
588
1
		);
589

            
590
		// Setup (add a supported asset)
591
1
		assert_ok!(XcmWeightTrader::add_asset(
592
1
			RuntimeOrigin::signed(AddAccount::get()),
593
1
			Location::parent(),
594
1
			500_000_000,
595
1
		));
596
1
		assert_eq!(
597
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
598
1
			Some(500_000_000),
599
1
		);
600

            
601
		// We should support parent asset now
602
1
		assert_eq!(
603
1
			XcmWeightTrader::query_acceptable_payment_assets(5),
604
1
			Ok(vec![
605
1
				VersionedAssetId::from(XcmAssetId(<Test as crate::Config>::NativeLocation::get())),
606
1
				VersionedAssetId::from(XcmAssetId(Location::parent()))
607
1
			])
608
1
		);
609

            
610
		// Setup: pause parent asset
611
1
		assert_ok!(XcmWeightTrader::pause_asset_support(
612
1
			RuntimeOrigin::signed(PauseAccount::get()),
613
1
			Location::parent(),
614
1
		));
615
1
		assert_eq!(
616
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
617
1
			None
618
1
		);
619

            
620
		// We should not support paused assets
621
1
		assert_eq!(
622
1
			XcmWeightTrader::query_acceptable_payment_assets(5),
623
1
			Ok(vec![VersionedAssetId::from(XcmAssetId(
624
1
				<Test as crate::Config>::NativeLocation::get()
625
1
			)),])
626
1
		);
627
1
	})
628
1
}
629

            
630
#[test]
631
1
fn test_query_weight_to_asset_fee() {
632
1
	new_test_ext().execute_with(|| {
633
1
		let native_asset =
634
1
			VersionedAssetId::from(XcmAssetId(<Test as crate::Config>::NativeLocation::get()));
635
1
		let parent_asset = VersionedAssetId::from(XcmAssetId(Location::parent()));
636
1
		let weight_to_buy = Weight::from_parts(10_000, 0);
637
1

            
638
1
		// Native asset price should be 1:1
639
1
		assert_eq!(
640
1
			XcmWeightTrader::query_weight_to_asset_fee(weight_to_buy, native_asset.clone()),
641
1
			Ok(10_000)
642
1
		);
643

            
644
		// Should not be able to query fees for an unsupported asset
645
1
		assert_eq!(
646
1
			XcmWeightTrader::query_weight_to_asset_fee(weight_to_buy, parent_asset.clone()),
647
1
			Err(XcmPaymentApiError::AssetNotFound)
648
1
		);
649

            
650
		// Setup (add a supported asset)
651
1
		assert_ok!(XcmWeightTrader::add_asset(
652
1
			RuntimeOrigin::signed(AddAccount::get()),
653
1
			Location::parent(),
654
1
			500_000_000,
655
1
		));
656
1
		assert_eq!(
657
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
658
1
			Some(500_000_000),
659
1
		);
660

            
661
		// Parent asset price should be 0.5
662
1
		assert_eq!(
663
1
			XcmWeightTrader::query_weight_to_asset_fee(weight_to_buy, parent_asset.clone()),
664
1
			Ok(2 * 10_000_000_000_000)
665
1
		);
666

            
667
		// Setup: pause parent asset
668
1
		assert_ok!(XcmWeightTrader::pause_asset_support(
669
1
			RuntimeOrigin::signed(PauseAccount::get()),
670
1
			Location::parent(),
671
1
		));
672
1
		assert_eq!(
673
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
674
1
			None
675
1
		);
676

            
677
		// We should not support paused assets
678
1
		assert_eq!(
679
1
			XcmWeightTrader::query_weight_to_asset_fee(weight_to_buy, parent_asset.clone()),
680
1
			Err(XcmPaymentApiError::AssetNotFound)
681
1
		);
682

            
683
		// Setup: unpause parent asset and edit price
684
1
		assert_ok!(XcmWeightTrader::resume_asset_support(
685
1
			RuntimeOrigin::signed(ResumeAccount::get()),
686
1
			Location::parent(),
687
1
		));
688
1
		assert_ok!(XcmWeightTrader::edit_asset(
689
1
			RuntimeOrigin::signed(EditAccount::get()),
690
1
			Location::parent(),
691
1
			2_000_000_000,
692
1
		));
693
1
		assert_eq!(
694
1
			XcmWeightTrader::get_asset_relative_price(&Location::parent()),
695
1
			Some(2_000_000_000),
696
1
		);
697

            
698
		// We should support unpaused asset with new price
699
1
		assert_eq!(
700
1
			XcmWeightTrader::query_weight_to_asset_fee(weight_to_buy, parent_asset),
701
1
			Ok(10_000_000_000_000 / 2)
702
1
		);
703
1
	})
704
1
}