Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Settmint #448

Merged
merged 2 commits into from
Aug 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions lib-serml/serp/serp-treasury/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use sp_runtime::{
};
use sp_std::prelude::*;
use support::{
DEXManager, Price, PriceProvider, Ratio, SerpTreasury, SerpTreasuryExtended
DEXManager, PriceProvider, Ratio, SerpTreasury, SerpTreasuryExtended
};

mod mock;
Expand Down Expand Up @@ -105,10 +105,6 @@ pub mod module {
/// The price source of currencies
type PriceSource: PriceProvider<CurrencyId>;

/// The default price rate for all stablecurrencies, if `None` price is not returned
#[pallet::constant]
type DefaultPriceRate: Get<Price>;

#[pallet::constant]
/// The SERP Treasury's module id, keeps serplus and reserve asset.
type PalletId: Get<PalletId>;
Expand Down
2 changes: 0 additions & 2 deletions lib-serml/serp/serp-treasury/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,6 @@ parameter_types! {

pub SerpTesSchedule: BlockNumber = 60; // Triggers SERP-TES for serping after Every 60 blocks
pub MaxSlippageSwapWithDEX: Ratio = Ratio::one();
pub DefaultPriceRate: Price = Price::saturating_from_rational(1, 1);
}

parameter_type_with_key! {
Expand Down Expand Up @@ -276,7 +275,6 @@ impl Config for Runtime {
type Dex = SetheumDEX;
type MaxSlippageSwapWithDEX = MaxSlippageSwapWithDEX;
type PriceSource = MockPriceSource;
type DefaultPriceRate = DefaultPriceRate;
type PalletId = SerpTreasuryPalletId;
type WeightInfo = ();
}
Expand Down
2 changes: 1 addition & 1 deletion lib-serml/settmint/settmint-manager/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub mod module {

/// SERP Treasury for issuing/burning stable currency adjust standard value
/// adjustment
type SerpTreasury: SerpTreasury<Self::AccountId>;
type SerpTreasury: SerpTreasury<Self::AccountId, Balance = Balance, CurrencyId = CurrencyId>;

/// The setter's module id, keep all reserves of Settmint.
#[pallet::constant]
Expand Down
148 changes: 85 additions & 63 deletions lib-serml/settmint/settmint-manager/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ use super::*;
use frame_support::{construct_runtime, ord_parameter_types, parameter_types, PalletId};
use frame_system::EnsureSignedBy;
use orml_traits::parameter_type_with_key;
use primitives::TokenSymbol;
use primitives::{Amount, ReserveIdentifier, TokenSymbol, TradingPair};
use sp_core::H256;
use sp_runtime::{
testing::Header,
traits::{AccountIdConversion, IdentityLookup},
};
use support::StandardValidator;
use support::{Price, Ratio, StandardValidator};
use sp_std::cell::RefCell;

pub type AccountId = u128;
pub type BlockNumber = u64;
Expand Down Expand Up @@ -133,51 +134,100 @@ impl orml_currencies::Config for Runtime {
}
pub type AdaptedBasicCurrency = orml_currencies::BasicCurrencyAdapter<Runtime, PalletBalances, Amount, BlockNumber>;

parameter_types! {
pub const GetExchangeFee: (u32, u32) = (1, 100);
pub const DexPalletId: PalletId = PalletId(*b"set/sdex");
pub const TradingPathLimit: u32 = 3;
pub EnabledTradingPairs: Vec<TradingPair> = vec![
TradingPair::from_currency_ids(DNAR, SETT).unwrap(),
TradingPair::from_currency_ids(AUDJ, SETT).unwrap(),
TradingPair::from_currency_ids(CADJ, SETT).unwrap(),
TradingPair::from_currency_ids(CHFJ, SETT).unwrap(),
TradingPair::from_currency_ids(EURJ, SETT).unwrap(),
TradingPair::from_currency_ids(GBPJ, SETT).unwrap(),
TradingPair::from_currency_ids(JPYJ, SETT).unwrap(),
TradingPair::from_currency_ids(SARJ, SETT).unwrap(),
TradingPair::from_currency_ids(SEKJ, SETT).unwrap(),
TradingPair::from_currency_ids(SGDJ, SETT).unwrap(),
TradingPair::from_currency_ids(USDJ, SETT).unwrap(),
TradingPair::from_currency_ids(AUDJ, DNAR).unwrap(),
TradingPair::from_currency_ids(CADJ, DNAR).unwrap(),
TradingPair::from_currency_ids(CHFJ, DNAR).unwrap(),
TradingPair::from_currency_ids(EURJ, DNAR).unwrap(),
TradingPair::from_currency_ids(GBPJ, DNAR).unwrap(),
TradingPair::from_currency_ids(JPYJ, DNAR).unwrap(),
TradingPair::from_currency_ids(SARJ, DNAR).unwrap(),
TradingPair::from_currency_ids(SEKJ, DNAR).unwrap(),
TradingPair::from_currency_ids(SGDJ, DNAR).unwrap(),
TradingPair::from_currency_ids(USDJ, DNAR).unwrap(),
];
}

impl setheum_dex::Config for Runtime {
type Event = Event;
type Currency = Currencies;
type GetExchangeFee = GetExchangeFee;
type TradingPathLimit = TradingPathLimit;
type PalletId = DexPalletId;
type CurrencyIdMapping = ();
type WeightInfo = ();
type ListingOrigin = EnsureSignedBy<One, AccountId>;
}

thread_local! {
static RELATIVE_PRICE: RefCell<Option<Price>> = RefCell::new(Some(Price::one()));
}

pub struct MockPriceSource;
impl MockPriceSource {
pub fn set_relative_price(price: Option<Price>) {
RELATIVE_PRICE.with(|v| *v.borrow_mut() = price);
}
}
impl PriceProvider<CurrencyId> for MockPriceSource {

fn get_relative_price(_base: CurrencyId, _quota: CurrencyId) -> Option<Price> {
RELATIVE_PRICE.with(|v| *v.borrow_mut())
}

fn get_market_price(_currency_id: CurrencyId) -> Option<Price> {
Some(Price::one())
}

fn get_peg_price(_currency_id: CurrencyId) -> Option<Price> {
Some(Price::one())
}

fn get_setter_price() -> Option<Price> {
Some(Price::one())
}

fn get_price(_currency_id: CurrencyId) -> Option<Price> {
None
}

fn lock_price(_currency_id: CurrencyId) {}

fn unlock_price(_currency_id: CurrencyId) {}
}

ord_parameter_types! {
pub const One: AccountId = 1;
}

parameter_types! {
pub StableCurrencyIds: Vec<CurrencyId> = vec![
SETT,
AEDJ,
AUDJ,
BRLJ,
CADJ,
CHFJ,
CLPJ,
CNYJ,
COPJ,
EURJ,
GBPJ,
HKDJ,
HUFJ,
IDRJ,
JPYJ,
KESJ,
KRWJ,
KZTJ,
MXNJ,
MYRJ,
NGNJ,
NOKJ,
NZDJ,
PENJ,
PHPJ,
PKRJ,
PLNJ,
QARJ,
RONJ,
RUBJ,
SARJ,
SEKJ,
SGDJ,
THBJ,
TRYJ,
TWDJ,
TZSJ,
USDJ,
ZARJ,
];
pub const SetterCurrencyId: CurrencyId = SETT; // Setter currency ticker is SETT/
pub const GetSettUSDCurrencyId: CurrencyId = USDJ; // Setter currency ticker is USDJ/
Expand Down Expand Up @@ -251,44 +301,16 @@ impl StandardValidator<AccountId, CurrencyId, Balance, Balance> for MockStandard

parameter_types! {
pub StandardCurrencyIds: Vec<CurrencyId> = vec![
AEDJ,
AUDJ,
BRLJ,
AUDJ,
CADJ,
CHFJ,
CLPJ,
CNYJ,
COPJ,
EURJ,
GBPJ,
HKDJ,
HUFJ,
IDRJ,
JPYJ,
KESJ,
KRWJ,
KZTJ,
MXNJ,
MYRJ,
NGNJ,
NOKJ,
NZDJ,
PENJ,
PHPJ,
PKRJ,
PLNJ,
QARJ,
RONJ,
RUBJ,
SARJ,
SEKJ,
SGDJ,
THBJ,
TRYJ,
TWDJ,
TZSJ,
SARJ,
SEKJ,
SGDJ,
USDJ,
ZARJ,
];
pub const GetReserveCurrencyId: CurrencyId = SETT;
pub const SettmintManagerPalletId: PalletId = PalletId(*b"set/mint");
Expand All @@ -304,7 +326,6 @@ impl Config for Runtime {
type StandardValidator = MockStandardValidator;
type SerpTreasury = SerpTreasuryModule;
type PalletId = SettmintManagerPalletId;
type OnUpdateSettMint = ();
}

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
Expand All @@ -322,6 +343,7 @@ construct_runtime!(
PalletBalances: pallet_balances::{Pallet, Call, Storage, Event<T>},
Currencies: orml_currencies::{Pallet, Call, Event<T>},
SerpTreasuryModule: serp_treasury::{Pallet, Storage, Call, Event<T>},
SetheumDEX: setheum_dex::{Pallet, Storage, Call, Event<T>, Config<T>},
}
);

Expand Down
58 changes: 36 additions & 22 deletions lib-serml/settmint/settmint-manager/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,27 @@ use mock::{Event, *};
fn standards_key() {
ExtBuilder::default().build().execute_with(|| {
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0);
assert_ok!(SettmintManagerModule::adjust_position(&ALICE, EURJ, 100, 100));
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 100);
assert_ok!(SettmintManagerModule::adjust_position(&ALICE, EURJ, 200, 200));
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 200);
assert_eq!(Currencies::free_balance(EURJ, &SettmintManagerModule::account_id()), 200);
assert_ok!(SettmintManagerModule::adjust_position(&ALICE, EURJ, -100, -100));
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0);
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 100);
});
}

