Commit 50a599c0 authored by Ian Lapham's avatar Ian Lapham Committed by GitHub

update vote fetching logic, delegate only on global page (#1165)

* update vote fetching logic, delegate only on global page

* Update index.ts

* add helper message on proposal page
Co-authored-by: default avatarNoah Zinsmeister <noahwz@gmail.com>
parent 9c473270
...@@ -25,6 +25,8 @@ export const PROPOSAL_LENGTH_IN_DAYS = 7 ...@@ -25,6 +25,8 @@ export const PROPOSAL_LENGTH_IN_DAYS = 7
export const GOVERNANCE_ADDRESS = '0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F' export const GOVERNANCE_ADDRESS = '0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F'
export const TIMELOCK_ADDRESS = '0x1a9C8182C09F50C8318d769245beA52c32BE35BC'
const UNI_ADDRESS = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984' const UNI_ADDRESS = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
export const UNI: { [chainId in ChainId]: Token } = { export const UNI: { [chainId in ChainId]: Token } = {
[ChainId.MAINNET]: new Token(ChainId.MAINNET, UNI_ADDRESS, 18, 'UNI', 'Uniswap'), [ChainId.MAINNET]: new Token(ChainId.MAINNET, UNI_ADDRESS, 18, 'UNI', 'Uniswap'),
...@@ -35,9 +37,9 @@ export const UNI: { [chainId in ChainId]: Token } = { ...@@ -35,9 +37,9 @@ export const UNI: { [chainId in ChainId]: Token } = {
} }
export const COMMON_CONTRACT_NAMES: { [address: string]: string } = { export const COMMON_CONTRACT_NAMES: { [address: string]: string } = {
'0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984': 'UNI', [UNI_ADDRESS]: 'UNI',
'0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F': 'Governance Alpha', [GOVERNANCE_ADDRESS]: 'Governance',
'0x1a9C8182C09F50C8318d769245beA52c32BE35BC': 'Timelock' [TIMELOCK_ADDRESS]: 'Timelock'
} }
// TODO: specify merkle distributor for mainnet // TODO: specify merkle distributor for mainnet
......
...@@ -9,19 +9,20 @@ import { CardSection, DataCard } from '../../components/earn/styled' ...@@ -9,19 +9,20 @@ import { CardSection, DataCard } from '../../components/earn/styled'
import { ArrowLeft } from 'react-feather' import { ArrowLeft } from 'react-feather'
import { ButtonPrimary } from '../../components/Button' import { ButtonPrimary } from '../../components/Button'
import { ProposalStatus } from './styled' import { ProposalStatus } from './styled'
import { useProposalData, useUserVotes, useUserDelegatee, ProposalData } from '../../state/governance/hooks' import { useProposalData, useUserVotesAsOfBlock, ProposalData, useUserDelegatee } from '../../state/governance/hooks'
import { useTimestampFromBlock } from '../../hooks/useTimestampFromBlock' import { useTimestampFromBlock } from '../../hooks/useTimestampFromBlock'
import { DateTime } from 'luxon' import { DateTime } from 'luxon'
import ReactMarkdown from 'react-markdown' import ReactMarkdown from 'react-markdown'
import VoteModal from '../../components/vote/VoteModal' import VoteModal from '../../components/vote/VoteModal'
import { TokenAmount, JSBI } from '@uniswap/sdk' import { TokenAmount, JSBI } from '@uniswap/sdk'
import { useTokenBalance } from '../../state/wallet/hooks'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import { UNI, ZERO_ADDRESS, PROPOSAL_LENGTH_IN_DAYS, COMMON_CONTRACT_NAMES } from '../../constants' import { PROPOSAL_LENGTH_IN_DAYS, COMMON_CONTRACT_NAMES, UNI, ZERO_ADDRESS } from '../../constants'
import { isAddress, getEtherscanLink } from '../../utils' import { isAddress, getEtherscanLink } from '../../utils'
import { ApplicationModal } from '../../state/application/actions' import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useToggleDelegateModal, useToggleVoteModal } from '../../state/application/hooks' import { useModalOpen, useToggleDelegateModal, useToggleVoteModal } from '../../state/application/hooks'
import DelegateModal from '../../components/vote/DelegateModal' import DelegateModal from '../../components/vote/DelegateModal'
import { GreyCard } from '../../components/Card'
import { useTokenBalance } from '../../state/wallet/hooks'
const PageWrapper = styled(AutoColumn)` const PageWrapper = styled(AutoColumn)`
width: 100%; width: 100%;
...@@ -102,7 +103,7 @@ export default function VotePage({ ...@@ -102,7 +103,7 @@ export default function VotePage({
params: { id } params: { id }
} }
}: RouteComponentProps<{ id: string }>) { }: RouteComponentProps<{ id: string }>) {
const { account, chainId } = useActiveWeb3React() const { chainId, account } = useActiveWeb3React()
// get data for this specific proposal // get data for this specific proposal
const proposalData: ProposalData | undefined = useProposalData(id) const proposalData: ProposalData | undefined = useProposalData(id)
...@@ -132,11 +133,21 @@ export default function VotePage({ ...@@ -132,11 +133,21 @@ export default function VotePage({
const againstPercentage: string = const againstPercentage: string =
proposalData && totalVotes ? ((proposalData.againstCount * 100) / totalVotes).toFixed(0) + '%' : '0%' proposalData && totalVotes ? ((proposalData.againstCount * 100) / totalVotes).toFixed(0) + '%' : '0%'
// show delegation option if they have have a balance, have not delegated // only count available votes as of the proposal start block
const availableVotes: TokenAmount | undefined = useUserVotes() const availableVotes: TokenAmount | undefined = useUserVotesAsOfBlock(proposalData?.startBlock ?? undefined)
// only show voting if user has > 0 votes at proposal start block and proposal is active,
const showVotingButtons =
availableVotes &&
JSBI.greaterThan(availableVotes.raw, JSBI.BigInt(0)) &&
proposalData &&
proposalData.status === 'active'
const uniBalance: TokenAmount | undefined = useTokenBalance(account ?? undefined, chainId ? UNI[chainId] : undefined) const uniBalance: TokenAmount | undefined = useTokenBalance(account ?? undefined, chainId ? UNI[chainId] : undefined)
const userDelegatee: string | undefined = useUserDelegatee() const userDelegatee: string | undefined = useUserDelegatee()
const showUnlockVoting = Boolean(
// in blurb link to home page if they are able to unlock
const showLinkForUnlock = Boolean(
uniBalance && JSBI.notEqual(uniBalance.raw, JSBI.BigInt(0)) && userDelegatee === ZERO_ADDRESS uniBalance && JSBI.notEqual(uniBalance.raw, JSBI.BigInt(0)) && userDelegatee === ZERO_ADDRESS
) )
...@@ -171,23 +182,22 @@ export default function VotePage({ ...@@ -171,23 +182,22 @@ export default function VotePage({
? 'Voting ends approximately ' + (endDate && endDate.toLocaleString(DateTime.DATETIME_FULL)) ? 'Voting ends approximately ' + (endDate && endDate.toLocaleString(DateTime.DATETIME_FULL))
: ''} : ''}
</TYPE.main> </TYPE.main>
{showUnlockVoting && endDate && endDate > now && (
<ButtonPrimary
style={{ width: 'fit-content' }}
padding="8px"
borderRadius="8px"
onClick={toggelDelegateModal}
>
Unlock Voting
</ButtonPrimary>
)}
</RowBetween> </RowBetween>
{proposalData && proposalData.status === 'active' && !showVotingButtons && (
<GreyCard>
<TYPE.black>
Only UNI votes that were self delegated or delegated to another address before block{' '}
{proposalData.startBlock} are eligible for voting.{' '}
{showLinkForUnlock && (
<span>
<StyledInternalLink to="/vote">Unlock voting</StyledInternalLink> to prepare for the next proposal.
</span>
)}
</TYPE.black>
</GreyCard>
)}
</AutoColumn> </AutoColumn>
{!showUnlockVoting && {showVotingButtons ? (
availableVotes &&
JSBI.greaterThan(availableVotes?.raw, JSBI.BigInt(0)) &&
endDate &&
endDate > now ? (
<RowFixed style={{ width: '100%', gap: '12px' }}> <RowFixed style={{ width: '100%', gap: '12px' }}>
<ButtonPrimary <ButtonPrimary
padding="8px" padding="8px"
......
...@@ -153,6 +153,7 @@ export function useUserDelegatee(): string { ...@@ -153,6 +153,7 @@ export function useUserDelegatee(): string {
return result?.[0] ?? undefined return result?.[0] ?? undefined
} }
// gets the users current votes
export function useUserVotes(): TokenAmount | undefined { export function useUserVotes(): TokenAmount | undefined {
const { account, chainId } = useActiveWeb3React() const { account, chainId } = useActiveWeb3React()
const uniContract = useUniContract() const uniContract = useUniContract()
...@@ -163,6 +164,18 @@ export function useUserVotes(): TokenAmount | undefined { ...@@ -163,6 +164,18 @@ export function useUserVotes(): TokenAmount | undefined {
return votes && uni ? new TokenAmount(uni, votes) : undefined return votes && uni ? new TokenAmount(uni, votes) : undefined
} }
// fetch available votes as of block (usually proposal start block)
export function useUserVotesAsOfBlock(block: number | undefined): TokenAmount | undefined {
const { account, chainId } = useActiveWeb3React()
const uniContract = useUniContract()
// check for available votes
const uni = chainId ? UNI[chainId] : undefined
const votes = useSingleCallResult(uniContract, 'getPriorVotes', [account ?? undefined, block ?? undefined])
?.result?.[0]
return votes && uni ? new TokenAmount(uni, votes) : undefined
}
export function useDelegateCallback(): (delegatee: string | undefined) => undefined | Promise<string> { export function useDelegateCallback(): (delegatee: string | undefined) => undefined | Promise<string> {
const { account, chainId, library } = useActiveWeb3React() const { account, chainId, library } = useActiveWeb3React()
const addTransaction = useTransactionAdder() const addTransaction = useTransactionAdder()
......
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