From 62ee5ec7347e1eff7871d53e9a81c13a2250765a Mon Sep 17 00:00:00 2001 From: Roman Kolpakov Date: Tue, 17 Dec 2024 14:22:48 +0300 Subject: [PATCH] feat: add draft for dual governance upgrade --- configs/config_mainnet.py | 2 + scripts/dual_governance_upgrade.py | 506 ++++++++++++++++++++++++++ tests/dual_governance_upgrade_test.py | 296 +++++++++++++++ utils/config.py | 4 + utils/permissions.py | 12 + 5 files changed, 820 insertions(+) create mode 100644 scripts/dual_governance_upgrade.py create mode 100644 tests/dual_governance_upgrade_test.py diff --git a/configs/config_mainnet.py b/configs/config_mainnet.py index 1c784fe60..4c66c5cd3 100644 --- a/configs/config_mainnet.py +++ b/configs/config_mainnet.py @@ -70,6 +70,8 @@ EASYTRACK_SIMPLE_DVT_CHANGE_NODE_OPERATOR_MANAGERS_FACTORY = "0xE31A0599A6772BCf9b2bFc9e25cf941e793c9a7D" EASYTRACK_CSM_SETTLE_EL_REWARDS_STEALING_PENALTY_FACTORY = "0xF6B6E7997338C48Ea3a8BCfa4BB64a315fDa76f4" +EASYTRACK_ALLOWED_TOKENS_REGISTRY = "0x4AC40c34f8992bb1e5E856A448792158022551ca" + # Multisigs FINANCE_MULTISIG = "0x48F300bD3C52c7dA6aAbDE4B683dEB27d38B9ABb" L1_EMERGENCY_BRAKES_MULTISIG = "0x73b047fe6337183A454c5217241D780a932777bD" diff --git a/scripts/dual_governance_upgrade.py b/scripts/dual_governance_upgrade.py new file mode 100644 index 000000000..895f1d9fa --- /dev/null +++ b/scripts/dual_governance_upgrade.py @@ -0,0 +1,506 @@ +""" +Voting 28/02/2025. +""" + +import time + +from typing import Dict, Tuple, Optional + +from web3 import Web3 +from utils.agent import agent_forward +from utils.voting import bake_vote_items, confirm_vote_script, create_vote +from brownie.network.transaction import TransactionReceipt +from utils.ipfs import upload_vote_ipfs_description, calculate_vote_ipfs_description +from utils.config import ( + contracts, + get_deployer_account, + get_is_live, + get_priority_fee, +) +from utils.permissions import ( + encode_permission_set_manager, + encode_permission_create, + encode_permission_revoke, + encode_permission_grant, +) + +try: + from brownie import interface +except ImportError: + print( + "You're probably running inside Brownie console. " "Please call:\n" "set_console_globals(interface=interface)" + ) + + +description = "" +DUAL_GOVERNANCE_EXECUTOR_ADDRESS = "" + +def start_vote(tx_params: Dict[str, str], silent: bool = False) -> Tuple[int, Optional[TransactionReceipt]]: + withdrawal_vault_as_proxy = interface.WithdrawalVaultManager(contracts.withdrawal_vault) + DEFAULT_ADMIN_ROLE = "0x0000000000000000000000000000000000000000000000000000000000000000" + + vote_desc_items, call_script_items = zip( + # Kernel ==================================================================================================== + ( + "Revoke permission for APP_MANAGER_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.kernel, + permission_name="APP_MANAGER_ROLE", + revoke_from=contracts.voting, + ), + ), + ( + "Grand permission for APP_MANAGER_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.kernel, + permission_name="APP_MANAGER_ROLE", + grant_to=contracts.agent, + ), + ), + ( + "Change permission manager for Kernel APP_MANAGER_ROLE.", + encode_permission_set_manager( + contracts.kernel, + "APP_MANAGER_ROLE", + contracts.agent, + ), + ), + # Lido ==================================================================================================== + ( + "Revoke permission for STAKING_CONTROL_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.lido, permission_name="STAKING_CONTROL_ROLE", revoke_from=contracts.voting + ), + ), + ( + "Grant permission for STAKING_CONTROL_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.lido, permission_name="STAKING_CONTROL_ROLE", grant_to=contracts.agent + ), + ), + ( + "Change permission manager for Lido STAKING_CONTROL_ROLE.", + encode_permission_set_manager(contracts.lido, "STAKING_CONTROL_ROLE", contracts.agent), + ), + ( + "Revoke permission for RESUME_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.lido, permission_name="RESUME_ROLE", revoke_from=contracts.voting + ), + ), + ( + "Grant permission for RESUME_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.lido, permission_name="RESUME_ROLE", grant_to=contracts.agent + ), + ), + ( + "Change permission manager for Lido RESUME_ROLE.", + encode_permission_set_manager(contracts.lido, "RESUME_ROLE", contracts.agent), + ), + ( + "Revoke permission for PAUSE_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.lido, permission_name="PAUSE_ROLE", revoke_from=contracts.voting + ), + ), + ( + "Grant permission for PAUSE_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.lido, permission_name="PAUSE_ROLE", grant_to=contracts.agent + ), + ), + ( + "Change permission manager for Lido PAUSE_ROLE.", + encode_permission_set_manager(contracts.lido, "PAUSE_ROLE", contracts.agent), + ), + ( + "Revoke permission for STAKING_PAUSE_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.lido, permission_name="STAKING_PAUSE_ROLE", revoke_from=contracts.voting + ), + ), + ( + "Grant permission for STAKING_PAUSE_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.lido, permission_name="STAKING_PAUSE_ROLE", grant_to=contracts.agent + ), + ), + ( + "Change permission manager for Lido STAKING_PAUSE_ROLE.", + encode_permission_set_manager(contracts.lido, "STAKING_PAUSE_ROLE", contracts.agent), + ), + # EVM Script Registry ========================================================================================== + ( + "Revoke permission for REGISTRY_ADD_EXECUTOR_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.evm_script_registry, + permission_name="REGISTRY_ADD_EXECUTOR_ROLE", + revoke_from=contracts.voting, + ), + ), + ( + "Grant permission for REGISTRY_ADD_EXECUTOR_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.evm_script_registry, + permission_name="REGISTRY_ADD_EXECUTOR_ROLE", + grant_to=contracts.agent, + ), + ), + ( + "Change permission manager for EVM Script Registry REGISTRY_ADD_EXECUTOR_ROLE.", + encode_permission_set_manager( + contracts.evm_script_registry, + "REGISTRY_ADD_EXECUTOR_ROLE", + contracts.agent, + ), + ), + ( + "Revoke permission for REGISTRY_MANAGER_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.evm_script_registry, + permission_name="REGISTRY_MANAGER_ROLE", + revoke_from=contracts.voting, + ), + ), + ( + "Grant permission for REGISTRY_MANAGER_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.evm_script_registry, + permission_name="REGISTRY_MANAGER_ROLE", + grant_to=contracts.agent, + ), + ), + ( + "Change permission manager for EVM Script Registry REGISTRY_MANAGER_ROLE.", + encode_permission_set_manager( + contracts.evm_script_registry, + "REGISTRY_MANAGER_ROLE", + contracts.agent, + ), + ), + # Curated Module ==================================================================================================== + ( + "Change permission manager for Curated module STAKING_ROUTER_ROLE.", + encode_permission_set_manager( + contracts.node_operators_registry, + "STAKING_ROUTER_ROLE", + contracts.agent, + ), + ), + ( + "Change permission manager for Curated module MANAGE_NODE_OPERATOR_ROLE.", + encode_permission_set_manager( + contracts.node_operators_registry, + "MANAGE_NODE_OPERATOR_ROLE", + contracts.agent, + ), + ), + ( + "Revoke permission for SET_NODE_OPERATOR_LIMIT_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.node_operators_registry, + permission_name="SET_NODE_OPERATOR_LIMIT_ROLE", + revoke_from=contracts.voting, + ), + ), + ( + "Grant permission for SET_NODE_OPERATOR_LIMIT_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.node_operators_registry, + permission_name="SET_NODE_OPERATOR_LIMIT_ROLE", + grant_to=contracts.agent, + ), + ), + ( + "Change permission manager for EVM Script Registry SET_NODE_OPERATOR_LIMIT_ROLE.", + encode_permission_set_manager( + contracts.node_operators_registry, + "SET_NODE_OPERATOR_LIMIT_ROLE", + contracts.agent, + ), + ), + ( + "Revoke permission for MANAGE_SIGNING_KEYS from Voting contract.", + encode_permission_revoke( + target_app=contracts.node_operators_registry, + permission_name="MANAGE_SIGNING_KEYS", + revoke_from=contracts.voting, + ), + ), + ( + "Grant permission for MANAGE_SIGNING_KEYS to Agent contract.", + encode_permission_grant( + target_app=contracts.node_operators_registry, + permission_name="MANAGE_SIGNING_KEYS", + grant_to=contracts.agent, + ), + ), + ( + "Change permission manager for EVM Script Registry MANAGE_SIGNING_KEYS.", + encode_permission_set_manager( + contracts.node_operators_registry, + "MANAGE_SIGNING_KEYS", + contracts.agent, + ), + ), + # SDVT Module ==================================================================================================== + ( + "Change permission manager for SDVT module STAKING_ROUTER_ROLE.", + encode_permission_set_manager( + contracts.simple_dvt, + "STAKING_ROUTER_ROLE", + contracts.agent, + ), + ), + ( + "Change permission manager for SDVT module MANAGE_NODE_OPERATOR_ROLE.", + encode_permission_set_manager( + contracts.simple_dvt, + "MANAGE_NODE_OPERATOR_ROLE", + contracts.agent, + ), + ), + ( + "Change permission manager for SDVT module SET_NODE_OPERATOR_LIMIT_ROLE.", + encode_permission_set_manager( + contracts.simple_dvt, + "SET_NODE_OPERATOR_LIMIT_ROLE", + contracts.agent, + ), + ), + # Withdrawal Vault ==================================================================================================== + ( + "Transfer Withdrawal Vault ownership from Voting to Agent.", + ( + contracts.withdrawal_vault.address, + withdrawal_vault_as_proxy.proxy_changeAdmin.encode_input(contracts.agent), + ), + ), + # Insurance Fund ==================================================================================================== + ( + "Transfer Insurance Fund ownership from Agent to Voting.", + ( + agent_forward( + [ + ( + contracts.insurance_fund.address, + contracts.insurance_fund.transferOwnership.encode_input(contracts.voting), + ) + ] + ) + ), + ), + # Finance ==================================================================================================== + ( + "Create new permission for CHANGE_PERIOD_ROLE, grant manager to Voting", + encode_permission_create( + target_app=contracts.finance.address, + permission_name="CHANGE_PERIOD_ROLE", + manager=contracts.voting, + grant_to=contracts.voting, + ), + ), + ( + "Create new permission for CHANGE_BUDGETS_ROLE, grant manager to Voting", + encode_permission_create( + target_app=contracts.finance.address, + permission_name="CHANGE_BUDGETS_ROLE", + manager=contracts.voting, + grant_to=contracts.voting, + ), + ), + # Token manager ==================================================================================================== + ( + "Create new permission for MINT_ROLE, grant manager to Voting", + encode_permission_create( + target_app=contracts.token_manager, + permission_name="MINT_ROLE", + manager=contracts.voting, + grant_to=contracts.voting, + ), + ), + ( + "Create new permission for REVOKE_VESTINGS_ROLE, grant manager to Voting", + encode_permission_create( + target_app=contracts.token_manager, + permission_name="REVOKE_VESTINGS_ROLE", + manager=contracts.voting, + grant_to=contracts.voting, + ), + ), + # Allowed Tokens Registry ==================================================================================================== + ( + "Grant DEFAULT_ADMIN_ROLE to Voting.", + ( + agent_forward( + [ + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.grantRole.encode_input( + DEFAULT_ADMIN_ROLE, contracts.voting + ), + ) + ] + ) + ), + ), + ( + "Revoke DEFAULT_ADMIN_ROLE from Agent.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.revokeRole.encode_input(DEFAULT_ADMIN_ROLE, contracts.agent), + ), + ), + ( + "Grant ADD_TOKEN_TO_ALLOWED_LIST_ROLE to Voting.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.grantRole.encode_input( + Web3.keccak(text="ADD_TOKEN_TO_ALLOWED_LIST_ROLE"), contracts.voting + ), + ), + ), + ( + "Revoke ADD_TOKEN_TO_ALLOWED_LIST_ROLE from Agent.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.revokeRole.encode_input( + Web3.keccak(text="ADD_TOKEN_TO_ALLOWED_LIST_ROLE"), contracts.agent + ), + ), + ), + ( + "Grant REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE to Voting.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.grantRole.encode_input( + Web3.keccak(text="REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE"), contracts.voting + ), + ), + ), + ( + "Revoke REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE from Agent.", + ( + contracts.allowed_tokens_registry.address, + contracts.allowed_tokens_registry.revokeRole.encode_input( + Web3.keccak(text="REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE"), contracts.agent + ), + ), + ), + # Agent ==================================================================================================== + ( + "Create new permission for ADD_PROTECTED_TOKEN_ROLE, grant manager to Voting", + encode_permission_create( + target_app=contracts.agent, + permission_name="ADD_PROTECTED_TOKEN_ROLE", + manager=contracts.voting, + grant_to=contracts.voting, + ), + ), + ( + "Create new permission for REMOVE_PROTECTED_TOKEN_ROLE, grant manager to Voting", + encode_permission_create( + target_app=contracts.agent, + permission_name="REMOVE_PROTECTED_TOKEN_ROLE", + manager=contracts.voting, + grant_to=contracts.voting, + ), + ), + ( + "Revoke permission for RUN_SCRIPT_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.agent, + permission_name="RUN_SCRIPT_ROLE", + revoke_from=contracts.voting, + ), + ), + ( + "Grant permission for RUN_SCRIPT_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.agent, + permission_name="RUN_SCRIPT_ROLE", + grant_to=contracts.agent + ), + ), + ( + "Change permission manager for Agent RUN_SCRIPT_ROLE.", + encode_permission_set_manager( + target_app=contracts.agent, + permission_name="RUN_SCRIPT_ROLE", + grant_to=contracts.agent, + ), + ), + ( + "Revoke permission for EXECUTE_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.agent, + permission_name="EXECUTE_ROLE", + revoke_from=contracts.voting, + ), + ), + ( + "Grant permission for EXECUTE_ROLE to DG Executor contract.", + encode_permission_grant( + target_app=contracts.agent, + permission_name="EXECUTE_ROLE", + grant_to=DUAL_GOVERNANCE_EXECUTOR_ADDRESS, + ), + ), + ( + "Change permission manager for Agent EXECUTE_ROLE.", + encode_permission_set_manager( + target_app=contracts.agent, + permission_name="EXECUTE_ROLE", + grant_to=contracts.agent, + ), + ), + # ACL ==================================================================================================== + ( + "Revoke permission for CREATE_PERMISSIONS_ROLE from Voting contract.", + encode_permission_revoke( + target_app=contracts.acl, + permission_name="CREATE_PERMISSIONS_ROLE", + revoke_from=contracts.voting, + ), + ), + ( + "Grant permission for CREATE_PERMISSIONS_ROLE to Agent contract.", + encode_permission_grant( + target_app=contracts.acl, + permission_name="CREATE_PERMISSIONS_ROLE", + grant_to=contracts.agent, + ), + ), + ( + "Change permission manager for ACL CREATE_PERMISSIONS_ROLE.", + encode_permission_set_manager( + contracts.acl, + "CREATE_PERMISSIONS_ROLE", + contracts.agent, + ), + ), + ) + + vote_items = bake_vote_items(list(vote_desc_items), list(call_script_items)) + + if silent: + desc_ipfs = calculate_vote_ipfs_description(description) + else: + desc_ipfs = upload_vote_ipfs_description(description) + + return confirm_vote_script(vote_items, silent, desc_ipfs) and list( + create_vote(vote_items, tx_params, desc_ipfs=desc_ipfs) + ) + + +def main(): + tx_params = {"from": get_deployer_account()} + if get_is_live(): + tx_params["priority_fee"] = get_priority_fee() + + vote_id, _ = start_vote(tx_params=tx_params, silent=False) + + vote_id >= 0 and print(f"Vote created: {vote_id}.") + + time.sleep(5) # hack for waiting thread #2. diff --git a/tests/dual_governance_upgrade_test.py b/tests/dual_governance_upgrade_test.py new file mode 100644 index 000000000..0c610b308 --- /dev/null +++ b/tests/dual_governance_upgrade_test.py @@ -0,0 +1,296 @@ +""" +Tests for voting 23/07/2024. +""" + +from scripts.dual_governance_upgrade import start_vote +from utils.config import contracts +from utils.test.tx_tracing_helpers import * +from brownie.network.transaction import TransactionReceipt +from utils.config import contracts + +try: + from brownie import interface +except ImportError: + print( + "You're probably running inside Brownie console. " "Please call:\n" "set_console_globals(interface=interface)" + ) + +def test_vote(helpers, accounts, ldo_holder, vote_ids_from_env, bypass_events_decoding): + dao_voting = contracts.voting + withdrawal_vault_as_proxy = interface.WithdrawalVaultManager(contracts.withdrawal_vault) + + # ACL + assert ( + contracts.acl.getPermissionManager(contracts.acl, contracts.acl.CREATE_PERMISSIONS_ROLE()) == contracts.voting + ) + assert contracts.acl.hasPermission(contracts.voting, contracts.acl, contracts.acl.CREATE_PERMISSIONS_ROLE()) + + # Kernel + assert contracts.acl.getPermissionManager(contracts.kernel, contracts.kernel.APP_MANAGER_ROLE()) == contracts.voting + assert contracts.acl.hasPermission(contracts.voting, contracts.kernel, contracts.kernel.APP_MANAGER_ROLE()) + + # Lido + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) == contracts.voting + assert contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.RESUME_ROLE()) == contracts.voting + assert contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.RESUME_ROLE()) + + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.PAUSE_ROLE()) == contracts.voting + assert contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.PAUSE_ROLE()) + + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_PAUSE_ROLE()) == contracts.voting + assert contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_PAUSE_ROLE()) + + # EVM Script Registry + assert ( + contracts.acl.getPermissionManager( + contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_ADD_EXECUTOR_ROLE() + ) + == contracts.voting + ) + assert contracts.acl.hasPermission( + contracts.voting, contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_ADD_EXECUTOR_ROLE() + ) + + assert ( + contracts.acl.getPermissionManager( + contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_MANAGER_ROLE() + ) + == contracts.voting + ) + assert contracts.acl.hasPermission( + contracts.voting, contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_MANAGER_ROLE() + ) + + # Node Operators Registry + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.STAKING_ROUTER_ROLE() + ) + == contracts.voting + ) + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.MANAGE_NODE_OPERATOR_ROLE() + ) + == contracts.voting + ) + + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE() + ) + == contracts.voting + ) + assert contracts.acl.hasPermission( + contracts.voting, + contracts.node_operators_registry, + contracts.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE(), + ) + + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.MANAGE_SIGNING_KEYS() + ) + == contracts.voting + ) + assert contracts.acl.hasPermission( + contracts.voting, contracts.node_operators_registry, contracts.node_operators_registry.MANAGE_SIGNING_KEYS() + ) + + # SDVT Module + + assert ( + contracts.acl.getPermissionManager( + contracts.simple_dvt, contracts.simple_dvt.STAKING_ROUTER_ROLE() + ) + == contracts.voting + ) + assert ( + contracts.acl.getPermissionManager( + contracts.simple_dvt, contracts.simple_dvt.SET_NODE_OPERATOR_LIMIT_ROLE() + ) + == contracts.voting + ) + assert ( + contracts.acl.getPermissionManager( + contracts.simple_dvt, contracts.simple_dvt.MANAGE_NODE_OPERATOR_ROLE() + ) + == contracts.voting + ) + + # Withdrawal vault + + assert withdrawal_vault_as_proxy.proxy_getAdmin() == contracts.voting + + # Insurance fund + + assert contracts.insurance_fund.owner() == contracts.agent + + # Finance + + assert contracts.acl.getPermissionManager(contracts.finance, contracts.finance.CHANGE_PERIOD_ROLE()) != contracts.voting + assert contracts.acl.getPermissionManager(contracts.finance, contracts.finance.CHANGE_BUDGETS_ROLE()) != contracts.voting + + # Token manager + assert contracts.acl.getPermissionManager(contracts.token_manager, contracts.token_manager.MINT_ROLE()) != contracts.voting + assert contracts.acl.getPermissionManager(contracts.token_manager, contracts.token_manager.REVOKE_VESTINGS_ROLE()) != contracts.voting + + # Allowed tokens registry + + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting) + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.ADD_TOKEN_TO_ALLOWED_LIST_ROLE(), contracts.agent) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.ADD_TOKEN_TO_ALLOWED_LIST_ROLE(), contracts.voting) + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE(), contracts.agent) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE(), contracts.voting) + + # Agent + + # START VOTE + vote_id = vote_ids_from_env[0] if vote_ids_from_env else start_vote({"from": ldo_holder}, silent=True)[0] + + tx: TransactionReceipt = helpers.execute_vote( + vote_id=vote_id, accounts=accounts, dao_voting=dao_voting, skip_time=3 * 60 * 60 * 24 + ) + + assert contracts.acl.getPermissionManager(contracts.acl, contracts.acl.CREATE_PERMISSIONS_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.acl, contracts.acl.CREATE_PERMISSIONS_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.acl, contracts.acl.CREATE_PERMISSIONS_ROLE()) + + # Kernel + assert contracts.acl.getPermissionManager(contracts.kernel, contracts.kernel.APP_MANAGER_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.kernel, contracts.kernel.APP_MANAGER_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.kernel, contracts.kernel.APP_MANAGER_ROLE()) + + # Lido + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.lido, contracts.lido.STAKING_CONTROL_ROLE()) + + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.RESUME_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.RESUME_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.lido, contracts.lido.RESUME_ROLE()) + + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.PAUSE_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.PAUSE_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.lido, contracts.lido.PAUSE_ROLE()) + + assert contracts.acl.getPermissionManager(contracts.lido, contracts.lido.STAKING_PAUSE_ROLE()) == contracts.agent + assert not contracts.acl.hasPermission(contracts.voting, contracts.lido, contracts.lido.STAKING_PAUSE_ROLE()) + assert contracts.acl.hasPermission(contracts.agent, contracts.lido, contracts.lido.STAKING_PAUSE_ROLE()) + + # EVM Script Registry + assert ( + contracts.acl.getPermissionManager( + contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_ADD_EXECUTOR_ROLE() + ) + == contracts.agent + ) + assert not contracts.acl.hasPermission( + contracts.voting, contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_ADD_EXECUTOR_ROLE() + ) + assert contracts.acl.hasPermission( + contracts.agent, contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_ADD_EXECUTOR_ROLE() + ) + + assert ( + contracts.acl.getPermissionManager( + contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_MANAGER_ROLE() + ) + == contracts.agent + ) + assert not contracts.acl.hasPermission( + contracts.voting, contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_MANAGER_ROLE() + ) + assert contracts.acl.hasPermission( + contracts.agent, contracts.evm_script_registry, contracts.evm_script_registry.REGISTRY_MANAGER_ROLE() + ) + + # Node Operators Registry + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.STAKING_ROUTER_ROLE() + ) + == contracts.agent + ) + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.MANAGE_NODE_OPERATOR_ROLE() + ) + == contracts.agent + ) + + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE() + ) + == contracts.agent + ) + assert not contracts.acl.hasPermission( + contracts.voting, + contracts.node_operators_registry, + contracts.node_operators_registry.SET_NODE_OPERATOR_LIMIT_ROLE(), + ) + + assert ( + contracts.acl.getPermissionManager( + contracts.node_operators_registry, contracts.node_operators_registry.MANAGE_SIGNING_KEYS() + ) + == contracts.agent + ) + assert not contracts.acl.hasPermission( + contracts.voting, contracts.node_operators_registry, contracts.node_operators_registry.MANAGE_SIGNING_KEYS() + ) + + # SDVT Module + + assert ( + contracts.acl.getPermissionManager( + contracts.simple_dvt, contracts.simple_dvt.STAKING_ROUTER_ROLE() + ) + == contracts.agent + ) + assert ( + contracts.acl.getPermissionManager( + contracts.simple_dvt, contracts.simple_dvt.SET_NODE_OPERATOR_LIMIT_ROLE() + ) + == contracts.agent + ) + assert ( + contracts.acl.getPermissionManager( + contracts.simple_dvt, contracts.simple_dvt.MANAGE_NODE_OPERATOR_ROLE() + ) + == contracts.agent + ) + + # Withdrawal vault + + assert withdrawal_vault_as_proxy.proxy_getAdmin() == contracts.agent + + # Insurance fund + + assert contracts.insurance_fund.owner() == contracts.voting + + # Finance + + assert contracts.acl.getPermissionManager(contracts.finance, contracts.finance.CHANGE_PERIOD_ROLE()) == contracts.voting + assert contracts.acl.getPermissionManager(contracts.finance, contracts.finance.CHANGE_BUDGETS_ROLE()) == contracts.voting + + # Token manager + assert contracts.acl.getPermissionManager(contracts.token_manager, contracts.token_manager.MINT_ROLE()) == contracts.voting + assert contracts.acl.getPermissionManager(contracts.token_manager, contracts.token_manager.REVOKE_VESTINGS_ROLE()) == contracts.voting + + # Allowed tokens registry + + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.voting) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.DEFAULT_ADMIN_ROLE(), contracts.agent) + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.ADD_TOKEN_TO_ALLOWED_LIST_ROLE(), contracts.voting) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.ADD_TOKEN_TO_ALLOWED_LIST_ROLE(), contracts.agent) + assert contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE(), contracts.voting) + assert not contracts.allowed_tokens_registry.hasRole(contracts.allowed_tokens_registry.REMOVE_TOKEN_FROM_ALLOWED_LIST_ROLE(), contracts.agent) + + # # Validate vote events + # if not bypass_events_decoding: + # assert count_vote_items_by_events(tx, dao_voting) == 2, "Incorrect voting items count" diff --git a/utils/config.py b/utils/config.py index 767e86afc..c5c80115c 100644 --- a/utils/config.py +++ b/utils/config.py @@ -390,6 +390,10 @@ def trp_escrow_factory(self) -> interface.VestingEscrowFactory: @property def token_rate_notifier(self) -> interface.TokenRateNotifier: return interface.TokenRateNotifier(L1_TOKEN_RATE_NOTIFIER) + + @property + def allowed_tokens_registry(self) -> interface.AllowedTokensRegistry: + return interface.AllowedTokensRegistry(EASYTRACK_ALLOWED_TOKENS_REGISTRY) def __getattr__(name: str) -> Any: if name == "contracts": diff --git a/utils/permissions.py b/utils/permissions.py index 4089f05ed..c6a5d1856 100644 --- a/utils/permissions.py +++ b/utils/permissions.py @@ -24,6 +24,18 @@ def encode_permission_revoke(target_app, permission_name, revoke_from) -> Tuple[ return acl.address, acl.revokePermission.encode_input(revoke_from, target_app, permission_id) +def encode_permission_set_manager(target_app, permission_name: str, grant_to: str) -> Tuple[str, str]: + acl = contracts.acl + permission_id = convert.to_uint(Web3.keccak(text=permission_name)) + return acl.address, acl.setPermissionManager.encode_input(grant_to, target_app, permission_id) + + +def encode_permission_create(target_app, permission_name: str, grant_to, manager) -> Tuple[str, str]: + acl = contracts.acl + permission_id = convert.to_uint(Web3.keccak(text=permission_name)) + return acl.address, acl.createPermission.encode_input(grant_to, target_app, permission_id, manager) + + def encode_permission_grant_p( target_app, permission_name: str,