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/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/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..afcbf47b --- /dev/null +++ b/abi/IRewardToken.json @@ -0,0 +1,524 @@ +[ + { + "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": [], + "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": "contract IFeesEscrow", + "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..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": [ { @@ -1091,5 +1053,18 @@ "outputs": [], "stateMutability": "nonpayable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IFeesEscrow", + "name": "_feesEscrow", + "type": "address" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ] diff --git a/audits/2022-09-16-Pessimistic.pdf b/audits/2022-09-16-Pessimistic.pdf new file mode 100644 index 00000000..3aec07eb Binary files /dev/null and b/audits/2022-09-16-Pessimistic.pdf differ diff --git a/contracts/interfaces/IBalancer.sol b/contracts/interfaces/IBalancer.sol new file mode 100644 index 00000000..69c457b7 --- /dev/null +++ b/contracts/interfaces/IBalancer.sol @@ -0,0 +1,73 @@ +// 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; +pragma abicoder v2; + +// 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 } + + /** + * @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; + } + + /** + * @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..a3419aa1 --- /dev/null +++ b/contracts/interfaces/IFeesEscrow.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +pragma solidity 0.7.5; + +/** + * @dev Interface of the FeesEscrow contract. + */ +interface IFeesEscrow { + /** + * @dev Event for tracking fees withdrawals to Pool contract. + * @param amount - the number of fees. + */ + event FeesTransferred(uint256 amount); + + /** + * @dev Function is used to transfer accumulated rewards to Pool contract. + * 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/IPool.sol b/contracts/interfaces/IPool.sol index f73eeba9..8c3f6ba4 100644 --- a/contracts/interfaces/IPool.sol +++ b/contracts/interfaces/IPool.sol @@ -258,16 +258,16 @@ interface IPool { */ function activateMultiple(address account, uint256[] calldata validatorIndexes) external; - /** - * @dev Function for registering new pool validator registration. - * @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; + + /** + * @dev Function for registering new pool validator registration. + * @param depositData - the deposit data to submit for the validator. + */ + function registerValidator(IPoolValidators.DepositData calldata depositData) external; } diff --git a/contracts/interfaces/IRewardToken.sol b/contracts/interfaces/IRewardToken.sol index 5ca9200f..c11df8f6 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. @@ -54,22 +55,11 @@ interface IRewardToken is IERC20Upgradeable { ); /** - * @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. + * @param _feesEscrow - address of the FeesEscrow contract. + */ + function upgrade(IFeesEscrow _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..9b9fcd27 --- /dev/null +++ b/contracts/interfaces/IWrapper.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// 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..14ebdca3 --- /dev/null +++ b/contracts/pool/FeesEscrow.sol @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: AGPL-3.0-only + +pragma solidity 0.7.5; +pragma abicoder v2; + +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 + * + * @dev FeesEscrow contract is used to receive tips from validators and transfer + * them to the Pool contract via calling transferToPool method from the RewardToken contract. + */ +contract FeesEscrow is IFeesEscrow { + using SafeERC20 for IERC20; + + // @dev Pool contract's address. + address private immutable pool; + + // @dev RewardToken contract's address. + address private immutable rewardToken; + + // @dev Balancer pool id for Symmetric Vault. + bytes32 private immutable symmetricPoolId; + + // @dev Symmetric Balancer Vault contract address. + IBalancerVault private immutable symmetricVault; + + // @dev Native xDAI wrapper contract address. + IWrapper private immutable wrapper; + + // @dev GNO to mGNO wrapper contract address. + address private immutable mGnoWrapper; + + // @dev GNO token contract address. + address private immutable gnoToken; + + // @dev mGNO token contract address. + IERC20 private immutable mGnoToken; + + constructor( + address _pool, + address _rewardToken, + bytes32 _symmetricPoolId, + IBalancerVault _symmetricVault, + IWrapper _wrapper, + address _mGnoWrapper, + address _gnoToken, + IERC20 _mGnoToken + ) { + pool = _pool; + rewardToken = _rewardToken; + symmetricPoolId = _symmetricPoolId; + symmetricVault = _symmetricVault; + wrapper = _wrapper; + mGnoWrapper = _mGnoWrapper; + gnoToken = _gnoToken; + mGnoToken = _mGnoToken; + } + + /** + * @dev See {IFeesEscrow-transferToPool}. + */ + function transferToPool() external override returns (uint256) { + require(msg.sender == rewardToken, "FeesEscrow: invalid caller"); + + // Fetch current native xDAI balance to be wrapped next + uint256 balance = address(this).balance; + + if (balance == 0) { + return 0; + } + + // Wrap all accumulated native xDAI tokens to WXDAI + wrapper.deposit{value: balance}(); + + // Prepare data to exchange WXDAI to GNO tokens via Balancer Vault + IBalancerVault.SingleSwap memory singleSwap = IBalancerVault.SingleSwap( + symmetricPoolId, + IBalancerVault.SwapKind.GIVEN_IN, + address(wrapper), + gnoToken, + balance, + new bytes(0) + ); + + // It's very important to approve WXDAI from FeesEscrow to Balancer Vault's without infinity approve + 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 + IERC20(gnoToken).safeApprove(mGnoWrapper, amountGnoOut); + bool success = IGNOToken(gnoToken).transferAndCall(mGnoWrapper, amountGnoOut, ""); + require(success, "FeesEscrow: failed to convert tokens"); + + uint mGnoBalance = mGnoToken.balanceOf(address(this)); + + // Transferring obtained mGNO amount to Pool contract + mGnoToken.safeTransfer(pool, mGnoBalance); + + emit FeesTransferred(amountGnoOut); + + return amountGnoOut; + } + + /** + * @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/tokens/RewardToken.sol b/contracts/tokens/RewardToken.sol index 8722a995..cdc3e09b 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,38 +52,13 @@ 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 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"); + // @dev Address of the FeesEscrow contract. + IFeesEscrow private feesEscrow; - __OwnablePausableUpgradeable_init(admin); - __ERC20_init("StakeWise Reward GNO", "rGNO"); - __ERC20Permit_init("StakeWise Reward GNO"); + function upgrade(IFeesEscrow _feesEscrow) external override onlyAdmin whenPaused { + require(address(feesEscrow) == address(0), "RewardToken: FeesEscrow address already set"); - stakedToken = IStakedToken(_stakedToken); - oracles = _oracles; - merkleDistributor = _merkleDistributor; - - protocolFeeRecipient = _protocolFeeRecipient; - emit ProtocolFeeRecipientUpdated(_protocolFeeRecipient); - - protocolFee = _protocolFee; - emit ProtocolFeeUpdated(_protocolFee); + feesEscrow = _feesEscrow; } /** @@ -236,6 +212,7 @@ contract RewardToken is IRewardToken, OwnablePausableUpgradeable, ERC20PermitUpg function updateTotalRewards(uint256 newTotalRewards) external override { require(msg.sender == oracles, "RewardToken: access denied"); + newTotalRewards = newTotalRewards.add(feesEscrow.transferToPool()); uint256 periodRewards = newTotalRewards.sub(totalRewards); if (periodRewards == 0) { lastUpdateBlockNumber = block.number; diff --git a/deployments/index.js b/deployments/index.js index 83339ee5..cd1ec485 100644 --- a/deployments/index.js +++ b/deployments/index.js @@ -1,11 +1,72 @@ -const { contracts } = require('./settings'); +const { white, green } = require('chalk'); +const { ethers, upgrades, config } = require('hardhat'); +const { contracts, contractSettings } = require('./settings'); + +function log(message) { + if (config != null && config.suppressLogs !== true) { + console.log(message); + } +} + +const SymmetricPoolId = + '0x650f5d96e83d3437bf5382558cb31f0ac5536684000200000000000000000001'; + +async function upgradeRewardToken(feesEscrowContractAddress) { + const signer = await ethers.provider.getSigner(contractSettings.admin); + const RewardToken = await ethers.getContractFactory('RewardToken', signer); + let rewardToken = await RewardToken.attach(contracts.rewardToken); + + // pause + if (!(await rewardToken.paused())) { + await rewardToken.pause(); + } + + // upgrade RewardToken to new implementation + const proxy = await upgrades.upgradeProxy(contracts.rewardToken, RewardToken); + 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.MGNOWrapper, + contracts.GNOToken, + contracts.MGNOToken + ); + log(white(`Deployed FeesEscrow contract: ${green(feesEscrow.address)}`)); + + const RewardToken = await ethers.getContractFactory('RewardToken'); + const rewardToken = await upgrades.prepareUpgrade( + contracts.rewardToken, + RewardToken + ); + log( + white(`Deployed RewardToken implementation contract: ${green(rewardToken)}`) + ); + + return { feesEscrow: feesEscrow.address, rewardToken }; } async function upgradeContracts() { - return contracts; + const { feesEscrow } = await deployContracts(); + + await upgradeRewardToken(feesEscrow); + log(white('Upgraded RewardToken contract')); + + return { + ...contracts, + feesEscrow, + }; } module.exports = { diff --git a/deployments/settings.js b/deployments/settings.js index b9eef3ae..491e5c87 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..3afb442f 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://gnosis.public-rpc.com/', chainId: 100, + blockNumber: 23880400, }, accounts: { accountsBalance: '1000000000000000000000000', @@ -146,6 +147,7 @@ module.exports = { 'MerkleDistributor', 'ContractChecker', 'Roles', + 'FeesEscrow', ], clear: true, flat: true, diff --git a/test/pool/FeesEscrow.test.js b/test/pool/FeesEscrow.test.js new file mode 100644 index 00000000..e78f7314 --- /dev/null +++ b/test/pool/FeesEscrow.test.js @@ -0,0 +1,100 @@ +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 mgnoToken; + +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 RewardToken = await ethers.getContractFactory('RewardToken'); + rewardToken = await RewardToken.attach(upgradedContracts.rewardToken); + pool = await Pool.at(upgradedContracts.pool); + mgnoToken = await ERC20Mock.attach(contracts.MGNOToken); + 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 mgnoToken.balanceOf(pool.address); + + // Fund "Validator" address + const validatorReward = ethers.utils.parseEther('10'); + 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 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 mgnoToken.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' + ); + }); +}); diff --git a/test/pool/stake.test.js b/test/pool/stake.test.js index 43df8ef6..86d37de3 100644 --- a/test/pool/stake.test.js +++ b/test/pool/stake.test.js @@ -19,10 +19,10 @@ const { upgradeContracts } = require('../../deployments'); const { contractSettings, contracts } = require('../../deployments/settings'); const { checkStakedToken, - mintMGNOTokens, stakeGNO, stakeMGNO, stakeGNOWithPermit, + mintMGNOTokens, } = require('../utils'); const { depositData,