From 1892844a0f0497a349aa1afd5792017c96e563f0 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Thu, 5 Oct 2023 13:48:23 -0300 Subject: [PATCH] test: working governance integration tests in ci --- .github/workflows/ci.yaml | 9 +- subgraphs/venus-governance/config/local.json | 2 +- .../venus-governance/src/operations/get.ts | 104 ++++++++++-------- subgraphs/venus-governance/template.yaml | 6 + .../tests/integration/index.ts | 44 +++----- .../tests/integration/utils/voter.ts | 19 ++-- 6 files changed, 96 insertions(+), 88 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4d49cd09..8a5c9b87 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -82,11 +82,10 @@ jobs: docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run deploy:docker sleep 5s docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run generate-subgraph-types - - # @TODO - turn on once the integration tests pass - # - name: Run Governance integration integration tests - # run: | - # docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run test:integration + + - name: Run Governance integration integration tests + run: | + docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run test:integration - name: Stop containers if: always() diff --git a/subgraphs/venus-governance/config/local.json b/subgraphs/venus-governance/config/local.json index bfefeb8e..95cc4063 100644 --- a/subgraphs/venus-governance/config/local.json +++ b/subgraphs/venus-governance/config/local.json @@ -1,6 +1,6 @@ { "network": "hardhat", - "accessControlManagerAddress": "0xc5a5C42992dECbae36851359345FE25997F5C42d", + "accessControlManagerAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", "accessControlManagerStartBlock": "0", "governorAlphaAddress": "0x1c9fD50dF7a4f066884b58A05D91e4b55005876A", "governorAlphaStartBlock": "0", diff --git a/subgraphs/venus-governance/src/operations/get.ts b/subgraphs/venus-governance/src/operations/get.ts index 28e8e252..8368f9e1 100644 --- a/subgraphs/venus-governance/src/operations/get.ts +++ b/subgraphs/venus-governance/src/operations/get.ts @@ -4,7 +4,7 @@ import { GovernorBravoDelegate2 } from '../../generated/GovernorBravoDelegate2/G import { Timelock } from '../../generated/GovernorBravoDelegate2/Timelock'; import { Delegate, Governance, GovernanceRoute, Proposal } from '../../generated/schema'; import { BIGINT_ZERO } from '../constants'; -import { governorBravoDelegateAddress } from '../constants/addresses'; +import { governorBravoDelegateAddress, nullAddress } from '../constants/addresses'; /** * While technically this function does also create, we don't care because it only happens once as the id is a constant. @@ -20,51 +20,65 @@ export const getGovernanceEntity = (): Governance => { governance.totalVoters = BIGINT_ZERO; governance.totalVotesMantissa = BIGINT_ZERO; governance.proposalsQueued = BIGINT_ZERO; + // Mocking values until we can correctly index current governance contract + governance.admin = nullAddress; + governance.implementation = nullAddress; + governance.guardian = nullAddress; + governance.quorumVotesMantissa = BIGINT_ZERO; + governance.proposalMaxOperations = BIGINT_ZERO; - governance.admin = governorBravoDelegate2.admin(); - governance.implementation = governorBravoDelegate2.implementation(); - governance.guardian = governorBravoDelegate2.guardian(); - governance.quorumVotesMantissa = governorBravoDelegate2.quorumVotes(); - governance.proposalMaxOperations = governorBravoDelegate2.proposalMaxOperations(); - // Governance Routes are set in initialization - // Normal - const normalProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(0)); - const normalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(0)); - const normalTimelock = Timelock.bind(normalTimelockAddress); - const normalGovernanceRoute = new GovernanceRoute('0'); - normalGovernanceRoute.governor = governorBravoDelegateAddress; - normalGovernanceRoute.timelock = normalTimelockAddress; - normalGovernanceRoute.queueDelayBlocks = normalTimelock.delay(); - normalGovernanceRoute.votingDelayBlocks = normalProposalConfig.getVotingDelay(); - normalGovernanceRoute.votingPeriodBlocks = normalProposalConfig.getVotingPeriod(); - normalGovernanceRoute.proposalThresholdMantissa = normalProposalConfig.getProposalThreshold(); - normalGovernanceRoute.save(); - // Fast track - const fastTrackProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(1)); - const fastTrackTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(1)); - const fastTrackTimelock = Timelock.bind(normalTimelockAddress); - const fastTrackGovernanceRoute = new GovernanceRoute('1'); - fastTrackGovernanceRoute.governor = governorBravoDelegateAddress; - fastTrackGovernanceRoute.timelock = fastTrackTimelockAddress; - fastTrackGovernanceRoute.queueDelayBlocks = fastTrackTimelock.delay(); - fastTrackGovernanceRoute.votingDelayBlocks = fastTrackProposalConfig.getVotingDelay(); - fastTrackGovernanceRoute.votingPeriodBlocks = fastTrackProposalConfig.getVotingPeriod(); - fastTrackGovernanceRoute.proposalThresholdMantissa = - fastTrackProposalConfig.getProposalThreshold(); - fastTrackGovernanceRoute.save(); - // Critical - const criticalProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(2)); - const criticalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(2)); - const criticalTimelock = Timelock.bind(normalTimelockAddress); - const criticalGovernanceRoute = new GovernanceRoute('2'); - criticalGovernanceRoute.governor = governorBravoDelegateAddress; - criticalGovernanceRoute.timelock = criticalTimelockAddress; - criticalGovernanceRoute.queueDelayBlocks = criticalTimelock.delay(); - criticalGovernanceRoute.votingDelayBlocks = criticalProposalConfig.getVotingDelay(); - criticalGovernanceRoute.votingPeriodBlocks = criticalProposalConfig.getVotingPeriod(); - criticalGovernanceRoute.proposalThresholdMantissa = - criticalProposalConfig.getProposalThreshold(); - criticalGovernanceRoute.save(); + // There is only one active governance entity + // but while indexing proposals created with previous governance contracts all these calls will fail + // This method only exists on the latest governance interface so if it succeeds we can safely index the contract + const normalProposalConfigResult = governorBravoDelegate2.try_proposalConfigs(new BigInt(0)); + if (normalProposalConfigResult.reverted === false) { + governance.admin = governorBravoDelegate2.admin(); + governance.implementation = governorBravoDelegate2.implementation(); + governance.guardian = governorBravoDelegate2.guardian(); + governance.quorumVotesMantissa = governorBravoDelegate2.quorumVotes(); + governance.proposalMaxOperations = governorBravoDelegate2.proposalMaxOperations(); + // Governance Routes are set in initialization + // Normal + const normalProposalConfig = normalProposalConfigResult.value; + const normalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(0)); + const normalTimelock = Timelock.bind(normalTimelockAddress); + const normalGovernanceRoute = new GovernanceRoute('0'); + normalGovernanceRoute.governor = governorBravoDelegateAddress; + normalGovernanceRoute.timelock = normalTimelockAddress; + normalGovernanceRoute.queueDelayBlocks = normalTimelock.delay(); + normalGovernanceRoute.votingDelayBlocks = normalProposalConfig.getVotingDelay(); + normalGovernanceRoute.votingPeriodBlocks = normalProposalConfig.getVotingPeriod(); + normalGovernanceRoute.proposalThresholdMantissa = normalProposalConfig.getProposalThreshold(); + normalGovernanceRoute.save(); + // Fast track + const fastTrackProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(1)); + const fastTrackTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(1)); + const fastTrackTimelock = Timelock.bind(normalTimelockAddress); + const fastTrackGovernanceRoute = new GovernanceRoute('1'); + fastTrackGovernanceRoute.governor = governorBravoDelegateAddress; + fastTrackGovernanceRoute.timelock = fastTrackTimelockAddress; + fastTrackGovernanceRoute.queueDelayBlocks = fastTrackTimelock.delay(); + fastTrackGovernanceRoute.votingDelayBlocks = fastTrackProposalConfig.getVotingDelay(); + fastTrackGovernanceRoute.votingPeriodBlocks = fastTrackProposalConfig.getVotingPeriod(); + fastTrackGovernanceRoute.proposalThresholdMantissa = + fastTrackProposalConfig.getProposalThreshold(); + fastTrackGovernanceRoute.save(); + // Critical + const criticalProposalConfig = governorBravoDelegate2.proposalConfigs(new BigInt(2)); + const criticalTimelockAddress = governorBravoDelegate2.proposalTimelocks(new BigInt(2)); + const criticalTimelock = Timelock.bind(normalTimelockAddress); + const criticalGovernanceRoute = new GovernanceRoute('2'); + criticalGovernanceRoute.governor = governorBravoDelegateAddress; + criticalGovernanceRoute.timelock = criticalTimelockAddress; + criticalGovernanceRoute.queueDelayBlocks = criticalTimelock.delay(); + criticalGovernanceRoute.votingDelayBlocks = criticalProposalConfig.getVotingDelay(); + criticalGovernanceRoute.votingPeriodBlocks = criticalProposalConfig.getVotingPeriod(); + criticalGovernanceRoute.proposalThresholdMantissa = + criticalProposalConfig.getProposalThreshold(); + criticalGovernanceRoute.save(); + } + + governance.save(); } return governance as Governance; diff --git a/subgraphs/venus-governance/template.yaml b/subgraphs/venus-governance/template.yaml index 221e4142..2d3023df 100644 --- a/subgraphs/venus-governance/template.yaml +++ b/subgraphs/venus-governance/template.yaml @@ -24,6 +24,8 @@ dataSources: abis: - name: GovernorAlpha file: ../../packages/venus-governance-abis/GovernorAlpha.json + - name: GovernorBravoDelegate2 + file: ../../packages/venus-governance-abis/GovernorBravoDelegate2.json eventHandlers: - event: ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string) handler: handleProposalCreated @@ -55,6 +57,8 @@ dataSources: abis: - name: GovernorAlpha2 file: ../../packages/venus-governance-abis/GovernorAlpha2.json + - name: GovernorBravoDelegate2 + file: ../../packages/venus-governance-abis/GovernorBravoDelegate2.json eventHandlers: - event: ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string) handler: handleProposalCreated @@ -86,6 +90,8 @@ dataSources: abis: - name: GovernorBravoDelegate file: ../../packages/venus-governance-abis/GovernorBravoDelegate.json + - name: GovernorBravoDelegate2 + file: ../../packages/venus-governance-abis/GovernorBravoDelegate2.json eventHandlers: - event: ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string) handler: handleProposalCreated diff --git a/subgraphs/venus-governance/tests/integration/index.ts b/subgraphs/venus-governance/tests/integration/index.ts index 629cca99..67829416 100644 --- a/subgraphs/venus-governance/tests/integration/index.ts +++ b/subgraphs/venus-governance/tests/integration/index.ts @@ -1,28 +1,28 @@ -import { loadFixture, mine } from '@nomicfoundation/hardhat-network-helpers'; +import { mine } from '@nomicfoundation/hardhat-network-helpers'; import '@nomiclabs/hardhat-ethers'; import type { SignerWithAddress } from '@nomiclabs/hardhat-ethers/signers'; import { expect } from 'chai'; import { Contract } from 'ethers'; import { ethers } from 'hardhat'; -import { deploy, exec, normalizeMantissa, waitForSubgraphToBeSynced } from 'venus-subgraph-utils'; +import { deploy, scaleValue, waitForSubgraphToBeSynced } from 'venus-subgraph-utils'; import subgraphClient from '../../subgraph-client/index'; import { SUBGRAPH_ACCOUNT, SUBGRAPH_NAME, SYNC_DELAY } from './utils/constants'; -import deployFixtures from './utils/fixtures'; import { enfranchiseAccount } from './utils/voter'; describe('Governance', function () { let signers: SignerWithAddress[]; let governorAlpha: Contract; let governorAlpha2: Contract; - let xvs: Contract; - let xvsVault: Contract; before(async function () { this.timeout(50000000); // sometimes it takes a long time - ({ governorAlpha, governorAlpha2, xvs, xvsVault } = await loadFixture(deployFixtures)); + governorAlpha = await ethers.getContract('GovernorAlpha'); + governorAlpha2 = await ethers.getContract('GovernorAlpha2'); signers = await ethers.getSigners(); + const root = `${__dirname}/../..`; + await deploy({ root, packageName: 'venus-governance-subgraph', @@ -32,18 +32,12 @@ describe('Governance', function () { }); const [_, user1, user2, user3, user4] = signers; - await enfranchiseAccount(xvs, xvsVault, user1, normalizeMantissa(10e4, 1e18)); - await enfranchiseAccount(xvs, xvsVault, user2, normalizeMantissa(20e4, 1e18)); - await enfranchiseAccount(xvs, xvsVault, user3, normalizeMantissa(30e4, 1e18)); - await enfranchiseAccount(xvs, xvsVault, user4, normalizeMantissa(40e4, 1e18)); - }); - - after(async function () { - process.stdout.write('Clean up, removing subgraph....'); - exec(`yarn remove:local`, __dirname); - - process.stdout.write('Clean up complete.'); + await enfranchiseAccount(user1, scaleValue(100000, 18)); + await enfranchiseAccount(user2, scaleValue(200000, 18)); + await enfranchiseAccount(user3, scaleValue(300000, 18)); + await enfranchiseAccount(user4, scaleValue(400000, 18)); + await waitForSubgraphToBeSynced(SYNC_DELAY); }); describe('Alpha', function () { @@ -67,7 +61,6 @@ describe('Governance', function () { const { data: { proposal }, } = await subgraphClient.getProposalById('1'); - expect(proposal.id).to.be.equal('1'); expect(proposal.description).to.be.equal('Test proposal 1'); expect(proposal.status).to.be.equal('PENDING'); @@ -109,7 +102,7 @@ describe('Governance', function () { expect(delegate1.votes[0].id).to.equal(`${user1.address.toLowerCase()}-0x1`); expect(delegate1.votes[0].support).to.equal('AGAINST'); - expect(delegate1.votes[0].votes).to.equal('116807000000000000000000'); + expect(delegate1.votes[0].votes).to.equal('100000000000000000000000'); expect(delegate1.proposals).to.deep.equal([]); const { @@ -135,9 +128,9 @@ describe('Governance', function () { describe('Alpha2', function () { it('indexes created proposals - alpha2', async function () { const [_, user1] = signers; - await enfranchiseAccount(xvs, xvsVault, user1, normalizeMantissa(40e4, 1e18)); + await enfranchiseAccount(user1, scaleValue(600000, 18)); - const callData = ethers.utils.defaultAbiCoder.encode(['address'], [governorAlpha.address]); + const callData = ethers.utils.defaultAbiCoder.encode(['address'], [governorAlpha2.address]); const vip = [ ['0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'], // targets @@ -172,10 +165,9 @@ describe('Governance', function () { describe('Permission events', function () { it('indexes permission granted events', async function () { const { data } = await subgraphClient.getPermissions(); - expect(data).to.not.be.equal(undefined); const { permissions } = data!; - expect(permissions.length).to.be.equal(7); + expect(permissions.length).to.be.equal(12); permissions.forEach(pe => { expect(pe.type).to.be.equal('GRANTED'); @@ -193,10 +185,9 @@ describe('Governance', function () { await waitForSubgraphToBeSynced(SYNC_DELAY); const { data } = await subgraphClient.getPermissions(); - expect(data).to.not.be.equal(undefined); const { permissions } = data!; - expect(permissions.length).to.be.equal(8); + expect(permissions.length).to.be.equal(13); expect(permissions[0].type).to.be.equal('REVOKED'); }); @@ -212,10 +203,9 @@ describe('Governance', function () { await waitForSubgraphToBeSynced(SYNC_DELAY); const { data } = await subgraphClient.getPermissions(); - expect(data).to.not.be.equal(undefined); const { permissions } = data!; - expect(permissions.length).to.be.equal(8); + expect(permissions.length).to.be.equal(13); expect(permissions[0].type).to.be.equal('GRANTED'); }); diff --git a/subgraphs/venus-governance/tests/integration/utils/voter.ts b/subgraphs/venus-governance/tests/integration/utils/voter.ts index 546b914d..199f3662 100644 --- a/subgraphs/venus-governance/tests/integration/utils/voter.ts +++ b/subgraphs/venus-governance/tests/integration/utils/voter.ts @@ -1,16 +1,15 @@ import BigNumber from 'bignumber.js'; -import { Contract } from 'ethers'; -import { normalizeMantissa } from 'venus-subgraph-utils'; +import { ethers } from 'hardhat'; -export async function enfranchiseAccount( - xvs: Contract, - xvsVault: Contract, - account: any, - amount: BigNumber, -) { - await xvs.connect(account).approve(xvsVault.address, normalizeMantissa(1e10, 1e18).toFixed()); - await xvs.transfer(account.address, amount.times(1.5).toFixed()); +export async function enfranchiseAccount(account: any, amount: BigNumber) { + const xvs = await ethers.getContract('XVS'); + const xvsVault = await ethers.getContract('XVSVault'); + + await xvs.connect(account).approve(xvsVault.address, amount.toFixed()); + + await xvs.transfer(account.address, amount.toFixed()); await xvsVault.connect(account).deposit(xvs.address, 0, amount.toFixed()); + await xvsVault.connect(account).delegate(account.address); }