Skip to content

Commit

Permalink
fix(yield): show green banner only when vampire attack is ready (#5064)
Browse files Browse the repository at this point in the history
* fix(yield): show green banner only when vampire attack is ready

* fix(yield): make APR green only when another token is alternative

* chore: fix displaying of apy

* chore: fix cow amm banner displaying

* chore: reset lp token balances

* chore: reset balances loaded flag

* chore: reset balances cache

* chore: fix lpTokensWithBalancesAtom state

* chore: fix lint
  • Loading branch information
shoom3301 authored Nov 21, 2024
1 parent 94d71f1 commit cd9f2e1
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 130 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,9 @@ export function LpBalancesAndAllowancesUpdater({ account, chainId, enablePolling
return () => clearTimeout(timeout)
}, [])

useEffect(() => {
setAreLpBalancesLoaded(false)
}, [account, setAreLpBalancesLoaded])

return null
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const CoWAmmInlineBanner = ({ token, apyDiff }: { token: LpToken | undefi
{token && apyDiff && apyDiff > 0 ? (
<>
Convert your <TokenSymbol token={token} /> LP tokens into CoW AMM pools and earn up to{' '}
<strong>+{apyDiff}%</strong> more yield compared to <TokenSymbol token={token} />. Or, swap
<strong>+{apyDiff.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 @@ -27,7 +27,7 @@ import { CurrencyInfo } from 'common/pure/CurrencyInputPanel/types'
import { CoWAmmInlineBanner, SelectAPoolButton } from './elements'

import { usePoolsInfo } from '../../hooks/usePoolsInfo'
import { useVampireAttackFirstTarget } from '../../hooks/useVampireAttack'
import { useVampireAttack, useVampireAttackFirstTarget } from '../../hooks/useVampireAttack'
import { useYieldDerivedState } from '../../hooks/useYieldDerivedState'
import {
useYieldDeadlineState,
Expand Down Expand Up @@ -58,7 +58,7 @@ const YIELD_UNLOCK_SCREEN = {
}

export function YieldWidget() {
const { chainId } = useWalletInfo()
const { chainId, account } = useWalletInfo()
const { showRecipient } = useYieldSettings()
const deadlineState = useYieldDeadlineState()
const recipientToggleState = useYieldRecipientToggleState()
Expand All @@ -69,6 +69,7 @@ export function YieldWidget() {
const widgetActions = useYieldWidgetActions()
const receiveAmountInfo = useReceiveAmountInfo()
const poolsInfo = usePoolsInfo()
const vampireAttackContext = useVampireAttack()
const vampireAttackTarget = useVampireAttackFirstTarget()

const {
Expand Down Expand Up @@ -100,6 +101,11 @@ export function YieldWidget() {
const inputApy = inputPoolState?.info.apy
const outputApy = outputPoolState?.info.apy

const isTradeContainAlternativePool =
inputCurrency instanceof LpToken &&
outputCurrency instanceof LpToken &&
inputCurrency.tokens.every((token) => outputCurrency.tokens.includes(token))

const inputCurrencyInfo: CurrencyInfo = {
field: Field.INPUT,
currency: inputCurrency,
Expand All @@ -113,8 +119,7 @@ export function YieldWidget() {
<PoolApyPreview
apy={inputApy}
isSuperior={Boolean(
inputCurrency &&
inputCurrency instanceof LpToken &&
isTradeContainAlternativePool &&
inputCurrency.lpTokenProvider === LpTokenProvider.COW_AMM &&
(inputApy && outputApy ? inputApy > outputApy : true),
)}
Expand All @@ -136,7 +141,7 @@ export function YieldWidget() {
<PoolApyPreview
apy={outputApy}
isSuperior={Boolean(
outputCurrency instanceof LpToken &&
isTradeContainAlternativePool &&
outputCurrency.lpTokenProvider === LpTokenProvider.COW_AMM &&
(inputApy && outputApy ? outputApy > inputApy : true),
)}
Expand All @@ -161,7 +166,11 @@ export function YieldWidget() {
const rateInfoParams = useRateInfoParams(inputCurrencyInfo.amount, outputCurrencyInfo.amount)

const slots: TradeWidgetSlots = {
topContent: <CoWAmmInlineBanner token={vampireAttackTarget?.target.token} apyDiff={vampireAttackTarget?.apyDiff} />,
topContent: vampireAttackContext ? (
<CoWAmmInlineBanner token={vampireAttackTarget?.target.token} apyDiff={vampireAttackTarget?.apyDiff} />
) : !account ? (
<CoWAmmInlineBanner token={undefined} apyDiff={undefined} />
) : null,
selectTokenWidget: <SelectTokenWidget displayLpTokenLists />,
settingsWidget: <SettingsTab recipientToggleState={recipientToggleState} deadlineState={deadlineState} />,
bottomContent: useCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ export type LpTokenWithBalance = {

type LpTokensWithBalancesState = { tokens: Record<string, LpTokenWithBalance>; count: 0 }

export const LP_TOKENS_WITH_BALANCES_DEFAULT_STATE: LpTokensWithBalancesState = { tokens: {}, count: 0 }
export const LP_TOKENS_WITH_BALANCES_DEFAULT_STATE: () => LpTokensWithBalancesState = () => ({ tokens: {}, count: 0 })

export const lpTokensWithBalancesAtom = atom<LpTokensWithBalancesState>(LP_TOKENS_WITH_BALANCES_DEFAULT_STATE)
export const lpTokensWithBalancesAtom = atom<LpTokensWithBalancesState>(LP_TOKENS_WITH_BALANCES_DEFAULT_STATE())
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,41 @@ import { useEffect } from 'react'

import { useTokensBalances } from '@cowprotocol/balances-and-allowances'
import { TokenListCategory, useAllLpTokens } from '@cowprotocol/tokens'
import { useWalletInfo } from '@cowprotocol/wallet'

import { LP_TOKENS_WITH_BALANCES_DEFAULT_STATE, lpTokensWithBalancesAtom } from '../../state/lpTokensWithBalancesAtom'

const LP_CATEGORY = [TokenListCategory.LP]

export function LpTokensWithBalancesUpdater() {
const { account } = useWalletInfo()
const lpTokens = useAllLpTokens(LP_CATEGORY)
const { values: balances } = useTokensBalances()
const setState = useSetAtom(lpTokensWithBalancesAtom)

useEffect(() => {
if (!lpTokens.length) return

const state = lpTokens.reduce(
(acc, token) => {
const addressLower = token.address.toLowerCase()
const balance = balances[addressLower]
const state = lpTokens.reduce((acc, token) => {
const addressLower = token.address.toLowerCase()
const balance = balances[addressLower]

if (balance && !balance.isZero()) {
acc.count++
acc.tokens[addressLower] = { token, balance }
}
if (balance && !balance.isZero()) {
acc.count++
acc.tokens[addressLower] = { token, balance }
}

return acc
},
{ ...LP_TOKENS_WITH_BALANCES_DEFAULT_STATE },
)
return acc
}, LP_TOKENS_WITH_BALANCES_DEFAULT_STATE())

setState(state)
}, [setState, lpTokens, balances])

useEffect(() => {
if (!account) {
setState(LP_TOKENS_WITH_BALANCES_DEFAULT_STATE())
}
}, [account, setState])

return null
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useEffect, useMemo } from 'react'

import { LP_TOKEN_LIST_COW_AMM_ONLY, useAllLpTokens } from '@cowprotocol/tokens'
import { LpTokenProvider } from '@cowprotocol/types'
import { useWalletInfo } from '@cowprotocol/wallet'

import { useLpTokensWithBalances, usePoolsInfo } from 'modules/yield/shared'
import { POOLS_AVERAGE_DATA_MOCK } from 'modules/yield/updaters/PoolsInfoUpdater/mockPoolInfo'
Expand All @@ -14,6 +15,7 @@ import { vampireAttackAtom } from '../state/vampireAttackAtom'
import { TokenWithAlternative, TokenWithSuperiorAlternative } from '../types'

export function VampireAttackUpdater(): null {
const { account } = useWalletInfo()
const { tokens: lpTokensWithBalances, count: lpTokensWithBalancesCount } = useLpTokensWithBalances()
const cowAmmLpTokens = useAllLpTokens(LP_TOKEN_LIST_COW_AMM_ONLY)
const poolsInfo = usePoolsInfo()
Expand Down Expand Up @@ -102,12 +104,12 @@ export function VampireAttackUpdater(): null {
})

useEffect(() => {
if (cowAmmLpTokens.length === 0 || !areLpBalancesLoaded) {
if (!account || cowAmmLpTokens.length === 0 || !areLpBalancesLoaded) {
setVampireAttack(null)
} else {
setVampireAttack(context)
}
}, [context, cowAmmLpTokens.length, areLpBalancesLoaded, setVampireAttack])
}, [account, context, cowAmmLpTokens.length, areLpBalancesLoaded, setVampireAttack])

return null
}
18 changes: 12 additions & 6 deletions libs/balances-and-allowances/src/updaters/BalancesCacheUpdater.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { useAtom } from 'jotai/index'
import { useEffect, useRef } from 'react'
import { useEffect, useLayoutEffect, useRef } from 'react'

import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { mapSupportedNetworks, SupportedChainId } from '@cowprotocol/cow-sdk'
import { BigNumber } from '@ethersproject/bignumber'

import { balancesAtom, balancesCacheAtom } from '../state/balancesAtom'

export function BalancesCacheUpdater({ chainId }: { chainId: SupportedChainId }) {
export function BalancesCacheUpdater({ chainId, account }: { chainId: SupportedChainId; account?: string }) {
const [balances, setBalances] = useAtom(balancesAtom)
const [balancesCache, setBalancesCache] = useAtom(balancesCacheAtom)
const areBalancesRestoredFromCacheRef = useRef(false)

// Persist into localStorage only non-zero balances
useEffect(() => {
if (!account) {
setBalancesCache(mapSupportedNetworks({}))
return
}

setBalancesCache((state) => {
const balancesValues = balances.values

Expand Down Expand Up @@ -50,12 +55,13 @@ export function BalancesCacheUpdater({ chainId }: { chainId: SupportedChainId })
},
}
})
}, [chainId, balances.values, setBalancesCache, setBalances])
}, [chainId, account, balances.values, setBalancesCache])

// Restore balances from cache once
useEffect(() => {
useLayoutEffect(() => {
const cache = balancesCache[chainId]

if (!account) return
if (areBalancesRestoredFromCacheRef.current) return
if (!cache) return

Expand Down Expand Up @@ -83,7 +89,7 @@ export function BalancesCacheUpdater({ chainId }: { chainId: SupportedChainId })
})

return
}, [balancesCache, chainId, setBalances])
}, [balancesCache, chainId, account, setBalances])

return null
}

0 comments on commit cd9f2e1

Please sign in to comment.