文件 1 的 7:Context.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
文件 2 的 7:IERC20.sol
pragma solidity ^0.7.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 3 的 7:Ownable.sol
pragma solidity ^0.7.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 4 的 7:PowerSwitch.sol
pragma solidity 0.7.6;
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
interface IPowerSwitch {
event PowerOn();
event PowerOff();
event EmergencyShutdown();
enum State {Online, Offline, Shutdown}
function powerOn() external;
function powerOff() external;
function emergencyShutdown() external;
function isOnline() external view returns (bool status);
function isOffline() external view returns (bool status);
function isShutdown() external view returns (bool status);
function getStatus() external view returns (State status);
function getPowerController() external view returns (address controller);
}
contract PowerSwitch is IPowerSwitch, Ownable {
IPowerSwitch.State private _status;
constructor(address owner) {
require(owner != address(0), "PowerSwitch: invalid owner");
Ownable.transferOwnership(owner);
}
function powerOn() external override onlyOwner {
require(_status == IPowerSwitch.State.Offline, "PowerSwitch: cannot power on");
_status = IPowerSwitch.State.Online;
emit PowerOn();
}
function powerOff() external override onlyOwner {
require(_status == IPowerSwitch.State.Online, "PowerSwitch: cannot power off");
_status = IPowerSwitch.State.Offline;
emit PowerOff();
}
function emergencyShutdown() external override onlyOwner {
require(_status != IPowerSwitch.State.Shutdown, "PowerSwitch: cannot shutdown");
_status = IPowerSwitch.State.Shutdown;
emit EmergencyShutdown();
}
function isOnline() external view override returns (bool status) {
return _status == State.Online;
}
function isOffline() external view override returns (bool status) {
return _status == State.Offline;
}
function isShutdown() external view override returns (bool status) {
return _status == State.Shutdown;
}
function getStatus() external view override returns (IPowerSwitch.State status) {
return _status;
}
function getPowerController() external view override returns (address controller) {
return Ownable.owner();
}
}
文件 5 的 7:Powered.sol
pragma solidity 0.7.6;
import {IPowerSwitch} from "./PowerSwitch.sol";
interface IPowered {
function isOnline() external view returns (bool status);
function isOffline() external view returns (bool status);
function isShutdown() external view returns (bool status);
function getPowerSwitch() external view returns (address powerSwitch);
function getPowerController() external view returns (address controller);
}
contract Powered is IPowered {
address private _powerSwitch;
modifier onlyOnline() {
_onlyOnline();
_;
}
modifier onlyOffline() {
_onlyOffline();
_;
}
modifier notShutdown() {
_notShutdown();
_;
}
modifier onlyShutdown() {
_onlyShutdown();
_;
}
function _setPowerSwitch(address powerSwitch) internal {
_powerSwitch = powerSwitch;
}
function isOnline() public view override returns (bool status) {
return IPowerSwitch(_powerSwitch).isOnline();
}
function isOffline() public view override returns (bool status) {
return IPowerSwitch(_powerSwitch).isOffline();
}
function isShutdown() public view override returns (bool status) {
return IPowerSwitch(_powerSwitch).isShutdown();
}
function getPowerSwitch() public view override returns (address powerSwitch) {
return _powerSwitch;
}
function getPowerController() public view override returns (address controller) {
return IPowerSwitch(_powerSwitch).getPowerController();
}
function _onlyOnline() private view {
require(isOnline(), "Powered: is not online");
}
function _onlyOffline() private view {
require(isOffline(), "Powered: is not offline");
}
function _notShutdown() private view {
require(!isShutdown(), "Powered: is shutdown");
}
function _onlyShutdown() private view {
require(isShutdown(), "Powered: is not shutdown");
}
}
文件 6 的 7:RewardPool.sol
pragma solidity 0.7.6;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {TransferHelper} from "@uniswap/lib/contracts/libraries/TransferHelper.sol";
import {Powered} from "./Powered.sol";
interface IRewardPool {
function sendERC20(
address token,
address to,
uint256 value
) external;
function rescueERC20(address[] calldata tokens, address recipient) external;
}
contract RewardPool is IRewardPool, Powered, Ownable {
constructor(address powerSwitch) {
Powered._setPowerSwitch(powerSwitch);
}
function sendERC20(
address token,
address to,
uint256 value
) external override onlyOwner onlyOnline {
TransferHelper.safeTransfer(token, to, value);
}
function rescueERC20(address[] calldata tokens, address recipient)
external
override
onlyShutdown
{
require(
msg.sender == Powered.getPowerController(),
"RewardPool: only controller can withdraw after shutdown"
);
require(recipient != address(0), "RewardPool: recipient not defined");
for (uint256 index = 0; index < tokens.length; index++) {
address token = tokens[index];
uint256 balance = IERC20(token).balanceOf(address(this));
TransferHelper.safeTransfer(token, recipient, balance);
}
}
}
文件 7 的 7:TransferHelper.sol
pragma solidity >=0.6.0;
library TransferHelper {
function safeApprove(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::safeApprove: approve failed'
);
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::safeTransfer: transfer failed'
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::transferFrom: transferFrom failed'
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, 'TransferHelper::safeTransferETH: ETH transfer failed');
}
}
{
"compilationTarget": {
"contracts/aludel/RewardPool.sol": "RewardPool"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 1000
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"powerSwitch","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"getPowerController","outputs":[{"internalType":"address","name":"controller","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPowerSwitch","outputs":[{"internalType":"address","name":"powerSwitch","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOffline","outputs":[{"internalType":"bool","name":"status","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOnline","outputs":[{"internalType":"bool","name":"status","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isShutdown","outputs":[{"internalType":"bool","name":"status","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"sendERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]