pallet_static_price_provider/lib.rs
1// This file is part of Astar.
2
3// Copyright (C) Stake Technologies Pte.Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later
5
6// Astar is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// Astar is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with Astar. If not, see <http://www.gnu.org/licenses/>.
18
19//! # Static Price Provider Pallet
20//!
21//! A simple pallet that provides a static price for the native currency.
22//! This is a temporary solution before oracle is implemented & operational.
23//!
24//! ## Overview
25//!
26//! The Static Price Provider pallet provides functionality for setting the active native currency price via privileged call.
27//! Only the root can set the price.
28//!
29//! Network maintainers must ensure to update the price at appropriate times so that inflation & dApp Staking rewards are calculated correctly.
30
31#![cfg_attr(not(feature = "std"), no_std)]
32
33use frame_support::pallet_prelude::*;
34use frame_system::{ensure_root, pallet_prelude::*};
35pub use pallet::*;
36use sp_arithmetic::{fixed_point::FixedU128, traits::Zero};
37use sp_std::marker::PhantomData;
38
39use astar_primitives::oracle::PriceProvider;
40
41#[cfg(test)]
42mod mock;
43#[cfg(test)]
44mod tests;
45
46#[frame_support::pallet]
47pub mod pallet {
48
49 use super::*;
50
51 /// The current storage version.
52 pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
53
54 #[pallet::pallet]
55 #[pallet::storage_version(STORAGE_VERSION)]
56 pub struct Pallet<T>(PhantomData<T>);
57
58 #[pallet::config]
59 pub trait Config: frame_system::Config {}
60
61 #[pallet::event]
62 #[pallet::generate_deposit(pub(crate) fn deposit_event)]
63 pub enum Event<T: Config> {
64 /// New static native currency price has been set.
65 PriceSet { price: FixedU128 },
66 }
67
68 #[pallet::error]
69 pub enum Error<T> {
70 /// Zero is invalid value for the price (hopefully).
71 ZeroPrice,
72 }
73
74 /// Default value handler for active price.
75 /// This pallet is temporary and it's not worth bothering with genesis config.
76 pub struct DefaultActivePrice;
77 impl Get<FixedU128> for DefaultActivePrice {
78 fn get() -> FixedU128 {
79 FixedU128::from_rational(1, 10)
80 }
81 }
82
83 /// Current active native currency price.
84 #[pallet::storage]
85 #[pallet::whitelist_storage]
86 pub type ActivePrice<T: Config> = StorageValue<_, FixedU128, ValueQuery, DefaultActivePrice>;
87
88 #[pallet::call]
89 impl<T: Config> Pallet<T> {
90 /// Privileged action used to set the active native currency price.
91 ///
92 /// This is a temporary solution before oracle is implemented & operational.
93 #[pallet::call_index(0)]
94 #[pallet::weight(T::DbWeight::get().writes(1))]
95 pub fn force_set_price(origin: OriginFor<T>, price: FixedU128) -> DispatchResult {
96 ensure_root(origin)?;
97 ensure!(!price.is_zero(), Error::<T>::ZeroPrice);
98
99 ActivePrice::<T>::put(price);
100
101 Self::deposit_event(Event::<T>::PriceSet { price });
102
103 Ok(().into())
104 }
105 }
106
107 impl<T: Config> PriceProvider for Pallet<T> {
108 fn average_price() -> FixedU128 {
109 ActivePrice::<T>::get()
110 }
111 }
112}