fix last pr comments

This commit is contained in:
akildemir
2024-07-04 16:41:19 +03:00
parent ef703843a6
commit 1eee0a4d92
9 changed files with 138 additions and 93 deletions

1
Cargo.lock generated
View File

@@ -7998,6 +7998,7 @@ dependencies = [
"serai-coins-pallet", "serai-coins-pallet",
"serai-dex-pallet", "serai-dex-pallet",
"serai-genesis-liquidity-pallet", "serai-genesis-liquidity-pallet",
"serai-genesis-liquidity-primitives",
"serai-in-instructions-primitives", "serai-in-instructions-primitives",
"serai-primitives", "serai-primitives",
"serai-validator-sets-pallet", "serai-validator-sets-pallet",

View File

@@ -7,7 +7,7 @@ use primitives::*;
#[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, signature: Signature }, oraclize_values { prices: Prices, signature: Signature },
} }
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)] #[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]

View File

@@ -29,9 +29,9 @@ impl<'a> SeraiGenesisLiquidity<'a> {
.await .await
} }
pub fn set_initial_price(prices: Prices, signature: Signature) -> Transaction { pub fn oraclize_values(prices: Prices, signature: Signature) -> Transaction {
Serai::unsigned(serai_abi::Call::GenesisLiquidity( Serai::unsigned(serai_abi::Call::GenesisLiquidity(
serai_abi::genesis_liquidity::Call::set_initial_price { prices, signature }, serai_abi::genesis_liquidity::Call::oraclize_values { prices, signature },
)) ))
} }

View File

@@ -16,7 +16,7 @@ use serai_client::{
}; };
use serai_abi::{ use serai_abi::{
genesis_liquidity::primitives::{set_initial_price_message, Prices}, genesis_liquidity::primitives::{oraclize_values_message, Prices},
primitives::COINS, primitives::COINS,
}; };
@@ -101,7 +101,7 @@ async fn test_genesis_liquidity(serai: Serai) {
.unwrap(); .unwrap();
// set prices // set prices
let prices = Prices { bitcoin: 10u64.pow(8), monero: 184100, ethereum: 4785000, dai: 1500 }; let prices = Prices { monero: 184100, ethereum: 4785000, dai: 1500 };
set_prices(&serai, &prices).await; set_prices(&serai, &prices).await;
// wait little bit.. // wait little bit..
@@ -127,7 +127,7 @@ async fn test_genesis_liquidity(serai: Serai) {
let pool_btc = btc_addresses.iter().fold(0u128, |acc, value| acc + u128::from(value.1 .0)); let pool_btc = btc_addresses.iter().fold(0u128, |acc, value| acc + u128::from(value.1 .0));
let pool_xmr = xmr_addresses.iter().fold(0u128, |acc, value| acc + u128::from(value.1 .0)); let pool_xmr = xmr_addresses.iter().fold(0u128, |acc, value| acc + u128::from(value.1 .0));
let pool_btc_value = (pool_btc * u128::from(prices.bitcoin)) / 10u128.pow(8); let pool_btc_value = pool_btc;
let pool_xmr_value = (pool_xmr * u128::from(prices.monero)) / 10u128.pow(12); let pool_xmr_value = (pool_xmr * u128::from(prices.monero)) / 10u128.pow(12);
let total_value = pool_btc_value + pool_xmr_value; let total_value = pool_btc_value + pool_xmr_value;
@@ -176,7 +176,8 @@ async fn set_prices(serai: &Serai, prices: &Prices) {
// prepare a Musig tx to set the initial prices // prepare a Musig tx to set the initial prices
let pair = insecure_pair_from_name("Alice"); let pair = insecure_pair_from_name("Alice");
let public = pair.public(); let public = pair.public();
let set = ValidatorSet { session: Session(0), network: NetworkId::Serai }; // we publish the tx in set 2
let set = ValidatorSet { session: Session(2), network: NetworkId::Serai };
let public_key = <Ristretto as Ciphersuite>::read_G::<&[u8]>(&mut public.0.as_ref()).unwrap(); let public_key = <Ristretto as Ciphersuite>::read_G::<&[u8]>(&mut public.0.as_ref()).unwrap();
let secret_key = <Ristretto as Ciphersuite>::read_F::<&[u8]>( let secret_key = <Ristretto as Ciphersuite>::read_F::<&[u8]>(
@@ -195,13 +196,11 @@ async fn set_prices(serai: &Serai, prices: &Prices) {
&Schnorrkel::new(b"substrate"), &Schnorrkel::new(b"substrate"),
&HashMap::from([(threshold_keys.params().i(), threshold_keys.into())]), &HashMap::from([(threshold_keys.params().i(), threshold_keys.into())]),
), ),
&set_initial_price_message(&set, prices), &oraclize_values_message(&set, prices),
); );
// set initial prices // set initial prices
let _ = publish_tx( let _ =
serai, publish_tx(serai, &SeraiGenesisLiquidity::oraclize_values(*prices, Signature(sig.to_bytes())))
&SeraiGenesisLiquidity::set_initial_price(*prices, Signature(sig.to_bytes())), .await;
)
.await;
} }

