|
| 1 | +// SPDX-License-Identifier: MIT |
| 2 | +pragma solidity ^0.8.20; |
| 3 | + |
| 4 | +import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; |
| 5 | + |
| 6 | +library TransferHelper { |
| 7 | + function safeTransfer(address token, address to, uint256 value) internal { |
| 8 | + // bytes4(keccak256(bytes('transfer(address,uint256)'))); |
| 9 | + (bool success, bytes memory data) = token.call( |
| 10 | + abi.encodeWithSelector(0xa9059cbb, to, value) |
| 11 | + ); |
| 12 | + require( |
| 13 | + success && (data.length == 0 || abi.decode(data, (bool))), |
| 14 | + "safeTransfer: transfer failed" |
| 15 | + ); |
| 16 | + } |
| 17 | + |
| 18 | + function safeTransferETH(address to, uint256 value) internal { |
| 19 | + (bool success, ) = to.call{value: value}(new bytes(0)); |
| 20 | + require(success, "safeTransferETH: ETH transfer failed"); |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +interface IGovernance { |
| 25 | + // get current consensus group |
| 26 | + function getCurrentConsensus() external view returns (address[] memory); |
| 27 | +} |
| 28 | + |
| 29 | +interface IGovReward { |
| 30 | + function getMiners() external view returns (address[] memory); |
| 31 | + |
| 32 | + function withdraw() external; |
| 33 | +} |
| 34 | + |
| 35 | +contract GovReward is IGovReward, UUPSUpgradeable { |
| 36 | + address public constant SELF = 0x1212100000000000000000000000000000000003; |
| 37 | + address public constant GOV_ADMIN = |
| 38 | + 0x1212000000000000000000000000000000000000; |
| 39 | + // governance contact |
| 40 | + address public constant GOV = 0x1212000000000000000000000000000000000001; |
| 41 | + |
| 42 | + receive() external payable {} |
| 43 | + |
| 44 | + modifier onlyGov() { |
| 45 | + require(msg.sender == GOV, "not governance"); |
| 46 | + _; |
| 47 | + } |
| 48 | + |
| 49 | + modifier onlyAdmin() { |
| 50 | + require(msg.sender == GOV_ADMIN, "not admin"); |
| 51 | + _; |
| 52 | + } |
| 53 | + |
| 54 | + function _authorizeUpgrade( |
| 55 | + address newImplementation |
| 56 | + ) internal virtual override onlyAdmin {} |
| 57 | + |
| 58 | + // Only for precompiled uups implementation in genesis file, need to be removed when upgrading the contract. |
| 59 | + // This override is added because "immutable __self" in UUPSUpgradeable is not avaliable in precompiled contract. |
| 60 | + function _checkProxy() internal view virtual override { |
| 61 | + if ( |
| 62 | + address(this) == SELF || // Must be called through delegatecall |
| 63 | + ERC1967Utils.getImplementation() != SELF // Must be called through an active proxy |
| 64 | + ) { |
| 65 | + revert UUPSUnauthorizedCallContext(); |
| 66 | + } |
| 67 | + } |
| 68 | + |
| 69 | + // Only for precompiled uups implementation in genesis file, need to be removed when upgrading the contract. |
| 70 | + // This override is added because "immutable __self" in UUPSUpgradeable is not avaliable in precompiled contract. |
| 71 | + function _checkNotDelegated() internal view virtual override { |
| 72 | + if (address(this) != SELF) { |
| 73 | + // Must not be called through delegatecall |
| 74 | + revert UUPSUnauthorizedCallContext(); |
| 75 | + } |
| 76 | + } |
| 77 | + |
| 78 | + function getMiners() external view override returns (address[] memory) { |
| 79 | + return IGovernance(GOV).getCurrentConsensus(); |
| 80 | + } |
| 81 | + |
| 82 | + function withdraw() external onlyGov { |
| 83 | + if (address(this).balance > 0) { |
| 84 | + TransferHelper.safeTransferETH(GOV, address(this).balance); |
| 85 | + } |
| 86 | + } |
| 87 | +} |
0 commit comments