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 }: _<T::RuntimeOrigin>(origin, asset_id.clone(), caller_lookup, 1u32.into())
167 verify {
168 assert_last_event::<T, I>(Event::Created { asset_id: asset_id.into(), creator: caller.clone(), owner: caller }.into());
169 }
170
171 force_create {
172 let asset_id = default_asset_id::<T, I>();
173 let caller: T::AccountId = whitelisted_caller();
174 let caller_lookup = T::Lookup::unlookup(caller.clone());
175 }: _(SystemOrigin::Root, asset_id.clone(), caller_lookup, true, 1u32.into())
176 verify {
177 assert_last_event::<T, I>(Event::ForceCreated { asset_id: asset_id.into(), owner: caller }.into());
178 }
179
180 start_destroy {
181 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
182 Assets::<T, I>::freeze_asset(
183 SystemOrigin::Signed(caller.clone()).into(),
184 asset_id.clone(),
185 )?;
186 }:_(SystemOrigin::Signed(caller), asset_id.clone())
187 verify {
188 assert_last_event::<T, I>(Event::DestructionStarted { asset_id: asset_id.into() }.into());
189 }
190
191 destroy_accounts {
192 let c in 0 .. T::RemoveItemsLimit::get();
193 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
194 add_sufficients::<T, I>(caller.clone(), c);
195 Assets::<T, I>::freeze_asset(
196 SystemOrigin::Signed(caller.clone()).into(),
197 asset_id.clone(),
198 )?;
199 Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?;
200 }:_(SystemOrigin::Signed(caller), asset_id.clone())
201 verify {
202 assert_last_event::<T, I>(Event::AccountsDestroyed {
203 asset_id: asset_id.into(),
204 accounts_destroyed: c,
205 accounts_remaining: 0,
206 }.into());
207 }
208
209 destroy_approvals {
210 let a in 0 .. T::RemoveItemsLimit::get();
211 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
212 add_approvals::<T, I>(caller.clone(), a);
213 Assets::<T, I>::freeze_asset(
214 SystemOrigin::Signed(caller.clone()).into(),
215 asset_id.clone(),
216 )?;
217 Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?;
218 }:_(SystemOrigin::Signed(caller), asset_id.clone())
219 verify {
220 assert_last_event::<T, I>(Event::ApprovalsDestroyed {
221 asset_id: asset_id.into(),
222 approvals_destroyed: a,
223 approvals_remaining: 0,
224 }.into());
225 }
226
227 finish_destroy {
228 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
229 Assets::<T, I>::freeze_asset(
230 SystemOrigin::Signed(caller.clone()).into(),
231 asset_id.clone(),
232 )?;
233 Assets::<T,I>::start_destroy(SystemOrigin::Signed(caller.clone()).into(), asset_id.clone())?;
234 }:_(SystemOrigin::Signed(caller), asset_id.clone())
235 verify {
236 assert_last_event::<T, I>(Event::Destroyed {
237 asset_id: asset_id.into(),
238 }.into()
239 );
240 }
241
242 mint {
243 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
244 let amount = T::Balance::from(100u32);
245 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount)
246 verify {
247 assert_last_event::<T, I>(Event::Issued { asset_id: asset_id.into(), owner: caller, amount }.into());
248 }
249
250 burn {
251 let amount = T::Balance::from(100u32);
252 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
253 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, amount)
254 verify {
255 assert_last_event::<T, I>(Event::Burned { asset_id: asset_id.into(), owner: caller, balance: amount }.into());
256 }
257
258 transfer {
259 let amount = T::Balance::from(100u32);
260 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
261 let target: T::AccountId = account("target", 0, SEED);
262 let target_lookup = T::Lookup::unlookup(target.clone());
263 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount)
264 verify {
265 assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
266 }
267
268 transfer_keep_alive {
269 let mint_amount = T::Balance::from(200u32);
270 let amount = T::Balance::from(100u32);
271 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, mint_amount);
272 let target: T::AccountId = account("target", 0, SEED);
273 let target_lookup = T::Lookup::unlookup(target.clone());
274 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, amount)
275 verify {
276 assert!(frame_system::Pallet::<T>::account_exists(&caller));
277 assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
278 }
279
280 force_transfer {
281 let amount = T::Balance::from(100u32);
282 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
283 let target: T::AccountId = account("target", 0, SEED);
284 let target_lookup = T::Lookup::unlookup(target.clone());
285 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, target_lookup, amount)
286 verify {
287 assert_last_event::<T, I>(
288 Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into()
289 );
290 }
291
292 freeze {
293 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
294 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup)
295 verify {
296 assert_last_event::<T, I>(Event::Frozen { asset_id: asset_id.into(), who: caller }.into());
297 }
298
299 thaw {
300 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
301 Assets::<T, I>::freeze(
302 SystemOrigin::Signed(caller.clone()).into(),
303 asset_id.clone(),
304 caller_lookup.clone(),
305 )?;
306 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup)
307 verify {
308 assert_last_event::<T, I>(Event::Thawed { asset_id: asset_id.into(), who: caller }.into());
309 }
310
311 freeze_asset {
312 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
313 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone())
314 verify {
315 assert_last_event::<T, I>(Event::AssetFrozen { asset_id: asset_id.into() }.into());
316 }
317
318 thaw_asset {
319 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
320 Assets::<T, I>::freeze_asset(
321 SystemOrigin::Signed(caller.clone()).into(),
322 asset_id.clone(),
323 )?;
324 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone())
325 verify {
326 assert_last_event::<T, I>(Event::AssetThawed { asset_id: asset_id.into() }.into());
327 }
328
329 transfer_ownership {
330 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
331 let target: T::AccountId = account("target", 0, SEED);
332 let target_lookup = T::Lookup::unlookup(target.clone());
333 }: _(SystemOrigin::Signed(caller), asset_id.clone(), target_lookup)
334 verify {
335 assert_last_event::<T, I>(Event::OwnerChanged { asset_id: asset_id.into(), owner: target }.into());
336 }
337
338 set_team {
339 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
340 let target0 = T::Lookup::unlookup(account("target", 0, SEED));
341 let target1 = T::Lookup::unlookup(account("target", 1, SEED));
342 let target2 = T::Lookup::unlookup(account("target", 2, SEED));
343 }: _(SystemOrigin::Signed(caller), asset_id.clone(), target0, target1, target2)
344 verify {
345 assert_last_event::<T, I>(Event::TeamChanged {
346 asset_id: asset_id.into(),
347 issuer: account("target", 0, SEED),
348 admin: account("target", 1, SEED),
349 freezer: account("target", 2, SEED),
350 }.into());
351 }
352
353 set_reserves {
354 let n in 0 .. MAX_RESERVES;
355 let (asset_id, caller, reserves) = create_default_reserves::<T, I>(n);
356 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
357 let bounded_reserves = reserves.clone().try_into().unwrap();
358 }: _(SystemOrigin::Signed(caller), asset_id.clone(), bounded_reserves)
359 verify {
360 let expected_event = if reserves.is_empty() {
361 Event::ReservesRemoved { asset_id: asset_id.into() }
362 } else {
363 Event::ReservesUpdated { asset_id: asset_id.into(), reserves: reserves }
364 };
365 assert_last_event::<T, I>(expected_event.into());
366 }
367
368 set_metadata {
369 let n in 0 .. T::StringLimit::get();
370 let s in 0 .. T::StringLimit::get();
371
372 let name = vec![0u8; n as usize];
373 let symbol = vec![0u8; s as usize];
374 let decimals = 12;
375
376 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
377 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
378 }: _(SystemOrigin::Signed(caller), asset_id.clone(), name.clone(), symbol.clone(), decimals)
379 verify {
380 assert_last_event::<T, I>(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into());
381 }
382
383 clear_metadata {
384 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
385 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
386 let dummy = vec![0u8; T::StringLimit::get() as usize];
387 let origin = SystemOrigin::Signed(caller.clone()).into();
388 Assets::<T, I>::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?;
389 }: _(SystemOrigin::Signed(caller), asset_id.clone())
390 verify {
391 assert_last_event::<T, I>(Event::MetadataCleared { asset_id: asset_id.into() }.into());
392 }
393
394 force_set_metadata {
395 let n in 0 .. T::StringLimit::get();
396 let s in 0 .. T::StringLimit::get();
397
398 let name = vec![0u8; n as usize];
399 let symbol = vec![0u8; s as usize];
400 let decimals = 12;
401
402 let (asset_id, _, _) = create_default_asset::<T, I>(true);
403
404 let origin =
405 T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
406 let call = Call::<T, I>::force_set_metadata {
407 id: asset_id.clone(),
408 name: name.clone(),
409 symbol: symbol.clone(),
410 decimals,
411 is_frozen: false,
412 };
413 }: { call.dispatch_bypass_filter(origin)? }
414 verify {
415 assert_last_event::<T, I>(Event::MetadataSet { asset_id: asset_id.into(), name, symbol, decimals, is_frozen: false }.into());
416 }
417
418 force_clear_metadata {
419 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
420 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
421 let dummy = vec![0u8; T::StringLimit::get() as usize];
422 let origin = SystemOrigin::Signed(caller).into();
423 Assets::<T, I>::set_metadata(origin, asset_id.clone(), dummy.clone(), dummy, 12)?;
424
425 let origin =
426 T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
427 let call = Call::<T, I>::force_clear_metadata { id: asset_id.clone() };
428 }: { call.dispatch_bypass_filter(origin)? }
429 verify {
430 assert_last_event::<T, I>(Event::MetadataCleared { asset_id: asset_id.into() }.into());
431 }
432
433 force_asset_status {
434 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
435
436 let origin =
437 T::ForceOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
438 let call = Call::<T, I>::force_asset_status {
439 id: asset_id.clone(),
440 owner: caller_lookup.clone(),
441 issuer: caller_lookup.clone(),
442 admin: caller_lookup.clone(),
443 freezer: caller_lookup,
444 min_balance: 100u32.into(),
445 is_sufficient: true,
446 is_frozen: false,
447 };
448 }: { call.dispatch_bypass_filter(origin)? }
449 verify {
450 assert_last_event::<T, I>(Event::AssetStatusChanged { asset_id: asset_id.into() }.into());
451 }
452
453 approve_transfer {
454 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
455 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
456
457 let delegate: T::AccountId = account("delegate", 0, SEED);
458 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
459 let amount = 100u32.into();
460 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup, amount)
461 verify {
462 assert_last_event::<T, I>(Event::ApprovedTransfer { asset_id: asset_id.into(), source: caller, delegate, amount }.into());
463 }
464
465 transfer_approved {
466 let (asset_id, owner, owner_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
467 T::Currency::make_free_balance_be(&owner, DepositBalanceOf::<T, I>::max_value());
468
469 let delegate: T::AccountId = account("delegate", 0, SEED);
470 whitelist_account!(delegate);
471 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
472 let amount = 100u32.into();
473 let origin = SystemOrigin::Signed(owner.clone()).into();
474 Assets::<T, I>::approve_transfer(origin, asset_id.clone(), delegate_lookup, amount)?;
475
476 let dest: T::AccountId = account("dest", 0, SEED);
477 let dest_lookup = T::Lookup::unlookup(dest.clone());
478 }: _(SystemOrigin::Signed(delegate.clone()), asset_id.clone(), owner_lookup, dest_lookup, amount)
479 verify {
480 assert!(T::Currency::reserved_balance(&owner).is_zero());
481 assert_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: owner, to: dest, amount }.into());
482 }
483
484 cancel_approval {
485 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
486 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
487
488 let delegate: T::AccountId = account("delegate", 0, SEED);
489 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
490 let amount = 100u32.into();
491 let origin = SystemOrigin::Signed(caller.clone()).into();
492 Assets::<T, I>::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?;
493 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), delegate_lookup)
494 verify {
495 assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into());
496 }
497
498 force_cancel_approval {
499 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
500 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
501
502 let delegate: T::AccountId = account("delegate", 0, SEED);
503 let delegate_lookup = T::Lookup::unlookup(delegate.clone());
504 let amount = 100u32.into();
505 let origin = SystemOrigin::Signed(caller.clone()).into();
506 Assets::<T, I>::approve_transfer(origin, asset_id.clone(), delegate_lookup.clone(), amount)?;
507 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup, delegate_lookup)
508 verify {
509 assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into());
510 }
511
512 set_min_balance {
513 let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(false);
514 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), 50u32.into())
515 verify {
516 assert_last_event::<T, I>(Event::AssetMinBalanceChanged { asset_id: asset_id.into(), new_min_balance: 50u32.into() }.into());
517 }
518
519 touch {
520 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
521 let new_account: T::AccountId = account("newaccount", 1, SEED);
522 T::Currency::make_free_balance_be(&new_account, DepositBalanceOf::<T, I>::max_value());
523 assert_ne!(asset_owner, new_account);
524 assert!(!Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
525 }: _(SystemOrigin::Signed(new_account.clone()), asset_id.clone())
526 verify {
527 assert!(Account::<T, I>::contains_key(asset_id.into(), &new_account));
528 }
529
530 touch_other {
531 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
532 let new_account: T::AccountId = account("newaccount", 1, SEED);
533 let new_account_lookup = T::Lookup::unlookup(new_account.clone());
534 T::Currency::make_free_balance_be(&asset_owner, DepositBalanceOf::<T, I>::max_value());
535 assert_ne!(asset_owner, new_account);
536 assert!(!Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
537 }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id.clone(), new_account_lookup)
538 verify {
539 assert!(Account::<T, I>::contains_key(asset_id.into(), &new_account));
540 }
541
542 refund {
543 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
544 let new_account: T::AccountId = account("newaccount", 1, SEED);
545 T::Currency::make_free_balance_be(&new_account, DepositBalanceOf::<T, I>::max_value());
546 assert_ne!(asset_owner, new_account);
547 assert!(Assets::<T, I>::touch(
548 SystemOrigin::Signed(new_account.clone()).into(),
549 asset_id.clone()
550 ).is_ok());
551 assert_eq!(T::Currency::reserved_balance(&new_account), T::AssetAccountDeposit::get());
553 assert!(Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
555 }: _(SystemOrigin::Signed(new_account.clone()), asset_id, true)
556 verify {
557 assert!(T::Currency::reserved_balance(&new_account).is_zero());
559 }
560
561 refund_other {
562 let (asset_id, asset_owner, asset_owner_lookup) = create_default_asset::<T, I>(false);
563 let new_account: T::AccountId = account("newaccount", 1, SEED);
564 let new_account_lookup = T::Lookup::unlookup(new_account.clone());
565 T::Currency::make_free_balance_be(&asset_owner, DepositBalanceOf::<T, I>::max_value());
566 assert_ne!(asset_owner, new_account);
567 assert!(Assets::<T, I>::touch_other(
568 SystemOrigin::Signed(asset_owner.clone()).into(),
569 asset_id.clone(),
570 new_account_lookup.clone()
571 ).is_ok());
572 assert_eq!(T::Currency::reserved_balance(&asset_owner), T::AssetAccountDeposit::get());
574 assert!(Account::<T, I>::contains_key(asset_id.clone().into(), &new_account));
575 }: _(SystemOrigin::Signed(asset_owner.clone()), asset_id, new_account_lookup.clone())
576 verify {
577 assert!(T::Currency::reserved_balance(&asset_owner).is_zero());
579 }
580
581 block {
582 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, 100u32.into());
583 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), caller_lookup)
584 verify {
585 assert_last_event::<T, I>(Event::Blocked { asset_id: asset_id.into(), who: caller }.into());
586 }
587
588 transfer_all {
589 let amount = T::Balance::from(2 * MIN_BALANCE);
590 let (asset_id, caller, caller_lookup) = create_default_minted_asset::<T, I>(true, amount);
591 let target: T::AccountId = account("target", 0, SEED);
592 let target_lookup = T::Lookup::unlookup(target.clone());
593 }: _(SystemOrigin::Signed(caller.clone()), asset_id.clone(), target_lookup, false)
594 verify {
595 assert_last_event::<T, I>(Event::Transferred { asset_id: asset_id.into(), from: caller, to: target, amount }.into());
596 }
597
598 total_issuance {
599 use frame_support::traits::fungibles::Inspect;
600 let (asset_id, _, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
601 let amount;
602 }: {
603 amount = Pallet::<T, I>::total_issuance(asset_id.into());
604 } verify {
605 assert_eq!(amount, 100u32.into());
606 }
607
608 balance {
609 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
610 let amount;
611 }: {
612 amount = Pallet::<T, I>::balance(asset_id.into(), caller);
613 } verify {
614 assert_eq!(amount, 100u32.into());
615 }
616
617 allowance {
618 use frame_support::traits::fungibles::approvals::Inspect;
619 let (asset_id, caller, _) = create_default_minted_asset::<T, I>(true, 100u32.into());
620 add_approvals::<T, I>(caller.clone(), 1);
621 let delegate: T::AccountId = account("approval", 0, SEED);
622 let amount;
623 }: {
624 amount = Pallet::<T, I>::allowance(asset_id.into(), &caller, &delegate);
625 } verify {
626 assert_eq!(amount, 100u32.into());
627 }
628
629 migration_v2_foreign_asset_set_reserve_weight {
630 let (id, _, _) = create_default_asset::<T, I>(true);
631 let id: <T as pallet::Config<I>>::AssetId = id.into();
632 let reserve = T::BenchmarkHelper::create_reserve_id_parameter(42);
633 }: {
634 let asset_id = Asset::<T, I>::iter_keys().next()
635 .ok_or_else(|| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
636 assert_eq!(id, asset_id);
637 let bounded_reserves = vec![reserve.clone()].try_into().unwrap();
638 Pallet::<T, I>::unchecked_update_reserves(asset_id, bounded_reserves).unwrap();
639 }
640 verify {
641 assert_eq!(Reserves::<T, I>::get(id)[0], reserve);
642 }
643
644 get_metadata {
645 let (asset_id, caller, _) = create_default_asset::<T, I>(true);
646 T::Currency::make_free_balance_be(&caller, DepositBalanceOf::<T, I>::max_value());
647 let name_bytes = vec![0u8; T::StringLimit::get() as usize];
648 let symbol_bytes = vec![0u8; T::StringLimit::get() as usize];
649 let origin = SystemOrigin::Signed(caller).into();
650 Assets::<T, I>::set_metadata(origin, asset_id.clone(), name_bytes.clone(), symbol_bytes.clone(), 12)?;
651 }: {
652 let _ = Pallet::<T, I>::get_metadata(asset_id.clone().into());
653 } verify {
654 let metadata = Pallet::<T, I>::get_metadata(asset_id.into());
655 assert!(metadata.is_some());
656 let metadata = metadata.unwrap();
657 assert_eq!(metadata.name.to_vec(), name_bytes);
658 assert_eq!(metadata.symbol.to_vec(), symbol_bytes);
659 assert_eq!(metadata.decimals, 12);
660 }
661
662 impl_benchmark_test_suite!(Assets, crate::mock::new_test_ext(), crate::mock::Test)
663}