From 70259244aac704498edd4f5b23efa847183330fd Mon Sep 17 00:00:00 2001 From: Drygin Date: Thu, 27 Jan 2022 14:51:44 +0300 Subject: [PATCH] add contracts --- contracts/NovaUpgradeProposal.sol | 47 +++++++++++++++++++++++++++++++ scripts/deploy.js | 28 ++++++++++++++++++ src/0_generateAddresses.js | 37 ++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 contracts/NovaUpgradeProposal.sol create mode 100644 scripts/deploy.js create mode 100644 src/0_generateAddresses.js diff --git a/contracts/NovaUpgradeProposal.sol b/contracts/NovaUpgradeProposal.sol new file mode 100644 index 0000000..aa51c36 --- /dev/null +++ b/contracts/NovaUpgradeProposal.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.6.12; +pragma experimental ABIEncoderV2; + +import { ImmutableGovernanceInformation } from "tornado-governance/contracts/v2-vault-and-gas/ImmutableGovernanceInformation.sol"; + +interface IUpgradeableProxy { + function upgradeTo(address newImplementation) external; +} + +interface IAMB { + function requireToPassMessage(address _contract, bytes calldata _data, uint256 _gas) external returns (bytes32); +} + +contract NovaUpgradeProposal is ImmutableGovernanceInformation { + + event MessagePassed(bytes32 msgId); + + address public immutable novaProxy; + address public immutable newNovaImpl; + IAMB public immutable bridge; + uint256 public immutable gasLimit; + + constructor( + address _novaProxy, + address _newNovaImpl, + address _bridge, + uint256 _gasLimit + ) public { + novaProxy = _novaProxy; + newNovaImpl = _newNovaImpl; + bridge = IAMB(_bridge); + gasLimit = _gasLimit; + } + + function executeProposal() external { + bytes4 methodSelector = IUpgradeableProxy(address(0)).upgradeTo.selector; + bytes memory data = abi.encodeWithSelector(methodSelector, newNovaImpl); + bytes32 msgId = bridge.requireToPassMessage( + novaProxy, + data, + gasLimit + ); + emit MessagePassed(msgId); + } +} diff --git a/scripts/deploy.js b/scripts/deploy.js new file mode 100644 index 0000000..5c4877b --- /dev/null +++ b/scripts/deploy.js @@ -0,0 +1,28 @@ +const { ethers } = require('hardhat') +const { generate } = require('../src/0_generateAddresses') +const config = require('../config') + +async function deploy({ address, bytecode, singletonFactory }) { + const contractCode = await ethers.provider.getCode(address) + if (contractCode !== '0x') { + console.log(`Contract ${address} already deployed. Skipping...`) + return + } + await singletonFactory.deploy(bytecode, config.salt) +} + +async function main() { + const singletonFactory = await ethers.getContractAt( + 'SingletonFactory', + config.singletonFactoryVerboseWrapper, + ) + const contract = await generate(config) + await deploy({ ...contract, singletonFactory }) +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error) + process.exit(1) + }) diff --git a/src/0_generateAddresses.js b/src/0_generateAddresses.js new file mode 100644 index 0000000..e2aece9 --- /dev/null +++ b/src/0_generateAddresses.js @@ -0,0 +1,37 @@ +const { ethers } = require('hardhat') + +async function generate(config) { + const singletonFactory = await ethers.getContractAt('SingletonFactory', config.singletonFactory) + + const ProposalFactory = await ethers.getContractFactory('NovaUpgradeProposal') + const deploymentBytecodeProposal = + ProposalFactory.bytecode + + ProposalFactory.interface + .encodeDeploy([ + config.novaProxy, + config.newNovaImpl, + config.bridge, + config.gasLimit, + ]) + .slice(2) + + const proposalAddress = ethers.utils.getCreate2Address( + singletonFactory.address, + config.salt, + ethers.utils.keccak256(deploymentBytecodeProposal), + ) + + const result = { + proposalContract: { + address: proposalAddress, + bytecode: deploymentBytecodeProposal, + isProxy: false, + }, + } + + return result +} + +module.exports = { + generate, +}