diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..2b4fff4 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,27 @@ +{ + "env": { + "node": true, + "browser": true, + "es6": true, + "mocha": true + }, + "extends": ["eslint:recommended", "plugin:prettier/recommended", "prettier"], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parser": "babel-eslint", + "parserOptions": { + "ecmaVersion": 2018 + }, + "rules": { + "indent": ["error", 2], + "linebreak-style": ["error", "unix"], + "quotes": ["error", "single", { "avoidEscape": true }], + "semi": ["error", "never"], + "object-curly-spacing": ["error", "always"], + "comma-dangle": ["error", "always-multiline"], + "require-await": "error", + "prettier/prettier": ["error", { "printWidth": 110 }] + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..8d49586 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,8 @@ +.vscode +.idea +artifacts +artifacts-ovm +cache +cache-ovm +contracts/Verifier*.sol +src/types \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..f532b1b --- /dev/null +++ b/.prettierrc @@ -0,0 +1,16 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": true, + "semi": false, + "printWidth": 110, + "overrides": [ + { + "files": "*.sol", + "options": { + "singleQuote": false, + "printWidth": 130 + } + } + ] +} diff --git a/README.md b/README.md index 2a23c9f..019cf7d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # Nova upgrade proposal + There is Tornado governance proposal for upgrade nova contract on Xdai chain. -## Tests + +## Tests + 1. Install dependencies: ``` @@ -20,7 +23,9 @@ There is Tornado governance proposal for upgrade nova contract on Xdai chain. ``` yarn lint ``` + ## Deploy + 1. Check `config.json` for actual values. 2. Run deploy: diff --git a/contracts/NovaUpgradeProposal.sol b/contracts/NovaUpgradeProposal.sol index aa51c36..5a02278 100644 --- a/contracts/NovaUpgradeProposal.sol +++ b/contracts/NovaUpgradeProposal.sol @@ -6,42 +6,41 @@ pragma experimental ABIEncoderV2; import { ImmutableGovernanceInformation } from "tornado-governance/contracts/v2-vault-and-gas/ImmutableGovernanceInformation.sol"; interface IUpgradeableProxy { - function upgradeTo(address newImplementation) external; + function upgradeTo(address newImplementation) external; } interface IAMB { - function requireToPassMessage(address _contract, bytes calldata _data, uint256 _gas) external returns (bytes32); + function requireToPassMessage( + address _contract, + bytes calldata _data, + uint256 _gas + ) external returns (bytes32); } contract NovaUpgradeProposal is ImmutableGovernanceInformation { + event MessagePassed(bytes32 msgId); - event MessagePassed(bytes32 msgId); + address public immutable novaProxy; + address public immutable newNovaImpl; + IAMB public immutable bridge; + uint256 public immutable gasLimit; - 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; + } - 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); - } + 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/contracts/helpers/MockAMB.sol b/contracts/helpers/MockAMB.sol index 6d0f4ac..3611d15 100644 --- a/contracts/helpers/MockAMB.sol +++ b/contracts/helpers/MockAMB.sol @@ -4,36 +4,36 @@ pragma abicoder v2; import { IAMB } from "omnibridge/contracts/interfaces/IAMB.sol"; - abstract contract MockAMB is IAMB { - address public xDomainMessageSender; - bytes32 public xDomainMessageChainId; +abstract contract MockAMB is IAMB { + address public xDomainMessageSender; + bytes32 public xDomainMessageChainId; - struct Call { - address who; - bytes callData; - } - - constructor(address _xDomainMessageSender, uint256 _xDomainMessageChainId) { - xDomainMessageSender = _xDomainMessageSender; - xDomainMessageChainId = bytes32(uint256(_xDomainMessageChainId)); - } - - function setMessageSender(address _sender) external { - xDomainMessageSender = _sender; - } - - function messageSender() external view override returns (address) { - return xDomainMessageSender; - } - - function messageSourceChainId() external view override returns (bytes32) { - return xDomainMessageChainId; - } - - function execute(Call[] calldata _calls) external returns (bool success, bytes memory result) { - for (uint256 i = 0; i < _calls.length; i++) { - (success, result) = _calls[i].who.call(_calls[i].callData); - require(success, string(result)); + struct Call { + address who; + bytes callData; + } + + constructor(address _xDomainMessageSender, uint256 _xDomainMessageChainId) { + xDomainMessageSender = _xDomainMessageSender; + xDomainMessageChainId = bytes32(uint256(_xDomainMessageChainId)); + } + + function setMessageSender(address _sender) external { + xDomainMessageSender = _sender; + } + + function messageSender() external view override returns (address) { + return xDomainMessageSender; + } + + function messageSourceChainId() external view override returns (bytes32) { + return xDomainMessageChainId; + } + + function execute(Call[] calldata _calls) external returns (bool success, bytes memory result) { + for (uint256 i = 0; i < _calls.length; i++) { + (success, result) = _calls[i].who.call(_calls[i].callData); + require(success, string(result)); + } } - } } diff --git a/contracts/helpers/SingletonFactory.sol b/contracts/helpers/SingletonFactory.sol index e114c0d..7b8e56e 100644 --- a/contracts/helpers/SingletonFactory.sol +++ b/contracts/helpers/SingletonFactory.sol @@ -12,17 +12,17 @@ pragma solidity ^0.6.2; * @author Ricardo Guilherme Schmidt (Status Research & Development GmbH) */ contract SingletonFactory { - /** - * @notice Deploys `_initCode` using `_salt` for defining the deterministic address. - * @param _initCode Initialization code. - * @param _salt Arbitrary value to modify resulting address. - * @return createdContract Created contract address. - */ - function deploy(bytes memory _initCode, bytes32 _salt) public returns (address payable createdContract) { - assembly { - createdContract := create2(0, add(_initCode, 0x20), mload(_initCode), _salt) + /** + * @notice Deploys `_initCode` using `_salt` for defining the deterministic address. + * @param _initCode Initialization code. + * @param _salt Arbitrary value to modify resulting address. + * @return createdContract Created contract address. + */ + function deploy(bytes memory _initCode, bytes32 _salt) public returns (address payable createdContract) { + assembly { + createdContract := create2(0, add(_initCode, 0x20), mload(_initCode), _salt) + } } - } } // IV is a value changed to generate the vanity address. // IV: 6583047 diff --git a/contracts/helpers/TestGovernanceUpgrade.sol b/contracts/helpers/TestGovernanceUpgrade.sol index 441179c..49e2e83 100644 --- a/contracts/helpers/TestGovernanceUpgrade.sol +++ b/contracts/helpers/TestGovernanceUpgrade.sol @@ -6,12 +6,9 @@ pragma experimental ABIEncoderV2; import { GovernanceGasUpgrade } from "tornado-governance/contracts/v2-vault-and-gas/gas/GovernanceGasUpgrade.sol"; contract TestGovernanceUpgrade is GovernanceGasUpgrade { - constructor( - address gasCompLogic, - address userVaultAddress - ) public GovernanceGasUpgrade(gasCompLogic, userVaultAddress) {} + constructor(address gasCompLogic, address userVaultAddress) public GovernanceGasUpgrade(gasCompLogic, userVaultAddress) {} - function test() public pure returns (int256) { - return 231; - } + function test() public pure returns (int256) { + return 231; + } } diff --git a/hardhat.config.js b/hardhat.config.js index 4909bd0..9e28bd7 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -57,18 +57,14 @@ module.exports = { }, accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] - : { - mnemonic: 'test test test test test test test test test test test junk', - }, + : { mnemonic: 'test test test test test junk' }, }, mainnet: { url: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_KEY}`, accounts: process.env.PRIVATE_KEY ? [process.env.PRIVATE_KEY] - : { - mnemonic: 'test test test test test test test test test test test junk', - }, + : { mnemonic: 'test test test test test junk' }, timeout: 2147483647, }, - } + }, } diff --git a/scripts/deploy.js b/scripts/deploy.js index 5c4877b..1696031 100644 --- a/scripts/deploy.js +++ b/scripts/deploy.js @@ -16,7 +16,7 @@ async function main() { 'SingletonFactory', config.singletonFactoryVerboseWrapper, ) - const contract = await generate(config) + const contract = await generate(config) await deploy({ ...contract, singletonFactory }) } diff --git a/src/0_generateAddresses.js b/src/0_generateAddresses.js index d41d78d..4383293 100644 --- a/src/0_generateAddresses.js +++ b/src/0_generateAddresses.js @@ -2,17 +2,12 @@ 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.ethAmbBridge, - config.gasLimit, - ]) + .encodeDeploy([config.novaProxy, config.newNovaImpl, config.ethAmbBridge, config.gasLimit]) .slice(2) const proposalAddress = ethers.utils.getCreate2Address( diff --git a/test/functions.test.js b/test/functions.test.js index e4ca8da..2c011cd 100644 --- a/test/functions.test.js +++ b/test/functions.test.js @@ -1,6 +1,5 @@ const { ethers } = require('hardhat') const { expect } = require('chai') -const fs = require('fs') const config = require('./test.config.json') const { getSignerFromAddress, takeSnapshot, revertSnapshot } = require('./utils') @@ -96,14 +95,14 @@ describe('General functionality tests', () => { state = await gov.state(id) expect(state).to.be.equal(ProposalState.AwaitingExecution) - await gov.execute(id) + await gov.execute(id) const amb = await ethers.getContractAt(ambPath, config.ethAmbBridge) const filter = amb.filters.UserRequestForAffirmation() const fromBlock = await ethers.provider.getBlock() events = await amb.queryFilter(filter, fromBlock.number) - bridgedData = events[0].args.encodedData.toString() - expect(bridgedData.slice(106,146)).to.be.equal(config.novaProxy.slice(2)) + const bridgedData = events[0].args.encodedData.toString() + expect(bridgedData.slice(106, 146)).to.be.equal(config.novaProxy.slice(2)) expect(bridgedData.slice(196)).to.be.equal(config.newNovaImpl.slice(2)) state = await gov.state(id)