From 9a87c5ca61a4697f2882acafcbfc375506520cd3 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Thu, 18 Aug 2022 09:53:38 +0000 Subject: [PATCH 01/16] FeesEscow contract with tests --- abi/AccessControlUpgradeable.json | 230 +++++++++ abi/IMerkleDistributor.json | 373 ++++++++++++++ abi/IOracles.json | 312 ++++++++++++ abi/IPool.json | 668 ++++++++++++++++++++++++++ abi/IPoolEscrow.json | 152 ++++++ abi/IPoolValidators.json | 213 ++++++++ abi/IRewardToken.json | 562 ++++++++++++++++++++++ abi/IRoles.json | 141 ++++++ abi/IStakedToken.json | 270 +++++++++++ abi/RewardToken.json | 13 + contracts/interfaces/IBalancer.sol | 75 +++ contracts/interfaces/IFeesEscrow.sol | 23 + contracts/interfaces/IRewardToken.sol | 7 + contracts/interfaces/IWrapper.sol | 9 + contracts/pool/FeesEscrow.sol | 97 ++++ contracts/tokens/RewardToken.sol | 13 +- deployments/index.js | 58 ++- deployments/settings.js | 2 + hardhat.config.js | 3 +- test/pool/FeesEscrow.test.js | 99 ++++ 20 files changed, 3315 insertions(+), 5 deletions(-) create mode 100644 abi/AccessControlUpgradeable.json create mode 100644 abi/IMerkleDistributor.json create mode 100644 abi/IOracles.json create mode 100644 abi/IPool.json create mode 100644 abi/IPoolEscrow.json create mode 100644 abi/IPoolValidators.json create mode 100644 abi/IRewardToken.json create mode 100644 abi/IRoles.json create mode 100644 abi/IStakedToken.json create mode 100644 contracts/interfaces/IBalancer.sol create mode 100644 contracts/interfaces/IFeesEscrow.sol create mode 100644 contracts/interfaces/IWrapper.sol create mode 100644 contracts/pool/FeesEscrow.sol create mode 100644 test/pool/FeesEscrow.test.js diff --git a/abi/AccessControlUpgradeable.json b/abi/AccessControlUpgradeable.json new file mode 100644 index 00000000..54cbec42 --- /dev/null +++ b/abi/AccessControlUpgradeable.json @@ -0,0 +1,230 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IMerkleDistributor.json b/abi/IMerkleDistributor.json new file mode 100644 index 00000000..d19450a4 --- /dev/null +++ b/abi/IMerkleDistributor.json @@ -0,0 +1,373 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + } + ], + "name": "Claimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "merkleProofs", + "type": "string" + } + ], + "name": "MerkleRootUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "rewardsLink", + "type": "string" + } + ], + "name": "OneTimeDistributionAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "startBlock", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endBlock", + "type": "uint256" + } + ], + "name": "PeriodicDistributionAdded", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address[]", + "name": "tokens", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" + }, + { + "internalType": "bytes32[]", + "name": "merkleProof", + "type": "bytes32[]" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "_merkleRoot", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_wordIndex", + "type": "uint256" + } + ], + "name": "claimedBitMap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "string", + "name": "rewardsLink", + "type": "string" + } + ], + "name": "distributeOneTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "durationInBlocks", + "type": "uint256" + } + ], + "name": "distributePeriodically", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracles", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "isClaimed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "merkleRoot", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "oracles", + "outputs": [ + { + "internalType": "contract IOracles", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "newMerkleRoot", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "merkleProofs", + "type": "string" + } + ], + "name": "setMerkleRoot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IOracles.json b/abi/IOracles.json new file mode 100644 index 00000000..3fc4aca9 --- /dev/null +++ b/abi/IOracles.json @@ -0,0 +1,312 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "merkleProofs", + "type": "string" + } + ], + "name": "MerkleRootVoteSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oracle", + "type": "address" + } + ], + "name": "OracleAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oracle", + "type": "address" + } + ], + "name": "OracleRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "oracles", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + } + ], + "name": "RegisterValidatorsVoteSubmitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "oracle", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "activatedValidators", + "type": "uint256" + } + ], + "name": "RewardsVoteSubmitted", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "addOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "currentRewardsNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "currentValidatorsNonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isMerkleRootVoting", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isOracle", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "withdrawalCredentials", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "depositDataRoot", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "publicKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct IPoolValidators.DepositData[]", + "name": "depositData", + "type": "tuple[]" + }, + { + "internalType": "bytes32[][]", + "name": "merkleProofs", + "type": "bytes32[][]" + }, + { + "internalType": "bytes32", + "name": "validatorsDepositRoot", + "type": "bytes32" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "registerValidators", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "removeOracle", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "merkleProofs", + "type": "string" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "submitMerkleRoot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "activatedValidators", + "type": "uint256" + }, + { + "internalType": "bytes[]", + "name": "signatures", + "type": "bytes[]" + } + ], + "name": "submitRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IPool.json b/abi/IPool.json new file mode 100644 index 00000000..0c54eb6a --- /dev/null +++ b/abi/IPool.json @@ -0,0 +1,668 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "Activated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "activatedValidators", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "ActivatedValidatorsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "validatorIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "ActivationScheduled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "minActivatingDeposit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "MinActivatingDepositUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "pendingValidatorsLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "PendingValidatorsLimitUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Refunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "partner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "StakedWithPartner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "referrer", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "StakedWithReferrer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "publicKey", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "ValidatorRegistered", + "type": "event" + }, + { + "inputs": [], + "name": "GNO_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MGNO_TOKEN", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MGNO_WRAPPER", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "VALIDATOR_TOTAL_DEPOSIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "validatorIndex", + "type": "uint256" + } + ], + "name": "activate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "validatorIndexes", + "type": "uint256[]" + } + ], + "name": "activateMultiple", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "activatedValidators", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "validatorIndex", + "type": "uint256" + } + ], + "name": "activations", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "mgnoIn", + "type": "uint256" + } + ], + "name": "calculateGNO", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "validatorIndex", + "type": "uint256" + } + ], + "name": "canActivate", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_withdrawalCredentials", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_validatorRegistration", + "type": "address" + }, + { + "internalType": "address", + "name": "_stakedToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_validators", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracles", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_minActivatingDeposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_pendingValidatorsLimit", + "type": "uint256" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "minActivatingDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingValidators", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pendingValidatorsLimit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "refund", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "withdrawalCredentials", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "depositDataRoot", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "publicKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct IPoolValidators.DepositData", + "name": "depositData", + "type": "tuple" + } + ], + "name": "registerValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newActivatedValidators", + "type": "uint256" + } + ], + "name": "setActivatedValidators", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newMinActivatingDeposit", + "type": "uint256" + } + ], + "name": "setMinActivatingDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newPendingValidatorsLimit", + "type": "uint256" + } + ], + "name": "setPendingValidatorsLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "referredBy", + "type": "address" + }, + { + "internalType": "bool", + "name": "hasRevenueShare", + "type": "bool" + } + ], + "name": "stakeGNO", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "referredBy", + "type": "address" + }, + { + "internalType": "bool", + "name": "hasRevenueShare", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "stakeGNOWithPermit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "address", + "name": "referredBy", + "type": "address" + }, + { + "internalType": "bool", + "name": "hasRevenueShare", + "type": "bool" + } + ], + "name": "stakeMGNO", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "validatorRegistration", + "outputs": [ + { + "internalType": "contract IDepositContract", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawalCredentials", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/IPoolEscrow.json b/abi/IPoolEscrow.json new file mode 100644 index 00000000..640cf937 --- /dev/null +++ b/abi/IPoolEscrow.json @@ -0,0 +1,152 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferApplied", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "currentOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "futureOwner", + "type": "address" + } + ], + "name": "OwnershipTransferCommitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "payee", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "applyOwnershipTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "commitOwnershipTransfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "futureOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address payable", + "name": "payee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "payee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdrawTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IPoolValidators.json b/abi/IPoolValidators.json new file mode 100644 index 00000000..5512a370 --- /dev/null +++ b/abi/IPoolValidators.json @@ -0,0 +1,213 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "depositDataMerkleRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "depositDataMerkleProofs", + "type": "string" + } + ], + "name": "OperatorAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "OperatorCommitted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "OperatorRemoved", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "depositDataMerkleRoot", + "type": "bytes32" + }, + { + "internalType": "string", + "name": "depositDataMerkleProofs", + "type": "string" + } + ], + "name": "addOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "commitOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "name": "getOperator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracles", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "validatorId", + "type": "bytes32" + } + ], + "name": "isValidatorRegistered", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "withdrawalCredentials", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "depositDataRoot", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "publicKey", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + } + ], + "internalType": "struct IPoolValidators.DepositData", + "name": "depositData", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "merkleProof", + "type": "bytes32[]" + } + ], + "name": "registerValidator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_operator", + "type": "address" + } + ], + "name": "removeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IRewardToken.json b/abi/IRewardToken.json new file mode 100644 index 00000000..bf012a24 --- /dev/null +++ b/abi/IRewardToken.json @@ -0,0 +1,562 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "ProtocolFeeRecipientUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "protocolFee", + "type": "uint256" + } + ], + "name": "ProtocolFeeUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "isDisabled", + "type": "bool" + } + ], + "name": "RewardsToggled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "periodRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalRewards", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardPerToken", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "distributorReward", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "protocolReward", + "type": "uint256" + } + ], + "name": "RewardsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "checkpoints", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "claim", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_stakedToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_oracles", + "type": "address" + }, + { + "internalType": "address", + "name": "_protocolFeeRecipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_protocolFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_merkleDistributor", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastUpdateBlockNumber", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "merkleDistributor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFeeRecipient", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerToken", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "rewardsDisabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_protocolFee", + "type": "uint256" + } + ], + "name": "setProtocolFee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "setProtocolFeeRecipient", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bool", + "name": "isDisabled", + "type": "bool" + } + ], + "name": "setRewardsDisabled", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalRewards", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "updateRewardCheckpoint", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account1", + "type": "address" + }, + { + "internalType": "address", + "name": "account2", + "type": "address" + } + ], + "name": "updateRewardCheckpoints", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + }, + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newTotalRewards", + "type": "uint256" + } + ], + "name": "updateTotalRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feesEscrow", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IRoles.json b/abi/IRoles.json new file mode 100644 index 00000000..29fef019 --- /dev/null +++ b/abi/IRoles.json @@ -0,0 +1,141 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "OperatorRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "revenueShare", + "type": "uint256" + } + ], + "name": "OperatorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "partner", + "type": "address" + } + ], + "name": "PartnerRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "partner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "revenueShare", + "type": "uint256" + } + ], + "name": "PartnerUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "removeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "removePartner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "revenueShare", + "type": "uint256" + } + ], + "name": "setOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "revenueShare", + "type": "uint256" + } + ], + "name": "setPartner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IStakedToken.json b/abi/IStakedToken.json new file mode 100644 index 00000000..a1a28181 --- /dev/null +++ b/abi/IStakedToken.json @@ -0,0 +1,270 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "distributorPrincipal", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "bool", + "name": "isDisabled", + "type": "bool" + } + ], + "name": "toggleRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalDeposits", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/RewardToken.json b/abi/RewardToken.json index 933e4491..f79dd2ae 100644 --- a/abi/RewardToken.json +++ b/abi/RewardToken.json @@ -1091,5 +1091,18 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feesEscrow", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] diff --git a/contracts/interfaces/IBalancer.sol b/contracts/interfaces/IBalancer.sol new file mode 100644 index 00000000..338f6026 --- /dev/null +++ b/contracts/interfaces/IBalancer.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/interfaces/contracts/vault/IVault.sol + +pragma solidity 0.7.5; +pragma abicoder v2; + +interface IBalancerStruct { + enum SwapKind { GIVEN_IN, GIVEN_OUT } + + /** + * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on + * the `kind` value. + * + * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address). + * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault. + * + * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be + * used to extend swap behavior. + */ + struct SingleSwap { + bytes32 poolId; + SwapKind kind; + address assetIn; + address assetOut; + uint256 amount; + bytes userData; + } + + /** + * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the + * `recipient` account. + * + * If the caller is not `sender`, it must be an authorized relayer for them. + * + * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20 + * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender` + * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of + * `joinPool`. + * + * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of + * transferred. This matches the behavior of `exitPool`. + * + * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a + * revert. + */ + struct FundManagement { + address sender; + bool fromInternalBalance; + address payable recipient; + bool toInternalBalance; + } +} + +// This is Balancer Vault's interface. We use it mainly to exchange WXDAI to GNO token in FeesEscrow contract. +interface IBalancerVault is IBalancerStruct { + /** + * @dev Performs a swap with a single Pool. + * + * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens + * taken from the Pool, which must be greater than or equal to `limit`. + * + * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens + * sent to the Pool, which must be less than or equal to `limit`. + * + * Internal Balance usage and the recipient are determined by the `funds` struct. + * + * Emits a `Swap` event. + */ + function swap( + SingleSwap memory singleSwap, + FundManagement memory funds, + uint256 limit, + uint256 deadline + ) external payable returns (uint256); +} diff --git a/contracts/interfaces/IFeesEscrow.sol b/contracts/interfaces/IFeesEscrow.sol new file mode 100644 index 00000000..6bf0cdd6 --- /dev/null +++ b/contracts/interfaces/IFeesEscrow.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.7.5; + +/** + * @dev Interface of the FeesEscrow contract. + */ +interface IFeesEscrow { + /** + * @dev Event for tracking fees withdrawals to Pool contract. + * @param amountDAI - an amount of rewards before swap to GNO via Balancer Vault. + * @param amountGNO - an amount of rewards after swap. + */ + event FeesTransferred(uint256 amountDAI, uint256 amountGNO); + + /** + * @dev Function is used to transfer accumulated rewards to Pool contract. + * Can only be executed by the RewardEthToken contract. Also rewards accumulating + * in xDAI native tokens and this method swaps them to GNO token. Next GNO tokens + * are transferred to Pool. + */ + function transferToPool() external returns (uint256); +} diff --git a/contracts/interfaces/IRewardToken.sol b/contracts/interfaces/IRewardToken.sol index 5ca9200f..f0409428 100644 --- a/contracts/interfaces/IRewardToken.sol +++ b/contracts/interfaces/IRewardToken.sol @@ -71,6 +71,13 @@ interface IRewardToken is IERC20Upgradeable { address _merkleDistributor ) external; + /** + * @dev Function for upgrading the RewardEthToken contract. The `initialize` function must be defined + * if deploying contract for the first time that will initialize the state variables above. + * @param _feesEscrow - address of the FeesEscrow contract. + */ + function upgrade(address _feesEscrow) external; + /** * @dev Function for getting the address of the merkle distributor. */ diff --git a/contracts/interfaces/IWrapper.sol b/contracts/interfaces/IWrapper.sol new file mode 100644 index 00000000..a97db12b --- /dev/null +++ b/contracts/interfaces/IWrapper.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// https://github.com/gnosis/canonical-weth/blob/master/contracts/WETH9.sol + +pragma solidity 0.7.5; + +interface IWrapper { + function deposit() external payable; + function withdraw(uint amount) external; +} diff --git a/contracts/pool/FeesEscrow.sol b/contracts/pool/FeesEscrow.sol new file mode 100644 index 00000000..fee4159d --- /dev/null +++ b/contracts/pool/FeesEscrow.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.7.5; +pragma abicoder v2; + +import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; +import "../interfaces/IFeesEscrow.sol"; +import "../interfaces/IBalancer.sol"; +import "../interfaces/IWrapper.sol"; + +/** + * @title FeesEscrow + * + * @dev FeesEscrow contract is used to receive tips from validators and move them to the Pool contract + * when calling transferToPool method. + */ +contract FeesEscrow is IFeesEscrow, IBalancerStruct { + using SafeERC20Upgradeable for IERC20Upgradeable; + + // @dev Pool contract's address. + address private pool; + + // @dev RewardToken contract's address. + address private rewardToken; + + // @dev Balancer pool id for Symmetric Vault. + bytes32 private symmetricPoolId; + + // @dev Symmetric Balancer Vault contract address. + IBalancerVault private symmetricVault; + + // @dev Native xDAI wrapper contract address. + address private wrapper; + + // @dev GNO token contract address. + address private gnoToken; + + constructor( + address _pool, + address _rewardToken, + bytes32 _symmetricPoolId, + IBalancerVault _symmetricVault, + address _wrapper, + address _gnoToken + ) { + pool = _pool; + rewardToken = _rewardToken; + symmetricPoolId = _symmetricPoolId; + symmetricVault = _symmetricVault; + wrapper = _wrapper; + gnoToken = _gnoToken; + } + + /** + * @dev See {IFeesEscrow-transferToPool}. + */ + function transferToPool() external override returns (uint256) { + require(msg.sender == rewardToken, "FeesEscrow: invalid caller"); + + // Wrap all accumulated native xDAI tokens to WXDAI + uint256 balance = address(this).balance; + + if (balance == 0) { + return 0; + } + + IWrapper(wrapper).deposit{value: balance}(); + + // Prepare data to exchange WXDAI to GNO tokens via Balancer Vault + bytes memory userData = new bytes(0); + FundManagement memory funds = FundManagement(address(this), false, address(this), false); + SingleSwap memory singleSwap = SingleSwap( + symmetricPoolId, + SwapKind.GIVEN_IN, + wrapper, + gnoToken, + balance, + userData + ); + + // It's very important to approve WXDAI from FeesEscrow to Balancer Vault's without infinity approve + IERC20Upgradeable(wrapper).safeApprove(address(symmetricVault), balance); + + // Now we are ready to exchange WXDAI token to GNO + uint amountGnoOut = symmetricVault.swap(singleSwap, funds, 0, type(uint).max); + + // Transferring obtained GNO amount after exchanging to Pool contract address + IERC20Upgradeable(gnoToken).safeTransfer(pool, amountGnoOut); + + emit FeesTransferred(balance, amountGnoOut); + + return amountGnoOut; + } + + receive() external payable {} +} diff --git a/contracts/tokens/RewardToken.sol b/contracts/tokens/RewardToken.sol index 8722a995..4e144161 100644 --- a/contracts/tokens/RewardToken.sol +++ b/contracts/tokens/RewardToken.sol @@ -9,6 +9,7 @@ import "../interfaces/IStakedToken.sol"; import "../interfaces/IRewardToken.sol"; import "../interfaces/IMerkleDistributor.sol"; import "../interfaces/IOracles.sol"; +import "../interfaces/IFeesEscrow.sol"; import "./ERC20PermitUpgradeable.sol"; /** @@ -51,6 +52,9 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg // @dev Maps account address to whether rewards are distributed through the merkle distributor. mapping(address => bool) public override rewardsDisabled; + // @dev Address of the FeesEscrow contract. + address private feesEscrow; + /** * @dev See {IRewardToken-initialize}. */ @@ -85,6 +89,12 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg emit ProtocolFeeUpdated(_protocolFee); } + function upgrade(address _feesEscrow) external override onlyAdmin whenPaused { + require(feesEscrow == address(0), "Pool: FeesEscrow address already set"); + + feesEscrow = _feesEscrow; + } + /** * @dev See {IRewardToken-setRewardsDisabled}. */ @@ -236,7 +246,8 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg function updateTotalRewards(uint256 newTotalRewards) external override { require(msg.sender == oracles, "RewardToken: access denied"); - uint256 periodRewards = newTotalRewards.sub(totalRewards); + uint256 feesAmount = IFeesEscrow(feesEscrow).transferToPool(); + uint256 periodRewards = newTotalRewards.sub(totalRewards).add(feesAmount); if (periodRewards == 0) { lastUpdateBlockNumber = block.number; emit RewardsUpdated(0, newTotalRewards, rewardPerToken, 0, 0); diff --git a/deployments/index.js b/deployments/index.js index 83339ee5..0cfaeb5b 100644 --- a/deployments/index.js +++ b/deployments/index.js @@ -1,11 +1,63 @@ -const { contracts } = require('./settings'); +const { contracts, contractSettings } = require('./settings'); +const { ethers } = require('hardhat'); + +const SymmetricPoolId = + '0x650f5d96e83d3437bf5382558cb31f0ac5536684000200000000000000000001'; + +async function upgradeRewardEthToken(feesEscrowContractAddress) { + const signer = await ethers.provider.getSigner(contractSettings.admin); + const RewardEthToken = await ethers.getContractFactory('RewardToken', signer); + let rewardToken = await RewardEthToken.attach(contracts.rewardToken); + + // pause + if (!(await rewardToken.paused())) { + await rewardToken.pause(); + } + + // upgrade RewardEthToken to new implementation + const proxy = await upgrades.upgradeProxy( + contracts.rewardToken, + RewardEthToken + ); + await proxy.deployed(); + + // call upgrade + await rewardToken.upgrade(feesEscrowContractAddress); + + return rewardToken.unpause(); +} async function deployContracts() { - return contracts; + const FeesEscrow = await ethers.getContractFactory('FeesEscrow'); + const feesEscrow = await FeesEscrow.deploy( + contracts.pool, + contracts.rewardToken, + SymmetricPoolId, + contracts.GNOVault, + contracts.WXDAIToken, + contracts.GNOToken + ); + log('Deployed FeesEscrow contract:', feesEscrow.address); + + const RewardEthToken = await ethers.getContractFactory('RewardToken'); + const rewardToken = await upgrades.prepareUpgrade( + contracts.rewardToken, + RewardEthToken + ); + log('Deployed rewardToken implementation contract:', contracts.rewardToken); + + return { feesEscrow, rewardToken }; } async function upgradeContracts() { - return contracts; + const { feesEscrow } = await deployContracts(); + + await upgradeRewardEthToken(feesEscrow.address); + + return { + ...contracts, + feesEscrow: feesEscrow.address, + }; } module.exports = { diff --git a/deployments/settings.js b/deployments/settings.js index b9eef3ae..c2b5bc2c 100644 --- a/deployments/settings.js +++ b/deployments/settings.js @@ -12,6 +12,7 @@ let contracts = { MGNOWrapper: '0x647507A70Ff598F386CB96ae5046486389368C66', MGNOToken: '0x722fc4DAABFEaff81b97894fC623f91814a1BF68', GNOToken: '0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb', + WXDAIToken: '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', stakeWiseToken: '0xfdA94F056346d2320d4B5E468D6Ad099b2277746', oracles: '0xa6D123620Ea004cc5158b0ec260E934bd45C78c1', pool: '0x2f99472b727e15EECf9B9eFF9F7481B85d3b4444', @@ -22,6 +23,7 @@ let contracts = { merkleDistributor: '0x7dc30953CE236665d032329F6a922d67F0a33a2B', roles: '0x9b23e05AEfb37D5ea9b525016d19eb82b65F255c', contractChecker: '0x814f9c8C0269f11996138c77cc16A3A7f0A36b0C', + GNOVault: '0x24f87b37f4f249da61d89c3ff776a55c321b2773', }; module.exports = { diff --git a/hardhat.config.js b/hardhat.config.js index 3b19608b..982a14d4 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -109,8 +109,9 @@ module.exports = { networks: { hardhat: { forking: { - url: 'https://dai.poa.network/', + url: 'https://rpc.gnosischain.com/', chainId: 100, + blockNumber: 23795300, }, accounts: { accountsBalance: '1000000000000000000000000', diff --git a/test/pool/FeesEscrow.test.js b/test/pool/FeesEscrow.test.js new file mode 100644 index 00000000..c8491ea7 --- /dev/null +++ b/test/pool/FeesEscrow.test.js @@ -0,0 +1,99 @@ +const { send, ether, expectRevert } = require('@openzeppelin/test-helpers'); +const { ethers } = require('hardhat'); +const { expect } = require('chai'); +const { contracts, contractSettings } = require('../../deployments/settings'); +const { impersonateAccount, resetFork } = require('../utils'); +const { upgradeContracts } = require('../../deployments'); + +const Pool = artifacts.require('Pool'); +const FeesEscrow = artifacts.require('FeesEscrow'); + +let feesEscrow; +let pool; +let rewardToken; +let gnoToken; + +contract('FeesEscrow', (accounts) => { + let [sender] = accounts; + + beforeEach(async () => { + await impersonateAccount(contractSettings.admin); + await send.ether(sender, contractSettings.admin, ether('2')); + let upgradedContracts = await upgradeContracts(); + + const ERC20Mock = await ethers.getContractFactory('ERC20Mock'); + const RewardEthToken = await ethers.getContractFactory('RewardToken'); + rewardToken = await RewardEthToken.attach(upgradedContracts.rewardToken); + pool = await Pool.at(upgradedContracts.pool); + gnoToken = await ERC20Mock.attach(contracts.GNOToken); + feesEscrow = await FeesEscrow.at(upgradedContracts.feesEscrow); + }); + + afterEach(async () => resetFork()); + + it('transferToPool from RewardToken', async () => { + // eslint-disable-next-line no-unused-vars + const [_, validator] = await ethers.getSigners(); + await impersonateAccount(contracts.oracles); + const oraclesSigner = await ethers.getSigner(contracts.oracles); + + // Ensure zero balances before miner's reward distribution to FeesEscrow contract + const poolBalanceBefore = await gnoToken.balanceOf(pool.address); + expect(poolBalanceBefore.toString()).to.equal('0'); + + // Fund "Validator" address + const validatorReward = ethers.utils.parseEther('1000'); + await ethers.provider.send('hardhat_setBalance', [ + validator.address, + '0x1000000000000000000000', + ]); + + // Prepare for calling RewardToken.updateTotalRewards + const totalRewards = await rewardToken.totalRewards(); + const newTotalRewards = totalRewards.add(validatorReward); + + // Fund Oracles with balance for transaction fees + await ethers.provider.send('hardhat_setBalance', [ + oraclesSigner.address, + '0x1000000000000000000000', + ]); + + // Transfer reward from Validator to FeesEscrow + await validator.sendTransaction({ + to: feesEscrow.address, + value: validatorReward, + }); + + // Now call the RewardToken.updateTotalRewards by Oracles + await rewardToken + .connect(oraclesSigner) + .updateTotalRewards(newTotalRewards); + + // Ensure Pool GNO balance increased + const poolBalanceAfter = await gnoToken.balanceOf(pool.address); + expect(poolBalanceAfter.gt(poolBalanceBefore)).to.be.true; + + // FeeEscrow balances should be zero after updateTotalRewards + const feesEscrowNativeBalanceAfter = await ethers.provider.getBalance( + feesEscrow.address + ); + const feesEscrowBalanceAfter = await gnoToken.balanceOf(feesEscrow.address); + + expect(feesEscrowNativeBalanceAfter.toString()).to.equal('0'); + expect(feesEscrowBalanceAfter.toString()).to.equal('0'); + }); + + it('transferToPool from invalid caller', async () => { + // Send fees from "validator" to FeesEscrow contract + await send.ether( + sender, + feesEscrow.address, + ethers.utils.parseEther('1').toString() + ); + + await expectRevert( + feesEscrow.transferToPool(), + 'FeesEscrow: invalid caller' + ); + }); +}); From 0d7df6e6009c61e68693ca8da39dbd4b8286dae4 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Mon, 22 Aug 2022 12:15:39 +0000 Subject: [PATCH 02/16] Fix issues from review --- abi/IRewardToken.json | 2 +- abi/RewardToken.json | 2 +- contracts/interfaces/IBalancer.sol | 6 +- contracts/interfaces/IFeesEscrow.sol | 9 ++- contracts/interfaces/IRewardToken.sol | 3 +- contracts/pool/FeesEscrow.sol | 80 +++++++++++++++++++-------- contracts/tokens/RewardToken.sol | 8 +-- deployments/index.js | 8 ++- deployments/settings.js | 4 +- hardhat.config.js | 2 +- test/pool/FeesEscrow.test.js | 5 +- 11 files changed, 80 insertions(+), 49 deletions(-) diff --git a/abi/IRewardToken.json b/abi/IRewardToken.json index bf012a24..ed1fe1e6 100644 --- a/abi/IRewardToken.json +++ b/abi/IRewardToken.json @@ -549,7 +549,7 @@ { "inputs": [ { - "internalType": "address", + "internalType": "contract IFeesEscrow", "name": "_feesEscrow", "type": "address" } diff --git a/abi/RewardToken.json b/abi/RewardToken.json index f79dd2ae..3dab5cf6 100644 --- a/abi/RewardToken.json +++ b/abi/RewardToken.json @@ -1095,7 +1095,7 @@ { "inputs": [ { - "internalType": "address", + "internalType": "contract IFeesEscrow", "name": "_feesEscrow", "type": "address" } diff --git a/contracts/interfaces/IBalancer.sol b/contracts/interfaces/IBalancer.sol index 338f6026..e40287c4 100644 --- a/contracts/interfaces/IBalancer.sol +++ b/contracts/interfaces/IBalancer.sol @@ -4,7 +4,8 @@ pragma solidity 0.7.5; pragma abicoder v2; -interface IBalancerStruct { +// This is Balancer Vault's interface. We use it mainly to exchange WXDAI to GNO token in FeesEscrow contract. +interface IBalancerVault { enum SwapKind { GIVEN_IN, GIVEN_OUT } /** @@ -49,10 +50,7 @@ interface IBalancerStruct { address payable recipient; bool toInternalBalance; } -} -// This is Balancer Vault's interface. We use it mainly to exchange WXDAI to GNO token in FeesEscrow contract. -interface IBalancerVault is IBalancerStruct { /** * @dev Performs a swap with a single Pool. * diff --git a/contracts/interfaces/IFeesEscrow.sol b/contracts/interfaces/IFeesEscrow.sol index 6bf0cdd6..9667f281 100644 --- a/contracts/interfaces/IFeesEscrow.sol +++ b/contracts/interfaces/IFeesEscrow.sol @@ -9,15 +9,14 @@ interface IFeesEscrow { /** * @dev Event for tracking fees withdrawals to Pool contract. * @param amountDAI - an amount of rewards before swap to GNO via Balancer Vault. - * @param amountGNO - an amount of rewards after swap. + * @param amountMGNO - an amount of rewards after swap. */ - event FeesTransferred(uint256 amountDAI, uint256 amountGNO); + event FeesTransferred(uint256 amountDAI, uint256 amountMGNO); /** * @dev Function is used to transfer accumulated rewards to Pool contract. - * Can only be executed by the RewardEthToken contract. Also rewards accumulating - * in xDAI native tokens and this method swaps them to GNO token. Next GNO tokens - * are transferred to Pool. + * Can only be executed by the RewardEthToken contract. Also, rewards are accumulated + * in xDAI native tokens, converted to mGNO and transferred to Pool. */ function transferToPool() external returns (uint256); } diff --git a/contracts/interfaces/IRewardToken.sol b/contracts/interfaces/IRewardToken.sol index f0409428..cf7f8596 100644 --- a/contracts/interfaces/IRewardToken.sol +++ b/contracts/interfaces/IRewardToken.sol @@ -3,6 +3,7 @@ pragma solidity 0.7.5; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; +import "./IFeesEscrow.sol"; /** * @dev Interface of the RewardToken contract. @@ -76,7 +77,7 @@ interface IRewardToken is IERC20Upgradeable { * if deploying contract for the first time that will initialize the state variables above. * @param _feesEscrow - address of the FeesEscrow contract. */ - function upgrade(address _feesEscrow) external; + function upgrade(IFeesEscrow _feesEscrow) external; /** * @dev Function for getting the address of the merkle distributor. diff --git a/contracts/pool/FeesEscrow.sol b/contracts/pool/FeesEscrow.sol index fee4159d..2cdc5f95 100644 --- a/contracts/pool/FeesEscrow.sol +++ b/contracts/pool/FeesEscrow.sol @@ -1,13 +1,14 @@ -// SPDX-License-Identifier: AGPL-3.0-only +// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.7.5; pragma abicoder v2; -import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; -import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "../interfaces/IFeesEscrow.sol"; import "../interfaces/IBalancer.sol"; import "../interfaces/IWrapper.sol"; +import "../interfaces/IGNOToken.sol"; /** * @title FeesEscrow @@ -15,41 +16,60 @@ import "../interfaces/IWrapper.sol"; * @dev FeesEscrow contract is used to receive tips from validators and move them to the Pool contract * when calling transferToPool method. */ -contract FeesEscrow is IFeesEscrow, IBalancerStruct { - using SafeERC20Upgradeable for IERC20Upgradeable; +contract FeesEscrow is IFeesEscrow { + using SafeERC20 for IERC20; // @dev Pool contract's address. - address private pool; + address private immutable pool; // @dev RewardToken contract's address. - address private rewardToken; + address private immutable rewardToken; // @dev Balancer pool id for Symmetric Vault. - bytes32 private symmetricPoolId; + bytes32 private immutable symmetricPoolId; // @dev Symmetric Balancer Vault contract address. - IBalancerVault private symmetricVault; + IBalancerVault private immutable symmetricVault; // @dev Native xDAI wrapper contract address. - address private wrapper; + IWrapper private immutable wrapper; + + // @dev GNO to mGNO wrapper contract address. + address private immutable mGnoWrapper; // @dev GNO token contract address. - address private gnoToken; + address private immutable gnoToken; + + // @dev mGNO token contract address. + address private immutable mGnoToken; + + /* + * @dev This struct used only in IBalancerVault.swap method so we decided to + * move it to contract state and make immutable. But immutable and constant + * modifiers are not supported for structs for now, only for primitive types + * and strings - that's why there is no immutable modifier. + */ + IBalancerVault.FundManagement private funds; constructor( address _pool, address _rewardToken, bytes32 _symmetricPoolId, IBalancerVault _symmetricVault, - address _wrapper, - address _gnoToken + IWrapper _wrapper, + address _mGnoWrapper, + address _gnoToken, + address _mGnoToken ) { pool = _pool; rewardToken = _rewardToken; symmetricPoolId = _symmetricPoolId; symmetricVault = _symmetricVault; wrapper = _wrapper; + mGnoWrapper = _mGnoWrapper; gnoToken = _gnoToken; + mGnoToken = _mGnoToken; + funds = IBalancerVault.FundManagement(address(this), false, address(this), false); } /** @@ -58,40 +78,52 @@ contract FeesEscrow is IFeesEscrow, IBalancerStruct { function transferToPool() external override returns (uint256) { require(msg.sender == rewardToken, "FeesEscrow: invalid caller"); - // Wrap all accumulated native xDAI tokens to WXDAI + // Fetch current native xDAI balance to be wrapped next uint256 balance = address(this).balance; if (balance == 0) { return 0; } - IWrapper(wrapper).deposit{value: balance}(); + // Wrap all accumulated native xDAI tokens to WXDAI + wrapper.deposit{value: balance}(); // Prepare data to exchange WXDAI to GNO tokens via Balancer Vault - bytes memory userData = new bytes(0); - FundManagement memory funds = FundManagement(address(this), false, address(this), false); - SingleSwap memory singleSwap = SingleSwap( + IBalancerVault.SingleSwap memory singleSwap = IBalancerVault.SingleSwap( symmetricPoolId, - SwapKind.GIVEN_IN, - wrapper, + IBalancerVault.SwapKind.GIVEN_IN, + address(wrapper), gnoToken, balance, - userData + new bytes(0) ); // It's very important to approve WXDAI from FeesEscrow to Balancer Vault's without infinity approve - IERC20Upgradeable(wrapper).safeApprove(address(symmetricVault), balance); + IERC20(address(wrapper)).safeApprove(address(symmetricVault), balance); // Now we are ready to exchange WXDAI token to GNO uint amountGnoOut = symmetricVault.swap(singleSwap, funds, 0, type(uint).max); - // Transferring obtained GNO amount after exchanging to Pool contract address - IERC20Upgradeable(gnoToken).safeTransfer(pool, amountGnoOut); + // Convert GNO tokens to mGNO + IERC20(gnoToken).safeApprove(mGnoWrapper, amountGnoOut); + bool success = IGNOToken(gnoToken).transferAndCall(mGnoWrapper, amountGnoOut, ""); + require(success, "FeesEscrow: failed to convert tokens"); + + uint mGnoBalance = IERC20(mGnoToken).balanceOf(address(this)); + + // Transferring obtained ÑŒGNO amount to Pool contract + IERC20(mGnoToken).safeTransfer(pool, mGnoBalance); emit FeesTransferred(balance, amountGnoOut); return amountGnoOut; } + /** + * @dev Allows FeesEscrow contract to receive MEV rewards and priority fees + * from Validators addresses. Later these rewards will be converted to GNO + * and transferred to Pool contract by FeesEscrow.transferToPool method which + * is called once a day by RewardToken contract. + */ receive() external payable {} } diff --git a/contracts/tokens/RewardToken.sol b/contracts/tokens/RewardToken.sol index 4e144161..264a3957 100644 --- a/contracts/tokens/RewardToken.sol +++ b/contracts/tokens/RewardToken.sol @@ -53,7 +53,7 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg mapping(address => bool) public override rewardsDisabled; // @dev Address of the FeesEscrow contract. - address private feesEscrow; + IFeesEscrow private feesEscrow; /** * @dev See {IRewardToken-initialize}. @@ -89,8 +89,8 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg emit ProtocolFeeUpdated(_protocolFee); } - function upgrade(address _feesEscrow) external override onlyAdmin whenPaused { - require(feesEscrow == address(0), "Pool: FeesEscrow address already set"); + function upgrade(IFeesEscrow _feesEscrow) external override onlyAdmin whenPaused { + require(address(feesEscrow) == address(0), "Pool: FeesEscrow address already set"); feesEscrow = _feesEscrow; } @@ -246,7 +246,7 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg function updateTotalRewards(uint256 newTotalRewards) external override { require(msg.sender == oracles, "RewardToken: access denied"); - uint256 feesAmount = IFeesEscrow(feesEscrow).transferToPool(); + uint256 feesAmount = feesEscrow.transferToPool(); uint256 periodRewards = newTotalRewards.sub(totalRewards).add(feesAmount); if (periodRewards == 0) { lastUpdateBlockNumber = block.number; diff --git a/deployments/index.js b/deployments/index.js index 0cfaeb5b..2dcc9090 100644 --- a/deployments/index.js +++ b/deployments/index.js @@ -35,14 +35,16 @@ async function deployContracts() { SymmetricPoolId, contracts.GNOVault, contracts.WXDAIToken, - contracts.GNOToken + contracts.MGNOWrapper, + contracts.GNOToken, + contracts.MGNOToken ); log('Deployed FeesEscrow contract:', feesEscrow.address); - const RewardEthToken = await ethers.getContractFactory('RewardToken'); + const RewardToken = await ethers.getContractFactory('RewardToken'); const rewardToken = await upgrades.prepareUpgrade( contracts.rewardToken, - RewardEthToken + RewardToken ); log('Deployed rewardToken implementation contract:', contracts.rewardToken); diff --git a/deployments/settings.js b/deployments/settings.js index c2b5bc2c..491e5c87 100644 --- a/deployments/settings.js +++ b/deployments/settings.js @@ -12,7 +12,7 @@ let contracts = { MGNOWrapper: '0x647507A70Ff598F386CB96ae5046486389368C66', MGNOToken: '0x722fc4DAABFEaff81b97894fC623f91814a1BF68', GNOToken: '0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb', - WXDAIToken: '0xe91d153e0b41518a2ce8dd3d7944fa863463a97d', + WXDAIToken: '0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d', stakeWiseToken: '0xfdA94F056346d2320d4B5E468D6Ad099b2277746', oracles: '0xa6D123620Ea004cc5158b0ec260E934bd45C78c1', pool: '0x2f99472b727e15EECf9B9eFF9F7481B85d3b4444', @@ -23,7 +23,7 @@ let contracts = { merkleDistributor: '0x7dc30953CE236665d032329F6a922d67F0a33a2B', roles: '0x9b23e05AEfb37D5ea9b525016d19eb82b65F255c', contractChecker: '0x814f9c8C0269f11996138c77cc16A3A7f0A36b0C', - GNOVault: '0x24f87b37f4f249da61d89c3ff776a55c321b2773', + GNOVault: '0x24F87b37F4F249Da61D89c3FF776a55c321B2773', }; module.exports = { diff --git a/hardhat.config.js b/hardhat.config.js index 982a14d4..198a4b7a 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -111,7 +111,7 @@ module.exports = { forking: { url: 'https://rpc.gnosischain.com/', chainId: 100, - blockNumber: 23795300, + blockNumber: 23829149, }, accounts: { accountsBalance: '1000000000000000000000000', diff --git a/test/pool/FeesEscrow.test.js b/test/pool/FeesEscrow.test.js index c8491ea7..0782c110 100644 --- a/test/pool/FeesEscrow.test.js +++ b/test/pool/FeesEscrow.test.js @@ -25,7 +25,7 @@ contract('FeesEscrow', (accounts) => { const RewardEthToken = await ethers.getContractFactory('RewardToken'); rewardToken = await RewardEthToken.attach(upgradedContracts.rewardToken); pool = await Pool.at(upgradedContracts.pool); - gnoToken = await ERC20Mock.attach(contracts.GNOToken); + gnoToken = await ERC20Mock.attach(contracts.MGNOToken); feesEscrow = await FeesEscrow.at(upgradedContracts.feesEscrow); }); @@ -39,10 +39,9 @@ contract('FeesEscrow', (accounts) => { // Ensure zero balances before miner's reward distribution to FeesEscrow contract const poolBalanceBefore = await gnoToken.balanceOf(pool.address); - expect(poolBalanceBefore.toString()).to.equal('0'); // Fund "Validator" address - const validatorReward = ethers.utils.parseEther('1000'); + const validatorReward = ethers.utils.parseEther('10'); await ethers.provider.send('hardhat_setBalance', [ validator.address, '0x1000000000000000000000', From 07b266add0239d14f66fd3c48770ee77ea1d09d6 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Tue, 23 Aug 2022 07:34:23 +0000 Subject: [PATCH 03/16] Fix issues --- contracts/interfaces/IBalancer.sol | 2 +- contracts/interfaces/IFeesEscrow.sol | 4 ++-- contracts/interfaces/IRewardToken.sol | 2 +- contracts/interfaces/IWrapper.sol | 2 +- contracts/pool/FeesEscrow.sol | 15 ++++++--------- contracts/tokens/RewardToken.sol | 4 ++-- deployments/index.js | 15 ++++++--------- hardhat.config.js | 2 +- test/pool/FeesEscrow.test.js | 4 ++-- 9 files changed, 22 insertions(+), 28 deletions(-) diff --git a/contracts/interfaces/IBalancer.sol b/contracts/interfaces/IBalancer.sol index e40287c4..69c457b7 100644 --- a/contracts/interfaces/IBalancer.sol +++ b/contracts/interfaces/IBalancer.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: AGPL-3.0-only +// SPDX-License-Identifier: GPL-3.0-or-later // https://github.com/balancer-labs/balancer-v2-monorepo/blob/master/pkg/interfaces/contracts/vault/IVault.sol pragma solidity 0.7.5; diff --git a/contracts/interfaces/IFeesEscrow.sol b/contracts/interfaces/IFeesEscrow.sol index 9667f281..509bcbb0 100644 --- a/contracts/interfaces/IFeesEscrow.sol +++ b/contracts/interfaces/IFeesEscrow.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: AGPL-3.0-only +// SPDX-License-Identifier: GPL-3.0-or-later pragma solidity 0.7.5; @@ -15,7 +15,7 @@ interface IFeesEscrow { /** * @dev Function is used to transfer accumulated rewards to Pool contract. - * Can only be executed by the RewardEthToken contract. Also, rewards are accumulated + * Can only be executed by the RewardToken contract. Also, rewards are accumulated * in xDAI native tokens, converted to mGNO and transferred to Pool. */ function transferToPool() external returns (uint256); diff --git a/contracts/interfaces/IRewardToken.sol b/contracts/interfaces/IRewardToken.sol index cf7f8596..ca339b05 100644 --- a/contracts/interfaces/IRewardToken.sol +++ b/contracts/interfaces/IRewardToken.sol @@ -73,7 +73,7 @@ interface IRewardToken is IERC20Upgradeable { ) external; /** - * @dev Function for upgrading the RewardEthToken contract. The `initialize` function must be defined + * @dev Function for upgrading the RewardToken contract. The `initialize` function must be defined * if deploying contract for the first time that will initialize the state variables above. * @param _feesEscrow - address of the FeesEscrow contract. */ diff --git a/contracts/interfaces/IWrapper.sol b/contracts/interfaces/IWrapper.sol index a97db12b..9b9fcd27 100644 --- a/contracts/interfaces/IWrapper.sol +++ b/contracts/interfaces/IWrapper.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: AGPL-3.0-only +// SPDX-License-Identifier: GPL-3.0-or-later // https://github.com/gnosis/canonical-weth/blob/master/contracts/WETH9.sol pragma solidity 0.7.5; diff --git a/contracts/pool/FeesEscrow.sol b/contracts/pool/FeesEscrow.sol index 2cdc5f95..2c6f3e87 100644 --- a/contracts/pool/FeesEscrow.sol +++ b/contracts/pool/FeesEscrow.sol @@ -43,14 +43,6 @@ contract FeesEscrow is IFeesEscrow { // @dev mGNO token contract address. address private immutable mGnoToken; - /* - * @dev This struct used only in IBalancerVault.swap method so we decided to - * move it to contract state and make immutable. But immutable and constant - * modifiers are not supported for structs for now, only for primitive types - * and strings - that's why there is no immutable modifier. - */ - IBalancerVault.FundManagement private funds; - constructor( address _pool, address _rewardToken, @@ -69,7 +61,6 @@ contract FeesEscrow is IFeesEscrow { mGnoWrapper = _mGnoWrapper; gnoToken = _gnoToken; mGnoToken = _mGnoToken; - funds = IBalancerVault.FundManagement(address(this), false, address(this), false); } /** @@ -89,6 +80,12 @@ contract FeesEscrow is IFeesEscrow { wrapper.deposit{value: balance}(); // Prepare data to exchange WXDAI to GNO tokens via Balancer Vault + IBalancerVault.FundManagement memory funds = IBalancerVault.FundManagement( + address(this), + false, + address(this), + false + ); IBalancerVault.SingleSwap memory singleSwap = IBalancerVault.SingleSwap( symmetricPoolId, IBalancerVault.SwapKind.GIVEN_IN, diff --git a/contracts/tokens/RewardToken.sol b/contracts/tokens/RewardToken.sol index 264a3957..6282a816 100644 --- a/contracts/tokens/RewardToken.sol +++ b/contracts/tokens/RewardToken.sol @@ -90,7 +90,7 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg } function upgrade(IFeesEscrow _feesEscrow) external override onlyAdmin whenPaused { - require(address(feesEscrow) == address(0), "Pool: FeesEscrow address already set"); + require(address(feesEscrow) == address(0), "RewardToken: FeesEscrow address already set"); feesEscrow = _feesEscrow; } @@ -247,7 +247,7 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg require(msg.sender == oracles, "RewardToken: access denied"); uint256 feesAmount = feesEscrow.transferToPool(); - uint256 periodRewards = newTotalRewards.sub(totalRewards).add(feesAmount); + uint256 periodRewards = newTotalRewards.add(feesAmount).sub(totalRewards); if (periodRewards == 0) { lastUpdateBlockNumber = block.number; emit RewardsUpdated(0, newTotalRewards, rewardPerToken, 0, 0); diff --git a/deployments/index.js b/deployments/index.js index 2dcc9090..51efd226 100644 --- a/deployments/index.js +++ b/deployments/index.js @@ -4,21 +4,18 @@ const { ethers } = require('hardhat'); const SymmetricPoolId = '0x650f5d96e83d3437bf5382558cb31f0ac5536684000200000000000000000001'; -async function upgradeRewardEthToken(feesEscrowContractAddress) { +async function upgradeRewardToken(feesEscrowContractAddress) { const signer = await ethers.provider.getSigner(contractSettings.admin); - const RewardEthToken = await ethers.getContractFactory('RewardToken', signer); - let rewardToken = await RewardEthToken.attach(contracts.rewardToken); + const RewardToken = await ethers.getContractFactory('RewardToken', signer); + let rewardToken = await RewardToken.attach(contracts.rewardToken); // pause if (!(await rewardToken.paused())) { await rewardToken.pause(); } - // upgrade RewardEthToken to new implementation - const proxy = await upgrades.upgradeProxy( - contracts.rewardToken, - RewardEthToken - ); + // upgrade RewardToken to new implementation + const proxy = await upgrades.upgradeProxy(contracts.rewardToken, RewardToken); await proxy.deployed(); // call upgrade @@ -54,7 +51,7 @@ async function deployContracts() { async function upgradeContracts() { const { feesEscrow } = await deployContracts(); - await upgradeRewardEthToken(feesEscrow.address); + await upgradeRewardToken(feesEscrow.address); return { ...contracts, diff --git a/hardhat.config.js b/hardhat.config.js index 198a4b7a..216f8fb0 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -111,7 +111,7 @@ module.exports = { forking: { url: 'https://rpc.gnosischain.com/', chainId: 100, - blockNumber: 23829149, + blockNumber: 23843101, }, accounts: { accountsBalance: '1000000000000000000000000', diff --git a/test/pool/FeesEscrow.test.js b/test/pool/FeesEscrow.test.js index 0782c110..6a7979ce 100644 --- a/test/pool/FeesEscrow.test.js +++ b/test/pool/FeesEscrow.test.js @@ -22,8 +22,8 @@ contract('FeesEscrow', (accounts) => { let upgradedContracts = await upgradeContracts(); const ERC20Mock = await ethers.getContractFactory('ERC20Mock'); - const RewardEthToken = await ethers.getContractFactory('RewardToken'); - rewardToken = await RewardEthToken.attach(upgradedContracts.rewardToken); + const RewardToken = await ethers.getContractFactory('RewardToken'); + rewardToken = await RewardToken.attach(upgradedContracts.rewardToken); pool = await Pool.at(upgradedContracts.pool); gnoToken = await ERC20Mock.attach(contracts.MGNOToken); feesEscrow = await FeesEscrow.at(upgradedContracts.feesEscrow); From 4b39dcc8365338cdeb6d85978a3410e6d64d19dc Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Tue, 23 Aug 2022 07:44:06 +0000 Subject: [PATCH 04/16] Small docstring fixes --- contracts/pool/FeesEscrow.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/pool/FeesEscrow.sol b/contracts/pool/FeesEscrow.sol index 2c6f3e87..d4e1a6f3 100644 --- a/contracts/pool/FeesEscrow.sol +++ b/contracts/pool/FeesEscrow.sol @@ -13,8 +13,8 @@ import "../interfaces/IGNOToken.sol"; /** * @title FeesEscrow * - * @dev FeesEscrow contract is used to receive tips from validators and move them to the Pool contract - * when calling transferToPool method. + * @dev FeesEscrow contract is used to receive tips from validators and transfer + * them to the Pool contract via calling transferToPool method by RewardToken contract. */ contract FeesEscrow is IFeesEscrow { using SafeERC20 for IERC20; @@ -118,7 +118,7 @@ contract FeesEscrow is IFeesEscrow { /** * @dev Allows FeesEscrow contract to receive MEV rewards and priority fees - * from Validators addresses. Later these rewards will be converted to GNO + * from Validators addresses. Later these rewards will be converted to mGNO * and transferred to Pool contract by FeesEscrow.transferToPool method which * is called once a day by RewardToken contract. */ From d70396b8b29b096592a6feef6433616284e956bd Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Tue, 23 Aug 2022 13:28:21 +0000 Subject: [PATCH 05/16] Fixes --- deployments/index.js | 2 +- test/pool/FeesEscrow.test.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/deployments/index.js b/deployments/index.js index 51efd226..15e6ec79 100644 --- a/deployments/index.js +++ b/deployments/index.js @@ -43,7 +43,7 @@ async function deployContracts() { contracts.rewardToken, RewardToken ); - log('Deployed rewardToken implementation contract:', contracts.rewardToken); + log('Deployed RewardToken implementation contract:', contracts.rewardToken); return { feesEscrow, rewardToken }; } diff --git a/test/pool/FeesEscrow.test.js b/test/pool/FeesEscrow.test.js index 6a7979ce..a78c53ab 100644 --- a/test/pool/FeesEscrow.test.js +++ b/test/pool/FeesEscrow.test.js @@ -11,7 +11,7 @@ const FeesEscrow = artifacts.require('FeesEscrow'); let feesEscrow; let pool; let rewardToken; -let gnoToken; +let mgnoToken; contract('FeesEscrow', (accounts) => { let [sender] = accounts; @@ -25,7 +25,7 @@ contract('FeesEscrow', (accounts) => { const RewardToken = await ethers.getContractFactory('RewardToken'); rewardToken = await RewardToken.attach(upgradedContracts.rewardToken); pool = await Pool.at(upgradedContracts.pool); - gnoToken = await ERC20Mock.attach(contracts.MGNOToken); + mgnoToken = await ERC20Mock.attach(contracts.MGNOToken); feesEscrow = await FeesEscrow.at(upgradedContracts.feesEscrow); }); @@ -38,7 +38,7 @@ contract('FeesEscrow', (accounts) => { const oraclesSigner = await ethers.getSigner(contracts.oracles); // Ensure zero balances before miner's reward distribution to FeesEscrow contract - const poolBalanceBefore = await gnoToken.balanceOf(pool.address); + const poolBalanceBefore = await mgnoToken.balanceOf(pool.address); // Fund "Validator" address const validatorReward = ethers.utils.parseEther('10'); @@ -69,14 +69,14 @@ contract('FeesEscrow', (accounts) => { .updateTotalRewards(newTotalRewards); // Ensure Pool GNO balance increased - const poolBalanceAfter = await gnoToken.balanceOf(pool.address); + const poolBalanceAfter = await mgnoToken.balanceOf(pool.address); expect(poolBalanceAfter.gt(poolBalanceBefore)).to.be.true; // FeeEscrow balances should be zero after updateTotalRewards const feesEscrowNativeBalanceAfter = await ethers.provider.getBalance( feesEscrow.address ); - const feesEscrowBalanceAfter = await gnoToken.balanceOf(feesEscrow.address); + const feesEscrowBalanceAfter = await mgnoToken.balanceOf(feesEscrow.address); expect(feesEscrowNativeBalanceAfter.toString()).to.equal('0'); expect(feesEscrowBalanceAfter.toString()).to.equal('0'); From 772253a0a5ad25ae6414512cb9771320ae9cf2b8 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Wed, 24 Aug 2022 18:07:18 +0000 Subject: [PATCH 06/16] blockNumber update & linter fixes --- hardhat.config.js | 2 +- test/pool/FeesEscrow.test.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hardhat.config.js b/hardhat.config.js index 216f8fb0..7ce39ec8 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -111,7 +111,7 @@ module.exports = { forking: { url: 'https://rpc.gnosischain.com/', chainId: 100, - blockNumber: 23843101, + blockNumber: 23867985, }, accounts: { accountsBalance: '1000000000000000000000000', diff --git a/test/pool/FeesEscrow.test.js b/test/pool/FeesEscrow.test.js index a78c53ab..e78f7314 100644 --- a/test/pool/FeesEscrow.test.js +++ b/test/pool/FeesEscrow.test.js @@ -76,7 +76,9 @@ contract('FeesEscrow', (accounts) => { const feesEscrowNativeBalanceAfter = await ethers.provider.getBalance( feesEscrow.address ); - const feesEscrowBalanceAfter = await mgnoToken.balanceOf(feesEscrow.address); + const feesEscrowBalanceAfter = await mgnoToken.balanceOf( + feesEscrow.address + ); expect(feesEscrowNativeBalanceAfter.toString()).to.equal('0'); expect(feesEscrowBalanceAfter.toString()).to.equal('0'); From 2ddb8a8bd80105b2e7209fe415217971045c3e19 Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Thu, 25 Aug 2022 14:13:28 +0300 Subject: [PATCH 07/16] Remove unused initialize method --- abi/IPool.json | 32 ---------------------- abi/IRewardToken.json | 38 --------------------------- abi/Pool.json | 32 ---------------------- abi/RewardToken.json | 38 --------------------------- contracts/interfaces/IFeesEscrow.sol | 4 +-- contracts/interfaces/IPool.sol | 14 ---------- contracts/interfaces/IRewardToken.sol | 18 ------------- contracts/pool/FeesEscrow.sol | 33 +++++++++++------------ contracts/pool/Pool.sol | 8 ------ contracts/tokens/RewardToken.sol | 37 +------------------------- 10 files changed, 19 insertions(+), 235 deletions(-) diff --git a/abi/IPool.json b/abi/IPool.json index 0c54eb6a..a3274d3a 100644 --- a/abi/IPool.json +++ b/abi/IPool.json @@ -112,25 +112,6 @@ "name": "PendingValidatorsLimitUpdated", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Refunded", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -438,19 +419,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "refund", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { diff --git a/abi/IRewardToken.json b/abi/IRewardToken.json index ed1fe1e6..afcbf47b 100644 --- a/abi/IRewardToken.json +++ b/abi/IRewardToken.json @@ -240,44 +240,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "admin", - "type": "address" - }, - { - "internalType": "address", - "name": "_stakedToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_oracles", - "type": "address" - }, - { - "internalType": "address", - "name": "_protocolFeeRecipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_protocolFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_merkleDistributor", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "lastUpdateBlockNumber", diff --git a/abi/Pool.json b/abi/Pool.json index 38420592..2534252c 100644 --- a/abi/Pool.json +++ b/abi/Pool.json @@ -125,25 +125,6 @@ "name": "PendingValidatorsLimitUpdated", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "Refunded", - "type": "event" - }, { "anonymous": false, "inputs": [ @@ -753,19 +734,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "refund", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { diff --git a/abi/RewardToken.json b/abi/RewardToken.json index 3dab5cf6..031fdbde 100644 --- a/abi/RewardToken.json +++ b/abi/RewardToken.json @@ -571,44 +571,6 @@ "stateMutability": "nonpayable", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "admin", - "type": "address" - }, - { - "internalType": "address", - "name": "_stakedToken", - "type": "address" - }, - { - "internalType": "address", - "name": "_oracles", - "type": "address" - }, - { - "internalType": "address", - "name": "_protocolFeeRecipient", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_protocolFee", - "type": "uint256" - }, - { - "internalType": "address", - "name": "_merkleDistributor", - "type": "address" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [ { diff --git a/contracts/interfaces/IFeesEscrow.sol b/contracts/interfaces/IFeesEscrow.sol index 509bcbb0..d45d3f8b 100644 --- a/contracts/interfaces/IFeesEscrow.sol +++ b/contracts/interfaces/IFeesEscrow.sol @@ -9,9 +9,9 @@ interface IFeesEscrow { /** * @dev Event for tracking fees withdrawals to Pool contract. * @param amountDAI - an amount of rewards before swap to GNO via Balancer Vault. - * @param amountMGNO - an amount of rewards after swap. + * @param amountGNO - an amount of rewards after swap. */ - event FeesTransferred(uint256 amountDAI, uint256 amountMGNO); + event FeesTransferred(uint256 amountDAI, uint256 amountGNO); /** * @dev Function is used to transfer accumulated rewards to Pool contract. diff --git a/contracts/interfaces/IPool.sol b/contracts/interfaces/IPool.sol index f73eeba9..f6696622 100644 --- a/contracts/interfaces/IPool.sol +++ b/contracts/interfaces/IPool.sol @@ -17,13 +17,6 @@ interface IPool { */ event ValidatorRegistered(bytes publicKey, address operator); - /** - * @dev Event for tracking refunds. - * @param sender - address of the refund sender. - * @param amount - refunded amount. - */ - event Refunded(address indexed sender, uint256 amount); - /** * @dev Event for tracking scheduled deposit activation. * @param sender - address of the deposit sender. @@ -263,11 +256,4 @@ interface IPool { * @param depositData - the deposit data to submit for the validator. */ function registerValidator(IPoolValidators.DepositData calldata depositData) external; - - /** - * @dev Function for refunding to the pool. - * Can only be executed by the account with admin role. - * @param amount - the amount of mGNO tokens to refund. - */ - function refund(uint256 amount) external; } diff --git a/contracts/interfaces/IRewardToken.sol b/contracts/interfaces/IRewardToken.sol index ca339b05..c11df8f6 100644 --- a/contracts/interfaces/IRewardToken.sol +++ b/contracts/interfaces/IRewardToken.sol @@ -54,24 +54,6 @@ interface IRewardToken is IERC20Upgradeable { uint256 protocolReward ); - /** - * @dev Function for initializing the RewardToken contract. - * @param admin - address of the contract admin. - * @param _stakedToken - address of the StakedToken contract. - * @param _oracles - address of the Oracles contract. - * @param _protocolFeeRecipient - address of the protocol fee recipient. - * @param _protocolFee - protocol fee. - * @param _merkleDistributor - address of the MerkleDistributor contract. - */ - function initialize( - address admin, - address _stakedToken, - address _oracles, - address _protocolFeeRecipient, - uint256 _protocolFee, - address _merkleDistributor - ) external; - /** * @dev Function for upgrading the RewardToken contract. The `initialize` function must be defined * if deploying contract for the first time that will initialize the state variables above. diff --git a/contracts/pool/FeesEscrow.sol b/contracts/pool/FeesEscrow.sol index d4e1a6f3..3fb37878 100644 --- a/contracts/pool/FeesEscrow.sol +++ b/contracts/pool/FeesEscrow.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-3.0-or-later +// SPDX-License-Identifier: AGPL-3.0-only pragma solidity 0.7.5; pragma abicoder v2; @@ -14,7 +14,7 @@ import "../interfaces/IGNOToken.sol"; * @title FeesEscrow * * @dev FeesEscrow contract is used to receive tips from validators and transfer - * them to the Pool contract via calling transferToPool method by RewardToken contract. + * them to the Pool contract via calling transferToPool method from the RewardToken contract. */ contract FeesEscrow is IFeesEscrow { using SafeERC20 for IERC20; @@ -41,7 +41,7 @@ contract FeesEscrow is IFeesEscrow { address private immutable gnoToken; // @dev mGNO token contract address. - address private immutable mGnoToken; + IERC20 private immutable mGnoToken; constructor( address _pool, @@ -51,7 +51,7 @@ contract FeesEscrow is IFeesEscrow { IWrapper _wrapper, address _mGnoWrapper, address _gnoToken, - address _mGnoToken + IERC20 _mGnoToken ) { pool = _pool; rewardToken = _rewardToken; @@ -80,12 +80,6 @@ contract FeesEscrow is IFeesEscrow { wrapper.deposit{value: balance}(); // Prepare data to exchange WXDAI to GNO tokens via Balancer Vault - IBalancerVault.FundManagement memory funds = IBalancerVault.FundManagement( - address(this), - false, - address(this), - false - ); IBalancerVault.SingleSwap memory singleSwap = IBalancerVault.SingleSwap( symmetricPoolId, IBalancerVault.SwapKind.GIVEN_IN, @@ -99,6 +93,12 @@ contract FeesEscrow is IFeesEscrow { IERC20(address(wrapper)).safeApprove(address(symmetricVault), balance); // Now we are ready to exchange WXDAI token to GNO + IBalancerVault.FundManagement memory funds = IBalancerVault.FundManagement( + address(this), + false, + address(this), + false + ); uint amountGnoOut = symmetricVault.swap(singleSwap, funds, 0, type(uint).max); // Convert GNO tokens to mGNO @@ -106,10 +106,10 @@ contract FeesEscrow is IFeesEscrow { bool success = IGNOToken(gnoToken).transferAndCall(mGnoWrapper, amountGnoOut, ""); require(success, "FeesEscrow: failed to convert tokens"); - uint mGnoBalance = IERC20(mGnoToken).balanceOf(address(this)); + uint mGnoBalance = mGnoToken.balanceOf(address(this)); - // Transferring obtained ÑŒGNO amount to Pool contract - IERC20(mGnoToken).safeTransfer(pool, mGnoBalance); + // Transferring obtained mGNO amount to Pool contract + mGnoToken.safeTransfer(pool, mGnoBalance); emit FeesTransferred(balance, amountGnoOut); @@ -117,10 +117,9 @@ contract FeesEscrow is IFeesEscrow { } /** - * @dev Allows FeesEscrow contract to receive MEV rewards and priority fees - * from Validators addresses. Later these rewards will be converted to mGNO - * and transferred to Pool contract by FeesEscrow.transferToPool method which - * is called once a day by RewardToken contract. + * @dev Allows FeesEscrow contract to receive MEV rewards and priority fees. + * Later these rewards will be converted to mGNO and transferred to Pool contract by + * `FeesEscrow.transferToPool` method which is called once a day by the `RewardToken` contract. */ receive() external payable {} } diff --git a/contracts/pool/Pool.sol b/contracts/pool/Pool.sol index ba6b2350..b137618b 100644 --- a/contracts/pool/Pool.sol +++ b/contracts/pool/Pool.sol @@ -364,12 +364,4 @@ contract Pool is IPool, OwnablePausableUpgradeable { VALIDATOR_TOTAL_DEPOSIT ); } - - /** - * @dev See {IPool-refund}. - */ - function refund(uint256 amount) external override onlyAdmin { - IERC20Upgradeable(MGNO_TOKEN).safeTransferFrom(msg.sender, address(this), amount); - emit Refunded(msg.sender, amount); - } } diff --git a/contracts/tokens/RewardToken.sol b/contracts/tokens/RewardToken.sol index 6282a816..53c67c6f 100644 --- a/contracts/tokens/RewardToken.sol +++ b/contracts/tokens/RewardToken.sol @@ -55,40 +55,6 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg // @dev Address of the FeesEscrow contract. IFeesEscrow private feesEscrow; - /** - * @dev See {IRewardToken-initialize}. - */ - function initialize( - address admin, - address _stakedToken, - address _oracles, - address _protocolFeeRecipient, - uint256 _protocolFee, - address _merkleDistributor - ) - external override initializer - { - require(admin != address(0), "RewardToken: invalid admin address"); - require(_stakedToken != address(0), "RewardToken: invalid StakedToken address"); - require(_oracles != address(0), "RewardToken: invalid Oracles address"); - require(_protocolFee < 1e4, "RewardToken: invalid protocol fee"); - require(_merkleDistributor != address(0), "RewardToken: invalid MerkleDistributor address"); - - __OwnablePausableUpgradeable_init(admin); - __ERC20_init("StakeWise Reward GNO", "rGNO"); - __ERC20Permit_init("StakeWise Reward GNO"); - - stakedToken = IStakedToken(_stakedToken); - oracles = _oracles; - merkleDistributor = _merkleDistributor; - - protocolFeeRecipient = _protocolFeeRecipient; - emit ProtocolFeeRecipientUpdated(_protocolFeeRecipient); - - protocolFee = _protocolFee; - emit ProtocolFeeUpdated(_protocolFee); - } - function upgrade(IFeesEscrow _feesEscrow) external override onlyAdmin whenPaused { require(address(feesEscrow) == address(0), "RewardToken: FeesEscrow address already set"); @@ -246,8 +212,7 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg function updateTotalRewards(uint256 newTotalRewards) external override { require(msg.sender == oracles, "RewardToken: access denied"); - uint256 feesAmount = feesEscrow.transferToPool(); - uint256 periodRewards = newTotalRewards.add(feesAmount).sub(totalRewards); + uint256 periodRewards = newTotalRewards.add(feesEscrow.transferToPool()).sub(totalRewards); if (periodRewards == 0) { lastUpdateBlockNumber = block.number; emit RewardsUpdated(0, newTotalRewards, rewardPerToken, 0, 0); From c38f9be7b8122ed2a5b3a0d9d394ec72be2ba0bf Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Thu, 25 Aug 2022 14:14:25 +0300 Subject: [PATCH 08/16] Remove refund test --- test/pool/stake.test.js | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/test/pool/stake.test.js b/test/pool/stake.test.js index 43df8ef6..1d8d8686 100644 --- a/test/pool/stake.test.js +++ b/test/pool/stake.test.js @@ -19,7 +19,6 @@ const { upgradeContracts } = require('../../deployments'); const { contractSettings, contracts } = require('../../deployments/settings'); const { checkStakedToken, - mintMGNOTokens, stakeGNO, stakeMGNO, stakeGNOWithPermit, @@ -824,30 +823,4 @@ contract('Pool (stake)', (accounts) => { 'Pool: access denied' ); }); - - it('not admin cannot refund', async () => { - let amount = ether('10'); - await mintMGNOTokens(sender1, amount); - await expectRevert( - pool.refund(amount, { - from: sender1, - }), - 'OwnablePausable: access denied' - ); - }); - - it('admin can refund', async () => { - let amount = ether('10'); - await send.ether(otherAccounts[0], admin, ether('3000')); - await mintMGNOTokens(admin, amount); - await mgnoToken.approve(pool.address, amount, { from: admin }); - - let receipt = await pool.refund(amount, { - from: admin, - }); - await expectEvent(receipt, 'Refunded', { - sender: admin, - amount, - }); - }); }); From 613571078d4dc7dafadfe087f497a6ec90cad89b Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Thu, 25 Aug 2022 14:17:59 +0300 Subject: [PATCH 09/16] Update block number --- hardhat.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardhat.config.js b/hardhat.config.js index 7ce39ec8..271fbbf7 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -111,7 +111,7 @@ module.exports = { forking: { url: 'https://rpc.gnosischain.com/', chainId: 100, - blockNumber: 23867985, + blockNumber: 23880400, }, accounts: { accountsBalance: '1000000000000000000000000', From 6fdfba49ee97cdf30c61453765136da7efab1794 Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Thu, 25 Aug 2022 14:23:42 +0300 Subject: [PATCH 10/16] Update deployments --- deployments/index.js | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/deployments/index.js b/deployments/index.js index 15e6ec79..cd1ec485 100644 --- a/deployments/index.js +++ b/deployments/index.js @@ -1,5 +1,12 @@ +const { white, green } = require('chalk'); +const { ethers, upgrades, config } = require('hardhat'); const { contracts, contractSettings } = require('./settings'); -const { ethers } = require('hardhat'); + +function log(message) { + if (config != null && config.suppressLogs !== true) { + console.log(message); + } +} const SymmetricPoolId = '0x650f5d96e83d3437bf5382558cb31f0ac5536684000200000000000000000001'; @@ -36,26 +43,29 @@ async function deployContracts() { contracts.GNOToken, contracts.MGNOToken ); - log('Deployed FeesEscrow contract:', feesEscrow.address); + log(white(`Deployed FeesEscrow contract: ${green(feesEscrow.address)}`)); const RewardToken = await ethers.getContractFactory('RewardToken'); const rewardToken = await upgrades.prepareUpgrade( contracts.rewardToken, RewardToken ); - log('Deployed RewardToken implementation contract:', contracts.rewardToken); + log( + white(`Deployed RewardToken implementation contract: ${green(rewardToken)}`) + ); - return { feesEscrow, rewardToken }; + return { feesEscrow: feesEscrow.address, rewardToken }; } async function upgradeContracts() { const { feesEscrow } = await deployContracts(); - await upgradeRewardToken(feesEscrow.address); + await upgradeRewardToken(feesEscrow); + log(white('Upgraded RewardToken contract')); return { ...contracts, - feesEscrow: feesEscrow.address, + feesEscrow, }; } From 0eee77a7a448ad0ff9ca76382ba3c5d8c6ff89b0 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Thu, 25 Aug 2022 12:30:24 +0000 Subject: [PATCH 11/16] fixes --- contracts/interfaces/IPool.sol | 14 ++++++++++++++ contracts/pool/Pool.sol | 8 ++++++++ test/pool/stake.test.js | 26 ++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/contracts/interfaces/IPool.sol b/contracts/interfaces/IPool.sol index f6696622..8c3f6ba4 100644 --- a/contracts/interfaces/IPool.sol +++ b/contracts/interfaces/IPool.sol @@ -17,6 +17,13 @@ interface IPool { */ event ValidatorRegistered(bytes publicKey, address operator); + /** + * @dev Event for tracking refunds. + * @param sender - address of the refund sender. + * @param amount - refunded amount. + */ + event Refunded(address indexed sender, uint256 amount); + /** * @dev Event for tracking scheduled deposit activation. * @param sender - address of the deposit sender. @@ -251,6 +258,13 @@ interface IPool { */ function activateMultiple(address account, uint256[] calldata validatorIndexes) external; + /** + * @dev Function for refunding to the pool. + * Can only be executed by the account with admin role. + * @param amount - the amount of mGNO tokens to refund. + */ + function refund(uint256 amount) external; + /** * @dev Function for registering new pool validator registration. * @param depositData - the deposit data to submit for the validator. diff --git a/contracts/pool/Pool.sol b/contracts/pool/Pool.sol index b137618b..ba6b2350 100644 --- a/contracts/pool/Pool.sol +++ b/contracts/pool/Pool.sol @@ -364,4 +364,12 @@ contract Pool is IPool, OwnablePausableUpgradeable { VALIDATOR_TOTAL_DEPOSIT ); } + + /** + * @dev See {IPool-refund}. + */ + function refund(uint256 amount) external override onlyAdmin { + IERC20Upgradeable(MGNO_TOKEN).safeTransferFrom(msg.sender, address(this), amount); + emit Refunded(msg.sender, amount); + } } diff --git a/test/pool/stake.test.js b/test/pool/stake.test.js index 1d8d8686..47be21de 100644 --- a/test/pool/stake.test.js +++ b/test/pool/stake.test.js @@ -823,4 +823,30 @@ contract('Pool (stake)', (accounts) => { 'Pool: access denied' ); }); + + it('not admin cannot refund', async () => { + let amount = ether('10'); + await mintMGNOTokens(sender1, amount); + await expectRevert( + pool.refund(amount, { + from: sender1, + }), + 'OwnablePausable: access denied' + ); + }); + + it('admin can refund', async () => { + let amount = ether('10'); + await send.ether(otherAccounts[0], admin, ether('3000')); + await mintMGNOTokens(admin, amount); + await mgnoToken.approve(pool.address, amount, { from: admin }); + + let receipt = await pool.refund(amount, { + from: admin, + }); + await expectEvent(receipt, 'Refunded', { + sender: admin, + amount, + }); + }); }); From c414563370cfe39ac3b830405fb0902d9202f5e4 Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Thu, 25 Aug 2022 12:38:34 +0000 Subject: [PATCH 12/16] fixes --- test/pool/stake.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/pool/stake.test.js b/test/pool/stake.test.js index 47be21de..86d37de3 100644 --- a/test/pool/stake.test.js +++ b/test/pool/stake.test.js @@ -22,6 +22,7 @@ const { stakeGNO, stakeMGNO, stakeGNOWithPermit, + mintMGNOTokens, } = require('../utils'); const { depositData, From 0f65f25786843cdeef71c80f881ac4d8e86c41bf Mon Sep 17 00:00:00 2001 From: Dmitry Pavlov Date: Thu, 25 Aug 2022 12:43:00 +0000 Subject: [PATCH 13/16] new rpc node url --- hardhat.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardhat.config.js b/hardhat.config.js index 271fbbf7..4a53ab08 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -109,7 +109,7 @@ module.exports = { networks: { hardhat: { forking: { - url: 'https://rpc.gnosischain.com/', + url: 'https://gnosis.public-rpc.com/', chainId: 100, blockNumber: 23880400, }, From 3a5d7c9fab8eea284f413e2e0b0a86d85936c990 Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Fri, 2 Sep 2022 11:56:13 +0300 Subject: [PATCH 14/16] Fix fees transferred event --- abi/FeesEscrow.json | 78 ++++++++++++++++++++++++++++ abi/IFeesEscrow.json | 28 ++++++++++ abi/IPool.json | 32 ++++++++++++ abi/Pool.json | 32 ++++++++++++ contracts/interfaces/IFeesEscrow.sol | 5 +- contracts/pool/FeesEscrow.sol | 2 +- hardhat.config.js | 1 + 7 files changed, 174 insertions(+), 4 deletions(-) create mode 100644 abi/FeesEscrow.json create mode 100644 abi/IFeesEscrow.json diff --git a/abi/FeesEscrow.json b/abi/FeesEscrow.json new file mode 100644 index 00000000..c672d73f --- /dev/null +++ b/abi/FeesEscrow.json @@ -0,0 +1,78 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_symmetricPoolId", + "type": "bytes32" + }, + { + "internalType": "contract IBalancerVault", + "name": "_symmetricVault", + "type": "address" + }, + { + "internalType": "contract IWrapper", + "name": "_wrapper", + "type": "address" + }, + { + "internalType": "address", + "name": "_mGnoWrapper", + "type": "address" + }, + { + "internalType": "address", + "name": "_gnoToken", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_mGnoToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FeesTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "transferToPool", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/abi/IFeesEscrow.json b/abi/IFeesEscrow.json new file mode 100644 index 00000000..de112b4a --- /dev/null +++ b/abi/IFeesEscrow.json @@ -0,0 +1,28 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "FeesTransferred", + "type": "event" + }, + { + "inputs": [], + "name": "transferToPool", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IPool.json b/abi/IPool.json index a3274d3a..0c54eb6a 100644 --- a/abi/IPool.json +++ b/abi/IPool.json @@ -112,6 +112,25 @@ "name": "PendingValidatorsLimitUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Refunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -419,6 +438,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "refund", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/abi/Pool.json b/abi/Pool.json index 2534252c..38420592 100644 --- a/abi/Pool.json +++ b/abi/Pool.json @@ -125,6 +125,25 @@ "name": "PendingValidatorsLimitUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Refunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -734,6 +753,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "refund", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/contracts/interfaces/IFeesEscrow.sol b/contracts/interfaces/IFeesEscrow.sol index d45d3f8b..a3419aa1 100644 --- a/contracts/interfaces/IFeesEscrow.sol +++ b/contracts/interfaces/IFeesEscrow.sol @@ -8,10 +8,9 @@ pragma solidity 0.7.5; interface IFeesEscrow { /** * @dev Event for tracking fees withdrawals to Pool contract. - * @param amountDAI - an amount of rewards before swap to GNO via Balancer Vault. - * @param amountGNO - an amount of rewards after swap. + * @param amount - the number of fees. */ - event FeesTransferred(uint256 amountDAI, uint256 amountGNO); + event FeesTransferred(uint256 amount); /** * @dev Function is used to transfer accumulated rewards to Pool contract. diff --git a/contracts/pool/FeesEscrow.sol b/contracts/pool/FeesEscrow.sol index 3fb37878..14ebdca3 100644 --- a/contracts/pool/FeesEscrow.sol +++ b/contracts/pool/FeesEscrow.sol @@ -111,7 +111,7 @@ contract FeesEscrow is IFeesEscrow { // Transferring obtained mGNO amount to Pool contract mGnoToken.safeTransfer(pool, mGnoBalance); - emit FeesTransferred(balance, amountGnoOut); + emit FeesTransferred(amountGnoOut); return amountGnoOut; } diff --git a/hardhat.config.js b/hardhat.config.js index 4a53ab08..3afb442f 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -147,6 +147,7 @@ module.exports = { 'MerkleDistributor', 'ContractChecker', 'Roles', + 'FeesEscrow', ], clear: true, flat: true, From 9ea26352ab31bf0137a7b61026bfb940306071a2 Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Thu, 15 Sep 2022 20:24:26 +0300 Subject: [PATCH 15/16] Fix total supply --- contracts/tokens/RewardToken.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/tokens/RewardToken.sol b/contracts/tokens/RewardToken.sol index 53c67c6f..cdc3e09b 100644 --- a/contracts/tokens/RewardToken.sol +++ b/contracts/tokens/RewardToken.sol @@ -212,7 +212,8 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg function updateTotalRewards(uint256 newTotalRewards) external override { require(msg.sender == oracles, "RewardToken: access denied"); - uint256 periodRewards = newTotalRewards.add(feesEscrow.transferToPool()).sub(totalRewards); + newTotalRewards = newTotalRewards.add(feesEscrow.transferToPool()); + uint256 periodRewards = newTotalRewards.sub(totalRewards); if (periodRewards == 0) { lastUpdateBlockNumber = block.number; emit RewardsUpdated(0, newTotalRewards, rewardPerToken, 0, 0); From 0724fd6cd154147006efa54823b0c58071af3ee5 Mon Sep 17 00:00:00 2001 From: Dmitri Tsumak Date: Fri, 16 Sep 2022 14:38:45 +0300 Subject: [PATCH 16/16] Upload updated security audit --- audits/2022-09-16-Pessimistic.pdf | Bin 0 -> 245392 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 audits/2022-09-16-Pessimistic.pdf diff --git a/audits/2022-09-16-Pessimistic.pdf b/audits/2022-09-16-Pessimistic.pdf new file mode 100644 index 0000000000000000000000000000000000000000..3aec07ebc0b49c5e4fe0d7199c887a6a87952f77 GIT binary patch literal 245392 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�z2!bv+DcG*MX=-#%gszTs5gk> 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