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
//! Elements of governance concerning the Dancelight Fellowship.
18

            
19
use {
20
    frame_support::traits::{MapSuccess, TryMapSuccess},
21
    sp_runtime::traits::{CheckedReduceBy, ConstU16, Replace, ReplaceWithDefault},
22
};
23

            
24
use {
25
    super::*,
26
    crate::{CENTS, DAYS},
27
};
28

            
29
parameter_types! {
30
    pub const AlarmInterval: BlockNumber = 1;
31
    pub const SubmissionDeposit: Balance = 0;
32
    pub const UndecidingTimeout: BlockNumber = 7 * DAYS;
33
}
34

            
35
pub struct TracksInfo;
36
impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
37
    type Id = u16;
38
    type RuntimeOrigin = <RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin;
39
1
    fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo<Balance, BlockNumber>)] {
40
        static DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 10] = [
41
            (
42
                0u16,
43
                pallet_referenda::TrackInfo {
44
                    name: "candidates",
45
                    max_deciding: 10,
46
                    decision_deposit: 100 * 3 * CENTS,
47
                    prepare_period: 30 * MINUTES,
48
                    decision_period: 7 * DAYS,
49
                    confirm_period: 30 * MINUTES,
50
                    min_enactment_period: 1 * MINUTES,
51
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
52
                        length: Perbill::from_percent(100),
53
                        floor: Perbill::from_percent(50),
54
                        ceil: Perbill::from_percent(100),
55
                    },
56
                    min_support: pallet_referenda::Curve::LinearDecreasing {
57
                        length: Perbill::from_percent(100),
58
                        floor: Perbill::from_percent(0),
59
                        ceil: Perbill::from_percent(50),
60
                    },
61
                },
62
            ),
63
            (
64
                1u16,
65
                pallet_referenda::TrackInfo {
66
                    name: "members",
67
                    max_deciding: 10,
68
                    decision_deposit: 10 * 3 * CENTS,
69
                    prepare_period: 30 * MINUTES,
70
                    decision_period: 7 * DAYS,
71
                    confirm_period: 30 * MINUTES,
72
                    min_enactment_period: 1 * MINUTES,
73
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
74
                        length: Perbill::from_percent(100),
75
                        floor: Perbill::from_percent(50),
76
                        ceil: Perbill::from_percent(100),
77
                    },
78
                    min_support: pallet_referenda::Curve::LinearDecreasing {
79
                        length: Perbill::from_percent(100),
80
                        floor: Perbill::from_percent(0),
81
                        ceil: Perbill::from_percent(50),
82
                    },
83
                },
84
            ),
85
            (
86
                2u16,
87
                pallet_referenda::TrackInfo {
88
                    name: "proficients",
89
                    max_deciding: 10,
90
                    decision_deposit: 10 * 3 * CENTS,
91
                    prepare_period: 30 * MINUTES,
92
                    decision_period: 7 * DAYS,
93
                    confirm_period: 30 * MINUTES,
94
                    min_enactment_period: 1 * MINUTES,
95
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
96
                        length: Perbill::from_percent(100),
97
                        floor: Perbill::from_percent(50),
98
                        ceil: Perbill::from_percent(100),
99
                    },
100
                    min_support: pallet_referenda::Curve::LinearDecreasing {
101
                        length: Perbill::from_percent(100),
102
                        floor: Perbill::from_percent(0),
103
                        ceil: Perbill::from_percent(50),
104
                    },
105
                },
106
            ),
107
            (
108
                3u16,
109
                pallet_referenda::TrackInfo {
110
                    name: "fellows",
111
                    max_deciding: 10,
112
                    decision_deposit: 10 * 3 * CENTS,
113
                    prepare_period: 30 * MINUTES,
114
                    decision_period: 7 * DAYS,
115
                    confirm_period: 30 * MINUTES,
116
                    min_enactment_period: 1 * MINUTES,
117
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
118
                        length: Perbill::from_percent(100),
119
                        floor: Perbill::from_percent(50),
120
                        ceil: Perbill::from_percent(100),
121
                    },
122
                    min_support: pallet_referenda::Curve::LinearDecreasing {
123
                        length: Perbill::from_percent(100),
124
                        floor: Perbill::from_percent(0),
125
                        ceil: Perbill::from_percent(50),
126
                    },
127
                },
128
            ),
129
            (
130
                4u16,
131
                pallet_referenda::TrackInfo {
132
                    name: "senior fellows",
133
                    max_deciding: 10,
134
                    decision_deposit: 10 * 3 * CENTS,
135
                    prepare_period: 30 * MINUTES,
136
                    decision_period: 7 * DAYS,
137
                    confirm_period: 30 * MINUTES,
138
                    min_enactment_period: 1 * MINUTES,
139
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
140
                        length: Perbill::from_percent(100),
141
                        floor: Perbill::from_percent(50),
142
                        ceil: Perbill::from_percent(100),
143
                    },
144
                    min_support: pallet_referenda::Curve::LinearDecreasing {
145
                        length: Perbill::from_percent(100),
146
                        floor: Perbill::from_percent(0),
147
                        ceil: Perbill::from_percent(50),
148
                    },
149
                },
