diff --git a/deployments/hardhat/usdt/configuration.json b/deployments/hardhat/usdt/configuration.json new file mode 100644 index 000000000..bd2be60fd --- /dev/null +++ b/deployments/hardhat/usdt/configuration.json @@ -0,0 +1,26 @@ +{ + "name": "Compound USDT", + "symbol": "cUSDTv3", + "baseToken": "USDT", + "borrowMin": "100e6", + "storeFrontPriceFactor": 0.5, + "targetReserves": "5000000e6", + "rates": { + "supplyKink": 0.8, + "supplySlopeLow": 0.0325, + "supplySlopeHigh": 0.4, + "supplyBase": 0, + "borrowKink": 0.8, + "borrowSlopeLow": 0.035, + "borrowSlopeHigh": 0.25, + "borrowBase": 0.015 + }, + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "0", + "baseBorrowSpeed": "0", + "baseMinForRewards": "1000000e6" + }, + "rewardToken": "COMP", + "assets": {} +} diff --git a/deployments/hardhat/usdt/deploy.ts b/deployments/hardhat/usdt/deploy.ts new file mode 100644 index 000000000..c1229950b --- /dev/null +++ b/deployments/hardhat/usdt/deploy.ts @@ -0,0 +1,155 @@ +import { + Deployed, + DeploymentManager +} from '../../../plugins/deployment_manager'; +import { FaucetToken, SimplePriceFeed } from '../../../build/types'; +import { + DeploySpec, + cloneGov, + deployComet, + exp, + sameAddress, + wait +} from '../../../src/deploy'; + +async function makeToken( + deploymentManager: DeploymentManager, + amount: number, + name: string, + decimals: number, + symbol: string +): Promise { + const mint = (BigInt(amount) * 10n ** BigInt(decimals)).toString(); + return deploymentManager.deploy(symbol, 'test/FaucetToken.sol', [ + mint, + name, + decimals, + symbol + ]); +} + +async function makePriceFeed( + deploymentManager: DeploymentManager, + alias: string, + initialPrice: number, + decimals: number +): Promise { + return deploymentManager.deploy(alias, 'test/SimplePriceFeed.sol', [ + initialPrice * 1e8, + decimals + ]); +} + +// TODO: Support configurable assets as well? +export default async function deploy( + deploymentManager: DeploymentManager, + deploySpec: DeploySpec +): Promise { + const trace = deploymentManager.tracer(); + const ethers = deploymentManager.hre.ethers; + const signer = await deploymentManager.getSigner(); + + // Deploy governance contracts + const { fauceteer, governor, timelock } = await cloneGov(deploymentManager); + + const USDT = await makeToken(deploymentManager, 10000000, 'USDT', 18, 'USDT'); + const COMP = await makeToken(deploymentManager, 20000000, 'COMP', 8, 'COMP'); + const WETH = await makeToken(deploymentManager, 30000000, 'WETH', 10, 'WETH'); + + const usdtPriceFeed = await makePriceFeed( + deploymentManager, + 'USDT:priceFeed', + 1, + 8 + ); + const compPriceFeed = await makePriceFeed( + deploymentManager, + 'COMP:priceFeed', + 0.5, + 8 + ); + const wethPriceFeed = await makePriceFeed( + deploymentManager, + 'WETH:priceFeed', + 0.05, + 8 + ); + + const assetConfig0 = { + asset: COMP.address, + priceFeed: compPriceFeed.address, + decimals: (18).toString(), + borrowCollateralFactor: (0.65e18).toString(), + liquidateCollateralFactor: (0.7e18).toString(), + liquidationFactor: (0.93e18).toString(), + supplyCap: (10000000e8).toString() + }; + + const assetConfig1 = { + asset: WETH.address, + priceFeed: wethPriceFeed.address, + decimals: (18).toString(), + borrowCollateralFactor: (0.825e18).toString(), + liquidateCollateralFactor: (0.895e18).toString(), + liquidationFactor: (0.95e18).toString(), + supplyCap: (10000000e8).toString() + }; + + // Deploy all Comet-related contracts + let rewards; + try { + const deployed = await deployComet(deploymentManager, deploySpec, { + baseTokenPriceFeed: usdtPriceFeed.address, + assetConfigs: [assetConfig0, assetConfig1] + }); + rewards = deployed.rewards; + } catch (e) { + console.error(e); + return; + } + + await deploymentManager.idempotent( + async () => (await COMP.balanceOf(rewards.address)).eq(0), + async () => { + trace(`Sending some COMP to CometRewards`); + const amount = exp(2_000_000, 8); + trace(await wait(COMP.connect(signer).transfer(rewards.address, amount))); + trace( + `COMP.balanceOf(${rewards.address}): ${await COMP.balanceOf( + rewards.address + )}` + ); + } + ); + + // Mint some tokens + trace(`Attempting to mint as ${signer.address}...`); + + await Promise.all( + [ + [USDT, 1e8], + [COMP, 2e6], + [WETH, 1e7] + ].map(([asset, units]) => { + return deploymentManager.idempotent( + async () => (await asset.balanceOf(fauceteer.address)).eq(0), + async () => { + trace(`Minting ${units} ${await asset.symbol()} to fauceteer`); + const amount = exp(units, await asset.decimals()); + trace( + await wait( + asset.connect(signer).allocateTo(fauceteer.address, amount) + ) + ); + trace( + `asset.balanceOf(${signer.address}): ${await asset.balanceOf( + signer.address + )}` + ); + } + ); + }) + ); + + return { ...deployed, fauceteer }; +} diff --git a/deployments/hardhat/usdt/roots.json b/deployments/hardhat/usdt/roots.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/deployments/hardhat/usdt/roots.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/deployments/mainnet/usdt/configuration.json b/deployments/mainnet/usdt/configuration.json new file mode 100644 index 000000000..b3c419fd4 --- /dev/null +++ b/deployments/mainnet/usdt/configuration.json @@ -0,0 +1,77 @@ +{ + "name": "Compound USDT", + "symbol": "cUSDTv3", + "baseToken": "USDT", + "baseTokenAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "baseTokenPriceFeed": "0x3E7d1eAB13ad0104d2750B8863b489D65364e32D", + "borrowMin": "100e6", + "governor": "0x6d903f6003cca6255d85cca4d3b5e5146dc33925", + "pauseGuardian": "0xbbf3f1421d886e9b2c5d716b5192ac998af2012c", + "storeFrontPriceFactor": 0.5, + "targetReserves": "5000000e6", + "rates": { + "supplyKink": 0.8, + "supplySlopeLow": 0.0325, + "supplySlopeHigh": 0.4, + "supplyBase": 0, + "borrowKink": 0.8, + "borrowSlopeLow": 0.035, + "borrowSlopeHigh": 0.25, + "borrowBase": 0.015 + }, + "rewardToken": "COMP", + "rewardTokenAddress": "0xc00e94cb662c3520282e6f5717214004a7f26888", + "tracking": { + "indexScale": "1e15", + "baseSupplySpeed": "0", + "baseBorrowSpeed": "0", + "baseMinForRewards": "1000000e6" + }, + "assets": { + "COMP": { + "address": "0xc00e94cb662c3520282e6f5717214004a7f26888", + "priceFeed": "0xdbd020CAeF83eFd542f4De03e3cF0C28A4428bd5", + "decimals": "18", + "borrowCF": 0.65, + "liquidateCF": 0.70, + "liquidationFactor": 0.93, + "supplyCap": "0e18" + }, + "WBTC": { + "address": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", + "priceFeed": "0xF4030086522a5bEEa4988F8cA5B36dbC97BeE88c", + "decimals": "8", + "borrowCF": 0.70, + "liquidateCF": 0.77, + "liquidationFactor": 0.95, + "supplyCap": "0e8" + }, + "WETH": { + "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", + "priceFeed": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419", + "decimals": "18", + "borrowCF": 0.825, + "liquidateCF": 0.895, + "liquidationFactor": 0.95, + "supplyCap": "0e18" + }, + "UNI": { + "address": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984", + "priceFeed": "0x553303d460EE0afB37EdFf9bE42922D8FF63220e", + "decimals": "18", + "borrowCF": 0.75, + "liquidateCF": 0.81, + "liquidationFactor": 0.93, + "supplyCap": "0e18" + }, + "LINK": { + "address": "0x514910771af9ca656af840dff83e8264ecf986ca", + "priceFeed": "0x2c1d072e956AFFC0D435Cb7AC38EF18d24d9127c", + "decimals": "18", + "borrowCF": 0.79, + "liquidateCF": 0.85, + "liquidationFactor": 0.93, + "supplyCap": "0e18" + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/usdt/deploy.ts b/deployments/mainnet/usdt/deploy.ts new file mode 100644 index 000000000..76c1be8c8 --- /dev/null +++ b/deployments/mainnet/usdt/deploy.ts @@ -0,0 +1,19 @@ +import { Deployed, DeploymentManager } from '../../../plugins/deployment_manager'; +import { debug, DeploySpec, deployComet, exp, sameAddress, wait } from '../../../src/deploy'; + +export default async function deploy(deploymentManager: DeploymentManager, deploySpec: DeploySpec): Promise { + const USDT = await deploymentManager.existing('USDT', '0xdAC17F958D2ee523a2206206994597C13D831ec7'); + const WBTC = await deploymentManager.existing('WBTC', '0x2260fac5e5542a773aa44fbcfedf7c193bc2c599'); + const WETH = await deploymentManager.existing('WETH', '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2'); + const COMP = await deploymentManager.existing('COMP', '0xc00e94cb662c3520282e6f5717214004a7f26888'); + const LINK = await deploymentManager.existing('LINK', '0x514910771af9ca656af840dff83e8264ecf986ca'); + const UNI = await deploymentManager.existing('UNI', '0x1f9840a85d5af5bf1d1762f925bdaddc4201f984'); + + // Deploy all Comet-related contracts + const deployed = await deployComet(deploymentManager, deploySpec); + + // Get Bulker + const bulker = await deploymentManager.fromDep('bulker', 'mainnet', 'usdc'); + + return { ...deployed, bulker }; +} diff --git a/deployments/mainnet/usdt/relations.ts b/deployments/mainnet/usdt/relations.ts new file mode 100644 index 000000000..60b2c24d1 --- /dev/null +++ b/deployments/mainnet/usdt/relations.ts @@ -0,0 +1,5 @@ +import baseRelationConfig from '../../relations'; + +export default { + ...baseRelationConfig +};