1
0
Signed-off-by: AlienTornadosaurusHex <>
This commit is contained in:
AlienTornadosaurusHex 2023-05-22 20:25:59 +00:00
parent 4f141a5bb6
commit 68f5be64e2
3 changed files with 7 additions and 32 deletions

@ -9,8 +9,6 @@ import "../v3-relayer-registry/GovernanceStakingUpgrade.sol";
contract GovernancePatchUpgrade is GovernanceStakingUpgrade { contract GovernancePatchUpgrade is GovernanceStakingUpgrade {
mapping(uint256 => bytes32) public proposalCodehashes; mapping(uint256 => bytes32) public proposalCodehashes;
event CodehashDifferent(address target, bytes32 oldHash, bytes32 newHash);
// The stakingRewardsAddress sets the immutable to the new staking contract // The stakingRewardsAddress sets the immutable to the new staking contract
constructor( constructor(
address stakingRewardsAddress, address stakingRewardsAddress,
@ -32,18 +30,9 @@ contract GovernancePatchUpgrade is GovernanceStakingUpgrade {
proposalCodehash := extcodehash(target) proposalCodehash := extcodehash(target)
} }
if (proposalCodehash == proposalCodehashes[proposalId]) { require(proposalCodehash == proposalCodehashes[proposalId], "Governance::propose: metamorphic contracts not allowed");
super.execute(proposalId);
} else {
// So this should guarantee that the proposal should not be able to be executed in future
// But also, the proposal will be skipped each time. So the question is whether this, a silent
// skip, or a require can be used to stay "concise", and abandon the safety of having also this assign
// Outside dependencies, which don't exist as of yet, might believe that the proposal code was executed
proposal.executed = true;
// Let the event signify it was metamorphic super.execute(proposalId);
emit CodehashDifferent(target, proposalCodehashes[proposalId], proposalCodehash);
}
} }
// This should store the proposal extcodehash // This should store the proposal extcodehash

@ -17,7 +17,8 @@
"test:f": "yarn prettier:fix && yarn test", "test:f": "yarn prettier:fix && yarn test",
"clean": "yarn prettier:fix && yarn lint", "clean": "yarn prettier:fix && yarn lint",
"compile": "yarn prettier:fix && yarn hardhat compile", "compile": "yarn prettier:fix && yarn hardhat compile",
"coverage": "yarn hardhat coverage" "coverage": "yarn hardhat coverage",
"layout": "yarn hardhat check"
}, },
"author": "Tornado.cash team <hello@tornado.cash>", "author": "Tornado.cash team <hello@tornado.cash>",
"license": "MIT", "license": "MIT",

@ -264,25 +264,10 @@ describe('Gov Exploit Patch Upgrade Tests', () => {
// Load the contract // Load the contract
const maliciousProposal = await ethers.getContractAt('MaliciousProposal', maliciousProposalAddress) const maliciousProposal = await ethers.getContractAt('MaliciousProposal', maliciousProposalAddress)
// Check that the malicious proposer is the deployer
const deployer = await maliciousProposal.deployer()
// Get bal before
const deployerBalanceBefore = await torn.balanceOf(deployer)
const governanceBalanceBefore = await torn.balanceOf(governance.address)
expect(governanceBalanceBefore).to.be.gt(zero)
// Now execute // Now execute
await governance.execute(proposalId) await expect(governance.execute(proposalId)).to.be.revertedWith(
'Governance::propose: metamorphic contracts not allowed',
// Check bal after )
const deployerBalanceAfter = await torn.balanceOf(deployer)
const governanceBalanceAfter = await torn.balanceOf(governance.address)
// Protected
expect(deployerBalanceAfter).to.equal(deployerBalanceBefore)
expect(governanceBalanceAfter).to.equal(governanceBalanceBefore)
// Terminate the contract for the next test // Terminate the contract for the next test
await maliciousProposal.emergencyStop() await maliciousProposal.emergencyStop()