Skip to content

Commit 78b75f4

Browse files
Merge pull request #568 from Cerebellum-Network/release/7.3.5
Added FeeHandler Pallet
2 parents 3f7c44d + 6546dc0 commit 78b75f4

File tree

10 files changed

+353
-12
lines changed

10 files changed

+353
-12
lines changed

.github/workflows/stage.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
- name: configure aws credentials
3636
uses: aws-actions/configure-aws-credentials@v2
3737
with:
38-
role-to-assume: arn:aws:iam::${{ vars.DEV_NETWORK_AWS_ACCOUNT_ID }}:role/github
38+
role-to-assume: arn:aws:iam::${{ vars.SHARED_AWS_ACCOUNT_ID }}:role/github
3939
role-session-name: ${{ github.event.repository.name }}
4040
aws-region: us-west-2
4141

CHANGELOG.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
- [C] Changes is `Cere` Runtime
1111
- [D] Changes is `Cere Dev` Runtime
1212

13+
## [7.3.5]
14+
15+
- [C,D] Turn-Off Inflation and change reward source
16+
17+
## [7.3.4]
18+
19+
- [C,D] Stop Daily Burn from Treasury
20+
1321
## [7.3.3]
1422

1523
- [C,D] Fix `CheckMetadataHash` extension issue
16-
-
24+
1725
## [7.3.2]
1826

