-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
374 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { | ||
GetVMProposalsData, | ||
getVMProposalsData, | ||
} from './utils/getVMProposalsData'; | ||
|
||
export async function fetchUserProposalData({ | ||
input, | ||
}: { | ||
input: GetVMProposalsData; | ||
}) { | ||
try { | ||
throw new Error('TODO: API not implemented'); | ||
} catch (e) { | ||
console.error( | ||
'Error getting user proposal data from API, using RPC fallback', | ||
e, | ||
); | ||
|
||
const preparedData = await getVMProposalsData({ ...input }); | ||
|
||
return preparedData.map((vmData) => { | ||
return { | ||
proposalId: vmData.proposalData.id, | ||
votedInfo: { | ||
support: vmData.votedInfo.support, | ||
votedPower: vmData.votedInfo.votingPower, | ||
}, | ||
isVoted: vmData.votedInfo.votingPower !== 0n, | ||
}; | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { | ||
GetVotingPowerWithDelegationByBlockHash, | ||
getVotingPowerWithDelegationByBlockHash, | ||
} from './utils/getVotingPowerWithDelegationByBlockHash'; | ||
|
||
export async function fetchUserProposalsBalances({ | ||
input, | ||
}: { | ||
input: GetVotingPowerWithDelegationByBlockHash; | ||
}) { | ||
try { | ||
throw new Error('TODO: API not implemented'); | ||
} catch (e) { | ||
console.error( | ||
'Error getting user proposals balances from API, using RPC fallback', | ||
e, | ||
); | ||
return await getVotingPowerWithDelegationByBlockHash({ ...input }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import { | ||
IGovernanceDataHelper_ABI, | ||
IPayloadsControllerDataHelper_ABI, | ||
} from '@bgd-labs/aave-address-book'; | ||
import { Client } from 'viem'; | ||
import { readContract } from 'viem/actions'; | ||
|
||
import { appConfig } from '../../configs/appConfig'; | ||
import { PAGE_SIZE } from '../../configs/configs'; | ||
|
||
enum ProposalState { | ||
Null, // proposal does not exists | ||
Created, // created, waiting for a cooldown to initiate the balances snapshot | ||
Active, // balances snapshot set, voting in progress | ||
Queued, // voting results submitted, but proposal is under grace period when guardian can cancel it | ||
Executed, // results sent to the execution chain(s) | ||
Failed, // voting was not successful | ||
Cancelled, // got cancelled by guardian, or because proposition power of creator dropped below allowed minimum | ||
Expired, | ||
} | ||
|
||
enum PayloadState { | ||
None, | ||
Created, | ||
Queued, | ||
Executed, | ||
Cancelled, | ||
Expired, | ||
} | ||
|
||
export type GetProposalsWithPayloadsData = { | ||
proposalsCount?: number; | ||
proposalsIds?: number[]; | ||
pageSize?: number; | ||
client: Client; | ||
}; | ||
|
||
export async function getProposalsWithPayloadsData({ | ||
proposalsCount, | ||
proposalsIds, | ||
pageSize, | ||
client, | ||
}: GetProposalsWithPayloadsData) { | ||
const ids = proposalsCount | ||
? [...Array(Number(proposalsCount)).keys()] | ||
: (proposalsIds ?? []); | ||
|
||
const fr = Math.max.apply( | ||
null, | ||
ids.map((id) => id), | ||
); | ||
const to = Math.min.apply( | ||
null, | ||
ids.map((id) => id), | ||
); | ||
|
||
const proposalsData = await readContract(client, { | ||
abi: IGovernanceDataHelper_ABI, | ||
address: appConfig.govCoreConfig.dataHelperContractAddress, | ||
functionName: 'getProposalsData', | ||
args: [ | ||
appConfig.govCoreConfig.contractAddress, | ||
BigInt(fr), | ||
BigInt(to || 0), | ||
BigInt(pageSize || proposalsCount || PAGE_SIZE), | ||
], | ||
}); | ||
|
||
const payloadsData = ( | ||
await Promise.all( | ||
proposalsData.map(async (proposal) => { | ||
const payloadsChains = proposal.proposalData.payloads | ||
.map((payload) => payload.chain) | ||
.filter((value, index, self) => self.indexOf(value) === index); | ||
|
||
return ( | ||
await Promise.all( | ||
payloadsChains.map(async (chain) => { | ||
const payloadsByChain = proposal.proposalData.payloads.filter( | ||
(payload) => payload.chain === chain, | ||
); | ||
const payloadsController = payloadsByChain.map( | ||
(payload) => payload.payloadsController, | ||
)[0]; | ||
|
||
const payloadsData = await readContract(client, { | ||
abi: IPayloadsControllerDataHelper_ABI, | ||
address: | ||
appConfig.payloadsControllerConfig[Number(chain)] | ||
.dataHelperContractAddress, | ||
functionName: 'getPayloadsData', | ||
args: [ | ||
payloadsController, | ||
payloadsByChain.map((payload) => payload.payloadId), | ||
], | ||
}); | ||
|
||
return payloadsData.map((payload) => { | ||
return { | ||
...payload, | ||
chain, | ||
payloadsController, | ||
}; | ||
}); | ||
}), | ||
) | ||
).flat(); | ||
}), | ||
) | ||
).flat(); | ||
|
||
return proposalsData.map((proposal) => { | ||
const proposalPayloads = proposal.proposalData.payloads.map((payload) => { | ||
const data = payloadsData.find( | ||
(p) => | ||
Number(p.id) === payload.payloadId && | ||
p.chain === payload.chain && | ||
p.payloadsController === payload.payloadsController, | ||
); | ||
if (data) { | ||
return data; | ||
} else { | ||
return payloadsData[0]; // TODO: need fix | ||
} | ||
}); | ||
|
||
const isProposalPayloadsFinished = proposalPayloads.every( | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-expect-error | ||
(payload) => payload && payload?.state > PayloadState.Queued, | ||
); | ||
|
||
return { | ||
...proposal, | ||
payloads: proposalPayloads, | ||
isFinished: | ||
proposal.proposalData.state === ProposalState.Executed | ||
? isProposalPayloadsFinished | ||
: proposal.proposalData.state > ProposalState.Executed, | ||
}; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { IVotingMachineDataHelper_ABI } from '@bgd-labs/aave-address-book'; | ||
import { Address, Client, getContract, zeroAddress } from 'viem'; | ||
|
||
import { appConfig } from '../../configs/appConfig'; | ||
import { ProposalToGetUserData } from '../../types'; | ||
|
||
export type GetVMProposalsData = { | ||
initialProposals: ProposalToGetUserData[]; | ||
userAddress: string; | ||
clients: Record<number, Client>; | ||
representativeAddress?: string; | ||
}; | ||
|
||
export async function getVMProposalsData({ | ||
initialProposals, | ||
userAddress, | ||
representativeAddress, | ||
clients, | ||
}: GetVMProposalsData) { | ||
const votingMachineChainIds = initialProposals | ||
.map((data) => data.votingChainId) | ||
.filter((value, index, self) => self.indexOf(value) === index); | ||
|
||
const data = await Promise.all( | ||
votingMachineChainIds.map(async (chainId) => { | ||
const votingMachineDataHelper = getContract({ | ||
abi: IVotingMachineDataHelper_ABI, | ||
address: appConfig.votingMachineConfig[chainId].contractAddress, | ||
client: clients[chainId], | ||
}); | ||
|
||
const formattedInitialProposals = initialProposals | ||
.filter((proposal) => proposal.votingChainId === chainId) | ||
.map((proposal) => { | ||
return { | ||
id: proposal.id, | ||
snapshotBlockHash: proposal.snapshotBlockHash, | ||
}; | ||
}); | ||
|
||
if (representativeAddress && userAddress) { | ||
if (userAddress) { | ||
return ( | ||
(await votingMachineDataHelper.read.getProposalsData([ | ||
appConfig.votingMachineConfig[chainId].contractAddress, | ||
formattedInitialProposals, | ||
(representativeAddress || userAddress || zeroAddress) as Address, | ||
])) || [] | ||
); | ||
} | ||
} | ||
return ( | ||
(await votingMachineDataHelper.read.getProposalsData([ | ||
appConfig.votingMachineConfig[chainId].contractAddress, | ||
formattedInitialProposals, | ||
(userAddress || zeroAddress) as Address, | ||
])) || [] | ||
); | ||
}), | ||
); | ||
|
||
return data.flat(); | ||
} |
67 changes: 67 additions & 0 deletions
67
src/requests/utils/getVotingPowerWithDelegationByBlockHash.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { IAaveTokenV3_ABI } from '@bgd-labs/aave-governance-ui-helpers/dist/abis/IAaveTokenV3'; | ||
import { Address, Client, Hex } from 'viem'; | ||
import { getBlock, multicall } from 'viem/actions'; | ||
|
||
import { GovernancePowerType } from '../../types'; | ||
|
||
export type GetVotingPowerWithDelegationByBlockHash = { | ||
client: Client; | ||
blockHash: Hex; | ||
address: Address; | ||
assets: Address[]; | ||
}; | ||
|
||
export async function getVotingPowerWithDelegationByBlockHash({ | ||
client, | ||
blockHash, | ||
address, | ||
assets, | ||
}: GetVotingPowerWithDelegationByBlockHash) { | ||
const blockNumber = await getBlock(client, { | ||
blockHash, | ||
}); | ||
|
||
const wagmiContracts = assets.map((asset) => { | ||
const wagmiContract = { | ||
address: asset, | ||
abi: IAaveTokenV3_ABI, | ||
} as const; | ||
return wagmiContract; | ||
}); | ||
|
||
const data = await multicall(client, { | ||
contracts: [ | ||
...wagmiContracts.map((contract) => { | ||
return { | ||
...contract, | ||
functionName: 'balanceOf', | ||
args: [address], | ||
}; | ||
}), | ||
...wagmiContracts.map((contract) => { | ||
return { | ||
...contract, | ||
functionName: 'getPowerCurrent', | ||
args: [address, GovernancePowerType.VOTING], | ||
}; | ||
}), | ||
], | ||
blockNumber: blockNumber.number, | ||
}); | ||
|
||
return assets.map((asset, index) => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-expect-error | ||
const userBalance = data[index][0].result; | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-expect-error | ||
const votingPower = data[index][1].result; | ||
return { | ||
blockHash, | ||
asset: asset, | ||
votingPower: votingPower as bigint, | ||
userBalance: userBalance as bigint, | ||
isWithDelegatedPower: userBalance !== votingPower, | ||
}; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { z } from 'zod'; | ||
|
||
import { fetchUserProposalsBalances } from '../../../requests/fetchUserProposalsBalances'; | ||
import { GetVotingPowerWithDelegationByBlockHash } from '../../../requests/utils/getVotingPowerWithDelegationByBlockHash'; | ||
import { createTRPCRouter, publicProcedure } from '../trpc'; | ||
|
||
export const proposalsRouter = createTRPCRouter({ | ||
getBalances: publicProcedure | ||
.input(z.custom<GetVotingPowerWithDelegationByBlockHash>()) // TODO: server client | ||
.query(async (input) => await fetchUserProposalsBalances(input)), | ||
}); |
Oops, something went wrong.
4b84462
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This commit was deployed on ipfs