// SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; // ============ Internal Imports ============ import {IMailbox} from "../interfaces/IMailbox.sol"; // ============ External Imports ============ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import {Address} from "@openzeppelin/contracts/utils/Address.sol"; /** * @title Mailbox * @author Celo Labs Inc. * @notice Shared utilities between Outbox and Inbox. */ abstract contract Mailbox is IMailbox, OwnableUpgradeable { // ============ Immutable Variables ============ // Domain of chain on which the contract is deployed uint32 public immutable override localDomain; // ============ Public Variables ============ // Address of the validator manager contract. address public validatorManager; // ============ Upgrade Gap ============ // gap for upgrade safety uint256[49] private __GAP; // ============ Events ============ /** * @notice Emitted when the validator manager contract is changed * @param validatorManager The address of the new validatorManager */ event ValidatorManagerSet(address validatorManager); // ============ Modifiers ============ /** * @notice Ensures that a function is called by the validator manager contract. */ modifier onlyValidatorManager() { require(msg.sender == validatorManager, "!validatorManager"); _; } // ============ Constructor ============ constructor(uint32 _localDomain) { localDomain = _localDomain; } // ============ Initializer ============ function __Mailbox_initialize(address _validatorManager) internal onlyInitializing { // initialize owner __Ownable_init(); _setValidatorManager(_validatorManager); } // ============ External Functions ============ /** * @notice Set a new validator manager contract * @dev Mailbox(es) will initially be initialized using a trusted validator manager contract; * we will progressively decentralize by swapping the trusted contract with a new implementation * that implements Validator bonding & slashing, and rules for Validator selection & rotation * @param _validatorManager the new validator manager contract */ function setValidatorManager(address _validatorManager) external onlyOwner { _setValidatorManager(_validatorManager); } // ============ Internal Functions ============ /** * @notice Set the validator manager * @param _validatorManager Address of the validator manager */ function _setValidatorManager(address _validatorManager) internal { require( Address.isContract(_validatorManager), "!contract validatorManager" ); validatorManager = _validatorManager; emit ValidatorManagerSet(_validatorManager); } }