150
            ),
151
            (
152
                5u16,
153
                pallet_referenda::TrackInfo {
154
                    name: "experts",
155
                    max_deciding: 10,
156
                    decision_deposit: 1 * 3 * CENTS,
157
                    prepare_period: 30 * MINUTES,
158
                    decision_period: 7 * DAYS,
159
                    confirm_period: 30 * MINUTES,
160
                    min_enactment_period: 1 * MINUTES,
161
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
162
                        length: Perbill::from_percent(100),
163
                        floor: Perbill::from_percent(50),
164
                        ceil: Perbill::from_percent(100),
165
                    },
166
                    min_support: pallet_referenda::Curve::LinearDecreasing {
167
                        length: Perbill::from_percent(100),
168
                        floor: Perbill::from_percent(0),
169
                        ceil: Perbill::from_percent(50),
170
                    },
171
                },
172
            ),
173
            (
174
                6u16,
175
                pallet_referenda::TrackInfo {
176
                    name: "senior experts",
177
                    max_deciding: 10,
178
                    decision_deposit: 1 * 3 * CENTS,
179
                    prepare_period: 30 * MINUTES,
180
                    decision_period: 7 * DAYS,
181
                    confirm_period: 30 * MINUTES,
182
                    min_enactment_period: 1 * MINUTES,
183
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
184
                        length: Perbill::from_percent(100),
185
                        floor: Perbill::from_percent(50),
186
                        ceil: Perbill::from_percent(100),
187
                    },
188
                    min_support: pallet_referenda::Curve::LinearDecreasing {
189
                        length: Perbill::from_percent(100),
190
                        floor: Perbill::from_percent(0),
191
                        ceil: Perbill::from_percent(50),
192
                    },
193
                },
194
            ),
195
            (
196
                7u16,
197
                pallet_referenda::TrackInfo {
198
                    name: "masters",
199
                    max_deciding: 10,
200
                    decision_deposit: 1 * 3 * CENTS,
201
                    prepare_period: 30 * MINUTES,
202
                    decision_period: 7 * DAYS,
203
                    confirm_period: 30 * MINUTES,
204
                    min_enactment_period: 1 * MINUTES,
205
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
206
                        length: Perbill::from_percent(100),
207
                        floor: Perbill::from_percent(50),
208
                        ceil: Perbill::from_percent(100),
209
                    },
210
                    min_support: pallet_referenda::Curve::LinearDecreasing {
211
                        length: Perbill::from_percent(100),
212
                        floor: Perbill::from_percent(0),
213
                        ceil: Perbill::from_percent(50),
214
                    },
215
                },
216
            ),
217
            (
218
                8u16,
219
                pallet_referenda::TrackInfo {
220
                    name: "senior masters",
221
                    max_deciding: 10,
222
                    decision_deposit: 1 * 3 * CENTS,
223
                    prepare_period: 30 * MINUTES,
224
                    decision_period: 7 * DAYS,
225
                    confirm_period: 30 * MINUTES,
226
                    min_enactment_period: 1 * MINUTES,
227
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
228
                        length: Perbill::from_percent(100),
229
                        floor: Perbill::from_percent(50),
230
                        ceil: Perbill::from_percent(100),
231
                    },
232
                    min_support: pallet_referenda::Curve::LinearDecreasing {
233
                        length: Perbill::from_percent(100),
234
                        floor: Perbill::from_percent(0),
235
                        ceil: Perbill::from_percent(50),
236
                    },
237
                },
238
            ),
239
            (
240
                9u16,
241
                pallet_referenda::TrackInfo {
242
                    name: "grand masters",
243
                    max_deciding: 10,
244
                    decision_deposit: 1 * 3 * CENTS,
245
                    prepare_period: 30 * MINUTES,
246
                    decision_period: 7 * DAYS,
247
                    confirm_period: 30 * MINUTES,
248
                    min_enactment_period: 1 * MINUTES,
249
                    min_approval: pallet_referenda::Curve::LinearDecreasing {
250
                        length: Perbill::from_percent(100),
251
                        floor: Perbill::from_percent(50),
252
                        ceil: Perbill::from_percent(100),
253
                    },
254
                    min_support: pallet_referenda::Curve::LinearDecreasing {
255
                        length: Perbill::from_percent(100),
256
                        floor: Perbill::from_percent(0),
257
                        ceil: Perbill::from_percent(50),
258
                    },
259
                },
260
            ),
261
        ];
262
1
        &DATA[..]
263
1
    }
