From 05b23281a737e0e1eebb939ca1eea98f4bb0b4bf Mon Sep 17 00:00:00 2001 From: traceurl <25892474+traceurl@users.noreply.github.com> Date: Fri, 26 Jan 2024 16:58:19 +0800 Subject: [PATCH] deploy to sepolia --- config/sepolia-config.ts | 33 +++ deploy/sepolia/000_deploy_contracts.ts | 257 ++++++++++++++++++++++++ deploy/sepolia/001_setting_contracts.ts | 133 ++++++++++++ hardhat.config.ts | 7 +- 4 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 config/sepolia-config.ts create mode 100644 deploy/sepolia/000_deploy_contracts.ts create mode 100644 deploy/sepolia/001_setting_contracts.ts diff --git a/config/sepolia-config.ts b/config/sepolia-config.ts new file mode 100644 index 0000000..b8c1656 --- /dev/null +++ b/config/sepolia-config.ts @@ -0,0 +1,33 @@ +const SEPOLIA_CONFIG = { + defaultAddress: { + DODOApprove: "0x66c45FF040e86DC613F239123A5E21FFdC3A3fEC", + DODOApproveProxy: "0xE2004eE21f88a7D8e1A5EDc3c9617a0460CC7b99", + DODO: "", + WETH:"0x7B07164ecFaF0F0D85DFC062Bc205a4674c75Aa0", + }, + deployedAddress: { + D3Oracle: "0xbcd2FDC3B884Cf0dfD932f55Ec2Fe1fB7e8c62Da", + D3RateManager: "0xB5c7BA1EAde74800cD6cf5F56b1c4562De373780", + D3MMLiquidationRouter: "0x45b3Be51c0C6d8C621C883F36A63340D365565f5", + D3Vault: "0x63D34E9bA393a21f2aD9F3e24Ba4607D21BB365D", + D3UserQuota: "0xb57C5EECa0f3f8DBfa3202352080265FC325e8f4", + D3PoolQuota: "0x628E5081bA93b1c4F58E54e7175088B1ACe58852", + D3MMTemplate: "0x7dEdA1C0996e9A2Dd80C8Ff9b6C5406BBa1BDb9d", + D3MakerTemplate: "0xee7210fc88E1FFdB6aFb305E8F68b4f1d20FEdAd", + D3TokenTemplate: "0xc3cF2F9faAeE87b67E4ceAb3F67B6074Ae939cF3", + CloneFactory: "0x8414560d69650bC0c915d5d4385e1714a23cbe81", + Maintainer: "0xb37136B338C6cC0E459A35fe9Aa036f6b5A147c0", + D3FeeRateModel: "0x44023441f2Bad375b6b5C6354B03c3E9AD01E269", + D3MMFactory: "0xC6a85A0e8cAe3eADB1307056209E851643F32Fce", + D3Proxy: "0xF0a6A2cEb71Ed90b4E61f15BB36751d9a21eBfB6", // don't forget to add this to DODOApproveProxy + D3MM: "", + }, + chainlinkPriceFeed: { + BTC_USD: "0x1b44F3514812d835EB1BDB0acB33d3fA3351Ee43", + DAI_USD: "0x14866185B1962B63C3Ea9E03Bc1da838bab34C19", + ETH_USD: "0x694AA1769357215DE4FAC081bf1f309aDC325306", + USDC_USD: "0xA2F78ab2355fe2f984D808B5CeE7FD0A93D5270E", + }, +}; + +export { SEPOLIA_CONFIG }; diff --git a/deploy/sepolia/000_deploy_contracts.ts b/deploy/sepolia/000_deploy_contracts.ts new file mode 100644 index 0000000..8daf65a --- /dev/null +++ b/deploy/sepolia/000_deploy_contracts.ts @@ -0,0 +1,257 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { SEPOLIA_CONFIG as config } from "../../config/sepolia-config"; +import { BigNumber } from "@ethersproject/bignumber"; +import * as dotenv from 'dotenv'; +dotenv.config(); + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { deployments, getNamedAccounts, ethers } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + await main(); + + async function main() { + // await deployD3Oracle(true); + // await deployD3RateManager(false); + // await deployFeeRateModel(true); + // await deployLiquidatorAdapter(); + // await deployD3PoolQuota(); + // await deployD3Vault(true); + // await depolyD3MMFactory(); + // await deployD3Proxy(); + // await deployD3UserQuota(); + } + + async function deployContract(name: string, contract: string, args?: any[]) { + if (typeof args == 'undefined') { + args = [] + } + if (!config.deployedAddress[name] || config.deployedAddress[name] == "") { + console.log("Deploying contract:", name); + const deployResult = await deploy(contract, { + from: deployer, + args: args, + log: true, + }); + await verifyContract(deployResult.address, args); + return deployResult.address; + } else { + console.log("Fetch previous deployed address for", name, config.deployedAddress[name]); + return config.deployedAddress[name]; + } + } + + async function verifyContract(address: string, args?: any[]) { + if (typeof args == 'undefined') { + args = [] + } + try { + await hre.run("verify:verify", { + address: address, + constructorArguments: args, + }); + } catch (e) { + if (e.message != "Contract source code already verified") { + throw(e) + } + console.log(e.message) + } + } + + async function deployD3Oracle(shouldSet: boolean) { + const oracleAddress = await deployContract("D3Oracle", "D3Oracle", []); + if (shouldSet) { + const D3Oracle = await ethers.getContractAt("D3Oracle", oracleAddress); + + const priceSourceWBTC = { + oracle: config.chainlinkPriceFeed.WBTC_USD, + isWhitelisted: true, + priceTolerance: BigNumber.from(padZeros(9, 17)), + priceDecimal: 8, + tokenDecimal: 8, + heartBeat: 100000 + } + console.log("setPriceSource for WBTC...") + await D3Oracle.setPriceSource(config.defaultAddress.WBTC, priceSourceWBTC); + + const priceSourceBTC = { + oracle: config.chainlinkPriceFeed.BTC_USD, + isWhitelisted: true, + priceTolerance: BigNumber.from(padZeros(9, 17)), + priceDecimal: 8, + tokenDecimal: 8, + heartBeat: 100000 + } + console.log("setPriceSource for BTC...") + await D3Oracle.setPriceSource(config.defaultAddress.BTCb, priceSourceBTC); + + const priceSourceETH = { + oracle: config.chainlinkPriceFeed.ETH_USD, + isWhitelisted: true, + priceTolerance: BigNumber.from(padZeros(9, 17)), + priceDecimal: 8, + tokenDecimal: 18, + heartBeat: 100000 + } + console.log("setPriceSource for ETH...") + await D3Oracle.setPriceSource(config.defaultAddress.WETH, priceSourceETH); + + const priceSourceUSDT = { + oracle: config.chainlinkPriceFeed.USDT_USD, + isWhitelisted: true, + priceTolerance: BigNumber.from(padZeros(9, 17)), + priceDecimal: 8, + tokenDecimal: 6, + heartBeat: 100000 + } + console.log("setPriceSource for USDT...") + await D3Oracle.setPriceSource(config.defaultAddress.USDT, priceSourceUSDT); + + console.log("setPriceSource for USDTe...") + await D3Oracle.setPriceSource(config.defaultAddress.USDTe, priceSourceUSDT); + + const priceSourceUSDC = { + oracle: config.chainlinkPriceFeed.USDC_USD, + isWhitelisted: true, + priceTolerance: BigNumber.from(padZeros(9, 17)), + priceDecimal: 8, + tokenDecimal: 6, + heartBeat: 100000 + } + console.log("setPriceSource for USDC...") + await D3Oracle.setPriceSource(config.defaultAddress.USDC, priceSourceUSDC); + + const priceSourceAVAX = { + oracle: config.chainlinkPriceFeed.AVAX_USD, + isWhitelisted: true, + priceTolerance: BigNumber.from(padZeros(9, 17)), + priceDecimal: 8, + tokenDecimal: 18, + heartBeat: 100000 + } + console.log("setPriceSource for AVAX...") + await D3Oracle.setPriceSource(config.defaultAddress.WAVAX, priceSourceAVAX); + + } + } + + async function deployD3RateManager(shouldSet: boolean) { + const rateManagerAddress = await deployContract("D3RateManager", "D3RateManager", []); + if (shouldSet) { + const D3RateManager = await ethers.getContractAt("D3RateManager", rateManagerAddress); + + console.log("setStableCurve for WBTC...") + await D3RateManager.setStableCurve(config.defaultAddress.WBTC, padZeros(20, 16), padZeros(1, 18), padZeros(2, 18), padZeros(80, 16)); + + console.log("setStableCurve for BTC...") + await D3RateManager.setStableCurve(config.defaultAddress.BTCb, padZeros(20, 16), padZeros(1, 18), padZeros(2, 18), padZeros(80, 16)); + + console.log("setStableCurve for ETH...") + await D3RateManager.setStableCurve(config.defaultAddress.WETH, padZeros(20, 16), padZeros(1, 18), padZeros(2, 18), padZeros(80, 16)); + + console.log("setStableCurve for USDT...") + await D3RateManager.setStableCurve(config.defaultAddress.USDT, padZeros(20, 16), padZeros(1, 18), padZeros(2, 18), padZeros(80, 16)); + + console.log("setStableCurve for USDTe...") + await D3RateManager.setStableCurve(config.defaultAddress.USDTe, padZeros(20, 16), padZeros(1, 18), padZeros(2, 18), padZeros(80, 16)); + + console.log("setStableCurve for USDC...") + await D3RateManager.setStableCurve(config.defaultAddress.USDC, padZeros(20, 16), padZeros(1, 18), padZeros(2, 18), padZeros(80, 16)); + + console.log("setStableCurve for WAVAX...") + await D3RateManager.setStableCurve(config.defaultAddress.WAVAX, padZeros(20, 16), padZeros(1, 18), padZeros(2, 18), padZeros(80, 16)); + } + } + + async function deployFeeRateModel(shouldSet: boolean) { + const feeRateModelAddress = await deployContract("D3FeeRateModel", "D3FeeRateModel"); + if (shouldSet) { + const D3FeeRateModel = await ethers.getContractAt("D3FeeRateModel", feeRateModelAddress); + + console.log("init D3FeeRateModel...") + await D3FeeRateModel.init(deployer, 0); + } + } + + async function deployLiquidatorAdapter() { + await deployContract("D3MMLiquidationRouter", "D3MMLiquidationRouter", [config.defaultAddress.DODOApprove]); + } + + async function deployD3PoolQuota() { + await deployContract("D3PoolQuota", "D3PoolQuota", []); + } + + async function deployD3Vault(shouldSet: boolean) { + const vaultAddress = await deployContract("D3Vault", "D3Vault", []); + const dTokenAddress = await deployContract("D3TokenTemplate", "D3Token") + if (shouldSet) { + const D3Vault = await ethers.getContractAt("D3Vault", vaultAddress); + console.log("set CloneFactory address...") + await D3Vault.setCloneFactory(config.deployedAddress.CloneFactory); + console.log("set D3Token template...") + await D3Vault.setDTokenTemplate(dTokenAddress); + console.log("set D3Oracle address...") + await D3Vault.setNewOracle(config.deployedAddress.D3Oracle); + console.log("set D3PoolQuota address...") + await D3Vault.setNewD3PoolQuota(config.deployedAddress.D3PoolQuota); + console.log("set D3RateManager address...") + await D3Vault.setNewRateManager(config.deployedAddress.D3RateManager); + console.log("set maintainer address...") + await D3Vault.setMaintainer(deployer); + } + } + + async function depolyD3MMFactory() { + const d3MMTemplate = await deployContract("D3MMTemplate", "D3MM", []); + const d3MakerTemplate = await deployContract("D3MakerTemplate", "D3Maker", []); + const cloneFactory = config.deployedAddress.CloneFactory; + const d3Vault = config.deployedAddress.D3Vault; + const oracle = config.deployedAddress.D3Oracle; + const feeModel = config.deployedAddress.D3FeeRateModel; + const maintainer = config.deployedAddress.Maintainer; + + const args = [ + deployer, + [d3MMTemplate], + [d3MakerTemplate], + cloneFactory, + d3Vault, + oracle, + feeModel, + maintainer + ]; + const d3MMFactory = await deployContract("D3MMFactory", "D3MMFactory", args); + await verifyContract(d3MMFactory, args) + } + + async function deployD3Proxy() { + const vault = config.deployedAddress.D3Vault + console.log("vault", vault) + const dodoApproveProxy = config.defaultAddress.DODOApproveProxy + console.log("approve proxy", dodoApproveProxy) + const weth = config.defaultAddress.WETH + console.log("weth", weth) + const proxyAddress = await deployContract("D3Proxy", "D3Proxy", [dodoApproveProxy, weth, vault]) + await verifyContract(proxyAddress, [dodoApproveProxy, weth, vault]) + } + + async function deployD3UserQuota() { + const vToken = config.defaultAddress.WETH + const vault = config.deployedAddress.D3Vault + await deployContract("D3UserQuota", "D3UserQuota", [vToken, vault]) + } + + // ---------- helper function ---------- + + function padZeros(origin: number, count: number) { + return origin.toString() + '0'.repeat(count); + } + + function sleep(s) { + return new Promise(resolve => setTimeout(resolve, s * 1000)); + } +}; + +export default func; \ No newline at end of file diff --git a/deploy/sepolia/001_setting_contracts.ts b/deploy/sepolia/001_setting_contracts.ts new file mode 100644 index 0000000..474224e --- /dev/null +++ b/deploy/sepolia/001_setting_contracts.ts @@ -0,0 +1,133 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { DeployFunction } from "hardhat-deploy/types"; +import { SEPOLIA_CONFIG as config } from "../../config/sepolia-config"; +import { BigNumber } from "@ethersproject/bignumber"; +import * as dotenv from 'dotenv'; +dotenv.config(); + +const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + const { deployments, getNamedAccounts, ethers } = hre; + const { deploy } = deployments; + const { deployer } = await getNamedAccounts(); + + // await main(); + + async function main() { + await setD3Vault(true) + } + + async function setD3Vault(shouldSet: boolean) { + const vaultAddress = config.deployedAddress.D3Vault + if (shouldSet) { + const D3Vault = await ethers.getContractAt("D3Vault", vaultAddress) + console.log("set D3UserQuota address...") + await D3Vault.setNewD3UserQuota(config.deployedAddress.D3UserQuota) + console.log("set IM...") + await D3Vault.setIM(bignumberFromE(40e16)) + console.log("set MM...") + await D3Vault.setMM(bignumberFromE(20e16)) + console.log("add liquidation router...") + await D3Vault.addRouter(config.deployedAddress.D3MMLiquidationRouter) + console.log("add liquidator...") + await D3Vault.addLiquidator(process.env.LIQUIDATOR3) + console.log("set D3Factory...") + await D3Vault.setNewD3Factory(config.deployedAddress.D3MMFactory) + + console.log("addNewToken BTC...") + await D3Vault.addNewToken( + config.defaultAddress.BTCb, + bignumberFromE(1000e8), + bignumberFromE(500e8), + bignumberFromE(90e16), + bignumberFromE(110e16), + bignumberFromE(10e16) + ) + + console.log("addNewToken WBTC...") + await D3Vault.addNewToken( + config.defaultAddress.WBTC, + bignumberFromE(1000e8), + bignumberFromE(500e8), + bignumberFromE(90e16), + bignumberFromE(110e16), + bignumberFromE(10e16) + ) + + console.log("addNewToken WETH...") + await D3Vault.addNewToken( + config.defaultAddress.WETH, + bignumberFromE(10000e18), + bignumberFromE(5000e18), + bignumberFromE(90e16), + bignumberFromE(110e16), + bignumberFromE(10e16) + ) + + console.log("addNewToken USDT...") + await D3Vault.addNewToken( + config.defaultAddress.USDT, + bignumberFromE(10000000e6), + bignumberFromE(500000e6), + bignumberFromE(90e16), + bignumberFromE(110e16), + bignumberFromE(10e16) + ) + + console.log("addNewToken USDTe...") + await D3Vault.addNewToken( + config.defaultAddress.USDTe, + bignumberFromE(10000000e6), + bignumberFromE(500000e6), + bignumberFromE(90e16), + bignumberFromE(110e16), + bignumberFromE(10e16) + ) + + console.log("addNewToken USDC...") + await D3Vault.addNewToken( + config.defaultAddress.USDC, + bignumberFromE(10000000e6), + bignumberFromE(500000e6), + bignumberFromE(90e16), + bignumberFromE(110e16), + bignumberFromE(10e16) + ) + + console.log("addNewToken WAVAX...") + await D3Vault.addNewToken( + config.defaultAddress.WAVAX, + bignumberFromE(100000e18), + bignumberFromE(50000e18), + bignumberFromE(90e16), + bignumberFromE(110e16), + bignumberFromE(10e16) + ) + } + } + + // ---------- helper function ---------- + function bignumberFromE(num) { + let s = String(num) + if (/\d+\.?\d*e[\+\-]*\d+/i.test(s)) { + let parts = s.split('e') + console.log('parts', parts) + let r = parts[0] + let l = Math.abs(parts.pop()) + let combine = r + new Array(l + 1).join('0') + console.log(combine) + return BigNumber.from(combine); + } else { + return BigNumber.from(String(num)); + } + } + + function padZeros(origin: number, count: number) { + return origin.toString() + '0'.repeat(count); + } + + function sleep(s) { + return new Promise(resolve => setTimeout(resolve, s * 1000)); + } +}; + +export default func; diff --git a/hardhat.config.ts b/hardhat.config.ts index 5caf634..8e4c16d 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -71,6 +71,11 @@ const config: HardhatUserConfig = { chainId: 5, deploy: ["./deploy/goerli/"], }, + sepolia: { + url: TRUFFLE_DASHBOARD_RPC, + chainId: 11155111, + deploy: ["./deploy/sepolia/"], + }, arbitrum: { url: TRUFFLE_DASHBOARD_RPC, chainId: 42161, @@ -127,10 +132,10 @@ const config: HardhatUserConfig = { // API key for Etherscan. https://etherscan.io/ apiKey: { mainnet: process.env.ETHERSCAN_API_KEY ?? '', - eth: process.env.ETHERSCAN_API_KEY ?? '', bsc: process.env.BSCSCAN_API_KEY ?? '', arbi_testnet: process.env.ARBITRUM_TESTNET_API_KEY ?? '', goerli: process.env.GOERLI_API_KEY ?? '', + sepolia: process.env.SEPOLIA_API_KEY ?? '', kcc: process.env.KCC_API_KEY ?? '', arbitrumOne: process.env.ARBITRUM_API_KEY ?? '', polygon: process.env.POLYGON_API_KEY ?? '',