1
// Copyright (C) Parity Technologies (UK) Ltd.
2
// This file is part of Polkadot.
3

            
4
// Polkadot is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Polkadot is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
16

            
17
//! Custom origins for governance interventions.
18

            
19
pub use pallet_custom_origins::*;
20

            
21
1
#[frame_support::pallet]
22
pub mod pallet_custom_origins {
23
    use {
24
        crate::{Balance, CENTS, GRAND},
25
        frame_support::pallet_prelude::*,
26
    };
27

            
28
    #[pallet::config]
29
    pub trait Config: frame_system::Config {}
30

            
31
1
    #[pallet::pallet]
32
    pub struct Pallet<T>(_);
33

            
34
    #[derive(PartialEq, Eq, Clone, MaxEncodedLen, Encode, Decode, TypeInfo, RuntimeDebug)]
35
    #[pallet::origin]
36
    pub enum Origin {
37
        /// Origin for cancelling slashes.
38
        StakingAdmin,
39
        /// Origin for spending (any amount of) funds.
40
        Treasurer,
41
        /// Origin for managing the composition of the fellowship.
42
        FellowshipAdmin,
43
        /// Origin for managing the registrar.
44
        GeneralAdmin,
45
        /// Origin for starting auctions.
46
        AuctionAdmin,
47
        /// Origin able to force slot leases.
48
        LeaseAdmin,
49
        /// Origin able to cancel referenda.
50
        ReferendumCanceller,
51
        /// Origin able to kill referenda.
52
        ReferendumKiller,
53
        /// Origin able to spend up to 1 KSM from the treasury at once.
54
        SmallTipper,
55
        /// Origin able to spend up to 5 KSM from the treasury at once.
56
        BigTipper,
57
        /// Origin able to spend up to 50 KSM from the treasury at once.
58
        SmallSpender,
59
        /// Origin able to spend up to 500 KSM from the treasury at once.
60
        MediumSpender,
61
        /// Origin able to spend up to 5,000 KSM from the treasury at once.
62
        BigSpender,
63
        /// Origin able to dispatch a whitelisted call.
64
        WhitelistedCaller,
65
        /// Origin commanded by any members of the Polkadot Fellowship (no Dan grade needed).
66
        FellowshipInitiates,
67
        /// Origin commanded by Polkadot Fellows (3rd Dan fellows or greater).
68
        Fellows,
69
        /// Origin commanded by Polkadot Experts (5th Dan fellows or greater).
70
        FellowshipExperts,
71
        /// Origin commanded by Polkadot Masters (7th Dan fellows of greater).
72
        FellowshipMasters,
73
        /// Origin commanded by rank 1 of the Polkadot Fellowship and with a success of 1.
74
        Fellowship1Dan,
75
        /// Origin commanded by rank 2 of the Polkadot Fellowship and with a success of 2.
76
        Fellowship2Dan,
77
        /// Origin commanded by rank 3 of the Polkadot Fellowship and with a success of 3.
78
        Fellowship3Dan,
79
        /// Origin commanded by rank 4 of the Polkadot Fellowship and with a success of 4.
80
        Fellowship4Dan,
81
        /// Origin commanded by rank 5 of the Polkadot Fellowship and with a success of 5.
82
        Fellowship5Dan,
83
        /// Origin commanded by rank 6 of the Polkadot Fellowship and with a success of 6.
84
        Fellowship6Dan,
85
        /// Origin commanded by rank 7 of the Polkadot Fellowship and with a success of 7.
86
        Fellowship7Dan,
87
        /// Origin commanded by rank 8 of the Polkadot Fellowship and with a success of 8.
88
        Fellowship8Dan,
89
        /// Origin commanded by rank 9 of the Polkadot Fellowship and with a success of 9.
90
        Fellowship9Dan,
91
    }
92

            
93
    macro_rules! decl_unit_ensures {
94
		( $name:ident: $success_type:ty = $success:expr ) => {
95
			pub struct $name;
96
			impl<O: Into<Result<Origin, O>> + From<Origin>>
97
				EnsureOrigin<O> for $name
98
			{
99
				type Success = $success_type;
100
				fn try_origin(o: O) -> Result<Self::Success, O> {
101
					o.into().and_then(|o| match o {
102
						Origin::$name => Ok($success),
103
						r => Err(O::from(r)),
104
					})
105
				}
106
				#[cfg(feature = "runtime-benchmarks")]
107
				fn try_successful_origin() -> Result<O, ()> {
108
					Ok(O::from(Origin::$name))
109
				}
110
			}
111
		};
112
		( $name:ident ) => { decl_unit_ensures! { $name : () = () } };
113
		( $name:ident: $success_type:ty = $success:expr, $( $rest:tt )* ) => {
114
			decl_unit_ensures! { $name: $success_type = $success }
115
			decl_unit_ensures! { $( $rest )* }
116
		};
117
		( $name:ident, $( $rest:tt )* ) => {
118
			decl_unit_ensures! { $name }
119
			decl_unit_ensures! { $( $rest )* }
120
		};
121
		() => {}
122
	}
123
    decl_unit_ensures!(
124
        StakingAdmin,
125
        Treasurer,
126
        FellowshipAdmin,
127
        GeneralAdmin,
128
        AuctionAdmin,
129
        LeaseAdmin,
130
        ReferendumCanceller,
131
        ReferendumKiller,
132
        WhitelistedCaller,
133
        FellowshipInitiates: u16 = 0,
134
        Fellows: u16 = 3,
135
        FellowshipExperts: u16 = 5,
136
        FellowshipMasters: u16 = 7,
137
    );
138

            
139
    macro_rules! decl_ensure {
140
		(
141
			$vis:vis type $name:ident: EnsureOrigin<Success = $success_type:ty> {
142
				$( $item:ident = $success:expr, )*
143
			}
144
		) => {
145
			$vis struct $name;
146
			impl<O: Into<Result<Origin, O>> + From<Origin>>
147
				EnsureOrigin<O> for $name
148
			{
149
				type Success = $success_type;
150
				fn try_origin(o: O) -> Result<Self::Success, O> {
151
					o.into().and_then(|o| match o {
152
						$(
153
							Origin::$item => Ok($success),
154
						)*
155
						r => Err(O::from(r)),
156
					})
157
				}
158
				#[cfg(feature = "runtime-benchmarks")]
159
				fn try_successful_origin() -> Result<O, ()> {
160
					// By convention the more privileged origins go later, so for greatest chance
161
					// of success, we want the last one.
162
					let _result: Result<O, ()> = Err(());
163
					$(
164
						let _result: Result<O, ()> = Ok(O::from(Origin::$item));
165
					)*
166
					_result
167
				}
168
			}
169
		}
170
	}
171

            
172
    decl_ensure! {
173
        pub type Spender: EnsureOrigin<Success = Balance> {
174
            SmallTipper = 250 * 3 * CENTS,
175
            BigTipper = 1 * GRAND,
176
            SmallSpender = 10 * GRAND,
177
            MediumSpender = 100 * GRAND,
178
            BigSpender = 1_000 * GRAND,
179
            Treasurer = 10_000 * GRAND,
180
        }
181
    }
182

            
183
    decl_ensure! {
184
        pub type EnsureFellowship: EnsureOrigin<Success = u16> {
185
            Fellowship1Dan = 1,
186
            Fellowship2Dan = 2,
187
            Fellowship3Dan = 3,
188
            Fellowship4Dan = 4,
189
            Fellowship5Dan = 5,
190
            Fellowship6Dan = 6,
191
            Fellowship7Dan = 7,
192
            Fellowship8Dan = 8,
193
            Fellowship9Dan = 9,
194
        }
195
    }
196
}