Crate pallet_treasury

source ·
Expand description

Made with Substrate, for Polkadot.

github - polkadot

§Treasury Pallet

The Treasury pallet provides a “pot” of funds that can be managed by stakeholders in the system and a structure for making spending proposals from this pot.

§Overview

The Treasury Pallet itself provides the pot to store funds, and a means for stakeholders to propose and claim expenditures (aka spends). The chain will need to provide a method to approve spends (e.g. public referendum) and a method for collecting funds (e.g. inflation, fees).

By way of example, stakeholders could vote to fund the Treasury with a portion of the block reward and use the funds to pay developers.

§Terminology

  • Proposal: A suggestion to allocate funds from the pot to a beneficiary.
  • Beneficiary: An account who will receive the funds from a proposal iff the proposal is approved.
  • Pot: Unspent funds accumulated by the treasury pallet.
  • Spend An approved proposal for transferring a specific amount of funds to a designated beneficiary.

§Example

  1. Multiple local spends approved by spend origins and received by a beneficiary.
#[test]
fn spend_local_origin_works() {
    ExtBuilder::default().build().execute_with(|| {
        // Check that accumulate works when we have Some value in Dummy already.
        Balances::make_free_balance_be(&Treasury::account_id(), 101);
        // approve spend of some amount to beneficiary `6`.
        assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(10), 5, 6));
        assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(10), 5, 6));
        assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(10), 5, 6));
        assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(10), 5, 6));
        assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(11), 10, 6));
        assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(12), 20, 6));
        assert_ok!(Treasury::spend_local(RuntimeOrigin::signed(13), 50, 6));
        // free balance of `6` is zero, spend period has not passed.
        <Treasury as OnInitialize<u64>>::on_initialize(1);
        assert_eq!(Balances::free_balance(6), 0);
        // free balance of `6` is `100`, spend period has passed.
        <Treasury as OnInitialize<u64>>::on_initialize(2);
        assert_eq!(Balances::free_balance(6), 100);
        // `100` spent, `1` burned.
        assert_eq!(Treasury::pot(), 0);
    });
}
  1. Approve a spend of some asset kind and claim it.
#[test]
fn spend_payout_works() {
    ExtBuilder::default().build().execute_with(|| {
        System::set_block_number(1);
        // approve a `2` coins spend of asset `1` to beneficiary `6`, the spend valid from now.
        assert_ok!(Treasury::spend(
            RuntimeOrigin::signed(10),
            Box::new(1),
            2,
            Box::new(6),
            None
        ));
        // payout the spend.
        assert_ok!(Treasury::payout(RuntimeOrigin::signed(1), 0));
        // beneficiary received `2` coins of asset `1`.
        assert_eq!(paid(6, 1), 2);
        assert_eq!(SpendCount::<Test, _>::get(), 1);
        let payment_id = get_payment_id(0).expect("no payment attempt");
        System::assert_last_event(
            Event::<Test, _>::Paid {
                index: 0,
                payment_id,
            }
            .into(),
        );
        set_status(payment_id, PaymentStatus::Success);
        // the payment succeed.
        assert_ok!(Treasury::check_status(RuntimeOrigin::signed(1), 0));
        System::assert_last_event(Event::<Test, _>::SpendProcessed { index: 0 }.into());
        // cannot payout the same spend twice.
        assert_noop!(
            Treasury::payout(RuntimeOrigin::signed(1), 0),
            Error::<Test, _>::InvalidIndex
        );
    });
}

§Pallet API

See the pallet module for more information about the interfaces this pallet exposes, including its configuration trait, dispatchables, storage items, events and errors.

§Low Level / Implementation Details

Spends can be initiated using either the spend_local or spend dispatchable. The spend_local dispatchable enables the creation of spends using the native currency of the chain, utilizing the funds stored in the pot. These spends are automatically paid out every pallet::Config::SpendPeriod. On the other hand, the spend dispatchable allows spending of any asset kind managed by the treasury, with payment facilitated by a designated pallet::Config::Paymaster. To claim these spends, the payout dispatchable should be called within some temporal bounds, starting from the moment they become valid and within one pallet::Config::PayoutPeriod.

Re-exports§

Modules§

  • The pallet module in each FRAME pallet hosts the most important items needed to construct this pallet.
  • Autogenerated weights for pallet_treasury

Structs§

Enums§

Traits§

  • A trait to allow the Treasury Pallet to spend it’s funds for other purposes. There is an expectation that the implementer of this trait will correctly manage the mutable variables passed to it:

Type Aliases§