View File

@@ -47,7 +47,7 @@ pub mod pallet {
pub enum Event<T: Config> { pub enum Event<T: Config> {
GenesisLiquidityAdded { by: SeraiAddress, balance: Balance }, GenesisLiquidityAdded { by: SeraiAddress, balance: Balance },
GenesisLiquidityRemoved { by: SeraiAddress, balance: Balance }, GenesisLiquidityRemoved { by: SeraiAddress, balance: Balance },
GenesisLiquidityAddedToPool { coin1: Balance, coin2: Balance }, GenesisLiquidityAddedToPool { coin1: Balance, sri: Amount },
EconomicSecurityReached { network: NetworkId }, EconomicSecurityReached { network: NetworkId },
} }
@@ -56,20 +56,12 @@ pub mod pallet {
/// Keeps shares and the amount of coins per account. /// Keeps shares and the amount of coins per account.
#[pallet::storage] #[pallet::storage]
pub(crate) type Liquidity<T: Config> = StorageDoubleMap< pub(crate) type Liquidity<T: Config> =
_, StorageDoubleMap<_, Identity, Coin, Blake2_128Concat, PublicKey, LiquidityAmount, OptionQuery>;
Identity,
Coin,
Blake2_128Concat,
PublicKey,
(SubstrateAmount, SubstrateAmount),
OptionQuery,
>;
/// Keeps the total shares and the total amount of coins per coin. /// Keeps the total shares and the total amount of coins per coin.
#[pallet::storage] #[pallet::storage]
pub(crate) type Supply<T: Config> = pub(crate) type Supply<T: Config> = StorageMap<_, Identity, Coin, LiquidityAmount, OptionQuery>;
StorageMap<_, Identity, Coin, (SubstrateAmount, SubstrateAmount), OptionQuery>;
#[pallet::storage] #[pallet::storage]
pub(crate) type EconomicSecurityReached<T: Config> = pub(crate) type EconomicSecurityReached<T: Config> =
@@ -83,7 +75,7 @@ pub mod pallet {
#[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_initialize(n: BlockNumberFor<T>) -> Weight {
#[cfg(feature = "fast-epoch")] #[cfg(feature = "fast-epoch")]
let final_block = 10u64; let final_block = 10u64;
@@ -115,9 +107,14 @@ pub mod pallet {
continue; continue;
}; };
let pool_amount = u128::from(Supply::<T>::get(coin).unwrap_or((0, 0)).1); let pool_amount =
let pool_value = pool_amount.saturating_mul(value.into()) / 10u128.pow(coin.decimals()); u128::from(Supply::<T>::get(coin).unwrap_or(LiquidityAmount::zero()).coins);
total_value = total_value.saturating_add(pool_value); let pool_value = pool_amount
.checked_mul(value.into())
.unwrap()
.checked_div(10u128.pow(coin.decimals()))
.unwrap();
total_value = total_value.checked_add(pool_value).unwrap();
pool_values.push((coin, pool_amount, pool_value)); pool_values.push((coin, pool_amount, pool_value));
} }
@@ -127,11 +124,18 @@ pub mod pallet {
for (i, (coin, pool_amount, pool_value)) in pool_values.into_iter().enumerate() { for (i, (coin, pool_amount, pool_value)) in pool_values.into_iter().enumerate() {
// whatever sri left for the last coin should be ~= it's ratio // whatever sri left for the last coin should be ~= it's ratio
let sri_amount = if i == (pool_values_len - 1) { let sri_amount = if i == (pool_values_len - 1) {
GENESIS_SRI - total_sri_distributed GENESIS_SRI.checked_sub(total_sri_distributed).unwrap()
} else { } else {
u64::try_from(u128::from(GENESIS_SRI).saturating_mul(pool_value) / total_value).unwrap() u64::try_from(
u128::from(GENESIS_SRI)
.checked_mul(pool_value)
.unwrap()
.checked_div(total_value)
.unwrap(),
)
.unwrap()
}; };
total_sri_distributed += sri_amount; total_sri_distributed = total_sri_distributed.checked_add(sri_amount).unwrap();
// we can't add 0 liquidity // we can't add 0 liquidity
if !(pool_amount > 0 && sri_amount > 0) { if !(pool_amount > 0 && sri_amount > 0) {
@@ -154,7 +158,7 @@ pub mod pallet {
// let everyone know about the event // let everyone know about the event
Self::deposit_event(Event::GenesisLiquidityAddedToPool { Self::deposit_event(Event::GenesisLiquidityAddedToPool {
coin1: Balance { coin, amount: Amount(u64::try_from(pool_amount).unwrap()) }, coin1: Balance { coin, amount: Amount(u64::try_from(pool_amount).unwrap()) },
coin2: Balance { coin: Coin::Serai, amount: Amount(sri_amount) }, sri: Amount(sri_amount),
}); });
} }
assert_eq!(total_sri_distributed, GENESIS_SRI); assert_eq!(total_sri_distributed, GENESIS_SRI);
@@ -169,6 +173,7 @@ pub mod pallet {
} }
// we accept we reached economic security once we can mint smallest amount of a network's coin // we accept we reached economic security once we can mint smallest amount of a network's coin
// TODO: move EconomicSecurity to a separate pallet
for coin in COINS { for coin in COINS {
let existing = EconomicSecurityReached::<T>::get(coin.network()); let existing = EconomicSecurityReached::<T>::get(coin.network());
if existing.is_none() && if existing.is_none() &&
@@ -178,6 +183,8 @@ pub mod pallet {
Self::deposit_event(Event::EconomicSecurityReached { network: coin.network() }); Self::deposit_event(Event::EconomicSecurityReached { network: coin.network() });
} }
} }
Weight::zero() // TODO
} }
} }
@@ -190,33 +197,37 @@ pub mod pallet {
Err(Error::<T>::GenesisPeriodEnded)?; Err(Error::<T>::GenesisPeriodEnded)?;
} }
// mint the coins
Coins::<T>::mint(GENESIS_LIQUIDITY_ACCOUNT.into(), balance)?;
// calculate new shares & supply // calculate new shares & supply
let (new_shares, new_supply) = if let Some(supply) = Supply::<T>::get(balance.coin) { let (new_liquidity, new_supply) = if let Some(supply) = Supply::<T>::get(balance.coin) {
// calculate amount of shares for this amount // calculate amount of shares for this amount
let shares = Self::mul_div(supply.0, balance.amount.0, supply.1)?; let shares = Self::mul_div(supply.shares, balance.amount.0, supply.coins)?;
// get new shares for this account // get new shares for this account
let existing = Liquidity::<T>::get(balance.coin, account).unwrap_or((0, 0)); let existing =
Liquidity::<T>::get(balance.coin, account).unwrap_or(LiquidityAmount::zero());
( (
( LiquidityAmount {
existing.0.checked_add(shares).ok_or(Error::<T>::AmountOverflowed)?, shares: existing.shares.checked_add(shares).ok_or(Error::<T>::AmountOverflowed)?,
existing.1.checked_add(balance.amount.0).ok_or(Error::<T>::AmountOverflowed)?, coins: existing
), .coins
( .checked_add(balance.amount.0)
supply.0.checked_add(shares).ok_or(Error::<T>::AmountOverflowed)?, .ok_or(Error::<T>::AmountOverflowed)?,
supply.1.checked_add(balance.amount.0).ok_or(Error::<T>::AmountOverflowed)?, },
), LiquidityAmount {
shares: supply.shares.checked_add(shares).ok_or(Error::<T>::AmountOverflowed)?,
coins: supply
.coins
.checked_add(balance.amount.0)
.ok_or(Error::<T>::AmountOverflowed)?,
},
) )
} else { } else {
let first_amounts = (GENESIS_LP_SHARES, balance.amount.0); let first_amount = LiquidityAmount { shares: GENESIS_LP_SHARES, coins: balance.amount.0 };
(first_amounts, first_amounts) (first_amount, first_amount)
}; };
// save // save
Liquidity::<T>::set(balance.coin, account, Some(new_shares)); Liquidity::<T>::set(balance.coin, account, Some(new_liquidity));
Supply::<T>::set(balance.coin, Some(new_supply)); Supply::<T>::set(balance.coin, Some(new_supply));
Self::deposit_event(Event::GenesisLiquidityAdded { by: account.into(), balance }); Self::deposit_event(Event::GenesisLiquidityAdded { by: account.into(), balance });
Ok(()) Ok(())
@@ -280,16 +291,16 @@ pub mod pallet {
let supply = Supply::<T>::get(balance.coin).ok_or(Error::<T>::NotEnoughLiquidity)?; let supply = Supply::<T>::get(balance.coin).ok_or(Error::<T>::NotEnoughLiquidity)?;
// check we are still in genesis period // check we are still in genesis period
let (new_shares, new_supply) = if Self::genesis_ended() { let (new_liquidity, new_supply) = if Self::genesis_ended() {
// see how much liq tokens we have // see how much liq tokens we have
let total_liq_tokens = let total_liq_tokens =
LiquidityTokens::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), Coin::Serai).0; LiquidityTokens::<T>::balance(GENESIS_LIQUIDITY_ACCOUNT.into(), Coin::Serai).0;
// get how much user wants to remove // get how much user wants to remove
let (user_shares, user_coins) = let LiquidityAmount { shares, coins } =
Liquidity::<T>::get(balance.coin, account).unwrap_or((0, 0)); Liquidity::<T>::get(balance.coin, account).unwrap_or(LiquidityAmount::zero());
let total_shares = Supply::<T>::get(balance.coin).unwrap_or((0, 0)).0; let total_shares = Supply::<T>::get(balance.coin).unwrap_or(LiquidityAmount::zero()).shares;
let user_liq_tokens = Self::mul_div(total_liq_tokens, user_shares, total_shares)?; let user_liq_tokens = Self::mul_div(total_liq_tokens, shares, total_shares)?;
let amount_to_remove = Self::mul_div(user_liq_tokens, balance.amount.0, GENESIS_LP_SHARES)?; let amount_to_remove = Self::mul_div(user_liq_tokens, balance.amount.0, GENESIS_LP_SHARES)?;
// remove liquidity from pool // remove liquidity from pool
@@ -308,18 +319,25 @@ pub mod pallet {
// burn the SRI if necessary // burn the SRI if necessary
// TODO: take into consideration movement between pools. // TODO: take into consideration movement between pools.
let mut sri = current_sri.0.saturating_sub(prev_sri.0); let mut sri: u64 = current_sri.0.saturating_sub(prev_sri.0);
let distance_to_full_pay = let distance_to_full_pay =
GENESIS_SRI_TRICKLE_FEED.saturating_sub(Self::blocks_since_ec_security().unwrap_or(0)); GENESIS_SRI_TRICKLE_FEED.saturating_sub(Self::blocks_since_ec_security().unwrap_or(0));
let burn_sri_amount = sri.saturating_mul(distance_to_full_pay) / GENESIS_SRI_TRICKLE_FEED; let burn_sri_amount = u64::try_from(
u128::from(sri)
.checked_mul(u128::from(distance_to_full_pay))
.ok_or(Error::<T>::AmountOverflowed)?
.checked_div(u128::from(GENESIS_SRI_TRICKLE_FEED))
.ok_or(Error::<T>::AmountOverflowed)?,
)
.map_err(|_| Error::<T>::AmountOverflowed)?;
Coins::<T>::burn( Coins::<T>::burn(
origin.clone().into(), origin.clone().into(),
Balance { coin: Coin::Serai, amount: Amount(burn_sri_amount) }, Balance { coin: Coin::Serai, amount: Amount(burn_sri_amount) },
)?; )?;
sri -= burn_sri_amount; sri = sri.checked_sub(burn_sri_amount).ok_or(Error::<T>::AmountOverflowed)?;
// transfer to owner // transfer to owner
let coin_out = current_coin.0 - prev_coin.0; let coin_out = current_coin.0.saturating_sub(prev_coin.0);
Coins::<T>::transfer( Coins::<T>::transfer(
origin.clone().into(), origin.clone().into(),
account, account,
@@ -333,14 +351,17 @@ pub mod pallet {
// return new amounts // return new amounts
( (
( LiquidityAmount {
user_shares.checked_sub(amount_to_remove).ok_or(Error::<T>::AmountOverflowed)?, shares: shares.checked_sub(amount_to_remove).ok_or(Error::<T>::AmountOverflowed)?,
user_coins.checked_sub(coin_out).ok_or(Error::<T>::AmountOverflowed)?, coins: coins.checked_sub(coin_out).ok_or(Error::<T>::AmountOverflowed)?,
), },
( LiquidityAmount {
supply.0.checked_sub(amount_to_remove).ok_or(Error::<T>::AmountOverflowed)?, shares: supply
supply.1.checked_sub(coin_out).ok_or(Error::<T>::AmountOverflowed)?, .shares
), .checked_sub(amount_to_remove)
.ok_or(Error::<T>::AmountOverflowed)?,
coins: supply.coins.checked_sub(coin_out).ok_or(Error::<T>::AmountOverflowed)?,
},
) )
} else { } else {
if balance.amount.0 != GENESIS_LP_SHARES { if balance.amount.0 != GENESIS_LP_SHARES {
@@ -353,23 +374,26 @@ pub mod pallet {
Coins::<T>::transfer( Coins::<T>::transfer(
origin.into(), origin.into(),
account, account,
Balance { coin: balance.coin, amount: Amount(existing.1) }, Balance { coin: balance.coin, amount: Amount(existing.coins) },
)?; )?;
( (
(0, 0), LiquidityAmount::zero(),
( LiquidityAmount {
supply.0.checked_sub(existing.0).ok_or(Error::<T>::AmountOverflowed)?, shares: supply
supply.1.checked_sub(existing.1).ok_or(Error::<T>::AmountOverflowed)?, .shares
), .checked_sub(existing.shares)
.ok_or(Error::<T>::AmountOverflowed)?,
coins: supply.coins.checked_sub(existing.coins).ok_or(Error::<T>::AmountOverflowed)?,
},
) )
}; };
// save // save
if new_shares.0 == 0 { if new_liquidity == LiquidityAmount::zero() {
Liquidity::<T>::set(balance.coin, account, None); Liquidity::<T>::set(balance.coin, account, None);
} else { } else {
Liquidity::<T>::set(balance.coin, account, Some(new_shares)); Liquidity::<T>::set(balance.coin, account, Some(new_liquidity));
} }
Supply::<T>::set(balance.coin, Some(new_supply)); Supply::<T>::set(balance.coin, Some(new_supply));
@@ -380,7 +404,7 @@ pub mod pallet {
/// A call to submit the initial coin values in terms of BTC. /// A call to submit the initial coin values in terms of BTC.
#[pallet::call_index(1)] #[pallet::call_index(1)]
#[pallet::weight((0, DispatchClass::Operational))] // TODO #[pallet::weight((0, DispatchClass::Operational))] // TODO
pub fn set_initial_price( pub fn oraclize_values(
origin: OriginFor<T>, origin: OriginFor<T>,
prices: Prices, prices: Prices,
_signature: Signature, _signature: Signature,
@@ -388,7 +412,7 @@ pub mod pallet {
ensure_none(origin)?; ensure_none(origin)?;
// set the prices // set the prices
Oracle::<T>::set(Coin::Bitcoin, Some(prices.bitcoin)); Oracle::<T>::set(Coin::Bitcoin, Some(10u64.pow(8)));
Oracle::<T>::set(Coin::Monero, Some(prices.monero)); Oracle::<T>::set(Coin::Monero, Some(prices.monero));
Oracle::<T>::set(Coin::Ether, Some(prices.ethereum)); Oracle::<T>::set(Coin::Ether, Some(prices.ethereum));
Oracle::<T>::set(Coin::Dai, Some(prices.dai)); Oracle::<T>::set(Coin::Dai, Some(prices.dai));
@@ -402,11 +426,14 @@ pub mod pallet {
fn validate_unsigned(_: TransactionSource, call: &Self::Call) -> TransactionValidity { fn validate_unsigned(_: TransactionSource, call: &Self::Call) -> TransactionValidity {
match call { match call {
Call::set_initial_price { ref prices, ref signature } => { Call::oraclize_values { ref prices, ref signature } => {
// TODO: if this is supposed to be called after a month, serai set won't still be let network = NetworkId::Serai;
// in the session 0? Ideally this should pull the session from Vs pallet? let Some(session) = ValidatorSets::<T>::session(network) else {
let set = ValidatorSet { network: NetworkId::Serai, session: Session(0) }; return Err(TransactionValidityError::from(InvalidTransaction::Custom(0)));
let signers = ValidatorSets::<T>::participants_for_latest_decided_set(NetworkId::Serai) };
let set = ValidatorSet { network, session };
let signers = ValidatorSets::<T>::participants_for_latest_decided_set(network)
.expect("no participant in the current set") .expect("no participant in the current set")
.into_iter() .into_iter()
.map(|(p, _)| p) .map(|(p, _)| p)
@@ -414,17 +441,17 @@ pub mod pallet {
// check this didn't get called before // check this didn't get called before
if Self::oraclization_is_done() { if Self::oraclization_is_done() {
Err(InvalidTransaction::Custom(0))?; Err(InvalidTransaction::Custom(1))?;
} }
// make sure signers settings the price at the end of the genesis period. // make sure signers settings the price at the end of the genesis period.
// we don't need this check for tests. // we don't need this check for tests.
#[cfg(not(feature = "fast-epoch"))] #[cfg(not(feature = "fast-epoch"))]
if <frame_system::Pallet<T>>::block_number().saturated_into::<u64>() < MONTHS { if <frame_system::Pallet<T>>::block_number().saturated_into::<u64>() < MONTHS {
Err(InvalidTransaction::Custom(1))?; Err(InvalidTransaction::Custom(2))?;
} }
if !musig_key(set, &signers).verify(&set_initial_price_message(&set, prices), signature) { if !musig_key(set, &signers).verify(&oraclize_values_message(&set, prices), signature) {
Err(InvalidTransaction::BadProof)?; Err(InvalidTransaction::BadProof)?;
} }

View File

@@ -28,13 +28,27 @@ pub const GENESIS_LIQUIDITY_ACCOUNT: SeraiAddress = system_address(b"Genesis-liq
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))] #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Prices { pub struct Prices {
pub bitcoin: u64,
pub monero: u64, pub monero: u64,
pub ethereum: u64, pub ethereum: u64,
pub dai: u64, pub dai: u64,
} }
/// The message for the set_initial_price signature. #[derive(Clone, Copy, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
pub fn set_initial_price_message(set: &ValidatorSet, prices: &Prices) -> Vec<u8> { #[cfg_attr(feature = "std", derive(Zeroize))]
(b"GenesisLiquidity-set_initial_price", set, prices).encode() #[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct LiquidityAmount {
pub shares: u64,
pub coins: u64,
}
impl LiquidityAmount {
pub fn zero() -> Self {
LiquidityAmount { shares: 0, coins: 0 }
}
}
/// The message for the oraclize_values signature.
pub fn oraclize_values_message(set: &ValidatorSet, prices: &Prices) -> Vec<u8> {
(b"GenesisLiquidity-oraclize_values", set, prices).encode()
} }

View File

@@ -33,6 +33,7 @@ frame-support = { git = "https://github.com/serai-dex/substrate", default-featur
serai-primitives = { path = "../../primitives", default-features = false } serai-primitives = { path = "../../primitives", default-features = false }
in-instructions-primitives = { package = "serai-in-instructions-primitives", path = "../primitives", default-features = false } in-instructions-primitives = { package = "serai-in-instructions-primitives", path = "../primitives", default-features = false }
genesis-liquidity-primitives = { package = "serai-genesis-liquidity-primitives", path = "../../genesis-liquidity/primitives", 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 }
dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false } dex-pallet = { package = "serai-dex-pallet", path = "../../dex/pallet", default-features = false }
@@ -55,6 +56,7 @@ std = [
"serai-primitives/std", "serai-primitives/std",
"in-instructions-primitives/std", "in-instructions-primitives/std",
"genesis-liquidity-primitives/std",
"coins-pallet/std", "coins-pallet/std",
"dex-pallet/std", "dex-pallet/std",

View File

@@ -19,6 +19,7 @@ pub mod pallet {
use sp_core::sr25519::Public; use sp_core::sr25519::Public;
use serai_primitives::{Coin, Amount, Balance}; use serai_primitives::{Coin, Amount, Balance};
use genesis_liquidity_primitives::GENESIS_LIQUIDITY_ACCOUNT;
use frame_support::pallet_prelude::*; use frame_support::pallet_prelude::*;
use frame_system::{pallet_prelude::*, RawOrigin}; use frame_system::{pallet_prelude::*, RawOrigin};
@@ -205,6 +206,7 @@ pub mod pallet {
} }
} }
InInstruction::GenesisLiquidity(address) => { InInstruction::GenesisLiquidity(address) => {
Coins::<T>::mint(GENESIS_LIQUIDITY_ACCOUNT.into(), instruction.balance)?;
GenesisLiq::<T>::add_coin_liquidity(address.into(), instruction.balance)?; GenesisLiq::<T>::add_coin_liquidity(address.into(), instruction.balance)?;
} }
} }

View File

@@ -93,8 +93,8 @@ impl From<Call> for RuntimeCall {
serai_abi::genesis_liquidity::Call::remove_coin_liquidity { balance } => { serai_abi::genesis_liquidity::Call::remove_coin_liquidity { balance } => {
RuntimeCall::GenesisLiquidity(genesis_liquidity::Call::remove_coin_liquidity { balance }) RuntimeCall::GenesisLiquidity(genesis_liquidity::Call::remove_coin_liquidity { balance })
} }
serai_abi::genesis_liquidity::Call::set_initial_price { prices, signature } => { serai_abi::genesis_liquidity::Call::oraclize_values { prices, signature } => {
RuntimeCall::GenesisLiquidity(genesis_liquidity::Call::set_initial_price { RuntimeCall::GenesisLiquidity(genesis_liquidity::Call::oraclize_values {
prices, prices,
signature, signature,
}) })
@@ -276,8 +276,8 @@ impl TryInto<Call> for RuntimeCall {
genesis_liquidity::Call::remove_coin_liquidity { balance } => { genesis_liquidity::Call::remove_coin_liquidity { balance } => {
serai_abi::genesis_liquidity::Call::remove_coin_liquidity { balance } serai_abi::genesis_liquidity::Call::remove_coin_liquidity { balance }
} }
genesis_liquidity::Call::set_initial_price { prices, signature } => { genesis_liquidity::Call::oraclize_values { prices, signature } => {
serai_abi::genesis_liquidity::Call::set_initial_price { prices, signature } serai_abi::genesis_liquidity::Call::oraclize_values { prices, signature }
} }
_ => Err(())?, _ => Err(())?,
}), }),