diff --git a/pallets/communities/src/functions.rs b/pallets/communities/src/functions.rs index bb827995..23016fa3 100644 --- a/pallets/communities/src/functions.rs +++ b/pallets/communities/src/functions.rs @@ -1,4 +1,4 @@ -use super::{origin::DecisionMethod, *}; +use super::*; use fc_traits_memberships::{GenericRank, Inspect, Rank}; use frame_support::{ dispatch::PostDispatchInfo, @@ -95,7 +95,7 @@ impl Pallet { }; let say = *match (vote, decision_method) { - (Vote::AssetBalance(say, asset, ..), DecisionMethod::CommunityAsset(a)) if asset == a => say, + (Vote::AssetBalance(say, asset, ..), DecisionMethod::CommunityAsset(a, _)) if asset == a => say, (Vote::NativeBalance(say, ..), DecisionMethod::NativeToken) | (Vote::Standard(say), DecisionMethod::Membership | DecisionMethod::Rank) => say, _ => fail!(Error::::InvalidVoteType), diff --git a/pallets/communities/src/lib.rs b/pallets/communities/src/lib.rs index 0ae489fb..15549aea 100644 --- a/pallets/communities/src/lib.rs +++ b/pallets/communities/src/lib.rs @@ -146,6 +146,7 @@ pub mod pallet { Blake2_128Concat, Parameter, }; use frame_system::pallet_prelude::{ensure_signed, BlockNumberFor, OriginFor}; + use sp_runtime::traits::AccountIdConversion; use sp_runtime::{ traits::{Dispatchable, StaticLookup}, TokenError, @@ -193,7 +194,7 @@ pub mod pallet { >; /// Type represents interactions between fungibles (i.e. assets) - type Assets: fungibles::Inspect + type Assets: fungibles::Inspect> + fungibles::Mutate + fungibles::Create + fungibles::hold::Inspect @@ -477,6 +478,15 @@ pub mod pallet { decision_method: DecisionMethodFor, ) -> DispatchResult { T::AdminOrigin::ensure_origin(origin)?; + if let DecisionMethod::CommunityAsset(ref asset, min_vote) = decision_method { + // best effort attemt to create the asset if it doesn't exist + let _ = >::create( + asset.clone(), + T::PalletId::get().into_account_truncating(), + false, + min_vote, + ); + } CommunityDecisionMethod::::set(community_id, decision_method); Self::deposit_event(Event::DecisionMethodSet { id: community_id }); Ok(()) diff --git a/pallets/communities/src/mock.rs b/pallets/communities/src/mock.rs index 92c90815..7bd8b1ca 100644 --- a/pallets/communities/src/mock.rs +++ b/pallets/communities/src/mock.rs @@ -24,8 +24,9 @@ pub use virto_common::{CommunityId, MembershipId}; use crate::{ self as pallet_communities, - origin::{DecisionMethod, EnsureCommunity, EnsureSignedPays}, + origin::{EnsureCommunity, EnsureSignedPays}, types::{Tally, VoteWeight}, + DecisionMethod, }; // Weights constants @@ -455,7 +456,7 @@ pub(crate) struct TestEnvBuilder { assets_config: AssetsConfig, balances: Vec<(AccountId, Balance)>, communities: Vec, - decision_methods: sp_std::collections::btree_map::BTreeMap>, + decision_methods: sp_std::collections::btree_map::BTreeMap>, members: Vec<(CommunityId, AccountId)>, memberships: Vec<(CommunityId, MembershipId)>, tracks: Vec<(TrackIdOf, TrackInfoOf)>, @@ -498,7 +499,7 @@ impl TestEnvBuilder { pub(crate) fn add_community( mut self, community_id: CommunityId, - decision_method: DecisionMethod, + decision_method: DecisionMethod, members: &[AccountId], memberships: &[MembershipId], maybe_track: Option>, diff --git a/pallets/communities/src/origin.rs b/pallets/communities/src/origin.rs index adf2b0b5..57ea01fa 100644 --- a/pallets/communities/src/origin.rs +++ b/pallets/communities/src/origin.rs @@ -126,16 +126,6 @@ pub enum Subset { AtLeastRank(GenericRank), } -/// The mechanism used by the community or one of its subsets to make decisions -#[derive(Clone, Debug, Decode, Default, Encode, Eq, MaxEncodedLen, PartialEq, TypeInfo)] -pub enum DecisionMethod { - #[default] - Membership, - NativeToken, - CommunityAsset(AssetId), - Rank, -} - #[cfg(feature = "xcm")] impl TryConvert, xcm::v3::MultiLocation> for RawOrigin where diff --git a/pallets/communities/src/tests/governance.rs b/pallets/communities/src/tests/governance.rs index b27c94bb..60b3148f 100644 --- a/pallets/communities/src/tests/governance.rs +++ b/pallets/communities/src/tests/governance.rs @@ -6,9 +6,8 @@ use parity_scale_codec::Encode; use sp_runtime::{str_array as s, BoundedVec, TokenError}; use crate::{ - origin::DecisionMethod, types::{Tally, Vote}, - Call, + Call, DecisionMethod, }; use frame_support::assert_noop; use pallet_referenda::TrackInfo; @@ -108,7 +107,7 @@ fn new_test_ext() -> sp_io::TestExternalities { // Community-asset based .add_community( COMMUNITY_B, - DecisionMethod::CommunityAsset(COMMUNITY_B_ASSET_ID), + DecisionMethod::CommunityAsset(COMMUNITY_B_ASSET_ID, 0), &[BOB, CHARLIE], memberships_of(COMMUNITY_B), Some(CommunityTrack::get()), diff --git a/pallets/communities/src/types.rs b/pallets/communities/src/types.rs index 2a9b80ef..da43ba66 100644 --- a/pallets/communities/src/types.rs +++ b/pallets/communities/src/types.rs @@ -1,4 +1,3 @@ -use crate::origin::DecisionMethod; use crate::{CommunityDecisionMethod, Config}; use fc_traits_memberships::{Inspect, Rank}; use frame_support::pallet_prelude::*; @@ -16,7 +15,7 @@ pub type NativeBalanceOf = <::Balances as fungible::Inspect = ::AccountId; pub type CommunityIdOf = ::CommunityId; pub type VoteOf = Vote, AssetBalanceOf, NativeBalanceOf>; -pub type DecisionMethodFor = DecisionMethod>; +pub type DecisionMethodFor = DecisionMethod, AssetBalanceOf>; pub type PollIndexOf = <::Polls as Polling>>::Index; pub type AccountIdLookupOf = <::Lookup as StaticLookup>::Source; pub type PalletsOriginOf = @@ -54,6 +53,16 @@ pub enum CommunityState { Blocked, } +/// The mechanism used by the community or one of its subsets to make decisions +#[derive(Clone, Debug, Decode, Default, Encode, Eq, MaxEncodedLen, PartialEq, TypeInfo)] +pub enum DecisionMethod { + #[default] + Membership, + NativeToken, + CommunityAsset(AssetId, MinVote), + Rank, +} + // Governance pub type VoteWeight = u32; @@ -126,7 +135,7 @@ impl Tally { DecisionMethod::Membership => T::MemberMgmt::members_total(&community_id), DecisionMethod::Rank => T::MemberMgmt::ranks_total(&community_id), DecisionMethod::NativeToken => T::Balances::total_issuance().saturated_into::(), - DecisionMethod::CommunityAsset(asset_id) => { + DecisionMethod::CommunityAsset(asset_id, _) => { T::Assets::total_issuance(asset_id).saturated_into::() } }