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
//! Track configurations for governance.
18

            
19
use super::*;
20

            
21
const fn percent(x: i32) -> sp_arithmetic::FixedI64 {
22
    sp_arithmetic::FixedI64::from_rational(x as u128, 100)
23
}
24
use pallet_referenda::Curve;
25
const APP_ROOT: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
26
const SUP_ROOT: Curve = Curve::make_linear(28, 28, percent(0), percent(50));
27
const APP_STAKING_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
28
const SUP_STAKING_ADMIN: Curve =
29
    Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
30
const APP_TREASURER: Curve = Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
31
const SUP_TREASURER: Curve = Curve::make_linear(28, 28, percent(0), percent(50));
32
const APP_FELLOWSHIP_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
33
const SUP_FELLOWSHIP_ADMIN: Curve =
34
    Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
35
const APP_GENERAL_ADMIN: Curve =
36
    Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
37
const SUP_GENERAL_ADMIN: Curve =
38
    Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50));
39
const APP_AUCTION_ADMIN: Curve =
40
    Curve::make_reciprocal(4, 28, percent(80), percent(50), percent(100));
41
const SUP_AUCTION_ADMIN: Curve =
42
    Curve::make_reciprocal(7, 28, percent(10), percent(0), percent(50));
43
const APP_LEASE_ADMIN: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
44
const SUP_LEASE_ADMIN: Curve = Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
45
const APP_REFERENDUM_CANCELLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
46
const SUP_REFERENDUM_CANCELLER: Curve =
47
    Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
48
const APP_REFERENDUM_KILLER: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
49
const SUP_REFERENDUM_KILLER: Curve =
50
    Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
51
const APP_SMALL_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100));
52
const SUP_SMALL_TIPPER: Curve = Curve::make_reciprocal(1, 28, percent(4), percent(0), percent(50));
53
const APP_BIG_TIPPER: Curve = Curve::make_linear(10, 28, percent(50), percent(100));
54
const SUP_BIG_TIPPER: Curve = Curve::make_reciprocal(8, 28, percent(1), percent(0), percent(50));
55
const APP_SMALL_SPENDER: Curve = Curve::make_linear(17, 28, percent(50), percent(100));
56
const SUP_SMALL_SPENDER: Curve =
57
    Curve::make_reciprocal(12, 28, percent(1), percent(0), percent(50));
58
const APP_MEDIUM_SPENDER: Curve = Curve::make_linear(23, 28, percent(50), percent(100));
59
const SUP_MEDIUM_SPENDER: Curve =
60
    Curve::make_reciprocal(16, 28, percent(1), percent(0), percent(50));
61
const APP_BIG_SPENDER: Curve = Curve::make_linear(28, 28, percent(50), percent(100));
62
const SUP_BIG_SPENDER: Curve = Curve::make_reciprocal(20, 28, percent(1), percent(0), percent(50));
63
const APP_WHITELISTED_CALLER: Curve =
64
    Curve::make_reciprocal(16, 28 * 24, percent(96), percent(50), percent(100));
65
const SUP_WHITELISTED_CALLER: Curve =
66
    Curve::make_reciprocal(1, 28, percent(20), percent(5), percent(50));
