The home for Hyperlane core contracts, sdk packages, and other infrastructure
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hyperlane-monorepo/solidity/contracts/isms/multisig/StorageMultisigIsm.sol

144 lines
4.2 KiB

// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity >=0.8.0;
// ============ Internal Imports ============
import {AbstractMultisigIsm} from "./AbstractMultisigIsm.sol";
import {AbstractMerkleRootMultisigIsm} from "./AbstractMerkleRootMultisigIsm.sol";
import {AbstractMessageIdMultisigIsm} from "./AbstractMessageIdMultisigIsm.sol";
import {IInterchainSecurityModule} from "../../interfaces/IInterchainSecurityModule.sol";
import {IThresholdAddressFactory} from "../../interfaces/IThresholdAddressFactory.sol";
import {MinimalProxy} from "../../libs/MinimalProxy.sol";
import {PackageVersioned} from "../../PackageVersioned.sol";
// ============ External Imports ============
import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
abstract contract AbstractStorageMultisigIsm is
AbstractMultisigIsm,
Ownable2StepUpgradeable
{
address[] public validators;
uint8 public threshold;
event ValidatorsAndThresholdSet(address[] validators, uint8 threshold);
constructor(
address[] memory _validators,
uint8 _threshold
) Ownable2StepUpgradeable() {
validators = _validators;
threshold = _threshold;
_disableInitializers();
}
function initialize(
address _owner,
address[] memory _validators,
uint8 _threshold
) external initializer {
__Ownable2Step_init();
setValidatorsAndThreshold(_validators, _threshold);
_transferOwnership(_owner);
}
function setValidatorsAndThreshold(
address[] memory _validators,
uint8 _threshold
) public onlyOwner {
require(
0 < _threshold && _threshold <= _validators.length,
"Invalid threshold"
);
validators = _validators;
threshold = _threshold;
emit ValidatorsAndThresholdSet(_validators, _threshold);
}
function validatorsAndThreshold(
bytes calldata /* _message */
) public view override returns (address[] memory, uint8) {
return (validators, threshold);
}
}
contract StorageMerkleRootMultisigIsm is
AbstractMerkleRootMultisigIsm,
AbstractStorageMultisigIsm
{
uint8 public constant moduleType =
uint8(IInterchainSecurityModule.Types.MERKLE_ROOT_MULTISIG);
constructor(
address[] memory _validators,
uint8 _threshold
) AbstractStorageMultisigIsm(_validators, _threshold) {}
}
contract StorageMessageIdMultisigIsm is
AbstractMessageIdMultisigIsm,
AbstractStorageMultisigIsm
{
uint8 public constant moduleType =
uint8(IInterchainSecurityModule.Types.MESSAGE_ID_MULTISIG);
constructor(
address[] memory _validators,
uint8 _threshold
) AbstractStorageMultisigIsm(_validators, _threshold) {}
}
abstract contract StorageMultisigIsmFactory is
IThresholdAddressFactory,
PackageVersioned
{
/**
* @notice Emitted when a multisig module is deployed
* @param module The deployed ISM
*/
event ModuleDeployed(address module);
// ============ External Functions ============
function deploy(
address[] calldata _validators,
uint8 _threshold
) external returns (address ism) {
ism = MinimalProxy.create(implementation());
emit ModuleDeployed(ism);
AbstractStorageMultisigIsm(ism).initialize(
msg.sender,
_validators,
_threshold
);
}
function implementation() public view virtual returns (address);
}
contract StorageMerkleRootMultisigIsmFactory is StorageMultisigIsmFactory {
address internal immutable _implementation;
constructor() {
_implementation = address(
new StorageMerkleRootMultisigIsm(new address[](0), 0)
);
}
function implementation() public view override returns (address) {
return _implementation;
}
}
contract StorageMessageIdMultisigIsmFactory is StorageMultisigIsmFactory {
address internal immutable _implementation;
constructor() {
_implementation = address(
new StorageMessageIdMultisigIsm(new address[](0), 0)
);
}
function implementation() public view override returns (address) {
return _implementation;
}
}