feat: quick fix for new governor

This commit is contained in:
Noah Zinsmeister 2021-06-13 15:15:00 -04:00
parent 9eb20624cb
commit 5dd1249ddd
No known key found for this signature in database
GPG Key ID: 83022DD49188C9F2
6 changed files with 122 additions and 104 deletions

@ -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,28 +78,25 @@ 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 eventParsed = eventParser.parseLog(event).args
return {
description: eventParsed.description,
details: eventParsed.targets.map((target: string, i: number) => {
const signature = eventParsed.signatures[i]
const [name, types] = signature.substr(0, signature.length - 1).split('(')
const formattedEventData = proposalEvents?.map((event) => {
const eventParsed = eventParser.parseLog(event).args
return {
description: eventParsed.description,
details: eventParsed.targets.map((target: string, i: number) => {
const signature = eventParsed.signatures[i]
const [name, types] = signature.substr(0, signature.length - 1).split('(')
const calldata = eventParsed.calldatas[i]
const decoded = utils.defaultAbiCoder.decode(types.split(','), calldata)
const calldata = eventParsed.calldatas[i]
const decoded = utils.defaultAbiCoder.decode(types.split(','), calldata)
return {
target,
functionSig: name,
callData: decoded.join(', '),
}
}),
}
})
.reverse()
return {
target,
functionSig: name,
callData: decoded.join(', '),
}
}),
}
})
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,
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()),
details: formattedEvents[i].details,
}
return formattedProposal
})
} else {
return []
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(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,
}
})
)
} else {
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(