diff --git a/lib-serml/serp/serp-staking/README.md b/lib-serml/serp/serp-staking/README.md index 5d5a2dc27..a9a0ea431 100644 --- a/lib-serml/serp/serp-staking/README.md +++ b/lib-serml/serp/serp-staking/README.md @@ -148,7 +148,7 @@ decl_module! { #[weight = 0] pub fn reward_myself(origin) -> dispatch::DispatchResult { let reported = ensure_signed(origin)?; - >::reward_by_ids(vec![(reported, 10)]); + >::reward_by_ids(vec![(reported, 10)]); Ok(()) } } diff --git a/lib-serml/serp/serp-treasury/src/lib.rs b/lib-serml/serp/serp-treasury/src/lib.rs index 1102ef3fe..e3946e010 100644 --- a/lib-serml/serp/serp-treasury/src/lib.rs +++ b/lib-serml/serp/serp-treasury/src/lib.rs @@ -33,10 +33,7 @@ use frame_system::pallet_prelude::*; use orml_traits::{GetByKey, MultiCurrency, MultiCurrencyExtended}; use primitives::{Balance, CurrencyId}; use sp_runtime::{ - traits::{ - AccountIdConversion, Convert, - UniqueSaturatedInto, Zero, - }, + traits::{AccountIdConversion, Convert, Zero}, DispatchError, DispatchResult, }; use sp_std::{ @@ -46,12 +43,14 @@ use support::{ DEXManager, Price, PriceProvider, Ratio, SerpTreasury, SerpTreasuryExtended }; +mod price_to_balance_convertor; mod market_price_to_balance_convertor; mod peg_price_to_balance_convertor; mod mock; mod tests; pub mod weights; +pub use price_to_balance_convertor::PriceToBalanceConvertor; pub use market_price_to_balance_convertor::MarketPriceToBalanceConvertor; pub use peg_price_to_balance_convertor::PegPriceToBalanceConvertor; pub use module::*; @@ -182,10 +181,12 @@ pub mod module { // SERP TES (Token Elasticity of Supply). // Triggers Serping for all system stablecoins to stabilize stablecoin prices. let mut count: u32 = 0; - Self::setter_on_tes(); - count += 1; - Self::usdj_on_tes(); - count += 1; + if Self::setter_on_tes().is_ok() { + count += 1; + }; + if Self::usdj_on_tes().is_ok() { + count += 1; + } T::WeightInfo::on_initialize(count) } else { @@ -217,10 +218,10 @@ impl SerpTreasury for Pallet { currency_id, serping_amount, None, - ); + )?; // Burn Native Reserve asset (Dinar (DNAR)) - Self::burn_dinar(&Self::account_id(), serping_amount); + Self::burn_dinar(&Self::account_id(), serping_amount)?; >::deposit_event(Event::SerpUpDelivery(amount, currency_id)); Ok(()) @@ -234,7 +235,7 @@ impl SerpTreasury for Pallet { let six: Balance = 6; let serping_amount: Balance = six.saturating_mul(amount / 10); // Issue the SerpUp propper to the SettPayVault - Self::issue_propper(currency_id, &settpay_account, serping_amount); + Self::issue_propper(currency_id, &settpay_account, serping_amount)?; >::deposit_event(Event::SerpUpDelivery(amount, currency_id)); Ok(()) @@ -246,7 +247,7 @@ impl SerpTreasury for Pallet { // Charity Fund SerpUp Pool - 10% let serping_amount: Balance = amount / 10; // Issue the SerpUp propper to the SettPayVault - Self::issue_propper(currency_id, &charity_fund_account, serping_amount); + Self::issue_propper(currency_id, &charity_fund_account, serping_amount)?; >::deposit_event(Event::SerpUpDelivery(amount, currency_id)); Ok(()) @@ -260,6 +261,10 @@ impl SerpTreasury for Pallet { T::PriceSource::get_market_price(currency_id).unwrap_or_else(T::DefaultPriceRate::get) } + fn get_price_balance(currency_id: Self::CurrencyId) -> Price { + T::PriceSource::get_price(currency_id).unwrap_or_else(T::DefaultPriceRate::get) + } + fn get_peg_price_balance_value(currency_id: Self::CurrencyId, balance: Self::Balance) -> Self::Balance { crate::PegPriceToBalanceConvertor::::convert((currency_id, balance)) } @@ -268,6 +273,10 @@ impl SerpTreasury for Pallet { crate::MarketPriceToBalanceConvertor::::convert((currency_id, balance)) } + fn get_price_balance_value(currency_id: Self::CurrencyId, balance: Self::Balance) -> Self::Balance { + crate::PriceToBalanceConvertor::::convert((currency_id, balance)) + } + fn setter_on_tes() -> DispatchResult { let currency_id = T::SetterCurrencyId::get(); let one: Balance = 1; @@ -330,9 +339,9 @@ impl SerpTreasury for Pallet { !amount.is_zero(), Error::::InvalidAmount, ); - Self::get_buyback_serpup(amount, currency_id); - Self::get_settpay_serpup(amount, currency_id); - Self::get_charity_fund_serpup(amount, currency_id); + Self::get_buyback_serpup(amount, currency_id)?; + Self::get_settpay_serpup(amount, currency_id)?; + Self::get_charity_fund_serpup(amount, currency_id)?; >::deposit_event(Event::SerpUp(amount, currency_id)); Ok(()) @@ -365,13 +374,13 @@ impl SerpTreasury for Pallet { >::swap_dinar_to_exact_setter( amount, None, - ); + )?; } else { >::swap_setter_to_exact_settcurrency( currency_id, amount, None, - ); + )?; } >::deposit_event(Event::SerpDown(amount, currency_id)); @@ -444,39 +453,6 @@ impl SerpTreasury for Pallet { } impl SerpTreasuryExtended for Pallet { - /// Swap exact amount of Dinar to Setter, - /// return actual target Setter amount - fn swap_exact_dinar_to_setter( - supply_amount: Balance, - maybe_path: Option<&[CurrencyId]>, - ) -> sp_std::result::Result { - let dinar_currency_id = T::GetNativeCurrencyId::get(); - - let setter_currency_id = T::SetterCurrencyId::get(); - let default_swap_path = &[dinar_currency_id, setter_currency_id]; - let swap_path = match maybe_path { - None => default_swap_path, - Some(path) => { - let path_length = path.len(); - ensure!( - path_length >= 2 && path[0] == dinar_currency_id && path[path_length - 1] == setter_currency_id, - Error::::InvalidSwapPath - ); - path - } - }; - let price_impact_limit = Some(T::MaxSlippageSwapWithDEX::get()); - let Some(min_target_amount) = T::Dex::get_swap_target_amount(&swap_path, supply_amount, price_impact_limit).unwrap_or_else(T::Currency::minimum_balance(setter_currency_id)); - T::Currency::deposit(T::GetNativeCurrencyId::get(), &Self::account_id(), supply_amount)?; - T::Dex::swap_with_exact_supply( - &Self::account_id(), - swap_path, - supply_amount, - min_target_amount, - price_impact_limit, - ) - } - /// swap Dinar to get exact Setter, /// return actual supply Dinar amount fn swap_dinar_to_exact_setter( @@ -498,8 +474,18 @@ impl SerpTreasuryExtended for Pallet { path } }; + let one: Balance = 1; let price_impact_limit = Some(T::MaxSlippageSwapWithDEX::get()); - let Some(max_supply_amount) = T::Dex::get_swap_supply_amount(&swap_path, target_amount, price_impact_limit); + let dinar_price_into = Self::get_price_balance_value(dinar_currency_id, one); + let setter_price_into = Self::get_price_balance_value(setter_currency_id, one); + + // get a max_supply_amount of 105% of market value, marking the 5% slippage of `price_impact_limit`. + let relative_price = dinar_price_into / setter_price_into; + let max_supply_amount_full = target_amount / relative_price; + let max_supply_amount_fives = max_supply_amount_full / 20; + let max_supply_amount = max_supply_amount_fives * 21; + + // let Some(max_supply_amount) = T::Dex::get_swap_supply_amount(&swap_path, target_amount, price_impact_limit); T::Currency::deposit(dinar_currency_id, &Self::account_id(), max_supply_amount)?; T::Dex::swap_with_exact_target( &Self::account_id(), @@ -534,8 +520,18 @@ impl SerpTreasuryExtended for Pallet { path } }; + let one: Balance = 1; let price_impact_limit = Some(T::MaxSlippageSwapWithDEX::get()); - let Some(max_supply_amount) = T::Dex::get_swap_supply_amount(&swap_path, target_amount, price_impact_limit); + let setter_price_into = Self::get_price_balance_value(setter_currency_id, one); + let settcurrency_price_into = Self::get_price_balance_value(currency_id, one); + + // get a max_supply_amount of 105% of market value, marking the 5% slippage of `price_impact_limit`. + let relative_price = setter_price_into / settcurrency_price_into; + let max_supply_amount_full = target_amount / relative_price; + let max_supply_amount_fives = max_supply_amount_full / 20; + let max_supply_amount = max_supply_amount_fives * 21; + + // let Some(max_supply_amount) = T::Dex::get_swap_supply_amount(&swap_path, target_amount, price_impact_limit); T::Currency::deposit(setter_currency_id, &Self::account_id(), max_supply_amount)?; T::Dex::swap_with_exact_target( @@ -572,8 +568,18 @@ impl SerpTreasuryExtended for Pallet { path } }; + let one: Balance = 1; let price_impact_limit = Some(T::MaxSlippageSwapWithDEX::get()); - let Some(min_target_amount) = T::Dex::get_swap_target_amount(&swap_path, supply_amount, price_impact_limit).unwrap_or_else(T::Currency::minimum_balance(dinar_currency_id)); + let stablecurrency_price_into = Self::get_price_balance_value(currency_id, one); + let dinar_price_into = Self::get_price_balance_value(dinar_currency_id, one); + + // get a min_target_amount of 95% of market value, marking the 5% slippage of `price_impact_limit`. + let relative_price = dinar_price_into / stablecurrency_price_into; + let min_target_amount_full = supply_amount / relative_price; + let min_target_amount_fives = min_target_amount_full / 20; + let min_target_amount = min_target_amount_fives * 19; + + // let Some(min_target_amount) = T::Dex::get_swap_target_amount(&swap_path, supply_amount, price_impact_limit); T::Dex::swap_with_exact_supply( &Self::account_id(), swap_path, diff --git a/lib-serml/serp/serp-treasury/src/market_price_to_balance_convertor.rs b/lib-serml/serp/serp-treasury/src/market_price_to_balance_convertor.rs index bd0845bc3..4f76a289d 100644 --- a/lib-serml/serp/serp-treasury/src/market_price_to_balance_convertor.rs +++ b/lib-serml/serp/serp-treasury/src/market_price_to_balance_convertor.rs @@ -18,7 +18,6 @@ use super::*; use primitives::{Balance, CurrencyId}; -use support::Price; use sp_runtime::traits::Convert; use sp_runtime::FixedPointNumber; @@ -29,6 +28,6 @@ where T: Config, { fn convert((currency_id, balance): (CurrencyId, Balance)) -> Balance { - >::get_market_price_balance(currency_id).saturating_mul_int(balance) + <>::get_market_price_balance(currency_id).saturating_mul_int(balance) } } diff --git a/lib-serml/serp/serp-treasury/src/mock.rs b/lib-serml/serp/serp-treasury/src/mock.rs index 3ea4bd7ec..cf8f99c98 100644 --- a/lib-serml/serp/serp-treasury/src/mock.rs +++ b/lib-serml/serp/serp-treasury/src/mock.rs @@ -27,7 +27,6 @@ use orml_traits::parameter_type_with_key; use primitives::{Amount, ReserveIdentifier, TokenSymbol, TradingPair}; use sp_core::H256; use sp_runtime::{ - Permill, testing::Header, traits::{IdentityLookup, One as OneT, Zero}, DispatchError, FixedPointNumber, diff --git a/lib-serml/serp/serp-treasury/src/peg_price_to_balance_convertor.rs b/lib-serml/serp/serp-treasury/src/peg_price_to_balance_convertor.rs index 9d0716cfc..763b07393 100644 --- a/lib-serml/serp/serp-treasury/src/peg_price_to_balance_convertor.rs +++ b/lib-serml/serp/serp-treasury/src/peg_price_to_balance_convertor.rs @@ -18,7 +18,6 @@ use super::*; use primitives::{Balance, CurrencyId}; -use support::Price; use sp_runtime::traits::Convert; use sp_runtime::FixedPointNumber; @@ -29,6 +28,6 @@ where T: Config, { fn convert((currency_id, balance): (CurrencyId, Balance)) -> Balance { - >::get_peg_price_balance(currency_id).saturating_mul_int(balance) + <>::get_peg_price_balance(currency_id).saturating_mul_int(balance) } } diff --git a/lib-serml/serp/serp-treasury/src/price_to_balance_convertor.rs b/lib-serml/serp/serp-treasury/src/price_to_balance_convertor.rs new file mode 100644 index 000000000..6fa5dab88 --- /dev/null +++ b/lib-serml/serp/serp-treasury/src/price_to_balance_convertor.rs @@ -0,0 +1,33 @@ +// This file is part of Setheum. + +// Copyright (C) 2019-2021 Setheum Labs. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +use super::*; +use primitives::{Balance, CurrencyId}; +use sp_runtime::traits::Convert; +use sp_runtime::FixedPointNumber; + +pub struct PriceToBalanceConvertor(sp_std::marker::PhantomData); + +impl Convert<(CurrencyId, Balance), Balance> for PriceToBalanceConvertor +where + T: Config, +{ + fn convert((currency_id, balance): (CurrencyId, Balance)) -> Balance { + <>::get_price_balance(currency_id).saturating_mul_int(balance) + } +} diff --git a/lib-serml/settmint/settmint-engine/src/lib.rs b/lib-serml/settmint/settmint-engine/src/lib.rs index fdb31ab2b..e9e88f754 100644 --- a/lib-serml/settmint/settmint-engine/src/lib.rs +++ b/lib-serml/settmint/settmint-engine/src/lib.rs @@ -59,7 +59,7 @@ mod tests; pub use module::*; -pub type SettmintManagerOf = settmint_manager::Module; +pub type SettmintManagerOf = settmint_manager::; // typedef to help polkadot.js disambiguate Change with different generic // parameters diff --git a/lib-serml/settmint/settmint-engine/src/standard_exchange_rate_convertor.rs b/lib-serml/settmint/settmint-engine/src/standard_exchange_rate_convertor.rs index 7ce664d11..a9d915fb3 100644 --- a/lib-serml/settmint/settmint-engine/src/standard_exchange_rate_convertor.rs +++ b/lib-serml/settmint/settmint-engine/src/standard_exchange_rate_convertor.rs @@ -28,6 +28,6 @@ where T: Config, { fn convert((currency_id, balance): (CurrencyId, Balance)) -> Balance { - >::get_standard_exchange_rate(currency_id).saturating_mul_int(balance) + <>::get_standard_exchange_rate(currency_id).saturating_mul_int(balance) } } diff --git a/lib-serml/settmint/settmint-gateway/src/lib.rs b/lib-serml/settmint/settmint-gateway/src/lib.rs index f0018f6e7..e7f0883d8 100644 --- a/lib-serml/settmint/settmint-gateway/src/lib.rs +++ b/lib-serml/settmint/settmint-gateway/src/lib.rs @@ -130,7 +130,7 @@ pub mod module { standard_adjustment: Amount, ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; - >::adjust_position(&who, currency_id, reserve_adjustment, standard_adjustment)?; + >::adjust_position(&who, currency_id, reserve_adjustment, standard_adjustment)?; Ok(().into()) } @@ -150,7 +150,7 @@ pub mod module { let to = ensure_signed(origin)?; let from = T::Lookup::lookup(from)?; Self::check_authorization(&from, &to, currency_id)?; - >::transfer_reserve(&from, &to, currency_id)?; + >::transfer_reserve(&from, &to, currency_id)?; Ok(().into()) } diff --git a/lib-serml/support/src/lib.rs b/lib-serml/support/src/lib.rs index 4b1bd4b33..9d0000ccb 100644 --- a/lib-serml/support/src/lib.rs +++ b/lib-serml/support/src/lib.rs @@ -19,7 +19,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::upper_case_acronyms)] -use codec::{Decode, Encode, FullCodec, HasCompact}; +use codec::{Decode, Encode}; use frame_support::pallet_prelude::{DispatchClass, Pays, Weight}; use primitives::{ CurrencyId, @@ -32,9 +32,7 @@ use sp_runtime::{ DispatchError, DispatchResult, FixedU128, RuntimeDebug, }; use sp_std::{ - convert::{TryFrom, TryInto}, cmp::{Eq, PartialEq}, - fmt::Debug, prelude::*, }; @@ -61,14 +59,15 @@ impl Convert for () { Default::default() } } + /// Extensible conversion trait. Generic over both source and destination types. -pub trait ConvertPrice { +pub trait ConvertPrice { /// Make conversion. fn convert_price_to_balance(p: FixedU128) -> u128; } -impl ConvertPrice for () { - fn convert_price_to_balance(p: FixedU128) -> u128 { +impl ConvertPrice for () { + fn convert_price_to_balance(_p: FixedU128) -> u128 { Default::default() } } @@ -236,6 +235,9 @@ pub trait SerpTreasury { /// get the `market price` of a currency in converted `Balance` data type. fn get_market_price_balance(currency_id: Self::CurrencyId) -> Price; + /// get the `market price` of a currency in converted `Balance` data type. + fn get_price_balance(currency_id: Self::CurrencyId) -> Price; + /// get the balance value of the`peg_price` of a currency /// in converted `Balance` data type. fn get_peg_price_balance_value(currency_id: Self::CurrencyId, balance: Self::Balance) -> Self::Balance; @@ -244,6 +246,10 @@ pub trait SerpTreasury { /// in converted `Balance` data type. fn get_market_price_balance_value(currency_id: Self::CurrencyId, balance: Self::Balance) -> Self::Balance; + /// get the balance value of the`market price` of a currency + /// in converted `Balance` data type. + fn get_price_balance_value(currency_id: Self::CurrencyId, balance: Self::Balance) -> Self::Balance; + /// Trigger SERP-TES when required for Setter (SETT) to serp_down or serp_up. fn setter_on_tes() -> DispatchResult; @@ -300,12 +306,6 @@ pub trait SerpTreasury { } pub trait SerpTreasuryExtended: SerpTreasury { - // when setter needs serpdown - fn swap_exact_dinar_to_setter( - supply_amount: Self::Balance, - maybe_path: Option<&[Self::CurrencyId]>, - ) -> sp_std::result::Result; - // when setter needs serpdown fn swap_dinar_to_exact_setter( target_amount: Self::Balance,