Skip to content
Open
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
2 changes: 2 additions & 0 deletions zenlink-protocol/src/fee/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ parameter_types! {

pub const BlockHashCount: u64 = 250;
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
pub const NativeSwapFeesPotId: PalletId = PalletId(*b"/swpfees");
pub const MaxReserves: u32 = 50;
pub const MaxLocks:u32 = 50;
}
Expand Down Expand Up @@ -145,6 +146,7 @@ impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances, LocalAssetAdaptor<Tokens>>;
type PalletId = ZenlinkPalletId;
type NativeSwapFeesPotId = NativeSwapFeesPotId;
type AssetId = AssetId;
type LpGenerate = PairLpGenerate<Self>;
type SelfParaId = ();
Expand Down
2 changes: 2 additions & 0 deletions zenlink-protocol/src/foreign/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ parameter_types! {

pub const BlockHashCount: u64 = 250;
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
pub const NativeSwapFeesPotId: PalletId = PalletId(*b"/swpfees");
pub const MaxReserves: u32 = 50;
}

Expand Down Expand Up @@ -81,6 +82,7 @@ impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances>;
type PalletId = ZenlinkPalletId;
type NativeSwapFeesPotId = NativeSwapFeesPotId;
type AssetId = AssetId;
type LpGenerate = PairLpGenerate<Self>;
type SelfParaId = ();
Expand Down
21 changes: 21 additions & 0 deletions zenlink-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ pub mod pallet {
/// This parachain id.
type SelfParaId: Get<u32>;

/// Account Identifier from which the internal Pot is generated.
type NativeSwapFeesPotId: Get<PalletId>;

/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
Expand Down Expand Up @@ -193,6 +196,10 @@ pub mod pallet {
ValueQuery,
>;

#[pallet::storage]
#[pallet::getter(fn get_native_swap_fee_factor)]
pub type NativeSwapFeeFactor<T: Config> = StorageValue<_, u128, ValueQuery>;

#[pallet::genesis_config]
/// Refer: https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol#L88
pub struct GenesisConfig<T: Config> {
Expand Down Expand Up @@ -984,5 +991,19 @@ pub mod pallet {

Ok(())
}

#[pallet::call_index(18)]
#[pallet::weight(100_000_000)]
#[frame_support::transactional]
pub fn set_native_swap_fee_factor(
origin: OriginFor<T>,
native_swap_fees_factor: u128,
) -> DispatchResult {
ensure_root(origin)?;

NativeSwapFeeFactor::<T>::put(native_swap_fees_factor);

Ok(())
}
}
}
5 changes: 5 additions & 0 deletions zenlink-protocol/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,17 @@ pub struct AssetId {

pub trait AssetInfo {
fn is_support(&self) -> bool;
fn is_native(&self, self_chain_id: u32) -> bool;
}

impl AssetInfo for AssetId {
fn is_support(&self) -> bool {
matches!(self.asset_type, NATIVE | LIQUIDITY | LOCAL | RESERVED)
}

fn is_native(&self, self_chain_id: u32) -> bool {
self.chain_id == self_chain_id && self.asset_type == NATIVE && self.asset_index == 0
}
}

impl AssetId {
Expand Down
2 changes: 2 additions & 0 deletions zenlink-protocol/src/swap/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ parameter_types! {

pub const BlockHashCount: u64 = 250;
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
pub const NativeSwapFeesPotId: PalletId = PalletId(*b"/swpfees");
pub const MaxReserves: u32 = 50;
pub const MaxLocks:u32 = 50;
}
Expand Down Expand Up @@ -145,6 +146,7 @@ impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances, LocalAssetAdaptor<Tokens>>;
type PalletId = ZenlinkPalletId;
type NativeSwapFeesPotId = NativeSwapFeesPotId;
type AssetId = AssetId;
type LpGenerate = PairLpGenerate<Self>;
type SelfParaId = ();
Expand Down
28 changes: 26 additions & 2 deletions zenlink-protocol/src/swap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,12 +214,36 @@ impl<T: Config> Pallet<T> {
path: &[T::AssetId],
recipient: &T::AccountId,
) -> DispatchResult {
let amounts = Self::get_amount_out_by_path(amount_in, path)?;
let mut amount_in_less_native_swap_fee = amount_in;
if path[0].is_native(T::SelfParaId::get()) {
let native_swap_fee_factor = Self::get_native_swap_fee_factor();
if native_swap_fee_factor != 0u128 {
// charge a configurable % going to a pallet account for later distribution
let native_swap_fee =
amount_in.checked_div(native_swap_fee_factor).unwrap_or_default();
amount_in_less_native_swap_fee = amount_in.saturating_sub(native_swap_fee);
let native_swap_fees_account =
T::NativeSwapFeesPotId::get().into_account_truncating();
T::MultiAssetsHandler::transfer(
path[0],
who,
&native_swap_fees_account,
native_swap_fee,
)?;
}
}

let amounts = Self::get_amount_out_by_path(amount_in_less_native_swap_fee, path)?;
ensure!(amounts[amounts.len() - 1] >= amount_out_min, Error::<T>::InsufficientTargetAmount);

let pair_account = Self::pair_account_id(path[0], path[1]);

T::MultiAssetsHandler::transfer(path[0], who, &pair_account, amount_in)?;
T::MultiAssetsHandler::transfer(
path[0],
who,
&pair_account,
amount_in_less_native_swap_fee,
)?;
Self::swap(&amounts, path, recipient)?;

Self::deposit_event(Event::AssetSwap(
Expand Down
11 changes: 4 additions & 7 deletions zenlink-swap-router/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ use crate as router;
use crate::{Config, Pallet};
use orml_traits::{parameter_type_with_key, MultiCurrency};
use zenlink_protocol::{
AssetBalance, AssetId, AssetIdConverter, LocalAssetHandler, PairLpGenerate, ZenlinkMultiAssets,
LOCAL,
AssetBalance, AssetId, LocalAssetHandler, PairLpGenerate, ZenlinkMultiAssets, LOCAL,
};
use zenlink_stable_amm::traits::{StablePoolLpCurrencyIdGenerate, ValidateCurrency};

Expand All @@ -40,6 +39,7 @@ parameter_types! {
pub const BlockHashCount: u64 = 250;
pub const StableAmmPalletId: PalletId = PalletId(*b"/zlkSAmm");
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
pub const NativeSwapFeesPotId: PalletId = PalletId(*b"/swpfees");
pub const MaxReserves: u32 = 50;
pub const MaxLocks:u32 = 50;
pub const MinimumPeriod: Moment = SLOT_DURATION / 2;
Expand Down Expand Up @@ -210,13 +210,10 @@ impl zenlink_protocol::Config for Test {
type RuntimeEvent = RuntimeEvent;
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances, LocalAssetAdaptor<Tokens>>;
type PalletId = ZenlinkPalletId;
type NativeSwapFeesPotId = NativeSwapFeesPotId;
type AssetId = AssetId;
type LpGenerate = PairLpGenerate<Self>;
type TargetChains = ();
type SelfParaId = SelfParaId;
type XcmExecutor = ();
type AccountIdConverter = ();
type AssetIdConverter = AssetIdConverter;
type LpGenerate = PairLpGenerate<Self>;
type WeightInfo = ();
}

Expand Down