Skip to content

Commit 041006c

Browse files
authored
fix fungibles::Inspect::balance (#926)
* fix fungibles::Inspect::balance * update
1 parent 56d66f6 commit 041006c

File tree

3 files changed

+72
-16
lines changed

3 files changed

+72
-16
lines changed

tokens/src/lib.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -1768,7 +1768,7 @@ impl<T: Config> fungibles::Inspect<T::AccountId> for Pallet<T> {
17681768
}
17691769

17701770
fn balance(asset_id: Self::AssetId, who: &T::AccountId) -> Self::Balance {
1771-
Self::accounts(who, asset_id).total()
1771+
Self::accounts(who, asset_id).free
17721772
}
17731773

17741774
fn total_balance(asset_id: Self::AssetId, who: &T::AccountId) -> Self::Balance {
@@ -1869,11 +1869,21 @@ impl<T: Config> fungibles::Unbalanced<T::AccountId> for Pallet<T> {
18691869
who: &T::AccountId,
18701870
amount: Self::Balance,
18711871
) -> Result<Option<Self::Balance>, DispatchError> {
1872+
let max_reduction = <Self as fungibles::Inspect<_>>::reducible_balance(
1873+
asset_id,
1874+
who,
1875+
Preservation::Expendable,
1876+
Fortitude::Force,
1877+
);
1878+
18721879
// Balance is the same type and will not overflow
18731880
let (_, dust_amount) = Self::try_mutate_account(who, asset_id, |account, _| -> Result<(), DispatchError> {
1874-
// free = new_balance - reserved
1875-
account.free = amount.checked_sub(&account.reserved).ok_or(TokenError::BelowMinimum)?;
1881+
// Make sure the reduction (if there is one) is no more than the maximum
1882+
// allowed.
1883+
let reduction = account.free.saturating_sub(amount);
1884+
ensure!(reduction <= max_reduction, Error::<T>::BalanceTooLow);
18761885

1886+
account.free = amount;
18771887
Self::deposit_event(Event::BalanceSet {
18781888
currency_id: asset_id,
18791889
who: who.clone(),
@@ -1911,9 +1921,10 @@ impl<T: Config> fungibles::Unbalanced<T::AccountId> for Pallet<T> {
19111921
amount = amount.min(free);
19121922
}
19131923
let new_balance = old_balance.checked_sub(&amount).ok_or(TokenError::FundsUnavailable)?;
1914-
// Original implementation was not returning burnt dust in result
1915-
let dust_burnt = Self::write_balance(asset, who, new_balance)?.unwrap_or_default();
1916-
Ok(old_balance.saturating_sub(new_balance).saturating_add(dust_burnt))
1924+
let _dust_amount = Self::write_balance(asset, who, new_balance)?.unwrap_or_default();
1925+
1926+
// here just return decrease amount, shouldn't count the dust_amount
1927+
Ok(old_balance.saturating_sub(new_balance))
19171928
}
19181929
}
19191930

tokens/src/tests_events.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ fn pallet_fungibles_unbalanced_deposit_events() {
220220
System::assert_last_event(RuntimeEvent::Tokens(crate::Event::BalanceSet {
221221
currency_id: DOT,
222222
who: ALICE,
223-
free: 450,
223+
free: 500,
224224
reserved: 50,
225225
}));
226226

tokens/src/tests_fungibles.rs

+54-9
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,24 @@ fn fungibles_unbalanced_trait_should_work() {
119119
Preservation::Expendable,
120120
Fortitude::Polite
121121
),
122-
Ok(5)
122+
Ok(4)
123123
);
124124
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
125+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 0);
125126
// set reserved
126127
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::write_balance(DOT, &ALICE, 100));
127128
assert_ok!(<Tokens as MultiReservableCurrency<AccountId>>::reserve(DOT, &ALICE, 50));
129+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
130+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 100);
131+
assert_eq!(
132+
<Tokens as fungibles::Inspect<_>>::reducible_balance(
133+
DOT,
134+
&ALICE,
135+
Preservation::Protect,
136+
Fortitude::Polite
137+
),
138+
50
139+
);
128140
assert_noop!(
129141
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(
130142
DOT,
@@ -134,7 +146,7 @@ fn fungibles_unbalanced_trait_should_work() {
134146
Preservation::Protect,
135147
Fortitude::Polite
136148
),
137-
TokenError::BelowMinimum
149+
TokenError::FundsUnavailable
138150
);
139151
assert_eq!(
140152
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(
@@ -147,16 +159,19 @@ fn fungibles_unbalanced_trait_should_work() {
147159
),
148160
Ok(50)
149161
);
150-
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
162+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
163+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 50);
151164
assert_eq!(
152165
<Tokens as MultiReservableCurrency<AccountId>>::unreserve(DOT, &ALICE, 50),
153166
0
154167
);
155168
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
169+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 50);
156170

157171
// decrease_balance_at_most
158172
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::write_balance(DOT, &ALICE, 10));
159173
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 10);
174+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 10);
160175
assert_eq!(
161176
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(
162177
DOT,
@@ -168,6 +183,8 @@ fn fungibles_unbalanced_trait_should_work() {
168183
),
169184
Ok(10)
170185
);
186+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
187+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 0);
171188
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::write_balance(DOT, &ALICE, 10));
172189
assert_eq!(
173190
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(
@@ -181,6 +198,8 @@ fn fungibles_unbalanced_trait_should_work() {
181198
Ok(5)
182199
);
183200
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 5);
201+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 5);
202+
184203
// new balance < ExistentialDeposits, clean dust
185204
assert_eq!(
186205
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(
@@ -191,12 +210,24 @@ fn fungibles_unbalanced_trait_should_work() {
191210
Preservation::Expendable,
192211
Fortitude::Polite
193212
),
194-
Ok(5)
213+
Ok(4)
195214
);
196215
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
216+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 0);
197217
// set reserved
198218
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::write_balance(DOT, &ALICE, 100));
199219
assert_ok!(<Tokens as MultiReservableCurrency<AccountId>>::reserve(DOT, &ALICE, 50));
220+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
221+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 100);
222+
assert_eq!(
223+
<Tokens as fungibles::Inspect<_>>::reducible_balance(
224+
DOT,
225+
&ALICE,
226+
Preservation::Protect,
227+
Fortitude::Polite
228+
),
229+
50
230+
);
200231
assert_eq!(
201232
<Tokens as fungibles::Unbalanced<_>>::decrease_balance(
202233
DOT,
@@ -208,12 +239,14 @@ fn fungibles_unbalanced_trait_should_work() {
208239
),
209240
Ok(50),
210241
);
211-
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
242+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
243+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 50);
212244
assert_eq!(
213245
<Tokens as MultiReservableCurrency<AccountId>>::unreserve(DOT, &ALICE, 50),
214246
0
215247
);
216248
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 50);
249+
assert_eq!(<Tokens as fungibles::Inspect<_>>::total_balance(DOT, &ALICE), 50);
217250

