Skip to content

Commit

Permalink
feat: add solution for ex07
Browse files Browse the repository at this point in the history
  • Loading branch information
tdelabro committed Dec 27, 2022
1 parent 06323ff commit 29a4e35
Showing 1 changed file with 36 additions and 17 deletions.
53 changes: 36 additions & 17 deletions exercises/ex07-imbalances/imbalances/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,9 @@ pub mod pallet {
) -> DispatchResult {
ensure_root(origin)?;

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

Ok(())
}
Expand All @@ -81,10 +77,16 @@ pub mod pallet {
) -> DispatchResult {
ensure_root(origin)?;

// Todo: slash target
// Todo: give 1/3 of the slashed amount to the treasury and burn the rest
// Hint: use the `ration` method
// Hint: TreasuryAccount is defined as on l35 as a Config constant
let (negative_imbalance, _) = T::Currency::slash(&target, amount);
let (to_treasury, to_burn) = negative_imbalance.ration(1, 2);

T::Currency::resolve_creating(&T::TreasuryAccount::get(), to_treasury);
let amount_to_burn = to_burn.peek();
let burned = T::Currency::burn(amount_to_burn);
burned
.offset(to_burn)
.try_drop()
.map_err(|_| Error::<T>::ImbalanceOffsetFailed)?;

Ok(())
}
Expand All @@ -97,13 +99,30 @@ pub mod pallet {
beneficiary: T::AccountId,
) -> DispatchResult {
ensure_root(origin)?;

// Todo:
// Take as much as possible from each account in `sacked_accounts`,
// without removing them from existence
// and give it all to beneficiary
// except for the TreasuryFlatCut amount, that goes to the treasury for each sacked
// account Hint: there is a `split` method implemented on imbalances
let n_accounts = sacked_accounts.len();

let amount_collected = sacked_accounts.into_iter().try_fold(
NegativeBalanceOf::<T>::zero(),
|acc, account| {
let free_balance = T::Currency::free_balance(&account);
T::Currency::withdraw(
&account,
free_balance - T::Currency::minimum_balance(),
WithdrawReasons::TRANSFER,
ExistenceRequirement::KeepAlive,
)
.map(|v| acc.merge(v))
},
)?;

let amount_to_treasury = T::TreasuryFlatCut::get()
.checked_mul(&n_accounts.checked_into().ok_or(Error::<T>::Overflow)?)
.ok_or(Error::<T>::Overflow)?;

let (to_treasury, to_recipient) = amount_collected.split(amount_to_treasury);
T::Currency::resolve_creating(&T::TreasuryAccount::get(), to_treasury);
T::Currency::resolve_into_existing(&beneficiary, to_recipient)
.map_err(|_| Error::<T>::AccountDoesNotExist)?;

Ok(())
}
Expand Down

0 comments on commit 29a4e35

Please sign in to comment.