diff --git a/src/v4-patch/PatchProposal.sol b/src/v4-patch/PatchProposal.sol index 1c091fa..27661a6 100644 --- a/src/v4-patch/PatchProposal.sol +++ b/src/v4-patch/PatchProposal.sol @@ -3,115 +3,76 @@ pragma solidity ^0.6.12; pragma experimental ABIEncoderV2; -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; +import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + import { LoopbackProxy } from "../v1/LoopbackProxy.sol"; import { AdminUpgradeableProxy } from "./AdminUpgradeableProxy.sol"; -import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import { Address } from "@openzeppelin/contracts/utils/Address.sol"; import { GovernancePatchUpgrade } from "./GovernancePatchUpgrade.sol"; import { TornadoStakingRewards } from "./TornadoStakingRewards.sol"; import { RelayerRegistry } from "./RelayerRegistry.sol"; /** - * @notice Contract which should help the proposal deploy the necessary contracts. - */ -contract PatchProposalContractsFactory { - /** - * @notice Create a new TornadoStakingRewards contract. - * @param governance The address of Tornado Cash Goveranance. - * @param torn The torn token address. - * @param registry The address of the relayer registry. - * @return The address of the new staking contract. - */ - function createStakingRewards(address governance, address torn, address registry) - external - returns (address) - { - return address(new TornadoStakingRewards(governance, torn, registry)); - } - - /** - * @notice Create a new RelayerRegistry contract. - * @param torn The torn token address. - * @param governance The address of Tornado Cash Goveranance. - * @param ens The ens registrar address. - * @param staking The TornadoStakingRewards contract address. - * @return The address of the new registry contract. - */ - function createRegistryContract( - address torn, - address governance, - address ens, - address staking, - address feeManager - ) external returns (address) { - return address(new RelayerRegistry(torn, governance, ens, staking, feeManager)); - } -} - -/** - * @notice Proposal which should patch governance against the metamorphic contract replacement vulnerability. + * @notice Proposal which should patch governance against the metamorphic contract replacement vulnerability and also fix several issues which have appeared as a result of the attack. */ contract PatchProposal { - using SafeMath for uint256; - using Address for address; + // Address of the old staking proxy + address public constant oldStakingProxyAddress = 0x2FC93484614a34f26F7970CBB94615bA109BB4bf; - address public immutable feeManagerProxyAddress = 0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7; - address public immutable registryProxyAddress = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2; - address public immutable ensAddress = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e; + // 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 + address public constant userVaultAddress = 0x2F50508a8a3D323B91336FA3eA6ae50E55f32185; + + // Address of the governance proxy + address payable public constant governanceProxyAddress = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce; + + // Torn token IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C); - PatchProposalContractsFactory public immutable patchProposalContractsFactory; + // The staking proxy (pointing to a new implementation (with same code)) that we've deployed + address public immutable deployedStakingProxyContractAddress; - constructor(address _patchProposalContractsFactory) public { - patchProposalContractsFactory = PatchProposalContractsFactory(_patchProposalContractsFactory); + // The registry implementation (with same code) that we've deployed + address public immutable deployedRelayerRegistryImplementationAddress; + + constructor( + address _deployedStakingProxyContractAddress, + address _deployedRelayerRegistryImplementationAddress + ) public { + deployedStakingProxyContractAddress = _deployedStakingProxyContractAddress; + deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress; } /// @notice Function to execute the proposal. function executeProposal() external { - // address(this) has to be governance - address payable governance = payable(address(this)); - - // Get the two contracts gov depends on - address gasComp = address(GovernancePatchUpgrade(governance).gasCompensationVault()); - address vault = address(GovernancePatchUpgrade(governance).userVault()); - // Get the old staking contract - TornadoStakingRewards oldStaking = - TornadoStakingRewards(address(GovernancePatchUpgrade(governance).Staking())); + TornadoStakingRewards oldStaking = TornadoStakingRewards(oldStakingProxyAddress); // Get the small amount of TORN left oldStaking.withdrawTorn(TORN.balanceOf(address(oldStaking))); - // And create a new staking logic contract - TornadoStakingRewards newStakingImplementation = TornadoStakingRewards( - patchProposalContractsFactory.createStakingRewards( - address(governance), address(TORN), registryProxyAddress + // Upgrade the registry proxy + AdminUpgradeableProxy(payable(registryProxyAddress)).upgradeTo( + deployedRelayerRegistryImplementationAddress + ); + + // Now upgrade the governance implementation to the vulnerability resistant one + LoopbackProxy(governanceProxyAddress).upgradeTo( + address( + new GovernancePatchUpgrade( + deployedStakingProxyContractAddress, + gasCompensationVaultAddress, + userVaultAddress + ) ) ); - // Create new staking proxy contract (without initialization value) - bytes memory empty; - - address newStaking = - address(new AdminUpgradeableProxy(address(newStakingImplementation), address(governance), empty)); - - // And a new registry implementation - address newRegistryImplementationAddress = patchProposalContractsFactory.createRegistryContract( - address(TORN), address(governance), ensAddress, newStaking, feeManagerProxyAddress - ); - - // Upgrade the registry proxy - AdminUpgradeableProxy(payable(registryProxyAddress)).upgradeTo(newRegistryImplementationAddress); - - // Now upgrade the governance to the latest stuff - LoopbackProxy(payable(governance)).upgradeTo( - address(new GovernancePatchUpgrade(newStaking, gasComp, vault)) - ); - - // Compensate TORN for staking - TORN.transfer(newStaking, 94_092 ether); + // Transfer TORN in compensation to the staking proxy + TORN.transfer(deployedStakingProxyContractAddress, 94_092 ether); } }