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
use sp_runtime::str_array as s;
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: [pallet_referenda::Track<u16, Balance, BlockNumber>; 15] = [
69
    pallet_referenda::Track {
70
        id: 0,
71
        info: pallet_referenda::TrackInfo {
72
            name: s("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
    pallet_referenda::Track {
84
        id: 1,
85
        info: pallet_referenda::TrackInfo {
86
            name: s("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
    pallet_referenda::Track {
98
        id: 10,
99
        info: pallet_referenda::TrackInfo {
100
            name: s("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
    pallet_referenda::Track {
112
        id: 11,
113
        info: pallet_referenda::TrackInfo {
114
            name: s("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
    pallet_referenda::Track {
126
        id: 12,
127
        info: pallet_referenda::TrackInfo {
128
            name: s("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
    pallet_referenda::Track {
140
        id: 13,
141
        info: pallet_referenda::TrackInfo {
142
            name: s("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
    pallet_referenda::Track {
154
        id: 14,
155
        info: pallet_referenda::TrackInfo {
156
            name: s("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
    pallet_referenda::Track {
168
        id: 15,
169
        info: pallet_referenda::TrackInfo {
170
            name: s("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
    pallet_referenda::Track {
182
        id: 20,
183
        info: pallet_referenda::TrackInfo {
184
            name: s("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
    pallet_referenda::Track {
196
        id: 21,
197
        info: pallet_referenda::TrackInfo {
198
            name: s("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
    pallet_referenda::Track {
210
        id: 30,
211
        info: pallet_referenda::TrackInfo {
212
            name: s("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
    pallet_referenda::Track {
224
        id: 31,
225
        info: pallet_referenda::TrackInfo {
226
            name: s("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
    pallet_referenda::Track {
238
        id: 32,
239
        info: pallet_referenda::TrackInfo {
240
            name: s("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
    pallet_referenda::Track {
252
        id: 33,
253
        info: pallet_referenda::TrackInfo {
254
            name: s("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
    pallet_referenda::Track {
266
        id: 34,
267
        info: pallet_referenda::TrackInfo {
268
            name: s("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(
286
1
    ) -> impl Iterator<Item = Cow<'static, pallet_referenda::Track<Self::Id, Balance, BlockNumber>>>
287
1
    {
288
1
        TRACKS_DATA.iter().map(Cow::Borrowed)
289
1
    }
290
    fn track_for(id: &Self::RuntimeOrigin) -> Result<Self::Id, ()> {
291
        if let Ok(system_origin) = frame_system::RawOrigin::try_from(id.clone()) {
292
            match system_origin {
293
                frame_system::RawOrigin::Root => Ok(0),
294
                _ => Err(()),
295
            }
296
        } else if let Ok(custom_origin) = origins::Origin::try_from(id.clone()) {
297
            match custom_origin {
298
                origins::Origin::WhitelistedCaller => Ok(1),
299
                // General admin
300
                origins::Origin::StakingAdmin => Ok(10),
301
                origins::Origin::Treasurer => Ok(11),
302
                origins::Origin::LeaseAdmin => Ok(12),
303
                origins::Origin::FellowshipAdmin => Ok(13),
304
                origins::Origin::GeneralAdmin => Ok(14),
305
                origins::Origin::AuctionAdmin => Ok(15),
306
                // Referendum admins
307
                origins::Origin::ReferendumCanceller => Ok(20),
308
                origins::Origin::ReferendumKiller => Ok(21),
309
                // Limited treasury spenders
310
                origins::Origin::SmallTipper => Ok(30),
311
                origins::Origin::BigTipper => Ok(31),
312
                origins::Origin::SmallSpender => Ok(32),
313
                origins::Origin::MediumSpender => Ok(33),
314
                origins::Origin::BigSpender => Ok(34),
315
                _ => Err(()),
316
            }
317
        } else {
318
            Err(())
319
        }
320
    }
321
}