mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-12 05:59:23 +00:00
make remove liquidity an authorized call
This commit is contained in:
@@ -4,8 +4,7 @@ use serai_primitives::*;
|
|||||||
#[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 {
|
||||||
// This call is just a place holder so that abi works as expected.
|
remove_coin_liquidity { balance: Balance },
|
||||||
empty_call,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
|
#[derive(Clone, PartialEq, Eq, Debug, scale::Encode, scale::Decode, scale_info::TypeInfo)]
|
||||||
|
|||||||
@@ -10,10 +10,7 @@ pub mod pallet {
|
|||||||
use sp_std::{vec, collections::btree_map::BTreeMap};
|
use sp_std::{vec, collections::btree_map::BTreeMap};
|
||||||
|
|
||||||
use dex_pallet::{Pallet as Dex, Config as DexConfig};
|
use dex_pallet::{Pallet as Dex, Config as DexConfig};
|
||||||
use coins_pallet::{
|
use coins_pallet::{Config as CoinsConfig, Pallet as Coins, AllowMint};
|
||||||
primitives::{OutInstructionWithBalance, OutInstruction},
|
|
||||||
Config as CoinsConfig, Pallet as Coins, AllowMint,
|
|
||||||
};
|
|
||||||
|
|
||||||
use serai_primitives::*;
|
use serai_primitives::*;
|
||||||
pub use genesis_liquidity_primitives as primitives;
|
pub use genesis_liquidity_primitives as primitives;
|
||||||
@@ -165,12 +162,37 @@ pub mod pallet {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove the provided genesis liquidity for an account. If called pre-economic security era,
|
/// Returns the number of blocks since the coin's network reached economic security first time.
|
||||||
pub fn remove_coin_liquidity(
|
/// If the network is yet to be reached that threshold, 0 is returned. And maximum of
|
||||||
account: PublicKey,
|
/// `GENESIS_SRI_TRICKLE_FEED` returned.
|
||||||
balance: Balance,
|
fn blocks_since_ec_security(coin: &Coin) -> u64 {
|
||||||
out_address: ExternalAddress,
|
let ec_security_block =
|
||||||
) -> DispatchResult {
|
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());
|
let origin = RawOrigin::Signed(GENESIS_LIQUIDITY_ACCOUNT.into());
|
||||||
|
|
||||||
// check we are still in genesis period
|
// check we are still in genesis period
|
||||||
@@ -232,13 +254,9 @@ pub mod pallet {
|
|||||||
Err(Error::<T>::CanOnlyRemoveFullAmount)?;
|
Err(Error::<T>::CanOnlyRemoveFullAmount)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: do internal transfer instead?
|
// TODO: do external transfer instead for making it easier for the user?
|
||||||
let origin = RawOrigin::Signed(GENESIS_LIQUIDITY_ACCOUNT.into());
|
// or do we even want to make it easier?
|
||||||
let instruction = OutInstructionWithBalance {
|
Coins::<T>::transfer(origin.into(), account, balance)?;
|
||||||
instruction: OutInstruction { address: out_address, data: None },
|
|
||||||
balance,
|
|
||||||
};
|
|
||||||
Coins::<T>::burn_with_instruction(origin.into(), instruction)?;
|
|
||||||
|
|
||||||
// save
|
// save
|
||||||
Liquidity::<T>::set(balance.coin, account, None);
|
Liquidity::<T>::set(balance.coin, account, None);
|
||||||
@@ -247,29 +265,6 @@ pub mod pallet {
|
|||||||
Self::deposit_event(Event::GenesisLiquidityRemoved { by: account.into(), balance });
|
Self::deposit_event(Event::GenesisLiquidityRemoved { by: account.into(), balance });
|
||||||
Ok(())
|
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()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -204,14 +204,9 @@ pub mod pallet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InInstruction::GenesisLiquidity(ops) => match ops {
|
InInstruction::GenesisLiquidity(address) => {
|
||||||
GenesisLiquidityOperation::Add(address, balance) => {
|
GenesisLiq::<T>::add_coin_liquidity(address.into(), instruction.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)?;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,15 +71,6 @@ pub enum DexCall {
|
|||||||
Swap(Balance, OutAddress),
|
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)]
|
#[derive(Clone, PartialEq, Eq, Debug, Encode, Decode, MaxEncodedLen, TypeInfo)]
|
||||||
#[cfg_attr(feature = "std", derive(Zeroize))]
|
#[cfg_attr(feature = "std", derive(Zeroize))]
|
||||||
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
#[cfg_attr(feature = "borsh", derive(BorshSerialize, BorshDeserialize))]
|
||||||
@@ -87,7 +78,7 @@ pub enum GenesisLiquidityOperation {
|
|||||||
pub enum InInstruction {
|
pub enum InInstruction {
|
||||||
Transfer(SeraiAddress),
|
Transfer(SeraiAddress),
|
||||||
Dex(DexCall),
|
Dex(DexCall),
|
||||||
GenesisLiquidity(GenesisLiquidityOperation),
|
GenesisLiquidity(SeraiAddress),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug)]
|
#[derive(Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug)]
|
||||||
|
|||||||
@@ -177,6 +177,9 @@ impl Contains<RuntimeCall> for CallFilter {
|
|||||||
},
|
},
|
||||||
RuntimeCall::Dex(call) => !matches!(call, dex::Call::__Ignore(_, _)),
|
RuntimeCall::Dex(call) => !matches!(call, dex::Call::__Ignore(_, _)),
|
||||||
RuntimeCall::ValidatorSets(call) => !matches!(call, validator_sets::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::InInstructions(call) => !matches!(call, in_instructions::Call::__Ignore(_, _)),
|
||||||
RuntimeCall::Signals(call) => !matches!(call, signals::Call::__Ignore(_, _)),
|
RuntimeCall::Signals(call) => !matches!(call, signals::Call::__Ignore(_, _)),
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user