Access Controls
The Access Control system implements granular, function-level permissions across all contracts of Cap. It provides a sophisticated role-based access control mechanism that allows precise management of who can call specific functions on specific contracts, building on OpenZeppelin's AccessControlEnumberable Integration.
Roles are managed by the Access Control admin, currently set to Cap's multisig address
Mechanics
Each function on each contract has its own unique 32-byte role ID
The role ID is generated by combining:
The function selector (first 4 bytes of the function signature)
The contract address
Permissions can be granted/revoked at the function level
Contracts inherit access control through the
Access
abstract contract and uses the checkAccess modifier on protected functions
Architecture
Access.sol: Inheritable abstract contract that provides the base functionality for access control
AccessControl.sol: Central contract that implements the access control logic
Access Control
Core Functions
grantAccess
: Grants permission to call a specific function on a specific contract
function grantAccess(bytes4 _selector, address _contract, address _address) external
_selector
: Function selector (4-byte identifier) of the method to grant access to_contract
: Address of the contract containing the method_address
: Address to grant access to
revokeAccess
: Revokes permission to call a specific function on a specific contract
function revokeAccess(bytes4 _selector, address _contract, address _address) external
_selector
: Function selector (4-byte identifier) of the method to revoke access from_contract
: Address of the contract containing the method_address
: Address to revoke access from
checkAccess
: Verifies if an address has permission to call a specific function
function checkAccess(bytes4 _selector, address _contract, address _caller) external view returns (bool hasAccess)
Returns: True if access is granted, false otherwise
When a access controlled function is called, the checkAccess modifier calls _checkRole with the function's selector, contract and message sender.
role
: Gets the role identifier for a specific function selector on a contract
function role(bytes4 _selector, address _contract) public pure returns (bytes32 roleId)
_selector
: Function selector (4-byte identifier) of the method_contract
: Address of the contract containing the methodReturns: Unique role identifier derived from selector and contract address
Role Hierarchy
DEFAULT_ADMIN_ROLE
├── access_control_admin
│ ├── oracle_admin
│ ├── rate_oracle_admin
│ ├── lender_admin
│ ├── delegation_admin
│ └── vault_config_admin
└── Emergency Admin
DEFAULT_ADMIN_ROLE: Can upgrade the AccessControl contract
Access Management Roles: Can grant/revoke permissions
Function-Specific Roles: Control access to individual functions
Permission Types
1. Administrative Permissions
Contract upgrades (
bytes4(0)
)Access management (
grantAccess
,revokeAccess
)
2. Operational Permissions
Vault operations (
borrow
,repay
,mint
,burn
)Oracle managements (
setOracleData
,setStaleness
,setRates
)Asset management (
addAsset
,removeAsset
,pauseAsset
,setReserve
)Fee Auctions (
setDuration
,setStartPrice
,setPaymentToken
)Delegations (
addAgent
,modifyAgent
,registerNetwork
)
3. Emergency Permissions
Protocol pause (
pauseProtocol
,unpauseProtocol
)Emergency functions (
emergencyWithdraw
,rescueERC20
)
Last updated