Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 4aa213c

Browse files
Szegoobkchr
andauthored
Assets pallet: Giving the asset owner the ability to set minimum balance (#13486)
* set_min_balance * allow when new_min_balance < old_min_balance * add more specific event * Update frame/assets/src/lib.rs Co-authored-by: Bastian Köcher <git@kchr.de> * Update frame/assets/src/lib.rs Co-authored-by: Bastian Köcher <git@kchr.de> * ".git/.scripts/commands/bench/bench.sh" pallet dev pallet_assets * use actual weight --------- Co-authored-by: Bastian Köcher <git@kchr.de> Co-authored-by: command-bot <>
1 parent 024bfce commit 4aa213c

File tree

4 files changed

+337
-186
lines changed

4 files changed

+337
-186
lines changed

frame/assets/src/benchmarking.rs

+7
Original file line numberDiff line numberDiff line change
@@ -471,5 +471,12 @@ benchmarks_instance_pallet! {
471471
assert_last_event::<T, I>(Event::ApprovalCancelled { asset_id: asset_id.into(), owner: caller, delegate }.into());
472472
}
473473

474+
set_min_balance {
475+
let (asset_id, caller, caller_lookup) = create_default_asset::<T, I>(true);
476+
}: _(SystemOrigin::Signed(caller.clone()), asset_id, 50u32.into())
477+
verify {
478+
assert_last_event::<T, I>(Event::AssetMinBalanceChanged { asset_id: asset_id.into(), new_min_balance: 50u32.into() }.into());
479+
}
480+
474481
impl_benchmark_test_suite!(Assets, crate::mock::new_test_ext(), crate::mock::Test)
475482
}

frame/assets/src/lib.rs

+45
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ pub mod pallet {
514514
},
515515
/// An asset has had its attributes changed by the `Force` origin.
516516
AssetStatusChanged { asset_id: T::AssetId },
517+
/// The min_balance of an asset has been updated by the asset owner.
518+
AssetMinBalanceChanged { asset_id: T::AssetId, new_min_balance: T::Balance },
517519
}
518520

519521
#[pallet::error]
@@ -1511,6 +1513,49 @@ pub mod pallet {
15111513
let id: T::AssetId = id.into();
15121514
Self::do_refund(id, ensure_signed(origin)?, allow_burn)
15131515
}
1516+
1517+
/// Sets the minimum balance of an asset.
1518+
///
1519+
/// Only works if there aren't any accounts that are holding the asset or if
1520+
/// the new value of `min_balance` is less than the old one.
1521+
///
1522+
/// Origin must be Signed and the sender has to be the Owner of the
1523+
/// asset `id`.
1524+
///
1525+
/// - `id`: The identifier of the asset.
1526+
/// - `min_balance`: The new value of `min_balance`.
1527+
///
1528+
/// Emits `AssetMinBalanceChanged` event when successful.
1529+
#[pallet::call_index(28)]
1530+
#[pallet::weight(T::WeightInfo::set_min_balance())]
1531+
pub fn set_min_balance(
1532+
origin: OriginFor<T>,
1533+
id: T::AssetIdParameter,
1534+
min_balance: T::Balance,
1535+
) -> DispatchResult {
1536+
let origin = ensure_signed(origin)?;
1537+
let id: T::AssetId = id.into();
1538+
1539+
let mut details = Asset::<T, I>::get(id).ok_or(Error::<T, I>::Unknown)?;
1540+
ensure!(origin == details.owner, Error::<T, I>::NoPermission);
1541+
1542+
let old_min_balance = details.min_balance;
1543+
// Ensure that either the new min_balance is less than old min_balance or there aren't
1544+
// any accounts holding the asset.
1545+
ensure!(
1546+
min_balance < old_min_balance || details.accounts == 0,
1547+
Error::<T, I>::NoPermission
1548+
);
1549+
1550+
details.min_balance = min_balance;
1551+
Asset::<T, I>::insert(&id, details);
1552+
1553+
Self::deposit_event(Event::AssetMinBalanceChanged {
1554+
asset_id: id,
1555+
new_min_balance: min_balance,
1556+
});
1557+
Ok(())
1558+
}
15141559
}
15151560
}
15161561

frame/assets/src/tests.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,35 @@ fn force_asset_status_should_work() {
10911091
});
10921092
}
10931093

1094+
#[test]
1095+
fn set_min_balance_should_work() {
1096+
new_test_ext().execute_with(|| {
1097+
let id = 42;
1098+
Balances::make_free_balance_be(&1, 10);
1099+
assert_ok!(Assets::create(RuntimeOrigin::signed(1), id, 1, 30));
1100+
1101+
assert_ok!(Assets::mint(RuntimeOrigin::signed(1), id, 1, 50));
1102+
// won't execute because there is an asset holder.
1103+
assert_noop!(
1104+
Assets::set_min_balance(RuntimeOrigin::signed(1), id, 50),
1105+
Error::<Test>::NoPermission
1106+
);
1107+
1108+
// will execute because the new value of min_balance is less than the
1109+
// old value. 10 < 30
1110+
assert_ok!(Assets::mint(RuntimeOrigin::signed(1), id, 1, 10));
1111+
1112+
assert_ok!(Assets::burn(RuntimeOrigin::signed(1), id, 1, 50));
1113+
assert_noop!(
1114+
Assets::set_min_balance(RuntimeOrigin::signed(2), id, 50),
1115+
Error::<Test>::NoPermission
1116+
);
1117+
1118+
assert_ok!(Assets::set_min_balance(RuntimeOrigin::signed(1), id, 50));
1119+
assert_eq!(Asset::<Test>::get(id).unwrap().min_balance, 50);
1120+
});
1121+
}
1122+
10941123
#[test]
10951124
fn balance_conversion_should_work() {
10961125
new_test_ext().execute_with(|| {

0 commit comments

Comments
 (0)