Skip to content

Commit 29a4e35

Browse files
committed
feat: add solution for ex07
1 parent 06323ff commit 29a4e35

File tree

1 file changed

+36
-17
lines changed
  • exercises/ex07-imbalances/imbalances/src

1 file changed

+36
-17
lines changed

exercises/ex07-imbalances/imbalances/src/lib.rs

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,9 @@ pub mod pallet {
6262
) -> DispatchResult {
6363
ensure_root(origin)?;
6464

65-
// Here we add some tokens to the chain total_issuance
66-
// If we do nothing more, those tokens will be removed when the `NegativeImbalance`
67-
// contained in the `amount_to_distribute` variable will be drop
6865
let amount_to_distribute = T::Currency::issue(amount);
69-
// TODO
70-
// We want to compensate this imbalance by increasing `benefeciary` balance by the
71-
// corresponding amount
66+
T::Currency::resolve_into_existing(&beneficiary, amount_to_distribute)
67+
.map_err(|_| Error::<T>::AccountDoesNotExist)?;
7268

7369
Ok(())
7470
}
@@ -81,10 +77,16 @@ pub mod pallet {
8177
) -> DispatchResult {
8278
ensure_root(origin)?;
8379

84-
// Todo: slash target
85-
// Todo: give 1/3 of the slashed amount to the treasury and burn the rest
86-
// Hint: use the `ration` method
87-
// Hint: TreasuryAccount is defined as on l35 as a Config constant
80+
let (negative_imbalance, _) = T::Currency::slash(&target, amount);
81+
let (to_treasury, to_burn) = negative_imbalance.ration(1, 2);
82+
83+
T::Currency::resolve_creating(&T::TreasuryAccount::get(), to_treasury);
84+
let amount_to_burn = to_burn.peek();
85+
let burned = T::Currency::burn(amount_to_burn);
86+
burned
87+
.offset(to_burn)
88+
.try_drop()
89+
.map_err(|_| Error::<T>::ImbalanceOffsetFailed)?;
8890

8991
Ok(())
9092
}
@@ -97,13 +99,30 @@ pub mod pallet {
9799
beneficiary: T::AccountId,
98100
) -> DispatchResult {
99101
ensure_root(origin)?;
100-
101-
// Todo:
102-
// Take as much as possible from each account in `sacked_accounts`,
103-
// without removing them from existence
104-
// and give it all to beneficiary
105-
// except for the TreasuryFlatCut amount, that goes to the treasury for each sacked
106-
// account Hint: there is a `split` method implemented on imbalances
102+
let n_accounts = sacked_accounts.len();
103+
104+
let amount_collected = sacked_accounts.into_iter().try_fold(
105+
NegativeBalanceOf::<T>::zero(),
106+
|acc, account| {
107+
let free_balance = T::Currency::free_balance(&account);
108+
T::Currency::withdraw(
109+
&account,
110+
free_balance - T::Currency::minimum_balance(),
111+
WithdrawReasons::TRANSFER,
112+
ExistenceRequirement::KeepAlive,
113+
)
114+
.map(|v| acc.merge(v))
115+
},
116+
)?;
117+
118+
let amount_to_treasury = T::TreasuryFlatCut::get()
119+
.checked_mul(&n_accounts.checked_into().ok_or(Error::<T>::Overflow)?)
120+
.ok_or(Error::<T>::Overflow)?;
121+
122+
let (to_treasury, to_recipient) = amount_collected.split(amount_to_treasury);
123+
T::Currency::resolve_creating(&T::TreasuryAccount::get(), to_treasury);
124+
T::Currency::resolve_into_existing(&beneficiary, to_recipient)
125+
.map_err(|_| Error::<T>::AccountDoesNotExist)?;
107126

108127
Ok(())
109128
}

0 commit comments

Comments
 (0)