diff --git a/solidity/core/contracts/Common.sol b/solidity/core/contracts/Common.sol index fcc4401a5..e5694d8b0 100644 --- a/solidity/core/contracts/Common.sol +++ b/solidity/core/contracts/Common.sol @@ -2,7 +2,6 @@ pragma solidity >=0.6.11; // ============ Internal Imports ============ -import {IValidatorManager} from "../interfaces/IValidatorManager.sol"; import {ICommon} from "../interfaces/ICommon.sol"; // ============ External Imports ============ import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; @@ -26,7 +25,7 @@ abstract contract Common is ICommon, OwnableUpgradeable { // The latest checkpointed root bytes32 public checkpointedRoot; // Address of ValidatorManager contract. - IValidatorManager public validatorManager; + address public validatorManager; // ============ Upgrade Gap ============ @@ -55,7 +54,7 @@ abstract contract Common is ICommon, OwnableUpgradeable { * @notice Ensures that function is called by the ValidatorManager contract */ modifier onlyValidatorManager() { - require(msg.sender == address(validatorManager), "!validatorManager"); + require(msg.sender == validatorManager, "!validatorManager"); _; } @@ -73,7 +72,7 @@ abstract contract Common is ICommon, OwnableUpgradeable { { // initialize owner __Ownable_init(); - _setValidatorManager(IValidatorManager(_validatorManager)); + _setValidatorManager(_validatorManager); } // ============ External Functions ============ @@ -86,7 +85,7 @@ abstract contract Common is ICommon, OwnableUpgradeable { * @param _validatorManager the new ValidatorManager contract */ function setValidatorManager(address _validatorManager) external onlyOwner { - _setValidatorManager(IValidatorManager(_validatorManager)); + _setValidatorManager(_validatorManager); } /** @@ -110,15 +109,13 @@ abstract contract Common is ICommon, OwnableUpgradeable { * @notice Set the ValidatorManager * @param _validatorManager Address of the ValidatorManager */ - function _setValidatorManager(IValidatorManager _validatorManager) - internal - { + function _setValidatorManager(address _validatorManager) internal { require( - Address.isContract(address(_validatorManager)), + Address.isContract(_validatorManager), "!contract validatorManager" ); validatorManager = _validatorManager; - emit NewValidatorManager(address(_validatorManager)); + emit NewValidatorManager(_validatorManager); } /** diff --git a/solidity/core/contracts/ValidatorManager.sol b/solidity/core/contracts/ValidatorManager.sol deleted file mode 100644 index c251b830f..000000000 --- a/solidity/core/contracts/ValidatorManager.sol +++ /dev/null @@ -1,131 +0,0 @@ -// SPDX-License-Identifier: MIT OR Apache-2.0 -pragma solidity >=0.6.11; - -// ============ Internal Imports ============ -import {IValidatorManager} from "../interfaces/IValidatorManager.sol"; -import {Outbox} from "./Outbox.sol"; -// ============ External Imports ============ -import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; -import {ECDSA} from "@openzeppelin/contracts/cryptography/ECDSA.sol"; - -/** - * @title ValidatorManager - * @author Celo Labs Inc. - * @notice MVP version of contract that will manage Validator selection and - * rotataion. - */ -contract ValidatorManager is IValidatorManager, Ownable { - // Mapping of domain -> validator address. - mapping(uint32 => address) public validators; - - // ============ Events ============ - - /** - * @notice Emitted when a validator is enrolled - * @param domain The domain for which the validator is being enrolled - * @param validator The address of the validator - */ - event ValidatorEnrolled(uint32 indexed domain, address indexed validator); - - /** - * @notice Emitted when proof of an improper checkpoint is submitted, - * which sets the contract to FAILED state - * @param root Root of the improper checkpoint - * @param index Index of the improper checkpoint - * @param signature Signature on `root` and `index` - */ - event ImproperCheckpoint( - address indexed outbox, - uint32 indexed domain, - address indexed validator, - bytes32 root, - uint256 index, - bytes signature - ); - - // ============ Constructor ============ - - constructor() Ownable() {} - - // ============ External Functions ============ - - /** - * @notice Enroll a validator for the given domain - * @dev only callable by trusted owner - * @param _domain The domain for which the validator is being set - * @param _validator The address of the validator - */ - function enrollValidator(uint32 _domain, address _validator) - external - onlyOwner - { - validators[_domain] = _validator; - emit ValidatorEnrolled(_domain, _validator); - } - - /** - * @notice Check if an Checkpoint is an Improper Checkpoint; - * if so, set the provided Outbox contract to FAILED state. - * - * An Improper Checkpoint is an checkpoint that was not previously checkpointed. - * @param _outbox Address of the Outbox contract to set to FAILED. - * @param _root Merkle root of the improper checkpoint - * @param _index Index root of the improper checkpoint - * @param _signature Validator signature on `_root` and `_index` - * @return TRUE if checkpoint was an Improper Checkpoint (implying Validator was slashed) - */ - function improperCheckpoint( - address _outbox, - bytes32 _root, - uint256 _index, - bytes calldata _signature - ) external returns (bool) { - uint32 _domain = Outbox(_outbox).localDomain(); - require( - isValidatorSignature(_domain, _root, _index, _signature), - "!validator sig" - ); - require(Outbox(_outbox).checkpoints(_root) != _index, "!improper"); - Outbox(_outbox).fail(); - emit ImproperCheckpoint( - _outbox, - _domain, - validators[_domain], - _root, - _index, - _signature - ); - return true; - } - - // ============ Public Functions ============ - - /** - * @notice Checks that signature was signed by Validator - * @param _domain Domain of Outbox contract - * @param _root Merkle root - * @param _index Corresponding leaf index - * @param _signature Signature on `_root` and `_index` - * @return TRUE iff signature is valid signed by validator - **/ - function isValidatorSignature( - uint32 _domain, - bytes32 _root, - uint256 _index, - bytes calldata _signature - ) public view override returns (bool) { - bytes32 _digest = keccak256( - abi.encodePacked(domainHash(_domain), _root, _index) - ); - _digest = ECDSA.toEthSignedMessageHash(_digest); - return (ECDSA.recover(_digest, _signature) == validators[_domain]); - } - - /** - * @notice Hash of domain concatenated with "ABACUS" - * @param _domain the domain to hash - */ - function domainHash(uint32 _domain) public pure returns (bytes32) { - return keccak256(abi.encodePacked(_domain, "ABACUS")); - } -} diff --git a/solidity/core/contracts/test/TestOutbox.sol b/solidity/core/contracts/test/TestOutbox.sol index c811dd7fd..298605a95 100644 --- a/solidity/core/contracts/test/TestOutbox.sol +++ b/solidity/core/contracts/test/TestOutbox.sol @@ -3,7 +3,6 @@ pragma solidity >=0.6.11; // ============ Internal Imports ============ import "../Outbox.sol"; -import {IValidatorManager} from "../../interfaces/IValidatorManager.sol"; contract TestOutbox is Outbox { constructor(uint32 _localDomain) Outbox(_localDomain) {} // solhint-disable-line no-empty-blocks @@ -21,6 +20,6 @@ contract TestOutbox is Outbox { * @param _validatorManager Address of the ValidatorManager */ function testSetValidatorManager(address _validatorManager) external { - validatorManager = IValidatorManager(_validatorManager); + validatorManager = _validatorManager; } }