From d53572896b89b1ba219a00e8ddad374f19e3d7dc Mon Sep 17 00:00:00 2001 From: Piotr Witek <739075+piotrwitek@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:35:47 +0200 Subject: [PATCH] Pw/refinance-fix-bugs (#3948) * Fixed BUG Any protocol and pool to Aave V3 Asset [sc-15714] * Added refinance supported networks check * Added dpm and owner addresses to raw positon info * Type Fix * Added comment * Disabled emode for stablecoins disabled on aave * Updated emode logic * Added missing params --- .../positions/PortfolioPositionBlock.tsx | 2 + .../helpers/isRefinanceSupportedNetwork.ts | 5 ++ .../components/RefinancePortfolioBanner.tsx | 53 +++++++++++++++++-- .../RefinanceFlowSidebarController.tsx | 1 + features/refinance/emodeStablecoinTokens.ts | 28 +--------- features/refinance/helpers/getEmode.tsx | 9 +++- features/refinance/helpers/getTargetPoolId.ts | 5 +- .../useAaveLikeRefinanceContextInputs.ts | 2 +- .../aave-like/getRawPositionDetails.ts | 6 ++- .../positions/handlers/maker/index.ts | 2 + .../morpho-blue/getRawPositionDetails.ts | 4 ++ .../positions/handlers/morpho-blue/index.ts | 2 + handlers/portfolio/types.ts | 2 + 13 files changed, 83 insertions(+), 38 deletions(-) create mode 100644 features/aave/helpers/isRefinanceSupportedNetwork.ts diff --git a/components/portfolio/positions/PortfolioPositionBlock.tsx b/components/portfolio/positions/PortfolioPositionBlock.tsx index 74b4e3c8dc..7c88967394 100644 --- a/components/portfolio/positions/PortfolioPositionBlock.tsx +++ b/components/portfolio/positions/PortfolioPositionBlock.tsx @@ -6,6 +6,7 @@ import { PortfolioPositionAutomationIcons } from 'components/portfolio/positions import { PortfolioPositionBlockDetail } from 'components/portfolio/positions/PortfolioPositionBlockDetail' import { ProtocolLabel } from 'components/ProtocolLabel' import dayjs from 'dayjs' +import { isRefinanceSupportedNetwork } from 'features/aave/helpers/isRefinanceSupportedNetwork' import { shouldShowPairId } from 'features/omni-kit/helpers' import { OmniProductType } from 'features/omni-kit/types' import { RefinancePortfolioBanner } from 'features/refinance/components' @@ -100,6 +101,7 @@ export const PortfolioPositionBlock = ({ position }: { position: PortfolioPositi }} > {isRefinanceEnabled && + isRefinanceSupportedNetwork(position.network) && position.availableToRefinance && position.netValue >= emptyPortfolioPositionNetValueThreshold && ( diff --git a/features/aave/helpers/isRefinanceSupportedNetwork.ts b/features/aave/helpers/isRefinanceSupportedNetwork.ts new file mode 100644 index 0000000000..dcc3e1992c --- /dev/null +++ b/features/aave/helpers/isRefinanceSupportedNetwork.ts @@ -0,0 +1,5 @@ +import { NetworkNames } from 'blockchain/networks' + +export const isRefinanceSupportedNetwork = (networkName: NetworkNames) => { + return networkName === NetworkNames.ethereumMainnet +} diff --git a/features/refinance/components/RefinancePortfolioBanner.tsx b/features/refinance/components/RefinancePortfolioBanner.tsx index ef53870c56..c590214eec 100644 --- a/features/refinance/components/RefinancePortfolioBanner.tsx +++ b/features/refinance/components/RefinancePortfolioBanner.tsx @@ -2,7 +2,13 @@ import { ProtocolName } from '@summer_fi/summerfi-sdk-common' import { useAccountContext } from 'components/context/AccountContextProvider' import { useRefinanceGeneralContext } from 'features/refinance/contexts/RefinanceGeneralContext' import { RefinanceModalController } from 'features/refinance/controllers' -import { getRefinanceContextInput } from 'features/refinance/helpers' +import { + getAaveLikePoolId, + getAaveLikePositionId, + getMorphoPositionId, + getRefinanceContextInput, +} from 'features/refinance/helpers' +import { getMorphoPoolId } from 'features/refinance/helpers/getMorphoPoolId' import { omniProductTypeToSDKType } from 'features/refinance/helpers/omniProductTypeToSDKType' import { useWalletManagement } from 'features/web3OnBoard/useConnection' import type { PortfolioPosition } from 'handlers/portfolio/types' @@ -106,8 +112,8 @@ export const RefinancePortfolioBanner: FC = ({ po borrowRate, maxLtv, ltv, - poolId, - positionId, + poolId: poolIdRaw, + positionId: positionIdRaw, pairId, collateralAmount, collateralPrice, @@ -115,8 +121,41 @@ export const RefinancePortfolioBanner: FC = ({ po debtPrice, liquidationPrice, ethPrice, + dpmAddress, + // ownerAddress, } = position.rawPositionDetails + let positionId: any = positionIdRaw + let poolId: any = poolIdRaw + + // we need to override raw positionId and poolId for Aavelike and Morpho as they require class instance + switch (protocol) { + case LendingProtocol.AaveV3: + positionId = getAaveLikePositionId(LendingProtocol.AaveV3, positionId.id) + poolId = getAaveLikePoolId( + LendingProtocol.SparkV3, + poolId.protocol.chainInfo, + poolId.collateralToken, + poolId.debtToken, + poolId.emodeType, + ) + break + case LendingProtocol.SparkV3: + positionId = getAaveLikePositionId(LendingProtocol.SparkV3, positionId.id) + poolId = getAaveLikePoolId( + LendingProtocol.SparkV3, + poolId.protocol.chainInfo, + poolId.collateralToken, + poolId.debtToken, + poolId.emodeType, + ) + break + case LendingProtocol.MorphoBlue: + positionId = getMorphoPositionId(positionId.id) + poolId = getMorphoPoolId(poolId.protocol.chainInfo, poolId.marketId) + break + } + // To be useful once we will have clear definition on all copy variants within banner // const refinanceToProtocols = { // [LendingProtocol.Maker]: [LendingProtocol.SparkV3], @@ -216,7 +255,13 @@ export const RefinancePortfolioBanner: FC = ({ po positionType: omniProductTypeToSDKType(productType), pairId, isOwner: wallet?.address.toLowerCase() === portfolioAddress?.toLowerCase(), - owner: undefined, + owner: dpmAddress, + dpm: dpmAddress + ? { + id: positionId.id, + address: dpmAddress, + } + : undefined, }) handleSetContext(contextInput) diff --git a/features/refinance/controllers/RefinanceFlowSidebarController.tsx b/features/refinance/controllers/RefinanceFlowSidebarController.tsx index 738ae19901..702c3b8d57 100644 --- a/features/refinance/controllers/RefinanceFlowSidebarController.tsx +++ b/features/refinance/controllers/RefinanceFlowSidebarController.tsx @@ -23,6 +23,7 @@ export const RefinanceFlowSidebarController = () => { token: 'ETH', // Take only proxies without CreatePosition events filterConsumedProxy: async (events) => events.length === 0, + // will trigger on DPM step onEverythingReady: ({ availableProxies }) => { // Check if owner is already dpm and use it as dpm for refinance, if not fallback to first available dpm const dpm = diff --git a/features/refinance/emodeStablecoinTokens.ts b/features/refinance/emodeStablecoinTokens.ts index 9bb71bd88d..3a08d9fd19 100644 --- a/features/refinance/emodeStablecoinTokens.ts +++ b/features/refinance/emodeStablecoinTokens.ts @@ -1,27 +1 @@ -export const emodeStablecoinTokensUpperCase = [ - 'ADAI', - 'AETHDAI', - 'AETHLUSD', - 'AETHPYUSD', - 'AETHSDAI', - 'AETHUSDC', - 'AETHUSDT', - 'AUSDC', - 'AUSDT', - 'CDAI', - 'CRVUSD', - 'CUSDC', - 'CUSDCV3', - 'DAI', - 'FRAX', - 'GHO', - 'GUSD', - 'PYUSD', - 'SDAI', - 'SUSD', - 'SUSDE', - 'USDC.E', - 'USDC', - 'USDE', - 'USDT', -] +export const emodeStablecoinTokensSparkUpperCase = ['SDAI', 'USDC', 'USDT'] diff --git a/features/refinance/helpers/getEmode.tsx b/features/refinance/helpers/getEmode.tsx index 4ad711b027..f0655a0caa 100644 --- a/features/refinance/helpers/getEmode.tsx +++ b/features/refinance/helpers/getEmode.tsx @@ -1,12 +1,17 @@ import { EmodeType } from '@summer_fi/summerfi-sdk-client' import type { IToken } from '@summer_fi/summerfi-sdk-common' import { emodeEthCorrelatedTokensUpperCase } from 'features/refinance/emodeEthCorrelatedTokens' -import { emodeStablecoinTokensUpperCase } from 'features/refinance/emodeStablecoinTokens' +import { emodeStablecoinTokensSparkUpperCase } from 'features/refinance/emodeStablecoinTokens' +import { LendingProtocol } from 'lendingProtocols' -export function getEmode(collateralToken: IToken, debtToken: IToken) { +export function getEmode(collateralToken: IToken, debtToken: IToken, protocol: LendingProtocol) { const collateralTokenSymbolUpperCase = collateralToken.symbol.toUpperCase() const debtTokenSymbolUpperCase = debtToken.symbol.toUpperCase() + // Stablecoins are disabled for aave v3 + const emodeStablecoinTokensUpperCase = + protocol === LendingProtocol.SparkV3 ? emodeStablecoinTokensSparkUpperCase : [] + if ( emodeStablecoinTokensUpperCase.includes(collateralTokenSymbolUpperCase) && emodeStablecoinTokensUpperCase.includes(debtTokenSymbolUpperCase) diff --git a/features/refinance/helpers/getTargetPoolId.ts b/features/refinance/helpers/getTargetPoolId.ts index 76ec0fb8b8..dd82608232 100644 --- a/features/refinance/helpers/getTargetPoolId.ts +++ b/features/refinance/helpers/getTargetPoolId.ts @@ -10,6 +10,7 @@ import { getEmode } from 'features/refinance/helpers/getEmode' import { mapTokenToSdkToken } from 'features/refinance/helpers/mapTokenToSdkToken' import { replaceTokenSymbolETHWithWETH } from 'features/refinance/helpers/replaceETHwithWETH' import { getTokenDisplayName } from 'helpers/getTokenDisplayName' +import { LendingProtocol } from 'lendingProtocols' export const getTargetPoolId = (protocol: IProtocol, ctx: RefinanceGeneralContextBase): IPoolId => { const { @@ -42,7 +43,7 @@ export const getTargetPoolId = (protocol: IProtocol, ctx: RefinanceGeneralContex name: 'Spark', chainInfo, }, - emodeType: getEmode(collateralToken, debtToken), + emodeType: getEmode(collateralToken, debtToken, LendingProtocol.SparkV3), collateralToken, debtToken, }) @@ -52,7 +53,7 @@ export const getTargetPoolId = (protocol: IProtocol, ctx: RefinanceGeneralContex name: 'AaveV3', chainInfo, }, - emodeType: getEmode(collateralToken, debtToken), + emodeType: getEmode(collateralToken, debtToken, LendingProtocol.AaveV3), collateralToken, debtToken, }) diff --git a/features/refinance/hooks/useAaveLikeRefinanceContextInputs.ts b/features/refinance/hooks/useAaveLikeRefinanceContextInputs.ts index e50c25e6d4..c44ac706cd 100644 --- a/features/refinance/hooks/useAaveLikeRefinanceContextInputs.ts +++ b/features/refinance/hooks/useAaveLikeRefinanceContextInputs.ts @@ -66,7 +66,7 @@ export const useAaveLikeRefinanceContextInputs = ({ const collateralToken = mapTokenToSdkToken(chainFamily.chainInfo, collateralTokenSymbol) const debtToken = mapTokenToSdkToken(chainFamily.chainInfo, debtTokenSymbol) - const emodeType = getEmode(collateralToken, debtToken) + const emodeType = getEmode(collateralToken, debtToken, lendingProtocol) const poolId = getAaveLikePoolId( lendingProtocol, diff --git a/handlers/portfolio/positions/handlers/aave-like/getRawPositionDetails.ts b/handlers/portfolio/positions/handlers/aave-like/getRawPositionDetails.ts index 8843d922c6..2226a1bc7d 100644 --- a/handlers/portfolio/positions/handlers/aave-like/getRawPositionDetails.ts +++ b/handlers/portfolio/positions/handlers/aave-like/getRawPositionDetails.ts @@ -74,7 +74,7 @@ export function getRawPositionDetails( const collateralToken = mapTokenToSdkToken(chainFamily.chainInfo, commonData.primaryToken) const debtToken = mapTokenToSdkToken(chainFamily.chainInfo, commonData.secondaryToken) - const emodeType = getEmode(collateralToken, debtToken) + const emodeType = getEmode(collateralToken, debtToken, lendingProtocol) const poolId = getAaveLikePoolId( lendingProtocol, @@ -97,7 +97,9 @@ export function getRawPositionDetails( borrowRate: borrowRate.toString(), positionId, poolId, - pairId: 1, // TODO: investigate what used for + pairId: 1, // TODO: investigate what used for, + dpmAddress: dpm.id, + ownerAddress: dpm.user, } return rawPositionDetails } diff --git a/handlers/portfolio/positions/handlers/maker/index.ts b/handlers/portfolio/positions/handlers/maker/index.ts index 14d35b141b..f3b863cdeb 100644 --- a/handlers/portfolio/positions/handlers/maker/index.ts +++ b/handlers/portfolio/positions/handlers/maker/index.ts @@ -153,6 +153,8 @@ export const makerPositionsHandler: PortfolioPositionsHandler = async ({ poolId, positionId, pairId: 1, + dpmAddress: undefined, + ownerAddress: undefined, }, ...(type === OmniProductType.Earn && { lendingType: 'passive' }), network: NetworkNames.ethereumMainnet, diff --git a/handlers/portfolio/positions/handlers/morpho-blue/getRawPositionDetails.ts b/handlers/portfolio/positions/handlers/morpho-blue/getRawPositionDetails.ts index 74a4a9bc06..042e887031 100644 --- a/handlers/portfolio/positions/handlers/morpho-blue/getRawPositionDetails.ts +++ b/handlers/portfolio/positions/handlers/morpho-blue/getRawPositionDetails.ts @@ -21,6 +21,8 @@ export function getRawPositionDetails( maxRiskRatio: RiskRatio, rate: string, prices: TokensPricesList, + proxyAddress: string, + ownerAddress: string, ) { const chainFamily = getChainInfoByChainId(networkId) if (!chainFamily) { @@ -57,6 +59,8 @@ export function getRawPositionDetails( positionId, poolId, pairId, + dpmAddress: proxyAddress, + ownerAddress, } return rawPositionDetails } diff --git a/handlers/portfolio/positions/handlers/morpho-blue/index.ts b/handlers/portfolio/positions/handlers/morpho-blue/index.ts index fb2991b043..f15e9a3810 100644 --- a/handlers/portfolio/positions/handlers/morpho-blue/index.ts +++ b/handlers/portfolio/positions/handlers/morpho-blue/index.ts @@ -149,6 +149,8 @@ async function getMorphoPositions({ position.maxRiskRatio, rate, prices, + proxyAddress, + position.owner, ) return { diff --git a/handlers/portfolio/types.ts b/handlers/portfolio/types.ts index 5c13912a73..0e4065e92e 100644 --- a/handlers/portfolio/types.ts +++ b/handlers/portfolio/types.ts @@ -40,6 +40,8 @@ export type PortfolioPosition = { poolId: IPoolId positionId: IPositionId pairId: number + dpmAddress: string | undefined + ownerAddress: string | undefined } /* lendingType: