Skip to content

Commit

Permalink
feat: add setter of xvsVault in bravo and test
Browse files Browse the repository at this point in the history
  • Loading branch information
GitGuru7 committed Feb 13, 2024
1 parent efaf426 commit 03259e8
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 0 deletions.
12 changes: 12 additions & 0 deletions contracts/Governance/GovernorBravoDelegate.sol
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,18 @@ contract GovernorBravoDelegate is GovernorBravoDelegateStorageV2, GovernorBravoE
return votes;
}

/**
* @notice Update address of XVS vault
* @dev Admin only. Update XVS Vault address
* @param xvsVault_ Address of XVS vault
*/
function _setXvsVault(address xvsVault_) external {
require(msg.sender == admin, "GovernorBravo::_setXvsVault: admin only");
require(xvsVault_ != address(0), "GovernorBravo::setXvsVault: invalid xvs address");
emit SetXvsVault(address(xvsVault), xvsVault_);
xvsVault = XvsVaultInterface(xvsVault_);
}

/**
* @notice Sets the new governance guardian
* @param newGuardian the address of the new guardian
Expand Down
3 changes: 3 additions & 0 deletions contracts/Governance/GovernorBravoInterfaces.sol
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ contract GovernorBravoEvents {

/// @notice Emitted when the maximum number of operations in one proposal is updated
event ProposalMaxOperationsUpdated(uint oldMaxOperations, uint newMaxOperations);

///@notice Emitted when address of XVS vault updated
event SetXvsVault(address indexed oldXvsVault, address indexed newXvsVault);
}

/**
Expand Down
72 changes: 72 additions & 0 deletions tests/Fork/GovernanceBravoStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { expect } from "chai";
import { BigNumber, Signer } from "ethers";
import { ethers } from "hardhat";

import {
GovernorBravoDelegate,
GovernorBravoDelegate__factory,
GovernorBravoDelegator,
GovernorBravoDelegator__factory,
} from "../../typechain";
import { forking, initMainnetUser } from "./utils";

const delegatorProxyAddress = "0x2d56dC077072B53571b8252008C60e945108c75a";
const guardianAddress = "0x1C2CAc6ec528c20800B2fe734820D87b581eAA6B";
let governorBravoDelegator: GovernorBravoDelegator;
let admin: string;
let votingDelay: BigNumber;
let pendingAdmin: string;
let implementation: string;
let impersonatedGuardian: Signer;
let governorBravoDelegate: GovernorBravoDelegate;
let votingPeriod: BigNumber;
let proposalThreshold: BigNumber;
let initialProposalId: BigNumber;
let xvsVault: string;
let proposalMaxOperations: BigNumber;
let guardian: string;

async function configureBravo() {
impersonatedGuardian = await initMainnetUser(guardianAddress, ethers.utils.parseEther("2"));
governorBravoDelegator = GovernorBravoDelegator__factory.connect(delegatorProxyAddress, impersonatedGuardian);
governorBravoDelegate = GovernorBravoDelegate__factory.connect(delegatorProxyAddress, impersonatedGuardian);
}

const FORK_MAINNET = process.env.FORK == "true" && process.env.FORKED_NETWORK == "bscmainnet";
if (FORK_MAINNET) {
const blockNumber = 35984931;
forking(blockNumber, async () => {
describe("Governor Bravo Storage Layout Test", async () => {
before(async () => {
await configureBravo();
votingDelay = await governorBravoDelegate.votingDelay();
pendingAdmin = await governorBravoDelegate.pendingAdmin();
implementation = await governorBravoDelegate.implementation();
admin = await governorBravoDelegate.admin();
votingPeriod = await governorBravoDelegate.votingPeriod();
proposalThreshold = await governorBravoDelegate.proposalThreshold();
initialProposalId = await governorBravoDelegate.initialProposalId();
xvsVault = await governorBravoDelegate.xvsVault();
proposalMaxOperations = await governorBravoDelegate.proposalMaxOperations();
guardian = await governorBravoDelegate.guardian();
});
it("Verify states after upgrade", async () => {
const governorBravoDelegateFactory = await ethers.getContractFactory("GovernorBravoDelegate");
const governorBravoDelegateNew = await governorBravoDelegateFactory.deploy();
await governorBravoDelegateNew.deployed();
await governorBravoDelegator.connect(impersonatedGuardian)._setImplementation(governorBravoDelegateNew.address);

expect(votingDelay).equals(await governorBravoDelegate.votingDelay());
expect(pendingAdmin).equals(await governorBravoDelegate.pendingAdmin());
expect(implementation).not.equals(await governorBravoDelegate.implementation());
expect(admin).equals(await governorBravoDelegate.admin());
expect(votingPeriod).equals(await governorBravoDelegate.votingPeriod());
expect(proposalThreshold).equals(await governorBravoDelegate.proposalThreshold());
expect(initialProposalId).equals(await governorBravoDelegate.initialProposalId());
expect(xvsVault).equals(await governorBravoDelegate.xvsVault());
expect(proposalMaxOperations).equals(await governorBravoDelegate.proposalMaxOperations());
expect(guardian).equals(await governorBravoDelegate.guardian());
});
});
});
}
35 changes: 35 additions & 0 deletions tests/Fork/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { impersonateAccount, setBalance } from "@nomicfoundation/hardhat-network-helpers";
import { NumberLike } from "@nomicfoundation/hardhat-network-helpers/dist/src/types";
import { ethers } from "hardhat";
import { network } from "hardhat";

export const setForkBlock = async (blockNumber: number) => {
await network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
jsonRpcUrl: process.env[`ARCHIVE_NODE_${process.env.FORKED_NETWORK}`],
blockNumber,
},
},
],
});
};

export const forking = (blockNumber: number, fn: () => void) => {
describe(`At block #${blockNumber}`, () => {
before(async () => {
await setForkBlock(blockNumber);
});
fn();
});
};

export const initMainnetUser = async (user: string, balance?: NumberLike) => {
await impersonateAccount(user);
if (balance !== undefined) {
await setBalance(user, balance);
}
return ethers.getSigner(user);
};
56 changes: 56 additions & 0 deletions tests/Governance/GovernanceBravo/setterTest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { FakeContract, MockContract, smock } from "@defi-wonderland/smock";
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import chai from "chai";
import { Signer } from "ethers";
import { ethers } from "hardhat";

import { GovernorBravoDelegate, GovernorBravoDelegate__factory, XVSVault } from "../../../typechain";

const { expect } = chai;
chai.use(smock.matchers);

let root: Signer;
let user: Signer;
let governorBravoDelegate: MockContract<GovernorBravoDelegate>;
let xvsVault: FakeContract<XVSVault>;

type GovernorBravoDelegateFixture = {
governorBravoDelegate: MockContract<GovernorBravoDelegate>;
xvsVault: FakeContract<XVSVault>;
};

async function governorBravoFixture(): Promise<GovernorBravoDelegateFixture> {
const GovernorBravoDelegateFactory = await smock.mock<GovernorBravoDelegate__factory>("GovernorBravoDelegate");
const governorBravoDelegate = await GovernorBravoDelegateFactory.deploy();
const xvsVault = await smock.fake<XVSVault>("XVSVault");
return { governorBravoDelegate, xvsVault };
}
describe("Governance Bravo Setter Test", async () => {
beforeEach(async () => {
[root, user] = await ethers.getSigners();
const contracts = await loadFixture(governorBravoFixture);
({ governorBravoDelegate, xvsVault } = contracts);
await governorBravoDelegate.setVariable("admin", await root.getAddress());
await governorBravoDelegate.setVariable("xvsVault", xvsVault.address);
});

describe("XvsVault setter in Governance Bravo", async () => {
it("Xvs vault address should be updated", async () => {
const newXvsVault = await smock.fake<XVSVault>("XVSVault");
expect(await governorBravoDelegate.xvsVault()).to.equal(xvsVault.address);
await governorBravoDelegate._setXvsVault(newXvsVault.address);
expect(await governorBravoDelegate.xvsVault()).to.equal(newXvsVault.address);
});
it("Revert on unauthorized access", async () => {
const newXvsVault = await smock.fake<XVSVault>("XVSVault");
await expect(governorBravoDelegate.connect(user)._setXvsVault(newXvsVault.address)).to.be.revertedWith(
"GovernorBravo::_setXvsVault: admin only",
);
});
it("Reverts on zero address", async () => {
await expect(governorBravoDelegate._setXvsVault(ethers.constants.AddressZero)).to.be.revertedWith(
"GovernorBravo::setXvsVault: invalid xvs address",
);
});
});
});

0 comments on commit 03259e8

Please sign in to comment.