forked from compound-finance/comet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGovernanceScenario.ts
154 lines (133 loc) · 7.23 KB
/
GovernanceScenario.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
import { scenario } from './context/CometContext';
import { expect } from 'chai';
import { BigNumberish, constants, utils } from 'ethers';
import { exp } from '../test/helpers';
import { FaucetToken } from '../build/types';
import { calldata } from '../src/deploy';
import { expectBase, isBridgedDeployment } from './utils';
scenario('upgrade Comet implementation and initialize', {filter: async (ctx) => !isBridgedDeployment(ctx)}, async ({ comet, configurator, proxyAdmin }, context) => {
// For this scenario, we will be using the value of LiquidatorPoints.numAbsorbs for address ZERO to test that initialize has been called
expect((await comet.liquidatorPoints(constants.AddressZero)).numAbsorbs).to.be.equal(0);
// Deploy new version of Comet Factory
const dm = context.world.deploymentManager;
const cometModifiedFactory = await dm.deploy('cometFactory', 'test/CometModifiedFactory.sol', [], true);
// Execute a governance proposal to:
// 1. Set the new factory address in Configurator
// 2. Deploy and upgrade to the new implementation of Comet
// 3. Call initialize(address) on the new version of Comet
const setFactoryCalldata = utils.defaultAbiCoder.encode(['address', 'address'], [comet.address, cometModifiedFactory.address]);
const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode(['address', 'address'], [configurator.address, comet.address]);
const initializeCalldata = utils.defaultAbiCoder.encode(['address'], [constants.AddressZero]);
await context.fastGovernanceExecute(
[configurator.address, proxyAdmin.address, comet.address],
[0, 0, 0],
['setFactory(address,address)', 'deployAndUpgradeTo(address,address)', 'initialize(address)'],
[setFactoryCalldata, deployAndUpgradeToCalldata, initializeCalldata]
);
// LiquidatorPoints.numAbsorbs for address ZERO should now be set as UInt32.MAX
expect((await comet.liquidatorPoints(constants.AddressZero)).numAbsorbs).to.be.equal(2 ** 32 - 1);
});
scenario('upgrade Comet implementation and initialize using deployUpgradeToAndCall', {filter: async (ctx) => !isBridgedDeployment(ctx)}, async ({ comet, configurator, proxyAdmin }, context) => {
// For this scenario, we will be using the value of LiquidatorPoints.numAbsorbs for address ZERO to test that initialize has been called
expect((await comet.liquidatorPoints(constants.AddressZero)).numAbsorbs).to.be.equal(0);
// Deploy new version of Comet Factory
const dm = context.world.deploymentManager;
const cometModifiedFactory = await dm.deploy(
'cometFactory',
'test/CometModifiedFactory.sol',
[],
true
);
// Execute a governance proposal to:
// 1. Set the new factory address in Configurator
// 2. DeployUpgradeToAndCall the new implementation of Comet
const setFactoryCalldata = utils.defaultAbiCoder.encode(['address', 'address'], [comet.address, cometModifiedFactory.address]);
const modifiedComet = (await dm.hre.ethers.getContractFactory('CometModified')).attach(comet.address);
const initializeCalldata = (await modifiedComet.populateTransaction.initialize(constants.AddressZero)).data;
const deployUpgradeToAndCallCalldata = utils.defaultAbiCoder.encode(['address', 'address', 'bytes'], [configurator.address, comet.address, initializeCalldata]);
await context.fastGovernanceExecute(
[configurator.address, proxyAdmin.address],
[0, 0],
['setFactory(address,address)', 'deployUpgradeToAndCall(address,address,bytes)'],
[setFactoryCalldata, deployUpgradeToAndCallCalldata]
);
// LiquidatorPoints.numAbsorbs for address ZERO should now be set as UInt32.MAX
expect((await comet.liquidatorPoints(constants.AddressZero)).numAbsorbs).to.be.equal(2 ** 32 - 1);
});
scenario('upgrade Comet implementation and call new function', {filter: async (ctx) => !isBridgedDeployment(ctx)}, async ({ comet, configurator, proxyAdmin, actors }, context) => {
const { signer } = actors;
// Deploy new version of Comet Factory
const dm = context.world.deploymentManager;
const cometModifiedFactory = await dm.deploy('cometFactory', 'test/CometModifiedFactory.sol', [], true);
// Upgrade Comet implementation
const setFactoryCalldata = utils.defaultAbiCoder.encode(['address', 'address'], [comet.address, cometModifiedFactory.address]);
const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode(['address', 'address'], [configurator.address, comet.address]);
await context.fastGovernanceExecute(
[configurator.address, proxyAdmin.address],
[0, 0],
['setFactory(address,address)', 'deployAndUpgradeTo(address,address)'],
[setFactoryCalldata, deployAndUpgradeToCalldata]
);
const CometModified = await dm.hre.ethers.getContractFactory('CometModified');
const modifiedComet = CometModified.attach(comet.address).connect(signer.signer);
// Call new functions on Comet
await modifiedComet.initialize(constants.AddressZero);
expect(await modifiedComet.newFunction()).to.be.equal(101n);
});
scenario('add new asset',
{
filter: async (ctx) => !isBridgedDeployment(ctx),
tokenBalances: {
$comet: { $base: '>= 1000' },
},
prices: {
$base: 1
}
},
async ({ comet, configurator, proxyAdmin, actors }, context) => {
const { albert } = actors;
// Deploy new token and pricefeed
const dm = context.world.deploymentManager;
const dogecoin = await dm.deploy<FaucetToken, [string, string, BigNumberish, string]>(
'DOGE',
'test/FaucetToken.sol',
[exp(1_000_000, 8).toString(), 'Dogecoin', 8, 'DOGE'],
true
);
const dogecoinPricefeed = await dm.deploy(
'DOGE:priceFeed',
'test/SimplePriceFeed.sol',
[exp(1_000, 8).toString(), 8],
true
);
// Allocate some tokens to Albert
await dogecoin.allocateTo(albert.address, exp(100, 8));
// Execute a governance proposal to:
// 1. Add new asset via Configurator
// 2. Deploy and upgrade to new implementation of Comet
const newAssetConfig = {
asset: dogecoin.address,
priceFeed: dogecoinPricefeed.address,
decimals: await dogecoin.decimals(),
borrowCollateralFactor: exp(0.8, 18),
liquidateCollateralFactor: exp(0.85, 18),
liquidationFactor: exp(0.95, 18),
supplyCap: exp(1_000, 8),
};
const addAssetCalldata = await calldata(configurator.populateTransaction.addAsset(comet.address, newAssetConfig));
const deployAndUpgradeToCalldata = utils.defaultAbiCoder.encode(['address', 'address'], [configurator.address, comet.address]);
await context.fastGovernanceExecute(
[configurator.address, proxyAdmin.address],
[0, 0],
['addAsset(address,(address,address,uint8,uint64,uint64,uint64,uint128))', 'deployAndUpgradeTo(address,address)'],
[addAssetCalldata, deployAndUpgradeToCalldata]
);
// Try to supply new token and borrow base
const baseAssetAddress = await comet.baseToken();
const borrowAmount = 1000n * (await comet.baseScale()).toBigInt();
await dogecoin.connect(albert.signer).approve(comet.address, exp(100, 8));
await albert.supplyAsset({ asset: dogecoin.address, amount: exp(100, 8) });
await albert.withdrawAsset({ asset: baseAssetAddress, amount: borrowAmount });
expect(await albert.getCometCollateralBalance(dogecoin.address)).to.be.equal(exp(100, 8));
expectBase(await albert.getCometBaseBalance(), -borrowAmount);
});