Skip to content

Commit

Permalink
Merge pull request #117 from VenusProtocol/add-bravo-governance-tests
Browse files Browse the repository at this point in the history
Add bravo governance tests
  • Loading branch information
coreyar authored Oct 30, 2023
2 parents 037186a + 25f225a commit 8cd3d7b
Show file tree
Hide file tree
Showing 25 changed files with 489 additions and 132 deletions.
6 changes: 3 additions & 3 deletions copy_contracts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ rm -rf contracts/protocol/contracts/test

mkdir -p ./contracts/governance/contracts/Governance
mkdir -p ./contracts/governance/contracts/legacy
cp ./node_modules/@venusprotocol/governance-contracts/contracts/legacy/GovernorBravoDelegateV1.sol ./contracts/governance/contracts/legacy/GovernorBravoDelegateV1.sol
cp ./node_modules/@venusprotocol/governance-contracts/contracts/legacy/GovernorBravoInterfaces.sol ./contracts/governance/contracts/legacy/GovernorBravoInterfaces.sol
cp ./node_modules/@venusprotocol/governance-contracts/contracts/legacy/GovernorBravoDelegator.sol ./contracts/governance/contracts/legacy/GovernorBravoDelegator.sol
cp -rf ./node_modules/@venusprotocol/governance-contracts/contracts/legacy ./contracts/governance/contracts
cp ./node_modules/@venusprotocol/governance-contracts/contracts/Governance/GovernorBravoInterfaces.sol ./contracts/governance/contracts/Governance/GovernorBravoInterfaces.sol

rm contracts/protocol/contracts/Governance/GovernorBravoDelegate.sol
rm contracts/protocol/contracts/Governance/GovernorBravoDelegator.sol
rm contracts/protocol/contracts/Governance/GovernorAlpha.sol
rm contracts/protocol/contracts/Governance/GovernorAlpha2.sol
rm contracts/protocol/contracts/Governance/Timelock.sol
rm -rf contracts/protocol/contracts/Lens/VenusLens.sol

Expand Down
7 changes: 7 additions & 0 deletions deploy/018-governance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
log: true,
autoMine: true,
});

await deploy('GovernorBravoDelegate', {
from: deployer,
args: [],
log: true,
autoMine: true,
});
};

