1
0

staking address must be behind proxy

Signed-off-by: AlienTornadosaurusHex <>
This commit is contained in:
AlienTornadosaurusHex 2023-05-27 15:01:23 +00:00
parent d8eee5b2b0
commit 2b49a83883
7 changed files with 64 additions and 36 deletions

@ -5,4 +5,4 @@ LATEST_BLOCK=false
# For deploying the proposal # For deploying the proposal
REGISTRY_IMPL_ADDRESS= REGISTRY_IMPL_ADDRESS=
STAKING_ADDRESS= STAKING_PROXY_ADDRESS=

@ -4,7 +4,6 @@ module.exports = {
tornWhale: '0xF977814e90dA44bFA03b6295A0616a897441aceC', tornWhale: '0xF977814e90dA44bFA03b6295A0616a897441aceC',
ens: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', ens: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
feeManager: '0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7', feeManager: '0x5f6c97C6AD7bdd0AE7E0Dd4ca33A4ED3fDabD4D7',
staking: '0x2FC93484614a34f26F7970CBB94615bA109BB4bf',
registry: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2', registry: '0x58E8dCC13BE9780fC42E8723D8EaD4CF46943dF2',
compensations: '0xFA4C1f3f7D5dd7c12a9Adb82Cd7dDA542E3d59ef', compensations: '0xFA4C1f3f7D5dd7c12a9Adb82Cd7dDA542E3d59ef',
vault: '0x2F50508a8a3D323B91336FA3eA6ae50E55f32185', vault: '0x2F50508a8a3D323B91336FA3eA6ae50E55f32185',

@ -12,10 +12,6 @@ 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";
interface Proxy {
function upgradeTo(address newImplementation) external;
}
/** /**
* @notice Proposal which should patch governance against the metamorphic contract replacement vulnerability. * @notice Proposal which should patch governance against the metamorphic contract replacement vulnerability.
*/ */
@ -39,13 +35,14 @@ contract PatchProposal {
IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C); IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C);
// These are the contracts we deployed // These are the contracts we deployed
address public immutable deployedStakingContractAddress; address public immutable deployedStakingProxyContractAddress;
address public immutable deployedRelayerRegistryImplementationAddress; address public immutable deployedRelayerRegistryImplementationAddress;
constructor(address _deployedStakingContractAddress, address _deployedRelayerRegistryImplementationAddress) constructor(
public address _deployedStakingProxyContractAddress,
{ address _deployedRelayerRegistryImplementationAddress
deployedStakingContractAddress = _deployedStakingContractAddress; ) public {
deployedStakingProxyContractAddress = _deployedStakingProxyContractAddress;
deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress; deployedRelayerRegistryImplementationAddress = _deployedRelayerRegistryImplementationAddress;
} }
@ -57,23 +54,23 @@ contract PatchProposal {
// 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)));
// Just to make compiler stfu
bytes memory bempty;
// And create a new staking contract proxy
TornadoStakingRewards newStaking = TornadoStakingRewards(
address(new AdminUpgradeableProxy(deployedStakingContractAddress, governanceProxyAddress, bempty))
);
// Upgrade the registry proxy // Upgrade the registry proxy
Proxy(registryProxyAddress).upgradeTo(deployedRelayerRegistryImplementationAddress); AdminUpgradeableProxy(payable(registryProxyAddress)).upgradeTo(
deployedRelayerRegistryImplementationAddress
);
// Now upgrade the governance to the latest stuff // Now upgrade the governance to the latest stuff
LoopbackProxy(governanceProxyAddress).upgradeTo( LoopbackProxy(governanceProxyAddress).upgradeTo(
address(new GovernancePatchUpgrade(address(newStaking), gasCompensationVaultAddress, userVaultAddress)) address(
new GovernancePatchUpgrade(
deployedStakingProxyContractAddress,
gasCompensationVaultAddress,
userVaultAddress
)
)
); );
// Transfer TORN in compensation to the staking proxy // Transfer TORN in compensation to the staking proxy
TORN.transfer(address(newStaking), 94_092 ether); TORN.transfer(deployedStakingProxyContractAddress, 94_092 ether);
} }
} }

