Skip to content
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
57 changes: 13 additions & 44 deletions pallets/vtoken-minting/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use frame_support::{
traits::{
AccountIdConversion, CheckedAdd, CheckedDiv, CheckedMul, CheckedSub, Saturating, Zero,
},
DispatchError,
DispatchError, Permill,
},
transactional, BoundedVec, PalletId,
};
Expand Down Expand Up @@ -149,8 +149,8 @@ pub mod pallet {
},
/// Several fees has been set.
FeeSet {
mint_fee: BalanceOf<T>,
redeem_fee: BalanceOf<T>,
mint_fee: Permill,
redeem_fee: Permill,
// hosting_fee: BalanceOf<T>,
},
HookIterationLimitSet {
Expand Down Expand Up @@ -181,7 +181,7 @@ pub mod pallet {

#[pallet::storage]
#[pallet::getter(fn fees)]
pub type Fees<T: Config> = StorageValue<_, (BalanceOf<T>, BalanceOf<T>), ValueQuery>;
pub type Fees<T: Config> = StorageValue<_, (Permill, Permill), ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn token_pool)]
Expand Down Expand Up @@ -247,16 +247,6 @@ pub mod pallet {
OptionQuery,
>;

#[pallet::storage]
#[pallet::getter(fn token_to_deduct)]
pub type TokenToDeduct<T: Config> =
StorageMap<_, Twox64Concat, CurrencyIdOf<T>, BalanceOf<T>, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn token_to_add)]
pub type TokenToAdd<T: Config> =
StorageMap<_, Twox64Concat, CurrencyIdOf<T>, BalanceOf<T>, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn token_to_rebond)]
pub type TokenToRebond<T: Config> = StorageMap<_, Twox64Concat, CurrencyIdOf<T>, BalanceOf<T>>;
Expand Down Expand Up @@ -333,7 +323,8 @@ pub mod pallet {
vtoken_amount >= MinimumRedeem::<T>::get(token_id),
Error::<T>::BelowMinimumRedeem
);
let (_mint_fee, redeem_fee) = Fees::<T>::get();
let (_mint_rate, redeem_rate) = Fees::<T>::get();
let redeem_fee = redeem_rate * vtoken_amount;
vtoken_amount =
vtoken_amount.checked_sub(&redeem_fee).ok_or(Error::<T>::CalculationOverflow)?;
// Charging fees
Expand Down Expand Up @@ -363,12 +354,6 @@ pub mod pallet {
.ok_or(Error::<T>::CalculationOverflow)?;
Ok(())
})?;
TokenToDeduct::<T>::mutate(&token_id, |pool| -> Result<(), Error<T>> {
*pool = pool
.checked_add(&token_amount)
.ok_or(Error::<T>::CalculationOverflow)?;
Ok(())
})?;
CurrencyUnlockingTotal::<T>::mutate(|pool| -> Result<(), Error<T>> {
*pool = pool
.checked_add(&token_amount)
Expand Down Expand Up @@ -797,9 +782,8 @@ pub mod pallet {
#[pallet::weight(0)]
pub fn set_fees(
origin: OriginFor<T>,
mint_fee: BalanceOf<T>,
redeem_fee: BalanceOf<T>,
// hosting_fee: BalanceOf<T>,
mint_fee: Permill,
redeem_fee: Permill,
) -> DispatchResult {
ensure_root(origin)?;

Expand Down Expand Up @@ -849,7 +833,8 @@ pub mod pallet {
) -> Result<(BalanceOf<T>, BalanceOf<T>, BalanceOf<T>), DispatchError> {
let token_pool_amount = Self::token_pool(token_id);
let vtoken_total_issuance = T::MultiCurrency::total_issuance(vtoken_id);
let (mint_fee, _redeem_fee) = Fees::<T>::get();
let (mint_rate, _redeem_rate) = Fees::<T>::get();
let mint_fee = mint_rate * token_amount;
let token_amount_excluding_fee =
token_amount.checked_sub(&mint_fee).ok_or(Error::<T>::CalculationOverflow)?;
let mut vtoken_amount = token_amount_excluding_fee;
Expand All @@ -871,12 +856,6 @@ pub mod pallet {
.ok_or(Error::<T>::CalculationOverflow)?;
Ok(())
})?;
TokenToAdd::<T>::mutate(&token_id, |pool| -> Result<(), Error<T>> {
*pool = pool
.checked_add(&token_amount_excluding_fee)
.ok_or(Error::<T>::CalculationOverflow)?;
Ok(())
})?;
Ok((token_amount_excluding_fee, vtoken_amount, mint_fee))
}

Expand Down Expand Up @@ -956,7 +935,7 @@ pub mod pallet {
&time_unit,
&token_id,
|value| -> Result<(), Error<T>> {
if let Some((total_locked_origin, ledger_list_origin, _)) = value {
if let Some((total_locked_origin, _ledger_list_origin, _)) = value {
if total_locked_origin == &unlock_amount {
*value = None;
return Ok(());
Expand All @@ -975,7 +954,7 @@ pub mod pallet {
&account,
&token_id,
|value| -> Result<(), Error<T>> {
if let Some((total_locked_origin, ledger_list_origin)) = value {
if let Some((total_locked_origin, _ledger_list_origin)) = value {
if total_locked_origin == &unlock_amount {
*value = None;
return Ok(());
Expand Down Expand Up @@ -1008,16 +987,6 @@ pub mod pallet {
Ok(())
})?;

TokenToAdd::<T>::mutate(&token_id, |pool| -> Result<(), Error<T>> {
*pool = pool.checked_sub(&unlock_amount).ok_or(Error::<T>::CalculationOverflow)?;
Ok(())
})?;

TokenToDeduct::<T>::mutate(&token_id, |pool| -> Result<(), Error<T>> {
*pool = pool.checked_sub(&unlock_amount).ok_or(Error::<T>::CalculationOverflow)?;
Ok(())
})?;

Self::deposit_event(Event::RedeemSuccess {
unlock_id: *index,
token_id,
Expand All @@ -1033,7 +1002,7 @@ pub mod pallet {
let time_unit = MinTimeUnit::<T>::get(ksm);
TimeUnitUnlockLedger::<T>::iter_prefix_values(time_unit.clone()).for_each(
|(_total_locked, ledger_list, token_id)| {
let mut entrance_account_balance = T::MultiCurrency::free_balance(
let entrance_account_balance = T::MultiCurrency::free_balance(
token_id,
&T::EntranceAccount::get().into_account(),
);
Expand Down
36 changes: 16 additions & 20 deletions pallets/vtoken-minting/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,37 @@

#![cfg(test)]

use frame_support::{assert_noop, assert_ok, BoundedVec};
use frame_support::{assert_noop, assert_ok, sp_runtime::Permill, BoundedVec};

use crate::{mock::*, *};

#[test]
fn mint() {
ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| {
assert_ok!(VtokenMinting::set_minimum_mint(Origin::root(), KSM, 200));
assert_ok!(VtokenMinting::set_fees(Origin::root(), 600, 20));
pub const FEE: Permill = Permill::from_percent(5);
assert_ok!(VtokenMinting::set_fees(Origin::root(), FEE, FEE));
assert_noop!(
VtokenMinting::mint(Some(BOB).into(), KSM, 100),
Error::<Runtime>::BelowMinimumMint
);
assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 1000));
assert_eq!(VtokenMinting::token_pool(KSM), 400);
assert_eq!(VtokenMinting::token_to_add(KSM), 400);
assert_eq!(VtokenMinting::token_pool(KSM), 950);
assert_eq!(VtokenMinting::minimum_mint(KSM), 200);
assert_eq!(Tokens::total_issuance(vKSM), 1400);
assert_eq!(Tokens::total_issuance(vKSM), 1950);

let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts();
assert_eq!(Tokens::free_balance(KSM, &entrance_account), 400);
assert_eq!(Tokens::free_balance(KSM, &entrance_account), 950);
let fee_account: AccountId = <Runtime as Config>::FeeAccount::get();
assert_eq!(Tokens::free_balance(KSM, &fee_account), 600);
assert_eq!(Tokens::free_balance(KSM, &fee_account), 50);
});
}

#[test]
fn redeem() {
ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| {
assert_ok!(VtokenMinting::set_fees(Origin::root(), 20, 20));
pub const FEE: Permill = Permill::from_percent(2);
assert_ok!(VtokenMinting::set_fees(Origin::root(), FEE, FEE));
assert_ok!(VtokenMinting::set_unlock_duration(Origin::root(), KSM, TimeUnit::Era(1)));
assert_ok!(VtokenMinting::increase_token_pool(KSM, 1000));
assert_ok!(VtokenMinting::update_ongoing_time_unit(KSM, TimeUnit::Era(1)));
Expand All @@ -65,29 +66,30 @@ fn redeem() {
);
assert_ok!(VtokenMinting::redeem(Some(BOB).into(), vKSM, 100));
assert_ok!(VtokenMinting::redeem(Some(BOB).into(), vKSM, 200));
assert_eq!(VtokenMinting::token_pool(KSM), 1720); // 1000 + 980 - 80 - 180
assert_eq!(VtokenMinting::token_to_add(KSM), 980);
assert_eq!(VtokenMinting::currency_unlocking_total(), 260); // 80 + 180
assert_eq!(VtokenMinting::token_pool(KSM), 1686); // 1000 + 980 - 98 - 196
assert_eq!(VtokenMinting::currency_unlocking_total(), 294); // 98 + 196
let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts();
assert_eq!(Tokens::free_balance(KSM, &entrance_account), 980);
let mut ledger_list_origin = BoundedVec::default();
assert_ok!(ledger_list_origin.try_push(0));
assert_ok!(ledger_list_origin.try_push(1));
assert_eq!(
VtokenMinting::user_unlock_ledger(BOB, KSM),
Some((260, ledger_list_origin.clone()))
Some((294, ledger_list_origin.clone()))
);
assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 0), Some((BOB, 80, TimeUnit::Era(2))));
assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 0), Some((BOB, 98, TimeUnit::Era(2))));
assert_eq!(
VtokenMinting::time_unit_unlock_ledger(TimeUnit::Era(2), KSM),
Some((260, ledger_list_origin, KSM))
Some((294, ledger_list_origin, KSM))
);
});
}

#[test]
fn rebond() {
ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| {
pub const FEE: Permill = Permill::from_percent(0);
assert_ok!(VtokenMinting::set_fees(Origin::root(), FEE, FEE));
assert_ok!(VtokenMinting::set_unlock_duration(Origin::root(), KSM, TimeUnit::Era(0)));
assert_ok!(VtokenMinting::increase_token_pool(KSM, 1000));
assert_ok!(VtokenMinting::update_ongoing_time_unit(KSM, TimeUnit::Era(1)));
Expand Down Expand Up @@ -115,7 +117,6 @@ fn rebond() {
assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 0), Some((BOB, 100, TimeUnit::Era(1))));
assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 1), None);
assert_eq!(VtokenMinting::token_pool(KSM), 1200);
assert_eq!(VtokenMinting::token_to_add(KSM), 500);
assert_eq!(VtokenMinting::currency_unlocking_total(), 100); // 200 + 100 - 200
let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts();
assert_eq!(Tokens::free_balance(KSM, &entrance_account), 300);
Expand All @@ -142,9 +143,7 @@ fn hook() {
assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 100));
assert_ok!(VtokenMinting::redeem(Some(BOB).into(), vKSM, 200));
assert_ok!(VtokenMinting::redeem(Some(BOB).into(), vKSM, 100));
assert_eq!(VtokenMinting::token_to_add(KSM), 300);
assert_eq!(VtokenMinting::currency_unlocking_total(), 300); // 200 + 100
assert_eq!(VtokenMinting::token_to_deduct(KSM), 300);
assert_noop!(
VtokenMinting::rebond(Some(BOB).into(), KSM, 100),
Error::<Runtime>::InvalidRebondToken
Expand All @@ -167,8 +166,6 @@ fn hook() {
VtokenMinting::on_initialize(0);
VtokenMinting::on_initialize(1);
assert_eq!(VtokenMinting::min_time_unit(KSM), TimeUnit::Era(6));
assert_eq!(VtokenMinting::token_to_add(KSM), 0);
assert_eq!(VtokenMinting::token_to_deduct(KSM), 0);
assert_eq!(VtokenMinting::currency_unlocking_total(), 0);
assert_ok!(VtokenMinting::mint(Some(BOB).into(), KSM, 100));
assert_ok!(VtokenMinting::redeem(Some(BOB).into(), vKSM, 200));
Expand Down Expand Up @@ -217,7 +214,6 @@ fn rebond_by_unlock_id() {
assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 0), None);
assert_eq!(VtokenMinting::token_unlock_ledger(KSM, 1), Some((BOB, 100, TimeUnit::Era(1))));
assert_eq!(VtokenMinting::token_pool(KSM), 1200);
assert_eq!(VtokenMinting::token_to_add(KSM), 500);
assert_eq!(VtokenMinting::currency_unlocking_total(), 100); // 200 + 100 - 200
let (entrance_account, _exit_account) = VtokenMinting::get_entrance_and_exit_accounts();
assert_eq!(Tokens::free_balance(KSM, &entrance_account), 300);
Expand Down