Skip to content
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

Deploy DAI Mainnet market #879

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
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, mainnet-usdt, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, polygon-usdt, arbitrum-usdc.e, arbitrum-usdc, arbitrum-weth, arbitrum-usdt, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, optimism-usdt, optimism-weth, scroll-goerli, scroll-usdc]
bases: [ development, mainnet, mainnet-weth, mainnet-usdt, mainnet-dai, goerli, goerli-weth, sepolia-usdc, sepolia-weth, fuji, mumbai, polygon, polygon-usdt, arbitrum-usdc.e, arbitrum-usdc, arbitrum-weth, arbitrum-usdt, arbitrum-goerli-usdc, arbitrum-goerli-usdc.e, base-usdbc, base-weth, base-usdc, base-goerli, base-goerli-weth, linea-goerli, optimism-usdc, optimism-usdt, optimism-weth, scroll-goerli, scroll-usdc]
name: Run scenarios
env:
ETHERSCAN_KEY: ${{ secrets.ETHERSCAN_KEY }}
Expand Down
66 changes: 66 additions & 0 deletions deployments/mainnet/dai/configuration.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"name": "Compound DAI",
"symbol": "cDAIv3",
"baseToken": "DAI",
"baseTokenAddress": "0x6B175474E89094C44Da98b954EedeAC495271d0F",
"baseTokenPriceFeed": "0xAed0c38402a5d19df6E4c03F4E2DceD6e29c1ee9",
"borrowMin": "100e18",
"governor": "0x6d903f6003cca6255d85cca4d3b5e5146dc33925",
"pauseGuardian": "0xbbf3f1421d886e9b2c5d716b5192ac998af2012c",
"storeFrontPriceFactor": 0.6,
"targetReserves": "20000000e18",
"rates": {
"supplyBase": 0,
"supplySlopeLow": 0.069,
"supplyKink": 0.85,
"supplySlopeHigh": 3.2,
"borrowBase": 0.015,
"borrowSlopeLow": 0.081,
"borrowKink": 0.85,
"borrowSlopeHigh": 4.2
},
"tracking": {
"indexScale": "1e15",
"baseSupplySpeed": "0e15",
"baseBorrowSpeed": "0e15",
"baseMinForRewards": "100000e18"
},
"rewardTokenAddress": "0xc00e94Cb662C3520282E6f5717214004A7f26888",
"assets": {
"USDe": {
"address": "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3",
"priceFeed": "0xa569d910839Ae8865Da8F8e70FfFb0cBA869F961",
"decimals": "18",
"borrowCF": 0.70,
"liquidateCF": 0.75,
"liquidationFactor": 0.85,
"supplyCap": "0e18"
},
"WETH": {
"address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"priceFeed": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419",
"decimals": "18",
"borrowCF": 0.83,
"liquidateCF": 0.9,
"liquidationFactor": 0.95,
"supplyCap": "0e18"
},
"WBTC": {
"address": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
"decimals": "8",
"borrowCF": 0.80,
"liquidateCF": 0.85,
"liquidationFactor": 0.95,
"supplyCap": "0e8"
},
"sUSDe": {
"address": "0x9D39A5DE30e57443BfF2A8307A4256c8797A3497",
"priceFeed": "0xFF3BC18cCBd5999CE63E788A1c250a88626aD099",
"decimals": "18",
"borrowCF": 0.70,
"liquidateCF": 0.75,
"liquidationFactor": 0.85,
"supplyCap": "0e18"
}
}
}
37 changes: 37 additions & 0 deletions deployments/mainnet/dai/deploy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Deployed, DeploymentManager } from '../../../plugins/deployment_manager';
import { DeploySpec, deployComet } from '../../../src/deploy';

