Multiple upgradeable contracts interaction

I have two contracts - one AccessRole and ERC20 token.
I want these both contracts to have the ability to be upgraded in the future. I am having trouble connecting these two contracts together.

a couple of questions

  1. I want my access roles to be a central place where multiple contracts can call it. The inheritance from roles to Token doesn't seem right? Because there would be multiple initializer. I am not sure how to implement this?
  2. When I addUser, am I calling the AccessRole or Token? Because it is not adding any roles.
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
import "@openzeppelin/contracts/access/IAccessControl.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

contract AccessRole is Initializable, AccessControlUpgradeable, UUPSUpgradeable {
// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initialize() initializer public {
        __AccessControl_init();
        __UUPSUpgradeable_init();

        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(ADMIN_ROLE, msg.sender);
    }

  function addUser(address account)
    public onlyAdmin
  {
    grantRole(USER_ROLE, account);
  }


}
import "../roles.sol";
contract Token is ERC20Upgradeable, ERC20BurnableUpgradeable, PausableUpgradeable, AccessRole {
/// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    function initializeToken(string memory name, string memory symbol)  public {
        __ERC20_init(name, symbol);
        __ERC20Burnable_init();
        __Pausable_init();
        __AccessControl_init();
        __UUPSUpgradeable_init();

        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(PAUSER_ROLE, msg.sender);
        _grantRole(MINTER_ROLE, msg.sender);
        _grantRole(UPGRADER_ROLE, msg.sender);
    }
}

If you want a central AccessControl contract, you would not be using inheritance.

You would not write this:

contract Token is ..., AccessRole {

Instead, you would write something like this:

contract Token is ... {
    AccessRole access;

    constructor(..., AccessRole _access) {
        _access = access;
    }

    function protected() public {
        require(access.hasRole(msg.sender, ROLE));
    }
}
2 Likes

Thank you for your email and advice.

Regard,

Fred.