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}