diff --git a/packages/hardhat/hardhat.config.ts b/packages/hardhat/hardhat.config.ts index a5e12196c..801445d35 100644 --- a/packages/hardhat/hardhat.config.ts +++ b/packages/hardhat/hardhat.config.ts @@ -19,6 +19,8 @@ import './tasks/addWethLiquidity' import './tasks/buySqueeth' import './tasks/buyWeth' import './tasks/increaseSlot' +import './tasks/openShortVault' +import './tasks/checkVaultStatus' // Load env variables dotenv.config() diff --git a/packages/hardhat/tasks/checkVaultStatus.ts b/packages/hardhat/tasks/checkVaultStatus.ts new file mode 100644 index 000000000..2b3b26f5b --- /dev/null +++ b/packages/hardhat/tasks/checkVaultStatus.ts @@ -0,0 +1,18 @@ +import { task, types } from "hardhat/config"; +import "@nomiclabs/hardhat-waffle"; + +// Example execution +/** + npx hardhat checkVaultStatus --input '0' --network ropsten + */ +task("checkVaultStatus", "Check if vault is liquidatable") + .addParam('input', 'vault id', 0, types.string) + .setAction(async ({ input: vaultId }, hre) => { + + const { getNamedAccounts, ethers, network } = hre; + const { deployer } = await getNamedAccounts(); + const controller = await ethers.getContract("Controller", deployer); + + const isVaultSafe = await controller.isVaultSafe(vaultId) + console.log(`Whether inputted vault is safe: `, isVaultSafe) + }); diff --git a/packages/hardhat/tasks/openShortVault.ts b/packages/hardhat/tasks/openShortVault.ts new file mode 100644 index 000000000..a698836b0 --- /dev/null +++ b/packages/hardhat/tasks/openShortVault.ts @@ -0,0 +1,43 @@ +import { task, types } from "hardhat/config"; +import "@nomiclabs/hardhat-waffle"; +import { BigNumber } from "ethers"; +import { getController, getEthUSDCPool, getOracle, getUSDC, getWETH } from "./utils"; + +export const one = BigNumber.from(10).pow(18) + +// Example execution +/** + npx hardhat openShortVault --input 50 --network ropsten + */ +task("openShortVault", "Add a short position with a 150% collateralization ratio") + .addParam('input', 'amount squeeth to mint', 50, types.string) + .setAction(async ({ input: squeethToMint }, hre) => { + + const { getNamedAccounts, ethers, network } = hre; + const { deployer } = await getNamedAccounts(); + const controller = await getController(ethers, deployer, network.name) + const oracle = await getOracle(ethers, deployer, network.name) + const ethUsdcPool = await getEthUSDCPool(ethers, deployer, network.name) + const weth = await getWETH(ethers, deployer, network.name) + const usdc = await getUSDC(ethers, deployer, network.name) + const ethPrice = await oracle.getTwap(ethUsdcPool.address, weth.address, usdc.address, 420, true) + const normFactor = await controller.normalizationFactor() + const debtAmount = ethers.utils.parseUnits(squeethToMint) + const mintRSqueethAmount = debtAmount.mul(normFactor).div(one) + const scaledEthPrice = ethPrice.div(10000) + const debtInEth = mintRSqueethAmount.mul(scaledEthPrice).div(one) + const collateralToDeposit = debtInEth.mul(3).div(2) + + const shortPowerPerp = await ethers.getContractAt("ShortPowerPerp", (await controller.shortPowerPerp())) + const oldVaultId = shortPowerPerp.nextId() + let oldVaultIdInt; + oldVaultId.then((value: any) => { + oldVaultIdInt = value.toNumber() + }).catch((err: any) => { + console.log(err); + }); + const newVaultId = oldVaultIdInt ? (oldVaultId + 1): null + const tx = await controller.mintWPowerPerpAmount(0, debtAmount, 0, {value: collateralToDeposit}) + await ethers.provider.waitForTransaction(tx.hash, 1) + console.log(`Added 150% collateralization vault with ID: `, newVaultId) + }); diff --git a/packages/hardhat/tasks/utils.ts b/packages/hardhat/tasks/utils.ts index 8479c8006..29df76ff9 100644 --- a/packages/hardhat/tasks/utils.ts +++ b/packages/hardhat/tasks/utils.ts @@ -1,4 +1,7 @@ import { Contract } from "ethers" +import { + abi as POOL_ABI, +} from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json' export const networkNameToUniRouter = (name: string) => { switch (name) { @@ -51,6 +54,33 @@ export const networkNameToWeth = (name: string) => { } } +export const networkNameToOracle = (name: string) => { + switch (name) { + case 'mainnet': return '0x65D66c76447ccB45dAf1e8044e918fA786A483A1' + case 'ropsten': return '0xBD9F4bE886653177D22fA9c79FD0DFc41407fC89' + case 'rinkebyArbitrum': return '0xe790Afe86c0bdc4Dd7C6CBb7dB087552Ec85F6fB' + default: return undefined + } +} + +export const networkNameToController = (name: string) => { + switch (name) { + case 'mainnet': return '0x64187ae08781B09368e6253F9E94951243A493D5' + case 'ropsten': return '0x59F0c781a6eC387F09C40FAA22b7477a2950d209' + case 'rinkebyArbitrum': return '0x6FBbc7eBd7E421839915e8e4fAcC9947dC32F4dE' + default: return undefined + } +} + +export const networkNameToEthUSDCPool = (name: string) => { + switch (name) { + case 'mainnet': return '0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8' + case 'ropsten': return '0x8356AbC730a218c24446C2c85708F373f354F0D8' + case 'rinkebyArbitrum': return '0xe7715b01a0B16E3e38A7d9b78F6Bd2b163D7f319' + default: return undefined + } +} + export const getWETH = async (ethers: any, deployer: string, networkName: string)=> { const wethAddr = networkNameToWeth(networkName) if (wethAddr === undefined) { @@ -58,7 +88,37 @@ export const getWETH = async (ethers: any, deployer: string, networkName: string return ethers.getContract("WETH9", deployer); } // get contract instance at address - return ethers.getContract('WETH9', wethAddr) + return ethers.getContractAt('WETH9', wethAddr) +} + +export const getOracle = async (ethers: any, deployer: string, networkName: string)=> { + const oracleAddr = networkNameToOracle(networkName) + if (oracleAddr === undefined) { + // get from deployed network + return ethers.getContract("Oracle", deployer); + } + // get contract instance at address + return ethers.getContractAt('Oracle', oracleAddr) +} + +export const getController = async (ethers: any, deployer: string, networkName: string)=> { + const controllerAddr = networkNameToController(networkName) + if (controllerAddr === undefined) { + // get from deployed network + return ethers.getContract("Controller", deployer); + } + // get contract instance at address + return ethers.getContractAt('Controller', controllerAddr) +} + +export const getEthUSDCPool = async (ethers: any, deployer: string, networkName: string)=> { + const ethUSDCPoolAddress = networkNameToEthUSDCPool(networkName) + if (ethUSDCPoolAddress === undefined) { + // get from deployed network + return ethers.getContract(POOL_ABI, deployer); + } + // get contract instance at address + return ethers.getContractAt(POOL_ABI, ethUSDCPoolAddress) } export const getUSDC = async (ethers: any, deployer: string, networkName: string)=> { @@ -68,7 +128,7 @@ export const getUSDC = async (ethers: any, deployer: string, networkName: string return ethers.getContract("MockErc20", deployer); } // get contract instance at address - return ethers.getContract('MockErc20', usdcAddress) + return ethers.getContractAt('MockErc20', usdcAddress) } /**