| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- // contracts/Governance.sol
- // SPDX-License-Identifier: Apache 2
- pragma solidity ^0.8.0;
- import "./Structs.sol";
- import "./GovernanceStructs.sol";
- import "./Messages.sol";
- import "./Setters.sol";
- import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
- abstract contract Governance is
- GovernanceStructs,
- Messages,
- Setters,
- ERC1967Upgrade
- {
- event ContractUpgraded(
- address indexed oldContract,
- address indexed newContract
- );
- event GuardianSetAdded(uint32 indexed index);
- // "Core" (left padded)
- bytes32 constant module =
- 0x00000000000000000000000000000000000000000000000000000000436f7265;
- function submitContractUpgrade(bytes memory _vm) public {
- Structs.VM memory vm = parseVM(_vm);
- (bool isValid, string memory reason) = verifyGovernanceVM(vm);
- require(isValid, reason);
- GovernanceStructs.ContractUpgrade memory upgrade = parseContractUpgrade(
- vm.payload
- );
- require(upgrade.module == module, "Invalid Module");
- require(upgrade.chain == chainId(), "Invalid Chain");
- setGovernanceActionConsumed(vm.hash);
- upgradeImplementation(upgrade.newContract);
- }
- function submitSetMessageFee(bytes memory _vm) public {
- Structs.VM memory vm = parseVM(_vm);
- (bool isValid, string memory reason) = verifyGovernanceVM(vm);
- require(isValid, reason);
- GovernanceStructs.SetMessageFee memory upgrade = parseSetMessageFee(
- vm.payload
- );
- require(upgrade.module == module, "Invalid Module");
- require(upgrade.chain == chainId(), "Invalid Chain");
- setGovernanceActionConsumed(vm.hash);
- setMessageFee(upgrade.messageFee);
- }
- function submitNewGuardianSet(bytes memory _vm) public {
- Structs.VM memory vm = parseVM(_vm);
- (bool isValid, string memory reason) = verifyGovernanceVM(vm);
- require(isValid, reason);
- GovernanceStructs.GuardianSetUpgrade
- memory upgrade = parseGuardianSetUpgrade(vm.payload);
- require(upgrade.module == module, "invalid Module");
- require(
- upgrade.chain == chainId() || upgrade.chain == 0,
- "invalid Chain"
- );
- require(
- upgrade.newGuardianSet.keys.length > 0,
- "new guardian set is empty"
- );
- require(
- upgrade.newGuardianSetIndex == getCurrentGuardianSetIndex() + 1,
- "index must increase in steps of 1"
- );
- setGovernanceActionConsumed(vm.hash);
- expireGuardianSet(getCurrentGuardianSetIndex());
- storeGuardianSet(upgrade.newGuardianSet, upgrade.newGuardianSetIndex);
- updateGuardianSetIndex(upgrade.newGuardianSetIndex);
- }
- function submitTransferFees(bytes memory _vm) public {
- Structs.VM memory vm = parseVM(_vm);
- (bool isValid, string memory reason) = verifyGovernanceVM(vm);
- require(isValid, reason);
- GovernanceStructs.TransferFees memory transfer = parseTransferFees(
- vm.payload
- );
- require(transfer.module == module, "invalid Module");
- require(
- transfer.chain == chainId() || transfer.chain == 0,
- "invalid Chain"
- );
- setGovernanceActionConsumed(vm.hash);
- address payable recipient = payable(
- address(uint160(uint256(transfer.recipient)))
- );
- recipient.transfer(transfer.amount);
- }
- function upgradeImplementation(address newImplementation) internal {
- address currentImplementation = _getImplementation();
- _upgradeTo(newImplementation);
- // Call initialize function of the new implementation
- (bool success, bytes memory reason) = newImplementation.delegatecall(
- abi.encodeWithSignature("initialize()")
- );
- require(success, string(reason));
- emit ContractUpgraded(currentImplementation, newImplementation);
- }
- function verifyGovernanceVM(
- Structs.VM memory vm
- ) internal view returns (bool, string memory) {
- // validate vm
- (bool isValid, string memory reason) = verifyVM(vm);
- if (!isValid) {
- return (false, reason);
- }
- // only current guardianset can sign governance packets
- if (vm.guardianSetIndex != getCurrentGuardianSetIndex()) {
- return (false, "not signed by current guardian set");
- }
- // verify source
- if (uint16(vm.emitterChainId) != governanceChainId()) {
- return (false, "wrong governance chain");
- }
- if (vm.emitterAddress != governanceContract()) {
- return (false, "wrong governance contract");
- }
- // prevent re-entry
- if (governanceActionIsConsumed(vm.hash)) {
- return (false, "governance action already consumed");
- }
- return (true, "");
- }
- }
|