make remove liquidity an authorized call

This commit is contained in:
akildemir
2024-04-17 13:54:23 +03:00
parent df774d153c
commit 7041dbeb0b
5 changed files with 43 additions and 60 deletions

View File

@@ -4,8 +4,7 @@ use serai_primitives::*;
#[cfg_attr(feature = "borsh", derive(borsh::BorshSerialize, borsh::BorshDeserialize))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum Call {
// This call is just a place holder so that abi works as expected.
empty_call,
remove_coin_liquidity { balance: Balance },
}
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]

View File

@@ -10,10 +10,7 @@ pub mod pallet {
use sp_std::{vec, collections::btree_map::BTreeMap};
use dex_pallet::{Pallet as Dex, Config as DexConfig};
use coins_pallet::{
primitives::{OutInstructionWithBalance, OutInstruction},
Config as CoinsConfig, Pallet as Coins, AllowMint,
};
use coins_pallet::{Config as CoinsConfig, Pallet as Coins, AllowMint};
use serai_primitives::*;
pub use genesis_liquidity_primitives as primitives;
@@ -165,12 +162,37 @@ pub mod pallet {
Ok(())
}
/// Remove the provided genesis liquidity for an account. If called pre-economic security era,
pub fn remove_coin_liquidity(
account: PublicKey,
balance: Balance,
out_address: ExternalAddress,
) -> DispatchResult {
/// Returns the number of blocks since the coin's network reached economic security first time.
/// If the network is yet to be reached that threshold, 0 is returned. And maximum of
/// `GENESIS_SRI_TRICKLE_FEED` returned.
fn blocks_since_ec_security(coin: &Coin) -> u64 {
let ec_security_block =
EconomicSecurityReached::<T>::get(coin.network()).saturated_into::<u64>();
let current = <frame_system::Pallet<T>>::block_number().saturated_into::<u64>();
if ec_security_block > 0 {
let diff = current - ec_security_block;
if diff > GENESIS_SRI_TRICKLE_FEED {
return GENESIS_SRI_TRICKLE_FEED;
}
return diff;
}
0
}
fn genesis_ended() -> bool {
<frame_system::Pallet<T>>::block_number() >= BLOCKS_PER_MONTH.into()
}
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Remove the provided genesis liquidity for an account.
#[pallet::call_index(0)]
#[pallet::weight((0, DispatchClass::Operational))] // TODO
pub fn remove_coin_liquidity(origin: OriginFor<T>, balance: Balance) -> DispatchResult {
let account = ensure_signed(origin)?;
let origin = RawOrigin::Signed(GENESIS_LIQUIDITY_ACCOUNT.into());
// check we are still in genesis period
@@ -232,13 +254,9 @@ pub mod pallet {
Err(Error::<T>::CanOnlyRemoveFullAmount)?;
}
// TODO: do internal transfer instead?
let origin = RawOrigin::Signed(GENESIS_LIQUIDITY_ACCOUNT.into());
let instruction = OutInstructionWithBalance {
instruction: OutInstruction { address: out_address, data: None },
balance,
};
Coins::<T>::burn_with_instruction(origin.into(), instruction)?;
// TODO: do external transfer instead for making it easier for the user?
// or do we even want to make it easier?
Coins::<T>::transfer(origin.into(), account, balance)?;
// save
Liquidity::<T>::set(balance.coin, account, None);
@@ -247,29 +265,6 @@ pub mod pallet {
Self::deposit_event(Event::GenesisLiquidityRemoved { by: account.into(), balance });
Ok(())
}
/// Returns the number of blocks since the coin's network reached economic security first time.
/// If the network is yet to be reached that threshold, 0 is returned. And maximum of
/// `GENESIS_SRI_TRICKLE_FEED` returned.
fn blocks_since_ec_security(coin: &Coin) -> u64 {
let ec_security_block =
EconomicSecurityReached::<T>::get(coin.network()).saturated_into::<u64>();
let current = <frame_system::Pallet<T>>::block_number().saturated_into::<u64>();
if ec_security_block > 0 {
let diff = current - ec_security_block;
if diff > GENESIS_SRI_TRICKLE_FEED {
return GENESIS_SRI_TRICKLE_FEED;
}
return diff;
}
0
}
fn genesis_ended() -> bool {
<frame_system::Pallet<T>>::block_number() >= BLOCKS_PER_MONTH.into()
}
}
}

View File

@@ -204,14 +204,9 @@ pub mod pallet {
}
}
}
InInstruction::GenesisLiquidity(ops) => match ops {
GenesisLiquidityOperation::Add(address, balance) => {
GenesisLiq::<T>::add_coin_liquidity(address.into(), balance)?;
}
GenesisLiquidityOperation::Remove(address, balance, out_address) => {
GenesisLiq::<T>::remove_coin_liquidity(address.into(), balance, out_address)?;
}
},
InInstruction::GenesisLiquidity(address) => {
GenesisLiq::<T>::add_coin_liquidity(address.into(), instruction.balance)?;
}
}
Ok(())
}

View File

@@ -71,15 +71,6 @@ pub enum DexCall {
Swap(Balance, OutAddress),
}
#[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 enum GenesisLiquidityOperation {
Add(SeraiAddress, Balance),
Remove(SeraiAddress, Balance, ExternalAddress),
}
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
#[cfg_attr(feature = "std", derive(Zeroize))]
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
@@ -87,7 +78,7 @@ pub enum GenesisLiquidityOperation {
pub enum InInstruction {
Transfer(SeraiAddress),
Dex(DexCall),
GenesisLiquidity(GenesisLiquidityOperation),
GenesisLiquidity(SeraiAddress),
}
#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug)]

View File

@@ -177,6 +177,9 @@ impl Contains<RuntimeCall> for CallFilter {
},
RuntimeCall::Dex(call) => !matches!(call, dex::Call::__Ignore(_, _)),
RuntimeCall::ValidatorSets(call) => !matches!(call, validator_sets::Call::__Ignore(_, _)),
RuntimeCall::GenesisLiquidity(call) => {
!matches!(call, genesis_liquidity::Call::__Ignore(_, _))
}
RuntimeCall::InInstructions(call) => !matches!(call, in_instructions::Call::__Ignore(_, _)),
RuntimeCall::Signals(call) => !matches!(call, signals::Call::__Ignore(_, _)),