218251
// increase_balance
219252
assert_ok!(<Tokens as fungibles::Unbalanced<_>>::write_balance(DOT, &ALICE, 0));
@@ -285,11 +318,15 @@ fn fungibles_mutate_hold_trait_should_work() {
285318
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
286319
0
287320
);
321+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 100);
322+
288323
assert_ok!(<Tokens as fungibles::MutateHold<_>>::hold(DOT, REASON, &ALICE, 100));
289324
assert_eq!(
290325
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
291326
100
292327
);
328+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 0);
329+
293330
assert_eq!(
294331
<Tokens as fungibles::MutateHold<_>>::release(DOT, REASON, &ALICE, 40, Precision::Exact),
295332
Ok(40)
@@ -298,6 +335,7 @@ fn fungibles_mutate_hold_trait_should_work() {
298335
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
299336
60
300337
);
338+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 40);
301339

302340
// exceed hold amount when not in best_effort
303341
assert_noop!(
@@ -314,17 +352,20 @@ fn fungibles_mutate_hold_trait_should_work() {
314352
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
315353
0
316354
);
355+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 100);
317356

318357
assert_ok!(<Tokens as fungibles::MutateHold<_>>::hold(DOT, REASON, &ALICE, 70));
319358
assert_eq!(
320359
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
321360
70
322361
);
323-
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 100);
362+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 30);
363+
324364
assert_eq!(
325365
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &BOB),
326366
0
327367
);
368+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 100);
328369
assert_eq!(
329370
<Tokens as fungibles::MutateHold<_>>::transfer_on_hold(
330371
DOT,
@@ -342,11 +383,13 @@ fn fungibles_mutate_hold_trait_should_work() {
342383
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
343384
65
344385
);
345-
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 105);
386+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 30);
346387
assert_eq!(
347388
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &BOB),
348389
0
349390
);
391+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 105);
392+
350393
assert_eq!(
351394
<Tokens as fungibles::MutateHold<_>>::transfer_on_hold(
352395
DOT,
@@ -364,11 +407,12 @@ fn fungibles_mutate_hold_trait_should_work() {
364407
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
365408
60
366409
);
367-
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 110);
410+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 30);
368411
assert_eq!(
369412
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &BOB),
370413
5
371414
);
415+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 105);
372416

373417
// exceed hold amount when not in best_effort
374418
assert_noop!(
@@ -403,11 +447,12 @@ fn fungibles_mutate_hold_trait_should_work() {
403447
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &ALICE),
404448
0
405449
);
406-
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 170);
450+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &ALICE), 30);
407451
assert_eq!(
408452
<Tokens as fungibles::InspectHold<_>>::balance_on_hold(DOT, REASON, &BOB),
409453
65
410454
);
455+
assert_eq!(<Tokens as fungibles::Inspect<_>>::balance(DOT, &BOB), 105);
411456
});
412457
}
413458

0 commit comments

Comments
 (0)