import { TransactionResponse } from "@ethersproject/providers" ; import { subtask , task , types } from "hardhat/config" ; import { DisperseForwarder__factory , EmissionsController__factory , IERC20__factory , L2EmissionsController__factory , RevenueBuyBack__factory , RevenueForwarder__factory , SavingsManager__factory , } from "types/generated" ; import { ONE_HOUR } from "@utils/constants" ; import { logTxDetails , logger , mUSD , mBTC } from "./utils" ; import { getSigner } from "./utils/signerFactory" ; import { getChain , resolveAddress } from "./utils/networkAddressFactory" ; import { getBalancerPolygonReport } from "./utils/emission-disperse-bal" ; import { sendPrivateTransaction } from "./utils/flashbots" ; const log = logger ( "emission" ) ; subtask ( "emission-calc" , "Calculate the weekly emissions" ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const emissionsControllerAddress = resolveAddress ( "EmissionsController" , chain ) ; const emissionsController = EmissionsController__factory . connect ( emissionsControllerAddress , signer ) ; const tx = await emissionsController . calculateRewards ( ) ; await logTxDetails ( tx , "calculate rewards" ) ; } ) ; task ( "emission-calc" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; subtask ( "emission-dist" , "Distribute the weekly emissions" ) . addOptionalParam ( "dials" , "The number of dials starting at 0" , 17 , types . int ) . addOptionalParam ( "dialIds" , "A comma separated list of dial ids" , undefined , types . string ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const emissionsControllerAddress = resolveAddress ( "EmissionsController" , chain ) ; const emissionsController = EmissionsController__factory . connect ( emissionsControllerAddress , signer ) ; const dialIds = taskArgs . dialIds ? taskArgs . dialIds . split ( "," ) . map ( Number ) : [ ... Array ( taskArgs . dials ) . keys ( ) ] ; const tx = await emissionsController . distributeRewards ( dialIds ) ; await logTxDetails ( tx , `distribute rewards for dial ids ${ dialIds }` ) ; } ) ; task ( "emission-dist" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; subtask ( "l2-emission-dist" , "Distribute the weekly emissions on layer 2 to vaults" ) . addParam ( "recipient" , "The address of the end recipient. eg Vault" , undefined , types . string ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const emissionsControllerAddress = resolveAddress ( "EmissionsController" , chain ) ; const emissionsController = L2EmissionsController__factory . connect ( emissionsControllerAddress , signer ) ; const recipientAddress = resolveAddress ( taskArgs . recipient , chain , "vault" ) ; const tx = await emissionsController . distributeRewards ( [ recipientAddress ] ) ; await logTxDetails ( tx , `distribute rewards to ${ taskArgs . recipient }` ) ; } ) ; task ( "l2-emission-dist" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; subtask ( "emission-disperse-bal" , "Disperse Polygon Balancer Pool MTA rewards in a DisperseForwarder contract" ) . addParam ( "report" , "Report number from the bal-mining-script repo. eg 79" , undefined , types . int ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const disperseForwarderAddress = resolveAddress ( "DisperseForwarder" , chain ) ; const disperseForwarder = DisperseForwarder__factory . connect ( disperseForwarderAddress , signer ) ; const mtaAddress = resolveAddress ( "MTA" , chain ) ; const mtaToken = IERC20__factory . connect ( mtaAddress , signer ) ; const mtaBalance = await mtaToken . balanceOf ( disperseForwarderAddress ) ; try { const { disperser } = await getBalancerPolygonReport ( taskArgs . report , mtaBalance ) ; const tx = await disperseForwarder . disperseToken ( disperser . recipients , disperser . values ) ; await logTxDetails ( tx , `Disperse Balancer Pool MTA rewards ${ disperser . total }  to ${ disperser . recipients } recipients` ) ; } catch ( error ) { log ( `Error dispersing report ${ taskArgs . report } : ${ error . message }` ) ; process . exit ( 0 ) ; } } ) ; task ( "emission-disperse-bal" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; subtask ( "savings-dist-fees" , "Distributes governance fees from the Savings Manager to the Revenue Recipient" ) . addOptionalParam ( "masset" , "Symbol of mAsset that the fees were collected in. eg mUSD or mBTC" , "mUSD" , types . string ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const savingsManagerAddress = resolveAddress ( "SavingsManager" , chain ) ; const savingsManager = SavingsManager__factory . connect ( savingsManagerAddress , signer ) ; const mAssetAddress = resolveAddress ( taskArgs . masset , chain ) ; const tx = await savingsManager . distributeUnallocatedInterest ( mAssetAddress ) ; await logTxDetails ( tx , `distribute ${ taskArgs . masset } gov fees` ) ; } ) ; task ( "savings-dist-fees" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; subtask ( "revenue-forward" , "Forwards received revenue. eg Polygon mUSD revenue from SavingsManager" ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const revenueForwarderAddress = resolveAddress ( "RevenueRecipient" , chain ) ; const revenueForwarder = RevenueForwarder__factory . connect ( revenueForwarderAddress , signer ) ; const tx = await revenueForwarder . forward ( ) ; await logTxDetails ( tx , `forward gov fees` ) ; } ) ; task ( "revenue-forward" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; subtask ( "revenue-buy-back" , "Buy back MTA from mUSD and mBTC gov fees" ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const revenueBuyBackAddress = resolveAddress ( "RevenueBuyBack" , chain ) ; const revenueBuyBack = RevenueBuyBack__factory . connect ( revenueBuyBackAddress , signer ) ; let tx ; if ( hre . network . name === "hardhat" ) { tx = await revenueBuyBack . buyBackRewards ( [ mUSD . address , mBTC . address ] ) ; } else { const populatedTx = await revenueBuyBack . populateTransaction . buyBackRewards ( [ mUSD . address , mBTC . address ] ) ; tx = await sendPrivateTransaction ( populatedTx , signer ) ; } await logTxDetails ( tx , `buy back MTA from gov fees` ) ; } ) ; task ( "revenue-buy-back" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; subtask ( "revenue-donate-rewards" , "Donate purchased MTA to the staking dials in the Emissions Controller" ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( taskArgs , hre ) => { const signer = await getSigner ( hre , taskArgs . speed ) ; const chain = getChain ( hre ) ; const revenueBuyBackAddress = resolveAddress ( "RevenueBuyBack" , chain ) ; const revenueBuyBack = RevenueBuyBack__factory . connect ( revenueBuyBackAddress , signer ) ; const tx = await revenueBuyBack . donateRewards ( ) ; await logTxDetails ( tx , `donate purchased MTA to Emissions Controller` ) ; } ) ; task ( "revenue-donate-rewards" ) . setAction ( async ( _ , __ , runSuper ) => { await runSuper ( ) ; } ) ; task ( "emissions-process" , "Weekly mainnet emissions process" ) . addOptionalParam ( "speed" , "Defender Relayer speed param: 'safeLow' | 'average' | 'fast' | 'fastest'" , "fast" , types . string ) . setAction ( async ( { speed } , hre ) => { await hre . run ( "dials-snap" , { speed } ) ; const { increaseTime } = await import ( "@utils/time" ) ; await increaseTime ( ONE_HOUR ) ; await hre . run ( "savings-dist-fees" , { masset : "mUSD" , speed } ) ; await hre . run ( "savings-dist-fees" , { masset : "mBTC" , speed } ) ; await hre . run ( "revenue-buy-back" , { speed } ) ; await hre . run ( "revenue-donate-rewards" , { speed } ) ; await hre . run ( "emission-calc" , { speed } ) ; await hre . run ( "emission-dist" , { speed , dials : 15 } ) ; await hre . run ( "emission-dist" , { speed , dialIds : "16" } ) ; await hre . run ( "dials-snap" , { speed } ) ; } ) ;