// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; pragma experimental ABIEncoderV2; import "../v1/Governance.sol"; import "../v3-relayer-registry/GovernanceStakingUpgrade.sol"; contract GovernancePatchUpgrade is GovernanceStakingUpgrade { mapping(uint256 => bytes32) public proposalCodehashes; // The stakingRewardsAddress sets the immutable to the new staking contract constructor( address stakingRewardsAddress, address gasCompLogic, address userVaultAddress ) public GovernanceStakingUpgrade(stakingRewardsAddress, gasCompLogic, userVaultAddress) {} // This should guarantee that the proposal extcodehashes are good function execute(uint256 proposalId) public payable virtual override(Governance) { require(msg.sender != address(this), "pseudo-external function"); Proposal storage proposal = proposals[proposalId]; address target = proposal.target; bytes32 proposalCodehash; assembly { proposalCodehash := extcodehash(target) } require(proposalCodehash == proposalCodehashes[proposalId], "Governance::propose: metamorphic contracts not allowed"); super.execute(proposalId); } // This should store the proposal extcodehash function _propose( address proposer, address target, string memory description ) internal virtual override(Governance) returns (uint256 proposalId) { // Implies all former predicates were valid proposalId = super._propose(proposer, target, description); bytes32 proposalCodehash; assembly { proposalCodehash := extcodehash(target) } proposalCodehashes[proposalId] = proposalCodehash; } }