export default async function deploy(deploymentManager: DeploymentManager, deploySpec: DeploySpec): Promise<Deployed> {
const DAI = await deploymentManager.existing('DAI', '0x6B175474E89094C44Da98b954EedeAC495271d0F');
const WBTC = await deploymentManager.existing('WBTC', '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599');
const WETH = await deploymentManager.existing('WETH', '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2');
const USDe = await deploymentManager.existing('USDe', '0x4c9EDD5852cd905f086C759E8383e09bff1E68B3');
const sUSDe = await deploymentManager.existing('sUSDe', '0x9D39A5DE30e57443BfF2A8307A4256c8797A3497');
const COMP = await deploymentManager.existing('COMP', '0xc00e94Cb662C3520282E6f5717214004A7f26888');

const wbtcScalingPriceFeed = await deploymentManager.deploy(
'WBTC:priceFeed',
'pricefeeds/WBTCPriceFeed.sol',
[
'0xfdFD9C85aD200c506Cf9e21F1FD8dd01932FBB23', // WBTC / BTC price feed
'0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c', // BTC / USD price feed
8 // decimals
]
);

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

// Deploy Comet
const deployed = await deployComet(deploymentManager, deploySpec);
return {
...deployed,
bulker,
rewards,
COMP
};
}
249 changes: 249 additions & 0 deletions deployments/mainnet/dai/migrations/1719910152_configurate_and_ens.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
import { ethers, utils } from 'ethers';
import { DeploymentManager } from '../../../../plugins/deployment_manager/DeploymentManager';
import { migration } from '../../../../plugins/deployment_manager/Migration';
import { exp, getConfigurationStruct, proposal } from '../../../../src/deploy';
import { expect } from 'chai';

const ENSName = 'compound-community-licenses.eth';
const ENSResolverAddress = '0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41';
const ENSRegistryAddress = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e';
const ENSSubdomainLabel = 'v3-additional-grants';
const ENSSubdomain = `${ENSSubdomainLabel}.${ENSName}`;
const ENSTextRecordKey = 'v3-official-markets';

const cDAIAddress = '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643';
const NEW_FACTORY_ADDRESS = '0x698A949f3b4f7a5DdE236106F25Fa0eAcA0FcEF1';
const DAIAmount = ethers.BigNumber.from(exp(200_000, 18));

