8000 Deploy cWETHv3 to Goerli by kevincheng96 · Pull Request #646 · compound-finance/comet · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Deploy cWETHv3 to Goerli #646

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run-scenarios.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
strategy:
fail-fast: false
matrix:
bases: [ development, mainnet, mainnet-weth, goerli, fuji, mumbai ]
bases: [ development, mainnet, mainnet-weth, goerli, goerli-weth, fuji, mumbai ]
name: Run scenarios
env:
ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }}
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ These simulations are extremely useful for testing deployments before actually c
Source code verification is a relatively important part of deployments currently.
The 'spider' tool we use to crawl relevant addresses from the root addresses by default relies on pulling verified contract ABIs.
Verification happens normally as part of the deploy command-line task (the same command triggered by the `deploy-market` workflow).
Since deployments are idempotent by default, the deploy command can also be used to *just* verify the existing contracts.
Since deployments are idempotent by default, the deploy command can also be used to *just* verify the existing contracts (an explicit way to do this is via the `--no-deploy` flag).
When all contracts are already deployed, the only actions performed will be to verify the contracts remaining in the verification cache.
The script *always* attempts to verify the Comet implementation contract, since this is deployed via a factory and the status is relatively unknown to it.

Expand Down
44 changes: 44 additions & 0 deletions deployments/goerli/weth/configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "Compound WETH",
"symbol": "cWETHv3",
"baseToken": "WETH",
"baseTokenAddress": "0x42a71137C09AE83D8d05974960fd607d40033499",
"borrowMin": "0.1e18",
"governor": "0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399",
"pauseGuardian": "0x8Fa336EB4bF58Cfc508dEA1B0aeC7336f55B1399",
"storeFrontPriceFactor": 0.5,
"targetReserves": "5000e18",
"rates": {
"supplyKink": 0.9,
"supplySlopeLow": 0.01690681444,
"supplySlopeHigh": 0.6066567706,
"supplyBase": 0,
"borrowKink": 0.9,
"borrowSlopeLow": 0.05171500002,
"borrowSlopeHigh": 0.5171500339,
"borrowBase": 0.009945209674
},
"tracking": {
"indexScale": "1e15",
"baseSupplySpeed": "447916666666e0",
"baseBorrowSpeed": "0e15",
"baseMinForRewards": "1000e18"
},
"assets": {
"cbETH": {
"decimals": "18",
"borrowCF": 0.90,
"liquidateCF": 0.93,
"liquidationFactor": 0.95,
"supplyCap": "9_000e18"
},
"wstETH": {
"address": "0x4942BBAf745f235e525BAff49D31450810EDed5b",
"decimals": "18",
"borrowCF": 0.90,
"liquidateCF": 0.93,
"liquidationFactor": 0.95,
"supplyCap": "80_000e18"
}
}
}
148 changes: 148 additions & 0 deletions deployments/goerli/weth/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { Deployed, DeploymentManager } from '../../../plugins/deployment_manager';
import { debug, DeploySpec, deployComet, exp, sameAddress, wait } from '../../../src/deploy';

const clone = {
cbETHImpl: '0x31724cA0C982A31fbb5C57f4217AB585271fc9a5',
cbETHProxy: '0xBe9895146f7AF43049ca1c1AE358B0541Ea49704',
};

export default async function deploy(deploymentManager: DeploymentManager, deploySpec: DeploySpec): Promise<Deployed> {
const deployed = await deployContracts(deploymentManager, deploySpec);
await mintTokens(deploymentManager);
return deployed;
}