#[test]
fn check_update_reserve_overflow_work() {
fn check_update_position_underflow_work() {
ExtBuilder::default().build().execute_with(|| {
// reserve underflow
assert_noop!(
SettmintManagerModule::update_reserve(&ALICE, EURJ, -100, 0),
Error::<Runtime>::ReserveTooLow,
SettmintManagerModule::update_position(&ALICE, EURJ, -100, 0),
ArithmeticError::Underflow,
);

// standard underflow
assert_noop!(
SettmintManagerModule::update_reserve(&ALICE, EURJ, 0, -100),
Error::<Runtime>::StandardTooLow,
SettmintManagerModule::update_position(&ALICE, EURJ, 0, -100),
ArithmeticError::Underflow,
);
});
}
Expand All @@ -64,6 +65,12 @@ fn adjust_position_should_work() {
// mock can't pass position valid check
assert_eq!(SettmintManagerModule::adjust_position(&ALICE, USDJ, 500, 0).is_ok(), false);

// reserve_adjustment is positive
assert_noop!(
SettmintManagerModule::adjust_position(&ALICE, EURJ, 1000, 0),
orml_tokens::Error::<Runtime>::KeepAlive,
);

assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000);
assert_eq!(Currencies::free_balance(EURJ, &SettmintManagerModule::account_id()), 0);
assert_eq!(SettmintManagerModule::total_positions(EURJ).standard, 0);
Expand All @@ -81,34 +88,41 @@ fn adjust_position_should_work() {
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 300);
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 500);
assert_eq!(Currencies::free_balance(EURJ, &ALICE), 150);
System::assert_last_event(Event::SettmintManagerModule(crate::Event::PositionUpdated(ALICE, EURJ, 500, 300)));