1927
- [C] Update Hyperbridge Coprocessor for Mainnet.

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ members = [
2121
"pallets/erc721",
2222
"pallets/ddc-clusters-gov",
2323
"pallets/origins",
24+
"pallets/fee-handler",
2425
"primitives",
2526
"runtime/cere",
2627
"runtime/cere-dev",
@@ -194,6 +195,7 @@ pallet-ddc-staking = { path = "pallets/ddc-staking", default-features = false }
194195
pallet-erc20 = { path = "pallets/erc20", default-features = false }
195196
pallet-erc721 = { path = "pallets/erc721", default-features = false }
196197
pallet-origins = { path = "pallets/origins", default-features = false }
198+
pallet-fee-handler = { path = "pallets/fee-handler", default-features = false }
197199

198200
# Hyperbridge
199201
ismp = { default-features = false, version = "0.2.2" }

pallets/fee-handler/Cargo.toml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
[package]
2+
name = "pallet-fee-handler"
3+
version.workspace = true
4+
authors.workspace = true
5+
edition.workspace = true
6+
homepage.workspace = true
7+
license.workspace = true
8+
readme.workspace = true
9+
repository.workspace = true
10+
11+
[package.metadata.docs.rs]
12+
targets = ["x86_64-unknown-linux-gnu"]
13+
14+
[dependencies]
15+
codec = { features = ["derive"], workspace = true }
16+
scale-info = { features = ["derive"], workspace = true }
17+
18+
# frame deps
19+
frame-benchmarking = { optional = true, workspace = true }
20+
frame-support = { workspace = true }
21+
frame-system = { workspace = true }
22+
sp-runtime = { workspace = true }
23+
24+
[dev-dependencies]
25+
sp-core = { workspace = true, default-features = true }
26+
sp-io = { workspace = true, default-features = true }
27+
28+
[features]
29+
default = ["std"]
30+
std = [
31+
"codec/std",
32+
"frame-benchmarking?/std",
33+
"frame-support/std",
34+
"frame-system/std",
35+
"scale-info/std",
36+
"sp-core/std",
37+
"sp-io/std",
38+
"sp-runtime/std",
39+
]
40+
runtime-benchmarks = [
41+
"frame-benchmarking/runtime-benchmarks",
42+
"frame-support/runtime-benchmarks",
43+
"frame-system/runtime-benchmarks",
44+
"sp-runtime/runtime-benchmarks",
45+
]
46+
try-runtime = [
47+
"frame-support/try-runtime",
48+
"frame-system/try-runtime",
49+
"sp-runtime/try-runtime",
50+
]

pallets/fee-handler/src/lib.rs

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
//! # Fee Handler Pallet
2+
//!
3+
//! This pallet is responsible for handling fee distribution in a Substrate-based blockchain.
4+
//! It provides functionality to configure fee distribution proportions and transfer fees to
5+
//! designated accounts (e.g., treasury and fee pot accounts).
6+
//!
7+
//! ## Overview
8+
//!
9+
//! - Allows governance to configure fee distribution proportions.
10+
//! - Handles fee transfers to the treasury and fee pot accounts based on the configured
11+
//! proportions.
12+
//! - Emits events for key actions such as configuration updates and fee transfers.
13+
//!
14+
//! ## Dispatchable Functions
15+
//!
16+
//! - `manual_topup`: Allows a user to manually top up the fee pot account.
17+
//! - `fee_distribution_config`: Allows governance to set the fee distribution proportions.
18+
19+
#![cfg_attr(not(feature = "std"), no_std)]
20+
21+
// todo! Add Unit tests and Benchmarking
22+
23+
use codec::{Decode, Encode, MaxEncodedLen};
24+
use frame_support::{__private::RuntimeDebug, pallet_prelude::TypeInfo, traits::Currency};
25+
pub use pallet::*;
26+
use sp_runtime::{Permill, Saturating};
27+
28+
#[derive(PartialEq, Eq, Clone, Encode, Decode, RuntimeDebug, TypeInfo, MaxEncodedLen)]
29+
pub struct FeeDistributionProportion {
30+
treasury_proportion: Permill,
31+
fee_pot_proportion: Permill,
32+
}
33+
34+
pub type BalanceOf<T> =
35+
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
36+
37+
impl FeeDistributionProportion {
38+
/// Creates a new `FeeDistributionProportion` if the total proportions equal 100%.
39+
pub fn new(treasury_proportion: u32, fee_pot_proportion: u32) -> Option<Self> {
40+
let treasury_proportion = Permill::from_percent(treasury_proportion);
41+
let fee_pot_proportion = Permill::from_percent(fee_pot_proportion);
42+
let total = treasury_proportion.saturating_add(fee_pot_proportion);
43+
if total == Permill::one() {
44+
Some(Self { treasury_proportion, fee_pot_proportion })
45+
} else {
46+
None
47+
}
48+
}
49+
}
50+
51+
pub trait FeeHandler<T: Config> {
52+
/// Handles the distribution of fees to the treasury and fee pot accounts.
53+
fn handle_fee(source: T::AccountId, fee_amount: BalanceOf<T>) -> sp_runtime::DispatchResult;
54+
}
55+
56+
// todo! Fixed clippy warnings
57+
#[allow(deprecated)]
58+
#[allow(clippy::let_unit_value)]
59+
#[allow(clippy::manual_inspect)]
60+
#[frame_support::pallet]
61+
pub mod pallet {
62+
use frame_support::{
63+
pallet_prelude::*,
64+
traits::{ExistenceRequirement, LockableCurrency},
65+
PalletId,
66+
};
67+
use frame_system::pallet_prelude::*;
68+
use sp_runtime::traits::AccountIdConversion;
69+
70+
use super::*;
71+
72+
#[pallet::pallet]
73+
pub struct Pallet<T>(_);
74+
75+
#[pallet::config]
76+
pub trait Config: frame_system::Config {
77+
/// The overarching runtime event type.
78+
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
79+
/// Native Currency Support.
80+
type Currency: LockableCurrency<Self::AccountId, Moment = BlockNumberFor<Self>>;
81+
/// Governance origin for privileged calls.
82+
type GovernanceOrigin: EnsureOrigin<Self::RuntimeOrigin>;
83+
/// Pallet ID for the fee pot account.
84+
#[pallet::constant]
85+
type PalletId: Get<PalletId>;
86+
/// Pallet ID for the treasury account.
87+
#[pallet::constant]
88+
type TreasuryPalletId: Get<PalletId>;
89+
}
90+
91+
#[pallet::storage]
92+
pub type FeeDistributionProportionConfig<T> = StorageValue<_, FeeDistributionProportion>;
93+
94+
#[pallet::event]
95+
#[pallet::generate_deposit(pub(super) fn deposit_event)]
96+
pub enum Event<T: Config> {
97+
/// Manual top-up of the fee pot account.
98+
ManualFeeAccountTopUp { source: T::AccountId, amount: BalanceOf<T> },
99+
/// Fee distribution configuration updated.
100+
FeeDistributionProportionConfigSet { config: FeeDistributionProportion },
101+
}
102+
103+
#[pallet::error]
104+
pub enum Error<T> {
105+
/// Fee distribution configuration is not set.
106+
FeeDistributionConfigNotSet,
107+
/// Arithmetic overflow occurred.
108+
ArithmeticOverflow,
109+
}
110+
111+
#[pallet::call]
112+
impl<T: Config> Pallet<T> {
113+
/// Allows a user to manually top up the fee pot account.
114+
#[pallet::call_index(0)]
115+
// todo! Add actual weights
116+
#[pallet::weight(10_000)]
117+
pub fn manual_topup(origin: OriginFor<T>, amount: BalanceOf<T>) -> DispatchResult {
118+
let who = ensure_signed(origin)?;
119+
T::Currency::transfer(
120+
&who,
121+
&Self::fee_pot_account_id(),
122+
amount,
123+
ExistenceRequirement::AllowDeath,
124+
)?;
125+
Self::deposit_event(Event::ManualFeeAccountTopUp { source: who, amount });
126+
Ok(())
127+
}
128+
129+
/// Allows governance to set the fee distribution proportions.
130+
#[pallet::call_index(1)]
131+
// todo! Add actual weights
132+
#[pallet::weight(10_000)]
133+
pub fn fee_distribution_config(
134+
origin: OriginFor<T>,
135+
treasury_fee_proportion: u32,
136+
fee_pot_proportion: u32,
137+
) -> DispatchResult {
138+
T::GovernanceOrigin::ensure_origin(origin)?;
139+
let fee_distribution_config =
140+
FeeDistributionProportion::new(treasury_fee_proportion, fee_pot_proportion)
141+
.ok_or(Error::<T>::ArithmeticOverflow)?;
142+
<FeeDistributionProportionConfig<T>>::put(fee_distribution_config.clone());
143+
Self::deposit_event(Event::FeeDistributionProportionConfigSet {
144+
config: fee_distribution_config,
145+
});
146+
Ok(())
147+
}
148+
}
149+
150+
impl<T: Config> Pallet<T> {
151+
/// Returns the account ID of the fee pot.
152+
pub fn fee_pot_account_id() -> T::AccountId {
153+
T::PalletId::get().into_account_truncating()
154+
}
155+
156+
/// Returns the account ID of the treasury.
157+
pub fn treasury_account_id() -> T::AccountId {
158+
T::TreasuryPalletId::get().into_account_truncating()
159+
}
160+
}
161+
162+
impl<T: Config> FeeHandler<T> for Pallet<T> {
163+
fn handle_fee(source: T::AccountId, fee_amount: BalanceOf<T>) -> DispatchResult {
164+
let fee_config: FeeDistributionProportion = <FeeDistributionProportionConfig<T>>::get()
165+
.ok_or(Error::<T>::FeeDistributionConfigNotSet)?;
166+
let fee_pot_amount = fee_config.fee_pot_proportion.mul_floor(fee_amount);
167+
let treasury_amount = fee_amount.saturating_sub(fee_pot_amount);
168+
169+
let fee_pot_account = Pallet::<T>::fee_pot_account_id();
170+
let treasury_account = Pallet::<T>::treasury_account_id();
171+
172+
T::Currency::transfer(
173+
&source,
174+
&fee_pot_account,
175+
fee_pot_amount,
176+
ExistenceRequirement::AllowDeath,
177+
)?;
178+
T::Currency::transfer(
179+
&source,
180+
&treasury_account,
181+
treasury_amount,
182+
ExistenceRequirement::AllowDeath,
183+
)?;
184+
Ok(())
185+
}
186+
}
187+
}

runtime/cere-dev/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ pallet-ddc-payouts = { workspace = true }
103103
pallet-ddc-staking = { workspace = true }
104104
pallet-erc20 = { workspace = true }
105105
pallet-erc721 = { workspace = true }
106+
pallet-fee-handler = { workspace = true }
106107
pallet-origins = { workspace = true }
107108

108109
# Hyperbridge Depedencies
@@ -211,6 +212,7 @@ std = [
211212
"anyhow/std",
212213
"frame-metadata-hash-extension/std",
213214
"pallet-token-gateway/std",
215+
"pallet-fee-handler/std",
214216
]
215217
runtime-benchmarks = [
216218
"frame-benchmarking/runtime-benchmarks",

0 commit comments

Comments
 (0)