Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fd4005154 | ||
|
|
48eab0d0ac | ||
|
|
c9ee1b3b32 | ||
|
|
eb4c305eff | ||
|
|
d9825622f1 |
@@ -31,7 +31,7 @@
|
||||
"@uniswap/liquidity-staker": "^1.0.2",
|
||||
"@uniswap/merkle-distributor": "1.0.1",
|
||||
"@uniswap/sdk": "3.0.3",
|
||||
"@uniswap/token-lists": "^1.0.0-beta.17",
|
||||
"@uniswap/token-lists": "^1.0.0-beta.18",
|
||||
"@uniswap/v2-core": "1.0.0",
|
||||
"@uniswap/v2-periphery": "^1.1.0-beta.0",
|
||||
"@web3-react/core": "^6.0.9",
|
||||
|
||||
@@ -159,6 +159,26 @@ export const ButtonPink = styled(Base)`
|
||||
}
|
||||
`
|
||||
|
||||
export const ButtonUNIGradient = styled(ButtonPrimary)`
|
||||
color: white;
|
||||
padding: 4px 8px;
|
||||
height: 36px;
|
||||
font-weight: 500;
|
||||
background-color: ${({ theme }) => theme.bg3};
|
||||
background: radial-gradient(174.47% 188.91% at 1.84% 0%, #ff007a 0%, #2172e5 100%), #edeef2;
|
||||
width: fit-content;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
white-space: no-wrap;
|
||||
:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
:active {
|
||||
opacity: 0.9;
|
||||
}
|
||||
`
|
||||
|
||||
export const ButtonOutlined = styled(Base)`
|
||||
border: 1px solid ${({ theme }) => theme.bg2};
|
||||
background-color: transparent;
|
||||
|
||||
@@ -123,9 +123,6 @@ const AccountElement = styled.div<{ active: boolean }>`
|
||||
:focus {
|
||||
border: 1px solid blue;
|
||||
}
|
||||
/* :hover {
|
||||
background-color: ${({ theme, active }) => (!active ? theme.bg2 : theme.bg4)};
|
||||
} */
|
||||
`
|
||||
|
||||
const UNIAmount = styled(AccountElement)`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { JSBI, Pair, Percent } from '@uniswap/sdk'
|
||||
import { JSBI, Pair, Percent, TokenAmount } from '@uniswap/sdk'
|
||||
import { darken } from 'polished'
|
||||
import React, { useState } from 'react'
|
||||
import { ChevronDown, ChevronUp } from 'react-feather'
|
||||
@@ -9,10 +9,10 @@ import { useTotalSupply } from '../../data/TotalSupply'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useTokenBalance } from '../../state/wallet/hooks'
|
||||
import { ExternalLink, TYPE } from '../../theme'
|
||||
import { ExternalLink, TYPE, HideExtraSmall, ExtraSmallOnly } from '../../theme'
|
||||
import { currencyId } from '../../utils/currencyId'
|
||||
import { unwrappedToken } from '../../utils/wrappedCurrency'
|
||||
import { ButtonPrimary, ButtonSecondary, ButtonEmpty } from '../Button'
|
||||
import { ButtonPrimary, ButtonSecondary, ButtonEmpty, ButtonUNIGradient } from '../Button'
|
||||
import { transparentize } from 'polished'
|
||||
import { CardNoise } from '../earn/styled'
|
||||
|
||||
@@ -22,8 +22,9 @@ import Card, { GreyCard, LightCard } from '../Card'
|
||||
import { AutoColumn } from '../Column'
|
||||
import CurrencyLogo from '../CurrencyLogo'
|
||||
import DoubleCurrencyLogo from '../DoubleLogo'
|
||||
import { RowBetween, RowFixed } from '../Row'
|
||||
import { RowBetween, RowFixed, AutoRow } from '../Row'
|
||||
import { Dots } from '../swap/styleds'
|
||||
import { BIG_INT_ZERO } from '../../constants'
|
||||
|
||||
export const FixedHeightRow = styled(RowBetween)`
|
||||
height: 24px;
|
||||
@@ -47,6 +48,7 @@ interface PositionCardProps {
|
||||
pair: Pair
|
||||
showUnwrapped?: boolean
|
||||
border?: string
|
||||
stakedBalance?: TokenAmount // optional balance to indicate that liquidity is deposited in mining pool
|
||||
}
|
||||
|
||||
export function MinimalPositionCard({ pair, showUnwrapped = false, border }: PositionCardProps) {
|
||||
@@ -157,7 +159,7 @@ export function MinimalPositionCard({ pair, showUnwrapped = false, border }: Pos
|
||||
)
|
||||
}
|
||||
|
||||
export default function FullPositionCard({ pair, border }: PositionCardProps) {
|
||||
export default function FullPositionCard({ pair, border, stakedBalance }: PositionCardProps) {
|
||||
const { account } = useActiveWeb3React()
|
||||
|
||||
const currency0 = unwrappedToken(pair.token0)
|
||||
@@ -165,9 +167,12 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
|
||||
|
||||
const [showMore, setShowMore] = useState(false)
|
||||
|
||||
const userPoolBalance = useTokenBalance(account ?? undefined, pair.liquidityToken)
|
||||
const userDefaultPoolBalance = useTokenBalance(account ?? undefined, pair.liquidityToken)
|
||||
const totalPoolTokens = useTotalSupply(pair.liquidityToken)
|
||||
|
||||
// if staked balance balance provided, add to standard liquidity amount
|
||||
const userPoolBalance = stakedBalance ? userDefaultPoolBalance?.add(stakedBalance) : userDefaultPoolBalance
|
||||
|
||||
const poolTokenPercentage =
|
||||
!!userPoolBalance && !!totalPoolTokens && JSBI.greaterThanOrEqual(totalPoolTokens.raw, userPoolBalance.raw)
|
||||
? new Percent(userPoolBalance.raw, totalPoolTokens.raw)
|
||||
@@ -192,12 +197,22 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
|
||||
<CardNoise />
|
||||
<AutoColumn gap="12px">
|
||||
<FixedHeightRow>
|
||||
<RowFixed>
|
||||
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} margin={true} size={20} />
|
||||
<AutoRow gap="8px">
|
||||
<DoubleCurrencyLogo currency0={currency0} currency1={currency1} size={20} />
|
||||
<Text fontWeight={500} fontSize={20}>
|
||||
{!currency0 || !currency1 ? <Dots>Loading</Dots> : `${currency0.symbol}/${currency1.symbol}`}
|
||||
</Text>
|
||||
</RowFixed>
|
||||
{!!stakedBalance && (
|
||||
<ButtonUNIGradient as={Link} to={`/uni/${currencyId(currency0)}/${currencyId(currency1)}`}>
|
||||
<HideExtraSmall>Earning UNI</HideExtraSmall>
|
||||
<ExtraSmallOnly>
|
||||
<span role="img" aria-label="bolt">
|
||||
⚡
|
||||
</span>
|
||||
</ExtraSmallOnly>
|
||||
</ButtonUNIGradient>
|
||||
)}
|
||||
</AutoRow>
|
||||
|
||||
<RowFixed gap="8px">
|
||||
<ButtonEmpty
|
||||
@@ -208,7 +223,6 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
|
||||
>
|
||||
{showMore ? (
|
||||
<>
|
||||
{' '}
|
||||
Manage
|
||||
<ChevronUp size="20" style={{ marginLeft: '10px' }} />
|
||||
</>
|
||||
@@ -226,12 +240,22 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
|
||||
<AutoColumn gap="8px">
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Your pool tokens:
|
||||
Your total pool tokens:
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{userPoolBalance ? userPoolBalance.toSignificant(4) : '-'}
|
||||
</Text>
|
||||
</FixedHeightRow>
|
||||
{stakedBalance && (
|
||||
<FixedHeightRow>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pool tokens in rewards pool:
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{stakedBalance.toSignificant(4)}
|
||||
</Text>
|
||||
</FixedHeightRow>
|
||||
)}
|
||||
<FixedHeightRow>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
@@ -273,7 +297,9 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
|
||||
Your pool share:
|
||||
</Text>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{poolTokenPercentage ? poolTokenPercentage.toFixed(2) + '%' : '-'}
|
||||
{poolTokenPercentage
|
||||
? (poolTokenPercentage.toFixed(2) === '0.00' ? '<0.01' : poolTokenPercentage.toFixed(2)) + '%'
|
||||
: '-'}
|
||||
</Text>
|
||||
</FixedHeightRow>
|
||||
|
||||
@@ -285,26 +311,39 @@ export default function FullPositionCard({ pair, border }: PositionCardProps) {
|
||||
View accrued fees and analytics<span style={{ fontSize: '11px' }}>↗</span>
|
||||
</ExternalLink>
|
||||
</ButtonSecondary>
|
||||
<RowBetween marginTop="10px">
|
||||
{userDefaultPoolBalance && JSBI.greaterThan(userDefaultPoolBalance.raw, BIG_INT_ZERO) && (
|
||||
<RowBetween marginTop="10px">
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
borderRadius="8px"
|
||||
as={Link}
|
||||
to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
width="48%"
|
||||
>
|
||||
Add
|
||||
</ButtonPrimary>
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
borderRadius="8px"
|
||||
as={Link}
|
||||
width="48%"
|
||||
to={`/remove/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
>
|
||||
Remove
|
||||
</ButtonPrimary>
|
||||
</RowBetween>
|
||||
)}
|
||||
{stakedBalance && JSBI.greaterThan(stakedBalance.raw, BIG_INT_ZERO) && (
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
borderRadius="8px"
|
||||
as={Link}
|
||||
to={`/add/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
width="48%"
|
||||
to={`/uni/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
width="100%"
|
||||
>
|
||||
Add
|
||||
Manage Liquidity in Rewards Pool
|
||||
</ButtonPrimary>
|
||||
<ButtonPrimary
|
||||
padding="8px"
|
||||
borderRadius="8px"
|
||||
as={Link}
|
||||
width="48%"
|
||||
to={`/remove/${currencyId(currency0)}/${currencyId(currency1)}`}
|
||||
>
|
||||
Remove
|
||||
</ButtonPrimary>
|
||||
</RowBetween>
|
||||
)}
|
||||
</AutoColumn>
|
||||
)}
|
||||
</AutoColumn>
|
||||
|
||||
@@ -14,6 +14,7 @@ import { unwrappedToken } from '../../utils/wrappedCurrency'
|
||||
import { useTotalSupply } from '../../data/TotalSupply'
|
||||
import { usePair } from '../../data/Reserves'
|
||||
import useUSDCPrice from '../../utils/useUSDCPrice'
|
||||
import { BIG_INT_SECONDS_IN_WEEK } from '../../constants'
|
||||
|
||||
const StatContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -56,11 +57,6 @@ const TopSection = styled.div`
|
||||
`};
|
||||
`
|
||||
|
||||
// const APR = styled.div`
|
||||
// display: flex;
|
||||
// justify-content: flex-end;
|
||||
// `
|
||||
|
||||
const BottomSection = styled.div<{ showBackground: boolean }>`
|
||||
padding: 12px 16px;
|
||||
opacity: ${({ showBackground }) => (showBackground ? '1' : '0.4')};
|
||||
@@ -139,9 +135,15 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<TYPE.white> Pool rate </TYPE.white>
|
||||
<TYPE.white>{`${stakingInfo.totalRewardRate
|
||||
?.multiply(`${60 * 60 * 24 * 7}`)
|
||||
?.toFixed(0, { groupSeparator: ',' })} UNI / week`}</TYPE.white>
|
||||
<TYPE.white>
|
||||
{stakingInfo
|
||||
? stakingInfo.active
|
||||
? `${stakingInfo.totalRewardRate
|
||||
?.multiply(BIG_INT_SECONDS_IN_WEEK)
|
||||
?.toFixed(0, { groupSeparator: ',' })} UNI / week`
|
||||
: '0 UNI / week'
|
||||
: '-'}
|
||||
</TYPE.white>
|
||||
</RowBetween>
|
||||
</StatContainer>
|
||||
|
||||
@@ -157,9 +159,13 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
|
||||
<span role="img" aria-label="wizard-icon" style={{ marginRight: '0.5rem' }}>
|
||||
⚡
|
||||
</span>
|
||||
{`${stakingInfo.rewardRate
|
||||
?.multiply(`${60 * 60 * 24 * 7}`)
|
||||
?.toSignificant(4, { groupSeparator: ',' })} UNI / week`}
|
||||
{stakingInfo
|
||||
? stakingInfo.active
|
||||
? `${stakingInfo.rewardRate
|
||||
?.multiply(BIG_INT_SECONDS_IN_WEEK)
|
||||
?.toSignificant(4, { groupSeparator: ',' })} UNI / week`
|
||||
: '0 UNI / week'
|
||||
: '-'}
|
||||
</TYPE.black>
|
||||
</BottomSection>
|
||||
</>
|
||||
|
||||
@@ -179,6 +179,9 @@ export const INITIAL_ALLOWED_SLIPPAGE = 50
|
||||
// 20 minutes, denominated in seconds
|
||||
export const DEFAULT_DEADLINE_FROM_NOW = 60 * 20
|
||||
|
||||
// used for rewards deadlines
|
||||
export const BIG_INT_SECONDS_IN_WEEK = JSBI.BigInt(60 * 60 * 24 * 7)
|
||||
|
||||
export const BIG_INT_ZERO = JSBI.BigInt(0)
|
||||
|
||||
// one basis point
|
||||
|
||||
@@ -28,7 +28,7 @@ import { useTotalSupply } from '../../data/TotalSupply'
|
||||
import { usePair } from '../../data/Reserves'
|
||||
import usePrevious from '../../hooks/usePrevious'
|
||||
import useUSDCPrice from '../../utils/useUSDCPrice'
|
||||
import { BIG_INT_ZERO } from '../../constants'
|
||||
import { BIG_INT_ZERO, BIG_INT_SECONDS_IN_WEEK } from '../../constants'
|
||||
|
||||
const PageWrapper = styled(AutoColumn)`
|
||||
max-width: 640px;
|
||||
@@ -177,9 +177,11 @@ export default function Manage({
|
||||
<AutoColumn gap="sm">
|
||||
<TYPE.body style={{ margin: 0 }}>Pool Rate</TYPE.body>
|
||||
<TYPE.body fontSize={24} fontWeight={500}>
|
||||
{stakingInfo?.totalRewardRate
|
||||
?.multiply((60 * 60 * 24 * 7).toString())
|
||||
?.toFixed(0, { groupSeparator: ',' }) ?? '-'}
|
||||
{stakingInfo?.active
|
||||
? stakingInfo?.totalRewardRate
|
||||
?.multiply(BIG_INT_SECONDS_IN_WEEK)
|
||||
?.toFixed(0, { groupSeparator: ',' }) ?? '-'
|
||||
: '0'}
|
||||
{' UNI / week'}
|
||||
</TYPE.body>
|
||||
</AutoColumn>
|
||||
@@ -293,9 +295,11 @@ export default function Manage({
|
||||
<span role="img" aria-label="wizard-icon" style={{ marginRight: '8px ' }}>
|
||||
⚡
|
||||
</span>
|
||||
{stakingInfo?.rewardRate
|
||||
?.multiply((60 * 60 * 24 * 7).toString())
|
||||
?.toSignificant(4, { groupSeparator: ',' }) ?? '-'}
|
||||
{stakingInfo?.active
|
||||
? stakingInfo?.rewardRate
|
||||
?.multiply(BIG_INT_SECONDS_IN_WEEK)
|
||||
?.toSignificant(4, { groupSeparator: ',' }) ?? '-'
|
||||
: '0'}
|
||||
{' UNI / week'}
|
||||
</TYPE.black>
|
||||
</RowBetween>
|
||||
@@ -311,9 +315,11 @@ export default function Manage({
|
||||
|
||||
{!showAddLiquidityButton && (
|
||||
<DataRow style={{ marginBottom: '1rem' }}>
|
||||
<ButtonPrimary padding="8px" borderRadius="8px" width="160px" onClick={handleDepositClick}>
|
||||
{stakingInfo?.stakedAmount?.greaterThan(JSBI.BigInt(0)) ? 'Deposit' : 'Deposit UNI-V2 LP Tokens'}
|
||||
</ButtonPrimary>
|
||||
{stakingInfo && stakingInfo.active && (
|
||||
<ButtonPrimary padding="8px" borderRadius="8px" width="160px" onClick={handleDepositClick}>
|
||||
{stakingInfo?.stakedAmount?.greaterThan(JSBI.BigInt(0)) ? 'Deposit' : 'Deposit UNI-V2 LP Tokens'}
|
||||
</ButtonPrimary>
|
||||
)}
|
||||
|
||||
{stakingInfo?.stakedAmount?.greaterThan(JSBI.BigInt(0)) && (
|
||||
<>
|
||||
@@ -329,7 +335,7 @@ export default function Manage({
|
||||
)}
|
||||
</DataRow>
|
||||
)}
|
||||
{!userLiquidityUnstaked ? null : userLiquidityUnstaked.equalTo('0') ? null : (
|
||||
{!userLiquidityUnstaked ? null : userLiquidityUnstaked.equalTo('0') ? null : !stakingInfo?.active ? null : (
|
||||
<TYPE.main>{userLiquidityUnstaked.toSignificant(6)} UNI-V2 LP tokens available</TYPE.main>
|
||||
)}
|
||||
</PositionInfo>
|
||||
|
||||
@@ -9,6 +9,9 @@ import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/
|
||||
import { Countdown } from './Countdown'
|
||||
import Loader from '../../components/Loader'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { JSBI } from '@uniswap/sdk'
|
||||
import { BIG_INT_ZERO } from '../../constants'
|
||||
import { OutlineCard } from '../../components/Card'
|
||||
|
||||
const PageWrapper = styled(AutoColumn)`
|
||||
max-width: 640px;
|
||||
@@ -29,16 +32,25 @@ const PoolSection = styled.div`
|
||||
justify-self: center;
|
||||
`
|
||||
|
||||
const DataRow = styled(RowBetween)`
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
flex-direction: column;
|
||||
`};
|
||||
`
|
||||
|
||||
export default function Earn() {
|
||||
const { chainId } = useActiveWeb3React()
|
||||
|
||||
// staking info for connected account
|
||||
const stakingInfos = useStakingInfo()
|
||||
|
||||
const DataRow = styled(RowBetween)`
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
flex-direction: column;
|
||||
`};
|
||||
`
|
||||
/**
|
||||
* only show staking cards with balance
|
||||
* @todo only account for this if rewards are inactive
|
||||
*/
|
||||
const stakingInfosWithBalance = stakingInfos?.filter(s => JSBI.greaterThan(s.stakedAmount.raw, BIG_INT_ZERO))
|
||||
|
||||
// toggle copy if rewards are inactive
|
||||
const stakingRewardsExist = Boolean(typeof chainId === 'number' && (STAKING_REWARDS_INFO[chainId]?.length ?? 0) > 0)
|
||||
|
||||
return (
|
||||
@@ -81,9 +93,11 @@ export default function Earn() {
|
||||
{stakingRewardsExist && stakingInfos?.length === 0 ? (
|
||||
<Loader style={{ margin: 'auto' }} />
|
||||
) : !stakingRewardsExist ? (
|
||||
'No active rewards'
|
||||
<OutlineCard>No active pools</OutlineCard>
|
||||
) : stakingInfos?.length !== 0 && stakingInfosWithBalance.length === 0 ? (
|
||||
<OutlineCard>No active pools</OutlineCard>
|
||||
) : (
|
||||
stakingInfos?.map(stakingInfo => {
|
||||
stakingInfosWithBalance?.map(stakingInfo => {
|
||||
// need to sort by added liquidity here
|
||||
return <PoolCard key={stakingInfo.stakingRewardAddress} stakingInfo={stakingInfo} />
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useContext, useMemo } from 'react'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import { Pair } from '@uniswap/sdk'
|
||||
import { Pair, JSBI } from '@uniswap/sdk'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { SwapPoolTabs } from '../../components/NavigationTabs'
|
||||
|
||||
@@ -19,6 +19,8 @@ import { usePairs } from '../../data/Reserves'
|
||||
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
|
||||
import { Dots } from '../../components/swap/styleds'
|
||||
import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/earn/styled'
|
||||
import { useStakingInfo } from '../../state/stake/hooks'
|
||||
import { BIG_INT_ZERO } from '../../constants'
|
||||
|
||||
const PageWrapper = styled(AutoColumn)`
|
||||
max-width: 640px;
|
||||
@@ -107,11 +109,24 @@ export default function Pool() {
|
||||
|
||||
const hasV1Liquidity = useUserHasLiquidityInAllTokens()
|
||||
|
||||
// show liquidity even if its deposited in rewards contract
|
||||
const stakingInfo = useStakingInfo()
|
||||
const stakingInfosWithBalance = stakingInfo?.filter(pool => JSBI.greaterThan(pool.stakedAmount.raw, BIG_INT_ZERO))
|
||||
const stakingPairs = usePairs(stakingInfosWithBalance?.map(stakingInfo => stakingInfo.tokens))
|
||||
|
||||
// remove any pairs that also are included in pairs with stake in mining pool
|
||||
const v2PairsWithoutStakedAmount = allV2PairsWithLiquidity.filter(v2Pair => {
|
||||
return (
|
||||
stakingPairs
|
||||
?.map(stakingPair => stakingPair[1])
|
||||
.filter(stakingPair => stakingPair?.liquidityToken.address === v2Pair.liquidityToken.address).length === 0
|
||||
)
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageWrapper>
|
||||
<SwapPoolTabs active={'pool'} />
|
||||
|
||||
<VoteCard>
|
||||
<CardBGImage />
|
||||
<CardNoise />
|
||||
@@ -170,7 +185,7 @@ export default function Pool() {
|
||||
<Dots>Loading</Dots>
|
||||
</TYPE.body>
|
||||
</EmptyProposals>
|
||||
) : allV2PairsWithLiquidity?.length > 0 ? (
|
||||
) : allV2PairsWithLiquidity?.length > 0 || stakingPairs?.length > 0 ? (
|
||||
<>
|
||||
<ButtonSecondary>
|
||||
<RowBetween>
|
||||
@@ -180,10 +195,19 @@ export default function Pool() {
|
||||
<span> ↗</span>
|
||||
</RowBetween>
|
||||
</ButtonSecondary>
|
||||
|
||||
{allV2PairsWithLiquidity.map(v2Pair => (
|
||||
{v2PairsWithoutStakedAmount.map(v2Pair => (
|
||||
<FullPositionCard key={v2Pair.liquidityToken.address} pair={v2Pair} />
|
||||
))}
|
||||
{stakingPairs.map(
|
||||
(stakingPair, i) =>
|
||||
stakingPair[1] && ( // skip pairs that arent loaded
|
||||
<FullPositionCard
|
||||
key={stakingInfosWithBalance[i].stakingRewardAddress}
|
||||
pair={stakingPair[1]}
|
||||
stakedBalance={stakingInfosWithBalance[i].stakedAmount}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<EmptyProposals>
|
||||
|
||||
@@ -5,6 +5,7 @@ import { STAKING_REWARDS_INTERFACE } from '../../constants/abis/staking-rewards'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { NEVER_RELOAD, useMultipleContractSingleData } from '../multicall/hooks'
|
||||
import { tryParseAmount } from '../swap/hooks'
|
||||
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
|
||||
|
||||
export const STAKING_GENESIS = 1600387200
|
||||
|
||||
@@ -55,6 +56,8 @@ export interface StakingInfo {
|
||||
rewardRate: TokenAmount
|
||||
// when the period ends
|
||||
periodFinish: Date | undefined
|
||||
// if pool is active
|
||||
active: boolean
|
||||
// calculates a hypothetical amount of token distributed to the active account per second.
|
||||
getHypotheticalRewardRate: (
|
||||
stakedAmount: TokenAmount,
|
||||
@@ -67,6 +70,9 @@ export interface StakingInfo {
|
||||
export function useStakingInfo(pairToFilterBy?: Pair | null): StakingInfo[] {
|
||||
const { chainId, account } = useActiveWeb3React()
|
||||
|
||||
// detect if staking is ended
|
||||
const currentBlockTimestamp = useCurrentBlockTimestamp()
|
||||
|
||||
const info = useMemo(
|
||||
() =>
|
||||
chainId
|
||||
@@ -170,7 +176,12 @@ export function useStakingInfo(pairToFilterBy?: Pair | null): StakingInfo[] {
|
||||
|
||||
const individualRewardRate = getHypotheticalRewardRate(stakedAmount, totalStakedAmount, totalRewardRate)
|
||||
|
||||
const periodFinishMs = periodFinishState.result?.[0]?.mul(1000)?.toNumber()
|
||||
const periodFinishSeconds = periodFinishState.result?.[0]?.toNumber()
|
||||
const periodFinishMs = periodFinishSeconds * 1000
|
||||
|
||||
// compare period end timestamp vs current block timestamp (in seconds)
|
||||
const active =
|
||||
periodFinishSeconds && currentBlockTimestamp ? periodFinishSeconds > currentBlockTimestamp.toNumber() : true
|
||||
|
||||
memo.push({
|
||||
stakingRewardAddress: rewardsAddress,
|
||||
@@ -181,12 +192,24 @@ export function useStakingInfo(pairToFilterBy?: Pair | null): StakingInfo[] {
|
||||
totalRewardRate: totalRewardRate,
|
||||
stakedAmount: stakedAmount,
|
||||
totalStakedAmount: totalStakedAmount,
|
||||
getHypotheticalRewardRate
|
||||
getHypotheticalRewardRate,
|
||||
active
|
||||
})
|
||||
}
|
||||
return memo
|
||||
}, [])
|
||||
}, [balances, chainId, earnedAmounts, info, periodFinishes, rewardRates, rewardsAddresses, totalSupplies, uni])
|
||||
}, [
|
||||
balances,
|
||||
chainId,
|
||||
currentBlockTimestamp,
|
||||
earnedAmounts,
|
||||
info,
|
||||
periodFinishes,
|
||||
rewardRates,
|
||||
rewardsAddresses,
|
||||
totalSupplies,
|
||||
uni
|
||||
])
|
||||
}
|
||||
|
||||
export function useTotalUniEarned(): TokenAmount | undefined {
|
||||
|
||||
@@ -185,3 +185,16 @@ export const HideSmall = styled.span`
|
||||
display: none;
|
||||
`};
|
||||
`
|
||||
|
||||
export const HideExtraSmall = styled.span`
|
||||
${({ theme }) => theme.mediaWidth.upToExtraSmall`
|
||||
display: none;
|
||||
`};
|
||||
`
|
||||
|
||||
export const ExtraSmallOnly = styled.span`
|
||||
display: none;
|
||||
${({ theme }) => theme.mediaWidth.upToExtraSmall`
|
||||
display: block;
|
||||
`};
|
||||
`
|
||||
|
||||
@@ -10,5 +10,10 @@ describe('parseENSAddress', () => {
|
||||
expect(parseENSAddress('abso.lutely.eth')).toEqual({ ensName: 'abso.lutely.eth', ensPath: undefined })
|
||||
expect(parseENSAddress('eth')).toEqual(undefined)
|
||||
expect(parseENSAddress('eth/hello-world')).toEqual(undefined)
|
||||
expect(parseENSAddress('hello-world.eth')).toEqual({ ensName: 'hello-world.eth', ensPath: undefined })
|
||||
expect(parseENSAddress('-prefix-dash.eth')).toEqual(undefined)
|
||||
expect(parseENSAddress('suffix-dash-.eth')).toEqual(undefined)
|
||||
expect(parseENSAddress('it.eth')).toEqual({ ensName: 'it.eth', ensPath: undefined })
|
||||
expect(parseENSAddress('only-single--dash.eth')).toEqual(undefined)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const ENS_NAME_REGEX = /^(([a-zA-Z0-9]+\.)+)eth(\/.*)?$/
|
||||
const ENS_NAME_REGEX = /^(([a-zA-Z0-9]+(-[a-zA-Z0-9]+)*\.)+)eth(\/.*)?$/
|
||||
|
||||
export function parseENSAddress(ensAddress: string): { ensName: string; ensPath: string | undefined } | undefined {
|
||||
const match = ensAddress.match(ENS_NAME_REGEX)
|
||||
if (!match) return undefined
|
||||
return { ensName: `${match[1].toLowerCase()}eth`, ensPath: match[3] }
|
||||
return { ensName: `${match[1].toLowerCase()}eth`, ensPath: match[4] }
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
"jsx": "preserve",
|
||||
"downlevelIteration": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"types": ["react-spring", "jest"]
|
||||
"types": ["react-spring", "jest"],
|
||||
"baseUrl": "src"
|
||||
},
|
||||
"exclude": ["node_modules", "cypress"],
|
||||
"include": ["./src/**/*.ts", "./src/**/*.tsx", "src/components/Confetti/index.js"]
|
||||
|
||||
@@ -2726,10 +2726,10 @@
|
||||
tiny-warning "^1.0.3"
|
||||
toformat "^2.0.0"
|
||||
|
||||
"@uniswap/token-lists@^1.0.0-beta.17":
|
||||
version "1.0.0-beta.17"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/token-lists/-/token-lists-1.0.0-beta.17.tgz#a861fe96a0f3de91b01eae05dec05a6a2018b38e"
|
||||
integrity sha512-UVRmSsP/ghJ7Dg8BHYjAZmZL96jHlZKrFoIEuKD3g1E4FbahfwS2j2KAaf6iQuLx6RWo8PQmDZ99rfK6T2xi8w==
|
||||
"@uniswap/token-lists@^1.0.0-beta.18":
|
||||
version "1.0.0-beta.18"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/token-lists/-/token-lists-1.0.0-beta.18.tgz#b6c70b67fa9ee142e6df088e40490ec3a545e7ba"
|
||||
integrity sha512-RuDY36JUc2+Id2Dlpnt+coFfUEf9WkfvR0a3LKvwVgzAfcrd5KvjZg+PhAr4bczFU1aq7rs3/QLgwpsnFYaiPw==
|
||||
|
||||
"@uniswap/v2-core@1.0.0":
|
||||
version "1.0.0"
|
||||
|
||||
Reference in New Issue
Block a user