System::assert_last_event(Event::settmint_manager(crate::Event::PositionUpdated(ALICE, EURJ, 500, 300)));
// reserve_adjustment is negatives
// remove module account.
assert_eq!(Currencies::total_balance(EURJ, &SettmintManagerModule::account_id()), 500);
assert_eq!(System::account_exists(&SettmintManagerModule::account_id()), true);
assert_ok!(SettmintManagerModule::adjust_position(&ALICE, EURJ, -500, 0));
assert_eq!(Currencies::free_balance(EURJ, &SettmintManagerModule::account_id()), 0);
assert_eq!(System::account_exists(&SettmintManagerModule::account_id()), false);
});
}

#[test]
fn transfer_reserve_should_work() {
fn transfer_position_should_work() {
ExtBuilder::default().build().execute_with(|| {
System::set_block_number(1);
assert_ok!(SettmintManagerModule::update_reserve(&ALICE, EURJ, 400, 500));
assert_ok!(SettmintManagerModule::update_reserve(&BOB, EURJ, 100, 600));
assert_ok!(SettmintManagerModule::update_position(&ALICE, EURJ, 400, 500));
assert_ok!(SettmintManagerModule::update_position(&BOB, EURJ, 100, 600));
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 500);
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 400);
assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).standard, 600);
assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).reserve, 100);

