Skip to content

Commit

Permalink
v4.1.3
Browse files Browse the repository at this point in the history
v4.1.3
  • Loading branch information
platschi authored Nov 3, 2022
2 parents fed8943 + 25eaf6c commit db65d94
Show file tree
Hide file tree
Showing 37 changed files with 5,788 additions and 6,210 deletions.
Binary file modified assets/png/pnl-graphic.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/svg/futures/deposit-withdraw-arrows.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions assets/svg/futures/switch-arrows.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions assets/svg/futures/withdraw-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 11 additions & 6 deletions components/Text/NumberLabel.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import styled, { css } from 'styled-components';

const sharedStyles = css<{ fontWeight?: string; themeColor?: string }>`
type Contrast = 'strong' | 'mild';

const sharedStyles = css<{ fontWeight?: string; contrast?: Contrast }>`
font-family: ${(props) => props.theme.fonts.mono};
font-weight: ${(props) => props.fontWeight || 'regular'};
color: ${({ themeColor, theme }) =>
// @ts-ignore
(themeColor && theme.colors.selectedTheme[themeColor]) || theme.colors.selectedTheme.gray};
color: ${({ contrast, theme }) => {
if (!contrast) return theme.colors.selectedTheme.gray;
return contrast === 'strong'
? theme.colors.selectedTheme.text.value
: theme.colors.selectedTheme.text.label;
}};
`;

export const NumberDiv = styled.div<{ fontWeight?: string; themeColor?: string }>`
export const NumberDiv = styled.div<{ fontWeight?: string; contrast?: Contrast }>`
${sharedStyles}
`;

