Skip to content

Commit 3804843

Browse files
committed
Use static 0.3% exchange fee rate and fix set_fee_point
1 parent 5c26b98 commit 3804843

10 files changed

Lines changed: 48 additions & 51 deletions

File tree

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ Through the `UAI`(unified asset identifier) and `MultiAssetsHandler` interfaces,
2727
## Zenlink Protocol v0.4.0 Features
2828
- Based on the `newest` XCM design
2929
- Based on `FRAMEv2`
30-
- Swap exchange fee `configurable`
3130
- `Compatible` Polkadot XCMP cross-chain asset processing
3231
- Zenlink Protocol registration whitelist-XCM `trust collection management`
3332
- Through Transfer-By-XCM, `assets can flow freely` between parachains

example/runtime/src/zenlink.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ use super::{
1414

1515
parameter_types! {
1616
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
17-
pub const GetExchangeFee: (u32, u32) = (3, 1000); // 0.3%
1817
pub SelfParaId: u32 = ParachainInfo::get().into();
1918

2019
// xcm
@@ -132,7 +131,6 @@ pub type MultiAssets = ZenlinkMultiAssets<ZenlinkProtocol, Balances, LocalAssetA
132131

133132
impl zenlink_protocol::Config for Runtime {
134133
type Event = Event;
135-
type GetExchangeFee = GetExchangeFee;
136134
type MultiAssetsHandler = MultiAssets;
137135
type PalletId = ZenlinkPalletId;
138136
type SelfParaId = SelfParaId;

zenlink-protocol/src/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ Through the `UAI`(unified asset identifier) and `MultiAssetsHandler` interfaces,
99
## Zenlink Protocol v0.4.0 Features
1010
- Based on the `newest` XCM design
1111
- Based on `FRAMEv2`
12-
- Swap exchange fee rate `configurable`
1312
- `Compatible` Polkadot XCMP cross-chain asset processing
1413
- Zenlink Protocol registration whitelist-XCM `trust collection management`
1514
- Through Transfer-By-XCM, `assets can flow freely` between parachains

zenlink-protocol/src/fee/mock.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ parameter_types! {
3232

3333
pub const BlockHashCount: u64 = 250;
3434
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
35-
pub const GetExchangeFee: (u32, u32) = (3, 1000); // 0.3%
3635
pub const MaxReserves: u32 = 50;
3736
}
3837

@@ -76,7 +75,6 @@ impl pallet_balances::Config for Test {
7675

7776
impl Config for Test {
7877
type Event = Event;
79-
type GetExchangeFee = GetExchangeFee;
8078
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances>;
8179
type PalletId = ZenlinkPalletId;
8280
type TargetChains = ();

zenlink-protocol/src/fee/tests.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ fn fee_meta_setter_should_not_work() {
6666
DexPallet::set_fee_point(Origin::signed(BOB), 0),
6767
Error::<Test>::RequireProtocolAdmin
6868
);
69+
70+
assert_noop!(
71+
DexPallet::set_fee_point(Origin::signed(ALICE), 31u8),
72+
Error::<Test>::InvalidFeePoint
73+
);
6974
})
7075
}
7176

@@ -278,11 +283,12 @@ fn turn_on_protocol_fee_remove_liquidity_should_work() {
278283
fn turn_on_protocol_fee_swap_have_fee_should_work() {
279284
new_test_ext().execute_with(|| {
280285
// 1. turn on the protocol fee
281-
// use default rate: 1/6
282286

283287
let sorted_pair = DexPallet::sort_asset_id(DOT_ASSET_ID, BTC_ASSET_ID);
284288

285289
assert_ok!(DexPallet::set_fee_receiver(Origin::signed(ALICE), Some(BOB)));
290+
// use default rate: 0.3% * 1 / 6 = 0.0005
291+
assert_ok!(DexPallet::set_fee_point(Origin::signed(ALICE), 5u8));
286292
assert_eq!(DexPallet::k_last(sorted_pair), 0);
287293

288294
// 2. first add_liquidity

zenlink-protocol/src/foreign/mock.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ parameter_types! {
3232

3333
pub const BlockHashCount: u64 = 250;
3434
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
35-
pub const GetExchangeFee: (u32, u32) = (3, 1000); // 0.3%
3635
pub const MaxReserves: u32 = 50;
3736
}
3837

@@ -76,7 +75,6 @@ impl pallet_balances::Config for Test {
7675

7776
impl Config for Test {
7877
type Event = Event;
79-
type GetExchangeFee = GetExchangeFee;
8078
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances>;
8179
type PalletId = ZenlinkPalletId;
8280
type TargetChains = ();

zenlink-protocol/src/lib.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use frame_support::{
1818
PalletId, RuntimeDebug,
1919
};
2020
use sp_core::U256;
21-
use sp_runtime::traits::{AccountIdConversion, Hash, IntegerSquareRoot, One, StaticLookup, UniqueSaturatedInto, Zero};
21+
use sp_runtime::traits::{AccountIdConversion, Hash, IntegerSquareRoot, One, StaticLookup, Zero};
2222
use sp_std::{convert::TryInto, marker::PhantomData, prelude::*};
2323

2424
// -------xcm--------
@@ -67,12 +67,6 @@ pub mod pallet {
6767
pub trait Config: frame_system::Config {
6868
/// Because this pallet emits events, it depends on the runtime's definition of an event.
6969
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
70-
/// Trading fee rate
71-
/// The first item of the tuple is the numerator of the fee rate, second
72-
/// item is the denominator, fee_rate = numerator / denominator,
73-
/// use (u32, u32) over `Rate` type to minimize internal division operation.
74-
#[pallet::constant]
75-
type GetExchangeFee: Get<(u32, u32)>;
7670
/// The assets interface beyond native currency and other assets.
7771
type MultiAssetsHandler: MultiAssetsHandler<Self::AccountId>;
7872
/// This pallet id.
@@ -147,8 +141,10 @@ pub mod pallet {
147141
pub fee_admin: T::AccountId,
148142
/// The receiver of the protocol fee.
149143
pub fee_receiver: Option<T::AccountId>,
150-
/// The fee point which integer between [0,256),
151-
/// 0 means 100% new liquidity and 255 means 1/256.
144+
/// The fee point which integer between [0,30]
145+
/// 0 means no protocol fee.
146+
/// 30 means 0.3% * 100% = 0.0030.
147+
/// default is 5 and means 0.3% * 1 / 6 = 0.0005.
152148
pub fee_point: u8,
153149
}
154150

@@ -230,6 +226,8 @@ pub mod pallet {
230226
pub enum Error<T> {
231227
/// Require the admin who can reset the admin and receiver of the protocol fee.
232228
RequireProtocolAdmin,
229+
/// Invalid fee_point
230+
InvalidFeePoint,
233231
/// Unsupported AssetId by this ZenlinkProtocol Version.
234232
UnsupportedAssetType,
235233
/// Account balance must be greater than or equal to the transfer amount.
@@ -329,12 +327,15 @@ pub mod pallet {
329327
/// # Arguments
330328
///
331329
/// - `fee_point`:
332-
/// The fee point which integer between [0,256),
333-
/// 0 means mint 100% new liquidity and 255 means 1/256.
330+
/// The fee_point which integer between [0,30]
331+
/// 0 means no protocol fee.
332+
/// 30 means 0.3% * 100% = 0.0030.
333+
/// default is 5 and means 0.3% * 1 / 6 = 0.0005.
334334
#[pallet::weight(1_000_000)]
335335
pub fn set_fee_point(origin: OriginFor<T>, fee_point: u8) -> DispatchResult {
336336
let origin = ensure_signed(origin)?;
337337
ensure!(origin == Self::fee_meta().0, Error::<T>::RequireProtocolAdmin);
338+
ensure!(fee_point <= 30, Error::<T>::InvalidFeePoint);
338339

339340
FeeMeta::<T>::mutate(|fee_meta| (*fee_meta).2 = fee_point);
340341

zenlink-protocol/src/liquidity/mock.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ parameter_types! {
3232

3333
pub const BlockHashCount: u64 = 250;
3434
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
35-
pub const GetExchangeFee: (u32, u32) = (3, 1000); // 0.3%
3635
pub const MaxReserves: u32 = 50;
3736
}
3837

@@ -76,7 +75,6 @@ impl pallet_balances::Config for Test {
7675

7776
impl Config for Test {
7877
type Event = Event;
79-
type GetExchangeFee = GetExchangeFee;
8078
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances>;
8179
type PalletId = ZenlinkPalletId;
8280
type TargetChains = ();

zenlink-protocol/src/swap/mock.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ parameter_types! {
3232

3333
pub const BlockHashCount: u64 = 250;
3434
pub const ZenlinkPalletId: PalletId = PalletId(*b"/zenlink");
35-
pub const GetExchangeFee: (u32, u32) = (3, 1000); // 0.3%
3635
pub const MaxReserves: u32 = 50;
3736
}
3837

@@ -76,7 +75,6 @@ impl pallet_balances::Config for Test {
7675

7776
impl Config for Test {
7877
type Event = Event;
79-
type GetExchangeFee = GetExchangeFee;
8078
type MultiAssetsHandler = ZenlinkMultiAssets<Zenlink, Balances>;
8179
type PalletId = ZenlinkPalletId;
8280
type TargetChains = ();

zenlink-protocol/src/swap/mod.rs

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ impl<T: Config> Pallet<T> {
9292

9393
let mint_fee = Self::mint_protocol_fee(reserve_0, reserve_1, asset_0, asset_1, *total_liquidity);
9494
if let Some(fee_to) = Self::fee_meta().1 {
95-
if mint_fee > 0 {
95+
if mint_fee > 0 && Self::fee_meta().2 > 0 {
9696
Self::mutate_liquidity(asset_0, asset_1, &fee_to, mint_fee, true)?;
9797

9898
let old_total_liquidity = *total_liquidity;
@@ -116,12 +116,14 @@ impl<T: Config> Pallet<T> {
116116
T::MultiAssetsHandler::transfer(asset_1, who, &pair_account, amount_1)?;
117117

118118
if let Some(_fee_to) = Self::fee_meta().1 {
119-
// update reserve_0 and reserve_1
120-
let reserve_0 = T::MultiAssetsHandler::balance_of(asset_0, pair_account);
121-
let reserve_1 = T::MultiAssetsHandler::balance_of(asset_1, pair_account);
119+
if Self::fee_meta().2 > 0 {
120+
// update reserve_0 and reserve_1
121+
let reserve_0 = T::MultiAssetsHandler::balance_of(asset_0, pair_account);
122+
let reserve_1 = T::MultiAssetsHandler::balance_of(asset_1, pair_account);
122123

123-
// We allow reserve_0.saturating_mul(reserve_1) to overflow
124-
Self::mutate_k_last(asset_0, asset_1, reserve_0.saturating_mul(reserve_1));
124+
// We allow reserve_0.saturating_mul(reserve_1) to overflow
125+
Self::mutate_k_last(asset_0, asset_1, reserve_0.saturating_mul(reserve_1));
126+
}
125127
}
126128

127129
Self::deposit_event(Event::LiquidityAdded(
@@ -170,7 +172,7 @@ impl<T: Config> Pallet<T> {
170172

171173
let mint_fee = Self::mint_protocol_fee(reserve_0, reserve_1, asset_0, asset_1, *total_liquidity);
172174
if let Some(fee_to) = Self::fee_meta().1 {
173-
if mint_fee > 0 {
175+
if mint_fee > 0 && Self::fee_meta().2 > 0 {
174176
Self::mutate_liquidity(asset_0, asset_1, &fee_to, mint_fee, true)?;
175177

176178
let old_total_liquidity = *total_liquidity;
@@ -190,12 +192,14 @@ impl<T: Config> Pallet<T> {
190192
T::MultiAssetsHandler::transfer(asset_1, &pair_account, recipient, amount_1)?;
191193

192194
if let Some(_fee_to) = Self::fee_meta().1 {
193-
// update reserve_0 and reserve_1
194-
let reserve_0 = T::MultiAssetsHandler::balance_of(asset_0, pair_account);
195-
let reserve_1 = T::MultiAssetsHandler::balance_of(asset_1, pair_account);
195+
if Self::fee_meta().2 > 0 {
196+
// update reserve_0 and reserve_1
197+
let reserve_0 = T::MultiAssetsHandler::balance_of(asset_0, pair_account);
198+
let reserve_1 = T::MultiAssetsHandler::balance_of(asset_1, pair_account);
196199

197-
// We allow reserve_0.saturating_mul(reserve_1) to overflow
198-
Self::mutate_k_last(asset_0, asset_1, reserve_0.saturating_mul(reserve_1));
200+
// We allow reserve_0.saturating_mul(reserve_1) to overflow
201+
Self::mutate_k_last(asset_0, asset_1, reserve_0.saturating_mul(reserve_1));
202+
}
199203
}
200204

201205
Self::deposit_event(Event::LiquidityRemoved(
@@ -303,7 +307,7 @@ impl<T: Config> Pallet<T> {
303307
}
304308

305309
/// Refer: https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2Pair.sol#L88
306-
/// Take as a 1/(fee_point+1) cut of the ExchangeFeeRate fees earned by liquidity providers
310+
/// Take as a [0, 100%] cut of the exchange fees earned by liquidity providers
307311
pub(crate) fn mint_protocol_fee(
308312
reserve_0: AssetBalance,
309313
reserve_1: AssetBalance,
@@ -315,16 +319,18 @@ impl<T: Config> Pallet<T> {
315319
let mut mint_fee: AssetBalance = 0;
316320

317321
if let Some(_fee_to) = Self::fee_meta().1 {
318-
if new_k_last != 0 {
322+
if new_k_last != 0 && Self::fee_meta().2 > 0 {
319323
// u128 support integer_sqrt, but U256 not support
320324
// thus we allow reserve_0.saturating_mul(reserve_1) to overflow
321325
let root_k = U256::from(reserve_0.saturating_mul(reserve_1).integer_sqrt());
322326
let root_k_last = U256::from(new_k_last.integer_sqrt());
323327
if root_k > root_k_last {
324328
let fee_point = Self::fee_meta().2;
329+
let fix_fee_point = (30 - fee_point) / fee_point;
325330
let numerator = U256::from(total_liquidity).saturating_mul(root_k.saturating_sub(root_k_last));
326-
327-
let denominator = root_k.saturating_mul(U256::from(fee_point)).saturating_add(root_k_last);
331+
let denominator = root_k
332+
.saturating_mul(U256::from(fix_fee_point))
333+
.saturating_add(root_k_last);
328334

329335
let liquidity = numerator
330336
.checked_div(denominator)
@@ -389,6 +395,7 @@ impl<T: Config> Pallet<T> {
389395
})
390396
}
391397

398+
// 0.3% exchange fee rate
392399
fn get_amount_in(
393400
output_amount: AssetBalance,
394401
input_reserve: AssetBalance,
@@ -398,14 +405,12 @@ impl<T: Config> Pallet<T> {
398405
return Zero::zero();
399406
}
400407

401-
let (fee_numerator, fee_denominator) = T::GetExchangeFee::get();
402-
403408
let numerator = U256::from(input_reserve)
404409
.saturating_mul(U256::from(output_amount))
405-
.saturating_mul(U256::from(fee_denominator));
410+
.saturating_mul(U256::from(1000));
406411

407-
let denominator = (U256::from(output_reserve).saturating_sub(U256::from(output_amount)))
408-
.saturating_mul(U256::from(fee_denominator.saturating_sub(fee_numerator)));
412+
let denominator =
413+
(U256::from(output_reserve).saturating_sub(U256::from(output_amount))).saturating_mul(U256::from(997));
409414

410415
numerator
411416
.checked_div(denominator)
@@ -414,6 +419,7 @@ impl<T: Config> Pallet<T> {
414419
.unwrap_or_else(Zero::zero)
415420
}
416421

422+
// 0.3% exchange fee rate
417423
fn get_amount_out(
418424
input_amount: AssetBalance,
419425
input_reserve: AssetBalance,
@@ -423,16 +429,12 @@ impl<T: Config> Pallet<T> {
423429
return Zero::zero();
424430
}
425431

426-
let (fee_numerator, fee_denominator) = T::GetExchangeFee::get();
427-
428-
let input_amount_with_fee = U256::from(
429-
input_amount.saturating_mul(fee_denominator.saturating_sub(fee_numerator).unique_saturated_into()),
430-
);
432+
let input_amount_with_fee = U256::from(input_amount).saturating_mul(U256::from(997));
431433

432434
let numerator = input_amount_with_fee.saturating_mul(U256::from(output_reserve));
433435

434436
let denominator = U256::from(input_reserve)
435-
.saturating_mul(U256::from(fee_denominator))
437+
.saturating_mul(U256::from(1000))
436438
.saturating_add(input_amount_with_fee);
437439

438440
numerator

0 commit comments

Comments
 (0)