From c3798af615d104432ccd3b0e4806cb6739ff3e8b Mon Sep 17 00:00:00 2001 From: Schlagonia Date: Mon, 5 Feb 2024 15:48:40 -0700 Subject: [PATCH] feat: remove role --- contracts/Managers/RoleManager.sol | 23 ++++++ tests/manager/test_role_manager.py | 108 +++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/contracts/Managers/RoleManager.sol b/contracts/Managers/RoleManager.sol index 2cfda95..a3f0320 100644 --- a/contracts/Managers/RoleManager.sol +++ b/contracts/Managers/RoleManager.sol @@ -589,6 +589,29 @@ contract RoleManager is Governance2Step { emit RemovedVault(_vault); } + /** + * @notice Removes a specific role(s) for a `_holder` from the `_vaults`. + * @dev Can be used to remove one specific role or multiple. + * @param _vaults Array of vaults to adjust. + * @param _holder Address who's having a role removed. + * @param _role The role or roles to remove from the `_holder`. + */ + function removeRoles( + address[] calldata _vaults, + address _holder, + uint256 _role + ) external virtual onlyPositionHolder(DADDY) { + address _vault; + for (uint256 i = 0; i < _vaults.length; ++i) { + _vault = _vaults[i]; + // Make sure the vault is added to this Role Manager. + require(vaultConfig[_vault].asset != address(0), "vault not added"); + + // Remove the role. + IVault(_vault).remove_role(_holder, _role); + } + } + /*////////////////////////////////////////////////////////////// SETTERS //////////////////////////////////////////////////////////////*/ diff --git a/tests/manager/test_role_manager.py b/tests/manager/test_role_manager.py index 1ac246c..ecc44ef 100644 --- a/tests/manager/test_role_manager.py +++ b/tests/manager/test_role_manager.py @@ -1441,3 +1441,111 @@ def test_remove_vault( vault.accept_role_manager(sender=daddy) assert vault.role_manager() == daddy + + +def test_remove_role( + role_manager, + daddy, + brain, + security, + keeper, + strategy_manager, + asset, + user, + strategy, + healthcheck_accountant, + registry, + release_registry, + vault_factory, + debt_allocator_factory, +): + setup_role_manager( + role_manager=role_manager, + release_registry=release_registry, + registry=registry, + vault_factory=vault_factory, + accountant=healthcheck_accountant, + daddy=daddy, + ) + + rating = int(2) + + assert role_manager.getAllVaults() == [] + assert ( + role_manager.getVault(asset, vault_factory.apiVersion(), rating) == ZERO_ADDRESS + ) + assert registry.numAssets() == 0 + assert registry.numEndorsedVaults(asset) == 0 + + # Deploy a vault + tx = role_manager.newVault(asset, rating, sender=daddy) + + event = list(tx.decode_logs(registry.NewEndorsedVault))[0] + vault = project.dependencies["yearn-vaults"]["v3.0.1"].VaultV3.at(event.vault) + + event = list(tx.decode_logs(debt_allocator_factory.NewDebtAllocator))[0] + debt_allocator = project.DebtAllocator.at(event.allocator) + + (vault_asset, vault_rating, vault_debt_allocator, index) = role_manager.vaultConfig( + vault + ) + + assert vault_asset == asset + assert vault_rating == rating + assert vault_debt_allocator == debt_allocator + assert index == 0 + assert role_manager.getAllVaults() == [vault] + assert role_manager.getVault(asset, vault_factory.apiVersion(), rating) == vault + assert role_manager.vaults(index) == vault + assert role_manager.isVaultsRoleManager(vault) == True + + # Check roles + assert vault.roles(role_manager) == 0 + assert vault.roles(daddy) == daddy_roles + + # Remove 1 role and see if the rest remain the same. + new_roles = daddy_roles & ~ROLES.ADD_STRATEGY_MANAGER + + with ape.reverts("vault not added"): + role_manager.removeRoles( + [strategy], daddy, ROLES.ADD_STRATEGY_MANAGER, sender=daddy + ) + + with ape.reverts("!allowed"): + role_manager.removeRoles( + [vault], daddy, ROLES.ADD_STRATEGY_MANAGER, sender=user + ) + + tx = role_manager.removeRoles( + [vault], daddy, ROLES.ADD_STRATEGY_MANAGER, sender=daddy + ) + + event = list(tx.decode_logs(vault.RoleSet)) + + assert len(event) == 1 + assert event[0].account == daddy + assert event[0].role == new_roles + assert vault.roles(daddy) == new_roles + + with ape.reverts("not allowed"): + vault.add_strategy(strategy, sender=daddy) + + # Remove two roles at once + to_remove = ROLES.REVOKE_STRATEGY_MANAGER | ROLES.FORCE_REVOKE_MANAGER + + new_roles = new_roles & ~to_remove + + tx = role_manager.removeRoles([vault], daddy, to_remove, sender=daddy) + + event = list(tx.decode_logs(vault.RoleSet)) + + assert len(event) == 1 + assert event[0].account == daddy + assert event[0].role == new_roles + assert vault.roles(daddy) == new_roles + + with ape.reverts("not allowed"): + vault.revoke_strategy(strategy, sender=daddy) + + with ape.reverts("not allowed"): + vault.force_revoke_strategy(strategy, sender=daddy)