AccessManager pausing for PUBLIC_ROLE only

Hi!

I have questions on how to use AccessManager.

  1. Is it possible to grant multiple roles to one selector?
    struct TargetConfig {
        mapping(bytes4 selector => uint64 roleId) allowedRoles;
        Time.Delay adminDelay;
        bool closed;
    }

It seems that selector => uint64 roleId means one role per selector, while mapping(address target => TargetConfig mode) private _targets; means one TargetConfig per target.
Did I miss something?

  1. Is there any way to close/pause target for PUBLIC_ROLE only?

That's how I think it was designed:

  • Admins change targetFunctionRole for all publicly accessible function to non PUBLIC_ROLE
  • DEV_ROLE performs maintenance
  • Admins setTargetFunctionRole() (which rewrites fn's required role, see the Q1 above) to those functions back to PUBLIC_ROLE

Let's assume we use AccessManager at company level (see Environment example below). This approach means we need global admins to work on project-level tasks, which seems a bit frustrating, as it requires explanation/confirmations from project level to global level.

  1. Any way to delegate setTargeFunctionRole to project level, to PM, for example?

:computer: Environment

AccessManager env to manage all company's contracts:

  1. Global admins (e.g. multisig + CTO + security officer)
  2. Project's PM, DEVs, managers
  3. Global roles, such as CFO or marketing managers, allowed to perform similar operations for different projects

Hi @tknff!

  1. Is it possible to grant multiple roles to one selector?

No, your analysis is right, the roles are many-to-many in respect to users but only 1-to-1 in respect to selectors.

iirc, we took this decision because it's easier to make roles as granular as possible, meaning you can assign selectors to as many roles as you want, and assign them to userrs using Multicall.

  1. Is there any way to close/pause target for PUBLIC_ROLE only?

This is the default mode. If a contract inherits from AccessManaged and uses the restricted modifier on a method, this method will be restricted to only admins initially.

Let's assume we use AccessManager at company level (see Environment example below). This approach means we need global admins to work on project-level tasks, which seems a bit frustrating, as it requires explanation/confirmations from project level to global level.

You can configure your deployment in such a way that you assign all the roles needed during deployment using the deployment key and then you renounce at the end (here's an example). In such case, you wouldn't need any admin to work on project-level tasks.

  1. Any way to delegate setTargeFunctionRole to project level, to PM, for example?

Unfortunately, no. The setTargetFunctionRole is within the admin scope because any other configuration will reduce the security of the manager to the only address that can execute setTargetFunctionRole.

I suggest you give the admin role to a PM and give it an execution delay that's enough to prevent any bad action.

Thanks for your reply!

I need to clarify my questions, sorry, I didn't put it clear enough.

I meant to pause previously opened public function. Ok, here is use case:

  • the contract deployed and works, but then, at some point...
  • the contract is paused for public access, but devs can call admin functions,
  • then the contract unpaused

I'm trying to use one AccessManager for multiple projects, including future ones. :slight_smile:
I don't think it's practical to think of everything in advance, eh?

Because of the inability to delegate setTargetFunctionRole() and necessity to use that function to jiggle with roles when needed, I believe I have to continue using admin roles, but probably with multisig.

Thank you!

I meant to pause previously opened public function. Ok, here is use case:

  • the contract deployed and works, but then, at some point...
  • the contract is paused for public access, but devs can call admin functions,
  • then the contract unpaused

Right, this is a valid concern. We thought the manager should be designed in a way that's progressively decentralized, not the other way around.

Regardless, I think it's possible to use a contract that inherits from AccessManaged and it can only call setTargetFunctionRole with certain conditions, then give it the admin role. It will effectively delegate the setTargetFunctionRole to anything that restricts the call in this custom contract, (e.g. another EOA address, and only for certain roles).

I don't think it's practical to think of everything in advance, eh?

This is always the dilemma, huh? :sweat_smile: We designed AccessManager with this approach, and the result we came up with is fairly simple compared to what allows you to do. The setup I just mentioned is only a suggestion, but consider using the AccessManager to set up updating mechanisms through contracts restricted by itself.

You're welcome!