Skip to content

Commit

Permalink
Fix fungibles unbalanced (#823)
Browse files Browse the repository at this point in the history
* Add fungibles::Unbalanced tests

* fix set_balance
  • Loading branch information
zjb0807 authored and xlc committed Nov 7, 2022
1 parent 377213f commit 8ea467b
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 6 deletions.
15 changes: 10 additions & 5 deletions tokens/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1730,17 +1730,22 @@ impl<T: Config> fungibles::Transfer<T::AccountId> for Pallet<T> {
impl<T: Config> fungibles::Unbalanced<T::AccountId> for Pallet<T> {
fn set_balance(asset_id: Self::AssetId, who: &T::AccountId, amount: Self::Balance) -> DispatchResult {
// Balance is the same type and will not overflow
Self::mutate_account(who, asset_id, |account, _| {
account.free = amount;
Self::mutate_account(who, asset_id, |account, _| -> DispatchResult {
// fungibles::Unbalanced::decrease_balance didn't check account.reserved
// free = new_balance - reserved
account.free = amount
.checked_sub(&account.reserved)
.ok_or(ArithmeticError::Underflow)?;

Self::deposit_event(Event::BalanceSet {
currency_id: asset_id,
who: who.clone(),
free: amount,
free: account.free,
reserved: account.reserved,
});
});
Ok(())

Ok(())
})
}

fn set_total_issuance(asset_id: Self::AssetId, amount: Self::Balance) {
Expand Down
2 changes: 1 addition & 1 deletion tokens/src/tests_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ fn pallet_fungibles_unbalanced_deposit_events() {
System::assert_last_event(Event::Tokens(crate::Event::BalanceSet {
currency_id: DOT,
who: ALICE,
free: 500,
free: 450,
reserved: 50,
}));

Expand Down
107 changes: 107 additions & 0 deletions tokens/src/tests_fungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use super::*;
use frame_support::{assert_noop, assert_ok};
use mock::*;
use sp_runtime::{ArithmeticError, TokenError};

#[test]
fn fungibles_inspect_trait_should_work() {
Expand Down Expand Up @@ -54,13 +55,119 @@ fn fungibles_unbalanced_trait_should_work() {
.balances(vec![(ALICE, DOT, 100)])
.build()
.execute_with(|| {
// set_balance
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 100);
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::set_balance(DOT, &ALICE, 10));
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 10);

// set_total_issuance
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_issuance(DOT), 100);
<Tokens as fungibles::Unbalanced<_>>::set_total_issuance(DOT, 10);
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_issuance(DOT), 10);

// decrease_balance
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 10);
assert_noop!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(DOT, &ALICE, 20),
TokenError::NoFunds
);
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(DOT, &ALICE, 5),
Ok(5)
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 5);
// new balance < ExistentialDeposits, clean dust
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(DOT, &ALICE, 4),
Ok(5)
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
// set reserved
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::set_balance(DOT, &ALICE, 100));
assert_ok!(<Tokens as MultiReservableCurrency<AccountId>>::reserve(DOT, &ALICE, 50));
assert_noop!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(DOT, &ALICE, 60),
ArithmeticError::Underflow
);
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(DOT, &ALICE, 50),
Ok(50)
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
assert_eq!(
<Tokens as MultiReservableCurrency<AccountId>>::unreserve(DOT, &ALICE, 50),
0
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);

// decrease_balance_at_most
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::set_balance(DOT, &ALICE, 10));
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 10);
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance_at_most(DOT, &ALICE, 20),
10
);
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::set_balance(DOT, &ALICE, 10));
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance_at_most(DOT, &ALICE, 5),
5
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 5);
// new balance < ExistentialDeposits, clean dust
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance_at_most(DOT, &ALICE, 4),
5
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
// set reserved
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::set_balance(DOT, &ALICE, 100));
assert_ok!(<Tokens as MultiReservableCurrency<AccountId>>::reserve(DOT, &ALICE, 50));
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance_at_most(DOT, &ALICE, 60),
0
);
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::decrease_balance_at_most(DOT, &ALICE, 50),
50
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
assert_eq!(
<Tokens as MultiReservableCurrency<AccountId>>::unreserve(DOT, &ALICE, 50),
0
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);

// increase_balance
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::set_balance(DOT, &ALICE, 0));
assert_noop!(
<Tokens as fungibles::Unbalanced<_>>::increase_balance(DOT, &ALICE, 1),
TokenError::BelowMinimum
);
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::increase_balance(DOT, &ALICE, 2),
Ok(2)
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 2);
assert_noop!(
<Tokens as fungibles::Unbalanced<_>>::increase_balance(DOT, &ALICE, Balance::MAX),
ArithmeticError::Overflow
);

// increase_balance_at_most
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::set_balance(DOT, &ALICE, 0));
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::increase_balance_at_most(DOT, &ALICE, 1),
0
);
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::increase_balance_at_most(DOT, &ALICE, 2),
2
);
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 2);
assert_eq!(
<Tokens as fungibles::Unbalanced<_>>::increase_balance_at_most(DOT, &ALICE, Balance::MAX),
Balance::MAX - 2
);
});
}

Expand Down

0 comments on commit 8ea467b

Please sign in to comment.