67

            
68
const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 15] = [
69
    (
70
        0,
71
        pallet_referenda::TrackInfo {
72
            name: "root",
73
            max_deciding: 1,
74
            decision_deposit: 100 * GRAND,
75
            prepare_period: 8 * MINUTES,
76
            decision_period: 20 * MINUTES,
77
            confirm_period: 12 * MINUTES,
78
            min_enactment_period: 5 * MINUTES,
79
            min_approval: APP_ROOT,
80
            min_support: SUP_ROOT,
81
        },
82
    ),
83
    (
84
        1,
85
        pallet_referenda::TrackInfo {
86
            name: "whitelisted_caller",
87
            max_deciding: 100,
88
            decision_deposit: 10 * GRAND,
89
            prepare_period: 6 * MINUTES,
90
            decision_period: 20 * MINUTES,
91
            confirm_period: 4 * MINUTES,
92
            min_enactment_period: 3 * MINUTES,
93
            min_approval: APP_WHITELISTED_CALLER,
94
            min_support: SUP_WHITELISTED_CALLER,
95
        },
96
    ),
97
    (
98
        10,
99
        pallet_referenda::TrackInfo {
100
            name: "staking_admin",
101
            max_deciding: 10,
102
            decision_deposit: 5 * GRAND,
103
            prepare_period: 8 * MINUTES,
104
            decision_period: 20 * MINUTES,
105
            confirm_period: 8 * MINUTES,
106
            min_enactment_period: 3 * MINUTES,
107
            min_approval: APP_STAKING_ADMIN,
108
            min_support: SUP_STAKING_ADMIN,
109
        },
110
    ),
111
    (
112
        11,
113
        pallet_referenda::TrackInfo {
114
            name: "treasurer",
115
            max_deciding: 10,
116
            decision_deposit: 1 * GRAND,
117
            prepare_period: 8 * MINUTES,
118
            decision_period: 20 * MINUTES,
119
            confirm_period: 8 * MINUTES,
120
            min_enactment_period: 5 * MINUTES,
121
            min_approval: APP_TREASURER,
122
            min_support: SUP_TREASURER,
123
        },
124
    ),
125
    (
126
        12,
127
        pallet_referenda::TrackInfo {
128
            name: "lease_admin",
129
            max_deciding: 10,
130
            decision_deposit: 5 * GRAND,
131
            prepare_period: 8 * MINUTES,
132
            decision_period: 20 * MINUTES,
133
            confirm_period: 8 * MINUTES,
134
            min_enactment_period: 3 * MINUTES,
135
            min_approval: APP_LEASE_ADMIN,
136
            min_support: SUP_LEASE_ADMIN,
137
        },
138
    ),
139
    (
140
        13,
141
        pallet_referenda::TrackInfo {
142
            name: "fellowship_admin",
143
            max_deciding: 10,
144
            decision_deposit: 5 * GRAND,
145
            prepare_period: 8 * MINUTES,
146
            decision_period: 20 * MINUTES,
147
            confirm_period: 8 * MINUTES,
148
            min_enactment_period: 3 * MINUTES,
149
            min_approval: APP_FELLOWSHIP_ADMIN,
150
            min_support: SUP_FELLOWSHIP_ADMIN,
151
        },
152
    ),
153
    (
154
        14,
155
        pallet_referenda::TrackInfo {
156
            name: "general_admin",
157
            max_deciding: 10,
158
            decision_deposit: 5 * GRAND,
159
            prepare_period: 8 * MINUTES,
160
            decision_period: 20 * MINUTES,
161
            confirm_period: 8 * MINUTES,
162
            min_enactment_period: 3 * MINUTES,
163
            min_approval: APP_GENERAL_ADMIN,
164
            min_support: SUP_GENERAL_ADMIN,
165
        },
166
    ),
167
    (
168
        15,
169
        pallet_referenda::TrackInfo {
170
            name: "auction_admin",
171
            max_deciding: 10,
172
            decision_deposit: 5 * GRAND,
173
            prepare_period: 8 * MINUTES,
174
            decision_period: 20 * MINUTES,
175
            confirm_period: 8 * MINUTES,
176
            min_enactment_period: 3 * MINUTES,
177
            min_approval: APP_AUCTION_ADMIN,
178
            min_support: SUP_AUCTION_ADMIN,
179
        },
180
    ),
181
    (
182
        20,
183
        pallet_referenda::TrackInfo {
184
            name: "referendum_canceller",
185
            max_deciding: 1_000,
186
            decision_deposit: 10 * GRAND,
187
            prepare_period: 8 * MINUTES,
188
            decision_period: 14 * MINUTES,
189
            confirm_period: 8 * MINUTES,
190
            min_enactment_period: 3 * MINUTES,
191
            min_approval: APP_REFERENDUM_CANCELLER,
192
            min_support: SUP_REFERENDUM_CANCELLER,
193
        },
194
    ),
195
    (
196
        21,
197
        pallet_referenda::TrackInfo {
198
            name: "referendum_killer",
199
            max_deciding: 1_000,
200
            decision_deposit: 50 * GRAND,
201
            prepare_period: 8 * MINUTES,
202
            decision_period: 20 * MINUTES,
203
            confirm_period: 8 * MINUTES,
204
            min_enactment_period: 3 * MINUTES,
205
            min_approval: APP_REFERENDUM_KILLER,
206
            min_support: SUP_REFERENDUM_KILLER,
207
        },
208
    ),
209
    (
210
        30,
211
        pallet_referenda::TrackInfo {
212
            name: "small_tipper",
213
            max_deciding: 200,
214
            decision_deposit: 1 * 3 * CENTS,
215
            prepare_period: 1 * MINUTES,
216
            decision_period: 14 * MINUTES,
217
            confirm_period: 4 * MINUTES,
218
            min_enactment_period: 1 * MINUTES,
219
            min_approval: APP_SMALL_TIPPER,
220
            min_support: SUP_SMALL_TIPPER,
221
        },
222
    ),
223
    (
224
        31,
225
        pallet_referenda::TrackInfo {
226
            name: "big_tipper",
227
            max_deciding: 100,
228
            decision_deposit: 10 * 3 * CENTS,
229
            prepare_period: 4 * MINUTES,
230
            decision_period: 14 * MINUTES,
231
            confirm_period: 12 * MINUTES,
232
            min_enactment_period: 3 * MINUTES,
233
            min_approval: APP_BIG_TIPPER,
234
            min_support: SUP_BIG_TIPPER,
235
        },
236
    ),
237
    (
238
        32,
239
        pallet_referenda::TrackInfo {
240
            name: "small_spender",
241
            max_deciding: 50,
242
            decision_deposit: 100 * 3 * CENTS,
243
            prepare_period: 10 * MINUTES,
244
            decision_period: 20 * MINUTES,
245
            confirm_period: 10 * MINUTES,
246
            min_enactment_period: 5 * MINUTES,
247
            min_approval: APP_SMALL_SPENDER,
248
            min_support: SUP_SMALL_SPENDER,
249
        },
250
    ),
251
    (
252
        33,
253
        pallet_referenda::TrackInfo {
254
            name: "medium_spender",
255
            max_deciding: 50,
256
            decision_deposit: 200 * 3 * CENTS,
257
            prepare_period: 10 * MINUTES,
258
            decision_period: 20 * MINUTES,
259
            confirm_period: 12 * MINUTES,
260
            min_enactment_period: 5 * MINUTES,
261
            min_approval: APP_MEDIUM_SPENDER,
262
            min_support: SUP_MEDIUM_SPENDER,
263
        },
264
    ),
265
    (
266
        34,
267
        pallet_referenda::TrackInfo {
268
            name: "big_spender",
269
            max_deciding: 50,
270
            decision_deposit: 400 * 3 * CENTS,
271
            prepare_period: 10 * MINUTES,
272
            decision_period: 20 * MINUTES,
273
            confirm_period: 14 * MINUTES,
274
            min_enactment_period: 5 * MINUTES,
275
            min_approval: APP_BIG_SPENDER,
276
            min_support: SUP_BIG_SPENDER,
277
        },
278
    ),
279
];
280

            
281
pub struct TracksInfo;
282
impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
283
    type Id = u16;
