diff --git a/contracts/Proposal.sol b/contracts/Proposal.sol index b63462f..f758f68 100644 --- a/contracts/Proposal.sol +++ b/contracts/Proposal.sol @@ -17,17 +17,26 @@ interface IProposal4 { function getInstances() external view returns (TornadoProxy.Tornado[] memory instances); } +interface ITornadoProxy { + function updateInstance(TornadoProxy.Tornado calldata) external; + function tornadoTrees() external view returns(address); + function governance() external view returns(address); + function instances(ITornadoInstance) external view returns(bool, IERC20, TornadoProxy.InstanceState); +} + interface TornadoTrees is ITornadoTrees { function setTornadoProxyContract(address _tornadoProxy) external; } + contract Proposal { - TornadoProxy public constant tornadoProxyV2 = TornadoProxy(0x722122dF12D4e14e13Ac3b6895a86e84145b6967); + ITornadoProxy public constant tornadoProxyV2 = ITornadoProxy(0x722122dF12D4e14e13Ac3b6895a86e84145b6967); TornadoTrees public constant tornadoTrees = TornadoTrees(0x527653eA119F3E6a1F5BD18fbF4714081D7B31ce); IProposal4 public constant proposal4 = IProposal4(0x4B6C07B8940a7602fE4332AFa915b366e56eAce5); address public constant governance = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce; uint256 public constant txFee = 0.1 ether; uint256 public constant minStake = 500 ether; + uint256 public constant govFeeSplitPercent = 95; event DeploymentOf(string name, address addr); @@ -63,7 +72,7 @@ contract Proposal { // initializing Relayer registry RelayerRegistry registry = RelayerRegistry(address(registryProxy)); - registry.initialize(address(tornadoProxyV3), txFee, minStake); + registry.initialize(address(tornadoProxyV3), txFee, minStake, govFeeSplitPercent); // registering the new tornadoProxy contract in tornadoTrees tornadoTrees.setTornadoProxyContract(address(tornadoProxyV3)); diff --git a/contracts/RelayerRegistry.sol b/contracts/RelayerRegistry.sol index e92cc5c..040cb39 100644 --- a/contracts/RelayerRegistry.sol +++ b/contracts/RelayerRegistry.sol @@ -2,7 +2,6 @@ pragma solidity ^0.7.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts-upgradeable/proxy/Initializable.sol"; @@ -10,25 +9,28 @@ interface IENS { function owner(bytes32 node) external view returns (address); } -contract RelayerRegistry is Ownable, Initializable { +contract RelayerRegistry is Initializable { using SafeMath for uint256; IERC20 public constant TORN = IERC20(0x77777FeDdddFfC19Ff86DB637967013e6C6A116C); IENS public constant ENS = IENS(0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e); + address public constant GOV = 0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce; address public withdrawalProxy; mapping(address => Relayer) public relayers; - uint256 public txFee; + uint256 public txFee; // TODO should rely on baseFee for a tx uint256 public minStake; + uint256 public govFeeSplitPercent; uint256 public totalTornBurned; event Register(bytes32 ensHash, address relayer); event Stake(address indexed relayer, uint256 stake); event Kick(address indexed relayer, bool confiscation); + event Transaction(address indexed relayer, uint fee); event NewMinStake(uint256 stake); event NewTxFee(uint256 fee); event NewWithdrawalProxy(address proxy); - event Transaction(address indexed _relayer, uint _fee); + event NewGovFeeSplitPercent(uint256 govFeeSplitPercent); modifier onlyWithdrawalProxy { @@ -36,16 +38,22 @@ contract RelayerRegistry is Ownable, Initializable { _; } + modifier onlyGovernance { + require(msg.sender == GOV, "only governance"); + _; + } + struct Relayer { uint256 balance; bytes32 ensHash; mapping(address => bool) addresses; } - function initialize(address _withdrawalProxy, uint256 _txFee, uint256 _minStake) external initializer { + function initialize(address _withdrawalProxy, uint256 _txFee, uint256 _minStake, uint256 _govFeeSplitPercent) external initializer { withdrawalProxy = _withdrawalProxy; txFee = _txFee; minStake = _minStake; + govFeeSplitPercent = _govFeeSplitPercent; } function register(uint _stake, bytes32 _ensHash) external { @@ -78,22 +86,35 @@ contract RelayerRegistry is Ownable, Initializable { } } - function setTxFee(uint256 _txFee) external onlyOwner { + function distributeFees() external { + uint _totalTornBurned = totalTornBurned; + uint govAmount = totalTornBurned.mul(govFeeSplitPercent).div(100); + TORN.transfer(GOV, govAmount); + TORN.transfer(address(0), _totalTornBurned.sub(govAmount)); + } + + function setTxFee(uint256 _txFee) external onlyGovernance { txFee = _txFee; emit NewTxFee(_txFee); } - function setMinStake(uint256 _stake) external onlyOwner { + function setMinStake(uint256 _stake) external onlyGovernance { minStake = _stake; emit NewMinStake(_stake); } - function setWithdrawalProxy(address _proxy) external onlyOwner { + function setWithdrawalProxy(address _proxy) external onlyGovernance { withdrawalProxy = _proxy; emit NewWithdrawalProxy(_proxy); } - function kick(address _relayer, bool confiscateStake) external onlyOwner { + function setGovFeeSplitPercent(uint256 _govFeeSplitPercent) external onlyGovernance { + require(_govFeeSplitPercent <= 100, "Percent should an integer number from 0 to 100"); + govFeeSplitPercent = _govFeeSplitPercent; + emit NewGovFeeSplitPercent(_govFeeSplitPercent); + } + + function kick(address _relayer, bool confiscateStake) external onlyGovernance { Relayer storage relayer = relayers[_relayer]; TORN.transfer(confiscateStake ? msg.sender : _relayer, relayer.balance); relayer.balance = 0; diff --git a/hardhat.config.js b/hardhat.config.js index a6450d5..61dd0e4 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -2,6 +2,7 @@ require('dotenv').config() require('@nomiclabs/hardhat-waffle') require('@nomiclabs/hardhat-etherscan') require('hardhat-etherscan-abi') +require('hardhat-contract-sizer') /** * @type import('hardhat/config').HardhatUserConfig @@ -61,4 +62,9 @@ module.exports = { // Obtain one at https://etherscan.io/ apiKey: process.env.ETHERSCAN_KEY, }, + contractSizer: { + alphaSort: true, + runOnCompile: true, + disambiguatePaths: false, + }, } diff --git a/package.json b/package.json index 1a1598e..5b80a0d 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "ethereum-waffle": "^3.0.0", "ethers": "^5.0.0", "hardhat": "^2.1.2", + "hardhat-contract-sizer": "^2.0.3", "prettier": "^2.3.2", "prettier-plugin-solidity": "^1.0.0-beta.17", "solhint-plugin-prettier": "^0.0.5" diff --git a/yarn.lock b/yarn.lock index 594daa9..e9f854b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2282,6 +2282,16 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +cli-table3@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" + integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== + dependencies: + object-assign "^4.1.0" + string-width "^4.2.0" + optionalDependencies: + colors "^1.1.2" + cliui@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -2349,6 +2359,11 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +colors@^1.1.2, colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -4138,6 +4153,14 @@ har-validator@~5.1.3: ajv "^6.12.3" har-schema "^2.0.0" +hardhat-contract-sizer@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/hardhat-contract-sizer/-/hardhat-contract-sizer-2.0.3.tgz#604455fd803865f81c29f60364e863eaa19395a7" + integrity sha512-iaixOzWxwOSIIE76cl2uk4m9VXI1hKU3bFt+gl7jDhyb2/JB2xOp5wECkfWqAoc4V5lD4JtjldZlpSTbzX+nPQ== + dependencies: + cli-table3 "^0.6.0" + colors "^1.4.0" + hardhat-etherscan-abi@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/hardhat-etherscan-abi/-/hardhat-etherscan-abi-0.1.1.tgz#5f2c0460aea1a649c2188619405f70a9ea1e019b"