文件 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.6.0 <0.8.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:IERC677.sol
pragma solidity 0.7.4;
import "./IERC20.sol";
interface IERC677 is IERC20 {
function transferAndCall(address _to, uint256 _value, bytes calldata _data) external returns (bool success);
}
文件 4 的 7:IOffchainAggregator.sol
pragma solidity 0.7.4;
interface IOffchainAggregator {
function owedPayment(address _transmitter) external view returns (uint256);
function withdrawPayment(address _transmitter) external;
function transferPayeeship(address _transmitter, address _proposed) external;
function acceptPayeeship(address _transmitter) external;
}
文件 5 的 7:OffchainAggregatorSweeper.sol
pragma solidity 0.7.4;
import "./IERC677.sol";
import "./IOffchainAggregator.sol";
import "./Sweeper.sol";
contract OffchainAggregatorSweeper is Sweeper {
IERC677 public token;
address public transmitter;
constructor(
address _nodeRewards,
uint256 _minToWithdraw,
address _transmitter,
address _token
) Sweeper(_nodeRewards, _minToWithdraw) {
transmitter = _transmitter;
token = IERC677(_token);
}
function withdrawable() external view override returns (uint256[] memory) {
uint256[] memory _withdrawable = new uint256[](contracts.length);
for (uint i = 0; i < contracts.length; i++) {
_withdrawable[i] = IOffchainAggregator(contracts[i]).owedPayment(transmitter);
}
return _withdrawable;
}
function _withdraw(uint256[] calldata _contractIdxs) internal override {
for (uint i = 0; i < _contractIdxs.length; i++) {
require(_contractIdxs[i] < contracts.length, "contractIdx must be < contracts length");
IOffchainAggregator aggregator = IOffchainAggregator(contracts[_contractIdxs[i]]);
if (aggregator.owedPayment(transmitter) >= minToWithdraw) {
aggregator.withdrawPayment(transmitter);
}
}
if (token.balanceOf(address(this)) > 0) {
token.transfer(nodeRewards, token.balanceOf(address(this)));
}
}
function _transferAdmin(uint256[] calldata _contractIdxs, address _newAdmin) internal override {
for (uint i = 0; i < _contractIdxs.length; i++) {
require(_contractIdxs[i] < contracts.length, "contractIdx must be < contracts length");
IOffchainAggregator(contracts[_contractIdxs[i]]).transferPayeeship(transmitter, _newAdmin);
}
}
function _acceptAdmin(uint256[] calldata _contractIdxs) internal override {
for (uint i = 0; i < _contractIdxs.length; i++) {
require(_contractIdxs[i] < contracts.length, "contractIdx must be < contracts length");
IOffchainAggregator(contracts[_contractIdxs[i]]).acceptPayeeship(transmitter);
}
}
}
文件 6 的 7:Ownable.sol
pragma solidity >=0.6.0 <0.8.0;
import "./Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () internal {
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;
}
}
文件 7 的 7:Sweeper.sol
pragma solidity 0.7.4;
import "./Ownable.sol";
abstract contract Sweeper is Ownable {
uint256 public minToWithdraw;
address[] public contracts;
address nodeRewards;
modifier onlyNodeRewards() {
require(nodeRewards == msg.sender, "NodeRewards only");
_;
}
constructor(address _nodeRewards, uint256 _minToWithdraw) {
nodeRewards = _nodeRewards;
minToWithdraw = _minToWithdraw;
}
function getContracts() external view returns (address[] memory) {
return contracts;
}
function withdraw(uint256[] calldata _contractIdxs) external virtual onlyNodeRewards() {
require(_contractIdxs.length <= contracts.length, "contractIdxs length must be <= contracts length");
_withdraw(_contractIdxs);
}
function withdrawable() external view virtual returns (uint256[] memory);
function transferAdmin(uint256[] calldata _contractIdxs, address _newAdmin) external onlyOwner() {
require(_contractIdxs.length <= contracts.length, "contractIdxs length must be <= contracts length");
_transferAdmin(_contractIdxs, _newAdmin);
}
function acceptAdmin(uint256[] calldata _contractIdxs) external onlyOwner() {
require(_contractIdxs.length <= contracts.length, "contractIdxs length must be <= contracts length");
_acceptAdmin(_contractIdxs);
}
function setMinToWithdraw(uint256 _minToWithdraw) external onlyOwner() {
minToWithdraw = _minToWithdraw;
}
function addContracts(address[] calldata _contracts) external onlyOwner() {
for (uint i = 0; i < _contracts.length; i++) {
contracts.push(_contracts[i]);
}
}
function removeContract(uint256 _index) external onlyOwner() {
require(_index < contracts.length, "Contract does not exist");
contracts[_index] = contracts[contracts.length - 1];
delete contracts[contracts.length - 1];
}
function _withdraw(uint256[] calldata _contractIdxs) internal virtual;
function _transferAdmin(uint256[] calldata _contractIdxs, address _newAdmin) internal virtual;
function _acceptAdmin(uint256[] calldata _contractIdxs) internal virtual {}
}
{
"compilationTarget": {
"OffchainAggregatorSweeper.sol": "OffchainAggregatorSweeper"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_nodeRewards","type":"address"},{"internalType":"uint256","name":"_minToWithdraw","type":"uint256"},{"internalType":"address","name":"_transmitter","type":"address"},{"internalType":"address","name":"_token","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":[{"internalType":"uint256[]","name":"_contractIdxs","type":"uint256[]"}],"name":"acceptAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_contracts","type":"address[]"}],"name":"addContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"contracts","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getContracts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minToWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"removeContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minToWithdraw","type":"uint256"}],"name":"setMinToWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"contract IERC677","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_contractIdxs","type":"uint256[]"},{"internalType":"address","name":"_newAdmin","type":"address"}],"name":"transferAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transmitter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_contractIdxs","type":"uint256[]"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawable","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"}]