Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dex swap fees #1

Open
wants to merge 10 commits into
base: polkadot-v0.9.37
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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 SwapFeesPotId: 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 PotId = SwapFeesPotId;
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 SwapFeesPotId: 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 PotId = SwapFeesPotId;
type AssetId = AssetId;
type LpGenerate = PairLpGenerate<Self>;
type SelfParaId = ();
Expand Down
3 changes: 3 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 PotId: Get<PalletId>;

/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
Expand Down
7 changes: 7 additions & 0 deletions zenlink-protocol/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,19 @@ pub struct AssetId {

pub trait AssetInfo {
fn is_support(&self) -> bool;
fn is_native(&self, self_chain_id: u32) -> bool {
false
ghzlatarev marked this conversation as resolved.
Show resolved Hide resolved
}
}

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 SwapFeesPotId: 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 PotId = SwapFeesPotId;
type AssetId = AssetId;
type LpGenerate = PairLpGenerate<Self>;
type SelfParaId = ();
Expand Down
14 changes: 12 additions & 2 deletions zenlink-protocol/src/swap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use super::*;
use crate::swap::util::*;
use primitives::AssetId;

#[cfg(test)]
mod mock;
Expand Down Expand Up @@ -214,12 +215,21 @@ 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 new_amount_in = amount_in;
if path[0].is_native(T::SelfParaId::get()) {
// charge 0.5% going to pallet account for later distribution
let fee = amount_in.checked_div(200).unwrap_or_default();
new_amount_in = amount_in - fee;
ghzlatarev marked this conversation as resolved.
Show resolved Hide resolved
let native_swap_fees_account = T::PotId::get().into_account_truncating();
T::MultiAssetsHandler::transfer(path[0], who, &native_swap_fees_account, fee)?;
}

let amounts = Self::get_amount_out_by_path(new_amount_in, 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, new_amount_in)?;
Self::swap(&amounts, path, recipient)?;

Self::deposit_event(Event::AssetSwap(
Expand Down
66 changes: 65 additions & 1 deletion zenlink-protocol/src/swap/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const DOT_ASSET_ID: AssetId = AssetId { chain_id: 200, asset_type: LOCAL, asset_

const KSM_ASSET_ID: AssetId = AssetId { chain_id: 200, asset_type: LOCAL, asset_index: 3 };

const BTC_ASSET_ID: AssetId = AssetId { chain_id: 300, asset_type: RESERVED, asset_index: 3 };
const BTC_ASSET_ID: AssetId = AssetId { chain_id: 0, asset_type: NATIVE, asset_index: 0 };

const ETH_ASSET_ID: AssetId = AssetId { chain_id: 300, asset_type: NATIVE, asset_index: 0 };

Expand Down Expand Up @@ -219,6 +219,70 @@ fn foreign_get_out_price_should_work() {
});
}

#[test]
fn pot_should_grow() {
new_test_ext().execute_with(|| {
assert_ok!(DexPallet::foreign_mint(DOT_ASSET_ID, &ALICE, u128::MAX));
assert_ok!(DexPallet::foreign_mint(BTC_ASSET_ID, &ALICE, u128::MAX));

let total_supply_dot = 50000 * DOT_UNIT;
let total_supply_btc = 50000 * BTC_UNIT;

assert_ok!(DexPallet::create_pair(RawOrigin::Root.into(), DOT_ASSET_ID, BTC_ASSET_ID,));

assert_ok!(DexPallet::inner_add_liquidity(
&ALICE,
DOT_ASSET_ID,
BTC_ASSET_ID,
total_supply_dot,
total_supply_btc,
0,
0
));
let balance_dot =
<Test as Config>::MultiAssetsHandler::balance_of(DOT_ASSET_ID, &PAIR_DOT_BTC);
let balance_btc =
<Test as Config>::MultiAssetsHandler::balance_of(BTC_ASSET_ID, &PAIR_DOT_BTC);

// // println!("balance_dot {} balance_btc {}", balance_dot, balance_btc);
// assert_eq!(balance_dot, 50000000000000000000);
// assert_eq!(balance_btc, 5000000000000);

let path = vec![BTC_ASSET_ID, DOT_ASSET_ID];
let amount_out_min = BTC_UNIT * 996 / 1000;
let amount_in = 1 * DOT_UNIT;
assert_ok!(DexPallet::inner_swap_exact_assets_for_assets(
&ALICE,
amount_in,
amount_out_min,
&path,
&BOB,
));

let btc_balance = <Test as Config>::MultiAssetsHandler::balance_of(BTC_ASSET_ID, &BOB);

// println!("btc_balance {}", btc_balance);
assert_eq!(btc_balance, 99698012);

assert!(btc_balance > amount_out_min);

let path = vec![BTC_ASSET_ID.clone(), DOT_ASSET_ID.clone()];
let amount_in = 1 * BTC_UNIT;
let amount_out_min = DOT_UNIT * 996 / 1000;
assert_ok!(DexPallet::inner_swap_exact_assets_for_assets(
&ALICE,
amount_in,
amount_out_min,
&path,
&BOB,
));
let dot_balance = <Test as Config>::MultiAssetsHandler::balance_of(DOT_ASSET_ID, &BOB);

// println!("dot_balance {}", dot_balance);
assert_eq!(dot_balance, 997019939603584)
})
}

#[test]
fn inner_swap_exact_assets_for_assets_should_work() {
new_test_ext().execute_with(|| {
Expand Down
10 changes: 3 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 Down Expand Up @@ -210,13 +209,10 @@ impl zenlink_protocol::Config for Test {
type RuntimeEvent = RuntimeEvent;
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances, LocalAssetAdaptor<Tokens>>;
type PalletId = ZenlinkPalletId;
type PotId = ZenlinkPalletId;
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