| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- // contracts/Governance.sol
- // SPDX-License-Identifier: Apache 2
- pragma solidity ^0.8.0;
- import "./PythGovernanceInstructions.sol";
- import "./PythInternalStructs.sol";
- import "./PythGetters.sol";
- import "./PythSetters.sol";
- import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol";
- /**
- * @dev `Governance` defines a means to enacting changes to the Pyth contract.
- */
- abstract contract PythGovernance is PythGetters, PythSetters, PythGovernanceInstructions {
- event ContractUpgraded(address oldImplementation, address newImplementation);
- event GovernanceDataSourceSet(PythInternalStructs.DataSource oldDataSource, PythInternalStructs.DataSource newDataSource,
- uint64 initialSequence);
- event DataSourcesSet(PythInternalStructs.DataSource[] oldDataSources, PythInternalStructs.DataSource[] newDataSources);
- event FeeSet(uint oldFee, uint newFee);
- event ValidPeriodSet(uint oldValidPeriod, uint newValidPeriod);
- function verifyGovernanceVM(bytes memory encodedVM) internal returns (IWormhole.VM memory parsedVM){
- (IWormhole.VM memory vm, bool valid, string memory reason) = wormhole().parseAndVerifyVM(encodedVM);
- require(valid, reason);
- require(isValidGovernanceDataSource(vm.emitterChainId, vm.emitterAddress), "VAA is not coming from the governance data source");
- require(vm.sequence > lastExecutedGovernanceSequence(), "VAA is older than the last executed governance VAA");
- setLastExecutedGovernanceSequence(vm.sequence);
- return vm;
- }
- function executeGovernanceInstruction(bytes calldata encodedVM) public {
- IWormhole.VM memory vm = verifyGovernanceVM(encodedVM);
- GovernanceInstruction memory gi = parseGovernanceInstruction(vm.payload);
- require(gi.targetChainId == chainId() || gi.targetChainId == 0, "invalid target chain for this governance instruction");
- if (gi.action == GovernanceAction.UpgradeContract) {
- require(gi.targetChainId != 0, "upgrade with chain id 0 is not possible");
- upgradeContract(gi.payload);
- } else if (gi.action == GovernanceAction.SetGovernanceDataSource) {
- setGovernanceDataSource(gi.payload);
- } else if (gi.action == GovernanceAction.SetDataSources) {
- setDataSources(gi.payload);
- } else if (gi.action == GovernanceAction.SetFee) {
- setFee(gi.payload);
- } else if (gi.action == GovernanceAction.SetValidPeriod) {
- setValidPeriod(gi.payload);
- } else {
- revert("invalid governance action");
- }
- }
- function upgradeContract(bytes memory encodedPayload) internal {
- UpgradeContractPayload memory payload = parseUpgradeContractPayload(encodedPayload);
- // This contract does not have enough access to execute this, it should be executed on the
- // upgradable
- upgradeUpgradableContract(payload);
- }
- function upgradeUpgradableContract(UpgradeContractPayload memory payload) virtual internal;
- function setGovernanceDataSource(bytes memory encodedPayload) internal {
- SetGovernanceDataSourcePayload memory payload = parseSetGovernanceDataSourcePayload(encodedPayload);
- PythInternalStructs.DataSource memory oldGovernanceDatSource = governanceDataSource();
- setGovernanceDataSource(payload.newGovernanceDataSource);
- setLastExecutedGovernanceSequence(payload.initialSequence);
- emit GovernanceDataSourceSet(oldGovernanceDatSource, governanceDataSource(), lastExecutedGovernanceSequence());
- }
- function setDataSources(bytes memory encodedPayload) internal {
- SetDataSourcesPayload memory payload = parseSetDataSourcesPayload(encodedPayload);
- PythInternalStructs.DataSource[] memory oldDataSources = validDataSources();
- for (uint i = 0; i < oldDataSources.length; i += 1) {
- _state.isValidDataSource[hashDataSource(oldDataSources[i])] = false;
- }
- delete _state.validDataSources;
- for (uint i = 0; i < payload.dataSources.length; i++) {
- _state.validDataSources.push(payload.dataSources[i]);
- _state.isValidDataSource[hashDataSource(payload.dataSources[i])] = true;
- }
- emit DataSourcesSet(oldDataSources, validDataSources());
- }
- function setFee(bytes memory encodedPayload) internal {
- SetFeePayload memory payload = parseSetFeePayload(encodedPayload);
- uint oldFee = singleUpdateFeeInWei();
- setSingleUpdateFeeInWei(payload.newFee);
- emit FeeSet(oldFee, singleUpdateFeeInWei());
- }
- function setValidPeriod(bytes memory encodedPayload) internal {
- SetValidPeriodPayload memory payload = parseSetValidPeriodPayload(encodedPayload);
- uint oldValidPeriod = validTimePeriodSeconds();
- setValidTimePeriodSeconds(payload.newValidPeriod);
- emit ValidPeriodSet(oldValidPeriod, validTimePeriodSeconds());
- }
- }
|