264
    fn track_for(id: &Self::RuntimeOrigin) -> Result<Self::Id, ()> {
265
        use super::origins::Origin;
266

            
267
        #[cfg(feature = "runtime-benchmarks")]
268
        {
269
            // For benchmarks, we enable a root origin.
270
            // It is important that this is not available in production!
271
            let root: Self::RuntimeOrigin = frame_system::RawOrigin::Root.into();
272
            if &root == id {
273
                return Ok(9);
274
            }
275
        }
276

            
277
        match Origin::try_from(id.clone()) {
278
            Ok(Origin::FellowshipInitiates) => Ok(0),
279
            Ok(Origin::Fellowship1Dan) => Ok(1),
280
            Ok(Origin::Fellowship2Dan) => Ok(2),
281
            Ok(Origin::Fellowship3Dan) | Ok(Origin::Fellows) => Ok(3),
282
            Ok(Origin::Fellowship4Dan) => Ok(4),
283
            Ok(Origin::Fellowship5Dan) | Ok(Origin::FellowshipExperts) => Ok(5),
284
            Ok(Origin::Fellowship6Dan) => Ok(6),
285
            Ok(Origin::Fellowship7Dan | Origin::FellowshipMasters) => Ok(7),
286
            Ok(Origin::Fellowship8Dan) => Ok(8),
287
            Ok(Origin::Fellowship9Dan) => Ok(9),
288
            _ => Err(()),
289
        }
290
    }
291
}
292
pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber);
293

            
294
pub type FellowshipReferendaInstance = pallet_referenda::Instance2;
295

            
296
impl pallet_referenda::Config<FellowshipReferendaInstance> for Runtime {
297
    type WeightInfo = weights::pallet_referenda::SubstrateWeight<Runtime>;
298
    type RuntimeCall = RuntimeCall;
299
    type RuntimeEvent = RuntimeEvent;
300
    type Scheduler = Scheduler;
301
    type Currency = Balances;
302
    type SubmitOrigin =
303
        pallet_ranked_collective::EnsureMember<Runtime, FellowshipCollectiveInstance, 1>;
304
    type CancelOrigin = FellowshipExperts;
305
    type KillOrigin = FellowshipMasters;
306
    type Slash = Treasury;
307
    type Votes = pallet_ranked_collective::Votes;
308
    type Tally = pallet_ranked_collective::TallyOf<Runtime, FellowshipCollectiveInstance>;
309
    type SubmissionDeposit = SubmissionDeposit;
310
    type MaxQueued = ConstU32<100>;
311
    type UndecidingTimeout = UndecidingTimeout;
312
    type AlarmInterval = AlarmInterval;
313
    type Tracks = TracksInfo;
314
    type Preimages = Preimage;
315
}
316

            
317
pub type FellowshipCollectiveInstance = pallet_ranked_collective::Instance1;
318

            
319
impl pallet_ranked_collective::Config<FellowshipCollectiveInstance> for Runtime {
320
    type WeightInfo = weights::pallet_ranked_collective::SubstrateWeight<Runtime>;
321
    type RuntimeEvent = RuntimeEvent;
322
    // Adding is by any of:
323
    // - Root.
324
    // - the FellowshipAdmin origin.
325
    // - a Fellowship origin.
326
    type AddOrigin = MapSuccess<Self::PromoteOrigin, ReplaceWithDefault<()>>;
327
    // Promotion is by any of:
328
    // - Root can demote arbitrarily.
329
    // - the FellowshipAdmin origin (i.e. token holder referendum);
330
    // - a vote by the rank *above* the new rank.
331
    type PromoteOrigin = EitherOf<
332
        frame_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
333
        EitherOf<
334
            MapSuccess<FellowshipAdmin, Replace<ConstU16<9>>>,
335
            TryMapSuccess<origins::EnsureFellowship, CheckedReduceBy<ConstU16<1>>>,
336
        >,
337
    >;
338
    // Removing is by any of:
339
    // - Root can remove arbitrarily.
340
    // - the FellowshipAdmin origin (i.e. token holder referendum);
341
    // - a vote by the rank two above the current rank.
342
    type RemoveOrigin = Self::DemoteOrigin;
343
    // Demotion is by any of:
344
    // - Root can demote arbitrarily.
345
    // - the FellowshipAdmin origin (i.e. token holder referendum);
346
    // - a vote by the rank two above the current rank.
347
    type DemoteOrigin = EitherOf<
348
        frame_system::EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
349
        EitherOf<
350
            MapSuccess<FellowshipAdmin, Replace<ConstU16<9>>>,
351
            TryMapSuccess<origins::EnsureFellowship, CheckedReduceBy<ConstU16<2>>>,
352
        >,
353
    >;
354
    // Exchange is by any of:
355
    // - Root can exchange arbitrarily.
356
    // - the Fellows origin;
357
    type ExchangeOrigin =
358
        EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Fellows>;
359
    type Polls = FellowshipReferenda;
360
    type MinRankOfClass = sp_runtime::traits::Identity;
361
    type MemberSwappedHandler = ();
362
    type VoteWeight = pallet_ranked_collective::Geometric;
363
    type MaxMemberCount = ();
364
    #[cfg(feature = "runtime-benchmarks")]
365
    type BenchmarkSetup = ();
366
}