// SPDX-License-Identifier: MIT pragma solidity ^0.6.12; pragma experimental ABIEncoderV2; import { LoopbackProxy } from "../v1/LoopbackProxy.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { GovernancePatchUpgrade } from "./GovernancePatchUpgrade.sol"; import { TornadoStakingRewards } from "./TornadoStakingRewards.sol"; import { RelayerRegistry } from "./RelayerRegistry.sol"; interface Proxy { function upgradeTo(address newImplementation) external; } /** * @notice Proposal which should patch governance against the metamorphic contract replacement vulnerability. */ contract PatchProposal { // Address of the staking proxy address public constant stakingProxyAddress = 0x2FC93484614a34f26F7970CBB94615bA109BB4bf; // Address of the registry proxy address public constant registryProxyAddress = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2; // Address of the gas compensation vault address public constant gasCompensationVaultAddress = 0xFA4C1f3f7D5dd7c12a9Adb82Cd7dDA542E3d59ef; // Address of the user vault (not replaced) address public constant userVaultAddress = 0x2F50508a8a3D323B91336FA3eA6ae50E55f32185; // Address of the governance proxy address payable public constant governanceProxyAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce; // Torn token IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C); // These are the contracts we deployed address public immutable deployedStakingContractAddress; address public immutable deployedRelayerRegistryImplementationAddress; constructor(address _deployedStakingContractAddress, address _deployedRelayerRegistryImplementationAddress) public { deployedStakingContractAddress = _deployedStakingContractAddress; deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress; } /// @notice Function to execute the proposal. function executeProposal() external { // Get the old staking contract TornadoStakingRewards oldStaking = TornadoStakingRewards(stakingProxyAddress); // Get the small amount of TORN left oldStaking.withdrawTorn(TORN.balanceOf(address(oldStaking))); // And create a new staking contract TornadoStakingRewards newStaking = TornadoStakingRewards(deployedStakingContractAddress); // Upgrade the registry proxy Proxy(registryProxyAddress).upgradeTo(deployedRelayerRegistryImplementationAddress); // Now upgrade the governance to the latest stuff LoopbackProxy(governanceProxyAddress).upgradeTo( address(new GovernancePatchUpgrade(address(newStaking), gasCompensationVaultAddress, userVaultAddress)) ); } }