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
#[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
163
    #[pallet::pallet]
32
    pub struct Pallet<T>(_);
33

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

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

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

            
182
    decl_ensure! {
183
        pub type Spender: EnsureOrigin<Success = Balance> {
184
            SmallTipper = 250 * 3 * CENTS,
185
            BigTipper = 1 * GRAND,
186
            SmallSpender = 10 * GRAND,
187
            MediumSpender = 100 * GRAND,
188
            BigSpender = 1_000 * GRAND,
189
            Treasurer = 10_000 * GRAND,
190
        }
191
    }
192

            
193
    decl_ensure! {
194
        pub type EnsureFellowship: EnsureOrigin<Success = u16> {
195
            Fellowship1Dan = 1,
196
            Fellowship2Dan = 2,
197
            Fellowship3Dan = 3,
198
            Fellowship4Dan = 4,
199
            Fellowship5Dan = 5,
200
            Fellowship6Dan = 6,
201
            Fellowship7Dan = 7,
202
            Fellowship8Dan = 8,
203
            Fellowship9Dan = 9,
204
        }
205
    }
206
}