284
    type RuntimeOrigin = <RuntimeOrigin as frame_support::traits::OriginTrait>::PalletsOrigin;
285
1
    fn tracks() -> &'static [(Self::Id, pallet_referenda::TrackInfo<Balance, BlockNumber>)] {
286
1
        &TRACKS_DATA[..]
287
1
    }
288
    fn track_for(id: &Self::RuntimeOrigin) -> Result<Self::Id, ()> {
289
        if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) {
290
            match system_origin {
291
                frame_system::RawOrigin::Root => Ok(0),
292
                _ => Err(()),
293
            }
294
        } else if let Ok(custom_origin) = origins::Origin::try_from(id.clone()) {
295
            match custom_origin {
296
                origins::Origin::WhitelistedCaller => Ok(1),
297
                // General admin
298
                origins::Origin::StakingAdmin => Ok(10),
299
                origins::Origin::Treasurer => Ok(11),
300
                origins::Origin::LeaseAdmin => Ok(12),
301
                origins::Origin::FellowshipAdmin => Ok(13),
302
                origins::Origin::GeneralAdmin => Ok(14),
303
                origins::Origin::AuctionAdmin => Ok(15),
304
                // Referendum admins
305
                origins::Origin::ReferendumCanceller => Ok(20),
306
                origins::Origin::ReferendumKiller => Ok(21),
307
                // Limited treasury spenders
308
                origins::Origin::SmallTipper => Ok(30),
309
                origins::Origin::BigTipper => Ok(31),
310
                origins::Origin::SmallSpender => Ok(32),
311
                origins::Origin::MediumSpender => Ok(33),
312
                origins::Origin::BigSpender => Ok(34),
313
                _ => Err(()),
314
            }
315
        } else {
316
            Err(())
317
        }
318
    }
319
}
320
pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber);