Source Code
Overview
HYPE Balance
HYPE Value
$0.00Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Initialize Confi... | 20755320 | 54 days ago | IN | 0 HYPE | 0.00001476 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ConfigurationManager
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 50 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {IConfigurationManager} from "../interfaces/IConfigurationManager.sol";
import {ConfigurationManagerParams} from "../types/ConfigurationManagerTypes.sol";
import {ProtocolAccessManaged} from "@summerfi/access-contracts/contracts/ProtocolAccessManaged.sol";
/**
* @title ConfigurationManager
* @notice Manages system-wide configuration parameters for the protocol
* @custom:see IConfigurationManager
*/
contract ConfigurationManager is IConfigurationManager, ProtocolAccessManaged {
bool public initialized;
/// @inheritdoc IConfigurationManager
address public raft;
/// @inheritdoc IConfigurationManager
address public tipJar;
/// @inheritdoc IConfigurationManager
address public treasury;
/// @inheritdoc IConfigurationManager
address public harborCommand;
/// @inheritdoc IConfigurationManager
address public fleetCommanderRewardsManagerFactory;
/**
* @notice Constructs the ConfigurationManager contract
* @param _accessManager The address of the ProtocolAccessManager contract
*/
constructor(address _accessManager) ProtocolAccessManaged(_accessManager) {}
/// @inheritdoc IConfigurationManager
function initializeConfiguration(
ConfigurationManagerParams memory params
) external onlyGovernor {
if (initialized) {
revert ConfigurationManagerAlreadyInitialized();
}
if (
params.raft == address(0) ||
params.tipJar == address(0) ||
params.treasury == address(0) ||
params.harborCommand == address(0) ||
params.fleetCommanderRewardsManagerFactory == address(0)
) {
revert AddressZero();
}
raft = params.raft;
tipJar = params.tipJar;
treasury = params.treasury;
harborCommand = params.harborCommand;
fleetCommanderRewardsManagerFactory = params
.fleetCommanderRewardsManagerFactory;
emit RaftUpdated(address(0), params.raft);
emit TipJarUpdated(address(0), params.tipJar);
emit TreasuryUpdated(address(0), params.treasury);
emit HarborCommandUpdated(address(0), params.harborCommand);
emit FleetCommanderRewardsManagerFactoryUpdated(
address(0),
params.fleetCommanderRewardsManagerFactory
);
initialized = true;
}
/// @inheritdoc IConfigurationManager
function setRaft(address newRaft) external onlyGovernor {
if (newRaft == address(0)) {
revert AddressZero();
}
emit RaftUpdated(raft, newRaft);
raft = newRaft;
}
/// @inheritdoc IConfigurationManager
function setTipJar(address newTipJar) external onlyGovernor {
if (newTipJar == address(0)) {
revert AddressZero();
}
emit TipJarUpdated(tipJar, newTipJar);
tipJar = newTipJar;
}
/// @inheritdoc IConfigurationManager
function setTreasury(address newTreasury) external onlyGovernor {
if (newTreasury == address(0)) {
revert AddressZero();
}
emit TreasuryUpdated(treasury, newTreasury);
treasury = newTreasury;
}
/// @inheritdoc IConfigurationManager
function setHarborCommand(address newHarborCommand) external onlyGovernor {
if (newHarborCommand == address(0)) {
revert AddressZero();
}
emit HarborCommandUpdated(harborCommand, newHarborCommand);
harborCommand = newHarborCommand;
}
/// @inheritdoc IConfigurationManager
function setFleetCommanderRewardsManagerFactory(
address newFleetCommanderRewardsManagerFactory
) external onlyGovernor {
if (newFleetCommanderRewardsManagerFactory == address(0)) {
revert AddressZero();
}
emit FleetCommanderRewardsManagerFactoryUpdated(
fleetCommanderRewardsManagerFactory,
newFleetCommanderRewardsManagerFactory
);
fleetCommanderRewardsManagerFactory = newFleetCommanderRewardsManagerFactory;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {IERC165, ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/IAccessControl.sol)
pragma solidity >=0.8.4;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/// @inheritdoc IERC165
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (utils/introspection/IERC165.sol)
pragma solidity >=0.4.16;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {IAccessControlErrors} from "../interfaces/IAccessControlErrors.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
/**
* @title LimitedAccessControl
* @dev This contract extends OpenZeppelin's AccessControl, disabling direct role granting and revoking.
* It's designed to be used as a base contract for more specific access control implementations.
* @dev This contract overrides the grantRole and revokeRole functions from AccessControl to disable direct role
* granting and revoking.
* @dev It doesn't override the renounceRole function, so it can be used to renounce roles for compromised accounts.
*/
abstract contract LimitedAccessControl is AccessControl, IAccessControlErrors {
/**
* @dev Overrides the grantRole function from AccessControl to disable direct role granting.
* @notice This function always reverts with a DirectGrantIsDisabled error.
*/
function grantRole(bytes32, address) public view override {
revert DirectGrantIsDisabled(msg.sender);
}
/**
* @dev Overrides the revokeRole function from AccessControl to disable direct role revoking.
* @notice This function always reverts with a DirectRevokeIsDisabled error.
*/
function revokeRole(bytes32, address) public view override {
revert DirectRevokeIsDisabled(msg.sender);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {IAccessControlErrors} from "../interfaces/IAccessControlErrors.sol";
import {ContractSpecificRoles, IProtocolAccessManager} from "../interfaces/IProtocolAccessManager.sol";
import {ProtocolAccessManager} from "./ProtocolAccessManager.sol";
import {Context} from "@openzeppelin/contracts/utils/Context.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/**
* @title ProtocolAccessManaged
* @notice This contract provides role-based access control functionality for protocol contracts
* by interfacing with a central ProtocolAccessManager.
*
* @dev This contract is meant to be inherited by other protocol contracts that need
* role-based access control. It provides modifiers and utilities to check various roles.
*
* The contract supports several key roles through modifiers:
* 1. GOVERNOR_ROLE: System-wide administrators
* 2. KEEPER_ROLE: Routine maintenance operators (contract-specific)
* 3. SUPER_KEEPER_ROLE: Advanced maintenance operators (global)
* 4. CURATOR_ROLE: Fleet-specific managers
* 5. GUARDIAN_ROLE: Emergency response operators
* 6. DECAY_CONTROLLER_ROLE: Specific role for decay management
* 7. ADMIRALS_QUARTERS_ROLE: Specific role for admirals quarters bundler contract
*
* Usage:
* - Inherit from this contract to gain access to role-checking modifiers
* - Use modifiers like onlyGovernor, onlyKeeper, etc. to protect functions
* - Access the internal _accessManager to perform custom role checks
*
* Security Considerations:
* - The contract validates the access manager address during construction
* - All role checks are performed against the immutable access manager instance
* - Contract-specific roles are generated using the contract's address to prevent conflicts
*/
contract ProtocolAccessManaged is IAccessControlErrors, Context {
/*//////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////*/
/// @notice Role identifier for protocol governors - highest privilege level with admin capabilities
bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE");
/// @notice Role identifier for super keepers who can globally perform fleet maintanence roles
bytes32 public constant SUPER_KEEPER_ROLE = keccak256("SUPER_KEEPER_ROLE");
/**
* @notice Role identifier for protocol guardians
* @dev Guardians have emergency powers across multiple protocol components:
* - Can pause/unpause Fleet operations for security
* - Can pause/unpause TipJar operations
* - Can cancel governance proposals on SummerGovernor even if they don't meet normal cancellation requirements
* - Can cancel TipJar proposals
*
* The guardian role serves as an emergency backstop to protect the protocol, but with less
* privilege than governors.
*/
bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE");
/**
* @notice Role identifier for decay controller
* @dev This role allows the decay controller to manage the decay of user voting power
*/
bytes32 public constant DECAY_CONTROLLER_ROLE =
keccak256("DECAY_CONTROLLER_ROLE");
/**
* @notice Role identifier for admirals quarters bundler contract
* @dev This role allows Admirals Quarters to unstake and withdraw assets from fleets, on behalf of users
* @dev Withdrawn tokens go straight to users wallet, lowering the risk of manipulation if the role is compromised
*/
bytes32 public constant ADMIRALS_QUARTERS_ROLE =
keccak256("ADMIRALS_QUARTERS_ROLE");
/*//////////////////////////////////////////////////////////////
STATE VARIABLES
//////////////////////////////////////////////////////////////*/
/// @notice The ProtocolAccessManager instance used for access control
ProtocolAccessManager internal immutable _accessManager;
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
/**
* @notice Initializes the ProtocolAccessManaged contract
* @param accessManager Address of the ProtocolAccessManager contract
* @dev Validates the provided accessManager address and initializes the _accessManager
*/
constructor(address accessManager) {
if (accessManager == address(0)) {
revert InvalidAccessManagerAddress(address(0));
}
if (
!IERC165(accessManager).supportsInterface(
type(IProtocolAccessManager).interfaceId
)
) {
revert InvalidAccessManagerAddress(accessManager);
}
_accessManager = ProtocolAccessManager(accessManager);
}
/*//////////////////////////////////////////////////////////////
MODIFIERS
//////////////////////////////////////////////////////////////*/
/**
* @notice Modifier to restrict access to governors only
*
* @dev Modifier to check that the caller has the Governor role
* @custom:internal-logic
* - Checks if the caller has the GOVERNOR_ROLE in the access manager
* @custom:effects
* - Reverts if the caller doesn't have the GOVERNOR_ROLE
* - Allows the function to proceed if the caller has the role
* @custom:security-considerations
* - Ensures that only authorized governors can access critical functions
* - Relies on the correct setup of the access manager
*/
modifier onlyGovernor() {
if (!_accessManager.hasRole(GOVERNOR_ROLE, msg.sender)) {
revert CallerIsNotGovernor(msg.sender);
}
_;
}
/**
* @notice Modifier to restrict access to keepers only
* @dev Modifier to check that the caller has the Keeper role
* @custom:internal-logic
* - Checks if the caller has either the contract-specific KEEPER_ROLE or the SUPER_KEEPER_ROLE
* @custom:effects
* - Reverts if the caller doesn't have either of the required roles
* - Allows the function to proceed if the caller has one of the roles
* @custom:security-considerations
* - Ensures that only authorized keepers can access maintenance functions
* - Allows for both contract-specific and super keepers
* @custom:gas-considerations
* - Performs two role checks, which may impact gas usage
*/
modifier onlyKeeper() {
if (
!_accessManager.hasRole(
generateRole(ContractSpecificRoles.KEEPER_ROLE, address(this)),
msg.sender
) && !_accessManager.hasRole(SUPER_KEEPER_ROLE, msg.sender)
) {
revert CallerIsNotKeeper(msg.sender);
}
_;
}
/**
* @notice Modifier to restrict access to super keepers only
* @dev Modifier to check that the caller has the Super Keeper role
* @custom:internal-logic
* - Checks if the caller has the SUPER_KEEPER_ROLE in the access manager
* @custom:effects
* - Reverts if the caller doesn't have the SUPER_KEEPER_ROLE
* - Allows the function to proceed if the caller has the role
* @custom:security-considerations
* - Ensures that only authorized super keepers can access advanced maintenance functions
* - Relies on the correct setup of the access manager
*/
modifier onlySuperKeeper() {
if (!_accessManager.hasRole(SUPER_KEEPER_ROLE, msg.sender)) {
revert CallerIsNotSuperKeeper(msg.sender);
}
_;
}
/**
* @notice Modifier to restrict access to curators only
* @param fleetAddress The address of the fleet to check the curator role for
* @dev Checks if the caller has the contract-specific CURATOR_ROLE
*/
modifier onlyCurator(address fleetAddress) {
if (
fleetAddress == address(0) ||
!_accessManager.hasRole(
generateRole(ContractSpecificRoles.CURATOR_ROLE, fleetAddress),
msg.sender
)
) {
revert CallerIsNotCurator(msg.sender);
}
_;
}
/**
* @notice Modifier to restrict access to guardians only
* @dev Modifier to check that the caller has the Guardian role
* @custom:internal-logic
* - Checks if the caller has the GUARDIAN_ROLE in the access manager
* @custom:effects
* - Reverts if the caller doesn't have the GUARDIAN_ROLE
* - Allows the function to proceed if the caller has the role
* @custom:security-considerations
* - Ensures that only authorized guardians can access emergency functions
* - Relies on the correct setup of the access manager
*/
modifier onlyGuardian() {
if (!_accessManager.hasRole(GUARDIAN_ROLE, msg.sender)) {
revert CallerIsNotGuardian(msg.sender);
}
_;
}
/**
* @notice Modifier to restrict access to either guardians or governors
* @dev Modifier to check that the caller has either the Guardian or Governor role
* @custom:internal-logic
* - Checks if the caller has either the GUARDIAN_ROLE or the GOVERNOR_ROLE
* @custom:effects
* - Reverts if the caller doesn't have either of the required roles
* - Allows the function to proceed if the caller has one of the roles
* @custom:security-considerations
* - Ensures that only authorized guardians or governors can access certain functions
* - Provides flexibility for functions that can be accessed by either role
* @custom:gas-considerations
* - Performs two role checks, which may impact gas usage
*/
modifier onlyGuardianOrGovernor() {
if (
!_accessManager.hasRole(GUARDIAN_ROLE, msg.sender) &&
!_accessManager.hasRole(GOVERNOR_ROLE, msg.sender)
) {
revert CallerIsNotGuardianOrGovernor(msg.sender);
}
_;
}
/**
* @notice Modifier to restrict access to decay controllers only
*/
modifier onlyDecayController() {
if (!_accessManager.hasRole(DECAY_CONTROLLER_ROLE, msg.sender)) {
revert CallerIsNotDecayController(msg.sender);
}
_;
}
/**
* @notice Modifier to restrict access to foundation only
* @dev Modifier to check that the caller has the Foundation role
* @custom:security-considerations
* - Ensures that only the Foundation can access vesting and related functions
* - Relies on the correct setup of the access manager
*/
modifier onlyFoundation() {
if (
!_accessManager.hasRole(
_accessManager.FOUNDATION_ROLE(),
msg.sender
)
) {
revert CallerIsNotFoundation(msg.sender);
}
_;
}
/*//////////////////////////////////////////////////////////////
PUBLIC FUNCTIONS
//////////////////////////////////////////////////////////////*/
/**
* @notice Generates a role identifier for a specific contract and role
* @param roleName The name of the role
* @param roleTargetContract The address of the contract the role is for
* @return The generated role identifier
* @dev This function is used to create unique role identifiers for contract-specific roles
*/
function generateRole(
ContractSpecificRoles roleName,
address roleTargetContract
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(roleName, roleTargetContract));
}
/**
* @notice Checks if an account has the Admirals Quarters role
* @param account The address to check
* @return bool True if the account has the Admirals Quarters role
*/
function hasAdmiralsQuartersRole(
address account
) public view returns (bool) {
return _accessManager.hasRole(ADMIRALS_QUARTERS_ROLE, account);
}
/*//////////////////////////////////////////////////////////////
INTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
/**
* @notice Helper function to check if an address has the Governor role
* @param account The address to check
* @return bool True if the address has the Governor role
*/
function _isGovernor(address account) internal view returns (bool) {
return _accessManager.hasRole(GOVERNOR_ROLE, account);
}
function _isDecayController(address account) internal view returns (bool) {
return _accessManager.hasRole(DECAY_CONTROLLER_ROLE, account);
}
/**
* @notice Helper function to check if an address has the Foundation role
* @param account The address to check
* @return bool True if the address has the Foundation role
*/
function _isFoundation(address account) internal view returns (bool) {
return
_accessManager.hasRole(_accessManager.FOUNDATION_ROLE(), account);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {ContractSpecificRoles, IProtocolAccessManager} from "../interfaces/IProtocolAccessManager.sol";
import {LimitedAccessControl} from "./LimitedAccessControl.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
/**
* @title ProtocolAccessManager
* @notice This contract is the central authority for access control within the protocol.
* It defines and manages various roles that govern different aspects of the system.
*
* @dev This contract extends LimitedAccessControl, which restricts direct role management.
* Roles are typically assigned during deployment or through governance proposals.
*
* The contract defines four main roles:
* 1. GOVERNOR_ROLE: System-wide administrators
* 2. KEEPER_ROLE: Routine maintenance operators
* 3. SUPER_KEEPER_ROLE: Advanced maintenance operators
* 4. COMMANDER_ROLE: Managers of specific protocol components (Arks)
* 5. ADMIRALS_QUARTERS_ROLE: Specific role for admirals quarters bundler contract
* Role Hierarchy and Management:
* - The GOVERNOR_ROLE is at the top of the hierarchy and can manage all other roles.
* - Other roles cannot manage roles directly due to LimitedAccessControl restrictions.
* - Role assignments are typically done through governance proposals or during initial setup.
*
* Usage in the System:
* - Other contracts in the system inherit from ProtocolAccessManaged, which checks permissions
* against this ProtocolAccessManager.
* - Critical functions in various contracts are protected by role-based modifiers
* (e.g., onlyGovernor, onlyKeeper, etc.) which query this contract for permissions.
*
* Security Considerations:
* - The GOVERNOR_ROLE has significant power and should be managed carefully, potentially
* through a multi-sig wallet or governance contract.
* - The SUPER_KEEPER_ROLE has elevated privileges and should be assigned judiciously.
* - The COMMANDER_ROLE is not directly manageable through this contract but is used
* in other parts of the system for specific access control.
*/
contract ProtocolAccessManager is IProtocolAccessManager, LimitedAccessControl {
/*//////////////////////////////////////////////////////////////
CONSTANTS
//////////////////////////////////////////////////////////////*/
/// @notice Role identifier for protocol governors - highest privilege level with admin capabilities
bytes32 public constant GOVERNOR_ROLE = keccak256("GOVERNOR_ROLE");
/// @notice Role identifier for super keepers who can globally perform fleet maintanence roles
bytes32 public constant SUPER_KEEPER_ROLE = keccak256("SUPER_KEEPER_ROLE");
/**
* @notice Role identifier for protocol guardians
* @dev Guardians have emergency powers across multiple protocol components:
* - Can pause/unpause Fleet operations for security
* - Can pause/unpause TipJar operations
* - Can cancel governance proposals on SummerGovernor even if they don't meet normal cancellation requirements
* - Can cancel TipJar proposals
*
* The guardian role serves as an emergency backstop to protect the protocol, but with less
* privilege than governors.
*/
bytes32 public constant GUARDIAN_ROLE = keccak256("GUARDIAN_ROLE");
/**
* @notice Role identifier for decay controller
* @dev This role allows the decay controller to manage the decay of user voting power
*/
bytes32 public constant DECAY_CONTROLLER_ROLE =
keccak256("DECAY_CONTROLLER_ROLE");
/**
* @notice Role identifier for admirals quarters bundler contract
* @dev This role allows Admirals Quarters to unstake and withdraw assets from fleets, on behalf of users
* @dev Withdrawn tokens go straight to users wallet, lowering the risk of manipulation if the role is compromised
*/
bytes32 public constant ADMIRALS_QUARTERS_ROLE =
keccak256("ADMIRALS_QUARTERS_ROLE");
/// @notice Minimum allowed guardian expiration period (7 days)
uint256 public constant MIN_GUARDIAN_EXPIRY = 7 days;
/// @notice Maximum allowed guardian expiration period (180 days)
uint256 public constant MAX_GUARDIAN_EXPIRY = 180 days;
/// @notice Role identifier for the Foundation which manages vesting wallets and related operations
bytes32 public constant FOUNDATION_ROLE = keccak256("FOUNDATION_ROLE");
/*//////////////////////////////////////////////////////////////
CONSTRUCTOR
//////////////////////////////////////////////////////////////*/
/**
* @notice Initializes the ProtocolAccessManager contract
* @param governor Address of the initial governor
* @dev Grants the governor address the GOVERNOR_ROLE
*/
constructor(address governor) {
_grantRole(GOVERNOR_ROLE, governor);
}
/**
* @dev Modifier to check that the caller has the Governor role
*/
modifier onlyGovernor() {
if (!hasRole(GOVERNOR_ROLE, msg.sender)) {
revert CallerIsNotGovernor(msg.sender);
}
_;
}
/*//////////////////////////////////////////////////////////////
PUBLIC FUNCTIONS
//////////////////////////////////////////////////////////////*/
/**
* @notice Checks if the contract supports a given interface
* @dev Overrides the supportsInterface function from AccessControl
* @param interfaceId The interface identifier, as specified in ERC-165
* @return bool True if the contract supports the interface, false otherwise
*
* This function supports:
* - IProtocolAccessManager interface
* - All interfaces supported by the parent AccessControl contract
*/
function supportsInterface(
bytes4 interfaceId
) public view override returns (bool) {
return
interfaceId == type(IProtocolAccessManager).interfaceId ||
super.supportsInterface(interfaceId);
}
/// @inheritdoc IProtocolAccessManager
function grantGovernorRole(address account) external onlyGovernor {
_grantRole(GOVERNOR_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function revokeGovernorRole(address account) external onlyGovernor {
_revokeRole(GOVERNOR_ROLE, account);
}
/*//////////////////////////////////////////////////////////////
EXTERNAL GOVERNOR FUNCTIONS
//////////////////////////////////////////////////////////////*/
/// @inheritdoc IProtocolAccessManager
function grantSuperKeeperRole(address account) external onlyGovernor {
_grantRole(SUPER_KEEPER_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function grantGuardianRole(address account) external onlyGovernor {
_grantRole(GUARDIAN_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function revokeGuardianRole(address account) external onlyGovernor {
_revokeRole(GUARDIAN_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function revokeSuperKeeperRole(address account) external onlyGovernor {
_revokeRole(SUPER_KEEPER_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function grantContractSpecificRole(
ContractSpecificRoles roleName,
address roleTargetContract,
address roleOwner
) public onlyGovernor {
bytes32 role = generateRole(roleName, roleTargetContract);
_grantRole(role, roleOwner);
}
/// @inheritdoc IProtocolAccessManager
function revokeContractSpecificRole(
ContractSpecificRoles roleName,
address roleTargetContract,
address roleOwner
) public onlyGovernor {
bytes32 role = generateRole(roleName, roleTargetContract);
_revokeRole(role, roleOwner);
}
/// @inheritdoc IProtocolAccessManager
function grantCuratorRole(
address fleetCommanderAddress,
address account
) public onlyGovernor {
grantContractSpecificRole(
ContractSpecificRoles.CURATOR_ROLE,
fleetCommanderAddress,
account
);
}
/// @inheritdoc IProtocolAccessManager
function revokeCuratorRole(
address fleetCommanderAddress,
address account
) public onlyGovernor {
revokeContractSpecificRole(
ContractSpecificRoles.CURATOR_ROLE,
fleetCommanderAddress,
account
);
}
/// @inheritdoc IProtocolAccessManager
function grantKeeperRole(
address fleetCommanderAddress,
address account
) public onlyGovernor {
grantContractSpecificRole(
ContractSpecificRoles.KEEPER_ROLE,
fleetCommanderAddress,
account
);
}
/// @inheritdoc IProtocolAccessManager
function revokeKeeperRole(
address fleetCommanderAddress,
address account
) public onlyGovernor {
revokeContractSpecificRole(
ContractSpecificRoles.KEEPER_ROLE,
fleetCommanderAddress,
account
);
}
/// @inheritdoc IProtocolAccessManager
function grantCommanderRole(
address arkAddress,
address account
) public onlyGovernor {
grantContractSpecificRole(
ContractSpecificRoles.COMMANDER_ROLE,
arkAddress,
account
);
}
/// @inheritdoc IProtocolAccessManager
function revokeCommanderRole(
address arkAddress,
address account
) public onlyGovernor {
revokeContractSpecificRole(
ContractSpecificRoles.COMMANDER_ROLE,
arkAddress,
account
);
}
/// @inheritdoc IProtocolAccessManager
function grantDecayControllerRole(address account) public onlyGovernor {
_grantRole(DECAY_CONTROLLER_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function revokeDecayControllerRole(address account) public onlyGovernor {
_revokeRole(DECAY_CONTROLLER_ROLE, account);
}
/*//////////////////////////////////////////////////////////////
PUBLIC FUNCTIONS
//////////////////////////////////////////////////////////////*/
/// @inheritdoc IProtocolAccessManager
function selfRevokeContractSpecificRole(
ContractSpecificRoles roleName,
address roleTargetContract
) public {
bytes32 role = generateRole(roleName, roleTargetContract);
if (!hasRole(role, msg.sender)) {
revert CallerIsNotContractSpecificRole(msg.sender, role);
}
_revokeRole(role, msg.sender);
}
/// @inheritdoc IProtocolAccessManager
function generateRole(
ContractSpecificRoles roleName,
address roleTargetContract
) public pure returns (bytes32) {
return keccak256(abi.encodePacked(roleName, roleTargetContract));
}
/// @inheritdoc IProtocolAccessManager
function grantAdmiralsQuartersRole(
address account
) external onlyRole(GOVERNOR_ROLE) {
_grantRole(ADMIRALS_QUARTERS_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function revokeAdmiralsQuartersRole(
address account
) external onlyRole(GOVERNOR_ROLE) {
_revokeRole(ADMIRALS_QUARTERS_ROLE, account);
}
mapping(address guardian => uint256 expirationTimestamp)
public guardianExpirations;
/**
* @notice Checks if an account is an active guardian (has role and not expired)
* @param account Address to check
* @return bool True if account is an active guardian
*/
function isActiveGuardian(address account) public view returns (bool) {
return
hasRole(GUARDIAN_ROLE, account) &&
guardianExpirations[account] > block.timestamp;
}
/**
* @notice Sets the expiration timestamp for a guardian
* @param account Guardian address
* @param expiration Timestamp when guardian powers expire
* @dev The expiration period (time from now until expiration) must be between MIN_GUARDIAN_EXPIRY and MAX_GUARDIAN_EXPIRY
* This ensures guardians can't be immediately removed (protecting against malicious proposals) while still
* allowing for their eventual phase-out (protecting against malicious guardians)
*/
function setGuardianExpiration(
address account,
uint256 expiration
) external onlyRole(GOVERNOR_ROLE) {
if (!hasRole(GUARDIAN_ROLE, account)) {
revert CallerIsNotGuardian(account);
}
uint256 expiryPeriod = expiration - block.timestamp;
if (
expiryPeriod < MIN_GUARDIAN_EXPIRY ||
expiryPeriod > MAX_GUARDIAN_EXPIRY
) {
revert InvalidGuardianExpiryPeriod(
expiryPeriod,
MIN_GUARDIAN_EXPIRY,
MAX_GUARDIAN_EXPIRY
);
}
guardianExpirations[account] = expiration;
emit GuardianExpirationSet(account, expiration);
}
/**
* @inheritdoc IProtocolAccessManager
*/
function hasRole(
bytes32 role,
address account
)
public
view
virtual
override(IProtocolAccessManager, AccessControl)
returns (bool)
{
return super.hasRole(role, account);
}
/// @inheritdoc IProtocolAccessManager
function getGuardianExpiration(
address account
) external view returns (uint256 expiration) {
if (!hasRole(GUARDIAN_ROLE, account)) {
revert CallerIsNotGuardian(account);
}
return guardianExpirations[account];
}
/// @inheritdoc IProtocolAccessManager
function grantFoundationRole(address account) external onlyGovernor {
_grantRole(FOUNDATION_ROLE, account);
}
/// @inheritdoc IProtocolAccessManager
function revokeFoundationRole(address account) external onlyGovernor {
_revokeRole(FOUNDATION_ROLE, account);
}
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
/**
* @title IAccessControlErrors
* @dev This file contains custom error definitions for access control in the system.
* @notice These custom errors provide more gas-efficient and informative error handling
* compared to traditional require statements with string messages.
*/
interface IAccessControlErrors {
/**
* @notice Thrown when a caller does not have the required role.
*/
error CallerIsNotContractSpecificRole(address caller, bytes32 role);
/**
* @notice Thrown when a caller is not the curator.
*/
error CallerIsNotCurator(address caller);
/**
* @notice Thrown when a caller is not the governor.
*/
error CallerIsNotGovernor(address caller);
/**
* @notice Thrown when a caller is not a keeper.
*/
error CallerIsNotKeeper(address caller);
/**
* @notice Thrown when a caller is not a super keeper.
*/
error CallerIsNotSuperKeeper(address caller);
/**
* @notice Thrown when a caller is not the commander.
*/
error CallerIsNotCommander(address caller);
/**
* @notice Thrown when a caller is neither the Raft nor the commander.
*/
error CallerIsNotRaftOrCommander(address caller);
/**
* @notice Thrown when a caller is not the Raft.
*/
error CallerIsNotRaft(address caller);
/**
* @notice Thrown when a caller is not an admin.
*/
error CallerIsNotAdmin(address caller);
/**
* @notice Thrown when a caller is not the guardian.
*/
error CallerIsNotGuardian(address caller);
/**
* @notice Thrown when a caller is not the guardian or governor.
*/
error CallerIsNotGuardianOrGovernor(address caller);
/**
* @notice Thrown when a caller is not the decay controller.
*/
error CallerIsNotDecayController(address caller);
/**
* @notice Thrown when a caller is not authorized to board.
*/
error CallerIsNotAuthorizedToBoard(address caller);
/**
* @notice Thrown when direct grant is disabled.
*/
error DirectGrantIsDisabled(address caller);
/**
* @notice Thrown when direct revoke is disabled.
*/
error DirectRevokeIsDisabled(address caller);
/**
* @notice Thrown when an invalid access manager address is provided.
*/
error InvalidAccessManagerAddress(address invalidAddress);
/**
* @notice Error thrown when a caller is not the Foundation
* @param caller The address that attempted the operation
*/
error CallerIsNotFoundation(address caller);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
/**
* @dev Dynamic roles are roles that are not hardcoded in the contract but are defined by the protocol
* Members of this enum are treated as prefixes to the role generated using prefix and target contract address
* e.g generateRole(ContractSpecificRoles.CURATOR_ROLE, address(this)) for FleetCommander, to generate the CURATOR_ROLE
* for the curator of the FleetCommander contract
*/
enum ContractSpecificRoles {
CURATOR_ROLE,
KEEPER_ROLE,
COMMANDER_ROLE
}
/**
* @title IProtocolAccessManager
* @notice Defines system roles and provides role based remote-access control for
* contracts that inherit from ProtocolAccessManaged contract
*/
interface IProtocolAccessManager {
/**
* @notice Grants the Governor role to a given account
*
* @param account The account to which the Governor role will be granted
*/
function grantGovernorRole(address account) external;
/**
* @notice Revokes the Governor role from a given account
*
* @param account The account from which the Governor role will be revoked
*/
function revokeGovernorRole(address account) external;
/**
* @notice Grants the Super Keeper role to a given account
*
* @param account The account to which the Super Keeper role will be granted
*/
function grantSuperKeeperRole(address account) external;
/**
* @notice Revokes the Super Keeper role from a given account
*
* @param account The account from which the Super Keeper role will be revoked
*/
function revokeSuperKeeperRole(address account) external;
/**
* @dev Generates a unique role identifier based on the role name and target contract address
* @param roleName The name of the role (from ContractSpecificRoles enum)
* @param roleTargetContract The address of the contract the role is for
* @return bytes32 The generated role identifier
* @custom:internal-logic
* - Combines the roleName and roleTargetContract using abi.encodePacked
* - Applies keccak256 hash function to generate a unique bytes32 identifier
* @custom:effects
* - Does not modify any state, pure function
* @custom:security-considerations
* - Ensures unique role identifiers for different contracts
* - Relies on the uniqueness of contract addresses and role names
*/
function generateRole(
ContractSpecificRoles roleName,
address roleTargetContract
) external pure returns (bytes32);
/**
* @notice Grants a contract specific role to a given account
* @param roleName The name of the role to grant
* @param roleTargetContract The address of the contract to grant the role for
* @param account The account to which the role will be granted
*/
function grantContractSpecificRole(
ContractSpecificRoles roleName,
address roleTargetContract,
address account
) external;
/**
* @notice Revokes a contract specific role from a given account
* @param roleName The name of the role to revoke
* @param roleTargetContract The address of the contract to revoke the role for
* @param account The account from which the role will be revoked
*/
function revokeContractSpecificRole(
ContractSpecificRoles roleName,
address roleTargetContract,
address account
) external;
/**
* @notice Grants the Curator role to a given account
* @param fleetCommanderAddress The address of the fleet commander to grant the role for
* @param account The account to which the role will be granted
*/
function grantCuratorRole(
address fleetCommanderAddress,
address account
) external;
/**
* @notice Revokes the Curator role from a given account
* @param fleetCommanderAddress The address of the fleet commander to revoke the role for
* @param account The account from which the role will be revoked
*/
function revokeCuratorRole(
address fleetCommanderAddress,
address account
) external;
/**
* @notice Grants the Keeper role to a given account
* @param fleetCommanderAddress The address of the fleet commander to grant the role for
* @param account The account to which the role will be granted
*/
function grantKeeperRole(
address fleetCommanderAddress,
address account
) external;
/**
* @notice Revokes the Keeper role from a given account
* @param fleetCommanderAddress The address of the fleet commander to revoke the role for
* @param account The account from which the role will be revoked
*/
function revokeKeeperRole(
address fleetCommanderAddress,
address account
) external;
/**
* @notice Grants the Commander role for a specific Ark
* @param arkAddress Address of the Ark contract
* @param account Address to grant the Commander role to
*/
function grantCommanderRole(address arkAddress, address account) external;
/**
* @notice Revokes the Commander role for a specific Ark
* @param arkAddress Address of the Ark contract
* @param account Address to revoke the Commander role from
*/
function revokeCommanderRole(address arkAddress, address account) external;
/**
* @notice Revokes a contract specific role from the caller
* @param roleName The name of the role to revoke
* @param roleTargetContract The address of the contract to revoke the role for
*/
function selfRevokeContractSpecificRole(
ContractSpecificRoles roleName,
address roleTargetContract
) external;
/**
* @notice Grants the Guardian role to a given account
*
* @param account The account to which the Guardian role will be granted
*/
function grantGuardianRole(address account) external;
/**
* @notice Revokes the Guardian role from a given account
*
* @param account The account from which the Guardian role will be revoked
*/
function revokeGuardianRole(address account) external;
/**
* @notice Grants the Decay Controller role to a given account
* @param account The account to which the Decay Controller role will be granted
*/
function grantDecayControllerRole(address account) external;
/**
* @notice Revokes the Decay Controller role from a given account
* @param account The account from which the Decay Controller role will be revoked
*/
function revokeDecayControllerRole(address account) external;
/**
* @notice Grants the ADMIRALS_QUARTERS_ROLE to an address
* @param account The address to grant the role to
*/
function grantAdmiralsQuartersRole(address account) external;
/**
* @notice Revokes the ADMIRALS_QUARTERS_ROLE from an address
* @param account The address to revoke the role from
*/
function revokeAdmiralsQuartersRole(address account) external;
/*//////////////////////////////////////////////////////////////
ROLE CONSTANTS
//////////////////////////////////////////////////////////////*/
/// @notice Role identifier for the Governor role
function GOVERNOR_ROLE() external pure returns (bytes32);
/// @notice Role identifier for the Guardian role
function GUARDIAN_ROLE() external pure returns (bytes32);
/// @notice Role identifier for the Super Keeper role
function SUPER_KEEPER_ROLE() external pure returns (bytes32);
/// @notice Role identifier for the Decay Controller role
function DECAY_CONTROLLER_ROLE() external pure returns (bytes32);
/// @notice Role identifier for the Admirals Quarters role
function ADMIRALS_QUARTERS_ROLE() external pure returns (bytes32);
/// @notice Role identifier for the Foundation, responsible for managing vesting wallets and related operations
function FOUNDATION_ROLE() external pure returns (bytes32);
/**
* @notice Checks if an account has a specific role
* @param role The role identifier to check
* @param account The account to check the role for
* @return bool True if the account has the role, false otherwise
*/
function hasRole(
bytes32 role,
address account
) external view returns (bool);
/*//////////////////////////////////////////////////////////////
EVENTS
//////////////////////////////////////////////////////////////*/
/**
* @notice Emitted when a guardian's expiration is set
* @param account The address of the guardian
* @param expiration The timestamp until which the guardian powers are valid
*/
event GuardianExpirationSet(address indexed account, uint256 expiration);
/*//////////////////////////////////////////////////////////////
GUARDIAN FUNCTIONS
//////////////////////////////////////////////////////////////*/
/**
* @notice Checks if an account is an active guardian (has role and not expired)
* @param account Address to check
* @return bool True if account is an active guardian
*/
function isActiveGuardian(address account) external view returns (bool);
/**
* @notice Sets the expiration timestamp for a guardian
* @param account Guardian address
* @param expiration Timestamp when guardian powers expire
*/
function setGuardianExpiration(
address account,
uint256 expiration
) external;
/**
* @notice Gets the expiration timestamp for a guardian
* @param account Guardian address
* @return uint256 Timestamp when guardian powers expire
*/
function guardianExpirations(
address account
) external view returns (uint256);
/**
* @notice Gets the expiration timestamp for a guardian
* @param account Guardian address
* @return expiration Timestamp when guardian powers expire
*/
function getGuardianExpiration(
address account
) external view returns (uint256 expiration);
/**
* @notice Emitted when an invalid guardian expiry period is set
* @param expiryPeriod The expiry period that was set
* @param minExpiryPeriod The minimum allowed expiry period
* @param maxExpiryPeriod The maximum allowed expiry period
*/
error InvalidGuardianExpiryPeriod(
uint256 expiryPeriod,
uint256 minExpiryPeriod,
uint256 maxExpiryPeriod
);
/**
* @notice Grants the Foundation role to a given account. The Foundation is responsible for
* managing vesting wallets and related operations.
* @param account The account to which the Foundation role will be granted
*/
function grantFoundationRole(address account) external;
/**
* @notice Revokes the Foundation role from a given account
* @param account The account from which the Foundation role will be revoked
*/
function revokeFoundationRole(address account) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
/**
* @title IConfigurationManagerErrors
* @dev This file contains custom error definitions for the ConfigurationManager contract.
* @notice These custom errors provide more gas-efficient and informative error handling
* compared to traditional require statements with string messages.
*/
interface IConfigurationManagerErrors {
/**
* @notice Thrown when ConfigurationManager was already initialized.
*/
error ConfigurationManagerAlreadyInitialized();
/**
* @notice Thrown when the Raft address is not set.
*/
error RaftNotSet();
/**
* @notice Thrown when the TipJar address is not set.
*/
error TipJarNotSet();
/**
* @notice Thrown when the Treasury address is not set.
*/
error TreasuryNotSet();
/**
* @notice Thrown when constructor address is set to the zero address.
*/
error AddressZero();
/**
* @notice Thrown when the HarborCommand address is not set.
*/
error HarborCommandNotSet();
/**
* @notice Thrown when a feature is not supported.
*/
error NotSupported();
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
/**
* @title IConfigurationManagerEvents
* @notice Interface for events emitted by the Configuration Manager
*/
interface IConfigurationManagerEvents {
/**
* @notice Emitted when the Raft address is updated
* @param newRaft The address of the new Raft
*/
event RaftUpdated(address oldRaft, address newRaft);
/**
* @notice Emitted when the tip jar address is updated
* @param newTipJar The address of the new tip jar
*/
event TipJarUpdated(address oldTipJar, address newTipJar);
/**
* @notice Emitted when the tip rate is updated
* @param newTipRate The new tip rate value
*/
event TipRateUpdated(uint8 oldTipRate, uint8 newTipRate);
/**
* @notice Emitted when the Treasury address is updated
* @param newTreasury The address of the new Treasury
*/
event TreasuryUpdated(address oldTreasury, address newTreasury);
/**
* @notice Emitted when the Harbor Command address is updated
* @param oldHarborCommand The address of the old Harbor Command
* @param newHarborCommand The address of the new Harbor Command
*/
event HarborCommandUpdated(
address oldHarborCommand,
address newHarborCommand
);
/**
* @notice Emitted when the Fleet Commander Rewards Manager Factory address is updated
* @param oldFleetCommanderRewardsManagerFactory The address of the old Fleet Commander Rewards Manager Factory
* @param newFleetCommanderRewardsManagerFactory The address of the new Fleet Commander Rewards Manager Factory
*/
event FleetCommanderRewardsManagerFactoryUpdated(
address oldFleetCommanderRewardsManagerFactory,
address newFleetCommanderRewardsManagerFactory
);
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
import {IConfigurationManagerErrors} from "../errors/IConfigurationManagerErrors.sol";
import {IConfigurationManagerEvents} from "../events/IConfigurationManagerEvents.sol";
import {ConfigurationManagerParams} from "../types/ConfigurationManagerTypes.sol";
/**
* @title IConfigurationManager
* @notice Interface for the ConfigurationManager contract, which manages system-wide parameters
* @dev This interface defines the getters and setters for system-wide parameters
*/
interface IConfigurationManager is
IConfigurationManagerEvents,
IConfigurationManagerErrors
{
/**
* @notice Initialize the configuration with the given parameters
* @param params The parameters to initialize the configuration with
* @dev Can only be called by the governor
*/
function initializeConfiguration(
ConfigurationManagerParams memory params
) external;
/**
* @notice Get the address of the Raft contract
* @return The address of the Raft contract
* @dev This is where rewards and farmed tokens are sent for processing
*/
function raft() external view returns (address);
/**
* @notice Get the current tip jar address
* @return The current tip jar address
* @dev This is the contract that owns tips and is responsible for
* dispensing them to claimants
*/
function tipJar() external view returns (address);
/**
* @notice Get the current treasury address
* @return The current treasury address
* @dev This is the contract that owns the treasury and is responsible for
* dispensing funds to the protocol's operations
*/
function treasury() external view returns (address);
/**
* @notice Get the address of theHarbor command
* @return The address of theHarbor command
* @dev This is the contract that's the registry of all Fleet Commanders
*/
function harborCommand() external view returns (address);
/**
* @notice Get the address of the Fleet Commander Rewards Manager Factory contract
* @return The address of the Fleet Commander Rewards Manager Factory contract
*/
function fleetCommanderRewardsManagerFactory()
external
view
returns (address);
/**
* @notice Set a new address for the Raft contract
* @param newRaft The new address for the Raft contract
* @dev Can only be called by the governor
*/
function setRaft(address newRaft) external;
/**
* @notice Set a new tip ar address
* @param newTipJar The address of the new tip jar
* @dev Can only be called by the governor
*/
function setTipJar(address newTipJar) external;
/**
* @notice Set a new treasury address
* @param newTreasury The address of the new treasury
* @dev Can only be called by the governor
*/
function setTreasury(address newTreasury) external;
/**
* @notice Set a new harbor command address
* @param newHarborCommand The address of the new harbor command
* @dev Can only be called by the governor
*/
function setHarborCommand(address newHarborCommand) external;
/**
* @notice Set a new fleet commander rewards manager factory address
* @param newFleetCommanderRewardsManagerFactory The address of the new fleet commander rewards manager factory
* @dev Can only be called by the governor
*/
function setFleetCommanderRewardsManagerFactory(
address newFleetCommanderRewardsManagerFactory
) external;
}// SPDX-License-Identifier: BUSL-1.1
pragma solidity 0.8.28;
/**
* @notice Initialization parameters for the ConfigurationManager contract
*/
struct ConfigurationManagerParams {
address raft;
address tipJar;
address treasury;
address harborCommand;
address fleetCommanderRewardsManagerFactory;
}{
"optimizer": {
"enabled": true,
"runs": 50
},
"evmVersion": "cancun",
"viaIR": true,
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_accessManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressZero","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotAdmin","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotAuthorizedToBoard","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotCommander","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"CallerIsNotContractSpecificRole","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotCurator","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotDecayController","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotFoundation","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotGovernor","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotGuardian","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotGuardianOrGovernor","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotKeeper","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotRaft","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotRaftOrCommander","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"CallerIsNotSuperKeeper","type":"error"},{"inputs":[],"name":"ConfigurationManagerAlreadyInitialized","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"DirectGrantIsDisabled","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"DirectRevokeIsDisabled","type":"error"},{"inputs":[],"name":"HarborCommandNotSet","type":"error"},{"inputs":[{"internalType":"address","name":"invalidAddress","type":"address"}],"name":"InvalidAccessManagerAddress","type":"error"},{"inputs":[],"name":"NotSupported","type":"error"},{"inputs":[],"name":"RaftNotSet","type":"error"},{"inputs":[],"name":"TipJarNotSet","type":"error"},{"inputs":[],"name":"TreasuryNotSet","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldFleetCommanderRewardsManagerFactory","type":"address"},{"indexed":false,"internalType":"address","name":"newFleetCommanderRewardsManagerFactory","type":"address"}],"name":"FleetCommanderRewardsManagerFactoryUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldHarborCommand","type":"address"},{"indexed":false,"internalType":"address","name":"newHarborCommand","type":"address"}],"name":"HarborCommandUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRaft","type":"address"},{"indexed":false,"internalType":"address","name":"newRaft","type":"address"}],"name":"RaftUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldTipJar","type":"address"},{"indexed":false,"internalType":"address","name":"newTipJar","type":"address"}],"name":"TipJarUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"oldTipRate","type":"uint8"},{"indexed":false,"internalType":"uint8","name":"newTipRate","type":"uint8"}],"name":"TipRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldTreasury","type":"address"},{"indexed":false,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryUpdated","type":"event"},{"inputs":[],"name":"ADMIRALS_QUARTERS_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DECAY_CONTROLLER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GUARDIAN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUPER_KEEPER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fleetCommanderRewardsManagerFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum ContractSpecificRoles","name":"roleName","type":"uint8"},{"internalType":"address","name":"roleTargetContract","type":"address"}],"name":"generateRole","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"harborCommand","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasAdmiralsQuartersRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"raft","type":"address"},{"internalType":"address","name":"tipJar","type":"address"},{"internalType":"address","name":"treasury","type":"address"},{"internalType":"address","name":"harborCommand","type":"address"},{"internalType":"address","name":"fleetCommanderRewardsManagerFactory","type":"address"}],"internalType":"struct ConfigurationManagerParams","name":"params","type":"tuple"}],"name":"initializeConfiguration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"raft","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newFleetCommanderRewardsManagerFactory","type":"address"}],"name":"setFleetCommanderRewardsManagerFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newHarborCommand","type":"address"}],"name":"setHarborCommand","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRaft","type":"address"}],"name":"setRaft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTipJar","type":"address"}],"name":"setTipJar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newTreasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tipJar","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a0806040523461010357602081610f54803803809161001f828561012d565b83398101031261010357516001600160a01b0381169081900361010357801561011a576040516301ffc9a760e01b815263261c910560e21b6004820152602081602481855afa90811561010f575f916100d0575b50156100be57608052604051610def90816101658239608051818181610160015281816102c80152818161036901528181610535015281816107010152818161083201526109ff0152f35b6347bd7c1d60e01b5f5260045260245ffd5b90506020813d602011610107575b816100eb6020938361012d565b8101031261010357518015158103610103575f610073565b5f80fd5b3d91506100de565b6040513d5f823e3d90fd5b6347bd7c1d60e01b5f525f60045260245ffd5b601f909101601f19168101906001600160401b0382119082101761015057604052565b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c908163117d8ae014610cdb57508063158ef93e14610cba5780631fcb6ee61461093b57806324ea54f41461090157806344ee0605146107eb5780635b0f83f3146107c35780635c66e3da146106ba57806361d027b31461069257806366e943f11461065857806369b3054b146105f7578063788d8366146104ee5780637aaceb95146104c6578063a89f38a31461048c578063c0b534c214610452578063ccc574901461042b578063d6c953c614610322578063ebc136d01461025f578063f0f44260146101195763f7e533ec146100ed575f80fd5b34610115575f366003190112610115576004546040516001600160a01b039091168152602090f35b5f80fd5b3461011557602036600319011261011557610132610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610254575f91610225575b5015610212576001600160a01b0381169081156102035760025460405190917f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a919081906101f0906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600255005b639fabe1c160e01b5f5260045ffd5b630ea7d7ed60e21b5f523360045260245ffd5b610247915060203d60201161024d575b61023f8183610d00565b810190610d4e565b82610198565b503d610235565b6040513d5f823e3d90fd5b3461011557602036600319011261011557610278610d22565b604051632474521560e21b81527fb00be3d6a5434b97b328543d1486d56adcb7e74080170d1cdd7e0306c3d9ba3d60048201526001600160a01b03918216602482015290602090829060449082907f0000000000000000000000000000000000000000000000000000000000000000165afa8015610254576020915f91610305575b506040519015158152f35b61031c9150823d841161024d5761023f8183610d00565b826102fa565b346101155760203660031901126101155761033b610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610254575f9161040c575b5015610212576001600160a01b0381169081156102035760045460405190917ffdc61a171cf2fa6f226e1e76e7a1769cfab9da2ff86bad6060c7d77ee62e1925919081906103f9906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600455005b610425915060203d60201161024d5761023f8183610d00565b826103a1565b34610115575f3660031901126101155760206040515f516020610d9a5f395f51905f528152f35b34610115575f3660031901126101155760206040517f025d8bbf3268be680d2605ebf6da15063b9915615bf1087dab336efc1bf970cb8152f35b34610115575f3660031901126101155760206040517fb00be3d6a5434b97b328543d1486d56adcb7e74080170d1cdd7e0306c3d9ba3d8152f35b34610115575f366003190112610115576001546040516001600160a01b039091168152602090f35b3461011557602036600319011261011557610507610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610254575f916105d8575b5015610212576001600160a01b0381169081156102035760035460405190917f5da6b94665bf1ffea8956b1bfd3424ac4e5879083197059f23e5181df77c3619919081906105c5906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600355005b6105f1915060203d60201161024d5761023f8183610d00565b8261056d565b346101155760403660031901126101155760043560038110156101155760209061061f610d38565b604051908382019260f81b835260018060601b03199060601b1660218201526015815261064d603582610d00565b519020604051908152f35b34610115575f3660031901126101155760206040517f0d186688925976bbe6755ae984501c8e3e2b103a7af59fd803ab9c6d891ae7e08152f35b34610115575f366003190112610115576002546040516001600160a01b039091168152602090f35b34610115576020366003190112610115576106d3610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610254575f916107a4575b5015610212576001600160a01b0381169081156102035760015460405190917ff6305c18a40cde2556a61871b17cd0a86d780832dc0e3e05a43c1d2ff8a53ac491908190610791906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600155005b6107bd915060203d60201161024d5761023f8183610d00565b82610739565b34610115575f366003190112610115576003546040516001600160a01b039091168152602090f35b3461011557602036600319011261011557610804610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610254575f916108e2575b5015610212576001600160a01b03811615610203575f54907fffe0a81e9fcc7a42c05a5b4b763ffb4ca50ddd532d824b476298bb1264194545604051806108bd8460018060a01b038760081c1683610d7f565b0390a1610100600160a81b031990911660089190911b610100600160a81b0316175f55005b6108fb915060203d60201161024d5761023f8183610d00565b8261086a565b34610115575f3660031901126101155760206040517f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50418152f35b346101155760a03660031901126101155760405160a0810181811067ffffffffffffffff821117610ca657604052610971610d22565b815261097b610d38565b602082019081526044356001600160a01b038116810361011557604083019081526064356001600160a01b03811681036101155760608401908152608435926001600160a01b03841684036101155760808501938452604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610254575f91610c87575b5015610212575f549360ff8516610c785785516001600160a01b0316158015610c66575b8015610c54575b8015610c42575b8015610c30575b610203577f5da6b94665bf1ffea8956b1bfd3424ac4e5879083197059f23e5181df77c3619610bf77ffdc61a171cf2fa6f226e1e76e7a1769cfab9da2ff86bad6060c7d77ee62e1925947f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a610bdf610baf987ff6305c18a40cde2556a61871b17cd0a86d780832dc0e3e05a43c1d2ff8a53ac4610bc7610c0f997fffe0a81e9fcc7a42c05a5b4b763ffb4ca50ddd532d824b476298bb126419454560019f519d60018f908060a01b0384511660018060a01b0319600154161760015560018060a01b0387511660018060a01b0319600254161760025560018060a01b038a511660018060a01b0319600354161760035560018060a01b038d511660018060a01b031960045416176004556040519160019182849360a01b031682610d66565b0390a18e8060a01b0390511660405191829182610d66565b0390a18b8060a01b0390511660405191829182610d66565b0390a1888060a01b0390511660405191829182610d66565b0390a1858060a01b0390511660405191829182610d66565b0390a16101008360a81b039060081b1690828060a81b03191617175f555f80f35b5080516001600160a01b031615610a70565b5082516001600160a01b031615610a69565b5083516001600160a01b031615610a62565b5081516001600160a01b031615610a5b565b63485ed86d60e01b5f5260045ffd5b610ca0915060203d60201161024d5761023f8183610d00565b86610a37565b634e487b7160e01b5f52604160045260245ffd5b34610115575f36600319011261011557602060ff5f54166040519015158152f35b34610115575f366003190112610115575f5460081c6001600160a01b03168152602090f35b90601f8019910116810190811067ffffffffffffffff821117610ca657604052565b600435906001600160a01b038216820361011557565b602435906001600160a01b038216820361011557565b90816020910312610115575180151581036101155790565b5f81526001600160a01b03909116602082015260400190565b6001600160a01b039182168152911660208201526040019056fe7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55a2646970667358221220a1a6ee10b854a0c1b2e75fbce6df1b1c0b41f7aea323dd608284b01386aa608e64736f6c634300081c003300000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f3560e01c908163117d8ae014610cdb57508063158ef93e14610cba5780631fcb6ee61461093b57806324ea54f41461090157806344ee0605146107eb5780635b0f83f3146107c35780635c66e3da146106ba57806361d027b31461069257806366e943f11461065857806369b3054b146105f7578063788d8366146104ee5780637aaceb95146104c6578063a89f38a31461048c578063c0b534c214610452578063ccc574901461042b578063d6c953c614610322578063ebc136d01461025f578063f0f44260146101195763f7e533ec146100ed575f80fd5b34610115575f366003190112610115576004546040516001600160a01b039091168152602090f35b5f80fd5b3461011557602036600319011261011557610132610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f6001600160a01b03165afa908115610254575f91610225575b5015610212576001600160a01b0381169081156102035760025460405190917f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a919081906101f0906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600255005b639fabe1c160e01b5f5260045ffd5b630ea7d7ed60e21b5f523360045260245ffd5b610247915060203d60201161024d575b61023f8183610d00565b810190610d4e565b82610198565b503d610235565b6040513d5f823e3d90fd5b3461011557602036600319011261011557610278610d22565b604051632474521560e21b81527fb00be3d6a5434b97b328543d1486d56adcb7e74080170d1cdd7e0306c3d9ba3d60048201526001600160a01b03918216602482015290602090829060449082907f00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f165afa8015610254576020915f91610305575b506040519015158152f35b61031c9150823d841161024d5761023f8183610d00565b826102fa565b346101155760203660031901126101155761033b610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f6001600160a01b03165afa908115610254575f9161040c575b5015610212576001600160a01b0381169081156102035760045460405190917ffdc61a171cf2fa6f226e1e76e7a1769cfab9da2ff86bad6060c7d77ee62e1925919081906103f9906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600455005b610425915060203d60201161024d5761023f8183610d00565b826103a1565b34610115575f3660031901126101155760206040515f516020610d9a5f395f51905f528152f35b34610115575f3660031901126101155760206040517f025d8bbf3268be680d2605ebf6da15063b9915615bf1087dab336efc1bf970cb8152f35b34610115575f3660031901126101155760206040517fb00be3d6a5434b97b328543d1486d56adcb7e74080170d1cdd7e0306c3d9ba3d8152f35b34610115575f366003190112610115576001546040516001600160a01b039091168152602090f35b3461011557602036600319011261011557610507610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f6001600160a01b03165afa908115610254575f916105d8575b5015610212576001600160a01b0381169081156102035760035460405190917f5da6b94665bf1ffea8956b1bfd3424ac4e5879083197059f23e5181df77c3619919081906105c5906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600355005b6105f1915060203d60201161024d5761023f8183610d00565b8261056d565b346101155760403660031901126101155760043560038110156101155760209061061f610d38565b604051908382019260f81b835260018060601b03199060601b1660218201526015815261064d603582610d00565b519020604051908152f35b34610115575f3660031901126101155760206040517f0d186688925976bbe6755ae984501c8e3e2b103a7af59fd803ab9c6d891ae7e08152f35b34610115575f366003190112610115576002546040516001600160a01b039091168152602090f35b34610115576020366003190112610115576106d3610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f6001600160a01b03165afa908115610254575f916107a4575b5015610212576001600160a01b0381169081156102035760015460405190917ff6305c18a40cde2556a61871b17cd0a86d780832dc0e3e05a43c1d2ff8a53ac491908190610791906001600160a01b03861683610d7f565b0390a16001600160a01b03191617600155005b6107bd915060203d60201161024d5761023f8183610d00565b82610739565b34610115575f366003190112610115576003546040516001600160a01b039091168152602090f35b3461011557602036600319011261011557610804610d22565b604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f6001600160a01b03165afa908115610254575f916108e2575b5015610212576001600160a01b03811615610203575f54907fffe0a81e9fcc7a42c05a5b4b763ffb4ca50ddd532d824b476298bb1264194545604051806108bd8460018060a01b038760081c1683610d7f565b0390a1610100600160a81b031990911660089190911b610100600160a81b0316175f55005b6108fb915060203d60201161024d5761023f8183610d00565b8261086a565b34610115575f3660031901126101155760206040517f55435dd261a4b9b3364963f7738a7a662ad9c84396d64be3365284bb7f0a50418152f35b346101155760a03660031901126101155760405160a0810181811067ffffffffffffffff821117610ca657604052610971610d22565b815261097b610d38565b602082019081526044356001600160a01b038116810361011557604083019081526064356001600160a01b03811681036101155760608401908152608435926001600160a01b03841684036101155760808501938452604051632474521560e21b81525f516020610d9a5f395f51905f5260048201523360248201526020816044817f00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f6001600160a01b03165afa908115610254575f91610c87575b5015610212575f549360ff8516610c785785516001600160a01b0316158015610c66575b8015610c54575b8015610c42575b8015610c30575b610203577f5da6b94665bf1ffea8956b1bfd3424ac4e5879083197059f23e5181df77c3619610bf77ffdc61a171cf2fa6f226e1e76e7a1769cfab9da2ff86bad6060c7d77ee62e1925947f4ab5be82436d353e61ca18726e984e561f5c1cc7c6d38b29d2553c790434705a610bdf610baf987ff6305c18a40cde2556a61871b17cd0a86d780832dc0e3e05a43c1d2ff8a53ac4610bc7610c0f997fffe0a81e9fcc7a42c05a5b4b763ffb4ca50ddd532d824b476298bb126419454560019f519d60018f908060a01b0384511660018060a01b0319600154161760015560018060a01b0387511660018060a01b0319600254161760025560018060a01b038a511660018060a01b0319600354161760035560018060a01b038d511660018060a01b031960045416176004556040519160019182849360a01b031682610d66565b0390a18e8060a01b0390511660405191829182610d66565b0390a18b8060a01b0390511660405191829182610d66565b0390a1888060a01b0390511660405191829182610d66565b0390a1858060a01b0390511660405191829182610d66565b0390a16101008360a81b039060081b1690828060a81b03191617175f555f80f35b5080516001600160a01b031615610a70565b5082516001600160a01b031615610a69565b5083516001600160a01b031615610a62565b5081516001600160a01b031615610a5b565b63485ed86d60e01b5f5260045ffd5b610ca0915060203d60201161024d5761023f8183610d00565b86610a37565b634e487b7160e01b5f52604160045260245ffd5b34610115575f36600319011261011557602060ff5f54166040519015158152f35b34610115575f366003190112610115575f5460081c6001600160a01b03168152602090f35b90601f8019910116810190811067ffffffffffffffff821117610ca657604052565b600435906001600160a01b038216820361011557565b602435906001600160a01b038216820361011557565b90816020910312610115575180151581036101155790565b5f81526001600160a01b03909116602082015260400190565b6001600160a01b039182168152911660208201526040019056fe7935bd0ae54bc31f548c14dba4d37c5c64b3f8ca900cb468fb8abd54d5894f55a2646970667358221220a1a6ee10b854a0c1b2e75fbce6df1b1c0b41f7aea323dd608284b01386aa608e64736f6c634300081c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f
-----Decoded View---------------
Arg [0] : _accessManager (address): 0x38fB5a7fa70103dCd9e8A969f3975A77E0fE755f
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000038fb5a7fa70103dcd9e8a969f3975a77e0fe755f
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.