feat: quick fix for new governor
This commit is contained in:
parent
9eb20624cb
commit
5dd1249ddd
@ -16,10 +16,12 @@ export const V2_ROUTER_ADDRESS: AddressMap = constructSameAddressMap(
|
||||
'0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
|
||||
false
|
||||
)
|
||||
export const GOVERNANCE_ADDRESS: AddressMap = constructSameAddressMap(
|
||||
'0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F',
|
||||
false
|
||||
)
|
||||
export const GOVERNANCE_ADDRESSES: AddressMap[] = [
|
||||
constructSameAddressMap('0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F', false),
|
||||
{
|
||||
[SupportedChainId.MAINNET]: '0xC4e172459f1E7939D522503B81AFAaC1014CE6F6',
|
||||
},
|
||||
]
|
||||
export const TIMELOCK_ADDRESS: AddressMap = constructSameAddressMap('0x1a9C8182C09F50C8318d769245beA52c32BE35BC', false)
|
||||
export const MERKLE_DISTRIBUTOR_ADDRESS: AddressMap = {
|
||||
[SupportedChainId.MAINNET]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
|
||||
|
@ -1,31 +1,12 @@
|
||||
import { GOVERNANCE_ADDRESS, TIMELOCK_ADDRESS, UNI_ADDRESS } from './addresses'
|
||||
import { GOVERNANCE_ADDRESSES, TIMELOCK_ADDRESS, UNI_ADDRESS } from './addresses'
|
||||
|
||||
export const COMMON_CONTRACT_NAMES: { [chainId: number]: { [address: string]: string } } = {
|
||||
[1]: {
|
||||
[UNI_ADDRESS[1]]: 'UNI',
|
||||
[GOVERNANCE_ADDRESS[1]]: 'Governance',
|
||||
[GOVERNANCE_ADDRESSES[0][1]]: 'Governance (V0)',
|
||||
[GOVERNANCE_ADDRESSES[1][1]]: 'Governance',
|
||||
[TIMELOCK_ADDRESS[1]]: 'Timelock',
|
||||
},
|
||||
[4]: {
|
||||
[UNI_ADDRESS[4]]: 'Rinkeby UNI',
|
||||
[GOVERNANCE_ADDRESS[4]]: 'Rinkeby Governance',
|
||||
[TIMELOCK_ADDRESS[4]]: 'Rinkeby Timelock',
|
||||
},
|
||||
[3]: {
|
||||
[UNI_ADDRESS[3]]: 'Ropsten UNI',
|
||||
[GOVERNANCE_ADDRESS[3]]: 'Ropsten Governance',
|
||||
[TIMELOCK_ADDRESS[3]]: 'Ropsten Timelock',
|
||||
},
|
||||
[42]: {
|
||||
[UNI_ADDRESS[42]]: 'Kovan UNI',
|
||||
[GOVERNANCE_ADDRESS[42]]: 'Kovan Governance',
|
||||
[TIMELOCK_ADDRESS[42]]: 'Kovan Timelock',
|
||||
},
|
||||
[5]: {
|
||||
[UNI_ADDRESS[5]]: 'Goerli UNI',
|
||||
[GOVERNANCE_ADDRESS[5]]: 'Goerli Governance',
|
||||
[TIMELOCK_ADDRESS[5]]: 'Goerli Timelock',
|
||||
},
|
||||
}
|
||||
|
||||
export const DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS = 13
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { UNISWAP_GRANTS_PROPOSAL_DESCRIPTION } from './uniswap_grants_proposal_description'
|
||||
|
||||
// Proposals are 0-indexed
|
||||
export const PROPOSAL_DESCRIPTION_TEXT: { [proposalId: number]: string } = {
|
||||
[2]: UNISWAP_GRANTS_PROPOSAL_DESCRIPTION,
|
||||
}
|
@ -27,7 +27,7 @@ import {
|
||||
V3_CORE_FACTORY_ADDRESSES,
|
||||
V3_MIGRATOR_ADDRESSES,
|
||||
ARGENT_WALLET_DETECTOR_ADDRESS,
|
||||
GOVERNANCE_ADDRESS,
|
||||
GOVERNANCE_ADDRESSES,
|
||||
MERKLE_DISTRIBUTOR_ADDRESS,
|
||||
MULTICALL2_ADDRESSES,
|
||||
V2_ROUTER_ADDRESS,
|
||||
@ -116,8 +116,11 @@ export function useMerkleDistributorContract() {
|
||||
return useContract(MERKLE_DISTRIBUTOR_ADDRESS, MERKLE_DISTRIBUTOR_ABI, true)
|
||||
}
|
||||
|
||||
export function useGovernanceContract() {
|
||||
return useContract(GOVERNANCE_ADDRESS, GOVERNANCE_ABI, true)
|
||||
export function useGovernanceContracts(): (Contract | null)[] {
|
||||
return [
|
||||
useContract(GOVERNANCE_ADDRESSES[0], GOVERNANCE_ABI, false),
|
||||
useContract(GOVERNANCE_ADDRESSES[1], GOVERNANCE_ABI, true),
|
||||
]
|
||||
}
|
||||
|
||||
export function useUniContract() {
|
||||
|
@ -120,7 +120,8 @@ export default function Vote() {
|
||||
const toggleDelegateModal = useToggleDelegateModal()
|
||||
|
||||
// get data to list all proposals
|
||||
const allProposals: ProposalData[] = useAllProposalData()
|
||||
// TODO don't hardcode for first gov alpha
|
||||
const allProposals: ProposalData[] = useAllProposalData()[0]
|
||||
|
||||
// user data
|
||||
const availableVotes: CurrencyAmount<Token> | undefined = useUserVotes()
|
||||
@ -248,7 +249,7 @@ export default function Vote() {
|
||||
</TYPE.subHeader>
|
||||
</EmptyProposals>
|
||||
)}
|
||||
{allProposals?.map((p: ProposalData, i) => {
|
||||
{allProposals?.reverse()?.map((p: ProposalData, i) => {
|
||||
return (
|
||||
<Proposal as={Link} to={'/vote/' + p.id} key={i}>
|
||||
<ProposalNumber>{p.id}</ProposalNumber>
|
||||
|
@ -1,8 +1,7 @@
|
||||
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { isAddress } from 'ethers/lib/utils'
|
||||
import { PROPOSAL_DESCRIPTION_TEXT } from '../../constants/proposals'
|
||||
import { UNI } from '../../constants/tokens'
|
||||
import { useGovernanceContract, useUniContract } from '../../hooks/useContract'
|
||||
import { useGovernanceContracts, useUniContract } from '../../hooks/useContract'
|
||||
import { calculateGasMargin } from '../../utils/calculateGasMargin'
|
||||
import { useSingleCallResult, useSingleContractMultipleData } from '../multicall/hooks'
|
||||
import { useActiveWeb3React } from '../../hooks/web3'
|
||||
@ -11,6 +10,7 @@ import { TransactionResponse } from '@ethersproject/providers'
|
||||
import { useTransactionAdder } from '../transactions/hooks'
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react'
|
||||
import { abi as GOV_ABI } from '@uniswap/governance/build/GovernorAlpha.json'
|
||||
import { UNISWAP_GRANTS_PROPOSAL_DESCRIPTION } from 'constants/proposals/uniswap_grants_proposal_description'
|
||||
|
||||
interface ProposalDetail {
|
||||
target: string
|
||||
@ -43,10 +43,9 @@ export enum ProposalState {
|
||||
Executed,
|
||||
}
|
||||
|
||||
// get count of all proposals made
|
||||
export function useProposalCount(): number | undefined {
|
||||
const gov = useGovernanceContract()
|
||||
const res = useSingleCallResult(gov, 'proposalCount')
|
||||
// get count of all proposals made on the given governor alpha
|
||||
function useProposalCount(govContract: ethers.Contract | null): number | undefined {
|
||||
const res = useSingleCallResult(govContract, 'proposalCount')
|
||||
if (res.result && !res.loading) {
|
||||
return parseInt(res.result[0])
|
||||
}
|
||||
@ -58,15 +57,15 @@ export function useProposalCount(): number | undefined {
|
||||
* new proposal event.
|
||||
*/
|
||||
const eventParser = new ethers.utils.Interface(GOV_ABI)
|
||||
export function useDataFromEventLogs() {
|
||||
function useDataFromEventLogs(govContract: ethers.Contract | null) {
|
||||
const { library, chainId } = useActiveWeb3React()
|
||||
const [formattedEvents, setFormattedEvents] =
|
||||
useState<{ description: string; details: { target: string; functionSig: string; callData: string }[] }[]>()
|
||||
const govContract = useGovernanceContract()
|
||||
|
||||
// create filter for these specific events
|
||||
const filter = useMemo(
|
||||
() => (govContract ? { ...govContract.filters.ProposalCreated(), fromBlock: 0, toBlock: 'latest' } : undefined),
|
||||
() =>
|
||||
govContract ? { ...govContract.filters.ProposalCreated(), fromBlock: 10861678, toBlock: 'latest' } : undefined,
|
||||
[govContract]
|
||||
)
|
||||
|
||||
@ -79,9 +78,7 @@ export function useDataFromEventLogs() {
|
||||
.getLogs(filter)
|
||||
.then((proposalEvents) => {
|
||||
if (stale) return
|
||||
// reverse events to get them from newest to odlest
|
||||
const formattedEventData = proposalEvents
|
||||
?.map((event) => {
|
||||
const formattedEventData = proposalEvents?.map((event) => {
|
||||
const eventParsed = eventParser.parseLog(event).args
|
||||
return {
|
||||
description: eventParsed.description,
|
||||
@ -100,7 +97,6 @@ export function useDataFromEventLogs() {
|
||||
}),
|
||||
}
|
||||
})
|
||||
.reverse()
|
||||
setFormattedEvents(formattedEventData)
|
||||
})
|
||||
.catch((error) => {
|
||||
@ -118,55 +114,93 @@ export function useDataFromEventLogs() {
|
||||
}
|
||||
|
||||
// get data for all past and active proposals
|
||||
export function useAllProposalData() {
|
||||
const proposalCount = useProposalCount()
|
||||
const govContract = useGovernanceContract()
|
||||
export function useAllProposalData(): ProposalData[][] {
|
||||
// fetch all governance contracts
|
||||
const govContracts = useGovernanceContracts()
|
||||
|
||||
const proposalIndexes = []
|
||||
for (let i = 1; i <= (proposalCount ?? 0); i++) {
|
||||
proposalIndexes.push([i])
|
||||
}
|
||||
// fetch the proposal count on the active contract
|
||||
const proposalCount = useProposalCount(govContracts[govContracts.length - 1])
|
||||
|
||||
// get metadata from past events
|
||||
const formattedEvents = useDataFromEventLogs()
|
||||
// get all proposals for all contracts
|
||||
const proposalsIndicesByGovContract = [
|
||||
[1, 2, 3, 4], // hardcoded for first governor alpha
|
||||
typeof proposalCount === 'number' ? new Array(proposalCount).fill(0).map((_, i) => i + 1) : [], // dynamic for current governor alpha
|
||||
]
|
||||
|
||||
// get all proposal entities
|
||||
const allProposals = useSingleContractMultipleData(govContract, 'proposals', proposalIndexes)
|
||||
const allProposalsByGovContract = [
|
||||
useSingleContractMultipleData(
|
||||
govContracts[0],
|
||||
'proposals',
|
||||
proposalsIndicesByGovContract[0].map((i) => [i])
|
||||
),
|
||||
useSingleContractMultipleData(
|
||||
govContracts[1],
|
||||
'proposals',
|
||||
proposalsIndicesByGovContract[1].map((i) => [i])
|
||||
),
|
||||
]
|
||||
|
||||
// get all proposal states
|
||||
const allProposalStates = useSingleContractMultipleData(govContract, 'state', proposalIndexes)
|
||||
const allProposalStatesByGovContract = [
|
||||
useSingleContractMultipleData(
|
||||
govContracts[0],
|
||||
'state',
|
||||
proposalsIndicesByGovContract[0].map((i) => [i])
|
||||
),
|
||||
useSingleContractMultipleData(
|
||||
govContracts[1],
|
||||
'state',
|
||||
proposalsIndicesByGovContract[1].map((i) => [i])
|
||||
),
|
||||
]
|
||||
|
||||
if (formattedEvents && allProposals && allProposalStates) {
|
||||
allProposals.reverse()
|
||||
allProposalStates.reverse()
|
||||
// get metadata from past events
|
||||
const formattedEventsByGovContract = [useDataFromEventLogs(govContracts[0]), useDataFromEventLogs(govContracts[1])]
|
||||
|
||||
return allProposals
|
||||
.filter((p, i) => {
|
||||
return Boolean(p.result) && Boolean(allProposalStates[i]?.result) && Boolean(formattedEvents[i])
|
||||
})
|
||||
.map((p, i) => {
|
||||
const description = PROPOSAL_DESCRIPTION_TEXT[allProposals.length - i - 1] || formattedEvents[i].description
|
||||
const formattedProposal: ProposalData = {
|
||||
id: allProposals[i]?.result?.id.toString(),
|
||||
title: description?.split(/# |\n/g)[1] || 'Untitled',
|
||||
description: description || 'No description.',
|
||||
proposer: allProposals[i]?.result?.proposer,
|
||||
const returnData: ProposalData[][] = []
|
||||
|
||||
for (let governorIndex = 0; governorIndex < allProposalsByGovContract.length; governorIndex++) {
|
||||
const allProposals = allProposalsByGovContract[governorIndex]
|
||||
const allProposalStates = allProposalStatesByGovContract[governorIndex]
|
||||
const formattedEvents = formattedEventsByGovContract[governorIndex]
|
||||
|
||||
if (
|
||||
allProposals?.every((p) => Boolean(p.result)) &&
|
||||
allProposalStates?.every((p) => Boolean(p.result)) &&
|
||||
formattedEvents?.every((p) => Boolean(p))
|
||||
) {
|
||||
returnData.push(
|
||||
allProposals.map((proposal, i): ProposalData => {
|
||||
let description = formattedEvents[i].description
|
||||
// overwrite broken description
|
||||
if (governorIndex === 0 && i === 2) description = UNISWAP_GRANTS_PROPOSAL_DESCRIPTION
|
||||
|
||||
return {
|
||||
id: proposal?.result?.id.toString(),
|
||||
title: description?.split(/# |\n/g)[1] ?? 'Untitled',
|
||||
description: description ?? 'No description.',
|
||||
proposer: proposal?.result?.proposer,
|
||||
status: allProposalStates[i]?.result?.[0] ?? ProposalState.Undetermined,
|
||||
forCount: parseFloat(ethers.utils.formatUnits(allProposals[i]?.result?.forVotes.toString(), 18)),
|
||||
againstCount: parseFloat(ethers.utils.formatUnits(allProposals[i]?.result?.againstVotes.toString(), 18)),
|
||||
startBlock: parseInt(allProposals[i]?.result?.startBlock?.toString()),
|
||||
endBlock: parseInt(allProposals[i]?.result?.endBlock?.toString()),
|
||||
forCount: parseFloat(ethers.utils.formatUnits(proposal?.result?.forVotes.toString(), 18)),
|
||||
againstCount: parseFloat(ethers.utils.formatUnits(proposal?.result?.againstVotes.toString(), 18)),
|
||||
startBlock: parseInt(proposal?.result?.startBlock?.toString()),
|
||||
endBlock: parseInt(proposal?.result?.endBlock?.toString()),
|
||||
details: formattedEvents[i].details,
|
||||
}
|
||||
return formattedProposal
|
||||
})
|
||||
)
|
||||
} else {
|
||||
return []
|
||||
returnData.push([])
|
||||
}
|
||||
}
|
||||
|
||||
return returnData
|
||||
}
|
||||
|
||||
export function useProposalData(id: string): ProposalData | undefined {
|
||||
const allProposalData = useAllProposalData()
|
||||
// TODO don't hardcode for first gov alpha
|
||||
const allProposalData = useAllProposalData()[0]
|
||||
return allProposalData?.find((p) => p.id === id)
|
||||
}
|
||||
|
||||
@ -232,7 +266,10 @@ export function useVoteCallback(): {
|
||||
} {
|
||||
const { account } = useActiveWeb3React()
|
||||
|
||||
const govContract = useGovernanceContract()
|
||||
// we only care about voting on the active governance contract
|
||||
const govContracts = useGovernanceContracts()
|
||||
const govContract = govContracts[govContracts.length - 1]
|
||||
|
||||
const addTransaction = useTransactionAdder()
|
||||
|
||||
const voteCallback = useCallback(
|
||||
|
Loading…
Reference in New Issue
Block a user