Change proposal: now creating with predeployed staking proxy and relayer registry implementation

This commit is contained in:
Theo 2023-05-28 11:14:51 +03:00
parent 195840d678
commit 2031afdbe8

@ -3,115 +3,76 @@
pragma solidity ^0.6.12; pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2; 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 { LoopbackProxy } from "../v1/LoopbackProxy.sol";
import { AdminUpgradeableProxy } from "./AdminUpgradeableProxy.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 { GovernancePatchUpgrade } from "./GovernancePatchUpgrade.sol";
import { TornadoStakingRewards } from "./TornadoStakingRewards.sol"; import { TornadoStakingRewards } from "./TornadoStakingRewards.sol";
import { RelayerRegistry } from "./RelayerRegistry.sol"; import { RelayerRegistry } from "./RelayerRegistry.sol";
/** /**
* @notice Contract which should help the proposal deploy the necessary contracts. * @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 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.
*/ */
contract PatchProposal { contract PatchProposal {
using SafeMath for uint256; // Address of the old staking proxy
using Address for address; address public constant oldStakingProxyAddress = 0x2FC93484614a34f26F7970CBB94615bA109BB4bf;
address public immutable feeManagerProxyAddress = 0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7; // Address of the registry proxy
address public immutable registryProxyAddress = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2; address public constant registryProxyAddress = 0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2;
address public immutable ensAddress = 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e;
// 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); 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 { // The registry implementation (with same code) that we've deployed
patchProposalContractsFactory = PatchProposalContractsFactory(_patchProposalContractsFactory); address public immutable deployedRelayerRegistryImplementationAddress;
constructor(
address _deployedStakingProxyContractAddress,
address _deployedRelayerRegistryImplementationAddress
) public {
deployedStakingProxyContractAddress = _deployedStakingProxyContractAddress;
deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress;
} }
/// @notice Function to execute the proposal. /// @notice Function to execute the proposal.
function executeProposal() external { 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 // Get the old staking contract
TornadoStakingRewards oldStaking = TornadoStakingRewards oldStaking = TornadoStakingRewards(oldStakingProxyAddress);
TornadoStakingRewards(address(GovernancePatchUpgrade(governance).Staking()));
// Get the small amount of TORN left // Get the small amount of TORN left
oldStaking.withdrawTorn(TORN.balanceOf(address(oldStaking))); oldStaking.withdrawTorn(TORN.balanceOf(address(oldStaking)));
// And create a new staking logic contract // Upgrade the registry proxy
TornadoStakingRewards newStakingImplementation = TornadoStakingRewards( AdminUpgradeableProxy(payable(registryProxyAddress)).upgradeTo(
patchProposalContractsFactory.createStakingRewards( deployedRelayerRegistryImplementationAddress
address(governance), address(TORN), registryProxyAddress );
// 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) // Transfer TORN in compensation to the staking proxy
bytes memory empty; TORN.transfer(deployedStakingProxyContractAddress, 94_092 ether);
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);
} }
} }