Skip to content

Commit

Permalink
fix: check gas sufficiency for chain native tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
chybisov committed Jul 11, 2022
1 parent d291348 commit 9deea31
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ import { MessageCard } from './InsufficientGasOrFundsMessage.style';

export const InsufficientGasOrFundsMessage: React.FC<BoxProps> = (props) => {
const { t } = useTranslation();
const {
hasGasBalanceOnStartChain,
hasGasOnCrossChain,
hasSufficientBalance,
} = useHasSufficientBalance();
const { hasGasOnStartChain, hasGasOnCrossChain, hasSufficientBalance } =
useHasSufficientBalance();

if (hasSufficientBalance && hasGasBalanceOnStartChain && hasGasOnCrossChain) {
if (hasSufficientBalance && hasGasOnStartChain && hasGasOnCrossChain) {
return null;
}

Expand All @@ -22,7 +19,7 @@ export const InsufficientGasOrFundsMessage: React.FC<BoxProps> = (props) => {
if (!hasSufficientBalance) {
message = t(`swap.warning.message.insufficientFunds`);
}
if (!hasGasBalanceOnStartChain) {
if (!hasGasOnStartChain) {
title = t(`swap.warning.title.insufficientGas`);
message = t(`swap.warning.message.insufficientGasOnStartChain`);
}
Expand Down
9 changes: 3 additions & 6 deletions packages/widget/src/components/SwapButton/SwapButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ export const SwapButton: React.FC = () => {

const { routes: swapRoutes, isLoading, isFetching } = useSwapRoutes();

const {
hasGasBalanceOnStartChain,
hasGasOnCrossChain,
hasSufficientBalance,
} = useHasSufficientBalance();
const { hasGasOnStartChain, hasGasOnCrossChain, hasSufficientBalance } =
useHasSufficientBalance();

const [chainId] = useWatch({
name: [SwapFormKeyHelper.getChainKey('from')],
Expand Down Expand Up @@ -74,7 +71,7 @@ export const SwapButton: React.FC = () => {
// loading={isLoading || isFetching}
disabled={
(!hasSufficientBalance ||
!hasGasBalanceOnStartChain ||
!hasGasOnStartChain ||
!hasGasOnCrossChain ||
isLoading ||
isFetching) &&
Expand Down
53 changes: 31 additions & 22 deletions packages/widget/src/hooks/useHasSufficientBalance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,63 @@ import { isSwapStep } from '@lifinance/sdk';
import Big from 'big.js';
import { useMemo } from 'react';
import { useWatch } from 'react-hook-form';
import { SwapFormKeyHelper } from '../providers/SwapFormProvider';
import { useDebouncedWatch } from '.';
import { SwapFormKey, SwapFormKeyHelper } from '../providers/SwapFormProvider';
import { useCurrentRoute } from '../stores';
import { useTokenBalances } from './useTokenBalances';

export const useHasSufficientBalance = () => {
const [route] = useCurrentRoute();
const [fromChainId, toChainId] = useWatch({
const [fromChainId, toChainId, fromToken] = useWatch({
name: [
SwapFormKeyHelper.getChainKey('from'),
SwapFormKeyHelper.getChainKey('to'),
SwapFormKey.FromToken,
],
});
const fromAmount = useDebouncedWatch(SwapFormKey.FromAmount, 250);
const lastStep = route?.steps.at(-1);
const { tokens: fromChainTokenBalances } = useTokenBalances(fromChainId);
const { tokens: toChainTokenBalances } = useTokenBalances(
lastStep?.action.fromChainId ?? toChainId,
);

const hasGasBalanceOnStartChain = useMemo(() => {
const token = route?.steps[0].estimate.gasCosts?.[0].token;
if (!token) {
const hasGasOnStartChain = useMemo(() => {
const gasToken = route?.steps[0].estimate.gasCosts?.[0].token;
if (!gasToken) {
return true;
}
const balance = Big(
fromChainTokenBalances?.find((t) => t.address === token.address)
const gasTokenBalance = Big(
fromChainTokenBalances?.find((t) => t.address === gasToken.address)
?.amount ?? 0,
);
const requiredAmount = route.steps

let requiredAmount = route.steps
.filter((step) => step.action.fromChainId === route.fromChainId)
.reduce(
(big, step) => big.plus(Big(step.estimate.gasCosts?.[0].amount || 0)),
Big(0),
)
.div(10 ** token.decimals);
return balance.gt(0) && balance.gte(requiredAmount);
.div(10 ** gasToken.decimals);
if (route.fromToken.address === gasToken.address) {
const tokenBalance = Big(
fromChainTokenBalances?.find(
(t) => t.address === route.fromToken.address,
)?.amount ?? 0,
);
requiredAmount = requiredAmount.plus(tokenBalance);
}
return gasTokenBalance.gt(0) && gasTokenBalance.gte(requiredAmount);
}, [fromChainTokenBalances, route]);

const hasGasOnCrossChain = useMemo(() => {
const token = lastStep?.estimate.gasCosts?.[0].token;
if (!token || !isSwapStep(lastStep)) {
const gasToken = lastStep?.estimate.gasCosts?.[0].token;
if (!gasToken || !isSwapStep(lastStep)) {
return true;
}
const balance = Big(
toChainTokenBalances?.find((t) => t.address === token.address)?.amount ??
0,
toChainTokenBalances?.find((t) => t.address === gasToken.address)
?.amount ?? 0,
);
const gasEstimate = lastStep.estimate.gasCosts?.[0].amount;
const requiredAmount = Big(gasEstimate || 0).div(
Expand All @@ -56,20 +68,17 @@ export const useHasSufficientBalance = () => {
}, [lastStep, toChainTokenBalances]);

const hasSufficientBalance = useMemo(() => {
if (!route) {
if (!fromToken || !fromAmount) {
return true;
}
const balance = Big(
fromChainTokenBalances?.find((t) => t.address === route.fromToken.address)
?.amount ?? 0,
fromChainTokenBalances?.find((t) => t.address === fromToken)?.amount ?? 0,
);
return Big(route.fromAmount)
.div(10 ** (route.fromToken.decimals ?? 0))
.lte(balance);
}, [fromChainTokenBalances, route]);
return Big(fromAmount).lte(balance);
}, [fromAmount, fromChainTokenBalances, fromToken]);

return {
hasGasBalanceOnStartChain,
hasGasOnStartChain,
hasGasOnCrossChain,
hasSufficientBalance,
};
Expand Down
9 changes: 3 additions & 6 deletions packages/widget/src/pages/SwapPage/SwapPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@ export const SwapPage: React.FC = () => {
const { t } = useTranslation();
const { state }: any = useLocation();
const navigate = useNavigate();
const {
hasGasBalanceOnStartChain,
hasGasOnCrossChain,
hasSufficientBalance,
} = useHasSufficientBalance();
const { hasGasOnStartChain, hasGasOnCrossChain, hasSufficientBalance } =
useHasSufficientBalance();
const { route, status, executeRoute, restartRoute, removeRoute } =
useRouteExecution(state.routeId as string);

Expand All @@ -26,7 +23,7 @@ export const SwapPage: React.FC = () => {
};

const isDisabled =
!hasSufficientBalance || !hasGasBalanceOnStartChain || !hasGasOnCrossChain;
!hasSufficientBalance || !hasGasOnStartChain || !hasGasOnCrossChain;

return (
<Container>
Expand Down

0 comments on commit 9deea31

Please sign in to comment.