diff --git a/scripts/deploy.ts b/scripts/deploy.ts index 8cf827c408..3e0aeaa224 100644 --- a/scripts/deploy.ts +++ b/scripts/deploy.ts @@ -72,7 +72,11 @@ async function main() { 'phase2-assets/collaterals/deploy_yearn_v2_curve_usdc.ts', 'phase2-assets/collaterals/deploy_yearn_v2_curve_usdp.ts', 'phase2-assets/collaterals/deploy_sfrax.ts', - 'phase2-assets/collaterals/deploy_sfrax_eth.ts' + 'phase2-assets/collaterals/deploy_sfrax_eth.ts', + 'phase2-assets/collaterals/deploy_steakusdc.ts', + 'phase2-assets/collaterals/deploy_steakpyusd.ts', + 'phase2-assets/collaterals/deploy_bbusdt.ts', + 'phase2-assets/collaterals/deploy_re7weth.ts' ) } else if (chainId == '8453' || chainId == '84531') { // Base L2 chains diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_bbusdt.ts b/scripts/deployment/phase2-assets/collaterals/deploy_bbusdt.ts new file mode 100644 index 0000000000..034a22aa52 --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_bbusdt.ts @@ -0,0 +1,91 @@ +import fs from 'fs' +import hre from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { networkConfig } from '../../../../common/configuration' +import { fp } from '../../../../common/numbers' +import { expect } from 'chai' +import { CollateralStatus } from '../../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + getDeploymentFilename, + fileExists, +} from '../../common' +import { + USDT_ORACLE_TIMEOUT, + USDT_ORACLE_ERROR, + USDT_USD_FEED, + PRICE_TIMEOUT, + DELAY_UNTIL_DEFAULT, +} from '../../../../test/plugins/individual-collateral/meta-morpho/constants' +import { MetaMorphoFiatCollateral } from '../../../../typechain' +import { ContractFactory } from 'ethers' + +async function main() { + // ==== Read Configuration ==== + const [deployer] = await hre.ethers.getSigners() + + const chainId = await getChainId(hre) + + console.log(`Deploying Collateral to network ${hre.network.name} (${chainId}) + with burner account: ${deployer.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + /******** Deploy MetaMorpho Flagship USDT - bbUSDT **************************/ + + const MetaMorphoFiatCollateralFactory: ContractFactory = await hre.ethers.getContractFactory( + 'MetaMorphoFiatCollateral' + ) + + const collateral = await MetaMorphoFiatCollateralFactory.connect( + deployer + ).deploy( + { + priceTimeout: PRICE_TIMEOUT.toString(), + chainlinkFeed: USDT_USD_FEED, + oracleError: USDT_ORACLE_ERROR.toString(), + erc20: networkConfig[chainId].tokens.bbUSDT, + maxTradeVolume: fp('0.5e6').toString(), // $7.5m vault + oracleTimeout: USDT_ORACLE_TIMEOUT.toString(), + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: USDT_ORACLE_ERROR.add(fp('0.01')).toString(), // +1% buffer rule + delayUntilDefault: DELAY_UNTIL_DEFAULT.toString(), + }, + fp('1e-6') // small admin fee uncertainty + ) + await collateral.deployed() + + console.log(`Deployed bbUSDT to ${hre.network.name} (${chainId}): ${collateral.address}`) + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + assetCollDeployments.collateral.bbUSDT = collateral.address + assetCollDeployments.erc20s.bbUSDT = networkConfig[chainId].tokens.bbUSDT + deployedCollateral.push(collateral.address.toString()) + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed collateral to ${hre.network.name} (${chainId}) + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_re7weth.ts b/scripts/deployment/phase2-assets/collaterals/deploy_re7weth.ts new file mode 100644 index 0000000000..717ae7d328 --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_re7weth.ts @@ -0,0 +1,91 @@ +import fs from 'fs' +import hre from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { networkConfig } from '../../../../common/configuration' +import { fp } from '../../../../common/numbers' +import { expect } from 'chai' +import { CollateralStatus } from '../../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + getDeploymentFilename, + fileExists, +} from '../../common' +import { + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, + ETH_USD_FEED, + PRICE_TIMEOUT, + DELAY_UNTIL_DEFAULT, +} from '../../../../test/plugins/individual-collateral/meta-morpho/constants' +import { MetaMorphoSelfReferentialCollateral } from '../../../../typechain' +import { ContractFactory } from 'ethers' + +async function main() { + // ==== Read Configuration ==== + const [deployer] = await hre.ethers.getSigners() + + const chainId = await getChainId(hre) + + console.log(`Deploying Collateral to network ${hre.network.name} (${chainId}) + with burner account: ${deployer.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + /******** Deploy MetaMorpho RE7 Labs ETH - Re7WETH **************************/ + + const MetaMorphoFiatCollateralFactory: ContractFactory = await hre.ethers.getContractFactory( + 'MetaMorphoSelfReferentialCollateral' + ) + + const collateral = ( + await MetaMorphoFiatCollateralFactory.connect(deployer).deploy( + { + priceTimeout: PRICE_TIMEOUT.toString(), + chainlinkFeed: ETH_USD_FEED, + oracleError: ETH_ORACLE_ERROR.toString(), + erc20: networkConfig[chainId].tokens.Re7WETH, + maxTradeVolume: fp('1e6').toString(), // $12m vault + oracleTimeout: ETH_ORACLE_TIMEOUT.toString(), + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: ETH_ORACLE_ERROR.add(fp('0.01')).toString(), // +1% buffer rule + delayUntilDefault: DELAY_UNTIL_DEFAULT.toString(), + }, + fp('1e-6') // small admin fee uncertainty + ) + ) + await collateral.deployed() + + console.log(`Deployed Re7WETH to ${hre.network.name} (${chainId}): ${collateral.address}`) + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + assetCollDeployments.collateral.Re7WETH = collateral.address + assetCollDeployments.erc20s.Re7WETH = networkConfig[chainId].tokens.Re7WETH + deployedCollateral.push(collateral.address.toString()) + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed collateral to ${hre.network.name} (${chainId}) + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_steakpyusd.ts b/scripts/deployment/phase2-assets/collaterals/deploy_steakpyusd.ts new file mode 100644 index 0000000000..f796086e9d --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_steakpyusd.ts @@ -0,0 +1,91 @@ +import fs from 'fs' +import hre from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { networkConfig } from '../../../../common/configuration' +import { fp } from '../../../../common/numbers' +import { expect } from 'chai' +import { CollateralStatus } from '../../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + getDeploymentFilename, + fileExists, +} from '../../common' +import { + PYUSD_ORACLE_TIMEOUT, + PYUSD_ORACLE_ERROR, + PYUSD_USD_FEED, + PRICE_TIMEOUT, + DELAY_UNTIL_DEFAULT, +} from '../../../../test/plugins/individual-collateral/meta-morpho/constants' +import { MetaMorphoFiatCollateral } from '../../../../typechain' +import { ContractFactory } from 'ethers' + +async function main() { + // ==== Read Configuration ==== + const [deployer] = await hre.ethers.getSigners() + + const chainId = await getChainId(hre) + + console.log(`Deploying Collateral to network ${hre.network.name} (${chainId}) + with burner account: ${deployer.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + /******** Deploy MetaMorpho Steakhouse PYUSD - steakPYUSD **************************/ + + const MetaMorphoFiatCollateralFactory: ContractFactory = await hre.ethers.getContractFactory( + 'MetaMorphoFiatCollateral' + ) + + const collateral = await MetaMorphoFiatCollateralFactory.connect( + deployer + ).deploy( + { + priceTimeout: PRICE_TIMEOUT.toString(), + chainlinkFeed: PYUSD_USD_FEED, + oracleError: PYUSD_ORACLE_ERROR.toString(), + erc20: networkConfig[chainId].tokens.steakPYUSD, + maxTradeVolume: fp('0.25e6').toString(), // $1.7m vault + oracleTimeout: PYUSD_ORACLE_TIMEOUT.toString(), + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: PYUSD_ORACLE_ERROR.add(fp('0.01')).toString(), // +1% buffer rule + delayUntilDefault: DELAY_UNTIL_DEFAULT.toString(), + }, + fp('1e-6') // small admin fee uncertainty + ) + await collateral.deployed() + + console.log(`Deployed steakPYUSD to ${hre.network.name} (${chainId}): ${collateral.address}`) + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + assetCollDeployments.collateral.steakPYUSD = collateral.address + assetCollDeployments.erc20s.steakPYUSD = networkConfig[chainId].tokens.steakPYUSD + deployedCollateral.push(collateral.address.toString()) + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed collateral to ${hre.network.name} (${chainId}) + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/deployment/phase2-assets/collaterals/deploy_steakusdc.ts b/scripts/deployment/phase2-assets/collaterals/deploy_steakusdc.ts new file mode 100644 index 0000000000..5d8ae1a02a --- /dev/null +++ b/scripts/deployment/phase2-assets/collaterals/deploy_steakusdc.ts @@ -0,0 +1,91 @@ +import fs from 'fs' +import hre from 'hardhat' +import { getChainId } from '../../../../common/blockchain-utils' +import { networkConfig } from '../../../../common/configuration' +import { fp } from '../../../../common/numbers' +import { expect } from 'chai' +import { CollateralStatus } from '../../../../common/constants' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, + getDeploymentFilename, + fileExists, +} from '../../common' +import { + USDC_ORACLE_TIMEOUT, + USDC_ORACLE_ERROR, + USDC_USD_FEED, + PRICE_TIMEOUT, + DELAY_UNTIL_DEFAULT, +} from '../../../../test/plugins/individual-collateral/meta-morpho/constants' +import { MetaMorphoFiatCollateral } from '../../../../typechain' +import { ContractFactory } from 'ethers' + +async function main() { + // ==== Read Configuration ==== + const [deployer] = await hre.ethers.getSigners() + + const chainId = await getChainId(hre) + + console.log(`Deploying Collateral to network ${hre.network.name} (${chainId}) + with burner account: ${deployer.address}`) + + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + // Get phase1 deployment + const phase1File = getDeploymentFilename(chainId) + if (!fileExists(phase1File)) { + throw new Error(`${phase1File} doesn't exist yet. Run phase 1`) + } + // Check previous step completed + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + const assetCollDeployments = getDeploymentFile(assetCollDeploymentFilename) + + const deployedCollateral: string[] = [] + + /******** Deploy MetaMorpho Steakhouse USDC - steakUSDC **************************/ + + const MetaMorphoFiatCollateralFactory: ContractFactory = await hre.ethers.getContractFactory( + 'MetaMorphoFiatCollateral' + ) + + const collateral = await MetaMorphoFiatCollateralFactory.connect( + deployer + ).deploy( + { + priceTimeout: PRICE_TIMEOUT.toString(), + chainlinkFeed: USDC_USD_FEED, + oracleError: USDC_ORACLE_ERROR.toString(), + erc20: networkConfig[chainId].tokens.steakUSDC, + maxTradeVolume: fp('1e6').toString(), // 17m vault + oracleTimeout: USDC_ORACLE_TIMEOUT.toString(), + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: USDC_ORACLE_ERROR.add(fp('0.01')).toString(), // +1% buffer rule + delayUntilDefault: DELAY_UNTIL_DEFAULT.toString(), + }, + fp('1e-6') // small admin fee uncertainty + ) + await collateral.deployed() + + console.log(`Deployed steakUSDC to ${hre.network.name} (${chainId}): ${collateral.address}`) + await (await collateral.refresh()).wait() + expect(await collateral.status()).to.equal(CollateralStatus.SOUND) + + assetCollDeployments.collateral.steakUSDC = collateral.address + assetCollDeployments.erc20s.steakUSDC = networkConfig[chainId].tokens.steakUSDC + deployedCollateral.push(collateral.address.toString()) + + fs.writeFileSync(assetCollDeploymentFilename, JSON.stringify(assetCollDeployments, null, 2)) + + console.log(`Deployed collateral to ${hre.network.name} (${chainId}) + New deployments: ${deployedCollateral} + Deployment file: ${assetCollDeploymentFilename}`) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verification/collateral-plugins/verify_re7weth.ts b/scripts/verification/collateral-plugins/verify_re7weth.ts new file mode 100644 index 0000000000..8d695a08ec --- /dev/null +++ b/scripts/verification/collateral-plugins/verify_re7weth.ts @@ -0,0 +1,60 @@ +import hre from 'hardhat' +import { getChainId } from '../../../common/blockchain-utils' +import { developmentChains, networkConfig } from '../../../common/configuration' +import { fp } from '../../../common/numbers' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, +} from '../../deployment/common' +import { + ETH_ORACLE_TIMEOUT, + ETH_ORACLE_ERROR, + ETH_USD_FEED, + PRICE_TIMEOUT, + DELAY_UNTIL_DEFAULT, +} from '../../../test/plugins/individual-collateral/meta-morpho/constants' +import { verifyContract } from '../../deployment/utils' + +let deployments: IAssetCollDeployments + +async function main() { + // ********** Read config ********** + const chainId = await getChainId(hre) + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + if (developmentChains.includes(hre.network.name)) { + throw new Error(`Cannot verify contracts for development chain ${hre.network.name}`) + } + + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + deployments = getDeploymentFile(assetCollDeploymentFilename) + + /******** Verify Re7WETH **************************/ + await verifyContract( + chainId, + deployments.collateral.Re7WETH, + [ + { + priceTimeout: PRICE_TIMEOUT.toString(), + chainlinkFeed: ETH_USD_FEED, + oracleError: ETH_ORACLE_ERROR.toString(), + erc20: networkConfig[chainId].tokens.Re7WETH, + maxTradeVolume: fp('1e6').toString(), + oracleTimeout: ETH_ORACLE_TIMEOUT.toString(), + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: ETH_ORACLE_ERROR.add(fp('0.01')).toString(), // +1% buffer rule + delayUntilDefault: DELAY_UNTIL_DEFAULT.toString(), + }, + fp('1e-6'), // small admin fee uncertainty + ], + 'contracts/plugins/assets/meta-morpho/MetaMorphoSelfReferentialCollateral.sol:MetaMorphoSelfReferentialCollateral' + ) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verification/collateral-plugins/verify_steakusdc.ts b/scripts/verification/collateral-plugins/verify_steakusdc.ts new file mode 100644 index 0000000000..277f30b6af --- /dev/null +++ b/scripts/verification/collateral-plugins/verify_steakusdc.ts @@ -0,0 +1,60 @@ +import hre from 'hardhat' +import { getChainId } from '../../../common/blockchain-utils' +import { developmentChains, networkConfig } from '../../../common/configuration' +import { fp } from '../../../common/numbers' +import { + getDeploymentFile, + getAssetCollDeploymentFilename, + IAssetCollDeployments, +} from '../../deployment/common' +import { + USDC_ORACLE_TIMEOUT, + USDC_ORACLE_ERROR, + USDC_USD_FEED, + PRICE_TIMEOUT, + DELAY_UNTIL_DEFAULT, +} from '../../../test/plugins/individual-collateral/meta-morpho/constants' +import { verifyContract } from '../../deployment/utils' + +let deployments: IAssetCollDeployments + +async function main() { + // ********** Read config ********** + const chainId = await getChainId(hre) + if (!networkConfig[chainId]) { + throw new Error(`Missing network configuration for ${hre.network.name}`) + } + + if (developmentChains.includes(hre.network.name)) { + throw new Error(`Cannot verify contracts for development chain ${hre.network.name}`) + } + + const assetCollDeploymentFilename = getAssetCollDeploymentFilename(chainId) + deployments = getDeploymentFile(assetCollDeploymentFilename) + + /******** Verify steakUSDC **************************/ + await verifyContract( + chainId, + deployments.collateral.steakUSDC, + [ + { + priceTimeout: PRICE_TIMEOUT.toString(), + chainlinkFeed: USDC_USD_FEED, + oracleError: USDC_ORACLE_ERROR.toString(), + erc20: networkConfig[chainId].tokens.steakUSDC, + maxTradeVolume: fp('1e6').toString(), + oracleTimeout: USDC_ORACLE_TIMEOUT.toString(), + targetName: hre.ethers.utils.formatBytes32String('USD'), + defaultThreshold: USDC_ORACLE_ERROR.add(fp('0.01')).toString(), // +1% buffer rule + delayUntilDefault: DELAY_UNTIL_DEFAULT.toString(), + }, + fp('1e-6'), // small admin fee uncertainty + ], + 'contracts/plugins/assets/meta-morpho/MetaMorphoFiatCollateral.sol:MetaMorphoFiatCollateral' + ) +} + +main().catch((error) => { + console.error(error) + process.exitCode = 1 +}) diff --git a/scripts/verify_etherscan.ts b/scripts/verify_etherscan.ts index 13ddca24b3..36f8fdd53f 100644 --- a/scripts/verify_etherscan.ts +++ b/scripts/verify_etherscan.ts @@ -71,7 +71,9 @@ async function main() { 'collateral-plugins/verify_yearn_v2_curve_usdc.ts', 'collateral-plugins/verify_yearn_v2_curve_usdp.ts', 'collateral-plugins/verify_sfrax.ts', - 'collateral-plugins/verify_sfrax_eth.ts' + 'collateral-plugins/verify_sfrax_eth.ts', + 'collateral-plugins/verify_steakusdc.ts', + 'collateral-plugins/verify_re7weth.ts' ) } else if (chainId == '8453' || chainId == '84531') { // Base L2 chains