Consistent Diamond Role Management

Core, AccountLayer, and ExpressProvider now expose the same canonical role-management and role-query interfaces.

Summary

Administrative tooling can now use the same account-first role calls against the Core, AccountLayer, and ExpressProvider diamonds. The diamond owner appoints default admins. A default admin appoints or removes role-specific admins, and either a default admin or the relevant role admin can grant and revoke that role.

Canonical interface

function setAdmin(address user) external;
function grantRole(address user, bytes32 role) external;
function revokeRole(address user, bytes32 role) external;
function addRoleAdmin(bytes32 role, address admin) external;
function removeRoleAdmin(bytes32 role, address admin) external;

function hasRole(address user, bytes32 role) external view returns (bool);
function isRoleAdmin(address user, bytes32 role) external view returns (bool);

setAdmin remains owner-only. addRoleAdmin and removeRoleAdmin require DEFAULT_ADMIN_ROLE. The account-first grantRole and revokeRole calls require the caller to administer the requested role.

Compatibility

The AccountLayer keeps setRoleAdmin(address,bytes32,bool). ExpressProvider keeps its owner-only grantRole(bytes32,address) and revokeRole(bytes32,address) overloads, as well as the role-first hasRole(bytes32,address) view. Existing integrations can continue using those selectors while new administrative tooling uses the shared interface.

Upgrade from v0.8.6.1

The AccountLayer change adds selectors without changing its storage layout. Existing roles and role-admin assignments remain in place after the facet cut.

ExpressProvider appends the new role-admin mapping after its existing storage fields. Existing configuration, balances, roles, and withdrawal state therefore remain at their original slots.