pallet_governance/
roles.rs

1use pallet_permission0_api::{CuratorPermissions, Permission0CuratorApi};
2use polkadot_sdk::{
3    frame_election_provider_support::Get,
4    frame_support::dispatch::DispatchResult,
5    polkadot_sdk_frame::prelude::OriginFor,
6    sp_runtime::{DispatchError, Percent},
7};
8
9use crate::{ensure, AccountIdOf, Allocators, Config, Error, Event};
10
11/// Adds a new allocator to the network, checking wether it's already registered.
12#[doc(hidden)]
13pub fn add_allocator<T: Config>(key: AccountIdOf<T>) -> DispatchResult {
14    ensure!(
15        !Allocators::<T>::contains_key(&key),
16        Error::<T>::AlreadyAllocator
17    );
18    Allocators::<T>::insert(key, ());
19    Ok(())
20}
21
22/// Removes an existing allocator to the network, checking wether it's registered.
23#[doc(hidden)]
24pub fn remove_allocator<T: Config>(key: AccountIdOf<T>) -> DispatchResult {
25    ensure!(
26        Allocators::<T>::contains_key(&key),
27        Error::<T>::NotAllocator
28    );
29    Allocators::<T>::remove(&key);
30    Ok(())
31}
32
33/// Sets a penalty ratio for the given agent.
34pub fn penalize_agent<T: Config>(
35    origin: OriginFor<T>,
36    agent_key: AccountIdOf<T>,
37    percentage: u8,
38) -> DispatchResult {
39    let curator = <T as Config>::Permission0::ensure_curator_permission(
40        origin,
41        CuratorPermissions::PENALTY_CONTROL,
42    )?;
43
44    let percentage = Percent::from_parts(percentage);
45    if percentage > T::MaxPenaltyPercentage::get() {
46        return Err(Error::<T>::InvalidPenaltyPercentage.into());
47    }
48
49    pallet_torus0::Agents::<T>::try_mutate(&agent_key, |agent| {
50        let Some(agent) = agent else {
51            return Err(Error::<T>::AgentNotFound.into());
52        };
53
54        agent.weight_penalty_factor = percentage;
55
56        Ok::<(), DispatchError>(())
57    })?;
58
59    crate::Pallet::<T>::deposit_event(Event::PenaltyApplied {
60        curator,
61        agent: agent_key,
62        penalty: percentage,
63    });
64
65    Ok(())
66}
67
68/// Returns error if the origin is not listed as an allocator.
69pub fn ensure_allocator<T: Config>(key: &AccountIdOf<T>) -> DispatchResult {
70    if !crate::Allocators::<T>::contains_key(key) {
71        return Err(Error::<T>::NotAllocator.into());
72    }
73
74    Ok(())
75}