From 1892844a0f0497a349aa1afd5792017c96e563f0 Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Thu, 5 Oct 2023 13:48:23 -0300 Subject: [PATCH 1/4] 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); } From c99966705fe473a0fb77ac4108bcbb572d015cef Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Thu, 5 Oct 2023 17:48:26 -0300 Subject: [PATCH 2/4] ci(test): run governance as separate job --- .github/workflows/ci.yaml | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8a5c9b87..0384b6cb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,7 +24,7 @@ jobs: - name: pretty run: yarn pretty - test: + unit-test: runs-on: ubuntu-20.04 steps: - name: Checkout @@ -48,8 +48,9 @@ jobs: - name: Run Matchstick tests run: yarn test - integration-test: + integration-test-isolated-pools: runs-on: ubuntu-20.04 + needs: unit-test steps: - name: Checkout uses: actions/checkout@v2 @@ -74,6 +75,26 @@ jobs: run: | docker exec -i subgraph-hardhat-node yarn workspace isolated-pools-subgraph run test:integration + - name: Stop containers + if: always() + run: | + docker-compose down -v + docker system prune -f -a --volumes + + integration-test-governance: + runs-on: ubuntu-20.04 + needs: unit-test + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Start containers + run: docker-compose up -d + + - name: Sleep to allow graph-node to become accessible + shell: bash + run: sleep 45s + - name: Generate Governance graphql types run: | docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run prepare:local From 9b2dfe49d2f014891e90df802af8cc7565230b3d Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Thu, 5 Oct 2023 18:34:33 -0300 Subject: [PATCH 3/4] refactor: break out tests into separate files --- .prettierignore | 1 + .../tests/integration/accessControlManager.ts | 64 ++++++ .../tests/integration/alpha.ts | 154 +++++++++++++ .../tests/integration/index.ts | 215 +----------------- .../tests/integration/setup.ts | 19 ++ 5 files changed, 241 insertions(+), 212 deletions(-) create mode 100644 subgraphs/venus-governance/tests/integration/accessControlManager.ts create mode 100644 subgraphs/venus-governance/tests/integration/alpha.ts create mode 100644 subgraphs/venus-governance/tests/integration/setup.ts diff --git a/.prettierignore b/.prettierignore index afe1c77b..d219af63 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,3 +6,4 @@ hardhat.config.ts /subgraphs/venus-governance/subgraph-client/.graphclient typechain-types +/subgraphs/venus-governance/tests/integration/index.ts diff --git a/subgraphs/venus-governance/tests/integration/accessControlManager.ts b/subgraphs/venus-governance/tests/integration/accessControlManager.ts new file mode 100644 index 00000000..d4a32766 --- /dev/null +++ b/subgraphs/venus-governance/tests/integration/accessControlManager.ts @@ -0,0 +1,64 @@ +import '@nomiclabs/hardhat-ethers'; +import { expect } from 'chai'; +import { ethers } from 'hardhat'; +import { waitForSubgraphToBeSynced } from 'venus-subgraph-utils'; + +import subgraphClient from '../../subgraph-client/index'; +import { SYNC_DELAY } from './utils/constants'; + +describe('AccessControlManager', function () { + before(async function () { + this.timeout(50000000); // sometimes it takes a long time + + await waitForSubgraphToBeSynced(SYNC_DELAY); + }); + + describe('Permission events', function () { + it('indexes permission granted events', async function () { + const { data } = await subgraphClient.getPermissions(); + + const { permissions } = data!; + expect(permissions.length).to.be.equal(12); + + permissions.forEach(pe => { + expect(pe.type).to.be.equal('GRANTED'); + }); + }); + + it('indexes permission revoked events', async function () { + const accessControlManager = await ethers.getContract('AccessControlManager'); + const tx = await accessControlManager.revokeCallPermission( + ethers.constants.AddressZero, + 'setMinLiquidatableCollateral(uint256)', + ethers.constants.AddressZero, + ); + await tx.wait(); + await waitForSubgraphToBeSynced(SYNC_DELAY); + + const { data } = await subgraphClient.getPermissions(); + + const { permissions } = data!; + expect(permissions.length).to.be.equal(13); + + expect(permissions[0].type).to.be.equal('REVOKED'); + }); + + it('updates a previously created record with a new permission type', async function () { + const accessControlManager = await ethers.getContract('AccessControlManager'); + const tx = await accessControlManager.giveCallPermission( + ethers.constants.AddressZero, + 'setMinLiquidatableCollateral(uint256)', + ethers.constants.AddressZero, + ); + await tx.wait(); + await waitForSubgraphToBeSynced(SYNC_DELAY); + + const { data } = await subgraphClient.getPermissions(); + + const { permissions } = data!; + expect(permissions.length).to.be.equal(13); + + expect(permissions[0].type).to.be.equal('GRANTED'); + }); + }); +}); diff --git a/subgraphs/venus-governance/tests/integration/alpha.ts b/subgraphs/venus-governance/tests/integration/alpha.ts new file mode 100644 index 00000000..11e18614 --- /dev/null +++ b/subgraphs/venus-governance/tests/integration/alpha.ts @@ -0,0 +1,154 @@ +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 { scaleValue, waitForSubgraphToBeSynced } from 'venus-subgraph-utils'; + +import subgraphClient from '../../subgraph-client/index'; +import { SYNC_DELAY } from './utils/constants'; +import { enfranchiseAccount } from './utils/voter'; + +describe('GovernorAlpha', function () { + let signers: SignerWithAddress[]; + let governorAlpha: Contract; + let governorAlpha2: Contract; + + before(async function () { + this.timeout(50000000); // sometimes it takes a long time + governorAlpha = await ethers.getContract('GovernorAlpha'); + governorAlpha2 = await ethers.getContract('GovernorAlpha2'); + signers = await ethers.getSigners(); + + const [_, user1, user2, user3, user4] = signers; + + 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 () { + it('indexes created proposal success', async function () { + const [_, _1, _2, _3, user4] = signers; + const callData = ethers.utils.defaultAbiCoder.encode(['address'], [governorAlpha.address]); + + const vip = [ + ['0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'], // targets + ['0'], // values + ['setPendingAdmin(address)'], // signatures + [callData], // params + 'Test proposal 1', // description + ]; + + const tx = await governorAlpha.connect(user4).propose(...vip); + await tx.wait(1); + + await waitForSubgraphToBeSynced(SYNC_DELAY); + + 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'); + expect(proposal.executionETA).to.be.null; + expect(proposal.targets).to.deep.equal([ + '0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'.toLowerCase(), + ]); + expect(proposal.values).to.deep.equal(['0']); + expect(proposal.signatures).to.deep.equal(['setPendingAdmin(address)']); + expect(proposal.calldatas).to.deep.equal([callData]); + }); + + it('index for vote cast', async function () { + const [_, user1, user2, user3, user4] = signers; + + const time = Date.now() + 106400; + await ethers.provider.send('evm_setNextBlockTimestamp', [time]); + await mine(1); + + let tx = await governorAlpha.connect(user1).castVote('1', false); + await tx.wait(1); + tx = await governorAlpha.connect(user2).castVote('1', true); + await tx.wait(1); + tx = await governorAlpha.connect(user3).castVote('1', true); + await tx.wait(1); + tx = await governorAlpha.connect(user4).castVote('1', true); + await tx.wait(1); + + await waitForSubgraphToBeSynced(SYNC_DELAY); + + const { + data: { proposal }, + } = await subgraphClient.getProposalById('1'); + expect(proposal.votes.length).to.be.equal(4); + + const { + data: { delegate: delegate1 }, + } = await subgraphClient.getDelegateById(user1.address.toLowerCase()); + + 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('100000000000000000000000'); + expect(delegate1.proposals).to.deep.equal([]); + + const { + data: { delegate: delegate2 }, + } = await subgraphClient.getDelegateById(user2.address.toLowerCase()); + expect(delegate2.votes[0].id).to.equal(`${user2.address.toLowerCase()}-0x1`); + expect(delegate2.votes[0].support).to.equal('FOR'); + expect(delegate2.votes[0].votes).to.equal('200000000000000000000000'); + expect(delegate2.proposals).to.deep.equal([]); + expect(delegate2.proposals).to.deep.equal([]); + + const { + data: { delegate: delegate4 }, + } = await subgraphClient.getDelegateById(user4.address.toLowerCase()); + expect(delegate4.proposals).to.deep.equal([{ id: '1', __typename: 'Proposal' }]); + }); + }); + + // @TODO Update proposal Status + // @TODO Changing delegates + // @TODO Governance + + describe('Alpha2', function () { + it('indexes created proposals - alpha2', async function () { + const [_, user1] = signers; + await enfranchiseAccount(user1, scaleValue(600000, 18)); + + const callData = ethers.utils.defaultAbiCoder.encode(['address'], [governorAlpha2.address]); + + const vip = [ + ['0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'], // targets + ['0'], // values + ['setPendingAdmin(address)'], // signatures + [callData], // params + 'Test proposal 21', // description + ]; + + const tx = await governorAlpha2.connect(user1).propose(...vip); + await tx.wait(1); + + await waitForSubgraphToBeSynced(SYNC_DELAY); + + const { + data: { proposal }, + } = await subgraphClient.getProposalById('21'); + + expect(proposal.id).to.be.equal('21'); + expect(proposal.description).to.be.equal('Test proposal 21'); + expect(proposal.status).to.be.equal('PENDING'); + expect(proposal.executionETA).to.be.null; + expect(proposal.targets).to.deep.equal([ + '0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'.toLowerCase(), + ]); + expect(proposal.values).to.deep.equal(['0']); + expect(proposal.signatures).to.deep.equal(['setPendingAdmin(address)']); + expect(proposal.calldatas).to.deep.equal([callData]); + }); + }); +}); diff --git a/subgraphs/venus-governance/tests/integration/index.ts b/subgraphs/venus-governance/tests/integration/index.ts index 67829416..62afed3f 100644 --- a/subgraphs/venus-governance/tests/integration/index.ts +++ b/subgraphs/venus-governance/tests/integration/index.ts @@ -1,213 +1,4 @@ -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, scaleValue, waitForSubgraphToBeSynced } from 'venus-subgraph-utils'; +import './setup'; +import './alpha'; +import './accessControlManager'; -import subgraphClient from '../../subgraph-client/index'; -import { SUBGRAPH_ACCOUNT, SUBGRAPH_NAME, SYNC_DELAY } from './utils/constants'; -import { enfranchiseAccount } from './utils/voter'; - -describe('Governance', function () { - let signers: SignerWithAddress[]; - let governorAlpha: Contract; - let governorAlpha2: Contract; - - before(async function () { - this.timeout(50000000); // sometimes it takes a long time - governorAlpha = await ethers.getContract('GovernorAlpha'); - governorAlpha2 = await ethers.getContract('GovernorAlpha2'); - signers = await ethers.getSigners(); - - const root = `${__dirname}/../..`; - - await deploy({ - root, - packageName: 'venus-governance-subgraph', - subgraphAccount: SUBGRAPH_ACCOUNT, - subgraphName: SUBGRAPH_NAME, - syncDelay: SYNC_DELAY, - }); - - const [_, user1, user2, user3, user4] = signers; - - 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 () { - it('indexes created proposal success', async function () { - const [_, _1, _2, _3, user4] = signers; - const callData = ethers.utils.defaultAbiCoder.encode(['address'], [governorAlpha.address]); - - const vip = [ - ['0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'], // targets - ['0'], // values - ['setPendingAdmin(address)'], // signatures - [callData], // params - 'Test proposal 1', // description - ]; - - const tx = await governorAlpha.connect(user4).propose(...vip); - await tx.wait(1); - - await waitForSubgraphToBeSynced(SYNC_DELAY); - - 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'); - expect(proposal.executionETA).to.be.null; - expect(proposal.targets).to.deep.equal([ - '0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'.toLowerCase(), - ]); - expect(proposal.values).to.deep.equal(['0']); - expect(proposal.signatures).to.deep.equal(['setPendingAdmin(address)']); - expect(proposal.calldatas).to.deep.equal([callData]); - }); - - it('index for vote cast', async function () { - const [_, user1, user2, user3, user4] = signers; - - const time = Date.now() + 106400; - await ethers.provider.send('evm_setNextBlockTimestamp', [time]); - await mine(1); - - let tx = await governorAlpha.connect(user1).castVote('1', false); - await tx.wait(1); - tx = await governorAlpha.connect(user2).castVote('1', true); - await tx.wait(1); - tx = await governorAlpha.connect(user3).castVote('1', true); - await tx.wait(1); - tx = await governorAlpha.connect(user4).castVote('1', true); - await tx.wait(1); - - await waitForSubgraphToBeSynced(SYNC_DELAY); - - const { - data: { proposal }, - } = await subgraphClient.getProposalById('1'); - expect(proposal.votes.length).to.be.equal(4); - - const { - data: { delegate: delegate1 }, - } = await subgraphClient.getDelegateById(user1.address.toLowerCase()); - - 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('100000000000000000000000'); - expect(delegate1.proposals).to.deep.equal([]); - - const { - data: { delegate: delegate2 }, - } = await subgraphClient.getDelegateById(user2.address.toLowerCase()); - expect(delegate2.votes[0].id).to.equal(`${user2.address.toLowerCase()}-0x1`); - expect(delegate2.votes[0].support).to.equal('FOR'); - expect(delegate2.votes[0].votes).to.equal('200000000000000000000000'); - expect(delegate2.proposals).to.deep.equal([]); - expect(delegate2.proposals).to.deep.equal([]); - - const { - data: { delegate: delegate4 }, - } = await subgraphClient.getDelegateById(user4.address.toLowerCase()); - expect(delegate4.proposals).to.deep.equal([{ id: '1', __typename: 'Proposal' }]); - }); - }); - - // @TODO Update proposal Status - // @TODO Changing delegates - // @TODO Governance - - describe('Alpha2', function () { - it('indexes created proposals - alpha2', async function () { - const [_, user1] = signers; - await enfranchiseAccount(user1, scaleValue(600000, 18)); - - const callData = ethers.utils.defaultAbiCoder.encode(['address'], [governorAlpha2.address]); - - const vip = [ - ['0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'], // targets - ['0'], // values - ['setPendingAdmin(address)'], // signatures - [callData], // params - 'Test proposal 21', // description - ]; - - const tx = await governorAlpha2.connect(user1).propose(...vip); - await tx.wait(1); - - await waitForSubgraphToBeSynced(SYNC_DELAY); - - const { - data: { proposal }, - } = await subgraphClient.getProposalById('21'); - - expect(proposal.id).to.be.equal('21'); - expect(proposal.description).to.be.equal('Test proposal 21'); - expect(proposal.status).to.be.equal('PENDING'); - expect(proposal.executionETA).to.be.null; - expect(proposal.targets).to.deep.equal([ - '0x939bD8d64c0A9583A7Dcea9933f7b21697ab6396'.toLowerCase(), - ]); - expect(proposal.values).to.deep.equal(['0']); - expect(proposal.signatures).to.deep.equal(['setPendingAdmin(address)']); - expect(proposal.calldatas).to.deep.equal([callData]); - }); - }); - - describe('Permission events', function () { - it('indexes permission granted events', async function () { - const { data } = await subgraphClient.getPermissions(); - - const { permissions } = data!; - expect(permissions.length).to.be.equal(12); - - permissions.forEach(pe => { - expect(pe.type).to.be.equal('GRANTED'); - }); - }); - - it('indexes permission revoked events', async function () { - const accessControlManager = await ethers.getContract('AccessControlManager'); - const tx = await accessControlManager.revokeCallPermission( - ethers.constants.AddressZero, - 'setMinLiquidatableCollateral(uint256)', - ethers.constants.AddressZero, - ); - await tx.wait(); - await waitForSubgraphToBeSynced(SYNC_DELAY); - - const { data } = await subgraphClient.getPermissions(); - - const { permissions } = data!; - expect(permissions.length).to.be.equal(13); - - expect(permissions[0].type).to.be.equal('REVOKED'); - }); - - it('updates a previously created record with a new permission type', async function () { - const accessControlManager = await ethers.getContract('AccessControlManager'); - const tx = await accessControlManager.giveCallPermission( - ethers.constants.AddressZero, - 'setMinLiquidatableCollateral(uint256)', - ethers.constants.AddressZero, - ); - await tx.wait(); - await waitForSubgraphToBeSynced(SYNC_DELAY); - - const { data } = await subgraphClient.getPermissions(); - - const { permissions } = data!; - expect(permissions.length).to.be.equal(13); - - expect(permissions[0].type).to.be.equal('GRANTED'); - }); - }); -}); diff --git a/subgraphs/venus-governance/tests/integration/setup.ts b/subgraphs/venus-governance/tests/integration/setup.ts new file mode 100644 index 00000000..0ac8a1c1 --- /dev/null +++ b/subgraphs/venus-governance/tests/integration/setup.ts @@ -0,0 +1,19 @@ +import { deploy } from 'venus-subgraph-utils'; + +import { SUBGRAPH_ACCOUNT, SUBGRAPH_NAME, SYNC_DELAY } from './utils/constants'; + +describe('Deploy Subgraph', function () { + before(async function () { + this.timeout(50000000); // sometimes it takes a long time + + const root = `${__dirname}/../..`; + + await deploy({ + root, + packageName: 'venus-governance-subgraph', + subgraphAccount: SUBGRAPH_ACCOUNT, + subgraphName: SUBGRAPH_NAME, + syncDelay: SYNC_DELAY, + }); + }); +}); From 85a86c329b53f72b2bf707acf3500402ddf0e9ac Mon Sep 17 00:00:00 2001 From: Corey Rice Date: Thu, 5 Oct 2023 18:34:54 -0300 Subject: [PATCH 4/4] ci(test): bail on first failed test --- .github/workflows/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0384b6cb..06e0f78d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -73,7 +73,7 @@ jobs: - name: Run Isolated Pools integration integration tests run: | - docker exec -i subgraph-hardhat-node yarn workspace isolated-pools-subgraph run test:integration + docker exec -i subgraph-hardhat-node yarn workspace isolated-pools-subgraph run test:integration --bail - name: Stop containers if: always() @@ -106,7 +106,7 @@ jobs: - name: Run Governance integration integration tests run: | - docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run test:integration + docker exec -i subgraph-hardhat-node yarn workspace venus-governance-subgraph run test:integration --bail - name: Stop containers if: always()