diff --git a/node/primitives/src/currency.rs b/node/primitives/src/currency.rs index 03bb66b18..05d7614bf 100644 --- a/node/primitives/src/currency.rs +++ b/node/primitives/src/currency.rs @@ -304,6 +304,24 @@ impl From for CurrencyId { } impl CurrencyId { + #[allow(non_snake_case)] + pub const fn vsAssets( + symbol: TokenSymbol, + index: ParaId, + first_slot: LeasePeriod, + last_slot: LeasePeriod, + ) -> (Self, Self) { + let vsbond_origin = CurrencyId::VSBond(symbol, index, first_slot, last_slot); + + let vsbond_fixed = match vsbond_origin { + Self::VSBond(TokenSymbol::KSM, 2001, 13, 20) => + Self::VSBond(TokenSymbol::BNC, 2001, 13, 20), + _ => vsbond_origin, + }; + + (Self::VSToken(symbol), vsbond_fixed) + } + pub fn to_token(&self) -> Result { match self { Self::VToken(symbol) => Ok(Self::Token(symbol.clone())), diff --git a/pallets/liquidity-mining/src/lib.rs b/pallets/liquidity-mining/src/lib.rs index 6eab2f126..f9b4a0bf8 100644 --- a/pallets/liquidity-mining/src/lib.rs +++ b/pallets/liquidity-mining/src/lib.rs @@ -551,7 +551,8 @@ pub mod pallet { let _ = T::ControlOrigin::ensure_origin(origin)?; #[allow(non_snake_case)] - let trading_pair = Self::vsAssets(index, first_slot, last_slot); + let trading_pair = + CurrencyId::vsAssets(T::RelayChainTokenSymbol::get(), index, first_slot, last_slot); Self::create_pool( trading_pair, @@ -583,7 +584,8 @@ pub mod pallet { let _ = T::ControlOrigin::ensure_origin(origin)?; #[allow(non_snake_case)] - let trading_pair = Self::vsAssets(index, first_slot, last_slot); + let trading_pair = + CurrencyId::vsAssets(T::RelayChainTokenSymbol::get(), index, first_slot, last_slot); Self::create_pool( trading_pair, @@ -1099,20 +1101,6 @@ pub mod pallet { Ok(to_rewards) } - - #[allow(non_snake_case)] - pub(crate) fn vsAssets( - index: ParaId, - first_slot: LeasePeriod, - last_slot: LeasePeriod, - ) -> (CurrencyId, CurrencyId) { - let token_symbol = T::RelayChainTokenSymbol::get(); - - let vsToken = CurrencyId::VSToken(token_symbol); - let vsBond = CurrencyId::VSBond(token_symbol, index, first_slot, last_slot); - - (vsToken, vsBond) - } } #[pallet::hooks] diff --git a/pallets/liquidity-mining/src/mock.rs b/pallets/liquidity-mining/src/mock.rs index 073976fbe..f79034039 100644 --- a/pallets/liquidity-mining/src/mock.rs +++ b/pallets/liquidity-mining/src/mock.rs @@ -238,7 +238,7 @@ pub(crate) const MINING_TRADING_PAIR: (CurrencyId, CurrencyId) = pub(crate) const MINING_DEPOSIT: CurrencyId = CurrencyId::LPToken(TokenSymbol::DOT, 2u8, TokenSymbol::KSM, 2u8); pub(crate) const FARMING_DEPOSIT_1: CurrencyId = CurrencyId::VSToken(TokenSymbol::KSM); -pub(crate) const FARMING_DEPOSIT_2: CurrencyId = CurrencyId::VSBond(TokenSymbol::KSM, 2001, 13, 20); +pub(crate) const FARMING_DEPOSIT_2: CurrencyId = CurrencyId::VSBond(TokenSymbol::BNC, 2001, 13, 20); pub(crate) const DEPOSIT_AMOUNT: Balance = UNIT; pub(crate) const REWARD_1: CurrencyId = CurrencyId::Native(TokenSymbol::BNC); pub(crate) const REWARD_2: CurrencyId = CurrencyId::Token(TokenSymbol::KSM); diff --git a/pallets/liquidity-mining/src/tests.rs b/pallets/liquidity-mining/src/tests.rs index c7913e334..85922d62a 100644 --- a/pallets/liquidity-mining/src/tests.rs +++ b/pallets/liquidity-mining/src/tests.rs @@ -2392,7 +2392,7 @@ fn fuck_bug() { const REWARD_AMOUNT: Balance = 10 * UNIT; const DEPOSIT_TOKEN_1: CurrencyId = CurrencyId::VSToken(TokenSymbol::KSM); - const DEPOSIT_TOKEN_2: CurrencyId = CurrencyId::VSBond(TokenSymbol::KSM, 2001, 13, 20); + const DEPOSIT_TOKEN_2: CurrencyId = CurrencyId::VSBond(TokenSymbol::BNC, 2001, 13, 20); assert_ok!(Tokens::set_balance(Origin::root(), ALICE, REWARD_TOKEN, INIT_AMOUNT, 0)); assert_ok!(Tokens::set_balance(Origin::root(), BOB, DEPOSIT_TOKEN_1, 0, INIT_AMOUNT)); diff --git a/pallets/salp/src/lib.rs b/pallets/salp/src/lib.rs index 8fc0e6999..de29402e0 100644 --- a/pallets/salp/src/lib.rs +++ b/pallets/salp/src/lib.rs @@ -1116,10 +1116,7 @@ pub mod pallet { let tokensymbo_bit = (currency_id_u64 & 0x0000_0000_0000_00ff) as u8; let token_symbol = TokenSymbol::try_from(tokensymbo_bit).unwrap_or(TokenSymbol::KSM); - let vsToken = CurrencyId::VSToken(token_symbol); - let vsBond = CurrencyId::VSBond(token_symbol, index, first_slot, last_slot); - - (vsToken, vsBond) + CurrencyId::vsAssets(token_symbol, index, first_slot, last_slot) } fn put_contribution( diff --git a/pallets/salp/src/tests.rs b/pallets/salp/src/tests.rs index b8e70e18c..ec19f7a76 100644 --- a/pallets/salp/src/tests.rs +++ b/pallets/salp/src/tests.rs @@ -19,7 +19,7 @@ // Ensure we're `no_std` when compiling for Wasm. use frame_support::{assert_noop, assert_ok, dispatch::DispatchError, traits::BalanceStatus as BS}; -use node_primitives::ContributionStatus; +use node_primitives::{ContributionStatus, CurrencyId, TokenSymbol}; use orml_traits::{MultiCurrency, MultiReservableCurrency}; use crate::{mock::*, Error, FundStatus}; @@ -1057,6 +1057,72 @@ fn redeem_should_work() { }); } +#[test] +fn redeem_with_speical_vsbond_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Salp::create(Some(ALICE).into(), 2001, 1_000, 13, 20)); + assert_ok!(Salp::contribute(Some(BRUCE).into(), 2001, 100)); + assert_ok!(Salp::confirm_contribute( + Some(ALICE).into(), + BRUCE, + 2001, + true, + CONTRIBUTON_INDEX + )); + + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).free, INIT_BALANCE - 100); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).reserved, 0); + + assert_eq!(Tokens::accounts(Salp::fund_account_id(2001), RelayCurrencyId::get()).free, 100); + assert_eq!(Tokens::accounts(Salp::fund_account_id(2001), RelayCurrencyId::get()).frozen, 0); + assert_eq!( + Tokens::accounts(Salp::fund_account_id(2001), RelayCurrencyId::get()).reserved, + 0 + ); + + assert_ok!(Salp::fund_success(Some(ALICE).into(), 2001)); + assert_ok!(Salp::unlock(Some(BRUCE).into(), BRUCE, 2001)); + + // Mock the BlockNumber + let block_begin_redeem = (SlotLength::get() + 1) * LeasePeriod::get(); + System::set_block_number(block_begin_redeem); + + assert_ok!(Salp::fund_retire(Some(ALICE).into(), 2001)); + assert_ok!(Salp::withdraw(Some(ALICE).into(), 2001)); + + #[allow(non_snake_case)] + let (vsToken, vsBond) = Salp::vsAssets(2001, 13, 20); + + assert_ok!(>::transfer(vsToken, &BRUCE, &CATHI, 50)); + assert_ok!(>::transfer(vsBond, &BRUCE, &CATHI, 50)); + + assert_ok!(Salp::redeem(Some(BRUCE).into(), 2001, 50)); + + assert_eq!(Tokens::accounts(BRUCE, vsToken).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).free, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, vsBond).reserved, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).free, INIT_BALANCE - 50); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, RelayCurrencyId::get()).reserved, 0); + + assert_ok!(Salp::redeem(Some(CATHI).into(), 2001, 50)); + + assert_eq!(Tokens::accounts(CATHI, vsToken).free, 0); + assert_eq!(Tokens::accounts(CATHI, vsToken).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, vsToken).reserved, 0); + assert_eq!(Tokens::accounts(CATHI, vsBond).free, 0); + assert_eq!(Tokens::accounts(CATHI, vsBond).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, vsBond).reserved, 0); + assert_eq!(Tokens::accounts(CATHI, RelayCurrencyId::get()).free, INIT_BALANCE + 50); + assert_eq!(Tokens::accounts(CATHI, RelayCurrencyId::get()).frozen, 0); + assert_eq!(Tokens::accounts(CATHI, RelayCurrencyId::get()).reserved, 0); + }); +} + #[test] fn redeem_with_wrong_origin_should_fail() { new_test_ext().execute_with(|| { diff --git a/pallets/vsbond-auction/src/lib.rs b/pallets/vsbond-auction/src/lib.rs index fdf48b370..baa309382 100644 --- a/pallets/vsbond-auction/src/lib.rs +++ b/pallets/vsbond-auction/src/lib.rs @@ -240,7 +240,8 @@ pub mod pallet { TokenSymbol::try_from(token_symbol_bit).map_err(|_| Error::::Unexpected)?; // Construct vsbond - let vsbond = CurrencyId::VSBond(currency_token_symbol, index, first_slot, last_slot); + let (_, vsbond) = + CurrencyId::vsAssets(currency_token_symbol, index, first_slot, last_slot); // Check the balance let (token_reserved, amount_reserved) = match order_type { diff --git a/pallets/vsbond-auction/src/mock.rs b/pallets/vsbond-auction/src/mock.rs index 8ab432de6..86d7cd766 100644 --- a/pallets/vsbond-auction/src/mock.rs +++ b/pallets/vsbond-auction/src/mock.rs @@ -128,6 +128,8 @@ pub(crate) fn new_test_ext() -> sp_io::TestExternalities { (ALICE, VSBOND, 100), (BRUCE, TOKEN, 100), (BRUCE, VSBOND, 100), + (ALICE, SPECIAL_VSBOND, 100), + (BRUCE, SPECIAL_VSBOND, 100), #[cfg(feature = "runtime-benchmarks")] (whitelist_caller.clone(), TOKEN, 100_000_000_000_000), #[cfg(feature = "runtime-benchmarks")] @@ -148,3 +150,4 @@ pub(crate) const ALICE: AccountId = 1; pub(crate) const BRUCE: AccountId = 2; pub(crate) const TOKEN: CurrencyId = InvoicingCurrency::get(); pub(crate) const VSBOND: CurrencyId = CurrencyId::VSBond(TokenSymbol::KSM, 3000, 13, 20); +pub(crate) const SPECIAL_VSBOND: CurrencyId = CurrencyId::VSBond(TokenSymbol::BNC, 2001, 13, 20); diff --git a/pallets/vsbond-auction/src/tests.rs b/pallets/vsbond-auction/src/tests.rs index dd8c78009..db94569f2 100644 --- a/pallets/vsbond-auction/src/tests.rs +++ b/pallets/vsbond-auction/src/tests.rs @@ -459,6 +459,7 @@ fn partial_clinch_sell_order_should_work() { assert_eq!(Tokens::accounts(BRUCE, TOKEN).reserved, 0); }); } + #[test] fn partial_clinch_buy_order_should_work() { new_test_ext().execute_with(|| { @@ -585,6 +586,132 @@ fn clinch_order_without_enough_token_should_fail() { }); } +#[test] +fn handle_special_vsbond_sell_order_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Auction::create_order( + Some(ALICE).into(), + 2001, + 13, + 20, + 100, + 33, + OrderType::Sell + )); + assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); + + assert_eq!(Auction::order_id(), 1); + + let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Sell); + assert_eq!(user_sell_order_ids.len(), 1); + + let order_info = Auction::order_info(0).unwrap(); + assert_eq!(order_info.remain, 67); + + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).free, 0); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).reserved, 67); + + assert_eq!(Tokens::accounts(ALICE, TOKEN).free, 110); + assert_eq!(Tokens::accounts(ALICE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, TOKEN).reserved, 0); + + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).free, 133); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).reserved, 0); + + assert_eq!(Tokens::accounts(BRUCE, TOKEN).free, 90); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).reserved, 0); + + assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 9999999)); + + let user_sell_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + assert_eq!(user_sell_order_ids.len(), 0); + + assert!(Auction::order_info(0).is_none()); + + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).free, 0); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).reserved, 0); + + assert_eq!(Tokens::accounts(ALICE, TOKEN).free, 132); + assert_eq!(Tokens::accounts(ALICE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, TOKEN).reserved, 0); + + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).free, 200); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).reserved, 0); + + assert_eq!(Tokens::accounts(BRUCE, TOKEN).free, 68); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).reserved, 0); + }); +} + +#[test] +fn handle_special_vsbond_buy_order_should_work() { + new_test_ext().execute_with(|| { + assert_ok!(Auction::create_order( + Some(ALICE).into(), + 2001, + 13, + 20, + 100, + 33, + OrderType::Buy + )); + assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 33)); + + assert_eq!(Auction::order_id(), 1); + + let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + assert_eq!(user_buy_order_ids.len(), 1); + + let order_info = Auction::order_info(0).unwrap(); + assert_eq!(order_info.remain, 67); + + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).free, 133); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).reserved, 0); + + assert_eq!(Tokens::accounts(ALICE, TOKEN).free, 67); + assert_eq!(Tokens::accounts(ALICE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, TOKEN).reserved, 23); + + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).free, 67); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).reserved, 0); + + assert_eq!(Tokens::accounts(BRUCE, TOKEN).free, 110); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).reserved, 0); + + assert_ok!(Auction::partial_clinch_order(Some(BRUCE).into(), 0, 9999999)); + + let user_buy_order_ids = Auction::user_order_ids(ALICE, OrderType::Buy); + assert_eq!(user_buy_order_ids.len(), 0); + + assert!(Auction::order_info(0).is_none()); + + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).free, 200); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, SPECIAL_VSBOND).reserved, 0); + + assert_eq!(Tokens::accounts(ALICE, TOKEN).free, 68); + assert_eq!(Tokens::accounts(ALICE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(ALICE, TOKEN).reserved, 0); + + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).free, 0); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, SPECIAL_VSBOND).reserved, 0); + + assert_eq!(Tokens::accounts(BRUCE, TOKEN).free, 132); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).frozen, 0); + assert_eq!(Tokens::accounts(BRUCE, TOKEN).reserved, 0); + }); +} + // Test Utilities #[test] fn check_price_to_pay() {