export default migration('1719910152_configurate_and_ens', {
async prepare() {
return {};
},

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

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

const configuration = await getConfigurationStruct(deploymentManager);

const ENSResolver = await deploymentManager.existing('ENSResolver', ENSResolverAddress);
const subdomainHash = ethers.utils.namehash(ENSSubdomain);
const currentChainId = 1;
const newMarketObject = { baseSymbol: 'DAI', cometAddress: comet.address };
const officialMarketsJSON = JSON.parse(await ENSResolver.text(subdomainHash, ENSTextRecordKey));

if (officialMarketsJSON[currentChainId]) {
officialMarketsJSON[currentChainId].push(newMarketObject);
} else {
officialMarketsJSON[currentChainId] = [newMarketObject];
}

const _reduceReservesCalldata = utils.defaultAbiCoder.encode(
['uint256'],
[DAIAmount]
);

const actions = [
// 1. Set Comet factory
{
contract: configurator,
signature: 'setFactory(address,address)',
args: [comet.address, NEW_FACTORY_ADDRESS],
},
// 2. Set the Comet configuration
{
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 Comet and upgrade it to the new implementation
{
contract: cometAdmin,
signature: 'deployAndUpgradeTo(address,address)',
args: [configurator.address, comet.address],
},
// 4. Set the reward configuration
{
contract: rewards,
signature: 'setRewardConfig(address,address)',
args: [comet.address, COMP.address],
},
// 5. Get DAI reserves from cDAI contract
{
target: cDAIAddress,
signature: '_reduceReserves(uint256)',
calldata: _reduceReservesCalldata
},
// 6. Transfer DAI to the Comet contract
{
contract: DAI,
signature: 'transfer(address,uint256)',
args: [comet.address, DAIAmount],
},
// 7. Update the list of official markets
{
target: ENSResolverAddress,
signature: 'setText(bytes32,string,string)',
calldata: ethers.utils.defaultAbiCoder.encode(
['bytes32', 'string', 'string'],
[subdomainHash, ENSTextRecordKey, JSON.stringify(officialMarketsJSON)]
)
}
];

const description = '# Initialize cDAIv3 on Ethereum Mainnet\n\n## Proposal summary\n\nCompound Growth Program [AlphaGrowth] proposes the deployment of Compound III to the Mainnet network. This proposal takes the governance steps recommended and necessary to initialize a Compound III DAI market on Mainnet; upon execution, cDAIv3 will be ready for use. Simulations have confirmed the market’s readiness, as much as possible, using the [Comet scenario suite](https://github.com/compound-finance/comet/tree/main/scenario). The new parameters include setting the risk parameters based off of the [recommendations from Gauntlet](https://www.comp.xyz/t/gauntlet-dai-v3-comet-on-mainnet-recommendation/5380/1).\n\nFurther detailed information can be found on the corresponding [proposal pull request](https://github.com/compound-finance/comet/pull/879), [deploy market GitHub action run](<>) and [forum discussion](https://www.comp.xyz/t/gauntlet-dai-v3-comet-on-mainnet-recommendation/5380).\n\n\n## Proposal Actions\n\nThe first proposal action sets the CometFactory for the new Comet instance in the existing Configurator.\n\nThe second action configures the Comet instance in the Configurator.\n\nThe third action deploys an instance of the newly configured factory and upgrades the Comet instance to use that implementation.\n\nThe fourth action configures the existing rewards contract for the newly deployed Comet instance.\n\nThe fifth action reduces Compound’s [cDAI](https://etherscan.io/address/0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643) reserves and transfers it to Timelock, in order to seed the market reserves for the cDAIv3 Comet.\n\nThe sixth action transfers reserves from Timelock to the cDAIv3 Comet.\n\nThe seventh action updates the ENS TXT record `v3-official-markets` on `v3-additional-grants.compound-community-licenses.eth`, updating the official markets JSON to include the new Ethereum Mainnet cDAIv3 market.';
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(): Promise<boolean> {
return false;
},

async verify(deploymentManager: DeploymentManager) {

const {
comet,
rewards,
timelock,
COMP,
WBTC,
WETH,
USDe,
sUSDe
} = await deploymentManager.getContracts();

// 1. & 2. & 3
const wbtcInfo = await comet.getAssetInfoByAddress(WBTC.address);
const wethInfo = await comet.getAssetInfoByAddress(WETH.address);
const usdeInfo = await comet.getAssetInfoByAddress(USDe.address);
const susdeInfo = await comet.getAssetInfoByAddress(sUSDe.address);

// expect(wbtcInfo.borrowCap).to.be.eq(exp(7_200, 8));
// expect(wethInfo.borrowCap).to.be.eq(exp(175_000 , 18));
// expect(usdeInfo.supplyCap).to.be.eq(exp(66_000_000, 18));
// expect(susdeInfo.borrowCap).to.be.eq(exp(35_000_000, 18));

// expect(await comet.baseTrackingSupplySpeed()).to.be.equal(exp(25 / 86400, 15, 18)); // 289351851851
// expect(await comet.baseTrackingBorrowSpeed()).to.be.equal(exp(15 / 86400, 15, 18)); // 173611111111

// 4.
const config = await rewards.rewardConfig(comet.address);
expect(config.token).to.be.equal(COMP.address);
expect(config.rescaleFactor).to.be.equal(exp(1, 12));
expect(config.shouldUpscale).to.be.equal(true);

expect((await comet.pauseGuardian()).toLowerCase()).to.be.eq('0xbbf3f1421d886e9b2c5d716b5192ac998af2012c');

// 5. & 6.
expect(await comet.getReserves()).to.be.equal(DAIAmount);

// 7.
const ENSResolver = await deploymentManager.existing('ENSResolver', ENSResolverAddress);
const ENSRegistry = await deploymentManager.existing('ENSRegistry', ENSRegistryAddress);
const subdomainHash = ethers.utils.namehash(ENSSubdomain);
const officialMarketsJSON = await ENSResolver.text(subdomainHash, ENSTextRecordKey);
const officialMarkets = JSON.parse(officialMarketsJSON);
expect(await ENSRegistry.recordExists(subdomainHash)).to.be.equal(true);
expect(await ENSRegistry.owner(subdomainHash)).to.be.equal(timelock.address);
expect(await ENSRegistry.resolver(subdomainHash)).to.be.equal(ENSResolverAddress);
expect(await ENSRegistry.ttl(subdomainHash)).to.be.equal(0);
expect(officialMarkets).to.deep.equal({
1: [
{
baseSymbol: 'USDC',
cometAddress: '0xc3d688B66703497DAA19211EEdff47f25384cdc3',
},
{
baseSymbol: 'WETH',
cometAddress: '0xA17581A9E3356d9A858b789D68B4d866e593aE94',
},
{
baseSymbol: 'USDT',
cometAddress: '0x3Afdc9BCA9213A35503b077a6072F3D0d5AB0840',
},
{
baseSymbol: 'DAI',
cometAddress: comet.address,
}
],
10: [
{
baseSymbol: 'USDC',
cometAddress: '0x2e44e174f7D53F0212823acC11C01A11d58c5bCB'
},
{
baseSymbol: 'USDT',
cometAddress: '0x995E394b8B2437aC8Ce61Ee0bC610D617962B214'
},
{
baseSymbol: 'WETH',
cometAddress: '0xE36A30D249f7761327fd973001A32010b521b6Fd'
}
],
137: [
{
baseSymbol: 'USDC',
cometAddress: '0xF25212E676D1F7F89Cd72fFEe66158f541246445'
},
{
baseSymbol: 'USDT',
cometAddress: '0xaeB318360f27748Acb200CE616E389A6C9409a07'
}
],
8453: [
{
baseSymbol: 'USDbC',
cometAddress: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf',
},
{
baseSymbol: 'WETH',
cometAddress: '0x46e6b214b524310239732D51387075E0e70970bf',
},
{
baseSymbol: 'USDC',
cometAddress: '0xb125E6687d4313864e53df431d5425969c15Eb2F',
}
],
42161: [
{
baseSymbol: 'USDC.e',
cometAddress: '0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA',
},
{
baseSymbol: 'USDC',
cometAddress: '0x9c4ec768c28520B50860ea7a15bd7213a9fF58bf',
},
{
baseSymbol: 'WETH',
cometAddress: '0x6f7D514bbD4aFf3BcD1140B7344b32f063dEe486'
},
{
baseSymbol: 'USDT',
cometAddress: '0xd98Be00b5D27fc98112BdE293e487f8D4cA57d07'
}
],
534352: [
{
baseSymbol: 'USDC',
cometAddress: '0xB2f97c1Bd3bf02f5e74d13f02E3e26F93D77CE44',
}
]
});
}
});
18 changes: 18 additions & 0 deletions deployments/mainnet/dai/relations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { RelationConfigMap } from '../../../plugins/deployment_manager/RelationConfig';
import baseRelationConfig from '../../relations';

export default {
...baseRelationConfig,
'AppProxyUpgradeable': {
artifact: 'contracts/ERC20.sol:ERC20',
},
'sUSDe': {
artifact: 'contracts/ERC20.sol:ERC20',
},
'USDe': {
artifact: 'contracts/ERC20.sol:ERC20',
},
'DAI': {
artifact: 'contracts/ERC20.sol:ERC20',
},
};
1 change: 1 addition & 0 deletions deployments/mainnet/dai/roots.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
Loading