export const NumberSpan = styled.span<{ fontWeight?: string; themeColor?: string }>`
export const NumberSpan = styled.span<{ fontWeight?: string; contrast?: Contrast }>`
${sharedStyles}
`;
130 changes: 66 additions & 64 deletions hooks/useFuturesData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import { useRefetchContext } from 'contexts/RefetchContext';
import { KWENTA_TRACKING_CODE, ORDER_PREVIEW_ERRORS } from 'queries/futures/constants';
import { PositionSide, FuturesTradeInputs, FuturesAccountType } from 'queries/futures/types';
import useGetFuturesPotentialTradeDetails from 'queries/futures/useGetFuturesPotentialTradeDetails';
import { getFuturesMarketContract } from 'queries/futures/utils';
import {
crossMarginMarginDeltaState,
currentMarketState,
Expand Down Expand Up @@ -124,11 +123,14 @@ const useFuturesData = () => {
return crossMarginAvailable ? { freeMargin: crossMarginAccountOverview.freeMargin } : null;
}, [crossMarginAccountOverview.freeMargin, crossMarginAvailable]);

const freeMargin = useMemo(() => crossMarginAccount?.freeMargin ?? zeroBN, [
crossMarginAccount?.freeMargin,
]);

const selectedLeverage = useMemo(() => {
const effectiveLeverage = position?.position?.leverage.toString() || '';
const leverage = effectiveLeverage || preferredLeverage[marketAsset] || DEFAULT_LEVERAGE;
const leverage = preferredLeverage[marketAsset] || DEFAULT_LEVERAGE;
return String(Math.min(maxLeverage.toNumber(), Number(leverage)));
}, [position?.position?.leverage, preferredLeverage, marketAsset, maxLeverage]);
}, [preferredLeverage, marketAsset, maxLeverage]);

const remainingMargin: Wei = useMemo(() => {
if (selectedAccountType === 'isolated_margin') {
Expand Down Expand Up @@ -162,24 +164,34 @@ const useFuturesData = () => {
if (aboveMaxLeverage && position?.position?.side === leverageSide) {
return zeroBN;
}
const currentValue = position?.position?.notionalValue ?? zeroBN;
let maxUsd = remainingMargin.mul(selectedLeverage);
maxUsd =

const totalMargin =
position?.position?.side === leverageSide
? maxUsd.sub(currentValue)
: maxUsd.add(currentValue);
maxUsd = maxUsd.sub(maxFee);
const buffer = maxUsd.mul(0.01);
? freeMargin
: freeMargin.add(position?.remainingMargin ?? zeroBN);

let maxUsd = totalMargin.mul(selectedLeverage);
if (position?.position?.side !== leverageSide) {
const notionalValue = position?.position?.size.mul(tradePrice);
maxUsd = maxUsd.add(notionalValue ?? zeroBN);
}

maxUsd = maxUsd.sub(maxFee.mul(selectedLeverage));
let buffer = maxUsd.mul(0.01);

return maxUsd.abs().sub(buffer);
}, [
selectedLeverage,
maxLeverage,
maxFee,
aboveMaxLeverage,
freeMargin,
remainingMargin,
leverageSide,
tradePrice,
selectedAccountType,
position?.position?.notionalValue,
position?.position?.size,
position?.remainingMargin,
position?.position?.side,
]);

Expand All @@ -194,15 +206,6 @@ const useFuturesData = () => {
}
}, [orderType, limitOrderFee, stopOrderFee]);

const getTradeFee = useCallback(
(size: Wei) => {
if (!synthetixjs) return ZERO_FEES;
const FuturesMarketContract = getFuturesMarketContract(marketAsset, synthetixjs.contracts);
return FuturesMarketContract.orderFee(size.toBN());
},
[synthetixjs, marketAsset]
);

const getCrossMarginEthBal = useCallback(async () => {
if (!crossMarginAddress) return zeroBN;
const bal = await provider.getBalance(crossMarginAddress);
Expand All @@ -227,10 +230,12 @@ const useFuturesData = () => {
),
]);
const staticRate = computeMarketFee(market, sizeDelta);
const total = crossMarginTradeFee

let total = crossMarginTradeFee
.add(dynamicFeeRate.feeRate)
.add(staticRate)
.add(advancedOrderFeeRate);

return total;
},
[
Expand All @@ -246,13 +251,14 @@ const useFuturesData = () => {
async (susdSizeDelta: Wei, nativeSizeDelta: Wei) => {
if (!synthetixjs) return ZERO_FEES;

const [volatilityFee, orderFee] = await Promise.all([
synthetixjs.contracts.Exchanger.dynamicFeeRateForExchange(
ethers.utils.formatBytes32String('sUSD'),
ethers.utils.formatBytes32String(marketAsset)
),
getTradeFee(nativeSizeDelta),
]);
const volatilityFeeRate = await synthetixjs.contracts.Exchanger.dynamicFeeRateForExchange(
ethers.utils.formatBytes32String('sUSD'),
ethers.utils.formatBytes32String(marketAsset)
);
const volatilityFeeWei = wei(volatilityFeeRate.feeRate);
const susdSize = susdSizeDelta.abs();
const staticRate = computeMarketFee(market, nativeSizeDelta);
const tradeFee = susdSize.mul(staticRate).add(susdSize.mul(volatilityFeeWei));

const currentDeposit =
orderType === 'limit' || orderType === 'stop market'
Expand All @@ -263,20 +269,17 @@ const useFuturesData = () => {
: zeroBN;

const crossMarginFee =
selectedAccountType === 'cross_margin'
? susdSizeDelta.abs().mul(crossMarginTradeFee)
: zeroBN;
selectedAccountType === 'cross_margin' ? susdSize.mul(crossMarginTradeFee) : zeroBN;
const limitStopOrderFee = calculateCrossMarginFee(susdSizeDelta);
const orderFeeWei = wei(orderFee.fee);
const volatilityFeeWei = wei(volatilityFee.feeRate);
const tradeFeeWei = wei(tradeFee);

const fees = {
staticFee: orderFeeWei,
staticFee: tradeFeeWei,
crossMarginFee: crossMarginFee,
dynamicFeeRate: volatilityFeeWei,
keeperEthDeposit: requiredDeposit,
limitStopOrderFee: limitStopOrderFee,
total: orderFeeWei.add(crossMarginFee).add(limitStopOrderFee),
total: tradeFeeWei.add(crossMarginFee).add(limitStopOrderFee),
};
setTradeFees(fees);
return fees;
Expand All @@ -287,9 +290,9 @@ const useFuturesData = () => {
marketAsset,
synthetixjs,
orderType,
market,
calculateCrossMarginFee,
setTradeFees,
getTradeFee,
getCrossMarginEthBal,
]
);
Expand Down Expand Up @@ -350,17 +353,17 @@ const useFuturesData = () => {
const onTradeAmountChange = useCallback(
(
value: string,
usdPrice: Wei,
currencyType: 'usd' | 'native',
options?: { simulateChange?: boolean; crossMarginLeverage?: Wei }
) => {
if (!value || tradePrice.eq(0)) {
if (!value || usdPrice.eq(0)) {
resetTradeState();
return;
}

const positiveTrade = leverageSide === PositionSide.LONG;
const nativeSize = currencyType === 'native' ? wei(value) : wei(value).div(tradePrice);
const usdSize = currencyType === 'native' ? tradePrice.mul(value) : wei(value);
const nativeSize = currencyType === 'native' ? wei(value) : wei(value).div(usdPrice);
const usdSize = currencyType === 'native' ? usdPrice.mul(value) : wei(value);
const changeEnabled = remainingMargin.gt(0) && value !== '';
const isolatedMarginLeverage = changeEnabled ? usdSize.div(remainingMargin) : zeroBN;

Expand All @@ -376,7 +379,7 @@ const useFuturesData = () => {
susdSize: changeEnabled ? weiToString(usdSize) : '',
nativeSizeDelta: positiveTrade ? nativeSize : nativeSize.neg(),
susdSizeDelta: positiveTrade ? usdSize : usdSize.neg(),
orderPrice: tradePrice,
orderPrice: usdPrice,
leverage: String(floorNumber(leverage)),
};

Expand All @@ -388,7 +391,6 @@ const useFuturesData = () => {
}
},
[
tradePrice,
remainingMargin,
maxLeverage,
selectedLeverage,
Expand Down Expand Up @@ -419,13 +421,9 @@ const useFuturesData = () => {
const onLeverageChange = useCallback(
(leverage: number) => {
if (selectedAccountType === 'cross_margin') {
if (position?.position) {
onChangeOpenPosLeverage(leverage);
} else {
onTradeAmountChange('', 'usd', {
crossMarginLeverage: wei(leverage),
});
}
onTradeAmountChange('', tradePrice, 'usd', {
crossMarginLeverage: wei(leverage),
});
} else {
if (leverage <= 0) {
resetTradeState();
Expand All @@ -434,26 +432,25 @@ const useFuturesData = () => {
marketAssetRate.eq(0) || remainingMargin.eq(0)
? ''
: wei(leverage).mul(remainingMargin).div(marketAssetRate).toString();
onTradeAmountChange(newTradeSize, 'native');
onTradeAmountChange(newTradeSize, tradePrice, 'native');
}
}
},
[
remainingMargin,
marketAssetRate,
selectedAccountType,
position?.position,
tradePrice,
resetTradeState,
onTradeAmountChange,
onChangeOpenPosLeverage,
]
);

const onTradeOrderPriceChange = useCallback(
(price: string) => {
if (price && tradeInputs.susdSize) {
// Recalc the trade
onTradeAmountChange(tradeInputs.susdSize, 'usd');
onTradeAmountChange(tradeInputs.susdSize, wei(price), 'usd');
}
},
[tradeInputs, onTradeAmountChange]
Expand Down Expand Up @@ -536,29 +533,32 @@ const useFuturesData = () => {
return;
}
try {
const currentValue = position?.position?.notionalValue || zeroBN;
let maxUsd = remainingMargin.mul(selectedLeverage);
maxUsd =
const totalMargin =
position?.position?.side === leverageSide
? maxUsd.sub(currentValue)
: maxUsd.add(currentValue);
? freeMargin
: freeMargin.add(position?.remainingMargin ?? zeroBN);

let maxUsd = totalMargin.mul(selectedLeverage);
if (position?.position?.side !== leverageSide) {
maxUsd = maxUsd.add(position?.position?.notionalValue ?? zeroBN);
}
const totalRate = await totalFeeRate(maxUsd);
const totalMaxFee = maxUsd.mul(totalRate);
setMaxFee(totalMaxFee.mul(selectedLeverage));
setMaxFee(totalMaxFee);
} catch (e) {
logError(e);
}
};
getMaxFee();
}, [
setMaxFee,
getTradeFee,
totalFeeRate,
crossMarginTradeFee,
leverageSide,
position?.remainingMargin,
position?.position?.notionalValue,
position?.position?.side,
remainingMargin,
freeMargin,
tradePrice,
selectedLeverage,
]);
Expand All @@ -572,7 +572,7 @@ const useFuturesData = () => {
) {
setOrderType('market');
}
onTradeAmountChange(tradeInputs.susdSize, 'usd');
onTradeAmountChange(tradeInputs.susdSize, tradePrice, 'usd');

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedAccountType, orderType, network.id]);
Expand All @@ -589,7 +589,7 @@ const useFuturesData = () => {

useEffect(() => {
if (tradeInputs.susdSizeDelta.eq(0)) return;
onTradeAmountChange(tradeInputs.susdSize, 'usd');
onTradeAmountChange(tradeInputs.susdSize, tradePrice, 'usd');
// Only want to react to leverage side change
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [leverageSide]);
Expand Down Expand Up @@ -623,6 +623,7 @@ const useFuturesData = () => {
submitCrossMarginOrder,
resetTradeState,
onTradeOrderPriceChange,
onChangeOpenPosLeverage,
marketAssetRate,
position,
marketAsset,
Expand All @@ -633,6 +634,7 @@ const useFuturesData = () => {
selectedLeverage,
error,
debounceFetchPreview,
tradePrice,
};
};

Expand Down
Loading

1 comment on commit db65d94

@vercel
Copy link

@vercel vercel bot commented on db65d94 Nov 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

kwenta – ./

kwenta-git-main-kwenta.vercel.app
kwenta.io
kwenta-kwenta.vercel.app

Please sign in to comment.