async function deployContracts(deploymentManager: DeploymentManager, deploySpec: DeploySpec): Promise<Deployed> {
const ethers = deploymentManager.hre.ethers;
const signer = await deploymentManager.getSigner();

// Declare existing assets as aliases
const WETH = await deploymentManager.existing('WETH', '0x42a71137C09AE83D8d05974960fd607d40033499', 'goerli');
Copy link
Contributor
@scott-silver scott-silver Jan 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like there are a number of different instances of the WETH9 contract on Goerli.

Looks like Uniswap uses 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6 on Goerli: https://docs.uniswap.org/contracts/v3/reference/deployments

Copy link
Contributor Author
@kevincheng96 kevincheng96 Jan 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, for some reason our Goerli USDC deployment has its own version of WETH. I chose to use that same WETH to be consistent.

const wstETH = await deploymentManager.existing('wstETH', '0x4942BBAf745f235e525BAff49D31450810EDed5b', 'goerli');

// Import shared contracts from cUSDCv3
const cometAdmin = await deploymentManager.fromDep('cometAdmin', 'goerli', 'usdc');
const cometFactory = await deploymentManager.fromDep('cometFactory', 'goerli', 'usdc');
const $configuratorImpl = await deploymentManager.fromDep('configurator:implementation', 'goerli', 'usdc');
const configurator = await deploymentManager.fromDep('configurator', 'goerli', 'usdc');
const rewards = await deploymentManager.fromDep('rewards', 'goerli', 'usdc');
const fauceteer = await deploymentManager.fromDep('fauceteer', 'goerli', 'usdc');
const fxRoot = await deploymentManager.fromDep('fxRoot', 'goerli', 'usdc');

// Clone cbETH
const cbETHProxyAdmin = await deploymentManager.deploy('cbETH:admin', 'vendor/proxy/transparent/ProxyAdmin.sol', []);
const cbETHImpl = await deploymentManager.clone('cbETH:implementation', clone.cbETHImpl, []);
const cbETHProxy = await deploymentManager.clone('cbETH', clone.cbETHProxy, [cbETHImpl.address]);
const cbETHProxyAdminSlot = '0x10d6a54a4754c8869d6886b5f5d7fbfa5b4522237ea5c60d11bc4e7a1ff9390b';
const cbETH = cbETHImpl.attach(cbETHProxy.address);
await deploymentManager.idempotent(
async () => !sameAddress(await ethers.provider.getStorageAt(cbETHProxy.address, cbETHProxyAdminSlot), cbETHProxyAdmin.address),
async () => {
debug(`Changing admin of cbETH proxy to ${cbETHProxyAdmin.address}`);
await wait(cbETHProxy.connect(signer).changeAdmin(cbETHProxyAdmin.address));

debug(`Initializing cbETH`);
await wait(cbETH.connect(signer).initialize(
'Coinbase Wrapped Staked ETH', // name
'cbETH', // symbol
'', // currency
18, // decimals
signer.address, // Master Minter
signer.address, // Pauser
signer.address, // Blacklister
signer.address // Owner
));
}
);

// Deploy stETH / ETH SimplePriceFeed
const stETHtoETHPriceFeed = await deploymentManager.deploy(
'stETHToETH:simplePriceFeed',
'test/SimplePriceFeed.sol',
[
exp(0.98882408, 18), // Latest answer on mainnet at block 16170924
18
]
);

// Deploy cbETH / ETH SimplePriceFeed
const cbETHtoETHPriceFeed = await deploymentManager.deploy(
'cbETHToETH:simplePriceFeed',
'test/SimplePriceFeed.sol',
[
exp(0.97, 18),
18
]
);

// Deploy WstETHPriceFeed
const wstETHPriceFeed = await deploymentManager.deploy(
'wstETH:priceFeed',
'WstETHPriceFeed.sol',
[
stETHtoETHPriceFeed.address, // stETH / ETH price feed
wstETH.address, // wstETH
8 // decimals
]
);

// Deploy constant price feed for WETH
const wethConstantPriceFeed = await deploymentManager.deploy(
'WETH:priceFeed',
'ConstantPriceFeed.sol',
[
8, // decimals
exp(1, 8) // constantPrice
]
);

// Deploy scaling price feed for cbETH
const cbETHScalingPriceFeed = await deploymentManager.deploy(
'cbETH:priceFeed',
'ScalingPriceFeed.sol',
[
cbETHtoETHPriceFeed.address, // cbETH / ETH price feed
8 // decimals
]
);

// Deploy all Comet-related contracts
const deployed = await deployComet(deploymentManager, deploySpec);
const { comet } = deployed;

// Deploy Bulker
const bulker = await deploymentManager.deploy(
'bulker',
'bulkers/MainnetBulker.sol',
[
await comet.governor(), // admin_
WETH.address, // weth_
wstETH.address // wsteth_
]
);

return { ...deployed, bulker, fauceteer, fxRoot };
}

async function mintTokens(deploymentManager: DeploymentManager) {
const signer = await deploymentManager.getSigner();
const contracts = await deploymentManager.contracts();
const fauceteer = contracts.get('fauceteer')!;

debug(`Attempting to mint as ${signer.address}...`);

// If we haven't spidered new contracts (which we could before minting, but its slow),
// then the proxy contract won't have the impl functions yet, so just do it explicitly
const cbETHProxy = contracts.get('cbETH')!, cbETHImpl = contracts.get('cbETH:implementation')!;
const cbETH = cbETHImpl.attach(cbETHProxy.address);
await deploymentManager.idempotent(
async () => (await cbETH.balanceOf(fauceteer.address)).eq(0),
async () => {
debug(`Minting 1M cbETH to fauceteer`);
const amount = exp(1_000_000, await cbETH.decimals());
await wait(cbETH.connect(signer).configureMinter(signer.address, amount));
await wait(cbETH.connect(signer).mint(fauceteer.address, amount));
debug(`cbETH.balanceOf(${fauceteer.address}): ${await cbETH.balanceOf(fauceteer.address)}`);
}
);
}
97 changes: 97 additions & 0 deletions deployments/goerli/weth/migrations/1672860425_initialize_market.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { DeploymentManager, migration } from '../../../../plugins/deployment_manager';
import { exp, getConfigurationStruct, proposal } from '../../../../src/deploy';

import { expect } from 'chai';

const COMPAddress = '0x3587b2F7E0E2D6166d6C14230e7Fe160252B0ba4';

