-
Notifications
You must be signed in to change notification settings - Fork 25
/
task.fork.ts
194 lines (157 loc) · 8.26 KB
/
task.fork.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import hre from 'hardhat';
import { expect } from 'chai';
import { Contract } from 'ethers';
import { fp } from '@helpers/numbers';
import { SignerWithAddress } from '@nomiclabs/hardhat-ethers/dist/src/signer-with-address';
import * as expectEvent from '@helpers/expectEvent';
import { describeForkTest } from '@src';
import { Task, TaskMode } from '@src';
import { getForkedNetwork } from '@src';
import { getSigner, impersonate } from '@src';
import { actionId } from '@helpers/models/misc/actions';
import TimelockAuthorizer from '@helpers/models/authorizer/TimelockAuthorizer';
import { advanceTime, DAY } from '@helpers/time';
import { ZERO_ADDRESS } from '@helpers/constants';
describeForkTest.skip('GaugeAdderV3', 'mainnet', 16370000, function () {
let factory: Contract;
let adaptorEntrypoint: Contract;
let authorizer: Contract;
let oldAuthorizer: Contract;
let gaugeAdder: Contract;
let daoMultisig: SignerWithAddress;
let gaugeController: Contract;
let migrator: Contract;
let vault: Contract;
let task: Task;
const LM_MULTISIG = '0xc38c5f97b34e175ffd35407fc91a937300e33860';
const LP_TOKEN = '0xbc5F4f9332d8415AAf31180Ab4661c9141CC84E4';
const DAO_MULTISIG = '0x10a19e7ee7d7f8a52822f6817de8ea18204f2e4f';
const weightCap = fp(0.001);
before('create timelock authorizer', async () => {
const timelockTask = new Task('20221202-timelock-authorizer', TaskMode.READ_ONLY, getForkedNetwork(hre));
authorizer = await timelockTask.deployedInstance('TimelockAuthorizer');
migrator = await timelockTask.deployedInstance('TimelockAuthorizerMigrator');
const adaptorEntrypointTask = new Task('20221124-authorizer-adaptor-entrypoint', TaskMode.READ_ONLY, 'mainnet');
adaptorEntrypoint = await adaptorEntrypointTask.deployedInstance('AuthorizerAdaptorEntrypoint');
});
before('change authorizer admin to the DAO multisig', async () => {
await migrator.startRootTransfer();
daoMultisig = await impersonate(DAO_MULTISIG, fp(100));
await authorizer.connect(daoMultisig).claimRoot();
const authorizerTask = new Task('20210418-authorizer', TaskMode.READ_ONLY, getForkedNetwork(hre));
oldAuthorizer = await authorizerTask.deployedInstance('Authorizer');
expect(await migrator.oldAuthorizer()).to.be.eq(oldAuthorizer.address);
const vaultTask = new Task('20210418-vault', TaskMode.READ_ONLY, getForkedNetwork(hre));
vault = await vaultTask.deployedInstance('Vault');
const setAuthorizerActionId = await actionId(vault, 'setAuthorizer');
await oldAuthorizer.connect(daoMultisig).grantRolesToMany([setAuthorizerActionId], [migrator.address]);
await migrator.finalizeMigration();
});
before('run Gauge Adder task', async () => {
task = new Task('20230109-gauge-adder-v3', TaskMode.TEST, getForkedNetwork(hre));
await task.run({ force: true });
gaugeAdder = await task.deployedInstance('GaugeAdder');
});
context('construction', () => {
it('stores the entrypoint', async () => {
expect(await gaugeAdder.getAuthorizerAdaptorEntrypoint()).to.equal(adaptorEntrypoint.address);
});
it('stores the gauge controller', async () => {
const gaugeControllerTask = new Task('20220325-gauge-controller', TaskMode.READ_ONLY, getForkedNetwork(hre));
gaugeController = await gaugeControllerTask.deployedInstance('GaugeController');
// Ensure we can call functions on the gaugeController
const controllerAdmin = await gaugeController.admin();
expect(controllerAdmin).to.not.equal(ZERO_ADDRESS);
expect(await gaugeController.gauge_exists(ZERO_ADDRESS)).to.be.false;
expect(await gaugeAdder.getGaugeController()).to.equal(gaugeController.address);
});
});
context('advanced functions', () => {
let lmMultisig: SignerWithAddress;
let admin: SignerWithAddress;
let gauge: Contract;
before('load accounts', async () => {
admin = await getSigner(0);
lmMultisig = await impersonate(LM_MULTISIG, fp(100));
});
before('create gauge factory', async () => {
const factoryTask = new Task('20220822-mainnet-gauge-factory-v2', TaskMode.TEST, getForkedNetwork(hre));
await factoryTask.run({ force: true });
factory = await factoryTask.deployedInstance('LiquidityGaugeFactory');
expect(await factory.isGaugeFromFactory(ZERO_ADDRESS)).to.be.false;
});
// We need to grant permission to the admin to add the LiquidityGaugeFactory to the GaugeAdder, and also to add
// gauges from said factory to the GaugeController.
before('grant permissions', async () => {
const addFactoryAction = await actionId(gaugeAdder, 'addGaugeFactory');
const addGaugeAction = await actionId(gaugeAdder, 'addEthereumGauge');
const gaugeControllerAddGaugeAction = await actionId(
adaptorEntrypoint,
'add_gauge(address,int128)',
gaugeController.interface
);
await authorizer
.connect(daoMultisig)
.manageGranter(addFactoryAction, lmMultisig.address, TimelockAuthorizer.EVERYWHERE, true);
await authorizer
.connect(daoMultisig)
.manageGranter(addGaugeAction, lmMultisig.address, TimelockAuthorizer.EVERYWHERE, true);
await authorizer
.connect(daoMultisig)
.manageGranter(gaugeControllerAddGaugeAction, lmMultisig.address, TimelockAuthorizer.EVERYWHERE, true);
let tx = await authorizer
.connect(lmMultisig)
.grantPermissions([addFactoryAction], admin.address, [TimelockAuthorizer.EVERYWHERE]);
expectEvent.inReceipt(await tx.wait(), 'PermissionGranted', {
actionId: addFactoryAction,
account: admin.address,
where: TimelockAuthorizer.EVERYWHERE,
});
tx = await authorizer
.connect(lmMultisig)
.grantPermissions([addGaugeAction], admin.address, [TimelockAuthorizer.EVERYWHERE]);
expectEvent.inReceipt(await tx.wait(), 'PermissionGranted', {
actionId: addGaugeAction,
account: admin.address,
where: TimelockAuthorizer.EVERYWHERE,
});
// Granting `GaugeController#add_gauge` permissions to the entrypoint has a delay, so the permission needs
// to be scheduled and executed after the required time passes.
tx = await authorizer
.connect(lmMultisig)
.scheduleGrantPermission(gaugeControllerAddGaugeAction, gaugeAdder.address, TimelockAuthorizer.EVERYWHERE, []);
const event = expectEvent.inReceipt(await tx.wait(), 'ExecutionScheduled');
const scheduledExecutionId = event.args.scheduledExecutionId;
// The adder cannot add a gauge in the controller before the delay passes.
expect(
await authorizer.canPerform(gaugeControllerAddGaugeAction, gaugeAdder.address, TimelockAuthorizer.EVERYWHERE)
).to.be.false;
await advanceTime(14 * DAY);
await authorizer.connect(lmMultisig).execute(scheduledExecutionId);
expect(await authorizer.canPerform(addFactoryAction, admin.address, TimelockAuthorizer.EVERYWHERE)).to.be.true;
expect(await authorizer.canPerform(addGaugeAction, admin.address, TimelockAuthorizer.EVERYWHERE)).to.be.true;
expect(
await authorizer.canPerform(gaugeControllerAddGaugeAction, gaugeAdder.address, TimelockAuthorizer.EVERYWHERE)
).to.be.true;
const entrypoint = await gaugeAdder.getAuthorizerAdaptorEntrypoint();
const gaugeAdderAuthorizer = await adaptorEntrypoint.getAuthorizer();
// Ensure the authorizer we just set the permissions on is the same one the gauge adder is using
expect(entrypoint).to.equal(adaptorEntrypoint.address);
expect(gaugeAdderAuthorizer).to.equal(authorizer.address);
});
it('can add factories for a gauge type', async () => {
const tx = await gaugeAdder.connect(admin).addGaugeFactory(factory.address, 2); // Ethereum is type 2
expectEvent.inReceipt(await tx.wait(), 'GaugeFactoryAdded', {
gaugeType: 2,
gaugeFactory: factory.address,
});
});
it('can add gauge to controller', async () => {
const tx = await factory.create(LP_TOKEN, weightCap);
const event = expectEvent.inReceipt(await tx.wait(), 'GaugeCreated');
gauge = await task.instanceAt('LiquidityGaugeV5', event.args.gauge);
await gaugeAdder.connect(admin).addEthereumGauge(gauge.address);
expect(await gaugeController.gauge_exists(gauge.address)).to.be.true;
});
});
});