func.tags = ['Governance'];
Expand Down
1 change: 0 additions & 1 deletion subgraphs/isolated-pools/tests/integration/pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ describe('Pools', function () {
const syncDelay = 6000;

before(async function () {
this.timeout(500000); // sometimes it takes a long time
const signers = await ethers.getSigners();
[root] = await ethers.getSigners();
acc1 = signers[1];
Expand Down
2 changes: 0 additions & 2 deletions subgraphs/isolated-pools/tests/integration/poolRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ describe('Pool Registry', function () {
const syncDelay = 2000;

before(async function () {
this.timeout(500000); // sometimes it takes a long time

[root] = await ethers.getSigners();
poolRegistry = await ethers.getContract('PoolRegistry');

Expand Down
1 change: 0 additions & 1 deletion subgraphs/isolated-pools/tests/integration/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { SUBGRAPH_ACCOUNT, SUBGRAPH_NAME, SYNC_DELAY } from './constants';

describe('Deploy Subgraph', function () {
it('should deploy subgraph', async function () {
this.timeout(500000); // sometimes it takes a long time
const root = `${__dirname}/../..`;

await deploy({
Expand Down
2 changes: 0 additions & 2 deletions subgraphs/isolated-pools/tests/integration/vTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ describe('VToken events', function () {
const borrowAmount = scaleValue(0.000025, 18);

before(async function () {
this.timeout(500000); // sometimes it takes a long time

const signers = await ethers.getSigners();
[_root, liquidator, borrower, liquidator2, borrower2, supplier1, supplier2] = signers;

Expand Down
21 changes: 2 additions & 19 deletions subgraphs/venus-governance/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Delegate @entity {

enum PROPOSAL_TYPE {
NORMAL
FASTRACK
FAST_TRACK
CRITICAL
}

Expand Down Expand Up @@ -105,7 +105,7 @@ type Governance @entity {
id: ID!

"Number of proposals created"
proposals: BigInt!
totalProposals: BigInt!

"Total number of accounts delegates that can participate in governance by voting or creating proposals"
totalDelegates: BigInt!
Expand Down Expand Up @@ -135,23 +135,6 @@ type Governance @entity {
proposalMaxOperations: BigInt!
}

type GovernanceRoute @entity {
"Index of the governance route"
id: ID!
"Governor implementation the route belongs to"
governor: Bytes!
"Address of timelock contract for route"
timelock: Bytes!
"Queue execution delay in blocks"
queueDelayBlocks: BigInt!
"The delay before voting on a proposal may take place, once proposed, in blocks"
votingDelayBlocks: BigInt!
"The duration of voting on a proposal, in blocks"
votingPeriodBlocks: BigInt!
"The number of votes required in order for a voter to become a proposer"
proposalThresholdMantissa: BigInt!
}

enum PermissionStatus {
GRANTED,
REVOKED
Expand Down
4 changes: 4 additions & 0 deletions subgraphs/venus-governance/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ export const BIGINT_ZERO = BigInt.fromI32(0);
export const BIGINT_ONE = BigInt.fromI32(1);
export const BIGDECIMAL_ZERO = new BigDecimal(BIGINT_ZERO);

// Ids
export const GOVERNANCE = 'GOVERNANCE';
export const SEPERATOR = '-';

// Vote support
export const FOR = 'FOR';
export const AGAINST = 'AGAINST';
Expand Down
2 changes: 2 additions & 0 deletions subgraphs/venus-governance/src/mappings/bravo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { createProposal, createVoteBravo } from '../operations/create';
import { getGovernanceEntity } from '../operations/get';
import { getOrCreateDelegate } from '../operations/getOrCreate';
import {
updateGovernanceEntity,
updateProposalCanceled,
updateProposalExecuted,
updateProposalQueued,
Expand Down Expand Up @@ -54,6 +55,7 @@ export function handleNewImplementation(event: NewImplementation): void {
const governance = getGovernanceEntity();
governance.implementation = event.params.newImplementation;
governance.save();
updateGovernanceEntity();
}

export function handleNewPendingAdmin(event: NewPendingAdmin): void {
Expand Down
2 changes: 1 addition & 1 deletion subgraphs/venus-governance/src/operations/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function createProposal<E>(event: E): Proposal {

const governance = getGovernanceEntity();

governance.proposals = governance.proposals.plus(BIGINT_ONE);
governance.totalProposals = governance.totalProposals.plus(BIGINT_ONE);
governance.save();
const targets = event.params.targets.map<Bytes>((address: Address) =>
Bytes.fromHexString(address.toHexString()),
Expand Down
71 changes: 8 additions & 63 deletions subgraphs/venus-governance/src/operations/get.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import { Address, BigInt, log } from '@graphprotocol/graph-ts';
import { Address, log } from '@graphprotocol/graph-ts';

import { GovernorBravoDelegate2 } from '../../generated/GovernorBravoDelegate2/GovernorBravoDelegate2';
import { Timelock } from '../../generated/GovernorBravoDelegate2/Timelock';
import { Delegate, Governance, GovernanceRoute, Proposal } from '../../generated/schema';
import { Delegate, Governance, Proposal } from '../../generated/schema';
import { BIGINT_ZERO } from '../constants';
import { governorBravoDelegatorAddress, nullAddress } from '../constants/addresses';
import { getDelegateId } from '../utilities/ids';
import { nullAddress } from '../constants/addresses';
import { getDelegateId, getGovernanceId } from '../utilities/ids';

/**
* While technically this function does also create, we don't care because it only happens once as the id is a constant.
* The initial values are mocked because they are updated when an implementation is set
* @returns Governance
*/
export const getGovernanceEntity = (): Governance => {
let governance = Governance.load(governorBravoDelegatorAddress.toHex());
let governance = Governance.load(getGovernanceId());
if (!governance) {
const governorBravoDelegate2 = GovernorBravoDelegate2.bind(governorBravoDelegatorAddress);
governance = new Governance(governorBravoDelegatorAddress.toHex());
governance.proposals = BIGINT_ZERO;
governance = new Governance(getGovernanceId());
governance.totalProposals = BIGINT_ZERO;
governance.totalDelegates = BIGINT_ZERO;
governance.totalVoters = BIGINT_ZERO;
governance.totalVotesMantissa = BIGINT_ZERO;
Expand All @@ -26,59 +24,6 @@ export const getGovernanceEntity = (): Governance => {
governance.guardian = nullAddress;
governance.quorumVotesMantissa = BIGINT_ZERO;
governance.proposalMaxOperations = BIGINT_ZERO;

// 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 = governorBravoDelegatorAddress;
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 = governorBravoDelegatorAddress;
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 = governorBravoDelegatorAddress;
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;
Expand Down
23 changes: 20 additions & 3 deletions subgraphs/venus-governance/src/operations/update.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { GovernorBravoDelegate2 } from '../../generated/GovernorBravoDelegate2/GovernorBravoDelegate2';
import { Governance } from '../../generated/schema';
import { BIGINT_ONE } from '../constants';
import { nullAddress } from '../constants/addresses';
import { governorBravoDelegatorAddress, nullAddress } from '../constants/addresses';
import { getGovernanceId } from '../utilities/ids';
import { getGovernanceEntity, getProposal } from './get';
import { getOrCreateDelegate } from './getOrCreate';

Expand Down Expand Up @@ -44,8 +47,10 @@ export function updateDelegateChanged<E>(event: E): void {
const oldDelegate = oldDelegateResult.entity;
oldDelegate.delegateCount = oldDelegate.delegateCount - 1;
oldDelegate.save();
}

governance.totalDelegates = governance.totalDelegates.minus(BIGINT_ONE);
if (fromDelegate == nullAddress.toHexString()) {
governance.totalDelegates = governance.totalDelegates.plus(BIGINT_ONE);
governance.save();
}

Expand All @@ -54,8 +59,10 @@ export function updateDelegateChanged<E>(event: E): void {
const newDelegate = newDelegateResult.entity;
newDelegate.delegateCount = newDelegate.delegateCount + 1;
newDelegate.save();
}

governance.totalDelegates = governance.totalDelegates.plus(BIGINT_ONE);
if (fromDelegate == nullAddress.toHexString()) {
governance.totalDelegates = governance.totalDelegates.minus(BIGINT_ONE);
governance.save();
}
}
Expand All @@ -76,3 +83,13 @@ export function updateDelegateVoteChanged<E>(event: E): void {
governance.totalVotesMantissa = governance.totalVotesMantissa.plus(votesDifference);
governance.save();
}

export function updateGovernanceEntity(): void {
const governorBravoDelegate2 = GovernorBravoDelegate2.bind(governorBravoDelegatorAddress);
const governance = Governance.load(getGovernanceId())!;
governance.quorumVotesMantissa = governorBravoDelegate2.quorumVotes();
governance.admin = governorBravoDelegate2.admin();
governance.guardian = governorBravoDelegate2.guardian();
governance.proposalMaxOperations = governorBravoDelegate2.proposalMaxOperations();
governance.save();
}
4 changes: 3 additions & 1 deletion subgraphs/venus-governance/src/utilities/ids.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Address, BigInt } from '@graphprotocol/graph-ts';

const SEPERATOR = '-';
import { GOVERNANCE, SEPERATOR } from '../constants';

export const getVoteId = (voter: Address, proposalId: BigInt): string =>
[voter.toHexString(), proposalId.toString()].join(SEPERATOR);
Expand All @@ -13,3 +13,5 @@ export const getPermissionId = (
[accountAddress.toHexString(), contractAddress.toHexString(), functionSig].join(SEPERATOR);

export const getDelegateId = (account: Address): string => account.toHexString();

export const getGovernanceId = (): string => GOVERNANCE;
6 changes: 6 additions & 0 deletions subgraphs/venus-governance/subgraph-client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Client as UrqlClient, createClient } from 'urql/core';
import {
DelegateByIdDocument,
DelegatesDocument,
GovernanceDocument,
PermissionsDocument,
ProposalByIdDocument,
ProposalsDocument,
Expand Down Expand Up @@ -51,6 +52,11 @@ class SubgraphClient {
const result = await this.query(PermissionsDocument, {});
return result;
}

async getGovernance() {
const result = await this.query(GovernanceDocument, {});
return result;
}
}

export default new SubgraphClient(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ 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);
});

Expand Down
4 changes: 0 additions & 4 deletions subgraphs/venus-governance/tests/integration/alpha.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ describe('GovernorAlpha', function () {
let user4: SignerWithAddress;

before(async function () {
this.timeout(10000000); // sometimes it takes a long time
governorAlpha = await ethers.getContract('GovernorAlpha');
governorAlpha2 = await ethers.getContract('GovernorAlpha2');
signers = await ethers.getSigners();
Expand Down Expand Up @@ -121,9 +120,6 @@ describe('GovernorAlpha', function () {
});

describe('Alpha2', function () {
before(async function () {
this.timeout(10000000); // sometimes it takes a long time
});
it('indexes created proposals - alpha2', async function () {
const [_, user1] = signers;
await enfranchiseAccount(user1, scaleValue(600000, 18));
Expand Down
Loading

0 comments on commit 8cd3d7b

Please sign in to comment.