Skip to content

Commit

Permalink
v7.2.5
Browse files Browse the repository at this point in the history
v7.2.5
  • Loading branch information
platschi authored Jun 14, 2023
2 parents 82ec0fa + 7cf007c commit 81f2bad
Show file tree
Hide file tree
Showing 53 changed files with 292 additions and 264 deletions.
3 changes: 2 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"builtin",
"external",
"internal",
["parent", "sibling"]
"parent",
"sibling"
],
"newlines-between": "always",
"pathGroups": [
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ jobs:
category: "/language:${{matrix.language}}"

- name: eslint-annotations
uses: DerLev/[email protected].0
uses: DerLev/[email protected].1
Binary file added assets/png/currencies/sstETH.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: 2 additions & 1 deletion components/TVChart/DataFeed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const getPriceScale = (asset: string | null) => {
case 'BTC':
case 'BNB':
case 'ETH':
case 'stETH':
case 'XAU':
return 100;
case 'DOGE':
Expand All @@ -86,7 +87,7 @@ const fetchCombinedCandles = async (
networkId: NetworkId
) => {
const candleData = await requestCandlesticks(
getDisplayAsset(base),
getDisplayAsset(base)?.toUpperCase() ?? '',
from,
to,
resolutionToSeconds(resolution),
Expand Down
1 change: 1 addition & 0 deletions components/TVChart/TVChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
IPositionLineAdapter,
widget,
} from '../../public/static/charting_library';

import { DEFAULT_RESOLUTION } from './constants';
import DataFeedFactory from './DataFeed';
import { ChartPosition } from './types';
Expand Down
47 changes: 47 additions & 0 deletions components/TextToggle/TextToggle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import styled, { css } from 'styled-components';

import { FlexDiv, FlexDivCol } from 'components/layout/flex';
import { Body } from 'components/Text';

interface TextToggleProps<T> {
title: string;
options: T[];
selectedOption: T;
onOptionChange: (value: T) => void;
}

const TextToggle: React.FC<TextToggleProps<any>> = ({
title,
options,
selectedOption,
onOptionChange,
}) => {
return (
<FlexDivCol>
<Body color="secondary">{title}</Body>
<FlexDiv columnGap="10px">
{options.map((value) => (
<ToggleButton $active={selectedOption === value} onClick={() => onOptionChange(value)}>
{value}
</ToggleButton>
))}
</FlexDiv>
</FlexDivCol>
);
};

const ToggleButton = styled(Body)<{ $active: boolean }>`
cursor: pointer;
text-transform: capitalize;
color: ${(props) => props.theme.colors.selectedTheme.newTheme.text.disabled};
${(props) =>
props.$active &&
css`
color: ${props.theme.colors.selectedTheme.newTheme.text.primary};
font-family: ${(props) => props.theme.fonts.bold};
`}
`;

export default TextToggle;
1 change: 1 addition & 0 deletions components/TextToggle/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './TextToggle';
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kwenta",
"version": "7.2.4",
"version": "7.2.5",
"scripts": {
"dev": "next",
"build": "next build",
Expand Down
1 change: 1 addition & 0 deletions queries/futures/useGetStats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { truncateAddress } from 'utils/formatters/string';
import logError from 'utils/logError';

import { getFuturesStats } from '../../sdk/utils/subgraph';

import { AccountStat, FuturesStat } from './types';

const useGetStats = (homepage?: boolean, options?: UseQueryOptions<any>) => {
Expand Down
10 changes: 10 additions & 0 deletions sdk/constants/futures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,16 @@ export const MARKETS: Record<FuturesMarketKey, FuturesMarketConfig> = {
testnet: '0x2d9315a88f3019f8efa88dfe9c0f0843712da0bac814461e27733f6b83eb51b3',
},
},
[FuturesMarketKey.sSTETHPERP]: {
key: FuturesMarketKey.sSTETHPERP,
asset: FuturesMarketAsset.STETH,
supports: 'both',
version: 2,
pythIds: {
mainnet: '0x846ae1bdb6300b817cee5fdee2a6da192775030db5615b94a465f53bd40850b5',
testnet: '0xb7abd25a76ddaffdf847224f03198ccb92723f90b2429cf33f0eecb96e352a86',
},
},
};

export const MARKET_ASSETS_BY_PYTH_ID = Object.values(MARKETS)
Expand Down
60 changes: 2 additions & 58 deletions sdk/contracts/PerpsV2MarketInternalV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ class FuturesMarketInternal {
);

const liqPrice = await this._approxLiquidationPrice(newPos, newPos.lastPrice);
const exactLiqPrice = await this._exactLiquidationPrice(newPos, liqPrice);
return { ...newPos, liqPrice: exactLiqPrice, fee, price: newPos.lastPrice, status: status };

return { ...newPos, liqPrice: liqPrice, fee, price: newPos.lastPrice, status: status };
};

_postTradeDetails = async (
Expand Down Expand Up @@ -268,18 +268,6 @@ class FuturesMarketInternal {
return multiplyDecimal(value, liqPremiumMultiplier);
};

_exactLiquidationPremium = async (positionSize: BigNumber, currentPrice: BigNumber) => {
if (positionSize.eq(0)) {
return 0;
}

const skewScale = await this._getSetting('skewScale');
const liqPremiumMultiplier = await this._getSetting('liquidationPremiumMultiplier');
const skewedSize = divideDecimal(positionSize.pow(2).div(UNIT_BIG_NUM).abs(), skewScale);
const value = multiplyDecimal(skewedSize, currentPrice);
return multiplyDecimal(value, liqPremiumMultiplier);
};

_orderFee = async (tradeParams: TradeParams) => {
const notionalDiff = multiplyDecimal(tradeParams.sizeDelta, tradeParams.fillPrice);
const marketSkew = await this._onChainData.marketSkew;
Expand Down Expand Up @@ -419,50 +407,6 @@ class FuturesMarketInternal {
return result.lt(0) ? BigNumber.from(0) : result;
};

_exactLiquidationPrice = async (position: Position, approxLiquidationPrice: BigNumber) => {
if (position.size.isZero()) {
return BigNumber.from('0');
}

const prices = Array.from(Array(1001).keys()).map((x) =>
wei(approxLiquidationPrice)
.mul(1 + (x - 500) / 1000)
.toBN()
);

// get settings once to avoid synchronous calls
await this._batchGetSettings();

// start with initial margin
const margins = await Promise.all(
prices.map((price) => this._marginPlusProfitFunding(position, price))
);

const liqMargins = await Promise.all(
prices.map((price) => this._exactLiquidationMargin(position.size, price))
);
const liqPremiums = await Promise.all(
prices.map((price) => this._exactLiquidationPremium(position.size, price))
);

const validPrices = prices.filter((price, i) => {
const margin = margins[i];
const liqMargin = liqMargins[i];
const liqPremium = liqPremiums[i];
return margin.sub(liqMargin).sub(liqPremium).lt(0);
});

let exactLiqPrice;
if (validPrices.length > 0) {
exactLiqPrice = position.size.gt(0)
? validPrices.reduce((max, current) => (max.gt(current) ? max : current))
: validPrices.reduce((min, current) => (min.lt(current) ? min : current));
} else {
exactLiqPrice = BigNumber.from(0);
}
return exactLiqPrice;
};

_exactLiquidationMargin = async (positionSize: BigNumber, price: BigNumber) => {
const keeperFee = await this._liquidationFee(positionSize, price);
const stakerFee = await this._stakerFee(positionSize, price);
Expand Down
1 change: 1 addition & 0 deletions sdk/contracts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import MultipleMerkleDistributorABI from '../contracts/abis/MultipleMerkleDistri
import MultipleMerkleDistributorPerpsV2ABI from '../contracts/abis/MultipleMerkleDistributorPerpsV2.json';
import RewardEscrowABI from '../contracts/abis/RewardEscrow.json';
import SupplyScheduleABI from '../contracts/abis/SupplySchedule.json';

import DappMaintenanceABI from './abis/DappMaintenance.json';
import ExchangeRatesABI from './abis/ExchangeRates.json';
import FuturesMarketDataABI from './abis/FuturesMarketData.json';
Expand Down
63 changes: 28 additions & 35 deletions sdk/services/futures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,22 @@ export default class FuturesService {

const parametersCalls = marketKeys.map((key: string) => PerpsV2MarketSettings.parameters(key));

const responses = await this.sdk.context.multicallProvider.all([...parametersCalls]);
const marketParameters = responses as IPerpsV2MarketSettings.ParametersStructOutput[];
let marketParameters: IPerpsV2MarketSettings.ParametersStructOutput[] = [];

if (this.sdk.context.isMainnet) {
marketParameters = await this.sdk.context.multicallProvider.all(parametersCalls);
} else {
const firstResponses = await this.sdk.context.multicallProvider.all(
parametersCalls.slice(0, 20)
);
const secondResponses = await this.sdk.context.multicallProvider.all(
parametersCalls.slice(20, parametersCalls.length)
);
marketParameters = [
...firstResponses,
...secondResponses,
] as IPerpsV2MarketSettings.ParametersStructOutput[];
}

const { suspensions, reasons } = await SystemStatus.getFuturesMarketSuspensions(marketKeys);

Expand Down Expand Up @@ -256,18 +270,10 @@ export default class FuturesService {
const positions = await Promise.all(
positionDetails.map(async (position, ind) => {
const canLiquidate = canLiquidateState[ind];
const marketAddress = futuresMarkets[ind].address;
const marketKey = futuresMarkets[ind].marketKey;
const asset = futuresMarkets[ind].asset;
const liquidationPrice = position.position.size.abs().gt(0)
? await this.sdk.futures.getExactLiquidationPrice(marketKey, marketAddress, position)
: position.liquidationPrice;
return mapFuturesPosition(
{ ...position, liquidationPrice },
canLiquidate,
asset,
marketKey
);

return mapFuturesPosition(position, canLiquidate, asset, marketKey);
})
);

Expand Down Expand Up @@ -544,27 +550,6 @@ export default class FuturesService {
);
}

public async getExactLiquidationPrice(
marketKey: FuturesMarketKey,
marketAddress: string,
positionDetails: PositionDetail
) {
const marketInternal = this.getInternalFuturesMarket(marketAddress, marketKey);
const internalPosition = {
id: '0',
size: positionDetails.position.size,
margin: positionDetails.position.margin,
lastFundingIndex: positionDetails.position.fundingIndex,
lastPrice: positionDetails.position.lastPrice,
};
const approxLiquidationPrice = positionDetails.liquidationPrice;
const exactLiqPrice = await marketInternal._exactLiquidationPrice(
internalPosition,
approxLiquidationPrice
);
return exactLiqPrice;
}

public async getCrossMarginTradePreview(
crossMarginAccount: string,
marketKey: FuturesMarketKey,
Expand Down Expand Up @@ -902,7 +887,10 @@ export default class FuturesService {
walletAddress: string,
crossMarginAddress: string,
order: SmartMarginOrderInputs,
cancelPendingReduceOrders?: boolean
options?: {
cancelPendingReduceOrders?: boolean;
cancelExpiredDelayedOrders?: boolean;
}
) {
const crossMarginAccountContract = SmartMarginAccount__factory.connect(
crossMarginAddress,
Expand All @@ -911,6 +899,11 @@ export default class FuturesService {
const commands = [];
const inputs = [];

if (options?.cancelExpiredDelayedOrders) {
commands.push(AccountExecuteFunctions.PERPS_V2_CANCEL_OFFCHAIN_DELAYED_ORDER);
inputs.push(defaultAbiCoder.encode(['address'], [market.address]));
}

const idleMargin = await this.getIdleMargin(walletAddress, crossMarginAddress);
const freeMargin = await this.getCrossMarginAccountBalance(crossMarginAddress);

Expand Down Expand Up @@ -998,7 +991,7 @@ export default class FuturesService {
}
}

if (cancelPendingReduceOrders) {
if (options?.cancelPendingReduceOrders) {
// Remove all pending reduce only orders if instructed
existingOrdersForMarket.forEach((o) => {
commands.push(AccountExecuteFunctions.GELATO_CANCEL_CONDITIONAL_ORDER);
Expand Down
2 changes: 2 additions & 0 deletions sdk/types/futures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ export enum FuturesMarketKey {
sTRXPERP = 'sTRXPERP',
sFLOKIPERP = 'sFLOKIPERP',
sINJPERP = 'sINJPERP',
sSTETHPERP = 'sSTETHPERP',
}

export enum FuturesMarketAsset {
Expand Down Expand Up @@ -159,6 +160,7 @@ export enum FuturesMarketAsset {
TRX = 'TRX',
FLOKI = 'FLOKI',
INJ = 'INJ',
STETH = 'STETH',
}

export interface FuturesMarketConfig {
Expand Down
7 changes: 6 additions & 1 deletion sdk/utils/futures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,9 @@ export const getMarketName = (asset: FuturesMarketAsset | null) => {
};

export const getDisplayAsset = (asset: string | null) => {
return asset ? (asset[0] === 's' ? asset.slice(1) : asset) : null;
if (!asset) return null;
if (asset === 'STETH') return 'stETH';
return asset[0] === 's' ? asset.slice(1) : asset;
};

export const calculateVolumes = (
Expand Down Expand Up @@ -690,6 +692,7 @@ export const MarketAssetByKey: Record<FuturesMarketKey, FuturesMarketAsset> = {
[FuturesMarketKey.sFLOKIPERP]: FuturesMarketAsset.FLOKI,
[FuturesMarketKey.sINJPERP]: FuturesMarketAsset.INJ,
[FuturesMarketKey.sTRXPERP]: FuturesMarketAsset.TRX,
[FuturesMarketKey.sSTETHPERP]: FuturesMarketAsset.STETH,
} as const;

export const MarketKeyByAsset: Record<FuturesMarketAsset, FuturesMarketKey> = {
Expand Down Expand Up @@ -734,6 +737,7 @@ export const MarketKeyByAsset: Record<FuturesMarketAsset, FuturesMarketKey> = {
[FuturesMarketAsset.FLOKI]: FuturesMarketKey.sFLOKIPERP,
[FuturesMarketAsset.INJ]: FuturesMarketKey.sINJPERP,
[FuturesMarketAsset.TRX]: FuturesMarketKey.sTRXPERP,
[FuturesMarketAsset.STETH]: FuturesMarketKey.sSTETHPERP,
} as const;

export const AssetDisplayByAsset: Record<FuturesMarketAsset, string> = {
Expand Down Expand Up @@ -778,6 +782,7 @@ export const AssetDisplayByAsset: Record<FuturesMarketAsset, string> = {
[FuturesMarketAsset.FLOKI]: 'Floki',
[FuturesMarketAsset.INJ]: 'Injective',
[FuturesMarketAsset.TRX]: 'Tron',
[FuturesMarketAsset.STETH]: 'Lido Staked ETH',
} as const;

export const marketOverrides: Partial<Record<FuturesMarketKey, Record<string, any>>> = {};
1 change: 1 addition & 0 deletions sections/exchange/TradeCard/CurrencyCard/CurrencyCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Card, { CardBody } from 'components/Card';
import { FlexDivRowCentered } from 'components/layout/flex';

import { Side } from '../types';

import CurrencyCardInput from './CurrencyCardInput';
import CurrencyCardSelector from './CurrencyCardSelector';

Expand Down
Loading

1 comment on commit 81f2bad

@vercel
Copy link

@vercel vercel bot commented on 81f2bad Jun 14, 2023

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.