From ae8e83d00690ea8f72561bb59f62e9dbb24a8df8 Mon Sep 17 00:00:00 2001 From: Yuri Tkachenko Date: Mon, 30 Sep 2024 13:24:47 +0100 Subject: [PATCH] chore: remove simpledvt deploy --- scripts/simpledvt/01-deploy-app-proxy.js | 93 ---- scripts/simpledvt/02-clone-nor.js | 553 ----------------------- scripts/simpledvt/03-check-deployed.js | 489 -------------------- scripts/simpledvt/helpers.js | 182 -------- 4 files changed, 1317 deletions(-) delete mode 100644 scripts/simpledvt/01-deploy-app-proxy.js delete mode 100644 scripts/simpledvt/02-clone-nor.js delete mode 100644 scripts/simpledvt/03-check-deployed.js delete mode 100644 scripts/simpledvt/helpers.js diff --git a/scripts/simpledvt/01-deploy-app-proxy.js b/scripts/simpledvt/01-deploy-app-proxy.js deleted file mode 100644 index 21edadf75..000000000 --- a/scripts/simpledvt/01-deploy-app-proxy.js +++ /dev/null @@ -1,93 +0,0 @@ -const { network } = require('hardhat') -const runOrWrapScript = require('../helpers/run-or-wrap-script') -const { log, yl } = require('../helpers/log') -const { getDeployer, readStateAppAddress, _checkEq, _pause } = require('./helpers') -const { - readNetworkState, - assertRequiredNetworkState, - persistNetworkState, -} = require('../helpers/persisted-network-state') - -const { hash: namehash } = require('eth-ens-namehash') -const { ZERO_ADDRESS } = require('../../test/helpers/utils') - -const APP_TRG = process.env.APP_TRG || 'simple-dvt' -const DEPLOYER = process.env.DEPLOYER || '' - -const REQUIRED_NET_STATE = ['lidoApm', 'lidoApmEnsName'] - -async function deployEmptyProxy({ web3, artifacts, trgAppName = APP_TRG }) { - const netId = await web3.eth.net.getId() - const deployer = await getDeployer(web3, DEPLOYER) - - log.splitter() - log(`Network ID: ${yl(netId)}`) - log(`Deployer: ${yl(deployer)}`) - - const state = readNetworkState(network.name, netId) - assertRequiredNetworkState(state, REQUIRED_NET_STATE) - - const trgAppFullName = `${trgAppName}.${state.lidoApmEnsName}` - const trgAppId = namehash(trgAppFullName) - - const kernelAddress = state.daoAddress || readStateAppAddress(state, `aragon-kernel`) - if (!kernelAddress) { - throw new Error(`No Aragon kernel (DAO address) found!`) - } - - log.splitter() - log(`DAO:`, yl(kernelAddress)) - log(`Target App:`, yl(trgAppName)) - log(`Target App ENS:`, yl(trgAppFullName)) - log(`Target App ID:`, yl(trgAppId)) - log.splitter() - - let trgProxyAddress - - if (state[`app:${trgAppName}`]) { - trgProxyAddress = readStateAppAddress(state, `app:${trgAppName}`) - } - - if (!trgProxyAddress || (await web3.eth.getCode(trgProxyAddress)) === '0x') { - await _pause('Ready for TX') - log.splitter() - - const kernel = await artifacts.require('Kernel').at(kernelAddress) - const tx = await log.tx( - `Deploying proxy for ${trgAppName}`, - kernel.newAppProxy(kernelAddress, trgAppId, { from: deployer }) - ) - // Find the deployed proxy address in the tx logs. - const e = tx.logs.find((l) => l.event === 'NewAppProxy') - trgProxyAddress = e.args.proxy - - // upd deployed state - persistNetworkState(network.name, netId, state, { - [`app:${trgAppName}`]: { - aragonApp: { - name: trgAppName, - fullName: trgAppFullName, - id: trgAppId, - }, - proxy: { - address: trgProxyAddress, - contract: '@aragon/os/contracts/apps/AppProxyUpgradeable.sol', - constructorArgs: [kernelAddress, trgAppId, '0x'], - }, - }, - }) - } - - log(`Target app proxy deployed at`, yl(trgProxyAddress)) - - log.splitter() - log('Checking deployed proxy...') - - const proxy = await artifacts.require('AppProxyUpgradeable').at(trgProxyAddress) - - _checkEq(await proxy.kernel(), kernelAddress, 'App proxy kernel address matches Lido DAO') - _checkEq(await proxy.appId(), trgAppId, 'App proxy AppId matches SimpleDVT') - _checkEq(await proxy.implementation(), ZERO_ADDRESS, 'App proxy has ZERO_ADDRESS implementations') -} - -module.exports = runOrWrapScript(deployEmptyProxy, module) diff --git a/scripts/simpledvt/02-clone-nor.js b/scripts/simpledvt/02-clone-nor.js deleted file mode 100644 index 6a617a923..000000000 --- a/scripts/simpledvt/02-clone-nor.js +++ /dev/null @@ -1,553 +0,0 @@ -const { network, ethers } = require('hardhat') -const { Contract } = require('ethers') -const { encodeCallScript } = require('@aragon/contract-helpers-test/src/aragon-os') -const { getEventArgument } = require('@aragon/contract-helpers-test') -const { EVMScriptDecoder, abiProviders } = require('evm-script-decoder') -const runOrWrapScript = require('../helpers/run-or-wrap-script') -const { log, yl, gr, cy } = require('../helpers/log') -// const { saveCallTxData } = require('../helpers/tx-data') -const { resolveLatestVersion } = require('../components/apm') -const { - readNetworkState, - assertRequiredNetworkState, - persistNetworkState, -} = require('../helpers/persisted-network-state') -const { resolveEnsAddress } = require('../components/ens') -const { hash: namehash } = require('eth-ens-namehash') -const { APP_NAMES, APP_ARTIFACTS } = require('../constants') -const { - getDeployer, - readStateAppAddress, - getSignature, - KERNEL_APP_BASES_NAMESPACE, - MANAGE_SIGNING_KEYS, - MANAGE_NODE_OPERATOR_ROLE, - SET_NODE_OPERATOR_LIMIT_ROLE, - STAKING_ROUTER_ROLE, - STAKING_MODULE_MANAGE_ROLE, - REQUEST_BURN_SHARES_ROLE, - SIMPLE_DVT_IPFS_CID, - easyTrackABI, - easyTrackFactoryABI, - _pause, - _checkLog, - _checkEqLog, -} = require('./helpers') -const { ETH, toBN } = require('../../test/helpers/utils') - -const APP_TRG = process.env.APP_TRG || APP_NAMES.SIMPLE_DVT -const APP_IPFS_CID = process.env.APP_IPFS_CID || SIMPLE_DVT_IPFS_CID -const DEPLOYER = process.env.DEPLOYER || '' - -const SIMULATE = !!process.env.SIMULATE -const VOTE_ID = process.env.VOTE_ID || '' - -const REQUIRED_NET_STATE = [ - 'ensAddress', - 'lidoApm', - 'lidoApmEnsName', - 'lidoLocator', - `app:${APP_NAMES.ARAGON_VOTING}`, - `app:${APP_NAMES.ARAGON_TOKEN_MANAGER}`, -] - -async function deploySimpleDVT({ web3, artifacts, trgAppName = APP_TRG, ipfsCid = APP_IPFS_CID }) { - const netId = await web3.eth.net.getId() - const deployer = await getDeployer(web3, DEPLOYER) - - log.splitter() - log(`Network ID: ${yl(netId)}`) - log(`Deployer: ${yl(deployer)}`) - - const state = readNetworkState(network.name, netId) - const srcAppName = APP_NAMES.NODE_OPERATORS_REGISTRY - assertRequiredNetworkState(state, REQUIRED_NET_STATE.concat([`app:${srcAppName}`, `app:${trgAppName}`])) - - const kernelAddress = state.daoAddress || readStateAppAddress(state, `aragon-kernel`) - if (!kernelAddress) { - throw new Error(`No Aragon kernel (DAO address) found!`) - } - - log.splitter() - - log(`Using ENS:`, yl(state.ensAddress)) - const ens = await artifacts.require('ENS').at(state.ensAddress) - log.splitter() - - const srcAppFullName = `${srcAppName}.${state.lidoApmEnsName}` - const srcAppId = namehash(srcAppFullName) - const { semanticVersion, contractAddress } = await resolveLatestVersion(srcAppId, ens, artifacts) - const srcVersion = semanticVersion.map((n) => n.toNumber()) - - log(`Source App:`, yl(srcAppName)) - log(`Source App ENS:`, yl(srcAppFullName)) - log(`Source App ID:`, yl(srcAppId)) - log(`Source Contract implementation:`, yl(contractAddress)) - log(`Source App version:`, yl(srcVersion.join('.'))) - log.splitter() - - const trgAppFullName = `${trgAppName}.${state.lidoApmEnsName}` - const trgAppId = namehash(trgAppFullName) - const trgProxyAddress = readStateAppAddress(state, `app:${trgAppName}`) - const trgAppArtifact = APP_ARTIFACTS[srcAppName] // get source app artifact - const trgApp = await artifacts.require(trgAppArtifact).at(trgProxyAddress) - - // set new version to 1.0.0 - const trgVersion = [1, 0, 0] - const contentURI = '0x' + Buffer.from(`ipfs:${ipfsCid}`, 'utf8').toString('hex') - - log(`Target App:`, yl(trgAppName)) - log(`Target App ENS:`, yl(trgAppFullName)) - log(`Target App ID:`, yl(trgAppId)) - log(`Target App proxy`, yl(trgProxyAddress)) - log(`Target Contract implementation:`, yl(contractAddress)) - log(`Target Content IPFS CID:`, yl(ipfsCid)) - log(`Target Content URI:`, yl(contentURI)) - log(`Target App version:`, yl(trgVersion.join('.'))) - - log.splitter() - const { - moduleName, - moduleType, - targetShare, - moduleFee, - treasuryFee, - penaltyDelay, - easyTrackAddress, - easyTrackTrustedCaller, - easyTrackFactories = {}, - } = state[`app:${trgAppName}`].stakingRouterModuleParams - - _checkLog(moduleName, `Target SR Module name`) - _checkLog(moduleType, `Target SR Module type`) - _checkLog(moduleFee, `Target SR Module fee`) - _checkLog(targetShare, `Target SR Module targetShare`) - _checkLog(treasuryFee, `Target SR Module treasuryFee`) - _checkLog(penaltyDelay, `Target SR Module penaltyDelay`) - - if (!trgProxyAddress || (await web3.eth.getCode(trgProxyAddress)) === '0x') { - log.error(`Target app proxy is not yet deployed!`) - return - } - - const trgRepoAddress = await resolveEnsAddress(artifacts, ens, trgAppId) - - if (trgRepoAddress && (await web3.eth.getCode(trgRepoAddress)) !== '0x') { - log(`Target App APM repo:`, yl(trgRepoAddress)) - log.error(`Target app is already deployed!`) - return - } - - const lidoLocatorAddress = readStateAppAddress(state, `lidoLocator`) - const votingAddress = readStateAppAddress(state, `app:${APP_NAMES.ARAGON_VOTING}`) - const tokenManagerAddress = readStateAppAddress(state, `app:${APP_NAMES.ARAGON_TOKEN_MANAGER}`) - const srAddress = readStateAppAddress(state, 'stakingRouter') - const lidoApmAddress = readStateAppAddress(state, 'lidoApm') - - const kernel = await artifacts.require('Kernel').at(kernelAddress) - const aclAddress = await kernel.acl() - const acl = await artifacts.require('ACL').at(aclAddress) - const stakingRouter = await artifacts.require('StakingRouter').at(srAddress) - const apmRegistry = await artifacts.require('APMRegistry').at(lidoApmAddress) - - const voteDesc = `Clone app '${srcAppName}' to '${trgAppName}'` - const voting = await artifacts.require('Voting').at(votingAddress) - const tokenManager = await artifacts.require('TokenManager').at(tokenManagerAddress) - const agentAddress = readStateAppAddress(state, `app:${APP_NAMES.ARAGON_AGENT}`) - const agent = await artifacts.require('Agent').at(agentAddress) - const daoTokenAddress = await tokenManager.token() - const daoToken = await artifacts.require('MiniMeToken').at(daoTokenAddress) - - const burnerAddress = readStateAppAddress(state, `burner`) - const burner = await artifacts.require('Burner').at(burnerAddress) - - log.splitter() - log(`DAO Kernel`, yl(kernelAddress)) - log(`ACL`, yl(aclAddress)) - log(`Voting`, yl(votingAddress)) - log(`Token manager`, yl(tokenManagerAddress)) - log(`LDO token`, yl(daoTokenAddress)) - log(`Lido APM`, yl(lidoApmAddress)) - log(`Staking Router`, yl(srAddress)) - log(`Burner`, yl(burnerAddress)) - log(`Lido Locator:`, yl(lidoLocatorAddress)) - - log.splitter() - - // use ethers.js Contract instance - const easytrack = new Contract(easyTrackAddress, easyTrackABI).connect(ethers.provider) - const easyTrackEVMScriptExecutor = await easytrack.evmScriptExecutor() - - log(`EasyTrack`, yl(easyTrackAddress)) - log(`EasyTrack EVM Script Executor`, yl(easyTrackEVMScriptExecutor)) - log(`EasyTrack Trusted caller`, yl(easyTrackTrustedCaller)) - - for (const f of Object.keys(easyTrackFactories)) { - log(`EasyTrack Factory <${cy(f)}>`, yl(easyTrackFactories[f])) - const fc = new Contract(easyTrackFactories[f], easyTrackFactoryABI, ethers.provider) - _checkEqLog(await fc.trustedCaller(), easyTrackTrustedCaller, `EasyTrack Factory <${cy(f)}> trusted caller`) - } - - log.splitter() - log(yl('^^^ check all the params above ^^^')) - await _pause() - log.splitter() - - const evmScriptCalls = [ - // create app repo - { - to: apmRegistry.address, - calldata: await apmRegistry.contract.methods - .newRepoWithVersion(trgAppName, votingAddress, trgVersion, contractAddress, contentURI) - .encodeABI(), - }, - // link appId with implementations - { - to: kernel.address, - calldata: await kernel.contract.methods.setApp(KERNEL_APP_BASES_NAMESPACE, trgAppId, contractAddress).encodeABI(), - }, - // initialize module - { - to: trgApp.address, - calldata: await trgApp.contract.methods - .initialize(lidoLocatorAddress, '0x' + Buffer.from(moduleType).toString('hex').padEnd(64, '0'), penaltyDelay) - .encodeABI(), - }, - ] - - // set permissions - - // grant perm for staking router - evmScriptCalls.push({ - to: acl.address, - calldata: await acl.contract.methods - .createPermission(srAddress, trgProxyAddress, STAKING_ROUTER_ROLE, votingAddress) - .encodeABI(), - }) - - // grant perms to easytrack evm script executor - evmScriptCalls.push({ - to: acl.address, - calldata: await acl.contract.methods - .grantPermission(easyTrackEVMScriptExecutor, trgProxyAddress, STAKING_ROUTER_ROLE) - .encodeABI(), - }) - - evmScriptCalls.push({ - to: acl.address, - calldata: await acl.contract.methods - .createPermission(easyTrackEVMScriptExecutor, trgProxyAddress, MANAGE_NODE_OPERATOR_ROLE, votingAddress) - .encodeABI(), - }) - evmScriptCalls.push({ - to: acl.address, - calldata: await acl.contract.methods - .createPermission(easyTrackEVMScriptExecutor, trgProxyAddress, SET_NODE_OPERATOR_LIMIT_ROLE, votingAddress) - .encodeABI(), - }) - - // grant manager to easytrack evm script executor - evmScriptCalls.push({ - to: acl.address, - calldata: await acl.contract.methods - .createPermission(easyTrackEVMScriptExecutor, trgProxyAddress, MANAGE_SIGNING_KEYS, easyTrackEVMScriptExecutor) - .encodeABI(), - }) - - // grant perms to easytrack factories - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.AddNodeOperators, - trgProxyAddress + - getSignature(trgApp, 'addNodeOperator').substring(2) + - aclAddress.substring(2) + - getSignature(acl, 'grantPermissionP').substring(2), - ]), - }) - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.ActivateNodeOperators, - trgProxyAddress + - getSignature(trgApp, 'activateNodeOperator').substring(2) + - aclAddress.substring(2) + - getSignature(acl, 'grantPermissionP').substring(2), - ]), - }) - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.DeactivateNodeOperators, - trgProxyAddress + - getSignature(trgApp, 'deactivateNodeOperator').substring(2) + - aclAddress.substring(2) + - getSignature(acl, 'revokePermission').substring(2), - ]), - }) - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.SetVettedValidatorsLimits, - trgProxyAddress + getSignature(trgApp, 'setNodeOperatorStakingLimit').substring(2), - ]), - }) - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.UpdateTargetValidatorLimits, - trgProxyAddress + getSignature(trgApp, 'updateTargetValidatorsLimits').substring(2), - ]), - }) - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.SetNodeOperatorNames, - trgProxyAddress + getSignature(trgApp, 'setNodeOperatorName').substring(2), - ]), - }) - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.SetNodeOperatorRewardAddresses, - trgProxyAddress + getSignature(trgApp, 'setNodeOperatorRewardAddress').substring(2), - ]), - }) - evmScriptCalls.push({ - to: easytrack.address, - calldata: await easytrack.interface.encodeFunctionData('addEVMScriptFactory', [ - easyTrackFactories.ChangeNodeOperatorManagers, - aclAddress + - getSignature(acl, 'revokePermission').substring(2) + - aclAddress.substring(2) + - getSignature(acl, 'grantPermissionP').substring(2), - ]), - }) - - // check missed STAKING_MODULE_MANAGE_ROLE role on Agent - if (!(await stakingRouter.hasRole(STAKING_MODULE_MANAGE_ROLE, voting.address))) { - evmScriptCalls.push({ - to: agent.address, - calldata: await agent.contract.methods - .execute( - stakingRouter.address, - 0, - await stakingRouter.contract.methods.grantRole(STAKING_MODULE_MANAGE_ROLE, agent.address).encodeABI() - ) - .encodeABI(), - }) - } - - // allow to request burner, add REQUEST_BURN_SHARES_ROLE - evmScriptCalls.push({ - to: agent.address, - calldata: await agent.contract.methods - .execute( - burner.address, - 0, - await burner.contract.methods.grantRole(REQUEST_BURN_SHARES_ROLE, trgProxyAddress).encodeABI() - ) - .encodeABI(), - }) - - // add module to SR - const addModuleCallData = await stakingRouter.contract.methods - .addStakingModule( - moduleName, // name - trgProxyAddress, // module address - targetShare, - moduleFee, - treasuryFee - ) - .encodeABI() - evmScriptCalls.push({ - to: agent.address, - calldata: await agent.contract.methods.execute(stakingRouter.address, 0, addModuleCallData).encodeABI(), - }) - - const evmScript = encodeCallScript(evmScriptCalls) - - const evmScriptDecoder = new EVMScriptDecoder( - new abiProviders.Local({ - [kernel.address]: kernel.abi, - [acl.address]: acl.abi, - [voting.address]: voting.abi, - [agent.address]: agent.abi, - [stakingRouter.address]: stakingRouter.abi, - [apmRegistry.address]: apmRegistry.abi, - [trgApp.address]: trgApp.abi, - [easytrack.address]: easyTrackABI, - }) - ) - - const decodedEVMScript = await evmScriptDecoder.decodeEVMScript(evmScript) - - log('Decoded voting script:') - for (const call of decodedEVMScript.calls) { - if (call.abi) { - const params = {} - const inputs = call.abi.inputs || [] - for (let i = 0; i < inputs.length; ++i) { - params[inputs[i].name] = call.decodedCallData[i] - } - log({ contract: call.address, method: call.abi.name, params }) - } else { - log(call) - } - } - - const newVoteEvmScript = encodeCallScript([ - { - to: voting.address, - calldata: await voting.contract.methods.newVote(evmScript, voteDesc, false, false).encodeABI(), - }, - ]) - - // skip update if VOTE_ID set - if (!VOTE_ID) { - // save app info - persistNetworkState(network.name, netId, state, { - [`app:${trgAppName}`]: { - aragonApp: { - name: trgAppName, - fullName: trgAppFullName, - id: trgAppId, - ipfsCid, - contentURI, - }, - implementation: { - address: contractAddress, - contract: 'contracts/0.4.24/nos/NodeOperatorsRegistry.sol', - }, - }, - }) - } - - log.splitter() - log(yl('^^^ check the decoded voting script above ^^^')) - - if (SIMULATE) { - await _pause('Ready for simulation') - log.splitter() - log(gr(`Simulating voting creation and enact!`)) - const { voters, quorum } = await getVoters(agentAddress, state.vestingParams, daoToken, voting) - - let voteId - if (!VOTE_ID) { - // create voting on behalf ldo holder - await ethers.getImpersonatedSigner(voters[0]) - log(`Creating voting on behalf holder`, yl(voters[0])) - const result = await tokenManager.forward(newVoteEvmScript, { from: voters[0], gasPrice: 0 }) - voteId = getEventArgument(result, 'StartVote', 'voteId', { decodeForAbi: voting.abi }) - log(`Voting created, Vote ID:`, yl(voteId)) - } else { - voteId = VOTE_ID - } - - // vote - log(`Checking state, Vote ID:`, yl(voteId)) - let vote = await voting.getVote(voteId) - if (vote.executed) { - log.error(`Vote ID: ${yl(voteId)} is already executed, can't simulate!`) - return - } - - log(`Collecting votes...`) - for (const voter of voters) { - if (vote.yea.gte(quorum)) { - break - } - const canVote = await voting.canVote(voteId, voter) - - if (canVote) { - await ethers.getImpersonatedSigner(voter) - log(`Cast voting on behalf holder:`, yl(voter)) - - await voting.vote(voteId, true, true, { from: voter, gasPrice: 0 }) - vote = await voting.getVote(voteId) - } else { - log(`Skip holder (can't vote):`, voter) - } - } - - if (vote.yea.lt(quorum)) { - log.error(`Not enough voting power for Vote ID:`, yl(voteId)) - return - } - log(`Vote quorum passed`) - - const voteTime = (await voting.voteTime()).toNumber() - // pass time and enact - log(`Pass time...`) - await ethers.provider.send('evm_increaseTime', [voteTime]) - await ethers.provider.send('evm_mine') - log(`Enacting vote...`) - await voting.executeVote(voteId, { from: deployer, gasPrice: 0 }) - - log(`Vote executed!`) - _checkEqLog(await trgApp.hasInitialized(), true, `Target App initialized`) - } else { - await _pause('Ready for TX') - log.splitter() - - const tx = await log.tx( - `Voting: Clone app '${srcAppName}' to '${trgAppName}'`, - tokenManager.forward(newVoteEvmScript, { from: deployer }) - ) - - const voteId = getEventArgument(tx, 'StartVote', 'voteId', { decodeForAbi: voting.abi }) - log(`Voting created, id`, yl(voteId)) - } - // else { - // await saveCallTxData( - // `Voting: Clone app '${srcAppName}' to '${trgAppName}'`, - // tokenManager, - // 'forward', - // `clone-tx-02-create-voting.json`, - // { - // arguments: [newVoteEvmScript], - // from: deployer, - // } - // ) - // // console.log({ txData }) - - // log.splitter() - // log(gr(`Before continuing the cloning, please send voting creation transactions`)) - // log(gr(`that you can find in the file listed above. You may use a multisig address`)) - // log(gr(`if it supports sending arbitrary tx.`)) - // } - - log.splitter() -} - -// try to get list of voters with most significant LDO amounts -async function getVoters(agentAddress, vestingParams, daoToken, voting) { - const totalSupply = await daoToken.totalSupply() - const quorumPcnt = await voting.minAcceptQuorumPct() - const quorum = totalSupply.mul(quorumPcnt).div(toBN(ETH(1))) - const minBalance = quorum.div(toBN(10)) // cliff to skip small holders - const voters = [] - let voteBalance = toBN(0) - - const holders = [ - agentAddress, // agent at 1st place as potentially the only sufficient - ...Object.entries(vestingParams.holders) - .sort((a, b) => (a[1] < b[1] ? 1 : a[1] > b[1] ? -1 : 0)) - .map(([h, b]) => h), - ] - - for (const holder of holders) { - const balance = await daoToken.balanceOf(holder) - if (balance.gte(minBalance)) { - voters.push(holder) - voteBalance = voteBalance.add(balance) - if (voteBalance.gt(quorum)) { - break - } - } - } - - return { voters, quorum } -} - -module.exports = runOrWrapScript(deploySimpleDVT, module) diff --git a/scripts/simpledvt/03-check-deployed.js b/scripts/simpledvt/03-check-deployed.js deleted file mode 100644 index 0ca2f0d15..000000000 --- a/scripts/simpledvt/03-check-deployed.js +++ /dev/null @@ -1,489 +0,0 @@ -const { network, ethers } = require('hardhat') -const { Contract, utils } = require('ethers') -const runOrWrapScript = require('../helpers/run-or-wrap-script') -const { log, yl, gr, cy } = require('../helpers/log') -const { - readStateAppAddress, - _checkEq, - _pause, - MANAGE_SIGNING_KEYS, - MANAGE_NODE_OPERATOR_ROLE, - SET_NODE_OPERATOR_LIMIT_ROLE, - STAKING_ROUTER_ROLE, - STAKING_MODULE_MANAGE_ROLE, - REQUEST_BURN_SHARES_ROLE, - SIMPLE_DVT_IPFS_CID, - easyTrackABI, - easyTrackEvmExecutorABI, - easyTrackFactoryABI, -} = require('./helpers') -const { readNetworkState, assertRequiredNetworkState } = require('../helpers/persisted-network-state') -const { hash: namehash } = require('eth-ens-namehash') -const { resolveLatestVersion } = require('../components/apm') -const { APP_NAMES, APP_ARTIFACTS } = require('../constants') -const { ETH, toBN, genKeys, ethToStr } = require('../../test/helpers/utils') -const { EvmSnapshot } = require('../../test/helpers/blockchain') -const { reportOracle, getSecondsPerFrame } = require('../../test/helpers/oracle') - -const APP_TRG = process.env.APP_TRG || 'simple-dvt' -const APP_IPFS_CID = process.env.APP_IPFS_CID || SIMPLE_DVT_IPFS_CID - -const SIMULATE = !!process.env.SIMULATE - -const REQUIRED_NET_STATE = [ - 'ensAddress', - 'lidoApm', - 'lidoApmEnsName', - 'lidoLocator', - `app:${APP_NAMES.ARAGON_AGENT}`, - `app:${APP_NAMES.ARAGON_VOTING}`, - `app:${APP_NAMES.ARAGON_TOKEN_MANAGER}`, -] - -async function checkSimpleDVT({ web3, artifacts, trgAppName = APP_TRG, ipfsCid = APP_IPFS_CID }) { - const netId = await web3.eth.net.getId() - - log.splitter() - log(`Network ID: ${yl(netId)}`) - - const state = readNetworkState(network.name, netId) - assertRequiredNetworkState(state, REQUIRED_NET_STATE.concat([`app:${trgAppName}`])) - - const kernelAddress = state.daoAddress || readStateAppAddress(state, `aragon-kernel`) - if (!kernelAddress) { - throw new Error(`No Aragon kernel (DAO address) found!`) - } - - log.splitter() - - log(`Using ENS:`, yl(state.ensAddress)) - const ens = await artifacts.require('ENS').at(state.ensAddress) - const lidoLocatorAddress = readStateAppAddress(state, `lidoLocator`) - log(`Lido Locator:`, yl(lidoLocatorAddress)) - log.splitter() - - const srcAppName = APP_NAMES.NODE_OPERATORS_REGISTRY - const srcAppFullName = `${srcAppName}.${state.lidoApmEnsName}` - const srcAppId = namehash(srcAppFullName) - const { contractAddress: srcContractAddress } = await resolveLatestVersion(srcAppId, ens, artifacts) - - const trgAppFullName = `${trgAppName}.${state.lidoApmEnsName}` - const trgAppId = namehash(trgAppFullName) - - const { semanticVersion, contractAddress, contentURI } = await resolveLatestVersion(trgAppId, ens, artifacts) - - _checkEq(contractAddress, srcContractAddress, 'App APM repo last version: implementation is the same to NOR') - _checkEq( - contentURI, - '0x' + Buffer.from(`ipfs:${ipfsCid}`, 'utf8').toString('hex'), - 'App APM repo last version: IPFS CIT correct' - ) - _checkEq(semanticVersion.map((x) => x.toNumber()).join(''), '100', 'App APM repo last version: app version = 1.0.0') - - const trgProxyAddress = readStateAppAddress(state, `app:${trgAppName}`) - const trgAppArtifact = APP_ARTIFACTS[srcAppName] // get source app artifact - const trgApp = await artifacts.require(trgAppArtifact).at(trgProxyAddress) - const { - moduleName, - moduleType, - targetShare, - moduleFee, - treasuryFee, - penaltyDelay, - easyTrackAddress, - easyTrackTrustedCaller, - easyTrackFactories = {}, - } = state[`app:${trgAppName}`].stakingRouterModuleParams - - _checkEq(await trgApp.appId(), trgAppId, 'App Contract: AppID correct') - _checkEq(await trgApp.kernel(), kernelAddress, 'App Contract: kernel address correct') - _checkEq(await trgApp.hasInitialized(), true, 'App Contract: initialized') - _checkEq(await trgApp.getLocator(), lidoLocatorAddress, 'App Contract: Locator address correct') - - log.splitter() - const kernel = await artifacts.require('Kernel').at(kernelAddress) - const aclAddress = await kernel.acl() - const acl = await artifacts.require('ACL').at(aclAddress) - const agentAddress = readStateAppAddress(state, `app:${APP_NAMES.ARAGON_AGENT}`) - const votingAddress = readStateAppAddress(state, `app:${APP_NAMES.ARAGON_VOTING}`) - const lidoAddress = readStateAppAddress(state, `app:${APP_NAMES.LIDO}`) - const srAddress = readStateAppAddress(state, 'stakingRouter') - const dsmAddress = readStateAppAddress(state, 'depositSecurityModule') - const stakingRouter = await artifacts.require('StakingRouter').at(srAddress) - const burnerAddress = readStateAppAddress(state, `burner`) - const burner = await artifacts.require('Burner').at(burnerAddress) - const easytrack = new Contract(easyTrackAddress, easyTrackABI).connect(ethers.provider) - const easyTrackEVMScriptExecutor = await easytrack.evmScriptExecutor() - - const accountingOracleAddress = readStateAppAddress(state, 'accountingOracle') - const oracle = await artifacts.require('AccountingOracle').at(accountingOracleAddress) - const hashConsensusAddress = readStateAppAddress(state, 'hashConsensusForAccountingOracle') - const consensus = await artifacts.require('HashConsensus').at(hashConsensusAddress) - - _checkEq( - await stakingRouter.hasRole(STAKING_MODULE_MANAGE_ROLE, agentAddress), - true, - 'Agent has role: STAKING_MODULE_MANAGE_ROLE' - ) - - _checkEq( - await burner.hasRole(REQUEST_BURN_SHARES_ROLE, trgProxyAddress), - true, - 'App has role: REQUEST_BURN_SHARES_ROLE' - ) - - _checkEq( - await acl.getPermissionManager(trgProxyAddress, MANAGE_SIGNING_KEYS), - easyTrackEVMScriptExecutor, - 'EasyTrackEVMScriptExecutor is permission manager: MANAGE_SIGNING_KEYS' - ) - _checkEq( - await acl.getPermissionManager(trgProxyAddress, MANAGE_NODE_OPERATOR_ROLE), - votingAddress, - 'Voting is permission manager: MANAGE_NODE_OPERATOR_ROLE' - ) - _checkEq( - await acl.getPermissionManager(trgProxyAddress, SET_NODE_OPERATOR_LIMIT_ROLE), - votingAddress, - 'Voting is permission manager: SET_NODE_OPERATOR_LIMIT_ROLE' - ) - _checkEq( - await acl.getPermissionManager(trgProxyAddress, STAKING_ROUTER_ROLE), - votingAddress, - 'Voting is permission manager: STAKING_ROUTER_ROLE' - ) - - _checkEq( - await acl.hasPermission(easyTrackEVMScriptExecutor, trgProxyAddress, MANAGE_SIGNING_KEYS), - true, - 'EasyTrackEVMScriptExecutor has permission: MANAGE_SIGNING_KEYS' - ) - _checkEq( - await acl.hasPermission(easyTrackEVMScriptExecutor, trgProxyAddress, MANAGE_NODE_OPERATOR_ROLE), - true, - 'EasyTrackEVMScriptExecutor has permission: MANAGE_NODE_OPERATOR_ROLE' - ) - _checkEq( - await acl.hasPermission(easyTrackEVMScriptExecutor, trgProxyAddress, SET_NODE_OPERATOR_LIMIT_ROLE), - true, - 'EasyTrackEVMScriptExecutor has permission: SET_NODE_OPERATOR_LIMIT_ROLE' - ) - - _checkEq( - await acl.hasPermission(easyTrackEVMScriptExecutor, trgProxyAddress, STAKING_ROUTER_ROLE), - true, - 'EasyTrackEVMScriptExecutor has permission: STAKING_ROUTER_ROLE' - ) - - _checkEq( - await acl.hasPermission(srAddress, trgProxyAddress, STAKING_ROUTER_ROLE), - true, - 'StakingRouter has permission: STAKING_ROUTER_ROLE' - ) - - log.splitter() - - _checkEq(await stakingRouter.getStakingModulesCount(), 2, 'StakingRouter: modules count = 2') - const srModuleId = 2 - _checkEq( - await stakingRouter.hasStakingModule(srModuleId), - true, - `StakingRouter: expected moduleId = ${srModuleId} exists` - ) - - const srModule = await stakingRouter.getStakingModule(srModuleId) - _checkEq(srModule.name, moduleName, `StakingRouter module: name = ${trgAppName}`) - _checkEq(srModule.stakingModuleAddress, trgProxyAddress, `StakingRouter module: address correct`) - _checkEq(srModule.treasuryFee, treasuryFee, `StakingRouter module: treasuryFee = ${treasuryFee}`) - _checkEq(srModule.stakingModuleFee, moduleFee, `StakingRouter module: moduleFee = ${moduleFee}`) - _checkEq(srModule.targetShare, targetShare, `StakingRouter module: targetShare = ${targetShare}`) - - log.splitter() - - _checkEq(await trgApp.getStuckPenaltyDelay(), penaltyDelay, `App params: penalty delay = ${penaltyDelay}`) - _checkEq( - await trgApp.getType(), - '0x' + Buffer.from(moduleType).toString('hex').padEnd(64, '0'), - `App params: module type = ${moduleType}` - ) - - _checkEq(await trgApp.getNodeOperatorsCount(), 0, `App initial values: no any operators (count = 0)`) - _checkEq(await trgApp.getActiveNodeOperatorsCount(), 0, `App initial values: no active operators (count = 0)`) - _checkEq(await trgApp.getNonce(), 0, `App initial values: nonce (keysOpIndex) = 0`) - - const { totalExitedValidators, totalDepositedValidators, depositableValidatorsCount } = - await trgApp.getStakingModuleSummary() - _checkEq(totalExitedValidators, 0, `App initial values: totalExitedValidators = 0`) - _checkEq(totalDepositedValidators, 0, `App initial values: totalDepositedValidators = 0`) - _checkEq(depositableValidatorsCount, 0, `App initial values: depositableValidatorsCount = 0`) - - log.splitter() - - // hardcode ET EVM script executor and ET factory ABIs to avoid adding external ABI files to repo - - const allFactories = await easytrack.getEVMScriptFactories() - // console.log(allFactories) - - // create ET factories instances - const factories = Object.entries(easyTrackFactories).reduce( - (f, [n, a]) => ({ ...f, [n]: new Contract(a, easyTrackFactoryABI, ethers.provider) }), - {} - ) - - for (const name of Object.keys(factories)) { - // `EasyTrack Factory <${cy(f)}>` - log(`ET factory <${cy(name)}>:`) - _checkEq(allFactories.includes(factories[name].address), true, `- in global list`) - _checkEq(await easytrack.isEVMScriptFactory(factories[name].address), true, `- isEVMScriptFactory`) - _checkEq(await factories[name].nodeOperatorsRegistry(), trgProxyAddress, `- matches target App`) - _checkEq(await factories[name].trustedCaller(), easyTrackTrustedCaller, `- trusted caller`) - } - - log.splitter() - - if (SIMULATE) { - await _pause('Ready for simulation') - log.splitter() - - log(gr(`Simulating adding keys and deposit!`)) - const strangers = await web3.eth.getAccounts() - - const abiCoder = new utils.AbiCoder() - - log('Creating snapshot...') - const snapshot = new EvmSnapshot(ethers.provider) - await snapshot.make() - - try { - const lido = await artifacts.require('Lido').at(lidoAddress) - - await ethers.getImpersonatedSigner(easyTrackAddress) - const easyTrackSigner = await ethers.getSigner(easyTrackAddress) - const evmExecutor = new Contract(easyTrackEVMScriptExecutor, easyTrackEvmExecutorABI, easyTrackSigner) - - const ADDRESS_1 = '0x0000000000000000000000000000000000000001' - const ADDRESS_2 = '0x0000000000000000000000000000000000000002' - const MANAGER_1 = '0x0000000000000000000000000000000000000011' - const MANAGER_2 = '0x0000000000000000000000000000000000000012' - - const depositsCount = 2000 - const op1keysAmount = 100 - const op2keysAmount = 50 - const keysAmount = op1keysAmount + op2keysAmount - if ((await trgApp.getNodeOperatorsCount()) < 1) { - // prepare node operators - - // add 2 NO via ET - // equivalent of: - // await trgApp.addNodeOperator('op 1', ADDRESS_1, { from: easyTrackEVMScriptExecutor, gasPrice: 0 }) - // await trgApp.addNodeOperator('op 2', ADDRESS_2, { from: easyTrackEVMScriptExecutor, gasPrice: 0 }) - - log(`Adding 2 operators via ET ${cy('AddNodeOperators')} factory...`) - let callData = abiCoder.encode( - // struct AddNodeOperatorInput { - // string name; - // address rewardAddress; - // address managerAddress; - // } - // - // uint256 nodeOperatorsCount, AddNodeOperatorInput[] memory nodeOperators - ['uint256', 'tuple(string,address,address)[]'], - [ - 0, - [ - ['op 1', ADDRESS_1, MANAGER_1], - ['op 2', ADDRESS_2, MANAGER_2], - ], - ] - ) - let evmScript = await factories.AddNodeOperators.createEVMScript(easyTrackTrustedCaller, callData) - await evmExecutor.executeEVMScript(evmScript, { gasPrice: 0 }) - _checkEq(await trgApp.getNodeOperatorsCount(), 2, `Module operators count = 2`) - - // add keys to module for op1 (on behalf op1 reward addr) - log(`Adding ${op1keysAmount} keys for op1 (on behalf op1 reward addr)...`) - await ethers.getImpersonatedSigner(ADDRESS_1) - let keys = genKeys(op1keysAmount) - await trgApp.addSigningKeys(0, op1keysAmount, keys.pubkeys, keys.sigkeys, { from: ADDRESS_1, gasPrice: 0 }) - - // add keys to module for op2 (on behalf op2 manager) - log(`Adding ${op2keysAmount} keys for op1 (on behalf op2 manager)...`) - await ethers.getImpersonatedSigner(MANAGER_2) - keys = genKeys(op2keysAmount) - await trgApp.addSigningKeys(1, op2keysAmount, keys.pubkeys, keys.sigkeys, { from: MANAGER_2, gasPrice: 0 }) - - log('Checking operators initial state...') - let opInfo = await trgApp.getNodeOperator(0, true) - _checkEq(opInfo.totalAddedValidators, op1keysAmount, `NO 1 totalAddedValidators = ${op1keysAmount}`) - opInfo = await trgApp.getNodeOperator(1, true) - _checkEq(opInfo.totalAddedValidators, op2keysAmount, `NO 2 totalAddedValidators = ${op2keysAmount}`) - - // increase keys limit via ET - // equivalent of: - // await trgApp.setNodeOperatorStakingLimit(0, op1keysAmount, { from: easyTrackEVMScriptExecutor, gasPrice: 0 }) - // await trgApp.setNodeOperatorStakingLimit(1, op2keysAmount, { from: easyTrackEVMScriptExecutor, gasPrice: 0 }) - - log(`Increasing operator's vetted keys limit via ET ${cy('SetVettedValidatorsLimits')} factory...`) - callData = abiCoder.encode( - // struct VettedValidatorsLimitInput { - // uint256 nodeOperatorId; - // uint256 stakingLimit; - // } - // - // VettedValidatorsLimitInput[] - ['tuple(uint256,uint256)[]'], - [ - [ - [0, op1keysAmount], - [1, op2keysAmount], - ], - ] - ) - evmScript = await factories.SetVettedValidatorsLimits.createEVMScript(easyTrackTrustedCaller, callData) - await evmExecutor.executeEVMScript(evmScript) - } - - log(`Checking SimpleDVT module state in StakingRouter...`) - let summary = await trgApp.getStakingModuleSummary() - _checkEq(summary.totalDepositedValidators, 0, `Module totalDepositedValidators = 0`) - _checkEq(summary.depositableValidatorsCount, keysAmount, `Module depositableValidatorsCount = ${keysAmount}`) - - const wqAddress = readStateAppAddress(state, 'withdrawalQueueERC721') - const withdrwalQueue = await artifacts.require('WithdrawalQueueERC721').at(wqAddress) - - const unfinalizedStETH = await withdrwalQueue.unfinalizedStETH() - const ethToDeposit = toBN(ETH(32 * depositsCount)) - let depositableEther = await lido.getDepositableEther() - - log(`Depositable ETH ${yl(ethToStr(depositableEther))} ETH`) - log(`Need (${yl(ethToStr(ethToDeposit))} ETH to deposit ${yl(depositsCount)} keys`) - - // simulate deposits by transfering ethers to Lido contract - if (depositableEther.lt(ethToDeposit)) { - log(`Simulating additional ETH submitting...`) - const bufferedEther = await lido.getBufferedEther() - const wqDebt = unfinalizedStETH.gt(bufferedEther) ? unfinalizedStETH.sub(bufferedEther) : toBN(0) - let ethToSubmit = ethToDeposit.add(wqDebt) - - let i = 0 - const minBalance = toBN(ETH(1)) - while (!ethToSubmit.isZero() && i < strangers.length) { - const balance = toBN(await web3.eth.getBalance(strangers[i])) - if (balance.gt(minBalance)) { - let ethToTransfer = balance.sub(minBalance) - if (ethToTransfer.gt(ethToSubmit)) { - ethToTransfer = ethToSubmit - } - log(`- ${ethToStr(ethToTransfer)} ETH from stranger ${strangers[i]}...`) - await web3.eth.sendTransaction({ value: ethToTransfer, to: lido.address, from: strangers[i], gasPrice: 0 }) - ethToSubmit = ethToSubmit.sub(ethToTransfer) - } - ++i - } - } - depositableEther = await lido.getDepositableEther() - - _checkEq( - depositableEther.gte(ethToDeposit), - true, - `Enough depositable ${yl(ethToStr(depositableEther))} ETH to` + - ` deposit ${yl(depositsCount)} keys (${yl(ethToStr(ethToDeposit))} ETH)` - ) - - // get max deposits count from SR (according targetShare value) - // - // NOR module id = 1 - // const maxDepositsCount1 = (await stakingRouter.getStakingModuleMaxDepositsCount(1, ethToDeposit)).toNumber() - // SimpleDVT module id = 2 - const maxDepositsCount2 = (await stakingRouter.getStakingModuleMaxDepositsCount(2, ethToDeposit)).toNumber() - // console.log({maxDepositsCount1, maxDepositsCount2}); - - log(`Depositing ${depositsCount} keys (on behalf DSM)..`) - const trgModuleId = 2 // sr module id - await ethers.getImpersonatedSigner(dsmAddress) - await lido.deposit(depositsCount, trgModuleId, '0x', { - from: dsmAddress, - gasPrice: 0, - }) - await ethers.provider.send('evm_increaseTime', [600]) - await ethers.provider.send('evm_mine') - - log(`Checking SimpleDVT module new state in StakingRouter...`) - summary = await trgApp.getStakingModuleSummary() - _checkEq( - summary.totalDepositedValidators, - maxDepositsCount2, - `Summary totalDepositedValidators = ${maxDepositsCount2}` - ) - _checkEq( - summary.depositableValidatorsCount, - keysAmount - maxDepositsCount2, - `Summary depositableValidatorsCount = ${keysAmount - maxDepositsCount2}` - ) - - // as only 2 ops in module and each has 0 deposited keys before - const depositedKeysHalf = maxDepositsCount2 / 2 - let op1DepositedKeys - let op2DepositedKeys - if (op1keysAmount < depositedKeysHalf) { - op1DepositedKeys = op1keysAmount - op2DepositedKeys = maxDepositsCount2 - op1DepositedKeys - } else if (op2keysAmount < depositedKeysHalf) { - op2DepositedKeys = op2keysAmount - op1DepositedKeys = maxDepositsCount2 - op2DepositedKeys - } else { - op1DepositedKeys = depositedKeysHalf - op2DepositedKeys = depositedKeysHalf - } - - const op1 = await trgApp.getNodeOperator(0, false) - _checkEq(op1.totalAddedValidators, op1keysAmount, `op1 state: totalAddedValidators = ${op1keysAmount}`) - _checkEq( - op1.totalDepositedValidators, - op1DepositedKeys, - `op1 state: totalDepositedValidators = ${op1DepositedKeys}` - ) - - const op2 = await trgApp.getNodeOperator(1, false) - _checkEq(op2.totalAddedValidators, op2keysAmount, `op2 state: totalAddedValidators = ${op2keysAmount}`) - _checkEq( - op2.totalDepositedValidators, - op2DepositedKeys, - `op2 state: totalDepositedValidators = ${op2DepositedKeys}` - ) - - log(`Simulating Oracle report...`) - const stat = await lido.getBeaconStat() - const rewards = stat.beaconBalance.mul(toBN(5)).div(toBN(365000)) // 5% annual - const clBalance = stat.beaconBalance.add(toBN(maxDepositsCount2).mul(toBN(ETH(32)))).add(rewards) - - // pass 1 frame - const secondsPerFrame = await getSecondsPerFrame(consensus) - await ethers.provider.send('evm_increaseTime', [secondsPerFrame]) - await ethers.provider.send('evm_mine') - const members = await consensus.getMembers() - for (const member of members.addresses) { - await ethers.getImpersonatedSigner(member) - } - - const bal11 = await lido.balanceOf(ADDRESS_1) - const bal21 = await lido.balanceOf(ADDRESS_2) - - await reportOracle(consensus, oracle, { - numValidators: stat.depositedValidators, - clBalance, - }) - - const bal12 = await lido.balanceOf(ADDRESS_1) - const bal22 = await lido.balanceOf(ADDRESS_2) - - _checkEq(bal12.gt(bal11), true, 'op1 got rewards') - _checkEq(bal22.gt(bal21), true, 'op2 got rewards') - } finally { - log('Reverting snapshot...') - await snapshot.rollback() - } - } -} - -module.exports = runOrWrapScript(checkSimpleDVT, module) diff --git a/scripts/simpledvt/helpers.js b/scripts/simpledvt/helpers.js deleted file mode 100644 index ecbe7868b..000000000 --- a/scripts/simpledvt/helpers.js +++ /dev/null @@ -1,182 +0,0 @@ -const readline = require('readline') -const { assert } = require('chai') -const { log, rd, mg, yl } = require('../helpers/log') - -const KERNEL_APP_BASES_NAMESPACE = '0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f' - -const MANAGE_SIGNING_KEYS = '0x75abc64490e17b40ea1e66691c3eb493647b24430b358bd87ec3e5127f1621ee' -const MANAGE_NODE_OPERATOR_ROLE = '0x78523850fdd761612f46e844cf5a16bda6b3151d6ae961fd7e8e7b92bfbca7f8' -const SET_NODE_OPERATOR_LIMIT_ROLE = '0x07b39e0faf2521001ae4e58cb9ffd3840a63e205d288dc9c93c3774f0d794754' -const STAKING_ROUTER_ROLE = '0xbb75b874360e0bfd87f964eadd8276d8efb7c942134fc329b513032d0803e0c6' -const STAKING_MODULE_MANAGE_ROLE = '0x3105bcbf19d4417b73ae0e58d508a65ecf75665e46c2622d8521732de6080c48' -const REQUEST_BURN_SHARES_ROLE = '0x4be29e0e4eb91f98f709d98803cba271592782e293b84a625e025cbb40197ba8' -const SIMPLE_DVT_IPFS_CID = 'QmaSSujHCGcnFuetAPGwVW5BegaMBvn5SCsgi3LSfvraSo' - -const easyTrackABI = [ - { - inputs: [], - name: 'evmScriptExecutor', - outputs: [{ internalType: 'contract IEVMScriptExecutor', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_evmScriptFactory', - type: 'address', - }, - { - internalType: 'bytes', - name: '_permissions', - type: 'bytes', - }, - ], - name: 'addEVMScriptFactory', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], - name: 'evmScriptFactories', - outputs: [{ internalType: 'address', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [{ internalType: 'address', name: '', type: 'address' }], - name: 'evmScriptFactoryPermissions', - outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'getEVMScriptFactories', - outputs: [{ internalType: 'address[]', name: '', type: 'address[]' }], - stateMutability: 'view', - type: 'function', - }, - - { - inputs: [{ internalType: 'address', name: '_maybeEVMScriptFactory', type: 'address' }], - name: 'isEVMScriptFactory', - outputs: [{ internalType: 'bool', name: '', type: 'bool' }], - stateMutability: 'view', - type: 'function', - }, -] - -const easyTrackEvmExecutorABI = [ - { - inputs: [{ internalType: 'bytes', name: '_evmScript', type: 'bytes' }], - name: 'executeEVMScript', - outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], - stateMutability: 'nonpayable', - type: 'function', - }, -] - -const easyTrackFactoryABI = [ - { - inputs: [ - { internalType: 'address', name: '_creator', type: 'address' }, - { internalType: 'bytes', name: '_evmScriptCallData', type: 'bytes' }, - ], - name: 'createEVMScript', - outputs: [{ internalType: 'bytes', name: '', type: 'bytes' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'nodeOperatorsRegistry', - outputs: [{ internalType: 'contract INodeOperatorsRegistry', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'trustedCaller', - outputs: [{ internalType: 'address', name: '', type: 'address' }], - stateMutability: 'view', - type: 'function', - }, -] - -async function getDeployer(web3, defaultDeployer) { - if (!defaultDeployer) { - const [firstAccount] = await web3.eth.getAccounts() - return firstAccount - } - return defaultDeployer -} - -function readStateAppAddress(state, app = '') { - const appState = state[app] - // goerli/mainnet deployed.json formats compatibility - return appState.proxyAddress || (appState.proxy && appState.proxy.address) || appState.address -} - -function getSignature(instance, method) { - const methodAbi = instance.contract._jsonInterface.find((i) => i.name === method) - if (!methodAbi) { - throw new Error(`Method ${method} not found in contract`) - } - return methodAbi.signature -} - -function _checkEq(a, b, descr = '') { - assert.equal(a, b, descr) - log.success(descr) -} - -function _checkLog(value, msg) { - log(msg, yl(value)) - assert.isDefined(value, 'Value is missing') -} - -function _checkEqLog(value, etalon, msg) { - log(msg, yl(value)) - assert.equal(value, etalon, `Value not equal to: ${etalon}`) -} - -function _pause(msg) { - if (msg) log(rd(`!!! ${msg}`)) - const rl = readline.createInterface({ input: process.stdin, output: process.stdout }) - const query = mg('>>> Enter Y (or y) to continue, interrupt process otherwise:') - - return new Promise((resolve) => - rl.question(query, (ans) => { - rl.close() - if (ans !== 'y' && ans !== 'Y') { - console.error(rd('Process aborted')) - process.exit(1) - } - resolve() - }) - ) -} - -module.exports = { - readStateAppAddress, - getDeployer, - getSignature, - _checkEq, - _checkLog, - _checkEqLog, - _pause, - KERNEL_APP_BASES_NAMESPACE, - MANAGE_SIGNING_KEYS, - MANAGE_NODE_OPERATOR_ROLE, - SET_NODE_OPERATOR_LIMIT_ROLE, - STAKING_ROUTER_ROLE, - STAKING_MODULE_MANAGE_ROLE, - REQUEST_BURN_SHARES_ROLE, - SIMPLE_DVT_IPFS_CID, - easyTrackABI, - easyTrackEvmExecutorABI, - easyTrackFactoryABI, -}