mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 21:49:26 +00:00
implement setting initial values for coins
This commit is contained in:
11
Cargo.lock
generated
11
Cargo.lock
generated
@@ -7329,6 +7329,7 @@ dependencies = [
|
|||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
"scale-info",
|
"scale-info",
|
||||||
"serai-coins-primitives",
|
"serai-coins-primitives",
|
||||||
|
"serai-genesis-liquidity-primitives",
|
||||||
"serai-in-instructions-primitives",
|
"serai-in-instructions-primitives",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
"serai-signals-primitives",
|
"serai-signals-primitives",
|
||||||
@@ -7527,6 +7528,9 @@ dependencies = [
|
|||||||
"serai-dex-pallet",
|
"serai-dex-pallet",
|
||||||
"serai-genesis-liquidity-primitives",
|
"serai-genesis-liquidity-primitives",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
|
"serai-validator-sets-primitives",
|
||||||
|
"sp-application-crypto",
|
||||||
|
"sp-core",
|
||||||
"sp-std",
|
"sp-std",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -7534,7 +7538,14 @@ dependencies = [
|
|||||||
name = "serai-genesis-liquidity-primitives"
|
name = "serai-genesis-liquidity-primitives"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"borsh",
|
||||||
|
"parity-scale-codec",
|
||||||
|
"scale-info",
|
||||||
"serai-primitives",
|
"serai-primitives",
|
||||||
|
"serai-validator-sets-primitives",
|
||||||
|
"serde",
|
||||||
|
"sp-std",
|
||||||
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ sp-consensus-grandpa = { git = "https://github.com/serai-dex/substrate" }
|
|||||||
serai-primitives = { path = "../primitives", version = "0.1" }
|
serai-primitives = { path = "../primitives", version = "0.1" }
|
||||||
serai-coins-primitives = { path = "../coins/primitives", version = "0.1" }
|
serai-coins-primitives = { path = "../coins/primitives", version = "0.1" }
|
||||||
serai-validator-sets-primitives = { path = "../validator-sets/primitives", version = "0.1" }
|
serai-validator-sets-primitives = { path = "../validator-sets/primitives", version = "0.1" }
|
||||||
|
serai-genesis-liquidity-primitives = { path = "../genesis-liquidity/primitives", version = "0.1" }
|
||||||
serai-in-instructions-primitives = { path = "../in-instructions/primitives", version = "0.1" }
|
serai-in-instructions-primitives = { path = "../in-instructions/primitives", version = "0.1" }
|
||||||
serai-signals-primitives = { path = "../signals/primitives", version = "0.1" }
|
serai-signals-primitives = { path = "../signals/primitives", version = "0.1" }
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@ borsh = [
|
|||||||
"serai-primitives/borsh",
|
"serai-primitives/borsh",
|
||||||
"serai-coins-primitives/borsh",
|
"serai-coins-primitives/borsh",
|
||||||
"serai-validator-sets-primitives/borsh",
|
"serai-validator-sets-primitives/borsh",
|
||||||
|
"serai-genesis-liquidity-primitives/borsh",
|
||||||
"serai-in-instructions-primitives/borsh",
|
"serai-in-instructions-primitives/borsh",
|
||||||
"serai-signals-primitives/borsh",
|
"serai-signals-primitives/borsh",
|
||||||
]
|
]
|
||||||
@@ -50,6 +52,7 @@ serde = [
|
|||||||
"serai-primitives/serde",
|
"serai-primitives/serde",
|
||||||
"serai-coins-primitives/serde",
|
"serai-coins-primitives/serde",
|
||||||
"serai-validator-sets-primitives/serde",
|
"serai-validator-sets-primitives/serde",
|
||||||
|
"serai-genesis-liquidity-primitives/serde",
|
||||||
"serai-in-instructions-primitives/serde",
|
"serai-in-instructions-primitives/serde",
|
||||||
"serai-signals-primitives/serde",
|
"serai-signals-primitives/serde",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
use serai_primitives::*;
|
use serai_primitives::*;
|
||||||
|
use serai_genesis_liquidity_primitives::*;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
|
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
|
||||||
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
|
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
|
||||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||||
pub enum Call {
|
pub enum Call {
|
||||||
remove_coin_liquidity { balance: Balance },
|
remove_coin_liquidity { balance: Balance },
|
||||||
|
set_initial_price { prices: Prices },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
|
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
|
||||||
|
|||||||
@@ -27,12 +27,15 @@ frame-system = { git = "https://github.com/serai-dex/substrate", default-feature
|
|||||||
frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
frame-support = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||||
|
|
||||||
sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||||
|
sp-core = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||||
|
sp-application-crypto = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||||
|
|
||||||
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false }
|
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false }
|
||||||
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false }
|
coins-pallet = { package = "serai-coins-pallet", path = "../../coins/pallet", default-features = false }
|
||||||
|
|
||||||
serai-primitives = { path = "../../primitives", default-features = false }
|
serai-primitives = { path = "../../primitives", default-features = false }
|
||||||
genesis-liquidity-primitives = { package = "serai-genesis-liquidity-primitives", path = "../primitives", default-features = false }
|
genesis-liquidity-primitives = { package = "serai-genesis-liquidity-primitives", path = "../primitives", default-features = false }
|
||||||
|
validator-sets-primitives = { package = "serai-validator-sets-primitives", path = "../../validator-sets/primitives", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std = [
|
std = [
|
||||||
@@ -43,12 +46,15 @@ std = [
|
|||||||
"frame-support/std",
|
"frame-support/std",
|
||||||
|
|
||||||
"sp-std/std",
|
"sp-std/std",
|
||||||
|
"sp-core/std",
|
||||||
|
"sp-application-crypto/std",
|
||||||
|
|
||||||
"coins-pallet/std",
|
"coins-pallet/std",
|
||||||
"dex-pallet/std",
|
"dex-pallet/std",
|
||||||
|
|
||||||
"serai-primitives/std",
|
"serai-primitives/std",
|
||||||
"genesis-liquidity-primitives/std",
|
"genesis-liquidity-primitives/std",
|
||||||
|
"validator-sets-primitives/std",
|
||||||
]
|
]
|
||||||
|
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
@@ -5,14 +5,20 @@
|
|||||||
pub mod pallet {
|
pub mod pallet {
|
||||||
use super::*;
|
use super::*;
|
||||||
use frame_system::{pallet_prelude::*, RawOrigin};
|
use frame_system::{pallet_prelude::*, RawOrigin};
|
||||||
use frame_support::{pallet_prelude::*, sp_runtime::SaturatedConversion};
|
use frame_support::{
|
||||||
|
pallet_prelude::*,
|
||||||
|
sp_runtime::{self, SaturatedConversion},
|
||||||
|
};
|
||||||
|
|
||||||
use sp_std::{vec, collections::btree_map::BTreeMap};
|
use sp_std::{vec, vec::Vec, collections::btree_map::BTreeMap};
|
||||||
|
use sp_core::sr25519::Signature;
|
||||||
|
use sp_application_crypto::RuntimePublic;
|
||||||
|
|
||||||
use dex_pallet::{Pallet as Dex, Config as DexConfig};
|
use dex_pallet::{Pallet as Dex, Config as DexConfig};
|
||||||
use coins_pallet::{Config as CoinsConfig, Pallet as Coins, AllowMint};
|
use coins_pallet::{Config as CoinsConfig, Pallet as Coins, AllowMint};
|
||||||
|
|
||||||
use serai_primitives::*;
|
use serai_primitives::*;
|
||||||
|
use validator_sets_primitives::{ValidatorSet, Session, musig_key};
|
||||||
pub use genesis_liquidity_primitives as primitives;
|
pub use genesis_liquidity_primitives as primitives;
|
||||||
use primitives::*;
|
use primitives::*;
|
||||||
|
|
||||||
@@ -26,6 +32,19 @@ pub mod pallet {
|
|||||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[pallet::genesis_config]
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode)]
|
||||||
|
pub struct GenesisConfig<T: Config> {
|
||||||
|
/// List of participants to place in the initial validator sets.
|
||||||
|
pub participants: Vec<T::AccountId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Config> Default for GenesisConfig<T> {
|
||||||
|
fn default() -> Self {
|
||||||
|
GenesisConfig { participants: Default::default() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[pallet::error]
|
#[pallet::error]
|
||||||
pub enum Error<T> {
|
pub enum Error<T> {
|
||||||
GenesisPeriodEnded,
|
GenesisPeriodEnded,
|
||||||
@@ -58,6 +77,20 @@ pub mod pallet {
|
|||||||
pub(crate) type EconomicSecurityReached<T: Config> =
|
pub(crate) type EconomicSecurityReached<T: Config> =
|
||||||
StorageMap<_, Identity, NetworkId, BlockNumberFor<T>, ValueQuery>;
|
StorageMap<_, Identity, NetworkId, BlockNumberFor<T>, ValueQuery>;
|
||||||
|
|
||||||
|
#[pallet::storage]
|
||||||
|
pub(crate) type Participants<T: Config> =
|
||||||
|
StorageMap<_, Identity, NetworkId, BoundedVec<PublicKey, ConstU32<150>>, ValueQuery>;
|
||||||
|
|
||||||
|
#[pallet::storage]
|
||||||
|
pub(crate) type Oracle<T: Config> = StorageMap<_, Identity, Coin, u64, ValueQuery>;
|
||||||
|
|
||||||
|
#[pallet::genesis_build]
|
||||||
|
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
|
||||||
|
fn build(&self) {
|
||||||
|
Participants::<T>::set(NetworkId::Serai, self.participants.clone().try_into().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[pallet::hooks]
|
#[pallet::hooks]
|
||||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
|
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
|
||||||
fn on_finalize(n: BlockNumberFor<T>) {
|
fn on_finalize(n: BlockNumberFor<T>) {
|
||||||
@@ -75,9 +108,14 @@ pub mod pallet {
|
|||||||
let mut pool_values = BTreeMap::new();
|
let mut pool_values = BTreeMap::new();
|
||||||
let mut total_value: u64 = 0;
|
let mut total_value: u64 = 0;
|
||||||
for coin in COINS {
|
for coin in COINS {
|
||||||
// TODO: following line is just a place holder till we get the actual coin value
|
if coin == Coin::Serai {
|
||||||
// in terms of btc.
|
continue;
|
||||||
let value = Dex::<T>::security_oracle_value(coin).unwrap_or(Amount(0)).0;
|
}
|
||||||
|
|
||||||
|
// initial coin value in terms of btc
|
||||||
|
let value = Oracle::<T>::get(coin);
|
||||||
|
|
||||||
|
// get the pool & individual address values
|
||||||
account_values.insert(coin, vec![]);
|
account_values.insert(coin, vec![]);
|
||||||
let mut pool_amount: u64 = 0;
|
let mut pool_amount: u64 = 0;
|
||||||
for (account, amount) in Liquidity::<T>::iter_prefix(coin) {
|
for (account, amount) in Liquidity::<T>::iter_prefix(coin) {
|
||||||
@@ -265,6 +303,50 @@ pub mod pallet {
|
|||||||
Self::deposit_event(Event::GenesisLiquidityRemoved { by: account.into(), balance });
|
Self::deposit_event(Event::GenesisLiquidityRemoved { by: account.into(), balance });
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A call to submit the initial coi values.
|
||||||
|
#[pallet::call_index(1)]
|
||||||
|
#[pallet::weight((0, DispatchClass::Operational))] // TODO
|
||||||
|
pub fn set_initial_price(
|
||||||
|
origin: OriginFor<T>,
|
||||||
|
prices: Prices,
|
||||||
|
_signature: Signature,
|
||||||
|
) -> DispatchResult {
|
||||||
|
ensure_none(origin)?;
|
||||||
|
|
||||||
|
// set the prices
|
||||||
|
Oracle::<T>::set(Coin::Bitcoin, prices.bitcoin);
|
||||||
|
Oracle::<T>::set(Coin::Monero, prices.monero);
|
||||||
|
Oracle::<T>::set(Coin::Ether, prices.ethereum);
|
||||||
|
Oracle::<T>::set(Coin::Dai, prices.dai);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pallet::validate_unsigned]
|
||||||
|
impl<T: Config> ValidateUnsigned for Pallet<T> {
|
||||||
|
type Call = Call<T>;
|
||||||
|
|
||||||
|
fn validate_unsigned(_: TransactionSource, call: &Self::Call) -> TransactionValidity {
|
||||||
|
match call {
|
||||||
|
Call::set_initial_price { ref prices, ref signature } => {
|
||||||
|
let set = ValidatorSet { network: NetworkId::Serai, session: Session(0) };
|
||||||
|
let signers = Participants::<T>::get(NetworkId::Serai);
|
||||||
|
|
||||||
|
if !musig_key(set, &signers).verify(&set_initial_price_message(&set, prices), signature) {
|
||||||
|
Err(InvalidTransaction::BadProof)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
ValidTransaction::with_tag_prefix("GenesisLiquidity")
|
||||||
|
.and_provides((0, set))
|
||||||
|
.longevity(u64::MAX)
|
||||||
|
.propagate(true)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
Call::remove_coin_liquidity { .. } => Err(InvalidTransaction::Call)?,
|
||||||
|
Call::__Ignore(_, _) => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,19 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
zeroize = { version = "^1.5", features = ["derive"], optional = true }
|
||||||
|
|
||||||
|
borsh = { version = "1", default-features = false, features = ["derive", "de_strict_order"], optional = true }
|
||||||
|
serde = { version = "1", default-features = false, features = ["derive", "alloc"], optional = true }
|
||||||
|
|
||||||
|
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive"] }
|
||||||
|
scale-info = { version = "2", default-features = false, features = ["derive"] }
|
||||||
|
|
||||||
|
sp-std = { git = "https://github.com/serai-dex/substrate", default-features = false }
|
||||||
|
|
||||||
serai-primitives = { path = "../../primitives", default-features = false }
|
serai-primitives = { path = "../../primitives", default-features = false }
|
||||||
|
validator-sets-primitives = { package = "serai-validator-sets-primitives", path = "../../validator-sets/primitives", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
std = [
|
std = ["serai-primitives/std", "validator-sets-primitives/std", "sp-std/std"]
|
||||||
"serai-primitives/std",
|
|
||||||
]
|
|
||||||
default = ["std"]
|
default = ["std"]
|
||||||
|
|||||||
@@ -2,7 +2,21 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
|
#[cfg(feature = "borsh")]
|
||||||
|
use borsh::{BorshSerialize, BorshDeserialize};
|
||||||
|
#[cfg(feature = "serde")]
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
|
use sp_std::vec::Vec;
|
||||||
|
|
||||||
|
use scale::{Encode, Decode, MaxEncodedLen};
|
||||||
|
use scale_info::TypeInfo;
|
||||||
|
|
||||||
use serai_primitives::*;
|
use serai_primitives::*;
|
||||||
|
use validator_sets_primitives::ValidatorSet;
|
||||||
|
|
||||||
// amount of blocks in 30 days for 6s per block.
|
// amount of blocks in 30 days for 6s per block.
|
||||||
pub const BLOCKS_PER_MONTH: u32 = 10 * 60 * 24 * 30;
|
pub const BLOCKS_PER_MONTH: u32 = 10 * 60 * 24 * 30;
|
||||||
@@ -15,3 +29,19 @@ pub const GENESIS_SRI: u64 = 100_000_000 * 10_u64.pow(8);
|
|||||||
|
|
||||||
// This is the account to hold and manage the genesis liquidity.
|
// This is the account to hold and manage the genesis liquidity.
|
||||||
pub const GENESIS_LIQUIDITY_ACCOUNT: SeraiAddress = system_address(b"Genesis-liquidity-account");
|
pub const GENESIS_LIQUIDITY_ACCOUNT: SeraiAddress = system_address(b"Genesis-liquidity-account");
|
||||||
|
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||||
|
#[cfg_attr(feature = "std", derive(Zeroize))]
|
||||||
|
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||||
|
pub struct Prices {
|
||||||
|
pub bitcoin: u64,
|
||||||
|
pub monero: u64,
|
||||||
|
pub ethereum: u64,
|
||||||
|
pub dai: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The message for the set_initial_price signature.
|
||||||
|
pub fn set_initial_price_message(set: &ValidatorSet, prices: &Prices) -> Vec<u8> {
|
||||||
|
(b"GenesisLiquidity-set_initial_price", set, prices).encode()
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use sc_service::ChainType;
|
|||||||
use serai_runtime::{
|
use serai_runtime::{
|
||||||
primitives::*, WASM_BINARY, BABE_GENESIS_EPOCH_CONFIG, RuntimeGenesisConfig, SystemConfig,
|
primitives::*, WASM_BINARY, BABE_GENESIS_EPOCH_CONFIG, RuntimeGenesisConfig, SystemConfig,
|
||||||
CoinsConfig, DexConfig, ValidatorSetsConfig, SignalsConfig, BabeConfig, GrandpaConfig,
|
CoinsConfig, DexConfig, ValidatorSetsConfig, SignalsConfig, BabeConfig, GrandpaConfig,
|
||||||
|
GenesisLiquidityConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type ChainSpec = sc_service::GenericChainSpec<RuntimeGenesisConfig>;
|
pub type ChainSpec = sc_service::GenericChainSpec<RuntimeGenesisConfig>;
|
||||||
@@ -60,6 +61,7 @@ fn devnet_genesis(
|
|||||||
.collect(),
|
.collect(),
|
||||||
participants: validators.clone(),
|
participants: validators.clone(),
|
||||||
},
|
},
|
||||||
|
genesis_liquidity: GenesisLiquidityConfig { participants: validators.clone() },
|
||||||
signals: SignalsConfig::default(),
|
signals: SignalsConfig::default(),
|
||||||
babe: BabeConfig {
|
babe: BabeConfig {
|
||||||
authorities: validators.iter().map(|validator| ((*validator).into(), 1)).collect(),
|
authorities: validators.iter().map(|validator| ((*validator).into(), 1)).collect(),
|
||||||
@@ -111,6 +113,7 @@ fn testnet_genesis(wasm_binary: &[u8], validators: Vec<&'static str>) -> Runtime
|
|||||||
.collect(),
|
.collect(),
|
||||||
participants: validators.clone(),
|
participants: validators.clone(),
|
||||||
},
|
},
|
||||||
|
genesis_liquidity: GenesisLiquidityConfig { participants: validators.clone() },
|
||||||
signals: SignalsConfig::default(),
|
signals: SignalsConfig::default(),
|
||||||
babe: BabeConfig {
|
babe: BabeConfig {
|
||||||
authorities: validators.iter().map(|validator| ((*validator).into(), 1)).collect(),
|
authorities: validators.iter().map(|validator| ((*validator).into(), 1)).collect(),
|
||||||
|
|||||||
Reference in New Issue
Block a user