export default migration('1672860425_initialize_market', {
prepare: async (deploymentManager: DeploymentManager) => {
return {};
},

enact: async (deploymentManager: DeploymentManager) => {
const trace = deploymentManager.tracer();

// Import shared contracts from cUSDCv3
const cometFactory = await deploymentManager.fromDep('cometFactory', 'goerli', 'usdc');

const {
governor,
comet,
configurator,
cometAdmin,
rewards,
} = await deploymentManager.getContracts();

const configuration = await getConfigurationStruct(deploymentManager);

const actions = [
// 1. Set the factory in the Configurator
{
contract: configurator,
signature: 'setFactory(address,address)',
args: [comet.address, cometFactory.address],
},

// 2. Set the configuration in the Configurator
{
contract: configurator,
signature: 'setConfiguration(address,(address,address,address,address,address,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint64,uint104,uint104,uint104,(address,address,uint8,uint64,uint64,uint64,uint128)[]))',
args: [comet.address, configuration],
},

// 3. Deploy and upgrade to a new version of Comet
{
contract: cometAdmin,
signature: "deployAndUpgradeTo(address,address)",
args: [configurator.address, comet.address],
},

// 4. Set the rewards configuration to COMP
{
contract: rewards,
signature: "setRewardConfig(address,address)",
args: [comet.address, COMPAddress],
},
];
const description = "# Initialize cWETHv3 on Goerli"
const txn = await deploymentManager.retry(
async () => trace((await governor.propose(...await proposal(actions, description))))
);

const event = txn.events.find(event => event.event === 'ProposalCreated');
const [proposalId] = event.args;

trace(`Created proposal ${proposalId}.`);
},

async enacted(deploymentManager: DeploymentManager): Promise<boolean> {
return true;
},


async verify(deploymentManager: DeploymentManager) {
const {
comet,
rewards,
wstETH,
cbETH,
} = await deploymentManager.getContracts();
// 2. & 3.
expect(await comet.baseTrackingSupplySpeed()).to.be.equal(exp(38.7 / 86400, 15, 18)); // ~ 38.7 COMP / day cut from v2
expect(await comet.baseTrackingBorrowSpeed()).to.be.equal(0);

const wstETHInfo = await comet.getAssetInfoByAddress(wstETH.address);
expect(wstETHInfo.supplyCap).to.be.equal(exp(80_000, 18)); // ~ $100M / $1225

const cbETHInfo = await comet.getAssetInfoByAddress(cbETH.address);
expect(cbETHInfo.supplyCap).to.be.equal(exp(9_000, 18)); // ~ $10M / $1091

// 4.
const config = await rewards.rewardConfig(comet.address);
expect(config.token).to.be.equal(COMPAddress);
expect(config.rescaleFactor).to.be.equal(1000000000000n);
expect(config.shouldUpscale).to.be.equal(true);
},
});
20 changes: 20 additions & 0 deletions deployments/goerli/weth/relations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import baseRelationConfig from '../../relations';

export default {
...baseRelationConfig,
'fxRoot': {
relations: {
stateSender: {
field: async (fxRoot) => fxRoot.stateSender()
}
}
},
'wstETH': {
artifact: 'contracts/bulkers/IWstETH.sol',
relations: {
stETH: {
field: async (wstETH) => wstETH.stETH()
}
}
},
};
8 changes: 8 additions & 0 deletions deployments/goerli/weth/roots.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"comet": "0x9A539EEc489AAA03D588212a164d0abdB5F08F5F",
"configurator": "0xB28495db3eC65A0e3558F040BC4f98A0d588Ae60",
"rewards": "0xef9e070044d62C38D2e316146dDe92AD02CF2c2c",
"bulker": "0x93817B582248F563D5d19923Bd5B92b045794668",
"fauceteer": "0x75442Ac771a7243433e033F3F8EaB2631e22938f",
"fxRoot": "0x3d1d3e34f7fb6d26245e6640e1c50710efff15ba"
}
9 changes: 8 additions & 1 deletion hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import './tasks/scenario/task.ts';
// Relation Config
import relationConfigMap from './deployments/relations';
import goerliRelationConfigMap from './deployments/goerli/usdc/relations';
import goerliWethRelationConfigMap from './deployments/goerli/weth/relations';
import mumbaiRelationConfigMap from './deployments/mumbai/usdc/relations';
import mainnetWethRelationConfigMap from './deployments/mainnet/weth/relations';

Expand Down Expand Up @@ -180,7 +181,8 @@ const config: HardhatUserConfig = {
relationConfigMap,
networks: {
goerli: {
usdc: goerliRelationConfigMap
usdc: goerliRelationConfigMap,
weth: goerliWethRelationConfigMap
},
mumbai: {
usdc: mumbaiRelationConfigMap
Expand Down Expand Up @@ -224,6 +226,11 @@ const config: HardhatUserConfig = {
network: 'goerli',
deployment: 'usdc'
},
{
name: 'goerli-weth',
network: 'goerli',
deployment: 'weth',
},
{
name: 'mumbai',
network: 'mumbai',
Expand Down
0