Skip to content

Commit b4bc256

Browse files
feat(evm): update swap and repay
1 parent 4a953a8 commit b4bc256

8 files changed

Lines changed: 238 additions & 294 deletions

File tree

apps/evm/src/clients/api/mutations/useSwapTokensAndRepay/index.ts

Lines changed: 151 additions & 144 deletions
Large diffs are not rendered by default.

apps/evm/src/libs/analytics/useAnalytics/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ type SwapAndRepay = AnalyticEvent & {
8484
toTokenAmountTokens: number;
8585
priceImpactPercentage: number;
8686
slippageTolerancePercentage: number;
87-
exchangeRate: number;
87+
exchangeRate?: number;
8888
repaidFullLoan: boolean;
8989
};
9090

apps/evm/src/pages/Market/OperationForm/Repay/RepayWithWalletBalanceForm/SubmitSection/index.tsx

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@ import { cn } from '@venusprotocol/ui';
55
import { ApproveTokenSteps, type ApproveTokenStepsProps, PrimaryButton } from 'components';
66
import { HIGH_PRICE_IMPACT_THRESHOLD_PERCENTAGE } from 'constants/swap';
77
import { useTranslation } from 'libs/translations';
8-
import type { Swap, Token } from 'types';
8+
import type { SwapQuote, Token } from 'types';
99

1010
import { SwitchChain } from 'containers/SwitchChain';
11-
import SwapSummary from '../../../SwapSummary';
1211

