UNPKG

@mstable/protocol

Version:
260 lines 18.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const axios_1 = __importDefault(require("axios")); const config_1 = require("hardhat/config"); const generated_1 = require("types/generated"); const RewardsDistributorEth__factory_1 = require("types/generated/factories/RewardsDistributorEth__factory"); const math_1 = require("@utils/math"); const utils_1 = require("ethers/lib/utils"); const constants_1 = require("@utils/constants"); const tokens_1 = require("./utils/tokens"); const defender_utils_1 = require("./utils/defender-utils"); const deploy_utils_1 = require("./utils/deploy-utils"); const networkAddressFactory_1 = require("./utils/networkAddressFactory"); const utils_2 = require("./utils"); const snap_utils_1 = require("./utils/snap-utils"); config_1.task("eject-stakers", "Ejects expired stakers from Meta staking contract (vMTA)") .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "average", config_1.types.string) .setAction(async (taskArgs, { ethers, hardhatArguments, network }) => { const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const chain = networkAddressFactory_1.getChain(network.name, hardhatArguments.config); const ejectorAddress = networkAddressFactory_1.getChainAddress("Ejector", chain); const ejector = generated_1.IEjector__factory.connect(ejectorAddress, signer); // TODO check the last time the eject was run // Check it's been more than 7 days since the last eject has been run // get stakers from API const response = await axios_1.default.get("https://api-dot-mstable.appspot.com/stakers"); const stakers = response.data.ejected; if (stakers.length === 0) { console.error(`No stakers to eject`); process.exit(0); } console.log(`${stakers.length} stakers to be ejected: ${stakers}`); const tx = await ejector.ejectMany(stakers); await deploy_utils_1.logTxDetails(tx, "ejectMany"); }); config_1.task("collect-interest", "Collects and streams interest from platforms") .addParam("asset", "Token symbol of main or feeder pool asset. eg mUSD, mBTC, fpmBTC/HBTC or fpmUSD/GUSD", undefined, config_1.types.string, false) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "average", config_1.types.string) .setAction(async (taskArgs, { ethers, hardhatArguments, network }) => { const chain = networkAddressFactory_1.getChain(network.name, hardhatArguments.config); const asset = tokens_1.tokens.find((t) => t.symbol === taskArgs.asset); if (!asset) { console.error(`Failed to find main or feeder pool asset with token symbol ${taskArgs.asset}`); process.exit(1); } const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const savingsManagerAddress = networkAddressFactory_1.getChainAddress("SavingsManager", chain); const savingsManager = generated_1.SavingsManager__factory.connect(savingsManagerAddress, signer); const lastBatchCollected = await savingsManager.lastBatchCollected(asset.address); const lastBatchDate = new Date(lastBatchCollected.mul(1000).toNumber()); console.log(`The last interest collection was ${lastBatchDate.toUTCString()}, epoch ${lastBatchCollected} seconds`); const currentEpoc = new Date().getTime() / 1000; if (currentEpoc - lastBatchCollected.toNumber() < 60 * 60 * 6) { console.error(`Can not run again as the last run was less then 6 hours ago`); process.exit(3); } const tx = await savingsManager.collectAndStreamInterest(asset.address); await deploy_utils_1.logTxDetails(tx, "collectAndStreamInterest"); }); config_1.task("polly-daily", "Runs the daily jobs against the contracts on Polygon mainnet") .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers, hardhatArguments, network }) => { const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const chain = networkAddressFactory_1.getChain(network.name, hardhatArguments.config); const aave = generated_1.PAaveIntegration__factory.connect(tokens_1.PmUSD.integrator, signer); const aaveTx = await aave.claimRewards({ gasLimit: 200000 }); await deploy_utils_1.logTxDetails(aaveTx, "claimRewards"); const liquidatorAddress = networkAddressFactory_1.getChainAddress("Liquidator", chain); const liquidator = generated_1.PLiquidator__factory.connect(liquidatorAddress, signer); const liquidatorTx = await liquidator.triggerLiquidation(tokens_1.PmUSD.integrator, { gasLimit: 2000000 }); await deploy_utils_1.logTxDetails(liquidatorTx, "triggerLiquidation"); const savingsManagerAddress = networkAddressFactory_1.getChainAddress("SavingsManager", chain); const savingsManager = generated_1.SavingsManager__factory.connect(savingsManagerAddress, signer); const savingsManagerTx = await savingsManager.collectAndStreamInterest(tokens_1.PmUSD.address, { gasLimit: 2000000, }); await deploy_utils_1.logTxDetails(savingsManagerTx, "collectAndStreamInterest"); }); config_1.task("polly-stake-imusd", "Stakes imUSD into the v-imUSD vault on Polygon") .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers }) => { const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const amount = math_1.simpleToExactAmount(20); const imUSD = generated_1.ERC20__factory.connect(tokens_1.PmUSD.savings, signer); const tx1 = await imUSD.approve(tokens_1.PmUSD.vault, amount); await deploy_utils_1.logTxDetails(tx1, "Relay approves v-imUSD vault to transfer imUSD"); const vault = generated_1.StakingRewards__factory.connect(tokens_1.PmUSD.vault, signer); const tx2 = await vault["stake(uint256)"](amount); await deploy_utils_1.logTxDetails(tx2, `stake ${utils_2.usdFormatter(amount)} imUSD in v-imUSD vault`); }); config_1.task("polly-dis-rewards", "Distributes MTA and WMATIC rewards to the imUSD vault on Polygon") .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .addOptionalParam("mtaAmount", "MTA tokens", 20833, config_1.types.int) .addOptionalParam("wmaticAmount", "WMATIC tokens", 18666, config_1.types.int) .setAction(async (taskArgs, { ethers, hardhatArguments, network }) => { const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const chain = networkAddressFactory_1.getChain(network.name, hardhatArguments.config); const mtaAmount = math_1.simpleToExactAmount(taskArgs.mtaAmount); const wmaticAmount = math_1.simpleToExactAmount(taskArgs.wmaticAmount); const rewardsDistributorAddress = networkAddressFactory_1.getChainAddress("RewardsDistributor", chain); const rewardsDistributor = generated_1.RewardsDistributor__factory.connect(rewardsDistributorAddress, signer); const mtaToken = generated_1.ERC20__factory.connect(tokens_1.PMTA.address, signer); const tx1 = await mtaToken.approve(rewardsDistributorAddress, mtaAmount); await deploy_utils_1.logTxDetails(tx1, `Relay account approve RewardsDistributor contract to transfer ${utils_2.usdFormatter(mtaAmount)} MTA`); const wmaticToken = generated_1.ERC20__factory.connect(tokens_1.PWMATIC.address, signer); const tx2 = await wmaticToken.approve(rewardsDistributorAddress, wmaticAmount); await deploy_utils_1.logTxDetails(tx2, `Relay account approve RewardsDistributor contract to transfer ${utils_2.usdFormatter(wmaticAmount)} WMATIC`); const tx3 = await rewardsDistributor.distributeRewards([tokens_1.PmUSD.vault], [mtaAmount], [wmaticAmount]); await deploy_utils_1.logTxDetails(tx3, `distributeRewards ${utils_2.usdFormatter(mtaAmount)} MTA and ${utils_2.usdFormatter(wmaticAmount)} WMATIC`); }); config_1.task("dis-rewards", "Distributes MTA rewards to a vault on Mainnet") .addParam("vaultAsset", "Symbol of asset that is staked. eg mUSD, MTA, GUSD, alUSD", undefined, config_1.types.string) .addOptionalParam("amount", "MTA tokens", 20833, config_1.types.int) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers, hardhatArguments, network }) => { const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const chain = networkAddressFactory_1.getChain(network.name, hardhatArguments.config); const vaultAsset = tokens_1.tokens.find((t) => t.symbol === taskArgs.vaultAsset && t.chain === chain); if (!vaultAsset) throw Error(`Could not find vault asset with symbol ${taskArgs.vaultAsset}`); const rewardsDistributorAddress = networkAddressFactory_1.getChainAddress("RewardsDistributor", chain); const rewardsDistributor = RewardsDistributorEth__factory_1.RewardsDistributorEth__factory.connect(rewardsDistributorAddress, signer); const mtaAmount = math_1.simpleToExactAmount(taskArgs.amount); const tx = await rewardsDistributor.distributeRewards([vaultAsset.vault], [mtaAmount]); await deploy_utils_1.logTxDetails(tx, `distributeRewards ${utils_1.formatUnits(mtaAmount)} MTA to vault with asset ${vaultAsset.symbol} and address ${vaultAsset.vault}`); }); config_1.task("rewards", "Get Compound and Aave platform reward tokens") .addOptionalParam("block", "Block number to compare rates at. (default: current block)", 0, config_1.types.int) .setAction(async (taskArgs, { ethers }) => { const signer = await defender_utils_1.getSigner(ethers); const block = await snap_utils_1.getBlock(ethers, taskArgs.block); console.log(`\nGetting platform tokens at block ${block.blockNumber}, ${block.blockTime.toUTCString()}`); await snap_utils_1.getCompTokens(signer, block); await snap_utils_1.getAaveTokens(signer, block); await snap_utils_1.getAlcxTokens(signer, block); }); config_1.task("proxy-upgrades", "Proxy implementation changes") .addParam("asset", "Token symbol of main or feeder pool asset. eg mUSD, mBTC, fpmBTC/HBTC or fpmUSD/GUSD", undefined, config_1.types.string, false) .addOptionalParam("from", "Block to query transaction events from. (default: deployment block)", 10148031, config_1.types.int) .addOptionalParam("to", "Block to query transaction events to. (default: current block)", 0, config_1.types.int) .setAction(async (taskArgs, { ethers }) => { const asset = tokens_1.tokens.find((t) => t.symbol === taskArgs.asset); if (!asset) { console.error(`Failed to find main or feeder pool asset with token symbol ${taskArgs.asset}`); process.exit(1); } const signer = await defender_utils_1.getSigner(ethers); const { fromBlock, toBlock } = await snap_utils_1.getBlockRange(ethers, taskArgs.from, taskArgs.to); const proxy = generated_1.AssetProxy__factory.connect(asset.address, signer); const filter = await proxy.filters.Upgraded(); const logs = await proxy.queryFilter(filter, fromBlock.blockNumber, toBlock.blockNumber); console.log(`${asset.symbol} proxy ${asset.address}`); logs.forEach((log) => { console.log(`Upgraded at block ${log.blockNumber} to ${log.args.implementation}`); }); }); config_1.task("vault-stake", "Stake into a vault") .addParam("asset", "Symbol of the asset that has a mStable vault. eg mUSD, alUSD, MTA", undefined, config_1.types.string) .addParam("amount", "Amount to be staked", undefined, config_1.types.int) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers, network }) => { const chain = networkAddressFactory_1.getChain(network.name); const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const signerAddress = await signer.getAddress(); const assetSymbol = taskArgs.asset; const assetToken = tokens_1.tokens.find((t) => t.symbol === assetSymbol && t.chain === chain); if (!assetToken) throw Error(`Could not find asset with symbol ${assetSymbol}`); if (!assetToken.vault) throw Error(`No vault is configured for asset ${assetSymbol}`); const vault = generated_1.StakingRewards__factory.connect(assetToken.vault, signer); const amount = math_1.simpleToExactAmount(taskArgs.amount); const tx = await vault["stake(uint256)"](amount); await deploy_utils_1.logTxDetails(tx, `${signerAddress} stakes ${amount} ${assetSymbol} in vault`); }); config_1.task("vault-withdraw", "Withdraw from a vault") .addParam("asset", "Symbol of the asset that has a mStable vault. eg mUSD, alUSD, MTA", undefined, config_1.types.string) .addParam("amount", "Amount to be withdrawn", undefined, config_1.types.int) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers, network }) => { const chain = networkAddressFactory_1.getChain(network.name); const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const signerAddress = await signer.getAddress(); const assetSymbol = taskArgs.asset; const assetToken = tokens_1.tokens.find((t) => t.symbol === assetSymbol && t.chain === chain); if (!assetToken) throw Error(`Could not find asset with symbol ${assetSymbol}`); if (!assetToken.vault) throw Error(`No vault is configured for asset ${assetSymbol}`); const vault = generated_1.StakingRewards__factory.connect(assetToken.vault, signer); const amount = math_1.simpleToExactAmount(taskArgs.amount); const tx = await vault.withdraw(amount); await deploy_utils_1.logTxDetails(tx, `${signerAddress} withdraw ${amount} ${assetSymbol} from vault`); }); config_1.task("vault-exit", "Exit from vault claiming rewards") .addParam("asset", "Symbol of the asset that has a mStable vault. eg mUSD, alUSD, MTA", undefined, config_1.types.string) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers, network }) => { const chain = networkAddressFactory_1.getChain(network.name); const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const signerAddress = await signer.getAddress(); const assetSymbol = taskArgs.asset; const assetToken = tokens_1.tokens.find((t) => t.symbol === assetSymbol && t.chain === chain); if (!assetToken) throw Error(`Could not find asset with symbol ${assetSymbol}`); if (!assetToken.vault) throw Error(`No vault is configured for asset ${assetSymbol}`); const vault = generated_1.StakingRewards__factory.connect(assetToken.vault, signer); const tx = await vault.exit(); await deploy_utils_1.logTxDetails(tx, `${signerAddress} exits ${assetSymbol} vault`); }); config_1.task("vault-claim", "Claim rewards from vault") .addParam("asset", "Symbol of the asset that has a mStable vault. eg mUSD, alUSD, MTA", undefined, config_1.types.string) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers, network }) => { const chain = networkAddressFactory_1.getChain(network.name); const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const signerAddress = await signer.getAddress(); const assetSymbol = taskArgs.asset; const assetToken = tokens_1.tokens.find((t) => t.symbol === assetSymbol && t.chain === chain); if (!assetToken) throw Error(`Could not find asset with symbol ${assetSymbol}`); if (!assetToken.vault) throw Error(`No vault is configured for asset ${assetSymbol}`); const vault = generated_1.StakingRewards__factory.connect(assetToken.vault, signer); const tx = await vault.claimReward(); await deploy_utils_1.logTxDetails(tx, `${signerAddress} claim rewards from ${assetSymbol} vault`); }); config_1.task("approve", "Approve account to transfer token from the Defender Relay account") .addParam("asset", "Symbol of the asset being approved. eg mUSD, imUSD, PmUSD, GUSD, alUSD, MTA", undefined, config_1.types.string) // TODO support the account being a contract name .addParam("account", "Address of the account that is approved to transferFrom", undefined, config_1.types.string) .addOptionalParam("tokenType", "Token address, savings, vault or feederPool.", "address", config_1.types.string) .addOptionalParam("amount", "Amount to approve. Default is max unit128", undefined, config_1.types.int) .addOptionalParam("speed", "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'", "fast", config_1.types.string) .setAction(async (taskArgs, { ethers, network }) => { const chain = networkAddressFactory_1.getChain(network.name); const signer = await defender_utils_1.getSigner(ethers, taskArgs.speed); const signerAddress = await signer.getAddress(); const assetSymbol = taskArgs.asset; const assetToken = tokens_1.tokens.find((t) => t.symbol === assetSymbol && t.chain === chain); if (!assetToken) throw Error(`Could not find asset with symbol ${assetSymbol}`); const approveAccount = taskArgs.account; // TODO validate address using a regex if (!approveAccount) throw Error(`Invalid approve address ${approveAccount}`); const { tokenType } = taskArgs; if (!assetToken[tokenType]) throw Error(`Can not fine ${tokenType} for token ${assetSymbol}`); const token = generated_1.ERC20__factory.connect(assetToken[tokenType], signer); const amount = taskArgs.amount ? math_1.simpleToExactAmount(taskArgs.amount) : constants_1.MAX_INT128; const tx = await token.approve(approveAccount, amount); await deploy_utils_1.logTxDetails(tx, `${signerAddress} approves ${approveAccount} to transfer ${utils_1.formatUnits(amount)} ${assetSymbol}`); }); module.exports = {}; //# sourceMappingURL=ops.js.map