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

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

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