Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(yield): use pools info from API #5138

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 0 additions & 24 deletions apps/cowswap-frontend/src/common/containers/CoWAmmBanner/types.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function CoWAmmBannerContent({
}: CoWAmmBannerContentProps) {
const isMobile = useMediaQuery(upToSmall)
const arrowBackgroundRef = useRef<HTMLDivElement>(null)
const { superiorAlternatives, cowAmmLpTokensCount, averageApyDiff, poolsAverageData } = vampireAttackContext
const { superiorAlternatives, cowAmmLpTokensCount, averageAprDiff, poolsAverageData } = vampireAttackContext

const handleCTAMouseEnter = useCallback(() => {
if (arrowBackgroundRef.current) {
Expand All @@ -59,9 +59,9 @@ export function CoWAmmBannerContent({
}, [])

const firstItemWithBetterCowAmm = superiorAlternatives?.[0]
const isCowAmmAverageBetter = !!averageApyDiff && averageApyDiff > 0
const betterAlternativeApyDiff = firstItemWithBetterCowAmm
? firstItemWithBetterCowAmm.alternativePoolInfo.apy - firstItemWithBetterCowAmm.tokenPoolInfo.apy
const isCowAmmAverageBetter = !!averageAprDiff && averageAprDiff > 0
const betterAlternativeAprDiff = firstItemWithBetterCowAmm
? firstItemWithBetterCowAmm.alternativePoolInfo.apr - firstItemWithBetterCowAmm.tokenPoolInfo.apr
: undefined

const worseThanCoWAmmProviders = useMemo(() => {
Expand All @@ -82,7 +82,7 @@ export function CoWAmmBannerContent({

if (!aVal || !bVal) return 0

return bVal.apy - aVal.apy
return bVal - aVal
}) as LpTokenProvider[]
}, [poolsAverageData])

Expand All @@ -108,10 +108,10 @@ export function CoWAmmBannerContent({
minFontSize={isTokenSelectorView ? 35 : isMobile ? 40 : isCowAmmAverageBetter ? 60 : 80}
maxFontSize={isTokenSelectorView ? 65 : isMobile ? 50 : isCowAmmAverageBetter ? 60 : 80}
>
{firstItemWithBetterCowAmm && betterAlternativeApyDiff && betterAlternativeApyDiff > 0
? `+${betterAlternativeApyDiff.toFixed(1)}%`
{firstItemWithBetterCowAmm && betterAlternativeAprDiff && betterAlternativeAprDiff > 0
? `+${betterAlternativeAprDiff.toFixed(1)}%`
: isCowAmmAverageBetter
? `+${averageApyDiff}%`
? `+${averageAprDiff}%`
: `${cowAmmLpTokensCount}+`}
</TextFit>
</h3>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function LpTokenPage({ poolAddress, onBack, onDismiss, onSelectToken }: L
<InfoRow>
<div>APR</div>
<div>
<span>{renderValue(info?.apy, (t) => `${t}%`, '-')}</span>
<span>{renderValue(info?.apr, (t) => `${t}%`, '-')}</span>
</div>
</InfoRow>
<InfoRow>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export function LpTokenLists({
<MobileCard key={token.address} data-address={token.address} onClick={() => onSelectToken(token)}>
<MobileCardRow>{commonContent}</MobileCardRow>
<MobileCardRowItem label="Balance" value={BalanceDisplay} />
<MobileCardRowItem label="APR" value={info?.apy ? `${info.apy}%` : ''} />
<MobileCardRowItem label="APR" value={info?.apr ? `${info.apr}%` : ''} />
<MobileCardRowItem
label="Details"
value={
Expand All @@ -120,7 +120,7 @@ export function LpTokenLists({
<ListItem key={token.address} data-address={token.address} onClick={() => onSelectToken(token)}>
<LpTokenWrapper>{commonContent}</LpTokenWrapper>
<LpTokenBalance>{BalanceDisplay}</LpTokenBalance>
<LpTokenYieldPercentage>{info?.apy ? `${info.apy}%` : ''}</LpTokenYieldPercentage>
<LpTokenYieldPercentage>{info?.apr ? `${info.apr}%` : ''}</LpTokenYieldPercentage>
<LpTokenTooltip onClick={onInfoClick}>
<Info size={18} />
</LpTokenTooltip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export const CoWAmmGreenLogo = (
<CoWAmmLogo overrideColor={`var(${UI.COLOR_COWAMM_DARK_GREEN})`} variant={ProductVariant.CowAmm} logoIconOnly />
)

export const CoWAmmInlineBanner = ({ token, apyDiff }: { token: LpToken | undefined; apyDiff: number | undefined }) => {
export const CoWAmmInlineBanner = ({ token, aprDiff }: { token: LpToken | undefined; aprDiff: number | undefined }) => {
return (
<DismissableInlineBanner
bannerId="yieldTopBanner"
Expand All @@ -26,10 +26,10 @@ export const CoWAmmInlineBanner = ({ token, apyDiff }: { token: LpToken | undefi
>
<strong>Boost Your Yield with One-Click Conversion</strong>
<span>
{token && apyDiff && apyDiff > 0 ? (
{token && aprDiff && aprDiff > 0 ? (
<>
Convert your <TokenSymbol token={token} /> LP tokens into CoW AMM pools and earn up to{' '}
<strong>+{apyDiff.toFixed(1)}%</strong> more yield compared to <TokenSymbol token={token} />. Or, swap
<strong>+{aprDiff.toFixed(1)}%</strong> more yield compared to <TokenSymbol token={token} />. Or, swap
</>
) : (
'Swap'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ export function YieldWidget() {
}, [outputCurrency, poolsInfo])

const isOutputLpToken = Boolean(outputCurrency && outputCurrency instanceof LpToken)
const inputApy = inputPoolState?.info.apy
const outputApy = outputPoolState?.info.apy
const inputApy = inputPoolState?.info.apr
const outputApy = outputPoolState?.info.apr

const isTradeContainAlternativePool =
inputCurrency instanceof LpToken &&
Expand Down Expand Up @@ -167,9 +167,9 @@ export function YieldWidget() {

const slots: TradeWidgetSlots = {
topContent: vampireAttackContext ? (
<CoWAmmInlineBanner token={vampireAttackTarget?.target.token} apyDiff={vampireAttackTarget?.apyDiff} />
<CoWAmmInlineBanner token={vampireAttackTarget?.target.token} aprDiff={vampireAttackTarget?.aprDiff} />
) : !account ? (
<CoWAmmInlineBanner token={undefined} apyDiff={undefined} />
<CoWAmmInlineBanner token={undefined} aprDiff={undefined} />
) : null,
selectTokenWidget: <SelectTokenWidget displayLpTokenLists />,
settingsWidget: <SettingsTab recipientToggleState={recipientToggleState} deadlineState={deadlineState} />,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ export function useVampireAttackFirstTarget() {
if (superiorAlternative) {
return {
target: superiorAlternative,
apyDiff: superiorAlternative.alternativePoolInfo.apy - superiorAlternative.tokenPoolInfo.apy,
aprDiff: superiorAlternative.alternativePoolInfo.apr - superiorAlternative.tokenPoolInfo.apr,
}
}

if (alternative) {
return {
target: alternative,
apyDiff: undefined,
aprDiff: undefined,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SupportedChainId, mapSupportedNetworks } from '@cowprotocol/cow-sdk'
import { walletInfoAtom } from '@cowprotocol/wallet'

export interface PoolInfo {
apy: number
apr: number
tvl: number
feeTier: number
volume24h: number
Expand Down
4 changes: 2 additions & 2 deletions apps/cowswap-frontend/src/modules/yield/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ export interface VampireAttackContext {
alternatives: TokenWithAlternative[] | null
superiorAlternatives: TokenWithSuperiorAlternative[] | null
cowAmmLpTokensCount: number
poolsAverageData: Partial<Record<LpTokenProvider, { apy: number }> | undefined>
averageApyDiff: number | undefined
poolsAverageData: Partial<Record<LpTokenProvider, number> | undefined>
averageAprDiff: number | undefined
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
import { useSetAtom } from 'jotai'
import { useEffect, useMemo } from 'react'

import { BFF_BASE_URL, SWR_NO_REFRESH_OPTIONS } from '@cowprotocol/common-const'
import { useWalletInfo } from '@cowprotocol/wallet'

import ms from 'ms.macro'
import useSWR from 'swr'

import { TradeType, useTradeTypeInfo } from 'modules/trade'

import { MOCK_POOL_INFO } from './mockPoolInfo'

import { useLpTokensWithBalances } from '../../hooks/useLpTokensWithBalances'
import { usePoolsInfo } from '../../hooks/usePoolsInfo'
import { upsertPoolsInfoAtom } from '../../state/poolsInfoAtom'
import { PoolInfo, upsertPoolsInfoAtom } from '../../state/poolsInfoAtom'

const POOL_INFO_CACHE_TIME = ms`1h`

/**
* The API should return info about requested pools + alternative COW AMM pools
* When tokenAddresses is null, it should return info about all pools
*/
function fetchPoolsInfo(tokenAddresses: string[] | null) {
console.log('TODO', tokenAddresses)
return Promise.resolve(MOCK_POOL_INFO)
interface PoolInfoDto {
apr: number
chain_id: number
contract_address: string
fee: number
project: string
tvl: number
volume: number
}

export function PoolsInfoUpdater() {
const { chainId } = useWalletInfo()
const poolsInfo = usePoolsInfo()
const upsertPoolsInfo = useSetAtom(upsertPoolsInfoAtom)
const tradeTypeInfo = useTradeTypeInfo()
Expand All @@ -42,13 +46,37 @@ export function PoolsInfoUpdater() {

const tokensKey = useMemo(() => tokensToUpdate.join(','), [tokensToUpdate])

const { data: poolsAverageData } = useSWR(
tokensKey || isYield ? [chainId, tokensToUpdate, 'getPoolsInfo'] : null,
async ([chainId, tokensToUpdate]) => {
const results: PoolInfoDto[] = await fetch(`${BFF_BASE_URL}/${chainId}/yield/getPoolsInfo`, {
method: 'post',
headers: { 'content-type': 'application/json' },
body: JSON.stringify(tokensToUpdate),
}).then((res) => res.json())

return results.reduce(
(acc, val) => {
acc[val.contract_address.toLowerCase()] = {
apr: +val.apr.toFixed(2),
tvl: +val.tvl.toFixed(2),
feeTier: val.fee,
volume24h: +val.volume.toFixed(2),
}

return acc
},
{} as Record<string, PoolInfo>,
)
},
SWR_NO_REFRESH_OPTIONS,
)

useEffect(() => {
if (tokensToUpdate.length > 0 || isYield) {
fetchPoolsInfo(isYield ? null : tokensToUpdate).then(upsertPoolsInfo)
}
// To avoid excessive recalculations we use tokensKey instead of tokensToUpdate in deps
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isYield, tokensKey, upsertPoolsInfo])
if (!poolsAverageData) return

upsertPoolsInfo(poolsAverageData)
}, [poolsAverageData, upsertPoolsInfo])

return null
}
Loading
Loading