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

Hotfix: fix execution fee refund #1464

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
1 change: 1 addition & 0 deletions sdk/src/types/fees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type ExecutionFee = {
warning?: string;
isFeeHigh: boolean;
isFeeVeryHigh: boolean;
gasLimit: bigint;
};

export type FeeItem = {
Expand Down
1 change: 1 addition & 0 deletions sdk/src/utils/fees/executionFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function getExecutionFee(
feeTokenAmount,
feeToken: nativeToken,
isFeeHigh,
gasLimit,
isFeeVeryHigh,
};
}
Expand Down
33 changes: 11 additions & 22 deletions src/components/Synthetics/NetworkFeeRow/NetworkFeeRow.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Trans, t } from "@lingui/macro";
import { ReactNode, useMemo } from "react";

import { BASIS_POINTS_DIVISOR, BASIS_POINTS_DIVISOR_BIGINT } from "config/factors";
import { useTokensData } from "context/SyntheticsStateContext/hooks/globalsHooks";
import { useExecutionFeeBufferBps } from "context/SyntheticsStateContext/hooks/settingsHooks";
import type { ExecutionFee } from "domain/synthetics/fees/types";
import { convertToUsd } from "domain/synthetics/tokens/utils";
import { formatTokenAmountWithUsd, formatUsd } from "lib/numbers";
Expand All @@ -13,22 +11,19 @@ import ExternalLink from "components/ExternalLink/ExternalLink";
import StatsTooltipRow from "components/StatsTooltip/StatsTooltipRow";
import TooltipWithPortal from "components/Tooltip/TooltipWithPortal";

import { KEEPER_MAX_PRIORITY_FEE_PER_GAS_MAP } from "config/chains";
import { useRawGasPrice } from "domain/synthetics/fees/useRawGasPrice";
import { useChainId } from "lib/chains";
import "./NetworkFeeRow.scss";
import { bigMath } from "lib/bigmath";

type Props = {
executionFee?: ExecutionFee;
isAdditionOrdersMsg?: boolean;
};

/**
* This is not an accurate refund ration, just an estimation based on the recent data.
* 10%
*/
const ESTIMATED_REFUND_BPS = 10 * 100;

export function NetworkFeeRow({ executionFee, isAdditionOrdersMsg }: Props) {
const executionFeeBufferBps = useExecutionFeeBufferBps();
const { chainId } = useChainId();
const rawGasPrice = useRawGasPrice(chainId);
const tokenData = useTokensData();

let displayDecimals = executionFee?.feeToken.priceDecimals;
Expand Down Expand Up @@ -62,23 +57,17 @@ export function NetworkFeeRow({ executionFee, isAdditionOrdersMsg }: Props) {

const estimatedRefundText = useMemo(() => {
let estimatedRefundTokenAmount: bigint | undefined;
if (!executionFee || executionFeeBufferBps === undefined) {
if (rawGasPrice === undefined || !executionFee) {
estimatedRefundTokenAmount = undefined;
} else {
const fee = executionFee.feeTokenAmount;
const feeBeforeBuffer = bigMath.mulDiv(
fee,
BASIS_POINTS_DIVISOR_BIGINT,
BigInt(BASIS_POINTS_DIVISOR + executionFeeBufferBps)
);
estimatedRefundTokenAmount =
bigMath.mulDiv(feeBeforeBuffer, BigInt(ESTIMATED_REFUND_BPS), BASIS_POINTS_DIVISOR_BIGINT) +
(fee - feeBeforeBuffer);
const maxPriorityFeePerGas = KEEPER_MAX_PRIORITY_FEE_PER_GAS_MAP[chainId] ?? 0n;
const keeperExecutionFeeAmount = (rawGasPrice + maxPriorityFeePerGas) * executionFee.gasLimit;
estimatedRefundTokenAmount = executionFee.feeTokenAmount - keeperExecutionFeeAmount;
}

let estimatedRefundUsd: bigint | undefined;

if (executionFeeBufferBps === undefined || !executionFee || !tokenData) {
if (!executionFee || !tokenData) {
estimatedRefundUsd = undefined;
} else {
estimatedRefundUsd = convertToUsd(
Expand All @@ -99,7 +88,7 @@ export function NetworkFeeRow({ executionFee, isAdditionOrdersMsg }: Props) {
);

return estimatedRefundText;
}, [displayDecimals, executionFee, executionFeeBufferBps, tokenData]);
}, [chainId, displayDecimals, executionFee, rawGasPrice, tokenData]);

const value: ReactNode = useMemo(() => {
if (executionFee?.feeUsd === undefined) {
Expand Down
8 changes: 7 additions & 1 deletion src/config/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const CHAIN_NAMES_MAP = {
// is also applied to the execution fee calculation
export const GAS_PRICE_PREMIUM_MAP = {
[ARBITRUM]: 0n,
[AVALANCHE]: 3000000000n, // 3 gwei
[AVALANCHE]: 0n,
};

// added to gasPrice
Expand Down Expand Up @@ -73,6 +73,12 @@ export const MAX_PRIORITY_FEE_PER_GAS_MAP: Record<number, bigint | undefined> =
[AVALANCHE_FUJI]: 1500000000n,
};

export const KEEPER_MAX_PRIORITY_FEE_PER_GAS_MAP: Record<number, bigint | undefined> = {
[ARBITRUM]: 300000000n,
[AVALANCHE]: 300000000n,
[AVALANCHE_FUJI]: 300000000n,
};

// added to maxPriorityFeePerGas
// applied to EIP-1559 transactions only
// is not applied to execution fee calculation
Expand Down
1 change: 1 addition & 0 deletions src/domain/synthetics/fees/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export type ExecutionFee = {
feeTokenAmount: bigint;
feeToken: Token;
warning?: string;
gasLimit: bigint;
};

export type FeeItem = {
Expand Down
6 changes: 2 additions & 4 deletions src/domain/synthetics/fees/useGasPrice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EXECUTION_FEE_CONFIG_V2, GAS_PRICE_PREMIUM_MAP, MAX_PRIORITY_FEE_PER_GAS_MAP } from "config/chains";
import { EXECUTION_FEE_CONFIG_V2, MAX_PRIORITY_FEE_PER_GAS_MAP } from "config/chains";
import { BASIS_POINTS_DIVISOR_BIGINT } from "config/factors";
import { useSettings } from "context/SettingsContext/SettingsContextProvider";
import { bigMath } from "lib/bigmath";
Expand Down Expand Up @@ -44,9 +44,7 @@ export function useGasPrice(chainId: number) {
gasPrice = gasPrice + buffer;
}

const premium = GAS_PRICE_PREMIUM_MAP[chainId] ?? 0n;

resolve(gasPrice + premium);
resolve(gasPrice);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
Expand Down
21 changes: 21 additions & 0 deletions src/domain/synthetics/fees/useRawGasPrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { getProvider } from "lib/rpc";
import useSWR from "swr";

export function useRawGasPrice(chainId: number) {
const { data: gasPrice } = useSWR<bigint | undefined>(["useRawGasPrice", chainId], {
fetcher: async () => {
const provider = getProvider(undefined, chainId);

if (!provider) {
return;
}

const feeData = await provider.getFeeData();
let gasPrice = feeData.gasPrice ?? 0n;

return gasPrice;
},
});

return gasPrice === undefined ? undefined : BigInt(gasPrice);
}
1 change: 1 addition & 0 deletions src/domain/synthetics/fees/utils/executionFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function getExecutionFee(
feeTokenAmount,
feeToken: nativeToken,
warning,
gasLimit,
};
}

Expand Down