Governance.sol 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. // contracts/Governance.sol
  2. // SPDX-License-Identifier: Apache 2
  3. pragma solidity ^0.8.0;
  4. import "./Structs.sol";
  5. import "./GovernanceStructs.sol";
  6. import "./Messages.sol";
  7. import "./Setters.sol";
  8. import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
  9. abstract contract Governance is GovernanceStructs, Messages, Setters, ERC1967Upgrade {
  10. event ContractUpgraded(address indexed oldContract, address indexed newContract);
  11. event GuardianSetAdded(uint32 indexed index);
  12. // "Core" (left padded)
  13. bytes32 constant module = 0x00000000000000000000000000000000000000000000000000000000436f7265;
  14. function submitContractUpgrade(bytes memory _vm) public {
  15. Structs.VM memory vm = parseVM(_vm);
  16. (bool isValid, string memory reason) = verifyGovernanceVM(vm);
  17. require(isValid, reason);
  18. GovernanceStructs.ContractUpgrade memory upgrade = parseContractUpgrade(vm.payload);
  19. require(upgrade.module == module, "Invalid Module");
  20. require(upgrade.chain == chainId(), "Invalid Chain");
  21. setGovernanceActionConsumed(vm.hash);
  22. upgradeImplementation(upgrade.newContract);
  23. }
  24. function submitSetMessageFee(bytes memory _vm) public {
  25. Structs.VM memory vm = parseVM(_vm);
  26. (bool isValid, string memory reason) = verifyGovernanceVM(vm);
  27. require(isValid, reason);
  28. GovernanceStructs.SetMessageFee memory upgrade = parseSetMessageFee(vm.payload);
  29. require(upgrade.module == module, "Invalid Module");
  30. require(upgrade.chain == chainId(), "Invalid Chain");
  31. setGovernanceActionConsumed(vm.hash);
  32. setMessageFee(upgrade.messageFee);
  33. }
  34. function submitNewGuardianSet(bytes memory _vm) public {
  35. Structs.VM memory vm = parseVM(_vm);
  36. (bool isValid, string memory reason) = verifyGovernanceVM(vm);
  37. require(isValid, reason);
  38. GovernanceStructs.GuardianSetUpgrade memory upgrade = parseGuardianSetUpgrade(vm.payload);
  39. require(upgrade.module == module, "invalid Module");
  40. require(upgrade.chain == chainId() || upgrade.chain == 0, "invalid Chain");
  41. require(upgrade.newGuardianSet.keys.length > 0, "new guardian set is empty");
  42. require(upgrade.newGuardianSetIndex == getCurrentGuardianSetIndex() + 1, "index must increase in steps of 1");
  43. setGovernanceActionConsumed(vm.hash);
  44. expireGuardianSet(getCurrentGuardianSetIndex());
  45. storeGuardianSet(upgrade.newGuardianSet, upgrade.newGuardianSetIndex);
  46. updateGuardianSetIndex(upgrade.newGuardianSetIndex);
  47. }
  48. function submitTransferFees(bytes memory _vm) public {
  49. Structs.VM memory vm = parseVM(_vm);
  50. (bool isValid, string memory reason) = verifyGovernanceVM(vm);
  51. require(isValid, reason);
  52. GovernanceStructs.TransferFees memory transfer = parseTransferFees(vm.payload);
  53. require(transfer.module == module, "invalid Module");
  54. require(transfer.chain == chainId() || transfer.chain == 0, "invalid Chain");
  55. setGovernanceActionConsumed(vm.hash);
  56. address payable recipient = payable(address(uint160(uint256(transfer.recipient))));
  57. recipient.transfer(transfer.amount);
  58. }
  59. function upgradeImplementation(address newImplementation) internal {
  60. address currentImplementation = _getImplementation();
  61. _upgradeTo(newImplementation);
  62. // Call initialize function of the new implementation
  63. (bool success, bytes memory reason) = newImplementation.delegatecall(abi.encodeWithSignature("initialize()"));
  64. require(success, string(reason));
  65. emit ContractUpgraded(currentImplementation, newImplementation);
  66. }
  67. function verifyGovernanceVM(Structs.VM memory vm) internal view returns (bool, string memory){
  68. // validate vm
  69. (bool isValid, string memory reason) = verifyVM(vm);
  70. if (!isValid){
  71. return (false, reason);
  72. }
  73. // only current guardianset can sign governance packets
  74. if (vm.guardianSetIndex != getCurrentGuardianSetIndex()) {
  75. return (false, "not signed by current guardian set");
  76. }
  77. // verify source
  78. if (uint16(vm.emitterChainId) != governanceChainId()) {
  79. return (false, "wrong governance chain");
  80. }
  81. if (vm.emitterAddress != governanceContract()) {
  82. return (false, "wrong governance contract");
  83. }
  84. // prevent re-entry
  85. if (governanceActionIsConsumed(vm.hash)){
  86. return (false, "governance action already consumed");
  87. }
  88. return (true, "");
  89. }
  90. }