Skip to content

Commit

Permalink
feat: handled treasury spending referenda with specific origin
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-cholakov committed Jun 4, 2024
1 parent bc41cf7 commit 2d76e35
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 28 deletions.
5 changes: 4 additions & 1 deletion pallets/token-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ pub mod pallet {
/// Percentage of growth to store in the treasury
#[pallet::constant]
type TreasuryGrowthPercentage: Get<Perbill>;
type TreasurySpender: EnsureOrigin<Self::RuntimeOrigin, Success = BalanceOf<Self>>;
/// Handler to notify the runtime when AVT growth is lifted.
type OnGrowthLiftedHandler: OnGrowthLiftedHandler<BalanceOf<Self>>;
type Scheduler: ScheduleAnon<BlockNumberFor<Self>, CallOf<Self>, Self::PalletsOrigin>
Expand Down Expand Up @@ -263,6 +264,7 @@ pub mod pallet {
InvalidLowerCall,
LowerDataLimitExceeded,
InvalidLowerId,
InsufficientPermission,
}

#[pallet::storage]
Expand Down Expand Up @@ -411,8 +413,9 @@ pub mod pallet {
recipient: T::AccountId,
amount: BalanceOf<T>,
) -> DispatchResult {
ensure_root(origin)?;
let max_amount = T::TreasurySpender::ensure_origin(origin)?;
ensure!(amount != BalanceOf::<T>::zero(), Error::<T>::AmountIsZero);
ensure!(amount <= max_amount, Error::<T>::InsufficientPermission);

<T as pallet::Config>::Currency::transfer(
&Self::compute_treasury_account_id(),
Expand Down
5 changes: 5 additions & 0 deletions runtime/avn/src/governance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ pub use super::*;

pub mod origins;
use frame_support::traits::EitherOf;
use frame_system::EnsureRootWithSuccess;
use origins::pallet_custom_origins::Spender;
pub use origins::{
pallet_custom_origins, ReferendumCanceller, ReferendumKiller, WhitelistedCaller,
};

pub mod tracks;
use pallet_token_manager;
use sp_core::ConstU128;
pub use tracks::TracksInfo;

parameter_types! {
Expand All @@ -33,6 +36,8 @@ parameter_types! {

impl pallet_custom_origins::Config for Runtime {}

pub type TreasurySpender = EitherOf<EnsureRootWithSuccess<AccountId, ConstU128<65535>>, Spender>;

pub struct ToTreasury<R>(sp_std::marker::PhantomData<R>);
impl<R> OnUnbalanced<NegativeImbalance<R>> for ToTreasury<R>
where
Expand Down
8 changes: 5 additions & 3 deletions runtime/avn/src/governance/origins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub use pallet_custom_origins::*;
#[frame_support::pallet]
pub mod pallet_custom_origins {
use frame_support::pallet_prelude::*;
use crate::Balance;
use crate::AVT;

#[pallet::config]
pub trait Config: frame_system::Config {}
Expand Down Expand Up @@ -114,9 +116,9 @@ pub mod pallet_custom_origins {

decl_ensure! {
pub type Spender: EnsureOrigin<Success = Balance> {
SmallSpender = 10 * GRAND,
MediumSpender = 100 * GRAND,
BigSpender = 1_000 * GRAND,
SmallSpender = 10 * AVT,
MediumSpender = 100 * AVT,
BigSpender = 1_000 * AVT,
}
}
}
7 changes: 4 additions & 3 deletions runtime/avn/src/governance/tracks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 8]
pallet_referenda::TrackInfo {
name: "small_spender",
max_deciding: 50,
decision_deposit: 100 * 3 * CENTS,
decision_deposit: 100 * 3 * AVT,
prepare_period: 10 * MINUTES,
decision_period: 20 * MINUTES,
confirm_period: 10 * MINUTES,
Expand All @@ -138,7 +138,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 8]
pallet_referenda::TrackInfo {
name: "medium_spender",
max_deciding: 50,
decision_deposit: 200 * 3 * CENTS,
decision_deposit: 200 * 3 * AVT,
prepare_period: 10 * MINUTES,
decision_period: 20 * MINUTES,
confirm_period: 12 * MINUTES,
Expand All @@ -152,7 +152,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 8]
pallet_referenda::TrackInfo {
name: "big_spender",
max_deciding: 50,
decision_deposit: 400 * 3 * CENTS,
decision_deposit: 400 * 3 * AVT,
prepare_period: 10 * MINUTES,
decision_period: 20 * MINUTES,
confirm_period: 14 * MINUTES,
Expand Down Expand Up @@ -184,6 +184,7 @@ impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
// Referendum admins
origins::Origin::ReferendumCanceller => Ok(3),
origins::Origin::ReferendumKiller => Ok(4),
// Spenders
origins::Origin::SmallSpender => Ok(5),
origins::Origin::MediumSpender => Ok(6),
origins::Origin::BigSpender => Ok(7),
Expand Down
8 changes: 4 additions & 4 deletions runtime/avn/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ use frame_support::{
dispatch::DispatchClass,
parameter_types,
traits::{
AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, Contains, Currency, Imbalance,
OnUnbalanced, PrivilegeCmp,
AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, Contains, Currency, Imbalance, OnUnbalanced, PrivilegeCmp
},
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight},
PalletId, RuntimeDebug,
Expand All @@ -45,7 +44,7 @@ pub use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureRoot, EnsureSigned, Event as SystemEvent, EventRecord, Phase,
};
use governance::pallet_custom_origins;
use governance::{pallet_custom_origins, TreasurySpender};
use proxy_config::AvnProxyConfig;
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
pub use sp_runtime::{MultiAddress, Perbill, Permill};
Expand Down Expand Up @@ -587,6 +586,7 @@ impl pallet_token_manager::pallet::Config for Runtime {
type Signature = Signature;
type OnGrowthLiftedHandler = ParachainStaking;
type TreasuryGrowthPercentage = TreasuryGrowthPercentage;
type TreasurySpender = TreasurySpender;
type AvnTreasuryPotId = AvnTreasuryPotId;
type WeightInfo = pallet_token_manager::default_weights::SubstrateWeight<Runtime>;
type Scheduler = Scheduler;
Expand Down Expand Up @@ -766,7 +766,7 @@ construct_runtime!(
// OpenGov pallets
Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>} = 97,
Scheduler: pallet_scheduler::{Pallet, Storage, Event<T>, Call} = 98,
Origins: pallet_custom_origins::{Origin} = 99,
Origins: pallet_custom_origins = 99,
ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 100,
Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 101,
Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 102
Expand Down
22 changes: 13 additions & 9 deletions runtime/test/src/governance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ pub use super::*;

pub mod origins;
use frame_support::traits::EitherOf;
use origins::pallet_custom_origins::Spender;
pub use origins::{
pallet_custom_origins, ReferendumCanceller, ReferendumKiller, WhitelistedCaller,
};

pub mod tracks;
use pallet_token_manager;
use sp_core::ConstU128;
pub use tracks::TracksInfo;

parameter_types! {
Expand All @@ -32,15 +35,7 @@ parameter_types! {

impl pallet_custom_origins::Config for Runtime {}

impl pallet_whitelist::Config for Runtime {
type WeightInfo = pallet_whitelist::weights::SubstrateWeight<Runtime>;
type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type WhitelistOrigin = EnsureRoot<Self::AccountId>;
type DispatchWhitelistedOrigin = EitherOf<EnsureRoot<Self::AccountId>, WhitelistedCaller>;
type Preimages = Preimage;
}

pub type TreasurySpender = EitherOf<EnsureRootWithSuccess<AccountId, ConstU128<65535>>, Spender>;
pub struct ToTreasury<R>(sp_std::marker::PhantomData<R>);
impl<R> OnUnbalanced<NegativeImbalance<R>> for ToTreasury<R>
where
Expand All @@ -55,6 +50,15 @@ where
}
}

impl pallet_whitelist::Config for Runtime {
type WeightInfo = pallet_whitelist::weights::SubstrateWeight<Runtime>;
type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type WhitelistOrigin = EnsureRoot<Self::AccountId>;
type DispatchWhitelistedOrigin = EitherOf<EnsureRoot<Self::AccountId>, WhitelistedCaller>;
type Preimages = Preimage;
}

impl pallet_referenda::Config for Runtime {
type WeightInfo = pallet_referenda::weights::SubstrateWeight<Runtime>;
type RuntimeCall = RuntimeCall;
Expand Down
49 changes: 49 additions & 0 deletions runtime/test/src/governance/origins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub use pallet_custom_origins::*;
#[frame_support::pallet]
pub mod pallet_custom_origins {
use frame_support::pallet_prelude::*;
use crate::Balance;
use crate::AVT;

#[pallet::config]
pub trait Config: frame_system::Config {}
Expand All @@ -39,6 +41,12 @@ pub mod pallet_custom_origins {
ReferendumKiller,
/// Origin able to dispatch a whitelisted call.
WhitelistedCaller,
/// Origin able to spend the amount specified in Spender.
SmallSpender,
/// Origin able to spend the amount specified in Spender.
MediumSpender,
/// Origin able to spend the amount specified in Spender.
BigSpender
}

macro_rules! decl_unit_ensures {
Expand Down Expand Up @@ -72,4 +80,45 @@ pub mod pallet_custom_origins {
() => {}
}
decl_unit_ensures!(GeneralAdmin, ReferendumCanceller, ReferendumKiller, WhitelistedCaller,);

macro_rules! decl_ensure {
(
$vis:vis type $name:ident: EnsureOrigin<Success = $success_type:ty> {
$( $item:ident = $success:expr, )*
}
) => {
$vis struct $name;
impl<O: Into<Result<Origin, O>> + From<Origin>>
EnsureOrigin<O> for $name
{
type Success = $success_type;
fn try_origin(o: O) -> Result<Self::Success, O> {
o.into().and_then(|o| match o {
$(
Origin::$item => Ok($success),
)*
r => Err(O::from(r)),
})
}
#[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin() -> Result<O, ()> {
// By convention the more privileged origins go later, so for greatest chance
// of success, we want the last one.
let _result: Result<O, ()> = Err(());
$(
let _result: Result<O, ()> = Ok(O::from(Origin::$item));
)*
_result
}
}
}
}

decl_ensure! {
pub type Spender: EnsureOrigin<Success = Balance> {
SmallSpender = 10 * AVT,
MediumSpender = 100 * AVT,
BigSpender = 1_000 * AVT,
}
}
}
56 changes: 55 additions & 1 deletion runtime/test/src/governance/tracks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,16 @@ const APP_WHITELISTED_CALLER: Curve =
const SUP_WHITELISTED_CALLER: Curve =
Curve::make_reciprocal(1, 2, percent(20), percent(5), percent(50));

const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 5] = [
const APP_SMALL_SPENDER: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
const SUP_SMALL_SPENDER: Curve =
Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
const APP_MEDIUM_SPENDER: Curve = Curve::make_linear(23, 28, percent(50), percent(100));
const SUP_MEDIUM_SPENDER: Curve =
Curve::make_reciprocal(16, 28, percent(1), percent(0), percent(50));
const APP_BIG_SPENDER: Curve = Curve::make_linear(28, 28, percent(50), percent(100));
const SUP_BIG_SPENDER: Curve = Curve::make_reciprocal(20, 28, percent(1), percent(0), percent(50));

const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 8] = [
(
0,
pallet_referenda::TrackInfo {
Expand Down Expand Up @@ -109,6 +118,48 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 5]
min_support: SUP_REFERENDUM_KILLER,
},
),
(
5,
pallet_referenda::TrackInfo {
name: "small_spender",
max_deciding: 5,
decision_deposit: 1 * AVT,
prepare_period: 1 * MINUTES,
decision_period: 2 * MINUTES,
confirm_period: 1 * MINUTES,
min_enactment_period: 1 * MINUTES,
min_approval: APP_SMALL_SPENDER,
min_support: SUP_SMALL_SPENDER,
},
),
(
6,
pallet_referenda::TrackInfo {
name: "medium_spender",
max_deciding: 5,
decision_deposit: 2 * AVT,
prepare_period: 1 * MINUTES,
decision_period: 2 * MINUTES,
confirm_period: 1 * MINUTES,
min_enactment_period: 1 * MINUTES,
min_approval: APP_MEDIUM_SPENDER,
min_support: SUP_MEDIUM_SPENDER,
},
),
(
7,
pallet_referenda::TrackInfo {
name: "big_spender",
max_deciding: 5,
decision_deposit: 4 * AVT,
prepare_period: 1 * MINUTES,
decision_period: 2 * MINUTES,
confirm_period: 1 * MINUTES,
min_enactment_period: 1 * MINUTES,
min_approval: APP_BIG_SPENDER,
min_support: SUP_BIG_SPENDER,
},
),
];

pub struct TracksInfo;
Expand All @@ -132,6 +183,9 @@ impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
// Referendum admins
origins::Origin::ReferendumCanceller => Ok(3),
origins::Origin::ReferendumKiller => Ok(4),
origins::Origin::SmallSpender => Ok(5),
origins::Origin::MediumSpender => Ok(6),
origins::Origin::BigSpender => Ok(7),
}
} else {
Err(())
Expand Down
13 changes: 6 additions & 7 deletions runtime/test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,15 @@ use frame_support::{
dispatch::DispatchClass,
parameter_types,
traits::{
AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, Contains, Currency, Imbalance,
OnUnbalanced, PrivilegeCmp,
AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, Contains, Currency, Imbalance, OnUnbalanced, PrivilegeCmp
},
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, ConstantMultiplier, Weight},
PalletId, RuntimeDebug,
};
use frame_system::{
limits::{BlockLength, BlockWeights},
EnsureRoot, EnsureSigned,
limits::{BlockLength, BlockWeights}, EnsureRoot, EnsureSigned
};
use governance::pallet_custom_origins;
use governance::{pallet_custom_origins, TreasurySpender};
use proxy_config::AvnProxyConfig;
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
pub use sp_runtime::{MultiAddress, Perbill, Permill};
Expand Down Expand Up @@ -169,7 +167,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("avn-test-parachain"),
impl_name: create_runtime_str!("avn-test-parachain"),
authoring_version: 1,
spec_version: 65,
spec_version: 66,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
Expand Down Expand Up @@ -607,6 +605,7 @@ impl pallet_token_manager::pallet::Config for Runtime {
type Signature = Signature;
type OnGrowthLiftedHandler = ParachainStaking;
type TreasuryGrowthPercentage = TreasuryGrowthPercentage;
type TreasurySpender = TreasurySpender;
type AvnTreasuryPotId = AvnTreasuryPotId;
type WeightInfo = pallet_token_manager::default_weights::SubstrateWeight<Runtime>;
type Scheduler = Scheduler;
Expand Down Expand Up @@ -778,7 +777,7 @@ construct_runtime!(
// OpenGov pallets
Preimage: pallet_preimage::{Pallet, Call, Storage, Event<T>} = 97,
Scheduler: pallet_scheduler::{Pallet, Storage, Event<T>, Call} = 98,
Origins: pallet_custom_origins::{Origin} = 99,
Origins: pallet_custom_origins = 99,
ConvictionVoting: pallet_conviction_voting::{Pallet, Call, Storage, Event<T>} = 100,
Referenda: pallet_referenda::{Pallet, Call, Storage, Event<T>} = 101,
Whitelist: pallet_whitelist::{Pallet, Call, Storage, Event<T>} = 102
Expand Down

0 comments on commit 2d76e35

Please sign in to comment.