restrict governance UI to mainnet only
fix governor name bug revert useContract change add governorIndex to vote page only fetch latest useLatestProposalCount fix useDataFromEventLogs hardcode proposalIndexes for old governors
This commit is contained in:
parent
d9bd392e6d
commit
b763659788
@ -18,13 +18,19 @@ export const V2_ROUTER_ADDRESS: AddressMap = constructSameAddressMap(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// most current governance contract address should always be the 0 index
|
// most current governance contract address should always be the 0 index
|
||||||
|
// only support governance on mainnet
|
||||||
export const GOVERNANCE_ADDRESSES: AddressMap[] = [
|
export const GOVERNANCE_ADDRESSES: AddressMap[] = [
|
||||||
{
|
{
|
||||||
[SupportedChainId.MAINNET]: '0xC4e172459f1E7939D522503B81AFAaC1014CE6F6',
|
[SupportedChainId.MAINNET]: '0xC4e172459f1E7939D522503B81AFAaC1014CE6F6',
|
||||||
},
|
},
|
||||||
constructSameAddressMap('0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F', false),
|
{
|
||||||
|
[SupportedChainId.MAINNET]: '0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F',
|
||||||
|
},
|
||||||
]
|
]
|
||||||
export const TIMELOCK_ADDRESS: AddressMap = constructSameAddressMap('0x1a9C8182C09F50C8318d769245beA52c32BE35BC', false)
|
export const TIMELOCK_ADDRESS: AddressMap = {
|
||||||
|
[SupportedChainId.MAINNET]: '0x1a9C8182C09F50C8318d769245beA52c32BE35BC',
|
||||||
|
}
|
||||||
|
|
||||||
export const MERKLE_DISTRIBUTOR_ADDRESS: AddressMap = {
|
export const MERKLE_DISTRIBUTOR_ADDRESS: AddressMap = {
|
||||||
[SupportedChainId.MAINNET]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
|
[SupportedChainId.MAINNET]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,9 @@ const governanceContracts = (): Record<string, string> =>
|
|||||||
GOVERNANCE_ADDRESSES.reduce(
|
GOVERNANCE_ADDRESSES.reduce(
|
||||||
(acc, addressMap, i) => ({
|
(acc, addressMap, i) => ({
|
||||||
...acc,
|
...acc,
|
||||||
[addressMap[SupportedChainId.MAINNET]]: `Governance${i === GOVERNANCE_ADDRESSES.length - 1 ? '' : ` (V${i})`}`,
|
[addressMap[SupportedChainId.MAINNET]]: `Governance${
|
||||||
|
i === 0 ? '' : ` (V${GOVERNANCE_ADDRESSES.length - 1 - i})`
|
||||||
|
}`,
|
||||||
}),
|
}),
|
||||||
{}
|
{}
|
||||||
)
|
)
|
||||||
|
@ -1,2 +1 @@
|
|||||||
export const UNISWAP_GRANTS_START_BLOCK = 11473815
|
export const UNISWAP_GRANTS_START_BLOCK = 11473815
|
||||||
export const EDUCATION_FUND_1_START_BLOCK = 12620175
|
|
||||||
|
@ -46,34 +46,19 @@ import { useActiveWeb3React } from './web3'
|
|||||||
|
|
||||||
// returns null on errors
|
// returns null on errors
|
||||||
export function useContract<T extends Contract = Contract>(
|
export function useContract<T extends Contract = Contract>(
|
||||||
addressOrAddressMap: string | { [chainId: number]: string } | { [chainId: number]: string }[] | undefined,
|
addressOrAddressMap: string | { [chainId: number]: string } | undefined,
|
||||||
ABI: any,
|
ABI: any,
|
||||||
withSignerIfPossible = true
|
withSignerIfPossible = true
|
||||||
): T | null {
|
): T | null {
|
||||||
const { library, account, chainId } = useActiveWeb3React()
|
const { library, account, chainId } = useActiveWeb3React()
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (!addressOrAddressMap || !ABI || !library || !chainId) {
|
if (!addressOrAddressMap || !ABI || !library || !chainId) return null
|
||||||
return null
|
|
||||||
}
|
|
||||||
let address: string | undefined
|
let address: string | undefined
|
||||||
if (typeof addressOrAddressMap === 'string') {
|
if (typeof addressOrAddressMap === 'string') address = addressOrAddressMap
|
||||||
address = addressOrAddressMap
|
else address = addressOrAddressMap[chainId]
|
||||||
} else if (!Array.isArray(addressOrAddressMap)) {
|
if (!address) return null
|
||||||
address = addressOrAddressMap[chainId]
|
|
||||||
}
|
|
||||||
if (!address && !Array.isArray(addressOrAddressMap)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
if (Array.isArray(addressOrAddressMap)) {
|
|
||||||
return addressOrAddressMap.map((addressMap) =>
|
|
||||||
getContract(addressMap[chainId], ABI, library, withSignerIfPossible && account ? account : undefined)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (!address) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return getContract(address, ABI, library, withSignerIfPossible && account ? account : undefined)
|
return getContract(address, ABI, library, withSignerIfPossible && account ? account : undefined)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to get contract', error)
|
console.error('Failed to get contract', error)
|
||||||
@ -131,21 +116,22 @@ export function useMerkleDistributorContract() {
|
|||||||
return useContract(MERKLE_DISTRIBUTOR_ADDRESS, MERKLE_DISTRIBUTOR_ABI, true)
|
return useContract(MERKLE_DISTRIBUTOR_ADDRESS, MERKLE_DISTRIBUTOR_ABI, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useGovernanceContracts(): Contract[] | null {
|
export function useGovernanceContracts(): (Contract | null)[] {
|
||||||
const { library, account, chainId } = useActiveWeb3React()
|
const { library, account, chainId } = useActiveWeb3React()
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (!library || !chainId) {
|
if (!library || !chainId) {
|
||||||
return null
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return GOVERNANCE_ADDRESSES.filter((addressMap) => Boolean(addressMap[chainId])).map((addressMap) => {
|
||||||
try {
|
try {
|
||||||
return GOVERNANCE_ADDRESSES.filter((addressMap) => Boolean(addressMap[chainId])).map((addressMap) =>
|
return getContract(addressMap[chainId], GOVERNANCE_ABI, library, account ? account : undefined)
|
||||||
getContract(addressMap[chainId], GOVERNANCE_ABI, library, account ? account : undefined)
|
|
||||||
)
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to get contract', error)
|
console.error('Failed to get contract', error)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}, [library, chainId, account])
|
}, [library, chainId, account])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ export default function App() {
|
|||||||
<Web3ReactManager>
|
<Web3ReactManager>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact strict path="/vote" component={Vote} />
|
<Route exact strict path="/vote" component={Vote} />
|
||||||
<Route exact strict path="/vote/:id" component={VotePage} />
|
<Route exact strict path="/vote/:governorIndex/:id" component={VotePage} />
|
||||||
<Route exact strict path="/claim" component={OpenClaimAddressModalAndRedirectToSwap} />
|
<Route exact strict path="/claim" component={OpenClaimAddressModalAndRedirectToSwap} />
|
||||||
<Route exact strict path="/uni" component={Earn} />
|
<Route exact strict path="/uni" component={Earn} />
|
||||||
<Route exact strict path="/uni/:currencyIdA/:currencyIdB" component={Manage} />
|
<Route exact strict path="/uni/:currencyIdA/:currencyIdB" component={Manage} />
|
||||||
|
@ -121,13 +121,13 @@ const ProposerAddressLink = styled(ExternalLink)`
|
|||||||
|
|
||||||
export default function VotePage({
|
export default function VotePage({
|
||||||
match: {
|
match: {
|
||||||
params: { id },
|
params: { governorIndex, id },
|
||||||
},
|
},
|
||||||
}: RouteComponentProps<{ id: string }>) {
|
}: RouteComponentProps<{ governorIndex: string; id: string }>) {
|
||||||
const { chainId, account } = 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(Number.parseInt(governorIndex), id)
|
||||||
|
|
||||||
// update support based on button interactions
|
// update support based on button interactions
|
||||||
const [support, setSupport] = useState<boolean>(true)
|
const [support, setSupport] = useState<boolean>(true)
|
||||||
|
@ -248,9 +248,9 @@ export default function Vote() {
|
|||||||
</TYPE.subHeader>
|
</TYPE.subHeader>
|
||||||
</EmptyProposals>
|
</EmptyProposals>
|
||||||
)}
|
)}
|
||||||
{allProposals?.reverse().map((p: ProposalData, i) => {
|
{allProposals?.reverse()?.map((p: ProposalData) => {
|
||||||
return (
|
return (
|
||||||
<Proposal as={Link} to={'/vote/' + p.id} key={i}>
|
<Proposal as={Link} to={`/vote/${p.governorIndex}/${p.id}`} key={`${p.governorIndex}${p.id}`}>
|
||||||
<ProposalNumber>{p.id}</ProposalNumber>
|
<ProposalNumber>{p.id}</ProposalNumber>
|
||||||
<ProposalTitle>{p.title}</ProposalTitle>
|
<ProposalTitle>{p.title}</ProposalTitle>
|
||||||
<ProposalStatus status={p.status}>{ProposalState[p.status]}</ProposalStatus>
|
<ProposalStatus status={p.status}>{ProposalState[p.status]}</ProposalStatus>
|
||||||
|
@ -2,16 +2,17 @@ import { TransactionResponse } from '@ethersproject/providers'
|
|||||||
import { abi as GOV_ABI } from '@uniswap/governance/build/GovernorAlpha.json'
|
import { abi as GOV_ABI } from '@uniswap/governance/build/GovernorAlpha.json'
|
||||||
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||||
import { GOVERNANCE_ADDRESSES } from 'constants/addresses'
|
import { GOVERNANCE_ADDRESSES } from 'constants/addresses'
|
||||||
|
import { SupportedChainId } from 'constants/chains'
|
||||||
import { UNISWAP_GRANTS_PROPOSAL_DESCRIPTION } from 'constants/proposals/uniswap_grants_proposal_description'
|
import { UNISWAP_GRANTS_PROPOSAL_DESCRIPTION } from 'constants/proposals/uniswap_grants_proposal_description'
|
||||||
import { ethers, utils } from 'ethers'
|
import { BigNumber, ethers, utils } from 'ethers'
|
||||||
import { isAddress } from 'ethers/lib/utils'
|
import { isAddress } from 'ethers/lib/utils'
|
||||||
import { useGovernanceContracts, useUniContract } from 'hooks/useContract'
|
import { useGovernanceContracts, useUniContract } from 'hooks/useContract'
|
||||||
import { useActiveWeb3React } from 'hooks/web3'
|
import { useActiveWeb3React } from 'hooks/web3'
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { calculateGasMargin } from 'utils/calculateGasMargin'
|
import { calculateGasMargin } from 'utils/calculateGasMargin'
|
||||||
import { EDUCATION_FUND_1_START_BLOCK, UNISWAP_GRANTS_START_BLOCK } from '../../constants/proposals'
|
import { UNISWAP_GRANTS_START_BLOCK } from '../../constants/proposals'
|
||||||
import { UNI } from '../../constants/tokens'
|
import { UNI } from '../../constants/tokens'
|
||||||
import { useMultipleContractMultipleData, useMultipleContractSingleData, useSingleCallResult } from '../multicall/hooks'
|
import { useMultipleContractMultipleData, useSingleCallResult } from '../multicall/hooks'
|
||||||
import { useTransactionAdder } from '../transactions/hooks'
|
import { useTransactionAdder } from '../transactions/hooks'
|
||||||
|
|
||||||
interface ProposalDetail {
|
interface ProposalDetail {
|
||||||
@ -31,6 +32,7 @@ export interface ProposalData {
|
|||||||
startBlock: number
|
startBlock: number
|
||||||
endBlock: number
|
endBlock: number
|
||||||
details: ProposalDetail[]
|
details: ProposalDetail[]
|
||||||
|
governorIndex: number // index in the governance address array for which this proposal pertains
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum ProposalState {
|
export enum ProposalState {
|
||||||
@ -46,63 +48,68 @@ export enum ProposalState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GovernanceInterface = new ethers.utils.Interface(GOV_ABI)
|
const GovernanceInterface = new ethers.utils.Interface(GOV_ABI)
|
||||||
// get count of all proposals made
|
// get count of all proposals made in the latest governor contract
|
||||||
export function useProposalCounts(): Record<string, number> | undefined {
|
function useLatestProposalCount(): number | undefined {
|
||||||
const { chainId } = useActiveWeb3React()
|
const govContracts = useGovernanceContracts()
|
||||||
const addresses = useMemo(() => {
|
|
||||||
if (!chainId) {
|
const res = useSingleCallResult(govContracts[0], 'proposalCount')
|
||||||
return []
|
|
||||||
|
if (res?.result?.[0]) {
|
||||||
|
return (res.result[0] as BigNumber).toNumber()
|
||||||
}
|
}
|
||||||
return GOVERNANCE_ADDRESSES.map((addressMap) => addressMap[chainId])
|
|
||||||
}, [chainId])
|
return undefined
|
||||||
const responses = useMultipleContractSingleData(addresses, GovernanceInterface, 'proposalCount')
|
|
||||||
return useMemo(() => {
|
|
||||||
return responses.reduce((acc, response, i) => {
|
|
||||||
if (response.result && !response.loading) {
|
|
||||||
return {
|
|
||||||
...acc,
|
|
||||||
[addresses[i]]: parseInt(response.result[0]),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
}, [addresses, responses])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Need proposal events to get description data emitted from
|
* Need proposal events to get description data emitted from
|
||||||
* new proposal event.
|
* new proposal event.
|
||||||
*/
|
*/
|
||||||
export function useDataFromEventLogs() {
|
function useDataFromEventLogs():
|
||||||
|
| {
|
||||||
|
description: string
|
||||||
|
details: { target: string; functionSig: string; callData: string }[]
|
||||||
|
}[][]
|
||||||
|
| undefined {
|
||||||
const { library, chainId } = useActiveWeb3React()
|
const { library, chainId } = useActiveWeb3React()
|
||||||
const [formattedEvents, setFormattedEvents] =
|
const [formattedEvents, setFormattedEvents] =
|
||||||
useState<{ description: string; details: { target: string; functionSig: string; callData: string }[] }[]>()
|
useState<{ description: string; details: { target: string; functionSig: string; callData: string }[] }[][]>()
|
||||||
|
|
||||||
const govContracts = useGovernanceContracts()
|
const govContracts = useGovernanceContracts()
|
||||||
|
|
||||||
// create filter for these specific events
|
// create filters for ProposalCreated events
|
||||||
const filters = useMemo(
|
const filters = useMemo(
|
||||||
() =>
|
() =>
|
||||||
govContracts
|
govContracts?.filter((govContract) => !!govContract)?.length > 0
|
||||||
? govContracts.map((contract) => ({
|
? govContracts
|
||||||
|
.filter((govContract): govContract is ethers.Contract => !!govContract)
|
||||||
|
.map((contract) => ({
|
||||||
...contract.filters.ProposalCreated(),
|
...contract.filters.ProposalCreated(),
|
||||||
fromBlock: 10861678,
|
fromBlock: 10861678, // TODO could optimize this on a per-contract basis, this is the safe value
|
||||||
toBlock: 'latest',
|
toBlock: 'latest',
|
||||||
}))
|
}))
|
||||||
: undefined,
|
: undefined,
|
||||||
[govContracts]
|
[govContracts]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// clear logs on chainId change
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
setFormattedEvents(undefined)
|
||||||
|
}
|
||||||
|
}, [chainId])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!filters || !library) return
|
if (!filters || !library) return
|
||||||
let stale = false
|
let stale = false
|
||||||
|
|
||||||
if (!formattedEvents) {
|
if (!formattedEvents) {
|
||||||
const filterRequests = filters.map((filter) => library.getLogs(filter))
|
Promise.all(filters.map((filter) => library.getLogs(filter)))
|
||||||
Promise.all(filterRequests)
|
|
||||||
.then((events) => events.flat())
|
|
||||||
.then((governanceContractsProposalEvents) => {
|
.then((governanceContractsProposalEvents) => {
|
||||||
if (stale) return
|
if (stale) return
|
||||||
const formattedEventData = governanceContractsProposalEvents.map((event) => {
|
|
||||||
|
const formattedEventData = governanceContractsProposalEvents.map((proposalEvents) => {
|
||||||
|
return proposalEvents.map((event) => {
|
||||||
const eventParsed = GovernanceInterface.parseLog(event).args
|
const eventParsed = GovernanceInterface.parseLog(event).args
|
||||||
return {
|
return {
|
||||||
description: eventParsed.description,
|
description: eventParsed.description,
|
||||||
@ -119,11 +126,17 @@ export function useDataFromEventLogs() {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
|
||||||
setFormattedEvents(formattedEventData)
|
setFormattedEvents(formattedEventData)
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
|
if (stale) return
|
||||||
|
|
||||||
console.error('Failed to fetch proposals', error)
|
console.error('Failed to fetch proposals', error)
|
||||||
|
setFormattedEvents(undefined)
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
stale = true
|
stale = true
|
||||||
}
|
}
|
||||||
@ -136,41 +149,22 @@ export function useDataFromEventLogs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get data for all past and active proposals
|
// get data for all past and active proposals
|
||||||
export function useAllProposalData() {
|
export function useAllProposalData(): ProposalData[] {
|
||||||
const { chainId } = useActiveWeb3React()
|
const { chainId } = useActiveWeb3React()
|
||||||
const proposalCounts = useProposalCounts()
|
const proposalCount = useLatestProposalCount()
|
||||||
|
|
||||||
const proposalIndexes = useMemo(() => {
|
|
||||||
const results: number[][][] = []
|
|
||||||
const emptyState = new Array(GOVERNANCE_ADDRESSES.length).fill([], 0)
|
|
||||||
GOVERNANCE_ADDRESSES.forEach((addressMap, i) => {
|
|
||||||
results[i] = []
|
|
||||||
if (!chainId) {
|
|
||||||
return emptyState
|
|
||||||
}
|
|
||||||
const address = addressMap[chainId]
|
|
||||||
if (!proposalCounts || proposalCounts[address] === undefined) {
|
|
||||||
return emptyState
|
|
||||||
}
|
|
||||||
for (let j = 1; j <= proposalCounts[address]; j++) {
|
|
||||||
results[i].push([j])
|
|
||||||
}
|
|
||||||
return results
|
|
||||||
})
|
|
||||||
return results.filter((indexArray) => indexArray.length > 0)
|
|
||||||
}, [chainId, proposalCounts])
|
|
||||||
|
|
||||||
const addresses = useMemo(() => {
|
const addresses = useMemo(() => {
|
||||||
if (!chainId) {
|
return chainId === SupportedChainId.MAINNET ? GOVERNANCE_ADDRESSES.map((addressMap) => addressMap[chainId]) : []
|
||||||
return []
|
}, [chainId])
|
||||||
}
|
|
||||||
return GOVERNANCE_ADDRESSES.map((addressMap) => addressMap[chainId]).filter(
|
|
||||||
(address) => proposalCounts && proposalCounts[address] > 0
|
|
||||||
)
|
|
||||||
}, [chainId, proposalCounts])
|
|
||||||
|
|
||||||
// get metadata from past events
|
const proposalIndexes = useMemo(() => {
|
||||||
const formattedEvents = useDataFromEventLogs()
|
return chainId === SupportedChainId.MAINNET
|
||||||
|
? [
|
||||||
|
typeof proposalCount === 'number' ? new Array(proposalCount).fill(0).map((_, i) => [i + 1]) : [], // dynamic for current governor alpha
|
||||||
|
[[1], [2], [3], [4]], // hardcoded for governor alpha V0
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
}, [chainId, proposalCount])
|
||||||
|
|
||||||
// get all proposal entities
|
// get all proposal entities
|
||||||
const allProposalsCallData = useMultipleContractMultipleData(
|
const allProposalsCallData = useMultipleContractMultipleData(
|
||||||
@ -178,7 +172,7 @@ export function useAllProposalData() {
|
|||||||
GovernanceInterface,
|
GovernanceInterface,
|
||||||
'proposals',
|
'proposals',
|
||||||
proposalIndexes
|
proposalIndexes
|
||||||
).flat()
|
)
|
||||||
|
|
||||||
// get all proposal states
|
// get all proposal states
|
||||||
const allProposalStatesCallData = useMultipleContractMultipleData(
|
const allProposalStatesCallData = useMultipleContractMultipleData(
|
||||||
@ -186,20 +180,36 @@ export function useAllProposalData() {
|
|||||||
GovernanceInterface,
|
GovernanceInterface,
|
||||||
'state',
|
'state',
|
||||||
proposalIndexes
|
proposalIndexes
|
||||||
).flat()
|
)
|
||||||
|
|
||||||
|
// get metadata from past events
|
||||||
|
const allFormattedEvents = useDataFromEventLogs()
|
||||||
|
|
||||||
|
// early return until events are fetched
|
||||||
|
if (!allFormattedEvents) return []
|
||||||
|
|
||||||
|
const results: ProposalData[][] = []
|
||||||
|
|
||||||
|
for (
|
||||||
|
let governanceContractIndex = 0;
|
||||||
|
governanceContractIndex < allProposalsCallData.length;
|
||||||
|
governanceContractIndex++
|
||||||
|
) {
|
||||||
|
const proposalsCallData = allProposalsCallData[governanceContractIndex]
|
||||||
|
const proposalStatesCallData = allProposalStatesCallData[governanceContractIndex]
|
||||||
|
const formattedEvents = allFormattedEvents[governanceContractIndex]
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!allProposalsCallData?.every((p) => Boolean(p.result)) ||
|
!proposalsCallData?.every((p) => Boolean(p.result)) ||
|
||||||
!allProposalStatesCallData?.every((p) => Boolean(p.result)) ||
|
!proposalStatesCallData?.every((p) => Boolean(p.result)) ||
|
||||||
!formattedEvents?.every((p) => Boolean(p))
|
!formattedEvents?.every((p) => Boolean(p))
|
||||||
) {
|
) {
|
||||||
return []
|
results.push([])
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const omittedProposalStartBlocks = [EDUCATION_FUND_1_START_BLOCK]
|
results.push(
|
||||||
|
proposalsCallData.map((proposal, i) => {
|
||||||
return allProposalsCallData
|
|
||||||
.map((proposal, i) => {
|
|
||||||
let description = formattedEvents[i].description
|
let description = formattedEvents[i].description
|
||||||
const startBlock = parseInt(proposal?.result?.startBlock?.toString())
|
const startBlock = parseInt(proposal?.result?.startBlock?.toString())
|
||||||
if (startBlock === UNISWAP_GRANTS_START_BLOCK) {
|
if (startBlock === UNISWAP_GRANTS_START_BLOCK) {
|
||||||
@ -210,20 +220,24 @@ export function useAllProposalData() {
|
|||||||
title: description?.split(/# |\n/g)[1] ?? 'Untitled',
|
title: description?.split(/# |\n/g)[1] ?? 'Untitled',
|
||||||
description: description ?? 'No description.',
|
description: description ?? 'No description.',
|
||||||
proposer: proposal?.result?.proposer,
|
proposer: proposal?.result?.proposer,
|
||||||
status: allProposalStatesCallData[i]?.result?.[0] ?? ProposalState.Undetermined,
|
status: proposalStatesCallData[i]?.result?.[0] ?? ProposalState.Undetermined,
|
||||||
forCount: parseFloat(ethers.utils.formatUnits(proposal?.result?.forVotes.toString(), 18)),
|
forCount: parseFloat(ethers.utils.formatUnits(proposal?.result?.forVotes.toString(), 18)),
|
||||||
againstCount: parseFloat(ethers.utils.formatUnits(proposal?.result?.againstVotes.toString(), 18)),
|
againstCount: parseFloat(ethers.utils.formatUnits(proposal?.result?.againstVotes.toString(), 18)),
|
||||||
startBlock,
|
startBlock,
|
||||||
endBlock: parseInt(proposal?.result?.endBlock?.toString()),
|
endBlock: parseInt(proposal?.result?.endBlock?.toString()),
|
||||||
details: formattedEvents[i].details,
|
details: formattedEvents[i].details,
|
||||||
|
governorIndex: i,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((proposal) => !omittedProposalStartBlocks.includes(proposal.startBlock))
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.flat()
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useProposalData(id: string): ProposalData | undefined {
|
export function useProposalData(governorIndex: number, id: string): ProposalData | undefined {
|
||||||
const allProposalData = useAllProposalData()
|
const allProposalData = useAllProposalData()
|
||||||
return allProposalData?.find((p) => p.id === id)
|
return allProposalData?.filter((p) => p.governorIndex === governorIndex)?.find((p) => p.id === id)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the users delegatee if it exists
|
// get the users delegatee if it exists
|
||||||
|
Loading…
Reference in New Issue
Block a user