diff --git a/Cargo.lock b/Cargo.lock
index fb495de8fe..deff9185d5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6551,7 +6551,7 @@ dependencies = [
 
 [[package]]
 name = "node-cli"
-version = "0.9.86"
+version = "0.9.87"
 dependencies = [
  "clap",
  "cumulus-client-cli",
diff --git a/node/cli/Cargo.toml b/node/cli/Cargo.toml
index 4883f6ab92..2147d9460f 100644
--- a/node/cli/Cargo.toml
+++ b/node/cli/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "node-cli"
-version = "0.9.86"
+version = "0.9.87"
 authors = ["Liebi Technologies <bifrost@liebi.com>"]
 description = "Bifrost Parachain Node"
 build = "build.rs"
diff --git a/node/primitives/src/currency.rs b/node/primitives/src/currency.rs
index 18635b7f15..e4df75c905 100644
--- a/node/primitives/src/currency.rs
+++ b/node/primitives/src/currency.rs
@@ -414,6 +414,7 @@ impl CurrencyId {
 
 	pub fn to_token(&self) -> Result<Self, ()> {
 		match self {
+			Self::VToken(TokenSymbol::BNC) => Ok(Self::Native(TokenSymbol::BNC)),
 			Self::VToken(symbol) => Ok(Self::Token(*symbol)),
 			Self::VToken2(id) => Ok(Self::Token2(*id)),
 			_ => Err(()),
@@ -424,6 +425,7 @@ impl CurrencyId {
 		match self {
 			Self::Token(symbol) => Ok(Self::VToken(*symbol)),
 			Self::Token2(id) => Ok(Self::VToken2(*id)),
+			Self::Native(TokenSymbol::BNC) => Ok(Self::VToken(TokenSymbol::BNC)),
 			_ => Err(()),
 		}
 	}
diff --git a/node/primitives/src/tests.rs b/node/primitives/src/tests.rs
index 562a9661d0..ac3a207c7e 100644
--- a/node/primitives/src/tests.rs
+++ b/node/primitives/src/tests.rs
@@ -362,3 +362,73 @@ fn u64_to_currency_id_should_work() {
 	assert_eq!(eb5, CurrencyId::try_from(0x07d5_004f_005f_0b05).unwrap());
 	assert_eq!(eb6, CurrencyId::try_from(0x07d6_005f_006f_0b06).unwrap());
 }
+
+#[test]
+fn to_vtoken_should_work() {
+	let native_bnc = CurrencyId::Native(TokenSymbol::BNC);
+	let native_asg = CurrencyId::Native(TokenSymbol::ASG);
+	let vtoken_ksm = CurrencyId::VToken(TokenSymbol::KSM);
+	let token_ksm = CurrencyId::Token(TokenSymbol::KSM);
+	let stable_kusd = CurrencyId::Stable(TokenSymbol::KUSD);
+	let vstoken_eth = CurrencyId::VSToken(TokenSymbol::ETH);
+	let vsbond_ksm = CurrencyId::VSBond(TokenSymbol::KSM, 2001, 0, 1000);
+	let token2_dot = CurrencyId::Token2(DOT_TOKEN_ID);
+	let vtoken2_dot = CurrencyId::VToken2(DOT_TOKEN_ID);
+	let vstoken2_dot = CurrencyId::VSToken2(DOT_TOKEN_ID);
+	let vsbond2_dot = CurrencyId::VSBond2(DOT_TOKEN_ID, 2030, 0, 1000);
+	let foreign_asset = CurrencyId::ForeignAsset(1984);
+	let blp = CurrencyId::BLP(100);
+	let stable_lp_token = CurrencyId::StableLpToken(100);
+	let lp_token = CurrencyId::LPToken(TokenSymbol::BNC, 0, TokenSymbol::KSM, 2);
+
+	assert_eq!(native_bnc.to_vtoken(), Ok(CurrencyId::VToken(TokenSymbol::BNC)));
+	assert_eq!(native_asg.to_vtoken(), Err(()));
+	assert_eq!(vtoken_ksm.to_vtoken(), Err(()));
+	assert_eq!(token_ksm.to_vtoken(), Ok(CurrencyId::VToken(TokenSymbol::KSM)));
+	assert_eq!(stable_kusd.to_vtoken(), Err(()));
+	assert_eq!(vstoken_eth.to_vtoken(), Err(()));
+	assert_eq!(vsbond_ksm.to_vtoken(), Err(()));
+	assert_eq!(token2_dot.to_vtoken(), Ok(CurrencyId::VToken2(DOT_TOKEN_ID)));
+	assert_eq!(vtoken2_dot.to_vtoken(), Err(()));
+	assert_eq!(vstoken2_dot.to_vtoken(), Err(()));
+	assert_eq!(vsbond2_dot.to_vtoken(), Err(()));
+	assert_eq!(foreign_asset.to_vtoken(), Err(()));
+	assert_eq!(blp.to_vtoken(), Err(()));
+	assert_eq!(stable_lp_token.to_vtoken(), Err(()));
+	assert_eq!(lp_token.to_vtoken(), Err(()));
+}
+
+#[test]
+fn to_token_should_work() {
+	let native_bnc = CurrencyId::Native(TokenSymbol::BNC);
+	let vtoken_bnc = CurrencyId::VToken(TokenSymbol::BNC);
+	let vtoken_ksm = CurrencyId::VToken(TokenSymbol::KSM);
+	let token_ksm = CurrencyId::Token(TokenSymbol::KSM);
+	let stable_kusd = CurrencyId::Stable(TokenSymbol::KUSD);
+	let vstoken_eth = CurrencyId::VSToken(TokenSymbol::ETH);
+	let vsbond_ksm = CurrencyId::VSBond(TokenSymbol::KSM, 2001, 0, 1000);
+	let token2_dot = CurrencyId::Token2(DOT_TOKEN_ID);
+	let vtoken2_dot = CurrencyId::VToken2(DOT_TOKEN_ID);
+	let vstoken2_dot = CurrencyId::VSToken2(DOT_TOKEN_ID);
+	let vsbond2_dot = CurrencyId::VSBond2(DOT_TOKEN_ID, 2030, 0, 1000);
+	let foreign_asset = CurrencyId::ForeignAsset(1984);
+	let blp = CurrencyId::BLP(100);
+	let stable_lp_token = CurrencyId::StableLpToken(100);
+	let lp_token = CurrencyId::LPToken(TokenSymbol::BNC, 0, TokenSymbol::KSM, 2);
+
+	assert_eq!(native_bnc.to_token(), Err(()));
+	assert_eq!(vtoken_bnc.to_token(), Ok(CurrencyId::Native(TokenSymbol::BNC)));
+	assert_eq!(vtoken_ksm.to_token(), Ok(CurrencyId::Token(TokenSymbol::KSM)));
+	assert_eq!(token_ksm.to_token(), Err(()));
+	assert_eq!(stable_kusd.to_token(), Err(()));
+	assert_eq!(vstoken_eth.to_token(), Err(()));
+	assert_eq!(vsbond_ksm.to_token(), Err(()));
+	assert_eq!(token2_dot.to_token(), Err(()));
+	assert_eq!(vtoken2_dot.to_token(), Ok(CurrencyId::Token2(DOT_TOKEN_ID)));
+	assert_eq!(vstoken2_dot.to_token(), Err(()));
+	assert_eq!(vsbond2_dot.to_token(), Err(()));
+	assert_eq!(foreign_asset.to_token(), Err(()));
+	assert_eq!(blp.to_token(), Err(()));
+	assert_eq!(stable_lp_token.to_token(), Err(()));
+	assert_eq!(lp_token.to_token(), Err(()));
+}
diff --git a/pallets/slp/src/tests/mod.rs b/pallets/slp/src/tests/mod.rs
index 9d3abfe1f7..7dfb28aa5c 100644
--- a/pallets/slp/src/tests/mod.rs
+++ b/pallets/slp/src/tests/mod.rs
@@ -27,13 +27,13 @@ mod parachain_staking_tests;
 #[cfg(test)]
 mod phala_tests;
 
+#[cfg(test)]
+pub use filecoin_tests::*;
 #[cfg(test)]
 pub use kusama_tests::*;
 #[cfg(test)]
 pub use moonriver_tests::*;
-// #[cfg(test)]
-// pub use parachain_staking_tests::*;
 #[cfg(test)]
-pub use filecoin_tests::*;
+pub use parachain_staking_tests::*;
 #[cfg(test)]
 pub use phala_tests::*;
diff --git a/pallets/slp/src/tests/parachain_staking_tests.rs b/pallets/slp/src/tests/parachain_staking_tests.rs
index 9f53f7403e..26fcf68e42 100644
--- a/pallets/slp/src/tests/parachain_staking_tests.rs
+++ b/pallets/slp/src/tests/parachain_staking_tests.rs
@@ -19,18 +19,16 @@
 #![cfg(test)]
 use crate::{
 	mocks::mock::*,
-	primitives::{OneToManyDelegationAction, OneToManyScheduledRequest},
-	*,
-};
-use frame_support::{assert_noop, assert_ok};
-use parachain_staking::RoundInfo;
-
-use crate::{
-	primitives::{OneToManyDelegatorStatus, OneToManyLedger},
-	BNC,
+	primitives::{
+		OneToManyDelegationAction, OneToManyDelegatorStatus, OneToManyLedger,
+		OneToManyScheduledRequest,
+	},
+	BNC, *,
 };
 use codec::alloc::collections::BTreeMap;
-use frame_support::PalletId;
+use frame_support::{assert_noop, assert_ok, PalletId};
+use node_primitives::VBNC;
+use parachain_staking::RoundInfo;
 use sp_runtime::traits::AccountIdConversion;
 
 #[test]
@@ -970,3 +968,52 @@ fn add_validator_and_remove_validator_works() {
 		assert_eq!(Slp::get_validators(BNC), Some(empty_bounded_vec));
 	});
 }
+
+#[test]
+fn charge_host_fee_and_tune_vtoken_exchange_rate_works() {
+	let subaccount_0_location =
+		MultiLocation { parents: 0, interior: X1(AccountId32 { network: None, id: ALICE.into() }) };
+
+	ExtBuilder::default().build().execute_with(|| {
+		// environment setup
+		parachain_staking_setup();
+
+		// First set base vtoken exchange rate. Should be 1:1.
+		assert_ok!(Currencies::deposit(VBNC, &ALICE, 1000));
+		assert_ok!(Slp::increase_token_pool(RuntimeOrigin::signed(ALICE), BNC, 1000));
+
+		// Set the hosting fee to be 20%, and the beneficiary to be bifrost treasury account.
+		let pct = Permill::from_percent(20);
+		let treasury_account_id_32: [u8; 32] = PalletId(*b"bf/trsry").into_account_truncating();
+		let treasury_location = MultiLocation {
+			parents: 0,
+			interior: X1(AccountId32 { network: None, id: treasury_account_id_32 }),
+		};
+
+		assert_ok!(Slp::set_hosting_fees(
+			RuntimeOrigin::signed(ALICE),
+			BNC,
+			Some((pct, treasury_location))
+		));
+
+		let pct_100 = Permill::from_percent(100);
+		assert_ok!(Slp::set_currency_tune_exchange_rate_limit(
+			RuntimeOrigin::signed(ALICE),
+			BNC,
+			Some((1, pct_100))
+		));
+
+		// call the charge_host_fee_and_tune_vtoken_exchange_rate
+		assert_ok!(Slp::charge_host_fee_and_tune_vtoken_exchange_rate(
+			RuntimeOrigin::signed(ALICE),
+			BNC,
+			1000,
+			Some(subaccount_0_location)
+		));
+
+		// check token pool, should be 1000 + 1000 = 2000
+		assert_eq!(<Runtime as Config>::VtokenMinting::get_token_pool(BNC), 2000);
+		// check vBNC issuance, should be 1000 + 20% * 1000 = 1200
+		assert_eq!(Currencies::total_issuance(VBNC), 1200);
+	});
+}
diff --git a/runtime/bifrost-kusama/src/lib.rs b/runtime/bifrost-kusama/src/lib.rs
index 2cb858d447..37cd26d3e2 100644
--- a/runtime/bifrost-kusama/src/lib.rs
+++ b/runtime/bifrost-kusama/src/lib.rs
@@ -133,7 +133,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: create_runtime_str!("bifrost"),
 	impl_name: create_runtime_str!("bifrost"),
 	authoring_version: 1,
-	spec_version: 986,
+	spec_version: 987,
 	impl_version: 0,
 	apis: RUNTIME_API_VERSIONS,
 	transaction_version: 1,
@@ -1905,10 +1905,11 @@ pub type Migrations = migrations::Unreleased;
 
 /// The runtime migrations per release.
 pub mod migrations {
+	#[allow(unused)]
 	use super::*;
 
 	/// Unreleased migrations. Add new ones here:
-	pub type Unreleased = bifrost_slp::migrations::v3::SlpMigration3<Runtime>;
+	pub type Unreleased = ();
 }
 
 /// Executive: handles dispatch to the various modules.
diff --git a/runtime/bifrost-polkadot/src/lib.rs b/runtime/bifrost-polkadot/src/lib.rs
index 31c4e5cc61..f96a1e433f 100644
--- a/runtime/bifrost-polkadot/src/lib.rs
+++ b/runtime/bifrost-polkadot/src/lib.rs
@@ -130,7 +130,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
 	spec_name: create_runtime_str!("bifrost_polkadot"),
 	impl_name: create_runtime_str!("bifrost_polkadot"),
 	authoring_version: 0,
-	spec_version: 986,
+	spec_version: 987,
 	impl_version: 0,
 	apis: RUNTIME_API_VERSIONS,
 	transaction_version: 1,
@@ -1709,10 +1709,11 @@ pub type Migrations = migrations::Unreleased;
 
 /// The runtime migrations per release.
 pub mod migrations {
+	#[allow(unused)]
 	use super::*;
 
 	/// Unreleased migrations. Add new ones here:
-	pub type Unreleased = bifrost_slp::migrations::v3::SlpMigration3<Runtime>;
+	pub type Unreleased = ();
 }
 
 /// Executive: handles dispatch to the various modules.