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

Fix XST LP fees calculation #635

Merged
merged 3 commits into from
Jul 31, 2023
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
4 changes: 2 additions & 2 deletions pallets/xst/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -852,11 +852,11 @@ impl<T: Config> Pallet<T> {
<T as pallet::Config>::PriceToolsPallet::get_average_price(
&T::GetSyntheticBaseAssetId::get(),
&T::GetBaseAssetId::get(),
// Since `Sell` is more expensive in case if we are selling XST
// Since `Buy` is more expensive in case if we are buying XOR
// (x XST -> y XOR; y XOR -> x' XST, x' < x),
// it seems logical to show this amount in order
// to not accidentally lie about the price.
PriceVariant::Sell,
PriceVariant::Buy,
)?
.into();
Ok((fee_amount * output_to_base)
Expand Down
28 changes: 14 additions & 14 deletions pallets/xst/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,8 @@ mod tests {
// amount in = 100 XSTUSD (A_in)
// amount out = (A_in * S) / X = (100 * 1) / 220 = 0.(45) XST (A_out)
// deduced fee = A_out * F = 0.(45) * 0.00666 = 0.0030(27) XST (F_xst)
// deduced fee in XOR = F_xst / X_b = 0.0030(27) / 0.6 = 0.0050(45) XOR (since we are buying XOR with XST)
assert_approx_eq!(price_a.fee, balance!(0.005045454545454545), 2);
// deduced fee in XOR = F_xst / X_b = 0.0030(27) / 0.6 = 0.0060(54) XOR (since we are buying XOR with XST)
assert_approx_eq!(price_a.fee, balance!(0.006054545454545454), 2);
// amount out with deduced fee = A_out - F_xst = 0.(45) - 0.0030(27) = 0.4515(18) XST
assert_approx_eq!(price_a.amount, balance!(0.451518181818181818), 2);

Expand All @@ -371,7 +371,7 @@ mod tests {
.unwrap();
assert_eq!(price_b.fee, balance!(0));
// we need to convert XOR fee back to XST
let xst_fee = (FixedWrapper::from(price_a.fee)*balance!(0.6)).into_balance();
let xst_fee = (FixedWrapper::from(price_a.fee)*balance!(0.5)).into_balance();
assert_approx_eq!(price_b.amount, xst_fee + price_a.amount, 2);

let (price_a, _) = XSTPool::quote(
Expand All @@ -393,8 +393,8 @@ mod tests {
// amount out = 100 XST (A_in)
// deduced fee = A_out / (1 - F_r) - A_out = 100 / (1 - 0.00666) - 100 = 0.670465298890611 XST (F_xst)
// amount in = ((A_out + F_xst) * X) / S = ((100 + 0.670465298890611) * 220) / 1 = 22147.5023657559344 XSTUSD (A_in)
// deduced fee in XOR = F_xst / X_b = 0.670465298890611 / 0.6 = 1.11744216481768504 XOR (since we are buying XOR with XST)
assert_approx_eq!(price_a.fee, balance!(1.11744216481768504), 1000);
// deduced fee in XOR = F_xst / X_b = 0.670465298890611 / 0.5 = 1.340930597781222944 XOR (since we are buying XOR with XST)
assert_approx_eq!(price_a.fee, balance!(1.340930597781222944), 1000);
assert_approx_eq!(price_a.amount, balance!(22147.5023657559344), 1000_000);

let (price_b, _) = XSTPool::quote(
Expand Down Expand Up @@ -465,8 +465,8 @@ mod tests {
// amount in = 100 XSTUSD (A_in)
// amount out = (A_in * S) / X = (100 * 1) / 220 = 0.(45) XST (A_out)
// deduced fee = A_out * F = 0.(45) * 0.00666 = 0.0030(27) XST (F_xst)
// deduced fee in XOR = F_xst / X_b = 0.0030(27) / 0.6 = 0.0050(45) XOR (since we are buying XOR with XST)
assert_approx_eq!(price_a.fee, balance!(0.005045454545454545), 2);
// deduced fee in XOR = F_xst / X_b = 0.0030(27) / 0.5 = 0.0060(54) XOR (since we are buying XOR with XST)
assert_approx_eq!(price_a.fee, balance!(0.006054545454545454), 2);

// Sell
let (price_c, _) = XSTPool::quote(
Expand Down Expand Up @@ -497,9 +497,9 @@ mod tests {
// amount out = 100 XSTUSD (A_out)
// amount in = (A_out * S) / X = (100 * 1) / 150 = 0.(6) XST (A_in)
// deduced fee = A_in / (1 - F) - A_in = 0.(6) / (1 - 0.00666) - A_in ~ 0.004469768659270743 XST (F_xst)
// deduced fee in XOR = F_xst / X_b = 0.004469768659270743 / 0.6 ~ 0.007449614432117905 XOR
// deduced fee in XOR = F_xst / X_b = 0.004469768659270743 / 0.5 ~ 0.008939537319 XOR
// (since we are buying XOR with XST)
assert_approx_eq!(price_c.fee, balance!(0.007449614432117905), 2);
assert_approx_eq!(price_c.fee, balance!(0.008939537318541485), 2);
});
}

Expand Down Expand Up @@ -741,7 +741,7 @@ mod tests {
let xst_to_xor_price = PriceTools::get_average_price(
&XST.into(),
&XOR.into(),
PriceVariant::Sell,
PriceVariant::Buy,
).expect("Expected to calculate price XST->XOR");
let expected_fee_amount = FixedWrapper::from(quote_amount.amount() / 2) * FixedWrapper::from(xst_to_xor_price);

Expand Down Expand Up @@ -880,9 +880,9 @@ mod tests {
// fee ratio for XSTEURO = 0.3 (F_r)
// amount in = 100 XST (A_in)
// amount out = (A_in * X * (1 - F_r)) / S = (100 * 150 * 0.7) / 3 = 3500 XSTEURO (A_out)
// fee = F_xst / X_b = 0.3 * 100 / 0.6 = 50 XOR
// fee = F_xst / X_b = 0.3 * 100 / 0.5 = 60 XOR
assert_approx_eq!(swap_outcome_before.amount, balance!(3500), 10000);
assert_approx_eq!(swap_outcome_before.fee, balance!(50), 10000);
assert_approx_eq!(swap_outcome_before.fee, balance!(60), 10000);

assert_ok!(XSTPool::set_synthetic_asset_fee(
RuntimeOrigin::root(),
Expand All @@ -908,9 +908,9 @@ mod tests {
// fee ratio for XSTEURO = 0.6 (F_r) <- dynamic fee + synthetic fee
// amount in = 100 XST (A_in)
// amount out = (A_in * X * (1 - F_r)) / S = (100 * 150 * 0.4) / 3 = 2000 XSTEURO (A_out)
// fee = F_xst / X_b = 0.6 * 100 / 0.6 = 100 XOR
// fee = F_xst / X_b = 0.6 * 100 / 0.5 = 120 XOR
assert_approx_eq!(swap_outcome_after.amount, balance!(2000), 10000);
assert_approx_eq!(swap_outcome_after.fee, balance!(100), 10000);
assert_approx_eq!(swap_outcome_after.fee, balance!(120), 10000);
});
}

Expand Down