diff --git a/contracts/README.md b/contracts/README.md index 84c6df5154..6576e7a8dd 100644 --- a/contracts/README.md +++ b/contracts/README.md @@ -343,15 +343,16 @@ export DEFENDER_TEAM_SECRET= # Set the DEBUG environment variable to oeth* for the Defender Action npx hardhat setActionVars --id 38e44420-f38b-4d4a-86b0-6012a8897ad9 npx hardhat setActionVars --id f4b5b8d4-82ff-483f-bfae-9fef015790ca +npx hardhat setActionVars --id 191d9631-70b9-43c5-9db4-1dd985fde05c -# Upload Deposit to EigenLayer code # The Defender autotask client uses generic env var names so we'll set them first from the values in the .env file export API_KEY=${DEFENDER_TEAM_KEY} export API_SECRET=${DEFENDER_TEAM_SECRET} # Holesky -npx defender-autotask update-code 38e44420-f38b-4d4a-86b0-6012a8897ad9 ./dist/operateValidators +npx defender-autotask update-code 38e44420-f38b-4d4a-86b0-6012a8897ad9 ./dist/registerValidators +npx defender-autotask update-code 191d9631-70b9-43c5-9db4-1dd985fde05c ./dist/doAccounting # Mainnet -npx defender-autotask update-code f4b5b8d4-82ff-483f-bfae-9fef015790ca ./dist/operateValidators +npx defender-autotask update-code f4b5b8d4-82ff-483f-bfae-9fef015790ca ./dist/registerValidators ``` `rollup` and `defender-autotask-client` can be installed globally to avoid the `npx` prefix. diff --git a/contracts/dev.env b/contracts/dev.env index f7754465b6..ccae286df8 100644 --- a/contracts/dev.env +++ b/contracts/dev.env @@ -34,4 +34,14 @@ ACCOUNTS_TO_FUND= #P2P API KEYS P2P_MAINNET_API_KEY=[SET API Key] -P2P_HOLESKY_API_KEY=[SET API Key] \ No newline at end of file +P2P_HOLESKY_API_KEY=[SET API Key] + +# Defender Team Key needed to upload code to Actions +# DEFENDER_TEAM_KEY= +# DEFENDER_TEAM_SECRET= + +# Defender Relayer API key +# HOLESKY_DEFENDER_API_KEY= +# HOLESKY_DEFENDER_API_SECRET= +# DEFENDER_API_KEY= +# DEFENDER_API_SECRET= diff --git a/contracts/package.json b/contracts/package.json index b732aa0ae9..19dcbdfc18 100644 --- a/contracts/package.json +++ b/contracts/package.json @@ -78,6 +78,7 @@ "papaparse": "^5.3.1", "prettier": "^2.3.2", "prettier-plugin-solidity": "1.0.0-beta.17", + "rollup": "^4.18.0", "solc": "0.8.6", "solhint": "^3.4.1", "solidifier": "^2.2.3", diff --git a/contracts/scripts/defender-actions/doAccounting.js b/contracts/scripts/defender-actions/doAccounting.js new file mode 100644 index 0000000000..ee5c9a63cd --- /dev/null +++ b/contracts/scripts/defender-actions/doAccounting.js @@ -0,0 +1,42 @@ +const { ethers } = require("ethers"); +const { + DefenderRelaySigner, + DefenderRelayProvider, +} = require("@openzeppelin/defender-relay-client/lib/ethers"); +const addresses = require("../../utils/addresses"); +const { logTxDetails } = require("../../utils/txLogger"); + +const nativeStakingStrategyAbi = require("../../abi/native_staking_SSV_strategy.json"); + +const log = require("../../utils/logger")("action:doAccounting"); + +// Entrypoint for the Defender Action +const handler = async (event) => { + console.log( + `DEBUG env var in handler before being set: "${process.env.DEBUG}"` + ); + + // Initialize defender relayer provider and signer + const provider = new DefenderRelayProvider(event); + const signer = new DefenderRelaySigner(event, provider, { speed: "fastest" }); + + const network = await provider.getNetwork(); + const networkName = network.chainId === 1 ? "mainnet" : "holesky"; + log(`Network: ${networkName} with chain id (${network.chainId})`); + + const nativeStakingProxyAddress = + addresses[networkName].NativeStakingSSVStrategyProxy; + log( + `Resolved Native Staking Strategy address to ${nativeStakingProxyAddress}` + ); + const nativeStakingStrategy = new ethers.Contract( + nativeStakingProxyAddress, + nativeStakingStrategyAbi, + signer + ); + + const tx = await nativeStakingStrategy.connect(signer).doAccounting(); + await logTxDetails(tx, "doAccounting"); +}; + +module.exports = { handler }; diff --git a/contracts/scripts/defender-actions/registerValidators.js b/contracts/scripts/defender-actions/registerValidators.js index f635949041..15036811d7 100644 --- a/contracts/scripts/defender-actions/registerValidators.js +++ b/contracts/scripts/defender-actions/registerValidators.js @@ -12,32 +12,29 @@ const addresses = require("../../utils/addresses"); const nativeStakingStrategyAbi = require("../../abi/native_staking_SSV_strategy.json"); const IWETH9Abi = require("../../abi/IWETH9.json"); -const log = require("../../utils/logger")("action:operateValidators"); +const log = require("../../utils/logger")("action:registerValidators"); // Entrypoint for the Defender Action const handler = async (event) => { - const store = new KeyValueStoreClient(event); - // Initialize defender relayer provider and signer console.log( `DEBUG env var in handler before being set: "${process.env.DEBUG}"` ); + const store = new KeyValueStoreClient(event); + + // Initialize defender relayer provider and signer const provider = new DefenderRelayProvider(event); const signer = new DefenderRelaySigner(event, provider, { speed: "fastest" }); const network = await provider.getNetwork(); const networkName = network.chainId === 1 ? "mainnet" : "holesky"; log(`Network: ${networkName} with chain id (${network.chainId})`); - console.log(`Network: ${networkName} with chain id (${network.chainId})`); const nativeStakingProxyAddress = addresses[networkName].NativeStakingSSVStrategyProxy; log( `Resolved Native Staking Strategy address to ${nativeStakingProxyAddress}` ); - console.log( - `Resolved Native Staking Strategy address to ${nativeStakingProxyAddress}` - ); const nativeStakingStrategy = new ethers.Contract( nativeStakingProxyAddress, nativeStakingStrategyAbi, @@ -46,17 +43,11 @@ const handler = async (event) => { const wethAddress = addresses[networkName].WETH; log(`Resolved WETH address to ${wethAddress}`); - console.log(`Resolved WETH address to ${wethAddress}`); const WETH = new ethers.Contract(wethAddress, IWETH9Abi, signer); const feeAccumulatorAddress = await nativeStakingStrategy.FEE_ACCUMULATOR_ADDRESS(); - const contracts = { - nativeStakingStrategy, - WETH, - }; - const p2p_api_key = network.chainId === 1 ? event.secrets.P2P_MAINNET_API_KEY @@ -69,7 +60,11 @@ const handler = async (event) => { const p2p_base_url = network.chainId === 1 ? "api.p2p.org" : "api-test-holesky.p2p.org"; - const config = { + await registerValidators({ + signer, + store, + nativeStakingStrategy, + WETH, feeAccumulatorAddress, p2p_api_key, p2p_base_url, @@ -77,17 +72,6 @@ const handler = async (event) => { // SSV Network contract on validator registration. This is calculated // at a Cluster level rather than a single validator. validatorSpawnOperationalPeriodInDays: 1, - // Stake the 32 ETH into the validator - stake: true, - // Clear the local state of the Defender Action - clear: true, - }; - - await registerValidators({ - signer, - contracts, - store, - config, }); }; diff --git a/contracts/scripts/defender-actions/rollup.config.cjs b/contracts/scripts/defender-actions/rollup.config.cjs index 06704a3159..a55e8d10e4 100644 --- a/contracts/scripts/defender-actions/rollup.config.cjs +++ b/contracts/scripts/defender-actions/rollup.config.cjs @@ -32,6 +32,7 @@ module.exports = [ input: "registerValidators.js", output: { file: "dist/registerValidators/index.js", + inlineDynamicImports: true, format: "cjs", }, }, @@ -40,6 +41,16 @@ module.exports = [ input: "stakeValidators.js", output: { file: "dist/stakeValidators/index.js", + inlineDynamicImports: true, + format: "cjs", + }, + }, + { + ...commonConfig, + input: "doAccounting.js", + output: { + file: "dist/doAccounting/index.js", + inlineDynamicImports: true, format: "cjs", }, }, diff --git a/contracts/scripts/defender-actions/stakeValidators.js b/contracts/scripts/defender-actions/stakeValidators.js new file mode 100644 index 0000000000..4422214973 --- /dev/null +++ b/contracts/scripts/defender-actions/stakeValidators.js @@ -0,0 +1,70 @@ +const { ethers } = require("ethers"); +const { + DefenderRelaySigner, + DefenderRelayProvider, +} = require("@openzeppelin/defender-relay-client/lib/ethers"); +const { + KeyValueStoreClient, +} = require("@openzeppelin/defender-kvstore-client"); +const { stakeValidators } = require("../../tasks/validator"); +const addresses = require("../../utils/addresses"); + +const nativeStakingStrategyAbi = require("../../abi/native_staking_SSV_strategy.json"); +const IWETH9Abi = require("../../abi/IWETH9.json"); + +const log = require("../../utils/logger")("action:stakeValidators"); + +// Entrypoint for the Defender Action +const handler = async (event) => { + console.log( + `DEBUG env var in handler before being set: "${process.env.DEBUG}"` + ); + + const store = new KeyValueStoreClient(event); + + // Initialize defender relayer provider and signer + const provider = new DefenderRelayProvider(event); + const signer = new DefenderRelaySigner(event, provider, { speed: "fastest" }); + + const network = await provider.getNetwork(); + const networkName = network.chainId === 1 ? "mainnet" : "holesky"; + log(`Network: ${networkName} with chain id (${network.chainId})`); + + const nativeStakingProxyAddress = + addresses[networkName].NativeStakingSSVStrategyProxy; + log( + `Resolved Native Staking Strategy address to ${nativeStakingProxyAddress}` + ); + const nativeStakingStrategy = new ethers.Contract( + nativeStakingProxyAddress, + nativeStakingStrategyAbi, + signer + ); + + const wethAddress = addresses[networkName].WETH; + log(`Resolved WETH address to ${wethAddress}`); + const WETH = new ethers.Contract(wethAddress, IWETH9Abi, signer); + + const p2p_api_key = + network.chainId === 1 + ? event.secrets.P2P_MAINNET_API_KEY + : event.secrets.P2P_HOLESKY_API_KEY; + if (!p2p_api_key) { + throw new Error( + "Secret with P2P API key not set. Add the P2P_MAINNET_API_KEY or P2P_HOLESKY_API_KEY secret" + ); + } + const p2p_base_url = + network.chainId === 1 ? "api.p2p.org" : "api-test-holesky.p2p.org"; + + await stakeValidators({ + signer, + store, + nativeStakingStrategy, + WETH, + p2p_api_key, + p2p_base_url, + }); +}; + +module.exports = { handler }; diff --git a/contracts/tasks/harvest.js b/contracts/tasks/harvest.js new file mode 100644 index 0000000000..3d789d039e --- /dev/null +++ b/contracts/tasks/harvest.js @@ -0,0 +1,21 @@ +const { resolveContract } = require("../utils/resolvers"); +const { getSigner } = require("../utils/signers"); +const { logTxDetails } = require("../utils/txLogger"); + +const log = require("../utils/logger")("task:harvest"); + +async function harvestAndSwap({ strategy, harvester }) { + const signer = await getSigner(); + + const harvesterContract = await resolveContract(harvester, "OETHHarvester"); + const strategyContract = await resolveContract(strategy); + + log(`Harvesting and swapping for strategy ${strategyContract.address}`); + const tx = await harvesterContract.connect(signer)[ + // eslint-disable-next-line no-unexpected-multiline + "harvestAndSwap(address)" + ](strategyContract.address); + await logTxDetails(tx, "harvestAndSwap"); +} + +module.exports = { harvestAndSwap }; diff --git a/contracts/tasks/ssv.js b/contracts/tasks/ssv.js index 1669d6798a..3212453471 100644 --- a/contracts/tasks/ssv.js +++ b/contracts/tasks/ssv.js @@ -34,7 +34,7 @@ const depositSSV = async ({ amount, operatorids }, hre) => { const clusterInfo = await getClusterInfo({ chainId: hre.network.config.chainId, ssvNetwork: ssvNetwork.address, - operatorIds: operatorids, + operatorids, ownerAddress: strategy.address, }); diff --git a/contracts/tasks/tasks.js b/contracts/tasks/tasks.js index 5529744b5a..720a43ace0 100644 --- a/contracts/tasks/tasks.js +++ b/contracts/tasks/tasks.js @@ -73,9 +73,16 @@ const { validatorOperationsConfig, registerValidators, stakeValidators, + exitValidator, + removeValidator, + doAccounting, resetStakeETHTally, setStakeETHThreshold, + fixAccounting, + pauseStaking, } = require("./validator"); +const { resolveContract } = require("../utils/resolvers"); +const { harvestAndSwap } = require("./harvest"); // can not import from utils/deploy since that imports hardhat globally const withConfirmation = async (deployOrTransactionPromise) => { @@ -892,6 +899,23 @@ task("setRewardTokenAddresses", "Sets the reward token of a strategy") ) .setAction(setRewardTokenAddresses); +// Harvester + +task("harvest", "Harvest and swap rewards for a strategy") + .addParam( + "strategy", + "Name of the strategy proxy contract or address. eg NativeStakingSSVStrategyProxy", + undefined, + types.string + ) + .addOptionalParam( + "harvester", + "Name of the harvester proxy contract or address", + "OETHHarvesterProxy", + types.string + ) + .setAction(harvestAndSwap); + // SSV subtask("getClusterInfo", "Print out information regarding SSV cluster") @@ -1036,21 +1060,69 @@ task("stakeValidators").setAction(async (_, __, runSuper) => { return runSuper(); }); +subtask("exitValidator", "Starts the exit process from a validator") + .addParam( + "pubkey", + "Public key of the validator to exit", + undefined, + types.string + ) + .addParam( + "operatorids", + "Comma separated operator ids. E.g. 60,79,220,349", + undefined, + types.string + ) + .setAction(exitValidator); +task("exitValidator").setAction(async (_, __, runSuper) => { + return runSuper(); +}); + subtask( - "resetStakeETHTally", - "Resets the amount of Ether staked back to zero" + "removeValidator", + "Removes a validator from the SSV cluster after it has exited the beacon chain" +) + .addParam( + "pubkey", + "Public key of the validator to exit", + undefined, + types.string + ) + .addParam( + "operatorids", + "Comma separated operator ids. E.g. 60,79,220,349", + undefined, + types.string + ) + .setAction(removeValidator); +task("removeValidator").setAction(async (_, __, runSuper) => { + return runSuper(); +}); + +subtask( + "doAccounting", + "Account for consensus rewards and validator exits in the Native Staking Strategy" ).setAction(async () => { const signer = await getSigner(); - const nativeStakingProxyFactory = await ethers.getContract( - "NativeStakingSSVStrategyProxy" + const nativeStakingStrategy = await resolveContract( + "NativeStakingSSVStrategyProxy", + "NativeStakingSSVStrategy" ); - await resetStakeETHTally({ + await doAccounting({ signer, - nativeStakingProxyFactory, + nativeStakingStrategy, }); }); +task("doAccounting").setAction(async (_, __, runSuper) => { + return runSuper(); +}); + +subtask( + "resetStakeETHTally", + "Resets the amount of Ether staked back to zero" +).setAction(resetStakeETHTally); task("resetStakeETHTally").setAction(async (_, __, runSuper) => { return runSuper(); }); @@ -1060,20 +1132,40 @@ subtask( "Sets the amount of Ether than can be staked before needing a reset" ) .addParam("amount", "Amount in ether", undefined, types.int) - .setAction(async (taskArgs) => { - const signer = await getSigner(); + .setAction(setStakeETHThreshold); +task("setStakeETHThreshold").setAction(async (_, __, runSuper) => { + return runSuper(); +}); - const nativeStakingProxyFactory = await ethers.getContract( - "NativeStakingSSVStrategyProxy" - ); +subtask("fixAccounting", "Fix the accounting of the Native Staking Strategy.") + .addOptionalParam( + "validators", + "The number of validators to adjust up or down (negative)", + 0, + types.int + ) + .addOptionalParam( + "rewards", + "The number of consensus rewards to adjust up or down (negative) in ether", + 0, + types.float + ) + .addOptionalParam( + "ether", + "amount of ether that gets wrapped into WETH and sent to the Vault", + 0, + types.float + ) + .setAction(fixAccounting); +task("fixAccounting").setAction(async (_, __, runSuper) => { + return runSuper(); +}); - await setStakeETHThreshold({ - ...taskArgs, - signer, - nativeStakingProxyFactory, - }); - }); -task("setStakeETHThreshold").setAction(async (_, __, runSuper) => { +subtask( + "pauseStaking", + "Pause the staking of the Native Staking Strategy" +).setAction(pauseStaking); +task("pauseStaking").setAction(async (_, __, runSuper) => { return runSuper(); }); diff --git a/contracts/tasks/validator.js b/contracts/tasks/validator.js index a194040b4f..b00d58e79f 100644 --- a/contracts/tasks/validator.js +++ b/contracts/tasks/validator.js @@ -6,7 +6,7 @@ const { KeyValueStoreClient, } = require("@openzeppelin/defender-kvstore-client"); -const { getClusterInfo } = require("./ssv"); +const { getClusterInfo } = require("../utils/ssv"); const addresses = require("../utils/addresses"); const { resolveContract } = require("../utils/resolvers"); const { getSigner } = require("../utils/signers"); @@ -75,7 +75,6 @@ const validatorOperationsConfig = async (taskArgs) => { // SSV Network contract on validator registration. This is calculated // at a Cluster level rather than a single validator. validatorSpawnOperationalPeriodInDays: taskArgs.days, - stake: taskArgs.stake, clear: taskArgs.clear, uuid: taskArgs.uuid, }; @@ -186,6 +185,13 @@ const registerValidators = async ({ break; } + if (currentState.state === "validator_registered") { + log( + `Validator has been registered. Run the stakeValidators task to stake the validator` + ); + break; + } + await sleep(1000); } }; @@ -217,7 +223,7 @@ const stakeValidators = async ({ }) => { let currentState; if (!uuid) { - let currentState = await getState(store); + currentState = await getState(store); log("currentState", currentState); if (!currentState) { @@ -489,7 +495,8 @@ const p2pRequest = async (url, api_key, method, body) => { const response = await rawResponse.json(); if (response.error != null) { - log("Call to P2P API failed with response:", response); + log(`Call to P2P API failed: ${method} ${url}`); + log(`response: `, response); throw new Error( `Failed to call to P2P API. Error: ${JSON.stringify(response.error)}` ); @@ -658,6 +665,9 @@ const confirmValidatorRegistered = async ( p2p_base_url ) => { const doConfirmation = async () => { + if (!uuid) { + throw Error(`UUID is required to get validator status.`); + } const response = await p2pRequest( `https://${p2p_base_url}/api/v1/eth/staking/ssv/request/status/${uuid}`, p2p_api_key, @@ -706,6 +716,9 @@ const getDepositData = async ( p2p_base_url ) => { const doConfirmation = async () => { + if (!uuid) { + throw Error(`UUID is required to get deposit data.`); + } const response = await p2pRequest( `https://${p2p_base_url}/api/v1/eth/staking/ssv/request/deposit-data/${uuid}`, p2p_api_key, @@ -761,7 +774,12 @@ const retry = async (apiCall, uuid, store, attempts = 20) => { } }; -async function exitValidator({ publicKey, signer, operatorIds }) { +async function exitValidator({ pubkey, operatorids }) { + const signer = await getSigner(); + + log(`Splitting operator IDs ${operatorids}`); + const operatorIds = operatorids.split(",").map((id) => parseInt(id)); + const strategy = await resolveContract( "NativeStakingSSVStrategyProxy", "NativeStakingSSVStrategy" @@ -770,11 +788,16 @@ async function exitValidator({ publicKey, signer, operatorIds }) { log(`About to exit validator`); const tx = await strategy .connect(signer) - .exitSsvValidator(publicKey, operatorIds); + .exitSsvValidator(pubkey, operatorIds); await logTxDetails(tx, "exitSsvValidator"); } -async function removeValidator({ publicKey, signer, operatorIds }) { +async function removeValidator({ pubkey, operatorids }) { + const signer = await getSigner(); + + log(`Splitting operator IDs ${operatorids}`); + const operatorIds = operatorids.split(",").map((id) => parseInt(id)); + const strategy = await resolveContract( "NativeStakingSSVStrategyProxy", "NativeStakingSSVStrategy" @@ -784,18 +807,26 @@ async function removeValidator({ publicKey, signer, operatorIds }) { const { cluster } = await getClusterInfo({ chainId: hre.network.config.chainId, ssvNetwork: hre.network.name.toUpperCase(), - operatorIds, + operatorids, ownerAddress: strategy.address, }); log(`About to exit validator`); const tx = await strategy .connect(signer) - .removeSsvValidator(publicKey, operatorIds, cluster); + .removeSsvValidator(pubkey, operatorIds, cluster); await logTxDetails(tx, "removeSsvValidator"); } -async function resetStakeETHTally({ signer }) { +async function doAccounting({ signer, nativeStakingStrategy }) { + log(`About to doAccounting`); + const tx = await nativeStakingStrategy.connect(signer).doAccounting(); + await logTxDetails(tx, "doAccounting"); +} + +async function resetStakeETHTally() { + const signer = await getSigner(); + const strategy = await resolveContract( "NativeStakingSSVStrategyProxy", "NativeStakingSSVStrategy" @@ -806,7 +837,9 @@ async function resetStakeETHTally({ signer }) { await logTxDetails(tx, "resetStakeETHTally"); } -async function setStakeETHThreshold({ signer, amount }) { +async function setStakeETHThreshold({ amount }) { + const signer = await getSigner(); + const strategy = await resolveContract( "NativeStakingSSVStrategyProxy", "NativeStakingSSVStrategy" @@ -819,12 +852,43 @@ async function setStakeETHThreshold({ signer, amount }) { await logTxDetails(tx, "setStakeETHThreshold"); } +async function fixAccounting({ validators, rewards, ether }) { + const signer = await getSigner(); + + const strategy = await resolveContract( + "NativeStakingSSVStrategyProxy", + "NativeStakingSSVStrategy" + ); + + log(`About to fix accounting`); + const tx = await strategy + .connect(signer) + .manuallyFixAccounting(validators, rewards, ether); + await logTxDetails(tx, "manuallyFixAccounting"); +} + +async function pauseStaking() { + const signer = await getSigner(); + + const strategy = await resolveContract( + "NativeStakingSSVStrategyProxy", + "NativeStakingSSVStrategy" + ); + + log(`About to pause the Native Staking Strategy`); + const tx = await strategy.connect(signer).pause(); + await logTxDetails(tx, "pause"); +} + module.exports = { validatorOperationsConfig, registerValidators, stakeValidators, removeValidator, exitValidator, + doAccounting, resetStakeETHTally, setStakeETHThreshold, + fixAccounting, + pauseStaking, }; diff --git a/contracts/yarn.lock b/contracts/yarn.lock index cea1711fd5..5e0638a4f1 100644 --- a/contracts/yarn.lock +++ b/contracts/yarn.lock @@ -1334,6 +1334,86 @@ estree-walker "^2.0.2" picomatch "^2.3.1" +"@rollup/rollup-android-arm-eabi@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz#bbd0e616b2078cd2d68afc9824d1fadb2f2ffd27" + integrity sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ== + +"@rollup/rollup-android-arm64@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz#97255ef6384c5f73f4800c0de91f5f6518e21203" + integrity sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA== + +"@rollup/rollup-darwin-arm64@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz#b6dd74e117510dfe94541646067b0545b42ff096" + integrity sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w== + +"@rollup/rollup-darwin-x64@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz#e07d76de1cec987673e7f3d48ccb8e106d42c05c" + integrity sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA== + +"@rollup/rollup-linux-arm-gnueabihf@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz#9f1a6d218b560c9d75185af4b8bb42f9f24736b8" + integrity sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA== + +"@rollup/rollup-linux-arm-musleabihf@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz#53618b92e6ffb642c7b620e6e528446511330549" + integrity sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A== + +"@rollup/rollup-linux-arm64-gnu@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz#99a7ba5e719d4f053761a698f7b52291cefba577" + integrity sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw== + +"@rollup/rollup-linux-arm64-musl@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz#f53db99a45d9bc00ce94db8a35efa7c3c144a58c" + integrity sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ== + +"@rollup/rollup-linux-powerpc64le-gnu@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz#cbb0837408fe081ce3435cf3730e090febafc9bf" + integrity sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA== + +"@rollup/rollup-linux-riscv64-gnu@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz#8ed09c1d1262ada4c38d791a28ae0fea28b80cc9" + integrity sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg== + +"@rollup/rollup-linux-s390x-gnu@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz#938138d3c8e0c96f022252a28441dcfb17afd7ec" + integrity sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg== + +"@rollup/rollup-linux-x64-gnu@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz#1a7481137a54740bee1ded4ae5752450f155d942" + integrity sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w== + +"@rollup/rollup-linux-x64-musl@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz#f1186afc601ac4f4fc25fac4ca15ecbee3a1874d" + integrity sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg== + +"@rollup/rollup-win32-arm64-msvc@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz#ed6603e93636a96203c6915be4117245c1bd2daf" + integrity sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA== + +"@rollup/rollup-win32-ia32-msvc@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz#14e0b404b1c25ebe6157a15edb9c46959ba74c54" + integrity sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg== + +"@rollup/rollup-win32-x64-msvc@4.18.0": + version "4.18.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz#5d694d345ce36b6ecf657349e03eb87297e68da4" + integrity sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g== + "@scure/base@~1.1.0": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" @@ -1568,7 +1648,7 @@ dependencies: "@types/node" "*" -"@types/estree@*", "@types/estree@^1.0.0": +"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.0": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== @@ -7510,6 +7590,31 @@ rlp@^2.2.3, rlp@^2.2.4: dependencies: bn.js "^5.2.0" +rollup@^4.18.0: + version "4.18.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.18.0.tgz#497f60f0c5308e4602cf41136339fbf87d5f5dda" + integrity sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg== + dependencies: + "@types/estree" "1.0.5" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.18.0" + "@rollup/rollup-android-arm64" "4.18.0" + "@rollup/rollup-darwin-arm64" "4.18.0" + "@rollup/rollup-darwin-x64" "4.18.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.18.0" + "@rollup/rollup-linux-arm-musleabihf" "4.18.0" + "@rollup/rollup-linux-arm64-gnu" "4.18.0" + "@rollup/rollup-linux-arm64-musl" "4.18.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.18.0" + "@rollup/rollup-linux-riscv64-gnu" "4.18.0" + "@rollup/rollup-linux-s390x-gnu" "4.18.0" + "@rollup/rollup-linux-x64-gnu" "4.18.0" + "@rollup/rollup-linux-x64-musl" "4.18.0" + "@rollup/rollup-win32-arm64-msvc" "4.18.0" + "@rollup/rollup-win32-ia32-msvc" "4.18.0" + "@rollup/rollup-win32-x64-msvc" "4.18.0" + fsevents "~2.3.2" + run-async@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"