assert_ok!(SettmintManagerModule::transfer_reserve(&ALICE, &BOB, EURJ));
assert_ok!(SettmintManagerModule::transfer_position(&ALICE, &BOB, EURJ));
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0);
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 0);
assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).standard, 1100);
assert_eq!(SettmintManagerModule::positions(EURJ, &BOB).reserve, 500);

System::assert_last_event(Event::settmint_manager(crate::Event::TransferReserve(ALICE, BOB, EURJ)));
System::assert_last_event(Event::SettmintManagerModule(crate::Event::TransferPosition(ALICE, BOB, EURJ)));
});
}

#[test]
fn update_reserve_should_work() {
fn update_position_should_work() {
ExtBuilder::default().build().execute_with(|| {
assert_eq!(Currencies::free_balance(SETT, &SettmintManagerModule::account_id()), 0);
assert_eq!(Currencies::free_balance(SETT, &ALICE), 1000);
Expand All @@ -120,7 +134,7 @@ fn update_reserve_should_work() {

let alice_ref_count_0 = System::consumers(&ALICE);

assert_ok!(SettmintManagerModule::update_reserve(&ALICE, EURJ, 3000, 2000));
assert_ok!(SettmintManagerModule::update_position(&ALICE, EURJ, 3000, 2000));

// just update records
assert_eq!(SettmintManagerModule::total_positions(EURJ).standard, 2000);
Expand All @@ -138,7 +152,7 @@ fn update_reserve_should_work() {

// should remove position storage if zero
assert_eq!(<Positions<Runtime>>::contains_key(EURJ, &ALICE), true);
assert_ok!(SettmintManagerModule::update_reserve(&ALICE, EURJ, -3000, -2000));
assert_ok!(SettmintManagerModule::update_position(&ALICE, EURJ, -3000, -2000));
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).standard, 0);
assert_eq!(SettmintManagerModule::positions(EURJ, &ALICE).reserve, 0);
assert_eq!(<Positions<Runtime>>::contains_key(EURJ, &ALICE), false);
Expand All @@ -152,16 +166,16 @@ fn update_reserve_should_work() {
#[test]
fn total_reserve_works() {
ExtBuilder::default().build().execute_with(|| {
assert_eq!(SettmintManagerModule::total_reserve(0);
assert_ok!(Currencies::deposit(SETT,&SettmintManagerModule::account_id()), 10));
assert_eq!(SettmintManagerModule::total_reserve(10));
assert_eq!(SettmintManagerModule::total_reserve(), 10);
assert_ok!(Currencies::deposit(SETT, &SettmintManagerModule::account_id(), 10));
assert_eq!(SettmintManagerModule::total_reserve(), 10);
});
}

#[test]
fn get_total_reserve_works() {
ExtBuilder::default().build().execute_with(|| {
assert_ok!(SettmintManagerModule::deposit_setter(&ALICE, 500));
assert_eq!(SettmintManagerModule::get_total_reserve(500));
assert_ok!(Currencies::deposit(SETT, &ALICE, 500));
assert_eq!(SettmintManagerModule::get_total_reserve(), 500);
});
}