diff --git a/package.json b/package.json index 9bc9104af8..05b66940e4 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,8 @@ "test:coverage": "jest --coverage" }, "dependencies": { - "@aave/contract-helpers": "1.28.1", - "@aave/math-utils": "1.28.1", + "@aave/contract-helpers": "1.28.2-fb3b77e8484c11bb786b9872259d7bcff30597e7.0", + "@aave/math-utils": "1.28.2-fb3b77e8484c11bb786b9872259d7bcff30597e7.0", "@bgd-labs/aave-address-book": "^2.26.1", "@emotion/cache": "11.10.3", "@emotion/react": "11.10.4", diff --git a/pages/v3-migration.page.tsx b/pages/v3-migration.page.tsx index e0ecce54ab..e431ad5c15 100644 --- a/pages/v3-migration.page.tsx +++ b/pages/v3-migration.page.tsx @@ -8,7 +8,6 @@ import { ContentContainer } from 'src/components/ContentContainer'; import { getMarketInfoById } from 'src/components/MarketSwitcher'; import { useUserMigrationReserves } from 'src/hooks/migration/useUserMigrationReserves'; import { useUserSummaryAfterMigration } from 'src/hooks/migration/useUserSummaryAfterMigration'; -import { useUserPoolReservesHumanized } from 'src/hooks/pool/useUserPoolReserves'; import { useUserSummaryAndIncentives } from 'src/hooks/pool/useUserSummaryAndIncentives'; import { MainLayout } from 'src/layouts/MainLayout'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; @@ -23,6 +22,7 @@ import { selectCurrentChainIdV3MarketData } from 'src/store/poolSelectors'; import { useRootStore } from 'src/store/root'; import { CustomMarket, + externalMarketsData, getNetworkConfig, MarketDataType, marketsData, @@ -34,6 +34,13 @@ const MigrateV3Modal = dynamic(() => ) ); +const EXTERNAL_MARKETS_TO_MIGRATE = Object.keys(externalMarketsData).map((key) => { + const market = externalMarketsData[key]; + return { + ...market, + }; +}); + const AAVE_MARKETS_TO_MIGRATE = Object.keys(marketsData) .map((key) => { const market = marketsData[key]; @@ -48,6 +55,10 @@ const selectableMarkets = [ title: 'Aave V2 Markets', markets: AAVE_MARKETS_TO_MIGRATE, }, + { + title: 'Spark Markets', + markets: EXTERNAL_MARKETS_TO_MIGRATE, + }, ]; export default function V3Migration() { @@ -91,20 +102,16 @@ export default function V3Migration() { const { data: fromUserSummaryAndIncentives, isLoading: fromUserSummaryAndIncentivesLoading } = useUserSummaryAndIncentives(fromMarketData); - - const { data: toUserReservesData, isLoading: toUserReservesDataLoading } = - useUserPoolReservesHumanized(toMarketData); const { data: toUserSummaryForMigration, isLoading: toUserSummaryForMigrationLoading } = useUserSummaryAndIncentives(toMarketData); - const toUserEModeCategoryId = toUserReservesData?.userEmodeCategoryId || 0; const { data: userSummaryAfterMigration, isLoading: userSummaryAfterMigrationLoading } = useUserSummaryAfterMigration(fromMarketData, toMarketData); + const toUserEModeCategoryId = toUserSummaryForMigration?.userEmodeCategoryId || 0; const loading = userMigrationReservesLoading || fromUserSummaryAndIncentivesLoading || - toUserReservesDataLoading || toUserSummaryForMigrationLoading || userSummaryAfterMigrationLoading; @@ -138,7 +145,7 @@ export default function V3Migration() { setFromMarketData(marketData); }; - const bottomPanelProps = fromUserSummaryAndIncentives && + const userSummaryBeforeMigration = fromUserSummaryAndIncentives && toUserSummaryForMigration && { fromUserSummaryBeforeMigration: fromUserSummaryAndIncentives, toUserSummaryBeforeMigration: toUserSummaryForMigration, @@ -159,7 +166,7 @@ export default function V3Migration() { > { - const migrateWithPermits = useRootStore((store) => store.migrateWithPermits); - const migrateWithoutPermits = useRootStore((store) => store.migrateWithoutPermits); - const getApprovePermitsForSelectedAssets = useRootStore( - (store) => store.getApprovePermitsForSelectedAssets + const [signatures, setSignatures] = useState<{ + supply: V3MigrationHelperSignedPermit[]; + borrow: V3MigrationHelperSignedCreditDelegationPermit[]; + }>({ + supply: [], + borrow: [], + }); + const { signTxData, sendTx } = useWeb3Context(); + const [ + user, + walletApprovalMethodPreference, + selectedMigrationSupplyAssets, + selectedMigrationBorrowAssets, + generateCreditDelegationSignatureRequest, + generateSignatureRequest, + estimateGasLimit, + ] = useRootStore((store) => [ + store.account, + store.walletApprovalMethodPreference, + store.selectedMigrationSupplyAssets, + store.selectedMigrationBorrowAssets, + store.generateCreditDelegationSignatureRequest, + store.generateSignatureRequest, + store.estimateGasLimit, + ]); + const { approvalTxState, mainTxState, setApprovalTxState, setTxError, setMainTxState } = + useModalContext(); + + const { migrationService } = useSharedDependencies(); + + const usePermit = walletApprovalMethodPreference === ApprovalMethod.PERMIT; + + const supplyAssets = selectUserSupplyAssetsForMigrationNoPermit( + selectedMigrationSupplyAssets, + userMigrationReserves.supplyReserves, + userMigrationReserves.isolatedReserveV3 + ); + + const repayAssets = selectMigrationRepayAssets( + selectedMigrationBorrowAssets, + userMigrationReserves.borrowReserves + ); + + const borrowPermitPayloads = selectMigrationBorrowPermitPayloads( + selectedMigrationBorrowAssets, + toUserSummaryForMigration, + userMigrationReserves.borrowReserves, + true ); - const { approval, action, loadingTxns, requiresApproval, mainTxState, approvalTxState } = - useTransactionHandler({ - handleGetTxns: async () => - await migrateWithoutPermits(toUserSummaryForMigration, userMigrationReserves), - handleGetPermitTxns: async (signatures, deadline) => - await migrateWithPermits( - signatures, - deadline, - toUserSummaryForMigration, - userMigrationReserves - ), - tryPermit: true, - permitAction: ProtocolAction.migrateV3, - }); - const handleApproval = async () => { - const approvePermitsForSelectedAssets = await getApprovePermitsForSelectedAssets( - toUserSummaryForMigration, - userMigrationReserves - ); - approval(approvePermitsForSelectedAssets); + const creditDelegationApprovals: MigrationDelegationApproval[] = borrowPermitPayloads.map( + ({ underlyingAsset, amount }) => ({ debtTokenAddress: underlyingAsset, amount }) + ); + + const { data: approvals, isLoading: approvalsLoading } = useMigrationApprovalTxs( + fromMarket, + toMarket, + supplyAssets, + creditDelegationApprovals + ); + + const requiresApproval = approvals + ? approvals.supplyApprovalTxs.length > 0 || + approvals.borrowCreditDelegationApprovalTxs.length > 0 + : false; + + const approval = async () => { + if (requiresApproval && approvals) { + try { + if (usePermit) { + setApprovalTxState({ ...approvalTxState, loading: true }); + const supplyApprovals = approvals.supplyApprovalTxs; + const borrowCreditDelegationApprovals = approvals.borrowCreditDelegationApprovalTxs; + const supplySignatures = await Promise.all( + supplyApprovals.map(async (supplyApproval) => { + const supplyAsset = supplyAssets.find( + (supplyAsset) => supplyAsset.aToken === supplyApproval.to + ); + invariant(supplyAsset, 'Supply asset not found'); + const signatureRequest = await generateSignatureRequest( + { + token: supplyAsset.aToken, + amount: supplyAsset.amount, + deadline: supplyAsset.deadline.toString(), + spender: fromMarket.addresses.V3_MIGRATOR || '', + }, + { chainId: fromMarket.chainId } + ); + return { + deadline: supplyAsset.deadline, + aToken: supplyAsset.aToken, + value: supplyAsset.amount, + signatureRequest, + }; + }) + ); + const borrowCreditDelegationSignatures = await Promise.all( + borrowCreditDelegationApprovals.map(async (borrowCreditDelegationApproval) => { + const borrowAsset = borrowPermitPayloads.find( + (borrowAsset) => borrowAsset.underlyingAsset === borrowCreditDelegationApproval.to + ); + invariant(borrowAsset, 'Borrow asset not found'); + const deadline = Math.floor(Date.now() / 1000 + 3600).toString(); + const signatureRequest = await generateCreditDelegationSignatureRequest( + { + ...borrowAsset, + deadline, + spender: fromMarket.addresses.V3_MIGRATOR || '', + }, + { chainId: fromMarket.chainId } + ); + return { + deadline, + debtToken: borrowAsset.underlyingAsset, + value: borrowAsset.amount, + signatureRequest, + }; + }) + ); + const supplySigned: V3MigrationHelperSignedPermit[] = await Promise.all( + supplySignatures.map(async (signatureRequest) => { + const signature = await signTxData(signatureRequest.signatureRequest); + return { + deadline: signatureRequest.deadline, + aToken: signatureRequest.aToken, + value: signatureRequest.value, + signedPermit: signature, + }; + }) + ); + const borrowSigned: V3MigrationHelperSignedCreditDelegationPermit[] = await Promise.all( + borrowCreditDelegationSignatures.map(async (signatureRequest) => { + const signature = await signTxData(signatureRequest.signatureRequest); + return { + deadline: signatureRequest.deadline, + debtToken: signatureRequest.debtToken, + value: signatureRequest.value, + signedPermit: signature, + }; + }) + ); + setSignatures({ + supply: supplySigned, + borrow: borrowSigned, + }); + setTxError(undefined); + setApprovalTxState({ + txHash: MOCK_SIGNED_HASH, + loading: false, + success: true, + }); + } else { + setApprovalTxState({ ...approvalTxState, loading: true }); + const supplyApprovalsResponse = await Promise.all( + approvals.supplyApprovalTxs.map((supplyApproval) => sendTx(supplyApproval)) + ); + const borrowApprovalsResponse = await Promise.all( + approvals.borrowCreditDelegationApprovalTxs.map((borrowCreditDelegationApproval) => + sendTx(borrowCreditDelegationApproval) + ) + ); + await Promise.all(supplyApprovalsResponse.map((elem) => elem.wait(1))); + await Promise.all(borrowApprovalsResponse.map((elem) => elem.wait(1))); + setApprovalTxState({ + txHash: supplyApprovalsResponse[0]?.hash || borrowApprovalsResponse[0]?.hash, + loading: false, + success: true, + }); + setTxError(undefined); + } + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setApprovalTxState({ + txHash: undefined, + loading: false, + }); + } + } + }; + + const action = async () => { + try { + setMainTxState({ ...mainTxState, loading: true }); + let tx = migrationService.getMigrationTx( + fromMarket, + toMarket, + user, + supplyAssets, + repayAssets, + signatures.supply, + signatures.borrow + ); + tx = await estimateGasLimit(tx, fromMarket.chainId); + const response = await sendTx(tx); + await response.wait(1); + setMainTxState({ + txHash: response.hash, + loading: false, + success: true, + }); + } catch (error) { + const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false); + setTxError(parsedError); + setMainTxState({ + txHash: undefined, + loading: false, + }); + } }; return ( Migrate} actionInProgressText={Migrating} diff --git a/src/components/transactions/MigrateV3/MigrateV3Modal.tsx b/src/components/transactions/MigrateV3/MigrateV3Modal.tsx index 1e6b5d7151..b07bef9b88 100644 --- a/src/components/transactions/MigrateV3/MigrateV3Modal.tsx +++ b/src/components/transactions/MigrateV3/MigrateV3Modal.tsx @@ -1,32 +1,18 @@ import React from 'react'; import { BasicModal } from 'src/components/primitives/BasicModal'; -import { useUserMigrationReserves } from 'src/hooks/migration/useUserMigrationReserves'; -import { useUserSummaryForMigration } from 'src/hooks/migration/useUserSummaryForMigration'; import { ModalType, useModalContext } from 'src/hooks/useModal'; -import { selectCurrentChainIdV3MarketData } from 'src/store/poolSelectors'; -import { useRootStore } from 'src/store/root'; import { MigrateV3ModalContent } from './MigrateV3ModalContent'; export const MigrateV3Modal = () => { - const { type, close } = useModalContext(); + const { type, close, args } = useModalContext(); - const currentChainId = useRootStore((store) => store.currentChainId); - const currentNetworkConfig = useRootStore((store) => store.currentNetworkConfig); - const currentMarketData = useRootStore((store) => store.currentMarketData); - const toMarketData = selectCurrentChainIdV3MarketData(currentChainId, currentNetworkConfig); - const fromMarketData = currentMarketData; - - const { data: userMigrationReserves } = useUserMigrationReserves(fromMarketData, toMarketData); - const { data: toUserSummaryForMigration } = useUserSummaryForMigration(toMarketData); + const { fromMarket, toMarket } = args; return ( - {userMigrationReserves && toUserSummaryForMigration && ( - + {fromMarket && toMarket && ( + )} ); diff --git a/src/components/transactions/MigrateV3/MigrateV3ModalContent.tsx b/src/components/transactions/MigrateV3/MigrateV3ModalContent.tsx index e1d3b25d2f..d61616a271 100644 --- a/src/components/transactions/MigrateV3/MigrateV3ModalContent.tsx +++ b/src/components/transactions/MigrateV3/MigrateV3ModalContent.tsx @@ -2,9 +2,9 @@ import { InterestRate } from '@aave/contract-helpers'; import { Trans } from '@lingui/macro'; import { Box, Button } from '@mui/material'; import { useRouter } from 'next/router'; -import { useCallback } from 'react'; -import { UserMigrationReserves } from 'src/hooks/migration/useUserMigrationReserves'; -import { UserSummaryForMigration } from 'src/hooks/migration/useUserSummaryForMigration'; +import { useMemo } from 'react'; +import { useUserMigrationReserves } from 'src/hooks/migration/useUserMigrationReserves'; +import { useUserSummaryForMigration } from 'src/hooks/migration/useUserSummaryForMigration'; import { useModalContext } from 'src/hooks/useModal'; import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; @@ -12,7 +12,7 @@ import { selectedUserSupplyReservesForMigration, selectSelectedBorrowReservesForMigrationV3, } from 'src/store/v3MigrationSelectors'; -import { CustomMarket, getNetworkConfig } from 'src/utils/marketsAndNetworksConfig'; +import { CustomMarket, getNetworkConfig, MarketDataType } from 'src/utils/marketsAndNetworksConfig'; import { TxErrorView } from '../FlowCommons/Error'; import { GasEstimationError } from '../FlowCommons/GasEstimationError'; @@ -24,64 +24,70 @@ import { MigrateV3Actions } from './MigrateV3Actions'; import { MigrateV3ModalAssetsList } from './MigrateV3ModalAssetsList'; interface MigrationV3ModalContentProps { - toUserSummaryForMigration: UserSummaryForMigration; - userMigrationReserves: UserMigrationReserves; + fromMarket: MarketDataType; + toMarket: MarketDataType; } -export const MigrateV3ModalContent = ({ - toUserSummaryForMigration, - userMigrationReserves, -}: MigrationV3ModalContentProps) => { - const currentChainId = useRootStore((store) => store.currentChainId); +export const MigrateV3ModalContent = ({ fromMarket, toMarket }: MigrationV3ModalContentProps) => { + const { data: userMigrationReserves } = useUserMigrationReserves(fromMarket, toMarket); + const { data: toUserSummaryForMigration } = useUserSummaryForMigration(toMarket); + + const currentChainId = fromMarket.chainId; const setCurrentMarket = useRootStore((store) => store.setCurrentMarket); const currentMarket = useRootStore((store) => store.currentMarket); + const selectedMigrationSupplyAssets = useRootStore( + (store) => store.selectedMigrationSupplyAssets + ); + const selectedMigrationBorrowAssets = useRootStore( + (store) => store.selectedMigrationBorrowAssets + ); const { gasLimit, mainTxState: migrateTxState, txError, closeWithCb } = useModalContext(); const { chainId: connectedChainId, readOnlyModeAddress } = useWeb3Context(); const router = useRouter(); const networkConfig = getNetworkConfig(currentChainId); - const { supplyPositions, borrowPositions } = useRootStore( - useCallback( - (state) => ({ - supplyPositions: selectedUserSupplyReservesForMigration( - state.selectedMigrationSupplyAssets, - userMigrationReserves.supplyReserves, - userMigrationReserves.isolatedReserveV3 - ), - borrowPositions: selectSelectedBorrowReservesForMigrationV3( - state.selectedMigrationBorrowAssets, - toUserSummaryForMigration, - userMigrationReserves - ), - }), - [userMigrationReserves, toUserSummaryForMigration] - ) - ); - - const supplyAssets = supplyPositions.map((supplyAsset) => { - return { - underlyingAsset: supplyAsset.underlyingAsset, - iconSymbol: supplyAsset.reserve.iconSymbol, - symbol: supplyAsset.reserve.symbol, - amount: supplyAsset.underlyingBalance, - amountInUSD: supplyAsset.underlyingBalanceUSD, - }; - }); - - const borrowsAssets = borrowPositions.map((asset) => { - return { - underlyingAsset: asset.debtKey, - iconSymbol: asset.reserve.iconSymbol, - symbol: asset.reserve.symbol, - amount: - asset.interestRate == InterestRate.Stable ? asset.stableBorrows : asset.variableBorrows, - amountInUSD: - asset.interestRate == InterestRate.Stable - ? asset.stableBorrowsUSD - : asset.variableBorrowsUSD, - }; - }); + const supplyAssets = useMemo(() => { + if (!userMigrationReserves) { + return []; + } + return selectedUserSupplyReservesForMigration( + selectedMigrationSupplyAssets, + userMigrationReserves.supplyReserves, + userMigrationReserves.isolatedReserveV3 + ).map((supplyAsset) => { + return { + underlyingAsset: supplyAsset.underlyingAsset, + iconSymbol: supplyAsset.reserve.iconSymbol, + symbol: supplyAsset.reserve.symbol, + amount: supplyAsset.underlyingBalance, + amountInUSD: supplyAsset.underlyingBalanceUSD, + }; + }); + }, [userMigrationReserves, selectedMigrationSupplyAssets]); + + const borrowAssets = useMemo(() => { + if (!userMigrationReserves || !toUserSummaryForMigration) { + return []; + } + return selectSelectedBorrowReservesForMigrationV3( + selectedMigrationBorrowAssets, + toUserSummaryForMigration, + userMigrationReserves + ).map((asset) => { + return { + underlyingAsset: asset.debtKey, + iconSymbol: asset.reserve.iconSymbol, + symbol: asset.reserve.symbol, + amount: + asset.interestRate == InterestRate.Stable ? asset.stableBorrows : asset.variableBorrows, + amountInUSD: + asset.interestRate == InterestRate.Stable + ? asset.stableBorrowsUSD + : asset.variableBorrowsUSD, + }; + }); + }, [userMigrationReserves, toUserSummaryForMigration, selectedMigrationBorrowAssets]); // is Network mismatched const isWrongNetwork = currentChainId !== connectedChainId; @@ -134,14 +140,14 @@ export const MigrateV3ModalContent = ({ )} - + Selected supply assets} assets={supplyAssets} /> Selected borrow assets} - assets={borrowsAssets} + assets={borrowAssets} /> @@ -153,6 +159,8 @@ export const MigrateV3ModalContent = ({ blocked={false} userMigrationReserves={userMigrationReserves} toUserSummaryForMigration={toUserSummaryForMigration} + fromMarket={fromMarket} + toMarket={toMarket} /> )} diff --git a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx index 1943d83837..486056cffe 100644 --- a/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx +++ b/src/components/transactions/Supply/SupplyWrappedTokenActions.tsx @@ -69,7 +69,11 @@ export const SupplyWrappedTokenActions = ({ data: approvedAmount, isFetching, refetch: fetchApprovedAmount, - } = useApprovedAmount({ marketData, token: tokenIn, spender: tokenWrapperAddress }); + } = useApprovedAmount({ + marketData, + token: tokenIn, + spender: tokenWrapperAddress, + }); let requiresApproval = false; if (approvedAmount !== undefined) { diff --git a/src/helpers/useTransactionHandler.tsx b/src/helpers/useTransactionHandler.tsx index 6a5e62d52d..08987cf6b1 100644 --- a/src/helpers/useTransactionHandler.tsx +++ b/src/helpers/useTransactionHandler.tsx @@ -34,7 +34,7 @@ interface UseTransactionHandlerProps { export type Approval = { amount: string; underlyingAsset: string; - permitType?: 'POOL' | 'SUPPLY_MIGRATOR_V3' | 'BORROW_MIGRATOR_V3' | 'STAKE'; + permitType?: 'POOL' | 'STAKE'; }; export const useTransactionHandler = ({ @@ -65,19 +65,13 @@ export const useTransactionHandler = ({ const [ signPoolERC20Approval, walletApprovalMethodPreference, - generateCreditDelegationSignatureRequest, - generatePermitPayloadForMigrationSupplyAsset, addTransaction, signStakingApproval, - currentMarketData, ] = useRootStore((state) => [ state.signERC20Approval, state.walletApprovalMethodPreference, - state.generateCreditDelegationSignatureRequest, - state.generatePermitPayloadForMigrationSupplyAsset, state.addTransaction, state.signStakingApproval, - state.currentMarketData, ]); const [approvalTxes, setApprovalTxes] = useState(); @@ -168,18 +162,6 @@ export const useTransactionHandler = ({ deadline, }) ); - } else if (approval.permitType === 'SUPPLY_MIGRATOR_V3') { - unsignedPromisePayloads.push( - generatePermitPayloadForMigrationSupplyAsset({ ...approval, deadline }) - ); - } else if (approval.permitType === 'BORROW_MIGRATOR_V3') { - unsignedPromisePayloads.push( - generateCreditDelegationSignatureRequest({ - ...approval, - deadline, - spender: currentMarketData.addresses.V3_MIGRATOR || '', - }) - ); } else if (approval.permitType === 'STAKE') { unsignedPromisePayloads.push( signStakingApproval({ diff --git a/src/hooks/migration/useMigrationApprovalTxs.ts b/src/hooks/migration/useMigrationApprovalTxs.ts new file mode 100644 index 0000000000..50ce6349d7 --- /dev/null +++ b/src/hooks/migration/useMigrationApprovalTxs.ts @@ -0,0 +1,30 @@ +import { + MigrationDelegationApproval, + MigrationSupplyAsset, +} from '@aave/contract-helpers/dist/esm/v3-migration-contract/v3MigrationTypes'; +import { useQuery } from '@tanstack/react-query'; +import { useRootStore } from 'src/store/root'; +import { MarketDataType } from 'src/ui-config/marketsConfig'; +import { useSharedDependencies } from 'src/ui-config/SharedDependenciesProvider'; + +export const useMigrationApprovalTxs = ( + fromMarketData: MarketDataType, + toMarketData: MarketDataType, + supplyAssets: MigrationSupplyAsset[], + creditDelegationApprovals: MigrationDelegationApproval[] +) => { + const user = useRootStore((store) => store.account); + const { migrationService } = useSharedDependencies(); + return useQuery({ + queryFn: () => + migrationService.getMigrationApprovalTxs( + fromMarketData, + toMarketData, + supplyAssets, + creditDelegationApprovals, + user + ), + enabled: !!user, + queryKey: ['migrationApprovalTxs'], + }); +}; diff --git a/src/hooks/migration/useUserMigrationReserves.ts b/src/hooks/migration/useUserMigrationReserves.ts index ef06c10454..55258552fe 100644 --- a/src/hooks/migration/useUserMigrationReserves.ts +++ b/src/hooks/migration/useUserMigrationReserves.ts @@ -1,19 +1,12 @@ -import { - ReservesDataHumanized, - ReservesIncentiveDataHumanized, - valueToWei, -} from '@aave/contract-helpers'; +import { valueToWei } from '@aave/contract-helpers'; import { ComputedUserReserve, valueToBigNumber } from '@aave/math-utils'; -import dayjs from 'dayjs'; import memoize from 'micro-memoize'; -import { UserReservesDataHumanized } from 'src/services/UIPoolService'; import { useRootStore } from 'src/store/root'; import { IsolatedReserve, MigrationDisabled, MigrationUserReserve, selectDefinitiveSupplyAssetForMigration, - selectFormatUserSummaryForMigration, selectIsolationModeForMigration, selectMigrationUnderlyingAssetWithExceptions, selectSplittedBorrowsForMigration, @@ -24,15 +17,13 @@ import { MigrationException, MigrationSelectedAsset } from 'src/store/v3Migratio import { MarketDataType } from 'src/ui-config/marketsConfig'; import { FormattedReservesAndIncentives } from '../pool/usePoolFormattedReserves'; -import { usePoolReservesHumanized } from '../pool/usePoolReserves'; -import { usePoolReservesIncentivesHumanized } from '../pool/usePoolReservesIncentives'; -import { useUserPoolReservesHumanized } from '../pool/useUserPoolReserves'; import { UserSummaryAndIncentives, useUserSummaryAndIncentives, } from '../pool/useUserSummaryAndIncentives'; import { combineQueries, SimplifiedUseQueryResult } from '../pool/utils'; import { useMigrationExceptionsSupplyBalance } from './useMigrationExceptionsSupplyBalance'; +import { UserSummaryForMigration, useUserSummaryForMigration } from './useUserSummaryForMigration'; export type SupplyMigrationReserve = ComputedUserReserve & { usageAsCollateralEnabledOnUserV3: boolean; @@ -58,27 +49,18 @@ export interface UserMigrationReserves { const select = memoize( ( - toReservesData: ReservesDataHumanized, - toUserReservesData: UserReservesDataHumanized, - toReservesIncentivesData: ReservesIncentiveDataHumanized[], + toUserSummaryForMigration: UserSummaryForMigration, fromUserSummaryAndIncentives: UserSummaryAndIncentives, migrationExceptions: Record, selectedMigrationSupplyAssets: MigrationSelectedAsset[] ): UserMigrationReserves => { const { userReservesData: userReserveV3Data, ...v3ReservesUserSummary } = - selectFormatUserSummaryForMigration( - toReservesData.reservesData, - toReservesIncentivesData, - toUserReservesData.userReserves, - toReservesData.baseCurrencyData, - dayjs().unix(), - toUserReservesData.userEmodeCategoryId - ); + toUserSummaryForMigration; const { userReservesData: userReservesV2Data, ...v2ReservesUserSummary } = fromUserSummaryAndIncentives; - const userEmodeCategoryId = toUserReservesData.userEmodeCategoryId; + const userEmodeCategoryId = toUserSummaryForMigration.userEmodeCategoryId; let isolatedReserveV3: IsolatedReserve | undefined = selectIsolationModeForMigration(v3ReservesUserSummary); @@ -245,9 +227,7 @@ export const useUserMigrationReserves = ( migrationFrom: MarketDataType, migrationTo: MarketDataType ): SimplifiedUseQueryResult => { - const toReservesDataQuery = usePoolReservesHumanized(migrationTo); - const toUserReservesDataQuery = useUserPoolReservesHumanized(migrationTo); - const toReservesIncentivesDataQuery = usePoolReservesIncentivesHumanized(migrationTo); + const toUserSummaryForMigrationDataQuery = useUserSummaryForMigration(migrationTo); const fromUserSummaryAndIncentives = useUserSummaryAndIncentives(migrationFrom); const userReservesV2Data = fromUserSummaryAndIncentives.data?.userReservesData; @@ -267,16 +247,12 @@ export const useUserMigrationReserves = ( ); const selector = ( - toReservesData: ReservesDataHumanized, - toUserReservesData: UserReservesDataHumanized, - toReservesIncentivesData: ReservesIncentiveDataHumanized[], + toUserSummaryForMigration: UserSummaryForMigration, fromUserSummaryAndIncentives: UserSummaryAndIncentives, migrationsExceptions: Record ) => { return select( - toReservesData, - toUserReservesData, - toReservesIncentivesData, + toUserSummaryForMigration, fromUserSummaryAndIncentives, migrationsExceptions, selectedMigrationSupplyAssets @@ -285,9 +261,7 @@ export const useUserMigrationReserves = ( return combineQueries( [ - toReservesDataQuery, - toUserReservesDataQuery, - toReservesIncentivesDataQuery, + toUserSummaryForMigrationDataQuery, fromUserSummaryAndIncentives, migrationsExceptionsQuery, ] as const, diff --git a/src/hooks/useModal.tsx b/src/hooks/useModal.tsx index a2409ea26f..c244b9ec31 100644 --- a/src/hooks/useModal.tsx +++ b/src/hooks/useModal.tsx @@ -4,6 +4,7 @@ import { EmodeModalType } from 'src/components/transactions/Emode/EmodeModalCont import { useWeb3Context } from 'src/libs/hooks/useWeb3Context'; import { useRootStore } from 'src/store/root'; import { TxErrorType } from 'src/ui-config/errorMapping'; +import { MarketDataType } from 'src/ui-config/marketsConfig'; import { GENERAL } from 'src/utils/mixPanelEvents'; import { Proposal } from './governance/useProposals'; @@ -46,6 +47,8 @@ export interface ModalArgsType { isFrozen?: boolean; representatives?: Array<{ chainId: ChainId; representative: string }>; chainId?: number; + fromMarket?: MarketDataType; + toMarket?: MarketDataType; } export type TxStateType = { @@ -106,7 +109,7 @@ export interface ModalContextType { openDebtSwitch: (underlyingAsset: string, currentRateMode: InterestRate) => void; openGovDelegation: () => void; openRevokeGovDelegation: () => void; - openV3Migration: () => void; + openV3Migration: (fromMarket: MarketDataType, toMarket: MarketDataType) => void; openGovVote: (proposal: Proposal, support: boolean, power: string) => void; openSwitch: (underlyingAsset?: string, chainId?: number) => void; openStakingMigrate: () => void; @@ -316,8 +319,9 @@ export const ModalContextProvider: React.FC = ({ children }) => { setType(ModalType.GovRepresentatives); setArgs({ representatives }); }, - openV3Migration: () => { + openV3Migration: (fromMarket, toMarket) => { trackEvent(GENERAL.OPEN_MODAL, { modal: 'V2->V3 Migration' }); + setArgs({ fromMarket, toMarket }); setType(ModalType.V3Migration); }, openSwitch: (underlyingAsset, chainId) => { diff --git a/src/modules/migration/MigrationBottomPanel.tsx b/src/modules/migration/MigrationBottomPanel.tsx index fbc9081ead..e391ebe8fe 100644 --- a/src/modules/migration/MigrationBottomPanel.tsx +++ b/src/modules/migration/MigrationBottomPanel.tsx @@ -242,7 +242,7 @@ export const MigrationBottomPanel = ({