1312
export interface SubmitSectionProps {
1413
isFormValid: boolean;
@@ -20,7 +19,7 @@ export interface SubmitSectionProps {
2019
isApproveFromTokenLoading: ApproveTokenStepsProps['isApproveTokenLoading'];
2120
isFromTokenWalletSpendingLimitLoading: ApproveTokenStepsProps['isWalletSpendingLimitLoading'];
2221
isRevokeFromTokenWalletSpendingLimitLoading: boolean;
23-
swap?: Swap;
22+
swapQuote?: SwapQuote;
2423
}
2524

2625
export const SubmitSection: React.FC<SubmitSectionProps> = ({
@@ -32,16 +31,16 @@ export const SubmitSection: React.FC<SubmitSectionProps> = ({
3231
isApproveFromTokenLoading,
3332
isFromTokenWalletSpendingLimitLoading,
3433
isRevokeFromTokenWalletSpendingLimitLoading,
35-
swap,
34+
swapQuote,
3635
isSwapLoading,
3736
}) => {
3837
const { t } = useTranslation();
3938

4039
const isSwappingWithHighPriceImpact = useMemo(
4140
() =>
42-
!!swap?.priceImpactPercentage &&
43-
swap?.priceImpactPercentage >= HIGH_PRICE_IMPACT_THRESHOLD_PERCENTAGE,
44-
[swap?.priceImpactPercentage],
41+
!!swapQuote?.priceImpactPercentage &&
42+
swapQuote?.priceImpactPercentage >= HIGH_PRICE_IMPACT_THRESHOLD_PERCENTAGE,
43+
[swapQuote?.priceImpactPercentage],
4544
);
4645

4746
const submitButtonLabel = useMemo(() => {
@@ -69,10 +68,6 @@ export const SubmitSection: React.FC<SubmitSectionProps> = ({
6968
>
7069
{submitButtonLabel}
7170
</PrimaryButton>
72-
73-
{isFormValid && !isSwapLoading && !isFromTokenWalletSpendingLimitLoading && (
74-
<SwapSummary swap={swap} type="repay" />
75-
)}
7671
</>
7772
);
7873

apps/evm/src/pages/Market/OperationForm/Repay/RepayWithWalletBalanceForm/index.tsx

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import BigNumber from 'bignumber.js';
22
import { useCallback, useEffect, useMemo, useState } from 'react';
33

44
import { cn } from '@venusprotocol/ui';
5-
import { useRepay, useSwapTokensAndRepay } from 'clients/api';
5+
import { useGetSwapQuote, useRepay, useSwapTokensAndRepay } from 'clients/api';
66
import {
77
Delimiter,
88
LabeledInlineContent,
@@ -12,14 +12,13 @@ import {
1212
TokenTextField,
1313
} from 'components';
1414
import useFormatTokensToReadableValue from 'hooks/useFormatTokensToReadableValue';
15-
import useGetSwapInfo from 'hooks/useGetSwapInfo';
1615
import useGetSwapTokenUserBalances from 'hooks/useGetSwapTokenUserBalances';
1716
import { useIsFeatureEnabled } from 'hooks/useIsFeatureEnabled';
1817
import useTokenApproval from 'hooks/useTokenApproval';
1918
import { VError } from 'libs/errors';
2019
import { useTranslation } from 'libs/translations';
2120
import { useAccountAddress } from 'libs/wallet';
22-
import type { Asset, BalanceMutation, Pool, Swap, SwapError, TokenBalance } from 'types';
21+
import type { Asset, BalanceMutation, Pool, SwapQuote, TokenBalance } from 'types';
2322
import {
2423
areTokensEqual,
2524
convertMantissaToTokens,
@@ -29,9 +28,11 @@ import {
2928
getUniqueTokenBalances,
3029
} from 'utilities';
3130

31+
import { NULL_ADDRESS } from 'constants/address';
3232
import { ConnectWallet } from 'containers/ConnectWallet';
3333
import useDebounceValue from 'hooks/useDebounceValue';
3434
import { useGetContractAddress } from 'hooks/useGetContractAddress';
35+
import { useGetUserSlippageTolerance } from 'hooks/useGetUserSlippageTolerance';
3536
import { useSimulateBalanceMutations } from 'hooks/useSimulateBalanceMutations';
3637
import { useAnalytics } from 'libs/analytics';
3738
import { ApyBreakdown } from '../../ApyBreakdown';
@@ -71,8 +72,8 @@ export interface RepayWithWalletBalanceFormUiProps
7172
isRevokeFromTokenWalletSpendingLimitLoading: boolean;
7273
onSubmitSuccess?: () => void;
7374
fromTokenWalletSpendingLimitTokens?: BigNumber;
74-
swap?: Swap;
75-
swapError?: SwapError;
75+
swapQuote?: SwapQuote;
76+
swapQuoteErrorCode?: string;
7677
}
7778

7879
export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUiProps> = ({
@@ -98,8 +99,8 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
9899
fromTokenWalletSpendingLimitTokens,
99100
revokeFromTokenWalletSpendingLimit,
100101
isRevokeFromTokenWalletSpendingLimitLoading,
101-
swap,
102-
swapError,
102+
swapQuote,
103+
swapQuoteErrorCode,
103104
}) => {
104105
const { t } = useTranslation();
105106
const { captureAnalyticEvent } = useAnalytics();
@@ -111,7 +112,7 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
111112

112113
const fromTokenUserWalletBalanceTokens = useMemo(() => {
113114
// Get wallet balance from the list of fetched token balances if integrated
114-
// swap feature is enabled and the selected token is different from the
115+
// swapQuote feature is enabled and the selected token is different from the
115116
// asset object
116117
if (isUsingSwap || isWrappingNativeToken) {
117118
const tokenBalance = tokenBalances.find(item =>
@@ -140,7 +141,7 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
140141
const debouncedFormAmountTokens = useDebounceValue(formValues.amountTokens);
141142

142143
let toTokenAmountTokens = isUsingSwap
143-
? getSwapToTokenAmountReceivedTokens(swap)
144+
? getSwapToTokenAmountReceivedTokens(swapQuote)
144145
: debouncedFormAmountTokens;
145146
toTokenAmountTokens = new BigNumber(toTokenAmountTokens || 0);
146147

@@ -167,8 +168,8 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
167168
fromTokenUserBorrowBalanceTokens: asset.userBorrowBalanceTokens,
168169
fromTokenWalletSpendingLimitTokens,
169170
isUsingSwap,
170-
swap,
171-
swapError,
171+
swapQuote,
172+
swapQuoteErrorCode,
172173
onSubmitSuccess,
173174
onSubmit,
174175
formValues,
@@ -192,7 +193,7 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
192193
fromTokenUserWalletBalanceTokens || 0,
193194
);
194195

195-
// If using swap, set input amount to wallet balance
196+
// If using swapQuote, set input amount to wallet balance
196197
if (isUsingSwap) {
197198
amountTokens = new BigNumber(fromTokenUserWalletBalanceTokens || 0);
198199
}
@@ -241,7 +242,7 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
241242
};
242243

243244
const canRepayFullLoan =
244-
// If user is using swap, we don't know if they can repay the full loan after conversion
245+
// If user is using swapQuote, we don't know if they can repay the full loan after conversion
245246
!isUsingSwap &&
246247
limitTokens.isGreaterThan(0) &&
247248
limitTokens.isGreaterThanOrEqualTo(asset.userBorrowBalanceTokens);
@@ -394,7 +395,7 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
394395
isFormValid={isFormValid}
395396
isSubmitting={isSubmitting}
396397
isRepayingFullLoan={isRepayingFullLoan}
397-
priceImpactPercentage={swap?.priceImpactPercentage}
398+
priceImpactPercentage={swapQuote?.priceImpactPercentage}
398399
/>
399400

400401
<div className="space-y-2">
@@ -420,14 +421,14 @@ export const RepayWithWalletBalanceFormUi: React.FC<RepayWithWalletBalanceFormUi
420421
simulatedPool={simulatedPool}
421422
balanceMutations={balanceMutations}
422423
isUsingSwap={isUsingSwap}
423-
swap={swap}
424+
swap={swapQuote}
424425
/>
425426
</div>
426427

427428
<SubmitSection
428429
isFormSubmitting={isSubmitting}
429430
isFormValid={isFormValid}
430-
swap={swap}
431+
swapQuote={swapQuote}
431432
isSwapLoading={isSwapLoading}
432433
fromToken={formValues.fromToken}
433434
approveFromToken={approveFromToken}
@@ -502,8 +503,7 @@ const RepayWithWalletBalanceForm: React.FC<RepayWithWalletBalanceFormProps> = ({
502503
}, [accountAddress, initialFormValues]);
503504

504505
const { address: swapRouterContractAddress } = useGetContractAddress({
505-
name: 'SwapRouter',
506-
poolComptrollerContractAddress: pool.comptrollerAddress,
506+
name: 'SwapRouterV2',
507507
});
508508

509509
// a user is trying to wrap the chain's native token if
@@ -592,7 +592,7 @@ const RepayWithWalletBalanceForm: React.FC<RepayWithWalletBalanceFormProps> = ({
592592
});
593593

594594
const onSubmit: RepayWithWalletBalanceFormUiProps['onSubmit'] = useCallback(
595-
async ({ fromToken, fromTokenAmountTokens, swap, fixedRepayPercentage }) => {
595+
async ({ fromToken, fromTokenAmountTokens, swapQuote, fixedRepayPercentage }) => {
596596
const repayFullLoan = fixedRepayPercentage === 100;
597597
const amountMantissa = convertTokensToMantissa({
598598
value: new BigNumber(fromTokenAmountTokens.trim()),
@@ -611,18 +611,18 @@ const RepayWithWalletBalanceForm: React.FC<RepayWithWalletBalanceFormProps> = ({
611611
});
612612
}
613613

614-
// Throw an error if we're meant to execute a swap but no swap was
614+
// Throw an error if we're meant to execute a swapQuote but no swapQuote was
615615
// passed through props. This should never happen since the form is
616-
// disabled while swap infos are being fetched, but we add this logic
616+
// disabled while swapQuote infos are being fetched, but we add this logic
617617
// as a safeguard
618-
if (!swap) {
618+
if (!swapQuote) {
619619
throw new VError({ type: 'unexpected', code: 'somethingWentWrong' });
620620
}
621621

622-
// Handle swap and repay flow
622+
// Handle swapQuote and repay flow
623623
return onSwapAndRepay({
624624
repayFullLoan,
625-
swap,
625+
swapQuote,
626626
poolName: pool.name,
627627
poolComptrollerContractAddress: pool.comptrollerAddress,
628628
vToken: asset.vToken,
@@ -639,24 +639,35 @@ const RepayWithWalletBalanceForm: React.FC<RepayWithWalletBalanceFormProps> = ({
639639
],
640640
);
641641

642-
const swapDirection = formValues.fixedRepayPercentage ? 'exactAmountOut' : 'exactAmountIn';
642+
const { address: swapRouterV2ContractAddress } = useGetContractAddress({
643+
name: 'SwapRouterV2',
644+
});
643645

644646
const debouncedFormAmountTokens = useDebounceValue(formValues.amountTokens);
647+
const fromTokenAmountTokens = new BigNumber(debouncedFormAmountTokens || 0);
645648

646-
const swapInfo = useGetSwapInfo({
647-
fromToken: formValues.fromToken || asset.vToken.underlyingToken,
648-
fromTokenAmountTokens:
649-
swapDirection === 'exactAmountIn' ? debouncedFormAmountTokens : undefined,
650-
toToken: asset.vToken.underlyingToken,
651-
toTokenAmountTokens: formValues.fixedRepayPercentage
652-
? calculatePercentageOfUserBorrowBalance({
653-
token: asset.vToken.underlyingToken,
654-
userBorrowBalanceTokens: asset.userBorrowBalanceTokens,
655-
percentage: formValues.fixedRepayPercentage,
656-
})
657-
: undefined,
658-
direction: swapDirection,
659-
});
649+
const { userSlippageTolerancePercentage } = useGetUserSlippageTolerance();
650+
651+
const {
652+
data: swapQuoteData,
653+
error: swapQuoteError,
654+
isLoading: swapQuoteLoading,
655+
} = useGetSwapQuote(
656+
{
657+
fromToken: formValues.fromToken,
658+
fromTokenAmountTokens,
659+
toToken: asset.vToken.underlyingToken,
660+
direction: 'exact-in',
661+
recipientAddress: swapRouterV2ContractAddress || NULL_ADDRESS,
662+
slippagePercentage: userSlippageTolerancePercentage,
663+
},
664+
{
665+
enabled:
666+
isUsingSwap && !!swapRouterV2ContractAddress && fromTokenAmountTokens.isGreaterThan(0),
667+
},
668+
);
669+
670+
const swapQuote = swapQuoteData?.swapQuote;
660671

661672
return (
662673
<RepayWithWalletBalanceFormUi
@@ -674,9 +685,9 @@ const RepayWithWalletBalanceForm: React.FC<RepayWithWalletBalanceFormProps> = ({
674685
integratedSwapTokenBalances={integratedSwapTokenBalancesData}
675686
onSubmit={onSubmit}
676687
isSubmitting={isSubmitting}
677-
swap={swapInfo.swap}
678-
swapError={swapInfo.error}
679-
isSwapLoading={swapInfo.isLoading}
688+
swapQuote={swapQuote}
689+
swapQuoteErrorCode={swapQuoteError?.code}
690+
isSwapLoading={swapQuoteLoading}
680691
isFromTokenApproved={isFromTokenApproved}
681692
approveFromToken={approveFromToken}
682693
isApproveFromTokenLoading={isApproveFromTokenLoading}

apps/evm/src/pages/Market/OperationForm/Repay/RepayWithWalletBalanceForm/useForm/index.tsx

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useEffect } from 'react';
33

44
import useIsMounted from 'hooks/useIsMounted';
55
import { handleError, isUserRejectedTxError } from 'libs/errors';
6-
import type { Asset, Swap, SwapError, Token, VToken } from 'types';
6+
import type { Asset, SwapQuote, Token, VToken } from 'types';
77
import { convertMantissaToTokens } from 'utilities';
88

99
import { useAnalytics } from 'libs/analytics';
@@ -23,7 +23,7 @@ export interface UseFormInput {
2323
toVToken: VToken;
2424
fromToken: Token;
2525
fromTokenAmountTokens: string;
26-
swap?: Swap;
26+
swapQuote?: SwapQuote;
2727
fixedRepayPercentage?: number;
2828
}) => Promise<unknown>;
2929
formValues: FormValues;
@@ -34,8 +34,8 @@ export interface UseFormInput {
3434
fromTokenWalletSpendingLimitTokens?: BigNumber;
3535
isFromTokenApproved?: boolean;
3636
isUsingSwap: boolean;
37-
swap?: Swap;
38-
swapError?: SwapError;
37+
swapQuote?: SwapQuote;
38+
swapQuoteErrorCode?: string;
3939
}
4040

4141
interface UseFormOutput {
@@ -53,8 +53,8 @@ const useForm = ({
5353
fromTokenWalletSpendingLimitTokens,
5454
isFromTokenApproved,
5555
onSubmitSuccess,
56-
swap,
57-
swapError,
56+
swapQuote,
57+
swapQuoteErrorCode,
5858
formValues,
5959
setFormValues,
6060
onSubmit,
@@ -64,8 +64,8 @@ const useForm = ({
6464

6565
const { isFormValid, formError } = useFormValidation({
6666
formValues,
67-
swap,
68-
swapError,
67+
swapQuote,
68+
swapQuoteErrorCode,
6969
isFromTokenApproved,
7070
isUsingSwap,
7171
fromTokenUserWalletBalanceTokens,
@@ -100,7 +100,7 @@ const useForm = ({
100100
fromTokenAmountTokens: formValues.amountTokens,
101101
fromToken: formValues.fromToken,
102102
fixedRepayPercentage: formValues.fixedRepayPercentage,
103-
swap,
103+
swapQuote,
104104
});
105105

106106
captureAnalyticEvent('repay_signed', analyticData);
@@ -148,26 +148,26 @@ const useForm = ({
148148
]);
149149

150150
useEffect(() => {
151-
// Fixed percentage using the swap
152-
const isSwapping = !!swap;
151+
// Fixed percentage using the swapQuote
152+
const isSwapping = !!swapQuote;
153153

154154
if (
155155
isMounted() &&
156156
formValues.fixedRepayPercentage &&
157157
isSwapping &&
158-
swap.direction === 'exactAmountOut'
158+
swapQuote.direction === 'exact-out'
159159
) {
160160
const expectedFromTokenAmountSoldTokens = convertMantissaToTokens({
161-
value: swap.expectedFromTokenAmountSoldMantissa,
162-
token: swap.fromToken,
161+
value: swapQuote.expectedFromTokenAmountSoldMantissa,
162+
token: swapQuote.fromToken,
163163
}).toFixed();
164164

165165
setFormValues(currentFormValues => ({
166166
...currentFormValues,
167167
amountTokens: expectedFromTokenAmountSoldTokens,
168168
}));
169169
}
170-
}, [formValues.fixedRepayPercentage, swap, setFormValues, isMounted]);
170+
}, [formValues.fixedRepayPercentage, swapQuote, setFormValues, isMounted]);
171171

172172
return {
173173
handleSubmit,

0 commit comments

Comments
 (0)