Skip to content

Commit 6083ad6

Browse files
committed
add tests for setWhitelistCall via GovernanceExecutor
1 parent 4f47357 commit 6083ad6

File tree

2 files changed

+139
-14
lines changed

2 files changed

+139
-14
lines changed

Diff for: contracts/bprotocol/governance/GovernanceExecutor.sol

+7-7
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ contract GovernanceExecutor is Ownable {
1616
event RequestPoolUpgrade(address indexed pool);
1717
event PoolUpgraded(address indexed pool);
1818

19-
event RequestWhitelistUpgrade(address indexed target, bytes4 functionSig, bool list);
20-
event WhitelistUpgraded(address indexed target, bytes4 functionSig, bool list);
19+
event RequestSetWhitelistCall(address indexed target, bytes4 functionSig, bool list);
20+
event WhitelistCallUpdated(address indexed target, bytes4 functionSig, bool list);
2121

2222
constructor(address registry_, uint delay_) public {
2323
registry = IRegistry(registry_);
@@ -79,9 +79,9 @@ contract GovernanceExecutor is Ownable {
7979
* @param functionSig function signature as bytes4
8080
* @param list `true` to whitelist, `false` otherwise
8181
*/
82-
function reqUpgradeWhitelist(address target, bytes4 functionSig, bool list) external onlyOwner {
82+
function reqSetWhitelistCall(address target, bytes4 functionSig, bool list) external onlyOwner {
8383
whitelistRequests[target][functionSig][list] = now;
84-
emit RequestWhitelistUpgrade(target, functionSig, list);
84+
emit RequestSetWhitelistCall(target, functionSig, list);
8585
}
8686

8787
/**
@@ -90,7 +90,7 @@ contract GovernanceExecutor is Ownable {
9090
* @param functionSig function signature as bytes4
9191
* @param list `true` to whitelist, `false` otherwise
9292
*/
93-
function dropUpgradeWhitelist(address target, bytes4 functionSig, bool list) external onlyOwner {
93+
function dropWhitelistCall(address target, bytes4 functionSig, bool list) external onlyOwner {
9494
delete whitelistRequests[target][functionSig][list];
9595
}
9696

@@ -100,14 +100,14 @@ contract GovernanceExecutor is Ownable {
100100
* @param functionSig function signature as bytes4
101101
* @param list `true` to whitelist, `false` otherwise
102102
*/
103-
function execUpgradeWhitelist(address target, bytes4 functionSig, bool list) external {
103+
function execSetWhitelistCall(address target, bytes4 functionSig, bool list) external {
104104
uint reqTime = whitelistRequests[target][functionSig][list];
105105
require(reqTime != 0, "request-not-valid");
106106
require(now >= add(reqTime, delay), "delay-not-over");
107107

108108
delete whitelistRequests[target][functionSig][list];
109109
registry.setWhitelistAvatarCall(target, functionSig, list);
110-
emit WhitelistUpgraded(target, functionSig, list);
110+
emit WhitelistCallUpdated(target, functionSig, list);
111111
}
112112

113113
function add(uint a, uint b) internal pure returns (uint) {

Diff for: test/governance/TestGovernanceExecutor.spec.ts

+132-7
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ import BN from "bn.js";
99
import { CompoundUtils } from "@utils/CompoundUtils";
1010
import { toWei } from "web3-utils";
1111
import { governorAddress } from "compound-protocol/scenario/src/Value/GovernorValue";
12+
import { expandEvent } from "compound-protocol/scenario/src/Macro";
1213

1314
const GovernanceExecutor: b.GovernanceExecutorContract = artifacts.require("GovernanceExecutor");
15+
const EmergencyMock: b.EmergencyMockContract = artifacts.require("EmergencyMock");
16+
const Avatar: b.AvatarContract = artifacts.require("Avatar");
1417

1518
const chai = require("chai");
1619
const expect = chai.expect;
@@ -226,22 +229,144 @@ contract("GovernanceExecutor", async (accounts) => {
226229
});
227230

228231
describe("GovernanceExecutor.reqUpgradeWhitelist()", async () => {
229-
it("only owner can request to whitelist a function");
232+
let mock: b.EmergencyMockInstance;
230233

231-
it("non-owner cannot request to whitelist a function");
234+
beforeEach(async () => {
235+
mock = await EmergencyMock.new();
236+
});
237+
238+
it("only owner can request to whitelist a function", async () => {
239+
const setXCallData = await mock.setX.call(777);
240+
const sig = setXCallData.substring(0, 10); // 2 chars per byte + "0x"
241+
242+
const tx = await governanceExecutor.reqSetWhitelistCall(mock.address, sig, true, {
243+
from: a.deployer,
244+
});
245+
expectEvent(tx, "RequestSetWhitelistCall", {
246+
target: mock.address,
247+
functionSig: sig,
248+
list: true,
249+
});
250+
});
251+
252+
it("non-owner cannot request to whitelist a function", async () => {
253+
const setXCallData = await mock.setX.call(777);
254+
const sig = setXCallData.substring(0, 10); // 2 chars per byte + "0x"
255+
256+
await expectRevert(
257+
governanceExecutor.reqSetWhitelistCall(mock.address, sig, true, { from: a.other }),
258+
"caller is not the owner",
259+
);
260+
});
232261
});
233262

234263
describe("GovernanceExecutor.dropUpgradeWhitelist()", async () => {
235-
it("only owner can drop whitelist request");
264+
let mock: b.EmergencyMockInstance;
265+
let fnSig: string;
266+
267+
beforeEach(async () => {
268+
mock = await EmergencyMock.new();
236269

237-
it("non-owner cannot drop a whitelist request");
270+
const setXCallData = await mock.setX.call(777);
271+
fnSig = setXCallData.substring(0, 10); // 2 chars per byte + "0x"
272+
const tx = await governanceExecutor.reqSetWhitelistCall(mock.address, fnSig, true, {
273+
from: a.deployer,
274+
});
275+
});
276+
277+
it("only owner can drop whitelist request", async () => {
278+
await governanceExecutor.dropWhitelistCall(mock.address, fnSig, true, { from: a.deployer });
279+
});
280+
281+
it("non-owner cannot drop a whitelist request", async () => {
282+
await expectRevert(
283+
governanceExecutor.dropWhitelistCall(mock.address, fnSig, true, { from: a.other }),
284+
"Ownable: caller is not the owner",
285+
);
286+
});
238287
});
239288

240289
describe("GovernanceExecutor.execUpgradeWhitelist()", async () => {
241-
it("should execute whitelist request");
290+
let mock: b.EmergencyMockInstance;
291+
let data: string;
292+
let fnSig: string;
293+
let avatar1: b.AvatarInstance;
294+
295+
beforeEach(async () => {
296+
await registry.newAvatar({ from: a.user1 });
297+
avatar1 = await Avatar.at(await registry.avatarOf(a.user1));
298+
mock = await EmergencyMock.new();
299+
300+
data = await mock.setX.call(777);
301+
fnSig = data.substring(0, 10); // 2 chars per byte + "0x"
302+
const tx = await governanceExecutor.reqSetWhitelistCall(mock.address, fnSig, true, {
303+
from: a.deployer,
304+
});
305+
306+
// Registry owner must be GovernanceExecutor
307+
await bProtocol.registry.transferOwnership(governanceExecutor.address, { from: a.deployer });
308+
});
309+
310+
it("should execute whitelist request", async () => {
311+
await expectRevert(
312+
avatar1.emergencyCall(mock.address, data, { from: a.user1 }),
313+
"not-listed",
314+
);
242315

243-
it("should fail when delay not over yet");
316+
await time.increase(TWO_DAYS);
317+
318+
const tx = await governanceExecutor.execSetWhitelistCall(mock.address, fnSig, true);
319+
expectEvent(tx, "WhitelistCallUpdated", {
320+
target: mock.address,
321+
functionSig: fnSig,
322+
list: true,
323+
});
324+
325+
expect(await mock.x()).to.be.bignumber.equal(new BN(5));
326+
await avatar1.emergencyCall(mock.address, data, { from: a.user1 });
327+
expect(await mock.x()).to.be.bignumber.equal(new BN(777));
328+
});
329+
330+
it("should fail when delay not over yet", async () => {
331+
await expectRevert(
332+
avatar1.emergencyCall(mock.address, data, { from: a.user1 }),
333+
"not-listed",
334+
);
244335

245-
it("should fail when request is invalid");
336+
await time.increase(ONE_DAY);
337+
338+
await expectRevert(
339+
governanceExecutor.execSetWhitelistCall(mock.address, fnSig, true),
340+
"delay-not-over",
341+
);
342+
343+
expect(await mock.x()).to.be.bignumber.equal(new BN(5));
344+
await expectRevert(
345+
avatar1.emergencyCall(mock.address, data, { from: a.user1 }),
346+
"not-listed",
347+
);
348+
expect(await mock.x()).to.be.bignumber.equal(new BN(5));
349+
});
350+
351+
it("should fail when request is invalid", async () => {
352+
await expectRevert(
353+
avatar1.emergencyCall(mock.address, data, { from: a.user1 }),
354+
"not-listed",
355+
);
356+
357+
await time.increase(TWO_DAYS);
358+
359+
await expectRevert(
360+
governanceExecutor.execSetWhitelistCall(mock.address, fnSig, false),
361+
"request-not-valid",
362+
);
363+
364+
expect(await mock.x()).to.be.bignumber.equal(new BN(5));
365+
await expectRevert(
366+
avatar1.emergencyCall(mock.address, data, { from: a.user1 }),
367+
"not-listed",
368+
);
369+
expect(await mock.x()).to.be.bignumber.equal(new BN(5));
370+
});
246371
});
247372
});

0 commit comments

Comments
 (0)