-
Notifications
You must be signed in to change notification settings - Fork 168
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
kevincheng96
merged 8 commits into
jflatow/mainnet-eth-live
from
kevin/goerli-weth-deploy
Jan 17, 2023
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
5e866c0
Deploy script for cWETHv3 goerli
kevincheng96 f2cc1d5
Increase amount of cbETH minted to 1mn
kevincheng96 f8d46fd
Update interest rate params
kevincheng96 f8d5db8
Use existing WETH
kevincheng96 65c9dac
No longer spider from deploy script
kevincheng96 0c7a5fc
Update roots after deploy
kevincheng96 5887907
Proposal to enable cWETHv3 market on Goerli (#647)
kevincheng96 10a3eec
Add missing await
kevincheng96 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | ||
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_ | ||
jflatow marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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()); | ||
kevincheng96 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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
97
deployments/goerli/weth/migrations/1672860425_initialize_market.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
}, | ||
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} | ||
} | ||
}, | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
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/deploymentsThere was a problem hiding this comment.
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.