From f85b38622220040ec0fffeaf4c5cd09868feb1d4 Mon Sep 17 00:00:00 2001 From: Roman Kolpakov Date: Tue, 21 Jan 2025 19:01:12 +0300 Subject: [PATCH] wip: to be recommited --- .../aragon-permissions.json | 8 + .../agent-transfer-permissions-config.ts | 300 +++++++++--------- .../config/lido-contracts.ts | 36 +-- .../contracts/AragonRolesVerifier.sol | 34 ++ .../deploy/deploy-aragon-verifier.ts | 63 ++++ scripts/permissions-migration/index.ts | 43 +-- .../src/aragon-generate-json.ts | 45 +++ .../src/aragon-permissions.ts | 46 +-- .../permissions-migration/src/comparison.ts | 1 + 9 files changed, 352 insertions(+), 224 deletions(-) create mode 100644 scripts/permissions-migration/aragon-permissions.json create mode 100644 scripts/permissions-migration/contracts/AragonRolesVerifier.sol create mode 100644 scripts/permissions-migration/deploy/deploy-aragon-verifier.ts create mode 100644 scripts/permissions-migration/src/aragon-generate-json.ts create mode 100644 scripts/permissions-migration/src/comparison.ts diff --git a/scripts/permissions-migration/aragon-permissions.json b/scripts/permissions-migration/aragon-permissions.json new file mode 100644 index 00000000..db90fae2 --- /dev/null +++ b/scripts/permissions-migration/aragon-permissions.json @@ -0,0 +1,8 @@ +[ + { + "where": "0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034", + "what": "0xa42eee1333c0758ba72be38e728b6dadb32ea767de5b4ddbaea1dae85b1b051f", + "who": "0xE92329EC7ddB11D25e25b3c21eeBf11f15eB325d", + "granted": true + } +] diff --git a/scripts/permissions-migration/config/agent-transfer-permissions-config.ts b/scripts/permissions-migration/config/agent-transfer-permissions-config.ts index dc3e1426..cc9ca5d1 100644 --- a/scripts/permissions-migration/config/agent-transfer-permissions-config.ts +++ b/scripts/permissions-migration/config/agent-transfer-permissions-config.ts @@ -10,161 +10,161 @@ export const ARAGON_CONTRACT_ROLES_CONFIG: AragonContractPermissionConfigs = { Lido: { address: LIDO_CONTRACTS.Lido, permissions: { - STAKING_CONTROL_ROLE: { manager: "None" }, - RESUME_ROLE: { manager: "None" }, - PAUSE_ROLE: { manager: "None" }, - UNSAFE_CHANGE_DEPOSITED_VALIDATORS_ROLE: { manager: "None" }, - STAKING_PAUSE_ROLE: { manager: "None" }, + STAKING_CONTROL_ROLE: { manager: "None", grantedTo: ["Agent"] }, + // RESUME_ROLE: { manager: "None" }, + // PAUSE_ROLE: { manager: "None" }, + // UNSAFE_CHANGE_DEPOSITED_VALIDATORS_ROLE: { manager: "None" }, + // STAKING_PAUSE_ROLE: { manager: "None" }, }, }, // Oracle Contracts - LegacyOracle: { - address: LIDO_CONTRACTS.LegacyOracle, - permissions: {}, - }, + // LegacyOracle: { + // address: LIDO_CONTRACTS.LegacyOracle, + // permissions: {}, + // }, - // DAO Contracts - DAOKernel: { - address: LIDO_CONTRACTS.DAOKernel, - permissions: { - APP_MANAGER_ROLE: { manager: "Agent" }, - }, - }, - Voting: { - address: LIDO_CONTRACTS.Voting, - permissions: { - UNSAFELY_MODIFY_VOTE_TIME_ROLE: { manager: "Voting" }, - MODIFY_QUORUM_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, - MODIFY_SUPPORT_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, - CREATE_VOTES_ROLE: { manager: "Voting", grantedTo: ["TokenManager"] }, - }, - }, - TokenManager: { - address: LIDO_CONTRACTS.TokenManager, - permissions: { - ISSUE_ROLE: { manager: "Voting" }, - ASSIGN_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, - BURN_ROLE: { manager: "Voting" }, - MINT_ROLE: { manager: "Voting" }, - REVOKE_VESTINGS_ROLE: { manager: "Voting" }, - }, - }, - Finance: { - address: LIDO_CONTRACTS.Finance, - permissions: { - CREATE_PAYMENTS_ROLE: { - manager: "Voting", - grantedTo: ["Voting", "EasyTrackEvmScriptExecutor"], - }, - CHANGE_PERIOD_ROLE: { manager: "Voting" }, - CHANGE_BUDGETS_ROLE: { manager: "Voting" }, - EXECUTE_PAYMENTS_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, - MANAGE_PAYMENTS_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, - }, - }, - Agent: { - address: LIDO_CONTRACTS.Agent, - permissions: { - ADD_PROTECTED_TOKEN_ROLE: { manager: "Voting" }, - REMOVE_PROTECTED_TOKEN_ROLE: { manager: "Voting" }, - TRANSFER_ROLE: { manager: "Voting", grantedTo: ["Finance"] }, - RUN_SCRIPT_ROLE: { - manager: "DualGovernance", - grantedTo: ["DualGovernance"], - }, - SAFE_EXECUTE_ROLE: { manager: "None" }, - DESIGNATE_SIGNER_ROLE: { manager: "Voting" }, - EXECUTE_ROLE: { - manager: "DualGovernance", - grantedTo: ["DualGovernance"], - }, - ADD_PRESIGNED_HASH_ROLE: { manager: "Voting" }, - }, - }, - ACL: { - address: LIDO_CONTRACTS.ACL, - permissions: { CREATE_PERMISSIONS_ROLE: { manager: "Agent" } }, - }, - AragonPM: { - address: LIDO_CONTRACTS.AragonPM, - permissions: { - CREATE_REPO_ROLE: { manager: "None" }, - }, - }, - EVMScriptRegistry: { - address: LIDO_CONTRACTS.EVMScriptRegistry, - permissions: { - REGISTRY_ADD_EXECUTOR_ROLE: { manager: "None" }, - REGISTRY_MANAGER_ROLE: { manager: "None" }, - }, - }, - VotingRepo: { - address: LIDO_CONTRACTS.VotingRepo, - permissions: { - CREATE_VERSION_ROLE: { manager: "None" }, - }, - }, - LidoRepo: { - address: LIDO_CONTRACTS.LidoRepo, - permissions: { - CREATE_VERSION_ROLE: { manager: "None" }, - }, - }, - LegacyOracleRepo: { - address: LIDO_CONTRACTS.LegacyOracleRepo, - permissions: { - CREATE_VERSION_ROLE: { manager: "None" }, - }, - }, - CuratedModuleRepo: { - address: LIDO_CONTRACTS.CuratedModuleRepo, - permissions: { - CREATE_VERSION_ROLE: { manager: "None" }, - }, - }, - SimpleDVTRepo: { - address: LIDO_CONTRACTS.SimpleDVTRepo, - permissions: { - CREATE_VERSION_ROLE: { manager: "None" }, - }, - }, - // Staking Modules - CuratedModule: { - address: LIDO_CONTRACTS.CuratedModule, - permissions: { - STAKING_ROUTER_ROLE: { manager: "Agent", grantedTo: ["StakingRouter"] }, - MANAGE_NODE_OPERATOR_ROLE: { manager: "Agent", grantedTo: ["Agent"] }, - SET_NODE_OPERATOR_LIMIT_ROLE: { - manager: "Agent", - grantedTo: ["EasyTrackEvmScriptExecutor"], - }, - MANAGE_SIGNING_KEYS: { - manager: "Agent", - }, - }, - }, - SimpleDVT: { - address: LIDO_CONTRACTS.SimpleDVT, - permissions: { - STAKING_ROUTER_ROLE: { - manager: "Agent", - grantedTo: ["StakingRouter", "EasyTrackEvmScriptExecutor"], - }, - MANAGE_NODE_OPERATOR_ROLE: { - manager: "Agent", - grantedTo: ["EasyTrackEvmScriptExecutor"], - }, - SET_NODE_OPERATOR_LIMIT_ROLE: { - manager: "Agent", - grantedTo: ["EasyTrackEvmScriptExecutor"], - }, - MANAGE_SIGNING_KEYS: { - manager: "EasyTrackEvmScriptExecutor", - grantedTo: ["EasyTrackEvmScriptExecutor"], - }, - }, - }, + // // DAO Contracts + // DAOKernel: { + // address: LIDO_CONTRACTS.DAOKernel, + // permissions: { + // APP_MANAGER_ROLE: { manager: "Agent" }, + // }, + // }, + // Voting: { + // address: LIDO_CONTRACTS.Voting, + // permissions: { + // UNSAFELY_MODIFY_VOTE_TIME_ROLE: { manager: "Voting" }, + // MODIFY_QUORUM_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, + // MODIFY_SUPPORT_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, + // CREATE_VOTES_ROLE: { manager: "Voting", grantedTo: ["TokenManager"] }, + // }, + // }, + // TokenManager: { + // address: LIDO_CONTRACTS.TokenManager, + // permissions: { + // ISSUE_ROLE: { manager: "Voting" }, + // ASSIGN_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, + // BURN_ROLE: { manager: "Voting" }, + // MINT_ROLE: { manager: "Voting" }, + // REVOKE_VESTINGS_ROLE: { manager: "Voting" }, + // }, + // }, + // Finance: { + // address: LIDO_CONTRACTS.Finance, + // permissions: { + // CREATE_PAYMENTS_ROLE: { + // manager: "Voting", + // grantedTo: ["Voting", "EasyTrackEvmScriptExecutor"], + // }, + // CHANGE_PERIOD_ROLE: { manager: "Voting" }, + // CHANGE_BUDGETS_ROLE: { manager: "Voting" }, + // EXECUTE_PAYMENTS_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, + // MANAGE_PAYMENTS_ROLE: { manager: "Voting", grantedTo: ["Voting"] }, + // }, + // }, + // Agent: { + // address: LIDO_CONTRACTS.Agent, + // permissions: { + // ADD_PROTECTED_TOKEN_ROLE: { manager: "Voting" }, + // REMOVE_PROTECTED_TOKEN_ROLE: { manager: "Voting" }, + // TRANSFER_ROLE: { manager: "Voting", grantedTo: ["Finance"] }, + // RUN_SCRIPT_ROLE: { + // manager: "DualGovernance", + // grantedTo: ["DualGovernance"], + // }, + // SAFE_EXECUTE_ROLE: { manager: "None" }, + // DESIGNATE_SIGNER_ROLE: { manager: "Voting" }, + // EXECUTE_ROLE: { + // manager: "DualGovernance", + // grantedTo: ["DualGovernance"], + // }, + // ADD_PRESIGNED_HASH_ROLE: { manager: "Voting" }, + // }, + // }, + // ACL: { + // address: LIDO_CONTRACTS.ACL, + // permissions: { CREATE_PERMISSIONS_ROLE: { manager: "Agent" } }, + // }, + // AragonPM: { + // address: LIDO_CONTRACTS.AragonPM, + // permissions: { + // CREATE_REPO_ROLE: { manager: "None" }, + // }, + // }, + // EVMScriptRegistry: { + // address: LIDO_CONTRACTS.EVMScriptRegistry, + // permissions: { + // REGISTRY_ADD_EXECUTOR_ROLE: { manager: "None" }, + // REGISTRY_MANAGER_ROLE: { manager: "None" }, + // }, + // }, + // VotingRepo: { + // address: LIDO_CONTRACTS.VotingRepo, + // permissions: { + // CREATE_VERSION_ROLE: { manager: "None" }, + // }, + // }, + // LidoRepo: { + // address: LIDO_CONTRACTS.LidoRepo, + // permissions: { + // CREATE_VERSION_ROLE: { manager: "None" }, + // }, + // }, + // LegacyOracleRepo: { + // address: LIDO_CONTRACTS.LegacyOracleRepo, + // permissions: { + // CREATE_VERSION_ROLE: { manager: "None" }, + // }, + // }, + // CuratedModuleRepo: { + // address: LIDO_CONTRACTS.CuratedModuleRepo, + // permissions: { + // CREATE_VERSION_ROLE: { manager: "None" }, + // }, + // }, + // SimpleDVTRepo: { + // address: LIDO_CONTRACTS.SimpleDVTRepo, + // permissions: { + // CREATE_VERSION_ROLE: { manager: "None" }, + // }, + // }, + // // Staking Modules + // CuratedModule: { + // address: LIDO_CONTRACTS.CuratedModule, + // permissions: { + // STAKING_ROUTER_ROLE: { manager: "Agent", grantedTo: ["StakingRouter"] }, + // MANAGE_NODE_OPERATOR_ROLE: { manager: "Agent", grantedTo: ["Agent"] }, + // SET_NODE_OPERATOR_LIMIT_ROLE: { + // manager: "Agent", + // grantedTo: ["EasyTrackEvmScriptExecutor"], + // }, + // MANAGE_SIGNING_KEYS: { + // manager: "Agent", + // }, + // }, + // }, + // SimpleDVT: { + // address: LIDO_CONTRACTS.SimpleDVT, + // permissions: { + // STAKING_ROUTER_ROLE: { + // manager: "Agent", + // grantedTo: ["StakingRouter", "EasyTrackEvmScriptExecutor"], + // }, + // MANAGE_NODE_OPERATOR_ROLE: { + // manager: "Agent", + // grantedTo: ["EasyTrackEvmScriptExecutor"], + // }, + // SET_NODE_OPERATOR_LIMIT_ROLE: { + // manager: "Agent", + // grantedTo: ["EasyTrackEvmScriptExecutor"], + // }, + // MANAGE_SIGNING_KEYS: { + // manager: "EasyTrackEvmScriptExecutor", + // grantedTo: ["EasyTrackEvmScriptExecutor"], + // }, + // }, + // }, }; export const OZ_CONTRACT_ROLES_CONFIG: OZContractRolesConfig = { diff --git a/scripts/permissions-migration/config/lido-contracts.ts b/scripts/permissions-migration/config/lido-contracts.ts index caaabb9d..4b23ae18 100644 --- a/scripts/permissions-migration/config/lido-contracts.ts +++ b/scripts/permissions-migration/config/lido-contracts.ts @@ -11,7 +11,7 @@ export type LidoContractName = export const LIDO_CONTRACTS = { // Core Protocol LidoLocator: "0xC1d0b3DE6792Bf6b4b37EccdcC24e45978Cfd2Eb", - Lido: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84", + Lido: "0x3F1c547b21f65e10480dE3ad8E19fAAC46C95034", StakingRouter: "0xFdDf38947aFB03C621C71b06C9C70bce73f12999", DepositSecurityModule: "0xffa96d84def2ea035c7ab153d8b991128e3d72fd", ExecutionLayerRewardsVault: "0x388C818CA8B9251b393131C08a736A67ccB19297", @@ -31,11 +31,11 @@ export const LIDO_CONTRACTS = { // DAO Contracts DAOKernel: "0xb8FFC3Cd6e7Cf5a098A1c92F48009765B24088Dc", - Voting: "0x2e59A20f205bB85a89C53f1936454680651E618e", + Voting: "0xdA7d2573Df555002503F29aA4003e398d28cc00f ", Agent: "0x3e40D73EB977Dc6a537aF587D48316feE66E9C8c", TokenManager: "0xf73a1260d222f447210581DDf212D915c09a3249", Finance: "0xB9E5CBB9CA5b0d659238807E84D0176930753d86", - ACL: "0x9895f0f17cc1d1891b6f18ee0b483b6f221b37bb", + ACL: "0xfd1E42595CeC3E83239bf8dFc535250e7F48E0bC", AragonPM: "0x0cb113890b04b49455dfe06554e2d784598a29c9", VotingRepo: "0x4ee3118e3858e8d7164a634825bfe0f73d99c792", LidoRepo: "0xF5Dc67E54FC96F993CD06073f71ca732C1E654B1", @@ -66,36 +66,6 @@ export const LIDO_CONTRACTS = { EasyTrackEvmScriptExecutor: "0xFE5986E06210aC1eCC1aDCafc0cc7f8D63B3F977", // Easy Track Factories for token transfers - LOLStETH_AllowedRecipientsRegistry: - "0x48c4929630099b217136b64089E8543dB0E5163a", - RewardsShareStETH_AllowedRecipientsRegistry: - "0xdc7300622948a7AdaF339783F6991F9cdDD79776", - LegoLDO_AllowedRecipientsRegistry: - "0x97615f72c3428A393d65A84A3ea6BBD9ad6C0D74", - LegoStablecoins_AllowedRecipientsRegistry: - "0xb0FE4D300334461523D9d61AaD90D0494e1Abb43", - RCCStableCoins_AllowedRecipientsRegistry: - "0xDc1A0C7849150f466F07d48b38eAA6cE99079f80", - RCCStETH_AllowedRecipientsRegistry: - "0xAAC4FcE2c5d55D1152512fe5FAA94DB267EE4863", - PMLStablecoins_AllowedRecipientsRegistry: - "0xDFfCD3BF14796a62a804c1B16F877Cf7120379dB", - PMLStETH_AllowedRecipientsRegistry: - "0x7b9B8d00f807663d46Fb07F87d61B79884BC335B", - ATCStablecoins_AllowedRecipientsRegistry: - "0xe07305F43B11F230EaA951002F6a55a16419B707", - ATCStETH_AllowedRecipientsRegistry: - "0xd3950eB3d7A9B0aBf8515922c0d35D13e85a2c91", - TRPLDO_AllowedRecipientsRegistry: - "0x231Ac69A1A37649C6B06a71Ab32DdD92158C80b8", - GasSupplyStETH_AllowedRecipientsRegistry: - "0x49d1363016aA899bba09ae972a1BF200dDf8C55F", - AllianceOpsStablecoins_AllowedRecipientsRegistry: - "0x3B525F4c059F246Ca4aa995D21087204F30c9E2F", - StonksStETH_AllowedRecipientsRegistry: - "0x1a7cFA9EFB4D5BfFDE87B0FaEb1fC65d653868C0", - StonksStablecoins_AllowedRecipientsRegistry: - "0x3f0534CCcFb952470775C516DC2eff8396B8A368", AllowedTokensRegistry: "0x4AC40c34f8992bb1e5E856A448792158022551ca", // Arbitrum diff --git a/scripts/permissions-migration/contracts/AragonRolesVerifier.sol b/scripts/permissions-migration/contracts/AragonRolesVerifier.sol new file mode 100644 index 00000000..ea6eaded --- /dev/null +++ b/scripts/permissions-migration/contracts/AragonRolesVerifier.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.26; + +interface ACL { + function hasPermission(address _who, address _where, bytes32 _what) external view returns (bool); +} + +contract AragonRolesVerifier { + struct RoleToVerify { + address who; + bytes32 what; + address where; + bool granted; + } + + address public constant ACL_ADDRESS = 0xfd1E42595CeC3E83239bf8dFc535250e7F48E0bC; + + RoleToVerify[] public rolesToVerify; + + constructor(RoleToVerify[] memory _rolesToVerify) { + for (uint256 i = 0; i < _rolesToVerify.length; i++) { + rolesToVerify.push(_rolesToVerify[i]); + } + } + + function verify() public view { + ACL acl = ACL(ACL_ADDRESS); + for (uint256 i = 0; i < rolesToVerify.length; i++) { + bool isPermissionGranted = + acl.hasPermission(rolesToVerify[i].who, rolesToVerify[i].where, rolesToVerify[i].what); + assert(isPermissionGranted == rolesToVerify[i].granted); + } + } +} diff --git a/scripts/permissions-migration/deploy/deploy-aragon-verifier.ts b/scripts/permissions-migration/deploy/deploy-aragon-verifier.ts new file mode 100644 index 00000000..54e54c05 --- /dev/null +++ b/scripts/permissions-migration/deploy/deploy-aragon-verifier.ts @@ -0,0 +1,63 @@ +import fs from "fs"; + +import { getAddress, hexlify } from "ethers"; +import { JsonRpcProvider, Wallet, ContractFactory } from "ethers"; + +export async function deployAragonVerifier( + provider: JsonRpcProvider, + privateKey?: string, + etherscanApiKey?: string, +) { + if (!privateKey) throw new Error("PRIVATE_KEY env variable is missing."); + if (!etherscanApiKey) + throw new Error("ETHERSCAN_API env variable is missing."); + + const wallet = new Wallet(privateKey, provider); + const contractJson = JSON.parse( + fs.readFileSync( + "./out/AragonRolesVerifier.sol/AragonRolesVerifier.json", + "utf8", + ), + ); + const contractABI = contractJson.abi; + const contractBytecode = contractJson.bytecode; + + const rawData = JSON.parse( + fs.readFileSync( + "./scripts/permissions-migration/aragon-permissions.json", + "utf8", + ), + ); + + console.log(rawData[0]); + + const roles = rawData.map((role: any) => ({ + who: getAddress(role.who), + what: hexlify(role.what), + where: getAddress(role.where), + granted: role.granted, + })); + + (async () => { + try { + console.log("🚀 Деплоим AragonRolesVerifier..."); + + // 📌 Создать контрактный factory + const factory = new ContractFactory( + contractABI, + contractBytecode, + wallet, + ); + + // 📌 Деплоить контракт с массивом структур + const contract = await factory.deploy(roles); + + console.log("📡 Ожидание деплоя..."); + await contract.waitForDeployment(); + + console.log(`✅ Контракт развернут по адресу: ${contract.target}`); + } catch (error) { + console.error("❌ Ошибка при деплое:", error); + } + })(); +} diff --git a/scripts/permissions-migration/index.ts b/scripts/permissions-migration/index.ts index 83a92b16..af7b38ae 100644 --- a/scripts/permissions-migration/index.ts +++ b/scripts/permissions-migration/index.ts @@ -6,6 +6,9 @@ import aragon from "./src/aragon-permissions"; import managed from "./src/managed-contracts"; import { retrieveDeployConfiguration } from "./src/aragon-deploy"; +import { aragonGenerateJson } from "./src/aragon-generate-json"; +import { deployAragonVerifier } from "./deploy/deploy-aragon-verifier"; + import { ARAGON_CONTRACT_ROLES_CONFIG, MANAGED_CONTRACTS, @@ -13,6 +16,8 @@ import { } from "./config/agent-transfer-permissions-config"; const RPC_URL = process.env.MAINNET_RPC_URL; +const PRIVATE_KEY = process.env.PRIVATE_KEY; +const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY; if (!RPC_URL) { throw new Error("RPC_URL env variable not set"); @@ -21,25 +26,27 @@ if (!RPC_URL) { async function main() { const provider = new JsonRpcProvider(RPC_URL); console.log(`## Lido Permissions Transitions`); - console.log( - aragon.formatContractPermissionsSection( - await aragon.collectPermissionsData( - provider, - ARAGON_CONTRACT_ROLES_CONFIG - ) - ) - ); - console.log( - oz.formatContractRolesSection( - await oz.collectRolesInfo(provider, OZ_CONTRACT_ROLES_CONFIG) - ) - ); - console.log( - managed.formatControlledContractsSection( - await managed.collectManagedContractsInfo(provider, MANAGED_CONTRACTS) - ) + const aragonPermissions = await aragon.collectPermissionsData( + provider, + ARAGON_CONTRACT_ROLES_CONFIG, ); - console.log(await retrieveDeployConfiguration(provider)); + + aragonGenerateJson(aragonPermissions); + // deployAragonVerifier(provider, PRIVATE_KEY, ETHERSCAN_API_KEY); + + // const ozPermissions = await oz.collectRolesInfo( + // provider, + // OZ_CONTRACT_ROLES_CONFIG, + // ); + // const managedContractsInfo = await managed.collectManagedContractsInfo( + // provider, + // MANAGED_CONTRACTS, + // ); + + // console.log(aragon.formatContractPermissionsSection(aragonPermissions)); + // console.log(oz.formatContractRolesSection(ozPermissions)); + // console.log(managed.formatControlledContractsSection(managedContractsInfo)); + // console.log(await retrieveDeployConfiguration(provider)); } main().catch((error) => { diff --git a/scripts/permissions-migration/src/aragon-generate-json.ts b/scripts/permissions-migration/src/aragon-generate-json.ts new file mode 100644 index 00000000..4f054453 --- /dev/null +++ b/scripts/permissions-migration/src/aragon-generate-json.ts @@ -0,0 +1,45 @@ +import { writeFileSync } from "fs"; +import { keccak256, toUtf8Bytes } from "ethers"; +import { AragonPermissionsInfo } from "./aragon-permissions"; +import { LIDO_CONTRACTS } from "../config/lido-contracts"; + +export async function aragonGenerateJson( + aragonPermissions: AragonPermissionsInfo, +) { + const result: any = []; + + for (const contract of Object.keys(aragonPermissions)) { + const contractAddress = contract as keyof typeof LIDO_CONTRACTS; + const modifiedPermissions = aragonPermissions[contract].filter( + (permission) => permission.isModified, + ); + if (!modifiedPermissions.length) continue; + + for (const permission of modifiedPermissions) { + for (const grantee of permission.holdersToGrantRole) { + if (grantee == "DualGovernance") continue; + result.push({ + where: LIDO_CONTRACTS[contractAddress], + what: keccak256(toUtf8Bytes(permission.name)), + who: LIDO_CONTRACTS[grantee as keyof typeof LIDO_CONTRACTS], + granted: true, + }); + } + + for (const grantee of permission.holdersToRevokeRole) { + if (grantee == "DualGovernance") continue; + result.push({ + where: LIDO_CONTRACTS[contractAddress], + what: keccak256(toUtf8Bytes(permission.name)), + who: LIDO_CONTRACTS[grantee as keyof typeof LIDO_CONTRACTS], + granted: false, + }); + } + } + } + + writeFileSync( + "./scripts/permissions-migration/aragon-permissions.json", + JSON.stringify(result), + ); +} diff --git a/scripts/permissions-migration/src/aragon-permissions.ts b/scripts/permissions-migration/src/aragon-permissions.ts index b5aec105..396be772 100644 --- a/scripts/permissions-migration/src/aragon-permissions.ts +++ b/scripts/permissions-migration/src/aragon-permissions.ts @@ -33,7 +33,7 @@ export type AragonContractPermissionConfigs = Record< AragonContractPermissionConfig >; -interface AragonPermissionInfo { +export interface AragonPermissionInfo { name: string; isModified: boolean; oldManager: LidoContractName; @@ -43,7 +43,7 @@ interface AragonPermissionInfo { holderAlreadyGrantedWithRole: LidoContractName[]; } -interface AragonPermissionsInfo { +export interface AragonPermissionsInfo { [contractName: string]: AragonPermissionInfo[]; } @@ -61,7 +61,7 @@ interface AragonPermissionHolders { } function formatContractPermissionsSection( - aragonContractsInfo: AragonPermissionsInfo + aragonContractsInfo: AragonPermissionsInfo, ) { const resSectionLines: string[] = ["### Aragon Roles Transition \n"]; @@ -88,17 +88,17 @@ function formatPermissionsInfoTable(aragonRolesInfo: AragonPermissionInfo[]) { let modifiedRolesCount = 0; for (const role of aragonRolesInfo.sort( - (a, b) => Number(!a.isModified) - Number(!b.isModified) + (a, b) => Number(!a.isModified) - Number(!b.isModified), )) { if (role.isModified) { modifiedRolesCount += 1; } const oldManagerLabel = md.label( - role.oldManager === "None" ? md.empty() : role.oldManager + role.oldManager === "None" ? md.empty() : role.oldManager, ); const newManagerLabel = md.label( - role.newManager === "None" ? md.empty() : role.newManager + role.newManager === "None" ? md.empty() : role.newManager, ); const managerTransition = @@ -107,31 +107,31 @@ function formatPermissionsInfoTable(aragonRolesInfo: AragonPermissionInfo[]) { : md.label(oldManagerLabel); const unknownRoleHolders = role.holdersToRevokeRole.filter((holderName) => - holderName.startsWith("Unknown") + holderName.startsWith("Unknown"), ); const knownRoleHolders = role.holdersToRevokeRole.filter( - (holderName) => !holderName.startsWith("Unknown") + (holderName) => !holderName.startsWith("Unknown"), ); const revokedFromItems = role.holdersToRevokeRole.length === 0 ? [md.empty()] : knownRoleHolders.map((roleHolder) => - md.bold(md.label(CONTRACT_LABELS[roleHolder] ?? roleHolder)) + md.bold(md.label(CONTRACT_LABELS[roleHolder] ?? roleHolder)), ); if (unknownRoleHolders.length > 0) { revokedFromItems.push( - md.label(`+${unknownRoleHolders.length} **UNKNOWN** holders`) + md.label(`+${unknownRoleHolders.length} **UNKNOWN** holders`), ); } const grantedToItems: string[] = [ ...role.holderAlreadyGrantedWithRole.map((roleHolder) => - md.label(CONTRACT_LABELS[roleHolder] ?? roleHolder) + md.label(CONTRACT_LABELS[roleHolder] ?? roleHolder), ), ...role.holdersToGrantRole.map((roleHolder) => - md.bold(CONTRACT_LABELS[roleHolder] ?? md.label(roleHolder)) + md.bold(CONTRACT_LABELS[roleHolder] ?? md.label(roleHolder)), ), ]; @@ -158,7 +158,7 @@ function formatPermissionsInfoTable(aragonRolesInfo: AragonPermissionInfo[]) { async function collectPermissionsData( provider: JsonRpcProvider, - config: AragonContractPermissionConfigs + config: AragonContractPermissionConfigs, ) { const { managers, permissions } = await fetchACLPermissionsInfo(provider); const aragonContractsInfo: AragonPermissionsInfo = {}; @@ -168,12 +168,12 @@ async function collectPermissionsData( aragonContractsInfo[contractName] = []; for (const [permissionName, { manager, grantedTo }] of Object.entries( - contractInfo.permissions + contractInfo.permissions, )) { const permissionHash = await getPermissionHash( provider, address, - permissionName + permissionName, ); const newManager = manager; @@ -191,13 +191,13 @@ async function collectPermissionsData( }); const holdersToGrantRole = (grantedTo ?? []).filter( - (roleHolder) => !currentlyGrantedTo.includes(roleHolder) + (roleHolder) => !currentlyGrantedTo.includes(roleHolder), ); const holdersToRevokeRole = currentlyGrantedTo.filter( - (roleHolderName) => !(grantedTo ?? []).includes(roleHolderName) + (roleHolderName) => !(grantedTo ?? []).includes(roleHolderName), ); const holderAlreadyGrantedWithRole = (grantedTo ?? []).filter( - (roleHolder) => currentlyGrantedTo.includes(roleHolder) + (roleHolder) => currentlyGrantedTo.includes(roleHolder), ); aragonContractsInfo[contractName].push({ @@ -253,7 +253,7 @@ async function fetchACLPermissionsInfo(provider: JsonRpcProvider) { if (!result.permissions[app][role].includes(entity!)) { } result.permissions[app][role] = result.permissions[app][role].filter( - (e) => e !== entity + (e) => e !== entity, ); } } @@ -265,14 +265,14 @@ async function fetchACLPermissionsInfo(provider: JsonRpcProvider) { async function getACLPermissionEvents( provider: JsonRpcProvider, - filterRange?: { fromBlock: number; toBlock?: number } + filterRange?: { fromBlock: number; toBlock?: number }, ) { const setPermissionTopic = id("SetPermission(address,address,bytes32,bool)"); const setPermissionParamsTopic = id( - "SetPermissionParams(address,address,bytes32,bytes32)" + "SetPermissionParams(address,address,bytes32,bytes32)", ); const changePermissionManagerTopic = id( - "ChangePermissionManager(address,bytes32,address)" + "ChangePermissionManager(address,bytes32,address)", ); const filterParams = { @@ -343,7 +343,7 @@ async function getACLPermissionEvents( async function getPermissionHash( provider: JsonRpcProvider, address: Address, - permissionName: string + permissionName: string, ) { return makeContractCall(provider, address, permissionName); } diff --git a/scripts/permissions-migration/src/comparison.ts b/scripts/permissions-migration/src/comparison.ts new file mode 100644 index 00000000..bc19b2cc --- /dev/null +++ b/scripts/permissions-migration/src/comparison.ts @@ -0,0 +1 @@ +export async function getContractsToCompareWithOmnubis() {}