Commit b50cac01 authored by Moody Salem's avatar Moody Salem

fix(uni): fix uni in circulation calculation and make uni button always show up

parent 1ac16586
...@@ -6,6 +6,7 @@ import tokenLogo from '../../assets/images/token-logo.png' ...@@ -6,6 +6,7 @@ import tokenLogo from '../../assets/images/token-logo.png'
import { UNI } from '../../constants' import { UNI } from '../../constants'
import { useTotalSupply } from '../../data/TotalSupply' import { useTotalSupply } from '../../data/TotalSupply'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import { useMerkleDistributorContract } from '../../hooks/useContract'
import useCurrentBlockTimestamp from '../../hooks/useCurrentBlockTimestamp' import useCurrentBlockTimestamp from '../../hooks/useCurrentBlockTimestamp'
import { useTotalUniEarned } from '../../state/stake/hooks' import { useTotalUniEarned } from '../../state/stake/hooks'
import { useAggregateUniBalance, useTokenBalance } from '../../state/wallet/hooks' import { useAggregateUniBalance, useTokenBalance } from '../../state/wallet/hooks'
...@@ -45,15 +46,18 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU ...@@ -45,15 +46,18 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
const total = useAggregateUniBalance() const total = useAggregateUniBalance()
const uniBalance: TokenAmount | undefined = useTokenBalance(account ?? undefined, uni) const uniBalance: TokenAmount | undefined = useTokenBalance(account ?? undefined, uni)
const uniUnHarvested: TokenAmount | undefined = useTotalUniEarned() const uniToClaim: TokenAmount | undefined = useTotalUniEarned()
const totalSupply: TokenAmount | undefined = useTotalSupply(uni) const totalSupply: TokenAmount | undefined = useTotalSupply(uni)
const uniPrice = useUSDCPrice(uni) const uniPrice = useUSDCPrice(uni)
const blockTimestamp = useCurrentBlockTimestamp() const blockTimestamp = useCurrentBlockTimestamp()
const unclaimedUni = useTokenBalance(useMerkleDistributorContract()?.address, uni)
const circulation: TokenAmount | undefined = useMemo( const circulation: TokenAmount | undefined = useMemo(
() => () =>
blockTimestamp && uni && chainId === ChainId.MAINNET ? computeUniCirculation(uni, blockTimestamp) : totalSupply, blockTimestamp && uni && chainId === ChainId.MAINNET
[blockTimestamp, chainId, totalSupply, uni] ? computeUniCirculation(uni, blockTimestamp, unclaimedUni)
: totalSupply,
[blockTimestamp, chainId, totalSupply, unclaimedUni, uni]
) )
return ( return (
...@@ -63,37 +67,41 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU ...@@ -63,37 +67,41 @@ export default function UniBalanceContent({ setShowUniBalanceModal }: { setShowU
<CardNoise /> <CardNoise />
<CardSection gap="md"> <CardSection gap="md">
<RowBetween> <RowBetween>
<TYPE.white color="white">Your UNI Breakdown</TYPE.white>{' '} <TYPE.white color="white">Your UNI Breakdown</TYPE.white>
<StyledClose stroke="white" onClick={() => setShowUniBalanceModal(false)} /> <StyledClose stroke="white" onClick={() => setShowUniBalanceModal(false)} />
</RowBetween> </RowBetween>
</CardSection> </CardSection>
<Break /> <Break />
<CardSection gap="sm"> {account && (
<AutoColumn gap="md" justify="center"> <>
<UniTokenAnimated width="48px" src={tokenLogo} />{' '} <CardSection gap="sm">
<TYPE.white fontSize={48} fontWeight={600} color="white"> <AutoColumn gap="md" justify="center">
{total?.toFixed(2, { groupSeparator: ',' })} <UniTokenAnimated width="48px" src={tokenLogo} />{' '}
</TYPE.white> <TYPE.white fontSize={48} fontWeight={600} color="white">
</AutoColumn> {total?.toFixed(2, { groupSeparator: ',' })}
<AutoColumn gap="md"> </TYPE.white>
<RowBetween> </AutoColumn>
<TYPE.white color="white">Balance:</TYPE.white> <AutoColumn gap="md">
<TYPE.white color="white">{uniBalance?.toFixed(2, { groupSeparator: ',' })}</TYPE.white> <RowBetween>
</RowBetween> <TYPE.white color="white">Balance:</TYPE.white>
<RowBetween> <TYPE.white color="white">{uniBalance?.toFixed(2, { groupSeparator: ',' })}</TYPE.white>
<TYPE.white color="white">Unclaimed:</TYPE.white> </RowBetween>
<TYPE.white color="white"> <RowBetween>
{uniUnHarvested?.toFixed(4, { groupSeparator: ',' })}{' '} <TYPE.white color="white">Unclaimed:</TYPE.white>
{uniUnHarvested && ( <TYPE.white color="white">
<StyledInternalLink onClick={() => setShowUniBalanceModal(false)} to="/uni"> {uniToClaim?.toFixed(4, { groupSeparator: ',' })}{' '}
(claim) {uniToClaim && uniToClaim.greaterThan('0') && (
</StyledInternalLink> <StyledInternalLink onClick={() => setShowUniBalanceModal(false)} to="/uni">
)} (claim)
</TYPE.white> </StyledInternalLink>
</RowBetween> )}
</AutoColumn> </TYPE.white>
</CardSection> </RowBetween>
<Break /> </AutoColumn>
</CardSection>
<Break />
</>
)}
<CardSection gap="sm"> <CardSection gap="sm">
<AutoColumn gap="md"> <AutoColumn gap="md">
<RowBetween> <RowBetween>
......
import { ChainId, TokenAmount, JSBI } from '@uniswap/sdk' import { ChainId, TokenAmount } from '@uniswap/sdk'
import React, { useState } from 'react' import React, { useState } from 'react'
import { Text } from 'rebass' import { Text } from 'rebass'
import { NavLink, withRouter } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { darken } from 'polished' import { darken } from 'polished'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
...@@ -264,7 +264,7 @@ const NETWORK_LABELS: { [chainId in ChainId]?: string } = { ...@@ -264,7 +264,7 @@ const NETWORK_LABELS: { [chainId in ChainId]?: string } = {
[ChainId.KOVAN]: 'Kovan' [ChainId.KOVAN]: 'Kovan'
} }
function Header({ history }: { history: any }) { export default function Header() {
const { account, chainId } = useActiveWeb3React() const { account, chainId } = useActiveWeb3React()
const { t } = useTranslation() const { t } = useTranslation()
...@@ -292,34 +292,32 @@ function Header({ history }: { history: any }) { ...@@ -292,34 +292,32 @@ function Header({ history }: { history: any }) {
<UniBalanceContent setShowUniBalanceModal={setShowUniBalanceModal} /> <UniBalanceContent setShowUniBalanceModal={setShowUniBalanceModal} />
</Modal> </Modal>
<HeaderRow> <HeaderRow>
<Title href="." style={{}}> <Title href=".">
<UniIcon> <UniIcon>
<img width={'24px'} src={isDark ? LogoDark : Logo} alt="logo" /> <img width={'24px'} src={isDark ? LogoDark : Logo} alt="logo" />
</UniIcon> </UniIcon>
</Title> </Title>
<HeaderLinks> <HeaderLinks>
<StyledNavLink id={`swap-nav-link`} to={'/swap'} isActive={() => history.location.pathname.includes('/swap')}> <StyledNavLink id={`swap-nav-link`} to={'/swap'}>
{t('swap')} {t('swap')}
</StyledNavLink> </StyledNavLink>
<StyledNavLink <StyledNavLink
id={`pool-nav-link`} id={`pool-nav-link`}
to={'/pool'} to={'/pool'}
isActive={() => isActive={(match, { pathname }) =>
history.location.pathname.includes('/pool') || Boolean(match) ||
history.location.pathname.includes('/add') || pathname.startsWith('/add') ||
history.location.pathname.includes('/remove') pathname.startsWith('/remove') ||
pathname.startsWith('/create') ||
pathname.startsWith('/find')
} }
> >
{t('pool')} {t('pool')}
</StyledNavLink> </StyledNavLink>
<StyledNavLink id={`stake-nav-link`} to={'/uni'} isActive={() => history.location.pathname.includes('/uni')}> <StyledNavLink id={`stake-nav-link`} to={'/uni'}>
UNI UNI
</StyledNavLink> </StyledNavLink>
<StyledNavLink <StyledNavLink id={`stake-nav-link`} to={'/vote'}>
id={`stake-nav-link`}
to={'/vote'}
isActive={() => history.location.pathname.includes('/vote')}
>
Vote Vote
</StyledNavLink> </StyledNavLink>
<StyledExternalLink id={`stake-nav-link`} href={'https://uniswap.info'}> <StyledExternalLink id={`stake-nav-link`} href={'https://uniswap.info'}>
...@@ -344,26 +342,28 @@ function Header({ history }: { history: any }) { ...@@ -344,26 +342,28 @@ function Header({ history }: { history: any }) {
<CardNoise /> <CardNoise />
</UNIWrapper> </UNIWrapper>
)} )}
{!availableClaim && aggregateBalance && JSBI.greaterThan(aggregateBalance.raw, JSBI.BigInt(0)) && ( {!availableClaim && aggregateBalance && (
<UNIWrapper onClick={() => setShowUniBalanceModal(true)}> <UNIWrapper onClick={() => setShowUniBalanceModal(true)}>
<UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}> <UNIAmount active={!!account && !availableClaim} style={{ pointerEvents: 'auto' }}>
<HideSmall> {account && (
<TYPE.white <HideSmall>
style={{ <TYPE.white
paddingRight: '.4rem' style={{
}} paddingRight: '.4rem'
> }}
<CountUp >
key={countUpValue} <CountUp
isCounting key={countUpValue}
start={parseFloat(countUpValuePrevious)} isCounting
end={parseFloat(countUpValue)} start={parseFloat(countUpValuePrevious)}
thousandsSeparator={','} end={parseFloat(countUpValue)}
duration={1} thousandsSeparator={','}
/> duration={1}
</TYPE.white> />
</HideSmall> </TYPE.white>
{'UNI'} </HideSmall>
)}
UNI
</UNIAmount> </UNIAmount>
<CardNoise /> <CardNoise />
</UNIWrapper> </UNIWrapper>
...@@ -385,5 +385,3 @@ function Header({ history }: { history: any }) { ...@@ -385,5 +385,3 @@ function Header({ history }: { history: any }) {
</HeaderFrame> </HeaderFrame>
) )
} }
export default withRouter(Header)
import { ChainId, JSBI, Token, TokenAmount } from '@uniswap/sdk'
import { BigNumber } from 'ethers'
import { ZERO_ADDRESS } from '../constants'
import { computeUniCirculation } from './computeUniCirculation'
describe('computeUniCirculation', () => {
const token = new Token(ChainId.RINKEBY, ZERO_ADDRESS, 18)
function expandTo18Decimals(num: JSBI | string | number) {
return JSBI.multiply(JSBI.BigInt(num), JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(18)))
}
function tokenAmount(num: JSBI | string | number) {
return new TokenAmount(token, expandTo18Decimals(num))
}
it('before staking', () => {
expect(computeUniCirculation(token, BigNumber.from(0), undefined)).toEqual(tokenAmount(150_000_000))
expect(computeUniCirculation(token, BigNumber.from(1600387200), undefined)).toEqual(tokenAmount(150_000_000))
})
it('mid staking', () => {
expect(computeUniCirculation(token, BigNumber.from(1600387200 + 15 * 24 * 60 * 60), undefined)).toEqual(
tokenAmount(155_000_000)
)
})
it('after staking and treasury vesting cliff', () => {
expect(computeUniCirculation(token, BigNumber.from(1600387200 + 60 * 24 * 60 * 60), undefined)).toEqual(
tokenAmount(224_575_341)
)
})
it('subtracts unclaimed uni', () => {
expect(computeUniCirculation(token, BigNumber.from(1600387200 + 15 * 24 * 60 * 60), tokenAmount(1000))).toEqual(
tokenAmount(154_999_000)
)
})
})
...@@ -38,21 +38,27 @@ function withVesting(before: JSBI, time: BigNumber, amount: number, start: numbe ...@@ -38,21 +38,27 @@ function withVesting(before: JSBI, time: BigNumber, amount: number, start: numbe
if (time.gt(start)) { if (time.gt(start)) {
if (time.gte(end)) { if (time.gte(end)) {
return JSBI.add(before, JSBI.BigInt(amount)) return JSBI.add(before, JSBI.BigInt(amount))
} else if (cliff && time.gte(cliff)) { } else {
return JSBI.add( if ((typeof cliff === 'number' && time.gte(cliff)) || typeof cliff === 'undefined') {
before, return JSBI.add(
JSBI.divide( before,
JSBI.multiply(JSBI.BigInt(amount), JSBI.BigInt(time.sub(start).toString())), JSBI.divide(
JSBI.subtract(JSBI.BigInt(end), JSBI.BigInt(start)) JSBI.multiply(JSBI.BigInt(amount), JSBI.BigInt(time.sub(start).toString())),
JSBI.subtract(JSBI.BigInt(end), JSBI.BigInt(start))
)
) )
) }
} }
} }
return before return before
} }
export function computeUniCirculation(uni: Token, blockTimestamp: BigNumber): TokenAmount { export function computeUniCirculation(
let wholeAmount = JSBI.BigInt(USERS_AMOUNT) // users, 15% uni: Token,
blockTimestamp: BigNumber,
unclaimedUni: TokenAmount | undefined
): TokenAmount {
let wholeAmount = JSBI.BigInt(USERS_AMOUNT)
// staking rewards // staking rewards
wholeAmount = withVesting(wholeAmount, blockTimestamp, STAKING_REWARDS_AMOUNT, STAKING_GENESIS, STAKING_END) wholeAmount = withVesting(wholeAmount, blockTimestamp, STAKING_REWARDS_AMOUNT, STAKING_GENESIS, STAKING_END)
...@@ -101,5 +107,6 @@ export function computeUniCirculation(uni: Token, blockTimestamp: BigNumber): To ...@@ -101,5 +107,6 @@ export function computeUniCirculation(uni: Token, blockTimestamp: BigNumber): To
wholeAmount = withVesting(wholeAmount, blockTimestamp, TEAM_YEAR_3_AMOUNT, TREASURY_BEGIN_YEAR_3, TREASURY_END_YEAR_3) wholeAmount = withVesting(wholeAmount, blockTimestamp, TEAM_YEAR_3_AMOUNT, TREASURY_BEGIN_YEAR_3, TREASURY_END_YEAR_3)
wholeAmount = withVesting(wholeAmount, blockTimestamp, TEAM_YEAR_4_AMOUNT, TREASURY_BEGIN_YEAR_4, TREASURY_END_YEAR_4) wholeAmount = withVesting(wholeAmount, blockTimestamp, TEAM_YEAR_4_AMOUNT, TREASURY_BEGIN_YEAR_4, TREASURY_END_YEAR_4)
return new TokenAmount(uni, JSBI.multiply(wholeAmount, JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(18)))) const total = new TokenAmount(uni, JSBI.multiply(wholeAmount, JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(18))))
return unclaimedUni ? total.subtract(unclaimedUni) : total
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment