Skip to content

Commit

Permalink
fix: easytrack permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
krogla committed Oct 8, 2023
1 parent f18b09a commit 87272fe
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 43 deletions.
24 changes: 19 additions & 5 deletions scripts/simpledvt/01-deploy-app-proxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const { hash: namehash } = require('eth-ens-namehash')
const APP_TRG = process.env.APP_TRG || 'simple-dvt'
const DEPLOYER = process.env.DEPLOYER || ''

const REQUIRED_NET_STATE = ['lidoApmAddress', 'lidoApmEnsName', 'daoAddress']
const REQUIRED_NET_STATE = ['lidoApmAddress', 'lidoApmEnsName']

async function deployEmptyProxy({ web3, artifacts, trgAppName = APP_TRG }) {
const netId = await web3.eth.net.getId()
Expand All @@ -40,18 +40,23 @@ async function deployEmptyProxy({ web3, artifacts, trgAppName = APP_TRG }) {
let trgProxyAddress

if (state[`app:${trgAppName}`]) {
trgProxyAddress = readStateAppAddress(state, `app:${trgAppName}`, yl(trgProxyAddress))
trgProxyAddress = readStateAppAddress(state, `app:${trgAppName}`)
}

if (trgProxyAddress && (await web3.eth.getCode(trgProxyAddress)) !== '0x') {
log.error(`Target app proxy is already deployed at`)
return
}

const kernel = await artifacts.require('Kernel').at(state.daoAddress)
const kernelAddress = state.daoAddress || readStateAppAddress(state, `aragon-kernel`)
if (!kernelAddress) {
log.error(`No Aragon kernel found!`)
return
}
const kernel = await artifacts.require('Kernel').at(kernelAddress)
const tx = await log.tx(
`Deploying proxy for ${trgAppName}`,
kernel.newAppProxy(kernel.address, trgAppId, { from: deployer })
kernel.newAppProxy(kernelAddress, trgAppId, { from: deployer })
)
// Find the deployed proxy address in the tx logs.
const e = tx.logs.find((l) => l.event === 'NewAppProxy')
Expand All @@ -60,7 +65,16 @@ async function deployEmptyProxy({ web3, artifacts, trgAppName = APP_TRG }) {
// upd deployed state
persistNetworkState2(network.name, netId, state, {
[`app:${trgAppName}`]: {
proxyAddress: trgProxyAddress,
aragonApp: {
name: trgAppName,
fullName: trgAppFullName,
id: trgAppId,
},
proxy: {
address: trgProxyAddress,
contract: '@aragon/os/contracts/apps/AppProxyUpgradeable.sol',
constructorArgs: [kernelAddress, trgAppId, '0x'],
},
},
})

Expand Down
181 changes: 143 additions & 38 deletions scripts/simpledvt/02-clone-nor.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { network, ethers } = require('hardhat')
const chalk = require('chalk')

const { Contract } = require('ethers')
const { encodeCallScript } = require('@aragon/contract-helpers-test/src/aragon-os')
const { getEventArgument } = require('@aragon/contract-helpers-test')

Expand Down Expand Up @@ -35,7 +35,6 @@ 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 EASYTRACK = process.env.EASYTRACK || ''
const SIMULATE = !!process.env.SIMULATE
// const EXTERNAL_DEPLOYER = !!process.env.EXTERNAL_DEPLOYER

Expand Down Expand Up @@ -83,9 +82,17 @@ async function deployNORClone({ web3, artifacts, trgAppName = APP_TRG, ipfsCid =

const trgAppFullName = `${trgAppName}.${state.lidoApmEnsName}`
const trgAppId = namehash(trgAppFullName)
const trgRepoAddress = await resolveEnsAddress(artifacts, ens, trgAppId)
const trgProxyAddress = readStateAppAddress(state, `app:${trgAppName}`)
const trgAppArtifact = APP_ARTIFACTS[srcAppName] // get source app artifact
const trgApp = await artifacts.require(trgAppArtifact).at(trgProxyAddress)

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
}

// set new version to 1.0.0
const trgVersion = [1, 0, 0]
Expand All @@ -108,6 +115,9 @@ async function deployNORClone({ web3, artifacts, trgAppName = APP_TRG, ipfsCid =
moduleFee = 500,
treasuryFee = 500,
penaltyDelay,
easyTrackAddress,
easyTrackEVMScriptExecutor,
easyTrackFactories = {},
} = state[`app:${trgAppName}`].stakingRouterModuleParams
log(`Target SR Module name`, yl(moduleName))
log(`Target SR Module type`, yl(moduleType))
Expand All @@ -121,6 +131,8 @@ async function deployNORClone({ web3, artifacts, trgAppName = APP_TRG, ipfsCid =
return
}

const trgRepoAddress = await resolveEnsAddress(artifacts, ens, trgAppId)

if (trgRepoAddress && (await web3.eth.getCode(trgProxyAddress)) !== '0x') {
log(`Target App APM repo:`, yl(trgRepoAddress))
log.error(`Target app is already deployed!`)
Expand All @@ -138,13 +150,35 @@ async function deployNORClone({ web3, artifacts, trgAppName = APP_TRG, ipfsCid =
const stakingRouter = await artifacts.require('StakingRouter').at(srAddress)
const apmRegistry = await artifacts.require('APMRegistry').at(state.lidoApmAddress)

const trgApp = await artifacts.require(trgAppArtifact).at(trgProxyAddress)
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 easytrackABI = [
{
inputs: [
{
internalType: 'address',
name: '_evmScriptFactory',
type: 'address',
},
{
internalType: 'bytes',
name: '_permissions',
type: 'bytes',
},
],
name: 'addEVMScriptFactory',
outputs: [],
stateMutability: 'nonpayable',
type: 'function',
},
]

// use ethers.js Contract instance
const easytrack = new Contract(easyTrackAddress, easytrackABI)
const evmScriptCalls = [
// create app repo
{
Expand All @@ -168,41 +202,113 @@ async function deployNORClone({ web3, artifacts, trgAppName = APP_TRG, ipfsCid =
]

// set permissions
const srcAppPerms = [
{
grantee: votingAddress, // default to voting
roles: {
MANAGE_SIGNING_KEYS,
MANAGE_NODE_OPERATOR_ROLE,
SET_NODE_OPERATOR_LIMIT_ROLE,
},
},
{
grantee: srAddress,
roles: { STAKING_ROUTER_ROLE },
},
]

// grant keys limit role to easytrack if defined
if (EASYTRACK) {
srcAppPerms.push({
grantee: EASYTRACK,
roles: {
SET_NODE_OPERATOR_LIMIT_ROLE,
},
})
}
// grant perm for staking router
evmScriptCalls.push({
to: acl.address,
calldata: await acl.contract.methods
.createPermission(srAddress, trgProxyAddress, STAKING_ROUTER_ROLE, votingAddress)
.encodeABI(),
})

for (const group of srcAppPerms) {
for (const roleId of Object.values(group.roles)) {
evmScriptCalls.push({
to: acl.address,
calldata: await acl.contract.methods
.createPermission(group.grantee, trgProxyAddress, roleId, 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.TransferNodeOperatorManager,
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))) {
Expand Down Expand Up @@ -249,7 +355,6 @@ async function deployNORClone({ web3, artifacts, trgAppName = APP_TRG, ipfsCid =
contentURI,
implementation: contractAddress,
contract: trgAppArtifact,
easytrackAddress: EASYTRACK,
},
})

Expand Down

0 comments on commit 87272fe

Please sign in to comment.