Skip to content
18 changes: 18 additions & 0 deletions node/primitives/src/currency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,24 @@ impl From<TokenSymbol> 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<Self, ()> {
match self {
Self::VToken(symbol) => Ok(Self::Token(symbol.clone())),
Expand Down
20 changes: 4 additions & 16 deletions pallets/liquidity-mining/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion pallets/liquidity-mining/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion pallets/liquidity-mining/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
5 changes: 1 addition & 4 deletions pallets/salp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
68 changes: 67 additions & 1 deletion pallets/salp/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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!(<Tokens as MultiCurrency<AccountId>>::transfer(vsToken, &BRUCE, &CATHI, 50));
assert_ok!(<Tokens as MultiCurrency<AccountId>>::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(|| {
Expand Down
3 changes: 2 additions & 1 deletion pallets/vsbond-auction/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ pub mod pallet {
TokenSymbol::try_from(token_symbol_bit).map_err(|_| Error::<T>::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 {
Expand Down
3 changes: 3 additions & 0 deletions pallets/vsbond-auction/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand All @@ -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);
127 changes: 127 additions & 0 deletions pallets/vsbond-auction/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(|| {
Expand Down Expand Up @@ -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() {
Expand Down