Skip to content

Commit

Permalink
Fix improper gas fee calculation (#6125)
Browse files Browse the repository at this point in the history
* add missing mul to eip1559

* use preferred network if available

* another NaN check guard
  • Loading branch information
walmat authored Sep 30, 2024
1 parent 8d84b7c commit b83ea23
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 41 deletions.
5 changes: 3 additions & 2 deletions src/__swaps__/screens/Swap/Swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { parseSearchAsset } from '@/__swaps__/utils/assets';
import { AbsolutePortalRoot } from '@/components/AbsolutePortal';
import { useDelayedMount } from '@/hooks/useDelayedMount';
import { userAssetsStore } from '@/state/assets/userAssets';
import { useSwapsStore } from '@/state/swaps/swapsStore';
import { swapsStore, useSwapsStore } from '@/state/swaps/swapsStore';
import { SwapWarning } from './components/SwapWarning';
import { clearCustomGasSettings } from './hooks/useCustomGas';
import { SwapProvider, useSwapContext } from './providers/swap-provider';
Expand Down Expand Up @@ -109,6 +109,7 @@ const useCleanupOnUnmount = () => {
useEffect(() => {
return () => {
const highestValueEth = userAssetsStore.getState().getHighestValueEth();
const preferredNetwork = swapsStore.getState().preferredNetwork;
const parsedAsset = highestValueEth
? parseSearchAsset({
assetWithPrice: undefined,
Expand All @@ -123,7 +124,7 @@ const useCleanupOnUnmount = () => {
outputAsset: null,
outputSearchQuery: '',
quote: null,
selectedOutputChainId: parsedAsset?.chainId ?? ChainId.mainnet,
selectedOutputChainId: parsedAsset?.chainId ?? preferredNetwork ?? ChainId.mainnet,
});

userAssetsStore.setState({ filter: 'all', inputSearchQuery: '' });
Expand Down
6 changes: 4 additions & 2 deletions src/__swaps__/screens/Swap/components/GasButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ function EstimatedGasFee() {
}

function SelectedGas({ isPill }: { isPill?: boolean }) {
const chainId = swapsStore(s => s.inputAsset?.chainId || ChainId.mainnet);
const preferredNetwork = swapsStore(s => s.preferredNetwork);
const chainId = swapsStore(s => s.inputAsset?.chainId || preferredNetwork || ChainId.mainnet);
const selectedGasSpeed = useSelectedGasSpeed(chainId);

return (
Expand Down Expand Up @@ -108,7 +109,8 @@ function keys<const T extends string>(obj: Record<T, unknown> | undefined) {
const GasMenu = ({ backToReview = false, children }: { backToReview?: boolean; children: ReactNode }) => {
const { SwapNavigation } = useSwapContext();

const chainId = swapsStore(s => s.inputAsset?.chainId || ChainId.mainnet);
const preferredNetwork = swapsStore(s => s.preferredNetwork);
const chainId = swapsStore(s => s.inputAsset?.chainId || preferredNetwork || ChainId.mainnet);
const metereologySuggestions = useMeteorologySuggestions({ chainId });
const customGasSettings = useCustomGasSettings(chainId);

Expand Down
34 changes: 10 additions & 24 deletions src/__swaps__/screens/Swap/hooks/useEstimatedGasFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import { useMemo } from 'react';
import { formatUnits } from 'viem';

import { useAccountSettings } from '@/hooks';
import { useSyncedSwapQuoteStore } from '../providers/SyncSwapStateAndSharedValues';
import { calculateGasFeeWorklet, useSyncedSwapQuoteStore } from '../providers/SyncSwapStateAndSharedValues';
import { GasSettings } from './useCustomGas';
import { useSelectedGas } from './useSelectedGas';
import { useSwapEstimatedGasLimit } from './useSwapEstimatedGasLimit';
import { useSwapsStore } from '@/state/swaps/swapsStore';

function safeBigInt(value: string) {
try {
Expand All @@ -19,24 +20,6 @@ function safeBigInt(value: string) {
}
}

const isFeeNaN = (value: string | undefined) => isNaN(Number(value)) || typeof value === 'undefined';

export function calculateGasFee(gasSettings: GasSettings, gasLimit: string) {
if (gasSettings.isEIP1559) {
if (isFeeNaN(gasSettings.maxBaseFee) || isFeeNaN(gasSettings.maxPriorityFee)) {
return null;
}

return add(gasSettings.maxBaseFee, gasSettings.maxPriorityFee);
}

if (isFeeNaN(gasSettings.gasPrice)) {
return null;
}

return multiply(gasLimit, gasSettings.gasPrice);
}

export function useEstimatedGasFee({
chainId,
gasLimit,
Expand All @@ -52,21 +35,24 @@ export function useEstimatedGasFee({
return useMemo(() => {
if (!gasLimit || !gasSettings || !nativeNetworkAsset?.price) return;

const fee = calculateGasFee(gasSettings, gasLimit);
if (!fee) return;
const gasFee = calculateGasFeeWorklet(gasSettings, gasLimit);
if (isNaN(Number(gasFee))) {
return;
}

const networkAssetPrice = nativeNetworkAsset.price.value?.toString();
if (!networkAssetPrice) return `${formatNumber(weiToGwei(fee))} Gwei`;
if (!networkAssetPrice) return `${formatNumber(weiToGwei(gasFee))} Gwei`;

const feeFormatted = formatUnits(safeBigInt(fee), nativeNetworkAsset.decimals).toString();
const feeFormatted = formatUnits(safeBigInt(gasFee), nativeNetworkAsset.decimals).toString();
const feeInUserCurrency = multiply(networkAssetPrice, feeFormatted);

return convertAmountToNativeDisplayWorklet(feeInUserCurrency, nativeCurrency, true);
}, [gasLimit, gasSettings, nativeCurrency, nativeNetworkAsset?.decimals, nativeNetworkAsset?.price]);
}

export function useSwapEstimatedGasFee(overrideGasSettings?: GasSettings) {
const { assetToSell, quote, chainId = ChainId.mainnet } = useSyncedSwapQuoteStore();
const preferredNetwork = useSwapsStore(s => s.preferredNetwork);
const { assetToSell, quote, chainId = preferredNetwork || ChainId.mainnet } = useSyncedSwapQuoteStore();
const gasSettings = useSelectedGas(chainId);

const { data: estimatedGasLimit, isFetching } = useSwapEstimatedGasLimit({ chainId, assetToSell, quote });
Expand Down
3 changes: 2 additions & 1 deletion src/__swaps__/screens/Swap/hooks/useNativeAssetForChain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { ChainId } from '@/chains/types';
import { SharedValue, runOnJS, useAnimatedReaction, useDerivedValue, useSharedValue } from 'react-native-reanimated';
import { ParsedAddressAsset } from '@/entities';
import { ethereumUtils } from '@/utils';
import { swapsStore } from '@/state/swaps/swapsStore';

export const useNativeAssetForChain = ({ inputAsset }: { inputAsset: SharedValue<ExtendedAnimatedAssetWithColors | null> }) => {
const chainId = useDerivedValue(() => inputAsset.value?.chainId ?? ChainId.mainnet);
const chainId = useDerivedValue(() => inputAsset.value?.chainId ?? swapsStore.getState().preferredNetwork ?? ChainId.mainnet);
const nativeAsset = useSharedValue<ParsedAddressAsset | undefined>(ethereumUtils.getNetworkNativeAsset({ chainId: chainId.value }));

const getNativeAssetForNetwork = useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { GasSettings } from '../hooks/useCustomGas';
import { useSelectedGas } from '../hooks/useSelectedGas';
import { useSwapEstimatedGasLimit } from '../hooks/useSwapEstimatedGasLimit';
import { useSwapContext } from './swap-provider';
import { useSwapsStore } from '@/state/swaps/swapsStore';

const BUFFER_RATIO = 0.5;

Expand Down Expand Up @@ -89,18 +90,13 @@ export function calculateGasFeeWorklet(gasSettings: GasSettings, gasLimit: strin
'worklet';

if (gasSettings.isEIP1559) {
if (isFeeNaNWorklet(gasSettings.maxBaseFee) || isFeeNaNWorklet(gasSettings.maxPriorityFee)) {
return null;
}

return sumWorklet(gasSettings.maxBaseFee || '0', gasSettings.maxPriorityFee || '0');
}

if (isFeeNaNWorklet(gasSettings.gasPrice)) {
return null;
const maxBaseFee = isFeeNaNWorklet(gasSettings.maxBaseFee) ? '0' : gasSettings.maxBaseFee;
const maxPriorityFee = isFeeNaNWorklet(gasSettings.maxPriorityFee) ? '0' : gasSettings.maxPriorityFee;
return mulWorklet(gasLimit, sumWorklet(maxBaseFee, maxPriorityFee));
}

return mulWorklet(gasLimit, gasSettings.gasPrice);
const gasPrice = isFeeNaNWorklet(gasSettings.gasPrice) ? '0' : gasSettings.gasPrice;
return mulWorklet(gasLimit, gasPrice);
}

export function formatUnitsWorklet(value: string, decimals: number) {
Expand Down Expand Up @@ -138,8 +134,12 @@ const getHasEnoughFundsForGasWorklet = ({

export function SyncGasStateToSharedValues() {
const { hasEnoughFundsForGas, internalSelectedInputAsset } = useSwapContext();
const preferredNetwork = useSwapsStore(s => s.preferredNetwork);

const initialChainId = useMemo(() => internalSelectedInputAsset.value?.chainId || ChainId.mainnet, [internalSelectedInputAsset]);
const initialChainId = useMemo(
() => internalSelectedInputAsset.value?.chainId || preferredNetwork || ChainId.mainnet,
[internalSelectedInputAsset, preferredNetwork]
);
const { assetToSell, chainId = initialChainId, quote } = useSyncedSwapQuoteStore();

const gasSettings = useSelectedGas(chainId);
Expand Down Expand Up @@ -198,7 +198,7 @@ export function SyncGasStateToSharedValues() {
}

const gasFee = calculateGasFeeWorklet(gasSettings, estimatedGasLimit);
if (gasFee === null || isNaN(Number(gasFee))) {
if (isNaN(Number(gasFee))) {
return;
}

Expand Down

0 comments on commit b83ea23

Please sign in to comment.