@ -39,11 +39,11 @@ const promptMessageBase = (middle) => `\n${middle}\n\nAre you sure you would lik
async function deploy() { async function deploy() {
const signer = await ethers.getSigner() const signer = await ethers.getSigner()
if (process.env.STAKING_ADDRESS === undefined) throw Error('Missing STAKING_ADDRESS.') if (process.env.STAKING_PROXY_ADDRESS === undefined) throw Error('Missing STAKING_PROXY_ADDRESS.')
if (process.env.REGISTRY_IMPL_ADDRESS === undefined) throw Error('Missing REGISTRY_IMPL_ADDRESS.') if (process.env.REGISTRY_IMPL_ADDRESS === undefined) throw Error('Missing REGISTRY_IMPL_ADDRESS.')
const stakingAddress = `${process.env.STAKING_ADDRESS}` const stakingProxyAddress = `${process.env.STAKING_PROXY_ADDRESS}`
const registryImplementationAddress = `${process.env.REGISTRY_IMPL_ADDRESS}` const registryImplementationAddress = `${process.env.REGISTRY_IMPL_ADDRESS}`
@ -52,7 +52,7 @@ async function deploy() {
let patchProposal let patchProposal
if (await prompt(promptMessageBase('Continuing to PatchProposal deployment.'))) { if (await prompt(promptMessageBase('Continuing to PatchProposal deployment.'))) {
patchProposal = await patchProposalDeployer.deploy(stakingAddress, registryImplementationAddress) patchProposal = await patchProposalDeployer.deploy(stakingProxyAddress, registryImplementationAddress)
console.log(deployedMessage('PatchProposal', 1, patchProposal.address)) console.log(deployedMessage('PatchProposal', 1, patchProposal.address))
} else { } else {
return '\nDecided to stop at PatchProposal deployment.\n' return '\nDecided to stop at PatchProposal deployment.\n'
@ -61,7 +61,7 @@ async function deploy() {
if (await prompt(promptMessageBase('Continuing to contract verification.'))) { if (await prompt(promptMessageBase('Continuing to contract verification.'))) {
await hre.run('verify:verify', { await hre.run('verify:verify', {
address: patchProposal.address, address: patchProposal.address,
constructorArguments: [stakingAddress, registryImplementationAddress], constructorArguments: [stakingProxyAddress, registryImplementationAddress],
}) })
console.log(verifiedMessage('PatchProposal')) console.log(verifiedMessage('PatchProposal'))

@ -41,6 +41,10 @@ const promptMessageBase = (middle) => `\n${middle}\n\nAre you sure you would lik
async function deploy() { async function deploy() {
const signer = await ethers.getSigner() const signer = await ethers.getSigner()
if (process.env.STAKING_PROXY_ADDRESS === undefined) throw Error('Missing STAKING_PROXY_ADDRESS.')
const stakingProxyAddress = `${process.env.STAKING_PROXY_ADDRESS}`
const registryImplementationDeployer = (await ethers.getContractFactory('RelayerRegistry')).connect(signer) const registryImplementationDeployer = (await ethers.getContractFactory('RelayerRegistry')).connect(signer)
let registry let registry
@ -50,7 +54,7 @@ async function deploy() {
config.TORN, config.TORN,
config.governance, config.governance,
config.ens, config.ens,
config.staking, stakingProxyAddress,
config.feeManager, config.feeManager,
) )
console.log(deployedMessage('RelayerRegistry (Implementation)', 1, registry.address)) console.log(deployedMessage('RelayerRegistry (Implementation)', 1, registry.address))
@ -61,7 +65,13 @@ async function deploy() {
if (await prompt(promptMessageBase('Continuing to contract verification.'))) { if (await prompt(promptMessageBase('Continuing to contract verification.'))) {
await hre.run('verify:verify', { await hre.run('verify:verify', {
address: registry.address, address: registry.address,
constructorArguments: [config.TORN, config.governance, config.ens, config.staking, config.feeManager], constructorArguments: [
config.TORN,
config.governance,
config.ens,
stakingProxyAddress,
config.feeManager,
],
}) })
console.log(verifiedMessage('RelayerRegistry (Implementation)')) console.log(verifiedMessage('RelayerRegistry (Implementation)'))
} else { } else {

@ -42,22 +42,40 @@ async function deploy() {
const signer = await ethers.getSigner() const signer = await ethers.getSigner()
const stakingDeployer = (await ethers.getContractFactory('TornadoStakingRewards')).connect(signer) const stakingDeployer = (await ethers.getContractFactory('TornadoStakingRewards')).connect(signer)
const proxyDeployer = (await ethers.getContractFactory('AdminUpgradeableProxy')).connect(signer)
let staking let impl, proxy
if (await prompt(promptMessageBase('Continuing to TornadoStakingRewards deployment.'))) { if (await prompt(promptMessageBase('Continuing to TornadoStakingRewards (Implementation) deployment.'))) {
staking = await stakingDeployer.deploy(config.governance, config.TORN, config.registry) impl = await stakingDeployer.deploy(config.governance, config.TORN, config.registry)
console.log(deployedMessage('TornadoStakingRewards', 1, staking.address)) console.log(deployedMessage('TornadoStakingRewards (Implementation)', 1, impl.address))
} else { } else {
return '\nDecided to stop at TornadoStakingRewards deployment.\n' return '\nDecided to stop at TornadoStakingRewards (Implementation) deployment.\n'
}
if (await prompt(promptMessageBase('Continuing to Staking Proxy deployment.'))) {
proxy = await proxyDeployer.deploy(impl.address, governance.address, [])
console.log(deployedMessage('Staking Proxy', 1, proxy.address))
} else {
return '\nDecided to stop at Staking Proxy deployment.\n'
} }
if (await prompt(promptMessageBase('Continuing to contract verification.'))) { if (await prompt(promptMessageBase('Continuing to contract verification.'))) {
await hre.run('verify:verify', { await hre.run('verify:verify', {
address: staking.address, address: impl.address,
constructorArguments: [config.governance, config.TORN, config.registry], constructorArguments: [config.governance, config.TORN, config.registry],
}) })
console.log(verifiedMessage('TornadoStakingRewards'))
console.log(verifiedMessage('TornadoStakingRewards (Implementation)'))
console.log('\nWaiting 5 seconds.\n')
await timeout(5)
await hre.run('verify:verify', {
address: proxy.address,
constructorArguments: [impl.address, governance.address, []],
})
console.log(verifiedMessage('Staking Proxy'))
} else { } else {
return '\nDecided to stop at contract verification.\n' return '\nDecided to stop at contract verification.\n'
} }

@ -56,6 +56,7 @@ describe('Gov Exploit Patch Upgrade Tests', () => {
let registryDeployer let registryDeployer
let stakingDeployer let stakingDeployer
let proxyDeployer
let proposerBalanceInitial let proposerBalanceInitial
@ -141,6 +142,7 @@ describe('Gov Exploit Patch Upgrade Tests', () => {
maliciousProposalDeployer = await ethers.getContractFactory('MaliciousProposal') maliciousProposalDeployer = await ethers.getContractFactory('MaliciousProposal')
stakingDeployer = await ethers.getContractFactory('TornadoStakingRewards') stakingDeployer = await ethers.getContractFactory('TornadoStakingRewards')
proxyDeployer = await ethers.getContractFactory('AdminUpgradeableProxy')
registryDeployer = await ethers.getContractFactory('RelayerRegistry') registryDeployer = await ethers.getContractFactory('RelayerRegistry')
proposalDeployer = await ethers.getContractFactory('PatchProposal') proposalDeployer = await ethers.getContractFactory('PatchProposal')
@ -156,11 +158,13 @@ describe('Gov Exploit Patch Upgrade Tests', () => {
staking = await stakingDeployer.deploy(config.governance, config.TORN, config.registry) staking = await stakingDeployer.deploy(config.governance, config.TORN, config.registry)
staking = await proxyDeployer.deploy(staking.address, governance.address, [])
registryImplementation = await registryDeployer.deploy( registryImplementation = await registryDeployer.deploy(
config.TORN, config.TORN,
config.governance, config.governance,
config.ens, config.ens,
config.staking, staking.address,
config.feeManager, config.feeManager,
) )