diff --git a/frame/assets/src/benchmarking.rs b/frame/assets/src/benchmarking.rs index ede5b4e77fac6..66f486c7bfde5 100644 --- a/frame/assets/src/benchmarking.rs +++ b/frame/assets/src/benchmarking.rs @@ -105,7 +105,8 @@ fn add_sufficients, I: 'static>(minter: T::AccountId, n: u32) { fn add_approvals, I: 'static>(minter: T::AccountId, n: u32) { let asset_id = default_asset_id::(); - T::Currency::deposit_creating(&minter, T::ApprovalDeposit::get() * n.into()); + // taking into account the ED requirement enforced by `Balances::reserve` we do (n + 1). + T::Currency::deposit_creating(&minter, T::ApprovalDeposit::get() * (n + 1).into()); let minter_lookup = T::Lookup::unlookup(minter.clone()); let origin = SystemOrigin::Signed(minter); Assets::::mint(origin.clone().into(), asset_id, minter_lookup, (100 * (n + 1)).into()) diff --git a/frame/assets/src/tests.rs b/frame/assets/src/tests.rs index d5fcece0e91d8..c0ab225c733bd 100644 --- a/frame/assets/src/tests.rs +++ b/frame/assets/src/tests.rs @@ -163,7 +163,7 @@ fn approval_lifecycle_works() { // so we create it :) assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 50)); assert_eq!(Asset::::get(0).unwrap().approvals, 1); assert_eq!(Balances::reserved_balance(&1), 1); @@ -189,7 +189,7 @@ fn transfer_approved_all_funds() { // so we create it :) assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 50)); assert_eq!(Asset::::get(0).unwrap().approvals, 1); assert_eq!(Balances::reserved_balance(&1), 1); @@ -211,7 +211,7 @@ fn approval_deposits_work() { let e = BalancesError::::InsufficientBalance; assert_noop!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 50), e); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 50)); assert_eq!(Balances::reserved_balance(&1), 1); @@ -229,7 +229,7 @@ fn cannot_transfer_more_than_approved() { new_test_ext().execute_with(|| { assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 50)); let e = Error::::Unapproved; assert_noop!(Assets::transfer_approved(RuntimeOrigin::signed(2), 0, 1, 3, 51), e); @@ -241,7 +241,7 @@ fn cannot_transfer_more_than_exists() { new_test_ext().execute_with(|| { assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 101)); let e = Error::::BalanceLow; assert_noop!(Assets::transfer_approved(RuntimeOrigin::signed(2), 0, 1, 3, 101), e); @@ -253,7 +253,7 @@ fn cancel_approval_works() { new_test_ext().execute_with(|| { assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 50)); assert_eq!(Asset::::get(0).unwrap().approvals, 1); assert_noop!( @@ -283,7 +283,7 @@ fn force_cancel_approval_works() { new_test_ext().execute_with(|| { assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 50)); assert_eq!(Asset::::get(0).unwrap().approvals, 1); let e = Error::::NoPermission; @@ -509,13 +509,6 @@ fn min_balance_should_work() { assert!(Assets::maybe_balance(0, 1).is_none()); assert_eq!(Asset::::get(0).unwrap().accounts, 0); assert_eq!(take_hooks(), vec![Hook::Died(0, 1)]); - - // Death by `transfer_approved`. - assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); - assert_ok!(Assets::approve_transfer(RuntimeOrigin::signed(1), 0, 2, 100)); - assert_ok!(Assets::transfer_approved(RuntimeOrigin::signed(2), 0, 1, 3, 91)); - assert_eq!(take_hooks(), vec![Hook::Died(0, 1)]); }); } @@ -1154,7 +1147,7 @@ fn querying_allowance_should_work() { use frame_support::traits::tokens::fungibles::approvals::{Inspect, Mutate}; assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); - Balances::make_free_balance_be(&1, 1); + Balances::make_free_balance_be(&1, 2); assert_ok!(Assets::approve(0, &1, &2, 50)); assert_eq!(Assets::allowance(0, &1, &2), 50); // Transfer asset 0, from owner 1 and delegate 2 to destination 3 diff --git a/frame/balances/src/benchmarking.rs b/frame/balances/src/benchmarking.rs index 206adba0f044b..5f01e97c16952 100644 --- a/frame/balances/src/benchmarking.rs +++ b/frame/balances/src/benchmarking.rs @@ -201,17 +201,17 @@ benchmarks_instance_pallet! { // Give some multiple of the existential deposit let existential_deposit = T::ExistentialDeposit::get(); let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into()); - let _ = as Currency<_>>::make_free_balance_be(&user, balance); + let _ = as Currency<_>>::make_free_balance_be(&user, balance + existential_deposit); // Reserve the balance as ReservableCurrency<_>>::reserve(&user, balance)?; assert_eq!(Balances::::reserved_balance(&user), balance); - assert!(Balances::::free_balance(&user).is_zero()); + assert_eq!(Balances::::free_balance(&user), existential_deposit); }: _(RawOrigin::Root, user_lookup, balance) verify { assert!(Balances::::reserved_balance(&user).is_zero()); - assert_eq!(Balances::::free_balance(&user), balance); + assert_eq!(Balances::::free_balance(&user), balance + existential_deposit); } impl_benchmark_test_suite!( diff --git a/frame/balances/src/lib.rs b/frame/balances/src/lib.rs index d3085152eba6c..46e60777c5b24 100644 --- a/frame/balances/src/lib.rs +++ b/frame/balances/src/lib.rs @@ -1193,12 +1193,15 @@ impl, I: 'static> fungible::MutateHold for Pallet::InsufficientBalance); - Self::mutate_account(who, |a| { - a.free -= amount; - a.reserved += amount; - })?; - Ok(()) + ensure!( + >::can_hold(who, amount), + Error::::InsufficientBalance, + ); + Self::try_mutate_account(who, |a, _| -> DispatchResult { + a.free = a.free.checked_sub(&amount).ok_or(Error::::InsufficientBalance)?; + a.reserved = a.reserved.checked_add(&amount).ok_or(ArithmeticError::Overflow)?; + Ok(()) + }) } fn release( who: &T::AccountId, @@ -1755,16 +1758,23 @@ impl, I: 'static> ReservableCurrency for Pallet where T::Balance: MaybeSerializeDeserialize + Debug, { - /// Check if `who` can reserve `value` from their free balance. + /// Check if `who` can reserve `value` from their free balance taking into account the + /// `ExistentialDeposit` making sure the account is not going to be destroyed in case of + /// overdraft. /// /// Always `true` if value to be reserved is zero. fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool { if value.is_zero() { return true } - Self::account(who).free.checked_sub(&value).map_or(false, |new_balance| { - Self::ensure_can_withdraw(who, value, WithdrawReasons::RESERVE, new_balance).is_ok() - }) + + let account = Self::account(who); + let min_balance = T::ExistentialDeposit::get().max(account.frozen(Reasons::All)); + + Self::account(who) + .free + .checked_sub(&value) + .map_or(false, |new_balance| new_balance >= min_balance) } fn reserved_balance(who: &T::AccountId) -> Self::Balance { @@ -1784,7 +1794,9 @@ where account.free.checked_sub(&value).ok_or(Error::::InsufficientBalance)?; account.reserved = account.reserved.checked_add(&value).ok_or(ArithmeticError::Overflow)?; - Self::ensure_can_withdraw(&who, value, WithdrawReasons::RESERVE, account.free) + Self::can_reserve(who, value) + .then(|| Ok::<(), sp_runtime::DispatchError>(())) + .ok_or(Error::::InsufficientBalance)? })?; Self::deposit_event(Event::Reserved { who: who.clone(), amount: value }); diff --git a/frame/balances/src/tests.rs b/frame/balances/src/tests.rs index 83944caf9f7ff..f2fae41c6ffe5 100644 --- a/frame/balances/src/tests.rs +++ b/frame/balances/src/tests.rs @@ -28,6 +28,7 @@ macro_rules! decl_tests { use frame_support::{ assert_noop, assert_storage_noop, assert_ok, assert_err, traits::{ + fungible::{self, BalancedHold, Inspect, InspectHold, MutateHold}, LockableCurrency, LockIdentifier, WithdrawReasons, Currency, ReservableCurrency, ExistenceRequirement::AllowDeath } @@ -182,7 +183,7 @@ macro_rules! decl_tests { ); assert_noop!( >::reserve(&1, 1), - Error::<$test, _>::LiquidityRestrictions, + Error::<$test, _>::InsufficientBalance, ); assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(1), @@ -201,7 +202,9 @@ macro_rules! decl_tests { Balances::set_lock(ID_1, &1, 10, WithdrawReasons::TRANSACTION_PAYMENT); assert_ok!(>::transfer(&1, &2, 1, AllowDeath)); - assert_ok!(>::reserve(&1, 1)); + assert_noop!(>::reserve(&1, 1), + Error::<$test, _>::InsufficientBalance, + ); assert!( as SignedExtension>::pre_dispatch( ChargeTransactionPayment::from(1), &1, @@ -289,16 +292,17 @@ macro_rules! decl_tests { System::inc_account_nonce(&2); assert_eq!(Balances::total_balance(&2), 256 * 20); - assert_ok!(Balances::reserve(&2, 256 * 19 + 1)); // account 2 becomes mostly reserved + assert_ok!(Balances::reserve(&2, 256 * 19)); // account 2 becomes mostly reserved + assert_ok!(Balances::transfer(Some(2).into(), 12, 1)); // account 2 free balance below ED assert_eq!(Balances::free_balance(2), 255); // "free" account deleted." - assert_eq!(Balances::total_balance(&2), 256 * 20); // reserve still exists. + assert_eq!(Balances::total_balance(&2), 256 * 20-1); // reserve still exists. assert_eq!(System::account_nonce(&2), 1); // account 4 tries to take index 1 for account 5. assert_ok!(Balances::transfer(Some(4).into(), 5, 256 * 1 + 0x69)); assert_eq!(Balances::total_balance(&5), 256 * 1 + 0x69); - assert!(Balances::slash(&2, 256 * 19 + 2).1.is_zero()); // account 2 gets slashed + assert!(Balances::slash(&2, 256 * 19 + 1).1.is_zero()); // account 2 gets slashed // "reserve" account reduced to 255 (below ED) so account deleted assert_eq!(Balances::total_balance(&2), 0); assert_eq!(System::account_nonce(&2), 0); // nonce zero @@ -393,6 +397,23 @@ macro_rules! decl_tests { }); } + #[test] + fn holding_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 111); + + assert_eq!(Balances::balance(&1), 111); + assert_eq!(Balances::reducible_balance(&1, false), 111); + assert_eq!(Balances::balance_on_hold(&1), 0); + + assert_ok!(Balances::hold(&1, 69)); + + assert_eq!(Balances::balance(&1), 111); + assert_eq!(Balances::reducible_balance(&1, false), 42); + assert_eq!(Balances::balance_on_hold(&1), 69); + }); + } + #[test] fn balance_transfer_when_reserved_should_not_work() { <$ext_builder>::default().build().execute_with(|| { @@ -405,6 +426,18 @@ macro_rules! decl_tests { }); } + #[test] + fn balance_transfer_when_held_should_not_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 111); + assert_ok!(Balances::hold(&1, 69)); + assert_noop!( + >::transfer(&1, &2, 69, false), + Error::<$test, _>::InsufficientBalance, + ); + }); + } + #[test] fn deducting_balance_should_work() { <$ext_builder>::default().build().execute_with(|| { @@ -437,6 +470,18 @@ macro_rules! decl_tests { }); } + #[test] + fn slashing_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 111); + assert_ok!(Balances::hold(&1, 69)); + assert_eq!(>::slash(&1, 69), Ok(42)); + assert_eq!(Balances::reducible_balance(&1, false), 0); + assert_eq!(Balances::balance_on_hold(&1), 69); + assert_eq!(Balances::total_issuance(), 69); + }); + } + #[test] fn withdrawing_balance_should_work() { <$ext_builder>::default().build().execute_with(|| { @@ -462,14 +507,45 @@ macro_rules! decl_tests { }); } + #[test] + fn slashing_incomplete_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 42); + assert_ok!(Balances::hold(&1, 21)); + assert_eq!(>::slash(&1, 69), Ok(21)); + assert_eq!(Balances::reducible_balance(&1, false), 0); + assert_eq!(Balances::balance_on_hold(&1), 21); + assert_eq!(Balances::total_issuance(), 21); + }); + } + #[test] fn unreserving_balance_should_work() { <$ext_builder>::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 111); + let _ = Balances::deposit_creating(&1, 112); assert_ok!(Balances::reserve(&1, 111)); Balances::unreserve(&1, 42); assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 42); + assert_eq!(Balances::free_balance(1), 43); + }); + } + + #[test] + fn hold_should_respect_ed() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 111); + assert_err!(Balances::hold(&1, 111), Error::<$test, _>::InsufficientBalance); + }); + } + + #[test] + fn releasing_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 112); + assert_ok!(Balances::hold(&1, 111)); + assert_eq!(Balances::release(&1, 42, false), Ok(42)); + assert_eq!(Balances::balance_on_hold(&1), 69); + assert_eq!(Balances::reducible_balance(&1, false), 43); }); } @@ -477,14 +553,26 @@ macro_rules! decl_tests { fn slashing_reserved_balance_should_work() { <$ext_builder>::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 111)); + assert_ok!(Balances::reserve(&1, 110)); assert_eq!(Balances::slash_reserved(&1, 42).1, 0); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 68); + assert_eq!(Balances::free_balance(1), 1); assert_eq!(>::get(), 69); }); } + #[test] + fn slashing_held_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 111); + assert_ok!(Balances::hold(&1, 110)); + assert_eq!(Balances::slash_held(&1, 42).1, 0); + assert_eq!(Balances::balance_on_hold(&1), 68); + assert_eq!(Balances::reducible_balance(&1, false), 1); + assert_eq!(Balances::total_issuance(), 69); + }); + } + #[test] fn slashing_incomplete_reserved_balance_should_work() { <$ext_builder>::default().build().execute_with(|| { @@ -497,10 +585,22 @@ macro_rules! decl_tests { }); } + #[test] + fn slashing_incomplete_held_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 111); + assert_ok!(Balances::hold(&1, 42)); + assert_eq!(Balances::slash_held(&1, 69).1, 0); + assert_eq!(Balances::reducible_balance(&1, false), 69); + assert_eq!(Balances::balance_on_hold(&1), 0); + assert_eq!(Balances::total_issuance(), 69); + }); + } + #[test] fn repatriating_reserved_balance_should_work() { <$ext_builder>::default().build().execute_with(|| { - let _ = Balances::deposit_creating(&1, 110); + let _ = Balances::deposit_creating(&1, 111); let _ = Balances::deposit_creating(&2, 1); assert_ok!(Balances::reserve(&1, 110)); assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Free), 0); @@ -508,7 +608,7 @@ macro_rules! decl_tests { RuntimeEvent::Balances(crate::Event::ReserveRepatriated { from: 1, to: 2, amount: 41, destination_status: Status::Free }) ); assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::free_balance(1), 1); assert_eq!(Balances::reserved_balance(2), 0); assert_eq!(Balances::free_balance(2), 42); }); @@ -519,15 +619,29 @@ macro_rules! decl_tests { <$ext_builder>::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 110); let _ = Balances::deposit_creating(&2, 1); - assert_ok!(Balances::reserve(&1, 110)); + assert_ok!(Balances::reserve(&1, 109)); assert_ok!(Balances::repatriate_reserved(&1, &2, 41, Status::Reserved), 0); - assert_eq!(Balances::reserved_balance(1), 69); - assert_eq!(Balances::free_balance(1), 0); + assert_eq!(Balances::reserved_balance(1), 68); + assert_eq!(Balances::free_balance(1), 1); assert_eq!(Balances::reserved_balance(2), 41); assert_eq!(Balances::free_balance(2), 1); }); } + #[test] + fn transferring_held_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 110); + let _ = >::mint_into(&2, 1); + assert_ok!(Balances::hold(&1, 109)); + assert_ok!(Balances::transfer_held(&1, &2, 41, false, true), 41); + assert_eq!(Balances::balance_on_hold(&1), 68); + assert_eq!(Balances::reducible_balance(&1, false), 1); + assert_eq!(Balances::balance_on_hold(&2), 41); + assert_eq!(Balances::reducible_balance(&2, false), 1); + }); + } + #[test] fn transferring_reserved_balance_to_yourself_should_work() { <$ext_builder>::default().build().execute_with(|| { @@ -544,15 +658,40 @@ macro_rules! decl_tests { }); } + #[test] + fn transferring_held_fungible_to_yourself_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 110); + assert_ok!(Balances::hold(&1, 50)); + assert_ok!(Balances::transfer_held(&1, &1, 50, true, false), 50); + assert_eq!(Balances::reducible_balance(&1, false), 110); + assert_eq!(Balances::balance_on_hold(&1), 0); + + assert_ok!(Balances::hold(&1, 50)); + assert_ok!(Balances::transfer_held(&1, &1, 60, true, false), 50); + assert_eq!(Balances::reducible_balance(&1, false), 110); + assert_eq!(Balances::balance_on_hold(&1), 0); + }); + } + #[test] fn transferring_reserved_balance_to_nonexistent_should_fail() { <$ext_builder>::default().build().execute_with(|| { let _ = Balances::deposit_creating(&1, 111); - assert_ok!(Balances::reserve(&1, 111)); + assert_ok!(Balances::reserve(&1, 110)); assert_noop!(Balances::repatriate_reserved(&1, &2, 42, Status::Free), Error::<$test, _>::DeadAccount); }); } + #[test] + fn transferring_held_fungible_to_nonexistent_should_fail() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 111); + assert_ok!(Balances::hold(&1, 110)); + assert_noop!(Balances::transfer_held(&1, &2, 42, false, false), Error::<$test, _>::DeadAccount); + }); + } + #[test] fn transferring_incomplete_reserved_balance_should_work() { <$ext_builder>::default().build().execute_with(|| { @@ -567,6 +706,20 @@ macro_rules! decl_tests { }); } + #[test] + fn transferring_incomplete_held_fungible_should_work() { + <$ext_builder>::default().build().execute_with(|| { + let _ = >::mint_into(&1, 110); + let _ = >::mint_into(&2, 1); + assert_ok!(Balances::hold(&1, 41)); + assert_ok!(Balances::transfer_held(&1, &2, 69, true, false), 41); + assert_eq!(Balances::balance_on_hold(&1), 0); + assert_eq!(Balances::reducible_balance(&1, false), 69); + assert_eq!(Balances::balance_on_hold(&2), 0); + assert_eq!(Balances::reducible_balance(&2, false), 42); + }); + } + #[test] fn transferring_too_high_value_should_not_panic() { <$ext_builder>::default().build().execute_with(|| { @@ -677,34 +830,19 @@ macro_rules! decl_tests { } #[test] - fn dust_moves_between_free_and_reserved() { + fn reserve_should_respect_ed() { <$ext_builder>::default() - .existential_deposit(100) .build() .execute_with(|| { - // Set balance to free and reserved at the existential deposit + // Set balance to ED assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 100, 0)); // Check balance assert_eq!(Balances::free_balance(1), 100); - assert_eq!(Balances::reserved_balance(1), 0); - - // Reserve some free balance - assert_ok!(Balances::reserve(&1, 50)); - // Check balance, the account should be ok. - assert_eq!(Balances::free_balance(1), 50); - assert_eq!(Balances::reserved_balance(1), 50); - - // Reserve the rest of the free balance - assert_ok!(Balances::reserve(&1, 50)); - // Check balance, the account should be ok. - assert_eq!(Balances::free_balance(1), 0); - assert_eq!(Balances::reserved_balance(1), 100); - - // Unreserve everything - Balances::unreserve(&1, 100); - // Check balance, all 100 should move to free_balance - assert_eq!(Balances::free_balance(1), 100); - assert_eq!(Balances::reserved_balance(1), 0); + // Reserve over ED + assert_noop!( + Balances::reserve(&1, 100), + Error::<$test, _>::InsufficientBalance + ); }); } diff --git a/frame/balances/src/tests_reentrancy.rs b/frame/balances/src/tests_reentrancy.rs index 90363140000e8..a18d64d6c27a1 100644 --- a/frame/balances/src/tests_reentrancy.rs +++ b/frame/balances/src/tests_reentrancy.rs @@ -29,10 +29,7 @@ use sp_io; use sp_runtime::{testing::Header, traits::IdentityLookup}; use crate::*; -use frame_support::{ - assert_ok, - traits::{Currency, ReservableCurrency}, -}; +use frame_support::{assert_ok, traits::Currency}; use frame_system::RawOrigin; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; @@ -212,53 +209,3 @@ fn transfer_dust_removal_tst2_should_work() { })); }); } - -#[test] -fn repatriating_reserved_balance_dust_removal_should_work() { - ExtBuilder::default().existential_deposit(100).build().execute_with(|| { - // Verification of reentrancy in dust removal - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 1, 1000, 0)); - assert_ok!(Balances::set_balance(RawOrigin::Root.into(), 2, 500, 0)); - - // Reserve a value on account 2, - // Such that free balance is lower than - // Exestintial deposit. - assert_ok!(Balances::reserve(&2, 450)); - - // Transfer of reserved fund from slashed account 2 to - // beneficiary account 1 - assert_ok!(Balances::repatriate_reserved(&2, &1, 450, Status::Free), 0); - - // Since free balance of account 2 is lower than - // existential deposit, dust amount is - // removed from the account 2 - assert_eq!(Balances::reserved_balance(2), 0); - assert_eq!(Balances::free_balance(2), 0); - - // account 1 is credited with reserved amount - // together with dust balance during dust - // removal. - assert_eq!(Balances::reserved_balance(1), 0); - assert_eq!(Balances::free_balance(1), 1500); - - // Verify the events - assert_eq!(System::events().len(), 11); - - System::assert_has_event(RuntimeEvent::Balances(crate::Event::ReserveRepatriated { - from: 2, - to: 1, - amount: 450, - destination_status: Status::Free, - })); - - System::assert_has_event(RuntimeEvent::Balances(crate::Event::DustLost { - account: 2, - amount: 50, - })); - - System::assert_last_event(RuntimeEvent::Balances(crate::Event::Deposit { - who: 1, - amount: 50, - })); - }); -} diff --git a/frame/bounties/src/benchmarking.rs b/frame/bounties/src/benchmarking.rs index 07dd781c29af3..7d31c9c3a474a 100644 --- a/frame/bounties/src/benchmarking.rs +++ b/frame/bounties/src/benchmarking.rs @@ -54,9 +54,9 @@ fn setup_bounty, I: 'static>( let fee = value / 2u32.into(); let deposit = T::BountyDepositBase::get() + T::DataDepositPerByte::get() * T::MaximumReasonLength::get().into(); - let _ = T::Currency::make_free_balance_be(&caller, deposit); + let _ = T::Currency::make_free_balance_be(&caller, deposit + 1u32.into()); let curator = account("curator", u, SEED); - let _ = T::Currency::make_free_balance_be(&curator, fee / 2u32.into()); + let _ = T::Currency::make_free_balance_be(&curator, fee / 2u32.into() + 1u32.into()); let reason = vec![0; d as usize]; (caller, curator, fee, value, reason) }