use crate::{AccountId, Credential, Runtime}; use frame_support::traits::{Currency, Imbalance}; use frame_support::{parameter_types, IterableStorageMap, StorageMap}; parameter_types! { pub const CurrentLeadCredential: Credential = 0; pub const AnyActiveCuratorCredential: Credential = 1; pub const AnyActiveChannelOwnerCredential: Credential = 2; pub const PrincipalIdMappingStartsAtCredential: Credential = 1000; } pub struct ContentWorkingGroupCredentials {} impl versioned_store_permissions::CredentialChecker for ContentWorkingGroupCredentials { fn account_has_credential( account: &AccountId, credential: ::Credential, ) -> bool { match credential { // Credentials from 0..999 represents groups or more complex requirements // Current Lead if set credential if credential == CurrentLeadCredential::get() => { match >::ensure_lead_is_set() { Ok((_, lead)) => lead.role_account == *account, _ => false, } } // Any Active Curator credential if credential == AnyActiveCuratorCredential::get() => { // Look for a Curator with a matching role account for (_principal_id, principal) in >::iter() { if let content_working_group::Principal::Curator(curator_id) = principal { let curator = >::get(curator_id); if curator.role_account == *account && curator.stage == content_working_group::CuratorRoleStage::Active { return true; } } } false } // Any Active Channel Owner credential if credential == AnyActiveChannelOwnerCredential::get() => { // Look for a ChannelOwner with a matching role account for (_principal_id, principal) in >::iter() { if let content_working_group::Principal::ChannelOwner(channel_id) = principal { let channel = >::get(channel_id); if channel.role_account == *account { return true; // should we also take publishing_status/curation_status into account ? } } } false } // mapping to working group principal id n if n >= PrincipalIdMappingStartsAtCredential::get() => { >::account_has_credential( account, n - PrincipalIdMappingStartsAtCredential::get(), ) } _ => false, } } } #[allow(dead_code)] pub struct ContentWorkingGroupStakingEventHandler {} impl stake::StakingEventsHandler for ContentWorkingGroupStakingEventHandler { fn unstaked( stake_id: &::StakeId, _unstaked_amount: stake::BalanceOf, remaining_imbalance: stake::NegativeImbalance, ) -> stake::NegativeImbalance { if !hiring::ApplicationIdByStakingId::::contains_key(stake_id) { // Stake not related to a staked role managed by the hiring module return remaining_imbalance; } let application_id = hiring::ApplicationIdByStakingId::::get(stake_id); if !content_working_group::CuratorApplicationById::::contains_key(application_id) { // Stake not for a Curator return remaining_imbalance; } // Notify the Hiring module - is there a potential re-entrancy bug if // instant unstaking is occuring? hiring::Module::::unstaked(*stake_id); // Only notify working group module if non instantaneous unstaking occured if content_working_group::UnstakerByStakeId::::contains_key(stake_id) { content_working_group::Module::::unstaked(*stake_id); } // Determine member id of the curator let curator_application = content_working_group::CuratorApplicationById::::get(application_id); let member_id = curator_application.member_id; // get member's profile let member_profile = membership::MembershipById::::get(member_id); // deposit funds to member's root_account // The application doesn't recorded the original source_account from which staked funds were // provided, so we don't really have another option at the moment. ::Currency::resolve_creating( &member_profile.root_account, remaining_imbalance, ); stake::NegativeImbalance::::zero() } // Handler for slashing event fn slashed( _id: &::StakeId, _slash_id: Option<::SlashId>, _slashed_amount: stake::BalanceOf, _remaining_stake: stake::BalanceOf, remaining_imbalance: stake::NegativeImbalance, ) -> stake::NegativeImbalance { // Check if the stake is associated with a hired curator or applicant // if their stake goes below minimum required for the role, // they should get deactivated. // Since we don't currently implement any slash initiation in working group, // there is nothing to do for now. // Not interested in transfering the slashed amount anywhere for now, // so return it to next handler. remaining_imbalance } }