Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ members = [
"substrate/frame/contracts/uapi",
"substrate/frame/conviction-voting",
"substrate/frame/core-fellowship",
"substrate/frame/dap",
"substrate/frame/delegated-staking",
"substrate/frame/democracy",
"substrate/frame/derivatives",
Expand Down Expand Up @@ -984,6 +985,7 @@ pallet-contracts-proc-macro = { path = "substrate/frame/contracts/proc-macro", d
pallet-contracts-uapi = { path = "substrate/frame/contracts/uapi", default-features = false }
pallet-conviction-voting = { path = "substrate/frame/conviction-voting", default-features = false }
pallet-core-fellowship = { path = "substrate/frame/core-fellowship", default-features = false }
pallet-dap = { path = "substrate/frame/dap", default-features = false }
pallet-default-config-example = { path = "substrate/frame/examples/default-config", default-features = false }
pallet-delegated-staking = { path = "substrate/frame/delegated-staking", default-features = false }
pallet-democracy = { path = "substrate/frame/democracy", default-features = false }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ cumulus-primitives-aura = { workspace = true }
cumulus-primitives-core = { workspace = true }
cumulus-primitives-utility = { workspace = true }
pallet-collator-selection = { workspace = true }
pallet-dap = { workspace = true }
pallet-message-queue = { workspace = true }
parachain-info = { workspace = true }
parachains-common = { workspace = true }
Expand Down Expand Up @@ -173,6 +174,7 @@ runtime-benchmarks = [
"pallet-balances/runtime-benchmarks",
"pallet-collator-selection/runtime-benchmarks",
"pallet-conviction-voting/runtime-benchmarks",
"pallet-dap/runtime-benchmarks",
"pallet-delegated-staking/runtime-benchmarks",
"pallet-election-provider-multi-block/runtime-benchmarks",
"pallet-fast-unstake/runtime-benchmarks",
Expand Down Expand Up @@ -246,6 +248,7 @@ try-runtime = [
"pallet-balances/try-runtime",
"pallet-collator-selection/try-runtime",
"pallet-conviction-voting/try-runtime",
"pallet-dap/try-runtime",
"pallet-delegated-staking/try-runtime",
"pallet-election-provider-multi-block/try-runtime",
"pallet-fast-unstake/try-runtime",
Expand Down Expand Up @@ -326,6 +329,7 @@ std = [
"pallet-balances/std",
"pallet-collator-selection/std",
"pallet-conviction-voting/std",
"pallet-dap/std",
"pallet-delegated-staking/std",
"pallet-election-provider-multi-block/std",
"pallet-fast-unstake/std",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl pallet_referenda::Config for Runtime {

parameter_types! {
pub const SpendPeriod: BlockNumber = 6 * DAYS;
pub const Burn: Permill = Permill::from_perthousand(2);
pub const Burn: Permill = Permill::zero();
pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS;

Expand All @@ -131,7 +131,7 @@ impl pallet_treasury::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type SpendPeriod = SpendPeriod;
type Burn = Burn;
type BurnDestination = ();
type BurnDestination = pallet_dap::BurnToDap<Runtime, Balances>;
type MaxApprovals = MaxApprovals;
type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
type SpendFunds = ();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1398,6 +1398,9 @@ construct_runtime!(
Treasury: pallet_treasury = 94,
AssetRate: pallet_asset_rate = 95,

// Dynamic Allocation Pool / Issuance Buffer
Dap: pallet_dap = 100,

// TODO: the pallet instance should be removed once all pools have migrated
// to the new account IDs.
AssetConversionMigration: pallet_asset_conversion_ops = 200,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ impl pallet_staking_async::Config for Runtime {
type RuntimeHoldReason = RuntimeHoldReason;
type CurrencyToVote = sp_staking::currency_to_vote::SaturatingCurrencyToVote;
type RewardRemainder = ();
type Slash = ();
type Slash = pallet_dap::SlashToDap<Runtime>;
type Reward = ();
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
Expand Down Expand Up @@ -311,6 +311,15 @@ impl pallet_staking_async_rc_client::Config for Runtime {
type ValidatorSetExportSession = ConstU32<4>;
}

parameter_types! {
pub const DapPalletId: frame_support::PalletId = frame_support::PalletId(*b"dap/buff");
}

impl pallet_dap::Config for Runtime {
type Currency = Balances;
type PalletId = DapPalletId;
}

#[derive(Encode, Decode)]
// Call indices taken from westend-next runtime.
pub enum RelayChainRuntimePallets {
Expand Down
2 changes: 1 addition & 1 deletion polkadot/runtime/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -923,7 +923,7 @@ impl pallet_fast_unstake::Config for Runtime {

parameter_types! {
pub const SpendPeriod: BlockNumber = 6 * DAYS;
pub const Burn: Permill = Permill::from_perthousand(2);
pub const Burn: Permill = Permill::zero();
pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
pub const PayoutSpendPeriod: BlockNumber = 30 * DAYS;
// The asset's interior location for the paying account. This is the Treasury
Expand Down
50 changes: 50 additions & 0 deletions prdoc/pr_10576.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
title: 'Introduce FundingSink trait and pallet-dap for AssetHub'
doc:
- audience: Runtime Dev
description: |-
This PR introduces the foundation for the Dynamic Allocation Pool (DAP) system:

1. **FundingSink trait** (frame-support): A new trait for returning funds to an issuance system.
Implementations can either burn directly (`DirectBurn`) or return to a buffer for reuse.

2. **pallet-dap**: A new pallet that implements `FundingSink` by collecting funds into a buffer
account instead of burning them. The buffer account is created via `inc_providers` at genesis
or on runtime upgrade, ensuring it can receive any amount including those below ED.

3. **AssetHub Westend integration**: The runtime now uses pallet-dap to redirect staking slashes
to the DAP buffer (via `SlashToDap`).

**Treasury burns are now disabled** so no need to integrate with DAP: treasury `Burn` parameter is set
to zero in Westend RC, AssetHub and collective runtimes. This means no treasury funds are burned at
the end of spend periods, preserving total issuance.

NOTE: User-initiated burns (via pallet_balances::burn extrinsic) do NOT go through DAP currently
but they burn directly instead, reducing total issuance immediately.

This is the first deliverable of the DAP system. Future PRs will add:
- pallet-dap-satellite for system chains
- Integration with other Westend system chains
- XCM-based fund transfers from satellites to the DAP buffer
- A FundingSource trait to pull funds from DAP, enabling the replacement of direct minting with requests for funds from the DAP buffer
- DAP's responsibility to mint according to the issuance curve defined for each chain
- The ability to configure the percentage of funds redirected from DAP to various destinations (validators, nominators, treasury, collators, etc)
- Support for multiple assets in DAP, including native tokens and stablecoins
crates:
- name: frame-support
bump: minor
- name: pallet-balances
bump: major
- name: pallet-dap
bump: patch
- name: polkadot-sdk
bump: minor
- name: asset-hub-westend-runtime
bump: major
- name: westend-runtime
bump: major
- name: pallet-staking-async
bump: patch
- name: pallet-staking-async-parachain-runtime
bump: major
- name: pallet-staking-async-rc-runtime
bump: major
33 changes: 28 additions & 5 deletions substrate/frame/balances/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,11 @@ pub mod pallet {
use codec::HasCompact;
use frame_support::{
pallet_prelude::*,
traits::{fungible::Credit, tokens::Precision, VariantCount, VariantCountOf},
traits::{
fungible::Credit,
tokens::{Precision, Preservation},
VariantCount, VariantCountOf,
},
};
use frame_system::pallet_prelude::*;

Expand Down Expand Up @@ -333,6 +337,20 @@ pub mod pallet {
Self::AccountId,
Self::Balance,
>;

// TODO(DAP): Uncomment this when we want user-initiated burns to go through DAP on
// runtimes that configure it. When uncommenting, all runtimes will need to specify
// this parameter explicitly:
// - DAP-enabled runtimes: `type BurnDestination = pallet_dap::ReturnToDap<Runtime>;`
// - Other runtimes: `type BurnDestination = DirectBurn<Runtime>;`
//
// /// Handler for user-initiated burns via the `burn` extrinsic.
// ///
// /// Runtimes can configure this to redirect burned funds to a buffer account
// /// (e.g., DAP buffer on Asset Hub). If not specified, burns reduce total issuance
// /// directly.
// #[pallet::no_default_bounds]
// type BurnDestination: FundingSink<Self::AccountId, Self::Balance>;
}

/// The in-code storage version.
Expand Down Expand Up @@ -852,23 +870,28 @@ pub mod pallet {
/// If the origin's account ends up below the existential deposit as a result
/// of the burn and `keep_alive` is false, the account will be reaped.
///
/// Unlike sending funds to a _burn_ address, which merely makes the funds inaccessible,
/// this `burn` operation will reduce total issuance by the amount _burned_.
/// Currently burns directly, reducing total issuance.
///
/// TODO(DAP): When `BurnDestination` is uncommented in the Config trait, this should
/// use `T::BurnDestination::return_funds()` instead to allow DAP-enabled runtimes to
/// redirect user-initiated burns to the DAP buffer.
#[pallet::call_index(10)]
#[pallet::weight(if *keep_alive {T::WeightInfo::burn_allow_death() } else {T::WeightInfo::burn_keep_alive()})]
pub fn burn(
origin: OriginFor<T>,
#[pallet::compact] value: T::Balance,
keep_alive: bool,
) -> DispatchResult {
use frame_support::traits::tokens::Fortitude;
let source = ensure_signed(origin)?;
let preservation = if keep_alive { Preserve } else { Expendable };
let preservation =
if keep_alive { Preservation::Preserve } else { Preservation::Expendable };
<Self as fungible::Mutate<_>>::burn_from(
&source,
value,
preservation,
Precision::Exact,
Polite,
Fortitude::Polite,
)?;
Ok(())
}
Expand Down
57 changes: 57 additions & 0 deletions substrate/frame/dap/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
[package]
name = "pallet-dap"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage.workspace = true
repository.workspace = true
description = "FRAME pallet for Dynamic Allocation Pool (DAP)"

[lints]
workspace = true

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { features = ["derive", "max-encoded-len"], workspace = true }
frame-benchmarking = { optional = true, workspace = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
log = { workspace = true }
scale-info = { features = ["derive"], workspace = true }
sp-runtime = { workspace = true }

[dev-dependencies]
pallet-balances = { workspace = true, default-features = true }
sp-core = { workspace = true, default-features = true }
sp-io = { workspace = true, default-features = true }

[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"log/std",
"pallet-balances/std",
"scale-info/std",
"sp-core/std",
"sp-io/std",
"sp-runtime/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-balances/try-runtime",
"sp-runtime/try-runtime",
]
Loading
Loading