From 8e0f4c36c213709e095c312f44ff7305fe6a94da Mon Sep 17 00:00:00 2001 From: Majorfi Date: Tue, 13 Aug 2024 10:14:09 +0200 Subject: [PATCH] feat: APR display --- .../components/details/VaultDetailsHeader.tsx | 110 +++++- .../components/list/VaultsV3ListRow.tsx | 335 ++++++++++-------- 2 files changed, 292 insertions(+), 153 deletions(-) diff --git a/apps/vaults-v3/components/details/VaultDetailsHeader.tsx b/apps/vaults-v3/components/details/VaultDetailsHeader.tsx index f112d6cb4..9c2d5c6c8 100755 --- a/apps/vaults-v3/components/details/VaultDetailsHeader.tsx +++ b/apps/vaults-v3/components/details/VaultDetailsHeader.tsx @@ -1,4 +1,4 @@ -import {useEffect, useState} from 'react'; +import {Fragment, useEffect, useState} from 'react'; import {erc20Abi, zeroAddress} from 'viem'; import {useBlockNumber} from 'wagmi'; import {useWeb3} from '@builtbymom/web3/contexts/useWeb3'; @@ -65,12 +65,13 @@ function VaultHeaderLineItem({label, children, legend}: TVaultHeaderLineItemProp ); } -function VaultAPR({apr}: {apr: TYDaemonVault['apr']}): ReactElement { +function VaultAPR({apr, source}: {apr: TYDaemonVault['apr']; source: string}): ReactElement { const extraAPR = apr.extra.stakingRewardsAPR + apr.extra.gammaRewardAPR; const monthlyAPR = apr.points.monthAgo; const weeklyAPR = apr.points.weekAgo; const netAPR = apr.netAPR + extraAPR; const currentAPR = apr.forwardAPR.netAPR + extraAPR; + const isSourceVeYFI = source === 'VeYFI'; if (apr.forwardAPR.type === '' && extraAPR === 0) { return ( @@ -84,7 +85,7 @@ function VaultAPR({apr}: {apr: TYDaemonVault['apr']}): ReactElement { ); } - if (apr.forwardAPR.type !== '' && extraAPR !== 0) { + if (apr.forwardAPR.type !== '' && extraAPR !== 0 && !isSourceVeYFI) { const boostedAPR = apr.forwardAPR.netAPR + extraAPR; return ( +
+
+ {'Est. APR: '} + + +  →  + + +
+ +
+ +
+

+ {'Estimated APR for the next period based on current data.'} +

+
+

{'• Base APR '}

+ +
+ +
+

{'• Rewards APR '}

+
+ +  →  + +
+
+
+
+ + }> + + + +
+ ); + } + return (
- +
diff --git a/apps/vaults-v3/components/list/VaultsV3ListRow.tsx b/apps/vaults-v3/components/list/VaultsV3ListRow.tsx index 94858f13d..951ae05ea 100755 --- a/apps/vaults-v3/components/list/VaultsV3ListRow.tsx +++ b/apps/vaults-v3/components/list/VaultsV3ListRow.tsx @@ -1,4 +1,4 @@ -import {useMemo} from 'react'; +import {Fragment, useMemo} from 'react'; import Link from 'next/link'; import {cl, formatAmount, isZero, toAddress, toNormalizedBN} from '@builtbymom/web3/utils'; import {Renderable} from '@yearn-finance/web-lib/components/Renderable'; @@ -16,6 +16,108 @@ import type {ReactElement} from 'react'; import type {TYDaemonVault} from '@yearn-finance/web-lib/utils/schemas/yDaemonVaultsSchemas'; import type {TNormalizedBN} from '@builtbymom/web3/types'; +function APRSubline({hasPendleArbRewards}: {hasPendleArbRewards: boolean}): ReactElement { + if (hasPendleArbRewards) { + return ( + + {`+ 1500 ARB per week 🚀`} + + ); + } + return ; +} + +function APRTooltip(props: { + baseAPR: number; + rewardsAPR?: number; + boost?: number; + range?: [number, number]; + hasPendleArbRewards?: boolean; +}): ReactElement { + return ( + +
+
+
+

{'• Base APR '}

+ +
+ + {props.rewardsAPR ? ( +
+

{'• Rewards APR '}

+ +
+ ) : null} + + {props.boost ? ( +
+

{'• Boost '}

+

{`${formatAmount(props.boost, 2, 2)} x`}

+
+ ) : null} + + {props.range ? ( +
+

{'• Rewards APR '}

+
+ +  →  + +
+
+ ) : null} + + {props.hasPendleArbRewards ? ( +
+

{'• Extra ARB '}

+

{`1 500/week`}

+
+ ) : null} +
+
+
+ ); +} + function VaultForwardAPR({currentVault}: {currentVault: TYDaemonVault}): ReactElement { const isEthMainnet = currentVault.chainID === 1; const hasPendleArbRewards = @@ -24,6 +126,9 @@ function VaultForwardAPR({currentVault}: {currentVault: TYDaemonVault}): ReactEl currentVault.address === toAddress('0x1Dd930ADD968ff5913C3627dAA1e6e6FCC9dc544') || currentVault.address === toAddress('0x34a2b066AF16409648eF15d239E656edB8790ca0'); + /********************************************************************************************** + ** If there is no forwardAPR, we only have the historical APR to display. + **********************************************************************************************/ if (currentVault.apr.forwardAPR.type === '') { const hasZeroAPR = isZero(currentVault.apr?.netAPR) || Number((currentVault.apr?.netAPR || 0).toFixed(2)) === 0; const boostedAPR = currentVault.apr.extra.stakingRewardsAPR + currentVault.apr.netAPR; @@ -31,7 +136,7 @@ function VaultForwardAPR({currentVault}: {currentVault: TYDaemonVault}): ReactEl if (currentVault.apr?.extra.stakingRewardsAPR > 0) { return ( -
+
- -
-
-
-

{'• Base APR '}

- -
- -
-

{'• Rewards APR '}

- -
-
-
-
+
- {/* TEMPORARY CODE TO NOTIFY 1500 ARB PER WEEK REWARD FOR SOME VAULTS */} - - {`+ 1500 ARB per week 🚀`} - +
); } return ( -
+
- {/* TEMPORARY CODE TO NOTIFY 1500 ARB PER WEEK REWARD FOR SOME VAULTS */} - - {`+ 1500 ARB per week 🚀`} - +
); } + /********************************************************************************************** + ** If we are on eth mainnet and the vault has a boost, we display the APR with the boost. + ** This is mostly valid for Curve vaults. + **********************************************************************************************/ if (isEthMainnet && currentVault.apr.forwardAPR.composite?.boost > 0 && !currentVault.apr.extra.stakingRewardsAPR) { const unBoostedAPR = currentVault.apr.forwardAPR.netAPR / currentVault.apr.forwardAPR.composite.boost; return ( -
+
- -
-
-
-

{'• Base APR '}

- -
- -
-

{'• Boost '}

-

{`${formatAmount(currentVault.apr.forwardAPR.composite.boost, 2, 2)} x`}

-
-
-
-
+
); @@ -193,11 +235,31 @@ function VaultForwardAPR({currentVault}: {currentVault: TYDaemonVault}): ReactEl ** Display the APR including the rewards APR if the rewards APR is greater than 0. **********************************************************************************************/ const sumOfRewardsAPR = currentVault.apr.extra.stakingRewardsAPR + currentVault.apr.extra.gammaRewardAPR; + const isSourceVeYFI = currentVault.staking.source === 'VeYFI'; if (sumOfRewardsAPR > 0) { - const boostedAPR = sumOfRewardsAPR + currentVault.apr.forwardAPR.netAPR; - const hasZeroBoostedAPR = isZero(boostedAPR) || Number(boostedAPR.toFixed(2)) === 0; + let veYFIRange: [number, number] | undefined = undefined; + let estAPRRange: [number, number] | undefined = undefined; + let boostedAPR: number; + let hasZeroBoostedAPR: boolean; + + if (isSourceVeYFI) { + veYFIRange = [ + currentVault.apr.extra.stakingRewardsAPR / 10 + currentVault.apr.extra.gammaRewardAPR, + sumOfRewardsAPR + ] as [number, number]; + boostedAPR = veYFIRange[0] + currentVault.apr.forwardAPR.netAPR; + hasZeroBoostedAPR = isZero(boostedAPR) || Number(boostedAPR.toFixed(2)) === 0; + estAPRRange = [ + veYFIRange[0] + currentVault.apr.forwardAPR.netAPR, + veYFIRange[1] + currentVault.apr.forwardAPR.netAPR + ] as [number, number]; + } else { + boostedAPR = sumOfRewardsAPR + currentVault.apr.forwardAPR.netAPR; + hasZeroBoostedAPR = isZero(boostedAPR) || Number(boostedAPR.toFixed(2)) === 0; + } + return ( -
+
- - - - - -
-
-
-

{'• Base APR '}

- -
- -
-

{'• Rewards APR '}

+ /> */} + {estAPRRange ? ( + + +  →  + + + ) : ( -
-
-
-
+ )} + + +
+ - {/* TEMPORARY CODE TO NOTIFY 1500 ARB PER WEEK REWARD FOR SOME VAULTS */} - - {`+ 1500 ARB per week 🚀`} - +
); } @@ -272,7 +323,7 @@ function VaultForwardAPR({currentVault}: {currentVault: TYDaemonVault}): ReactEl const hasCurrentAPR = !isZero(currentVault?.apr.forwardAPR.netAPR); if (hasCurrentAPR) { return ( -
+
- {/* TEMPORARY CODE TO NOTIFY 1500 ARB PER WEEK REWARD FOR SOME VAULTS */} - - {`+ 1500 ARB per week 🚀`} - +
); } const hasZeroAPR = isZero(currentVault.apr?.netAPR) || Number((currentVault.apr?.netAPR || 0).toFixed(2)) === 0; return ( -
+
- {/* TEMPORARY CODE TO NOTIFY 1500 ARB PER WEEK REWARD FOR SOME VAULTS */} - - {`+ 1500 ARB per week 🚀`} - +
); } @@ -337,7 +374,7 @@ function VaultHistoricalAPR({currentVault}: {currentVault: TYDaemonVault}): Reac if (currentVault.apr?.extra.stakingRewardsAPR > 0) { return ( -
+
+