1#![cfg(feature = "runtime-benchmarks")]
21
22use super::*;
23use alloc::vec;
24use frame_benchmarking::{
25 v1::{
26 account, benchmarks_instance_pallet, whitelist_account, whitelisted_caller, BenchmarkError,
27 },
28 BenchmarkResult,
29};
30use frame_support::traits::{EnsureOrigin, Get, UnfilteredDispatchable};
31use frame_system::RawOrigin as SystemOrigin;
32use sp_runtime::{traits::Bounded, Weight};
33
34use crate::Pallet as Assets;
35
36const SEED: u32 = 0;
37const MIN_BALANCE: u32 = 1;
38
39fn default_asset_id<T: Config<I>, I: 'static>() -> T::AssetIdParameter {
40 T::BenchmarkHelper::create_asset_id_parameter(0)
41}
42
43fn create_default_asset<T: Config<I>, I: 'static>(
44 is_sufficient: bool,
45) -> (T::AssetIdParameter, T::AccountId, AccountIdLookupOf<T>) {
46 let asset_id = default_asset_id::<T, I>();
47 let caller: T::AccountId = whitelisted_caller();
48 let caller_lookup = T::Lookup::unlookup(caller.clone());
49 let root = SystemOrigin::Root.into();
50 assert!(Assets::<T, I>::force_create(
51 root,
52 asset_id.clone(),
53 caller_lookup.clone(),
54 is_sufficient,
55 MIN_BALANCE.into(),
56 )
57 .is_ok());
58 (asset_id, caller, caller_lookup)
59}
60
61fn create_default_reserves<T: Config<I>, I: 'static>(
62 count: u32,
63) -> (T::AssetIdParameter, T::AccountId, Vec<T::ReserveData>) {
64 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
66 let mut reserves = Vec::<T::ReserveData>::new();
68 for i in 0..count {
69 reserves.push(T::BenchmarkHelper::create_reserve_id_parameter(i));
70 }
71 (asset_id, caller, reserves)
72}
73
74pub fn create_default_minted_asset<T: Config<I>, I: 'static>(
75 is_sufficient: bool,
76 amount: T::Balance,
77) -> (T::AssetIdParameter, T::AccountId, AccountIdLookupOf<T>) {
78 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(is_sufficient);
79 if !is_sufficient {
80 T::Currency::make_free_balance_be(&caller, T::Currency::minimum_balance());
81 }
82 assert!(Assets::<T, I>::mint(
83 SystemOrigin::Signed(caller.clone()).into(),
84 asset_id.clone(),
85 caller_lookup.clone(),
86 amount,
87 )
88 .is_ok());
89 (asset_id, caller, caller_lookup)
90}
91
92fn swap_is_sufficient<T: Config<I>, I: 'static>(s: &mut bool) {
93 let asset_id = default_asset_id::<T, I>();
94 Asset::<T, I>::mutate(&asset_id.into(), |maybe_a| {
95 if let Some(ref mut a) = maybe_a {
96 core::mem::swap(s, &mut a.is_sufficient)
97 }
98 });
99}
100
101fn add_sufficients<T: Config<I>, I: 'static>(minter: T::AccountId, n: u32) {
102 let asset_id = default_asset_id::<T, I>();
103 let origin = SystemOrigin::Signed(minter);
104 let mut s = true;
105 swap_is_sufficient::<T, I>(&mut s);
106 for i in 0..n {
107 let target = account("sufficient", i, SEED);
108 let target_lookup = T::Lookup::unlookup(target);
109 assert!(Assets::<T, I>::mint(
110 origin.clone().into(),
111 asset_id.clone(),
112 target_lookup,
113 100u32.into(),
114 )
115 .is_ok());
116 }
117 swap_is_sufficient::<T, I>(&mut s);
118}
119
120fn add_approvals<T: Config<I>, I: 'static>(minter: T::AccountId, n: u32) {
121 let asset_id = default_asset_id::<T, I>();
122 let _ = T::Currency::deposit_creating(
123 &minter,
124 T::ApprovalDeposit::get() * n.into() + T::Currency::minimum_balance(),
125 );
126 let minter_lookup = T::Lookup::unlookup(minter.clone());
127 let origin = SystemOrigin::Signed(minter);
128 Assets::<T, I>::mint(
129 origin.clone().into(),
130 asset_id.clone(),
131 minter_lookup,
132 (100 * (n + 1)).into(),
133 )
134 .unwrap();
135 let enough = T::Currency::minimum_balance();
136 for i in 0..n {
137 let target = account("approval", i, SEED);
138 T::Currency::make_free_balance_be(&target, enough);
139 let target_lookup = T::Lookup::unlookup(target);
140 Assets::<T, I>::approve_transfer(
141 origin.clone().into(),
142 asset_id.clone(),
143 target_lookup,
144 100u32.into(),
145 )
146 .unwrap();
147 }
148}
149
150fn assert_last_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::RuntimeEvent) {
151 frame_system::Pallet::<T>::assert_last_event(generic_event.into());
152}
153
154fn assert_event<T: Config<I>, I: 'static>(generic_event: <T as Config<I>>::RuntimeEvent) {
155 frame_system::Pallet::<T>::assert_has_event(generic_event.into());
156}
157
158benchmarks_instance_pallet! {
159 create {
160 let asset_id = default_asset_id::<T, I>();
161 let origin = T::CreateOrigin::try_successful_origin(&asset_id.clone().into())
162 .map_err(|_| BenchmarkError::Weightless)?;
163 let caller = T::CreateOrigin::ensure_origin(origin.clone(), &asset_id.clone().into()).unwrap();
164 let caller_lookup = T::Lookup::unlookup(caller.clone());
165 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
166 let next_id: T::AssetId = asset_id.clone().into();
168 NextAssetId::<T, I>::put(next_id);
169 }: _<T::RuntimeOrigin>(origin, asset_id.clone(), caller_lookup, 1u32.into())
170 verify {
171 assert_last_event::<T, I>(Event::Created { asset_id: asset_id.into(), creator: caller.clone(), owner: caller }.into());
172 }
173
174 force_create {
175 let asset_id = default_asset_id::<T, I>();
176 let caller: T::AccountId = whitelisted_caller();
177 let caller_lookup = T::Lookup::unlookup(caller.clone());
178 let next_id: T::AssetId = asset_id.clone().into();
180 NextAssetId::<T, I>::put(next_id);
181 }: _(SystemOrigin::Root, asset_id.clone(), caller_lookup, true, 1u32.into())
182 verify {
183 assert_last_event::<T, I>(Event::ForceCreated { asset_id: asset_id.into(), owner: caller }.into());
184 }
185
186 start_destroy {
187 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
188 Assets::<T, I>::freeze_asset(
189 SystemOrigin::Signed(caller.clone()).into(),
190 asset_id.clone(),
191 )?;
192 }:_(SystemOrigin::Signed(caller), asset_id.clone())
193 verify {
194 assert_last_event::<T, I>(Event::DestructionStarted { asset_id: asset_id.into() }.into());
195 }
196
197 destroy_accounts {
198 let c in 0 .. T::RemoveItemsLimit::get();
199 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
200 add_sufficients::<T, I>(caller.clone(), c);
201 Assets::<T, I>::freeze_asset(
202 SystemOrigin::Signed(caller.clone()).into(),
203 asset_id.clone(),
204 )?;
205 Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?;
206 }:_(SystemOrigin::Signed(caller), asset_id.clone())
207 verify {
208 assert_last_event::<T, I>(Event::AccountsDestroyed {
209 asset_id: asset_id.into(),
210 accounts_destroyed: c,
211 accounts_remaining: 0,
212 }.into());
213 }
214
215 destroy_approvals {
216 let a in 0 .. T::RemoveItemsLimit::get();
217 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
218 add_approvals::<T, I>(caller.clone(), a);
219 Assets::<T, I>::freeze_asset(
220 SystemOrigin::Signed(caller.clone()).into(),
221 asset_id.clone(),
222 )?;
223 Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?;
224 }:_(SystemOrigin::Signed(caller), asset_id.clone())
225 verify {
226 assert_last_event::<T, I>(Event::ApprovalsDestroyed {
227 asset_id: asset_id.into(),
228 approvals_destroyed: a,
229 approvals_remaining: 0,
230 }.into());
231 }
232
233 finish_destroy {
234 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
235 Assets::<T, I>::freeze_asset(
236 SystemOrigin::Signed(caller.clone()).into(),
237 asset_id.clone(),
238 )?;
239 Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?;
240 }:_(SystemOrigin::Signed(caller), asset_id.clone())
241 verify {
242 assert_last_event::<T, I>(Event::Destroyed {
243 asset_id: asset_id.into(),
244 }.into()
245 );
246 }
247
248 mint {
249 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
250 let amount = T::Balance::from(100u32);
251 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount)
252 verify {
253 assert_last_event::<T, I>(Event::Issued { asset_id: asset_id.into(), owner: caller, amount }.into());
254 }
255
256 burn {
257 let amount = T::Balance::from(100u32);
258 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
259 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount)
260 verify {
261 assert_last_event::<T, I>(Event::Burned { asset_id: asset_id.into(), owner: caller, balance: amount }.into());
262 }
263
264 transfer {
265 let amount = T::Balance::from(100u32);
266 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
267 let target: T::AccountId = account("target", 0, SEED);
268 let target_lookup = T::Lookup::unlookup(target.clone());
269 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount)
270 verify {
271 assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
272 }
273
274 transfer_keep_alive {
275 let mint_amount = T::Balance::from(200u32);
276 let amount = T::Balance::from(100u32);
277 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, mint_amount);
278 let target: T::AccountId = account("target", 0, SEED);
279 let target_lookup = T::Lookup::unlookup(target.clone());
280 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount)
281 verify {
282 assert!(frame_system::Pallet::<T>::account_exists(&caller));
283 assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
284 }
285
286 force_transfer {
287 let amount = T::Balance::from(100u32);
288 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
289 let target: T::AccountId = account("target", 0, SEED);
290 let target_lookup = T::Lookup::unlookup(target.clone());
291 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, target_lookup, amount)
292 verify {
293 assert_last_event::<T, I>(
294 Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()
295 );
296 }
297
298 freeze {
299 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
300 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup)
301 verify {
302 assert_last_event::<T, I>(Event::Frozen { asset_id: asset_id.into(), who: caller }.into());
303 }
304
305 thaw {
306 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
307 Assets::<T, I>::freeze(
308 SystemOrigin::Signed(caller.clone()).into(),
309 asset_id.clone(),
310 caller_lookup.clone(),
311 )?;
312 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup)
313 verify {
314 assert_last_event::<T, I>(Event::Thawed { asset_id: asset_id.into(), who: caller }.into());
315 }
316
317 freeze_asset {
318 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
319 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone())
320 verify {
321 assert_last_event::<T, I>(Event::AssetFrozen { asset_id: asset_id.into() }.into());
322 }
323
324 thaw_asset {
325 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
326 Assets::<T, I>::freeze_asset(
327 SystemOrigin::Signed(caller.clone()).into(),
328 asset_id.clone(),
329 )?;
330 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone())
331 verify {
332 assert_last_event::<T, I>(Event::AssetThawed { asset_id: asset_id.into() }.into());
333 }
334
335 transfer_ownership {
336 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
337 let target: T::AccountId = account("target", 0, SEED);
338 let target_lookup = T::Lookup::unlookup(target.clone());
339 }: _(SystemOrigin::Signed(caller), asset_id.clone(), target_lookup)
340 verify {
341 assert_last_event::<T, I>(Event::OwnerChanged { asset_id: asset_id.into(), owner: target }.into());
342 }
343
344 set_team {
345 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
346 let target0 = T::Lookup::unlookup(account("target", 0, SEED));
347 let target1 = T::Lookup::unlookup(account("target", 1, SEED));
348 let target2 = T::Lookup::unlookup(account("target", 2, SEED));
349 }: _(SystemOrigin::Signed(caller), asset_id.clone(), target0, target1, target2)
350 verify {
351 assert_last_event::<T, I>(Event::TeamChanged {
352 asset_id: asset_id.into(),
353 issuer: account("target", 0, SEED),
354 admin: account("target", 1, SEED),
355 freezer: account("target", 2, SEED),
356 }.into());
357 }
358
359 set_reserves {
360 let n in 0 .. MAX_RESERVES;
361 let (asset_id, caller, reserves) = create_default_reserves::<T, I>(n);
362 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
363 let bounded_reserves = reserves.clone().try_into().unwrap();
364 }: _(SystemOrigin::Signed(caller), asset_id.clone(), bounded_reserves)
365 verify {
366 let expected_event = if reserves.is_empty() {
367 Event::ReservesRemoved { asset_id: asset_id.into() }
368 } else {
369 Event::ReservesUpdated { asset_id: asset_id.into(), reserves: reserves }
370 };
371 assert_last_event::<T, I>(expected_event.into());
372 }
373
374 set_metadata {
375 let n in 0 .. T::StringLimit::get();
376 let s in 0 .. T::StringLimit::get();
377
378 let name = vec![0u8; n as usize];
379 let symbol = vec![0u8; s as usize];
380 let decimals = 12;
381
382 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
383 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
384 }: _(SystemOrigin::Signed(caller), asset_id.clone(), name.clone(), symbol.clone(), decimals)
385 verify {
386 assert_last_event::<T, I>(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into());
387 }
388
389 clear_metadata {
390 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
391 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
392 let dummy = vec![0u8; T::StringLimit::get() as usize];
393 let origin = SystemOrigin::Signed(caller.clone()).into();
394 Assets::<T, I>::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?;
395 }: _(SystemOrigin::Signed(caller), asset_id.clone())
396 verify {
397 assert_last_event::<T, I>(Event::MetadataCleared { asset_id: asset_id.into() }.into());
398 }
399
400 force_set_metadata {
401 let n in 0 .. T::StringLimit::get();
402 let s in 0 .. T::StringLimit::get();
403
404 let name = vec![0u8; n as usize];
405 let symbol = vec![0u8; s as usize];
406 let decimals = 12;
407
408 let (asset_id, _, _) = create_default_asset::<T, I>(true);
409
410 let origin =
411 T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
412 let call = Call::<T, I>::force_set_metadata {
413 id: asset_id.clone(),
414 name: name.clone(),
415 symbol: symbol.clone(),
416 decimals,
417 is_frozen: false,
418 };
419 }: { call.dispatch_bypass_filter(origin)? }
420 verify {
421 assert_last_event::<T, I>(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into());
422 }
423
424 force_clear_metadata {
425 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
426 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
427 let dummy = vec![0u8; T::StringLimit::get() as usize];
428 let origin = SystemOrigin::Signed(caller).into();
429 Assets::<T, I>::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?;
430
431 let origin =
432 T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
433 let call = Call::<T, I>::force_clear_metadata { id: asset_id.clone() };
434 }: { call.dispatch_bypass_filter(origin)? }
435 verify {
436 assert_last_event::<T, I>(Event::MetadataCleared { asset_id: asset_id.into() }.into());
437 }
438
439 force_asset_status {
440 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
441
442 let origin =
443 T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
444 let call = Call::<T, I>::force_asset_status {
445 id: asset_id.clone(),
446 owner: caller_lookup.clone(),
447 issuer: caller_lookup.clone(),
448 admin: caller_lookup.clone(),
449 freezer: caller_lookup,
450 min_balance: 100u32.into(),
451 is_sufficient: true,
452 is_frozen: false,
453 };
454 }: { call.dispatch_bypass_filter(origin)? }
455 verify {
456 assert_last_event::<T, I>(Event::AssetStatusChanged { asset_id: asset_id.into() }.into());
457 }
458
459 approve_transfer {
460 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
461 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
462
463 let delegate: T::AccountId = account("delegate", 0, SEED);
464 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
465 let amount = 100u32.into();
466 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup, amount)
467 verify {
468 assert_last_event::<T, I>(Event::ApprovedTransfer { asset_id: asset_id.into(), source: caller, delegate, amount }.into());
469 }
470
471 transfer_approved {
472 let (asset_id, owner, owner_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
473 T::Currency::make_free_balance_be(&owner, DepositBalanceOf::<T, I>::max_value());
474
475 let delegate: T::AccountId = account("delegate", 0, SEED);
476 whitelist_account!(delegate);
477 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
478 let amount = 100u32.into();
479 let origin = SystemOrigin::Signed(owner.clone()).into();
480 Assets::<T, I>::approve_transfer(origin, asset_id.clone(), delegate_lookup, amount)?;
481
482 let dest: T::AccountId = account("dest", 0, SEED);
483 let dest_lookup = T::Lookup::unlookup(dest.clone());
484 }: _(SystemOrigin::Signed(delegate.clone()), asset_id.clone(), owner_lookup, dest_lookup, amount)
485 verify {
486 assert!(T::Currency::reserved_balance(&owner).is_zero());
487 assert_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: owner, to: dest, amount }.into());
488 }
489
490 cancel_approval {
491 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
492 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
493
494 let delegate: T::AccountId = account("delegate", 0, SEED);
495 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
496 let amount = 100u32.into();
497 let origin = SystemOrigin::Signed(caller.clone()).into();
498 Assets::<T, I>::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?;
499 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup)
500 verify {
501 assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into());
502 }
503
504 force_cancel_approval {
505 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
506 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
507
508 let delegate: T::AccountId = account("delegate", 0, SEED);
509 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
510 let amount = 100u32.into();
511 let origin = SystemOrigin::Signed(caller.clone()).into();
512 Assets::<T, I>::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?;
513 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, delegate_lookup)
514 verify {
515 assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into());
516 }
517
518 set_min_balance {
519 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(false);
520 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), 50u32.into())
521 verify {
522 assert_last_event::<T, I>(Event::AssetMinBalanceChanged { asset_id: asset_id.into(), new_min_balance: 50u32.into() }.into());
523 }
524
525 touch {
526 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
527 let new_account: T::AccountId = account("newaccount", 1, SEED);
528 T::Currency::make_free_balance_be(&new_account, DepositBalanceOf::<T, I>::max_value());
529 assert_ne!(asset_owner, new_account);
530 assert!(!Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
531 }: _(SystemOrigin::Signed(new_account.clone()), asset_id.clone())
532 verify {
533 assert!(Account::<T, I>::contains_key(asset_id.into(), &new_account));
534 }
535
536 touch_other {
537 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
538 let new_account: T::AccountId = account("newaccount", 1, SEED);
539 let new_account_lookup = T::Lookup::unlookup(new_account.clone());
540 T::Currency::make_free_balance_be(&asset_owner, DepositBalanceOf::<T, I>::max_value());
541 assert_ne!(asset_owner, new_account);
542 assert!(!Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
543 }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id.clone(), new_account_lookup)
544 verify {
545 assert!(Account::<T, I>::contains_key(asset_id.into(), &new_account));
546 }
547
548 refund {
549 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
550 let new_account: T::AccountId = account("newaccount", 1, SEED);
551 T::Currency::make_free_balance_be(&new_account, DepositBalanceOf::<T, I>::max_value());
552 assert_ne!(asset_owner, new_account);
553 assert!(Assets::<T, I>::touch(
554 SystemOrigin::Signed(new_account.clone()).into(),
555 asset_id.clone()
556 ).is_ok());
557 assert_eq!(T::Currency::reserved_balance(&new_account), T::AssetAccountDeposit::get());
559 assert!(Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
561 }: _(SystemOrigin::Signed(new_account.clone()), asset_id, true)
562 verify {
563 assert!(T::Currency::reserved_balance(&new_account).is_zero());
565 }
566
567 refund_other {
568 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
569 let new_account: T::AccountId = account("newaccount", 1, SEED);
570 let new_account_lookup = T::Lookup::unlookup(new_account.clone());
571 T::Currency::make_free_balance_be(&asset_owner, DepositBalanceOf::<T, I>::max_value());
572 assert_ne!(asset_owner, new_account);
573 assert!(Assets::<T, I>::touch_other(
574 SystemOrigin::Signed(asset_owner.clone()).into(),
575 asset_id.clone(),
576 new_account_lookup.clone()
577 ).is_ok());
578 assert_eq!(T::Currency::reserved_balance(&asset_owner), T::AssetAccountDeposit::get());
580 assert!(Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
581 }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup.clone())
582 verify {
583 assert!(T::Currency::reserved_balance(&asset_owner).is_zero());
585 }
586
587 block {
588 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
589 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup)
590 verify {
591 assert_last_event::<T, I>(Event::Blocked { asset_id: asset_id.into(), who: caller }.into());
592 }
593
594 transfer_all {
595 let amount = T::Balance::from(2 * MIN_BALANCE);
596 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
597 let target: T::AccountId = account("target", 0, SEED);
598 let target_lookup = T::Lookup::unlookup(target.clone());
599 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, false)
600 verify {
601 assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
602 }
603
604 total_issuance {
605 use frame_support::traits::fungibles::Inspect;
606 let (asset_id, _, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
607 let amount;
608 }: {
609 amount = Pallet::<T, I>::total_issuance(asset_id.into());
610 } verify {
611 assert_eq!(amount, 100u32.into());
612 }
613
614 balance {
615 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
616 let amount;
617 }: {
618 amount = Pallet::<T, I>::balance(asset_id.into(), caller);
619 } verify {
620 assert_eq!(amount, 100u32.into());
621 }
622
623 allowance {
624 use frame_support::traits::fungibles::approvals::Inspect;
625 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
626 add_approvals::<T, I>(caller.clone(), 1);
627 let delegate: T::AccountId = account("approval", 0, SEED);
628 let amount;
629 }: {
630 amount = Pallet::<T, I>::allowance(asset_id.into(), &caller, &delegate);
631 } verify {
632 assert_eq!(amount, 100u32.into());
633 }
634
635 migration_v2_foreign_asset_set_reserve_weight {
636 let (id, _, _) = create_default_asset::<T, I>(true);
637 let id: <T as pallet::Config<I>>::AssetId = id.into();
638 let reserve = T::BenchmarkHelper::create_reserve_id_parameter(42);
639 }: {
640 let asset_id = Asset::<T, I>::iter_keys().next()
641 .ok_or_else(|| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
642 assert_eq!(id, asset_id);
643 let bounded_reserves = vec![reserve.clone()].try_into().unwrap();
644 Pallet::<T, I>::unchecked_update_reserves(asset_id, bounded_reserves).unwrap();
645 }
646 verify {
647 assert_eq!(Reserves::<T, I>::get(id)[0], reserve);
648 }
649
650 get_metadata {
651 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
652 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
653 let name_bytes = vec![0u8; T::StringLimit::get() as usize];
654 let symbol_bytes = vec![0u8; T::StringLimit::get() as usize];
655 let origin = SystemOrigin::Signed(caller).into();
656 Assets::<T, I>::set_metadata(origin, asset_id.clone(), name_bytes.clone(), symbol_bytes.clone(), 12)?;
657 }: {
658 let _ = Pallet::<T, I>::get_metadata(asset_id.clone().into());
659 } verify {
660 let metadata = Pallet::<T, I>::get_metadata(asset_id.into());
661 assert!(metadata.is_some());
662 let metadata = metadata.unwrap();
663 assert_eq!(metadata.name.to_vec(), name_bytes);
664 assert_eq!(metadata.symbol.to_vec(), symbol_bytes);
665 assert_eq!(metadata.decimals, 12);
666 }
667
668 impl_benchmark_test_suite!(Assets, crate::mock::new_test_ext(), crate::mock::Test)
669}