What would be the recommended approach to introduce inflation for block production/collator reward?

Is NegativeImbalance a good place for this, or implementing a separate pallet that schedules increments per block to a given destination account balance (e.g. treasury) is a better approach?

pub struct DealWithFees;
impl OnUnbalanced<NegativeImbalance> for DealWithFees {
    fn on_unbalanceds<B>(mut fees_then_tips: impl Iterator<Item = NegativeImbalance>) {
        if let Some(fees) = fees_then_tips.next() {
            let mut split = fees.ration(80, 20);
            if let Some(tips) = fees_then_tips.next() {
                // for tips, if any, 80% to treasury, 20% to block author (though this can be anything)
                tips.ration_merge_into(80, 20, &mut split);

1 Answer 1


Doing any kind of inflation on a Substrate chain can be broken up cleanly into two parts:

  1. Minting some new tokens (creating a negative imbalance)
  2. Assigning those new tokens to some source (handling the imbalance)

So, when you call a very generic function like issue:

// Create new funds into the total issuance, returning a negative imbalance
// for the amount issued.
// Is a no-op if amount to be issued it zero.
fn issue(mut amount: Self::Balance) -> Self::NegativeImbalance { ... }

You can arbitrarily create more of your token, then as shown in your post, some on_unbalanced handler can use that value to then increase some user's balance:

pub struct Author;
impl OnUnbalanced<NegativeImbalance> for Author {
    fn on_nonzero_unbalanced(amount: NegativeImbalance) {
        if let Some(author) = Authorship::author() {
            Balances::resolve_creating(&author, amount);

You can also simplify this process by wrapping both steps into a single call with a function like deposit_creating:

/// Deposit some `value` into the free balance of `who`, possibly creating a new account.
/// This function is a no-op if:
/// - the `value` to be deposited is zero; or
/// - the `value` to be deposited is less than the required ED and the account does not yet
///   exist; or
/// - the deposit would necessitate the account to exist and there are no provider references;
///   or
/// - `value` is so large it would cause the balance of `who` to overflow.
fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance { ... }

End of the day, there are a million ways to do this kind of thing. Just increasing the value of some number. How exactly you implement it depends on how modular or customizable you want things to be.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.