编译器
0.8.17+commit.8df45f5f
文件 1 的 8:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 8:Farming.sol
pragma solidity ^0.8.17;
import './IFarming.sol';
import '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import 'contracts/lib/ownable/Ownable.sol';
struct Erc20Info {
uint256 intervalNumber;
uint256 totalCountOnInterval;
}
contract Farming is IFarming, Ownable {
using SafeERC20 for IERC20;
IERC20 immutable _stackingContract;
mapping(address => Stack) _stacks;
uint256 constant _timeIntervalFirst = 7 days;
uint256 _timeInterval = 7 days;
uint256 _nextIntervalTime;
uint256 _intervalNumber;
uint256 _totalStacksOnInterval;
uint256 _totalStacks;
uint256 _totalEthOnInterval;
mapping(address => Erc20Info) _erc20nfos;
mapping(address => uint256) _ethClaimIntervals;
mapping(address => mapping(address => uint256)) _erc20ClaimIntervals;
constructor(address stackingContract) {
_stackingContract = IERC20(stackingContract);
_nextIntervalTime = block.timestamp + _timeIntervalFirst;
}
receive() external payable {}
function timeIntervalLength() external view returns (uint256) {
if (_intervalNumber == 0 && block.timestamp < _nextIntervalTime)
return _timeIntervalFirst;
return _timeInterval;
}
function setTimeIntervalLengthHours(
uint256 intervalHours
) external onlyOwner {
_timeInterval = intervalHours * 1 hours;
}
function intervalNumber() external view returns (uint256) {
uint256 intervals = _completedIntervals();
if (intervals == 0) return _intervalNumber;
return _intervalNumber + intervals;
}
function nextIntervalTime() external view returns (uint256) {
uint256 intervals = _completedIntervals();
if (intervals == 0) return _nextIntervalTime;
return _nextIntervalTime + intervals * _timeInterval;
}
function nextIntervalLapsedSeconds() external view returns (uint256) {
if (block.timestamp < _nextIntervalTime)
return _nextIntervalTime - block.timestamp;
return this.nextIntervalTime() - block.timestamp;
}
function _completedIntervals() internal view returns (uint256) {
if (block.timestamp < _nextIntervalTime) return 0;
return 1 + (block.timestamp - _nextIntervalTime) / _timeInterval;
}
function getStack(address account) external view returns (Stack memory) {
return _stacks[account];
}
function addStack(uint256 count) external returns (Stack memory) {
return _addStack(count);
}
function _addStack(uint256 count) internal returns (Stack memory) {
_nextInterval();
uint256 lastCount = _stackingContract.balanceOf(address(this));
_stackingContract.transferFrom(msg.sender, address(this), count);
uint256 added = _stackingContract.balanceOf(address(this)) - lastCount;
_stacks[msg.sender].count += added;
_stacks[msg.sender].creationInterval = _intervalNumber;
_totalStacks += added;
emit OnAddStack(msg.sender, _stacks[msg.sender], added);
return _stacks[msg.sender];
}
function addFullStack() external returns (Stack memory) {
return _addStack(_stackingContract.balanceOf(msg.sender));
}
function removeStack(uint256 count) external returns (Stack memory) {
return _removeStack(count);
}
function _removeStack(uint256 count) internal returns (Stack memory) {
_nextInterval();
require(_stacks[msg.sender].count >= count, 'not enough stack count');
uint256 lastCount = _stackingContract.balanceOf(address(this));
_stackingContract.transfer(msg.sender, count);
uint256 removed = lastCount -
_stackingContract.balanceOf(address(this));
_stacks[msg.sender].count -= removed;
_stacks[msg.sender].creationInterval = _intervalNumber;
_totalStacks -= removed;
emit OnRemoveStack(msg.sender, _stacks[msg.sender], removed);
return _stacks[msg.sender];
}
function removeFullStack() external returns (Stack memory) {
return _removeStack(_stacks[msg.sender].count);
}
function totalStacks() external view returns (uint256) {
return _totalStacks;
}
function totalStacksOnInterval() external view returns (uint256) {
if (this.intervalNumber() <= _intervalNumber)
return _totalStacksOnInterval;
return _totalStacks;
}
function ethTotalForRewards() external view returns (uint256) {
return address(this).balance;
}
function erc20TotalForRewards(
address erc20
) external view returns (uint256) {
if (erc20 == address(_stackingContract))
return IERC20(erc20).balanceOf(address(this)) - _totalStacks;
else return IERC20(erc20).balanceOf(address(this));
}
function ethOnInterval() external view returns (uint256) {
if (this.intervalNumber() <= _intervalNumber)
return _totalEthOnInterval;
return this.ethTotalForRewards();
}
function erc20OnInterval(address erc20) external view returns (uint256) {
return
_expectedErc20Info(erc20, this.intervalNumber())
.totalCountOnInterval;
}
function _expectedErc20Info(
address erc20,
uint256 expectedIntervalNumber
) internal view returns (Erc20Info memory) {
Erc20Info memory info = _erc20nfos[erc20];
if (expectedIntervalNumber <= info.intervalNumber) return info;
info.intervalNumber = expectedIntervalNumber;
info.totalCountOnInterval = this.erc20TotalForRewards(erc20);
return info;
}
function ethClaimIntervalForAccount(
address account
) external view returns (uint256) {
uint256 interval = _ethClaimIntervals[account];
if (_stacks[account].creationInterval + 1 > interval)
interval = _stacks[account].creationInterval + 1;
return interval + 1;
}
function erc20ClaimIntervalForAccount(
address account,
address erc20
) external view returns (uint256) {
uint256 interval = _erc20ClaimIntervals[account][erc20];
if (_stacks[account].creationInterval + 1 > interval)
interval = _stacks[account].creationInterval + 1;
return interval + 1;
}
function ethClaimCountForAccount(
address account
) external view returns (uint256) {
if (this.ethClaimIntervalForAccount(account) > this.intervalNumber())
return 0;
return this.ethClaimCountForStack(_stacks[account].count);
}
function erc20ClaimCountForAccount(
address account,
address erc20
) external view returns (uint256) {
if (
this.erc20ClaimIntervalForAccount(account, erc20) >
this.intervalNumber()
) return 0;
return this.erc20ClaimCountForStack(_stacks[account].count, erc20);
}
function ethClaimCountForAccountExpect(
address account
) external view returns (uint256) {
return this.ethClaimCountForStackExpect(_stacks[account].count);
}
function erc20ClaimCountForAccountExpect(
address account,
address erc20
) external view returns (uint256) {
return
this.erc20ClaimCountForStackExpect(_stacks[account].count, erc20);
}
function ethClaimCountForStackExpect(
uint256 stackSize
) external view returns (uint256) {
return
_claimCountForStack(
stackSize,
this.totalStacks(),
this.ethTotalForRewards()
);
}
function erc20ClaimCountForStackExpect(
uint256 stackSize,
address erc20
) external view returns (uint256) {
return
_claimCountForStack(
stackSize,
this.totalStacks(),
this.erc20TotalForRewards(erc20)
);
}
function ethClaimCountForNewStackExpect(
uint256 stackSize
) external view returns (uint256) {
return
_claimCountForStack(
stackSize,
this.totalStacks() + stackSize,
this.ethTotalForRewards()
);
}
function erc20ClaimCountForNewStackExpect(
uint256 stackSize,
address erc20
) external view returns (uint256) {
return
_claimCountForStack(
stackSize,
this.totalStacks() + stackSize,
this.erc20TotalForRewards(erc20)
);
}
function ethClaimCountForStack(
uint256 stackSize
) external view returns (uint256) {
return
_claimCountForStack(
stackSize,
this.totalStacksOnInterval(),
this.ethOnInterval()
);
}
function erc20ClaimCountForStack(
uint256 stackSize,
address erc20
) external view returns (uint256) {
return
_claimCountForStack(
stackSize,
this.totalStacksOnInterval(),
this.erc20OnInterval(erc20)
);
}
function _claimCountForStack(
uint256 stackCount,
uint256 totalStacksOnInterwal,
uint256 assetCountOnInterwal
) internal pure returns (uint256) {
if (stackCount > totalStacksOnInterwal) return assetCountOnInterwal;
if (totalStacksOnInterwal == 0) return 0;
return (stackCount * assetCountOnInterwal) / totalStacksOnInterwal;
}
function erc20ClaimForStack(
address erc20,
uint256 stackCount
) external view returns (uint256) {
return
_claimCountForStack(
stackCount,
this.totalStacksOnInterval(),
this.erc20OnInterval(erc20)
);
}
function _nextInterval() internal returns (bool) {
if (block.timestamp < _nextIntervalTime) return false;
_totalStacksOnInterval = this.totalStacks();
_intervalNumber = this.intervalNumber();
_nextIntervalTime = this.nextIntervalTime();
_totalEthOnInterval = this.ethTotalForRewards();
emit OnNextInterval(_intervalNumber);
return true;
}
function claimEth() external {
_claimEth();
}
function _claimEth() internal {
_nextInterval();
require(
this.ethClaimIntervalForAccount(msg.sender) <= _intervalNumber,
'can not claim on current interval'
);
_ethClaimIntervals[msg.sender] = _intervalNumber;
uint256 claimCount = _claimCountForStack(
_stacks[msg.sender].count,
_totalStacksOnInterval,
_totalEthOnInterval
);
require(claimCount > 0, 'notging to claim');
(bool sent, ) = payable(msg.sender).call{ value: claimCount }('');
require(sent, 'sent ether error: ether is not sent');
emit OnClaimEth(msg.sender, _stacks[msg.sender], claimCount);
}
function claimErc20(address erc20) external {
_claimErc20(erc20);
}
function _claimErc20(address erc20) internal {
_nextInterval();
Erc20Info storage info = _erc20nfos[erc20];
if (_intervalNumber > info.intervalNumber) {
info.intervalNumber = _intervalNumber;
info.totalCountOnInterval = this.erc20TotalForRewards(erc20);
}
require(
this.erc20ClaimIntervalForAccount(msg.sender, erc20) <=
_intervalNumber,
'can not claim on current interval'
);
_erc20ClaimIntervals[msg.sender][erc20] = _intervalNumber;
uint256 claimCount = _claimCountForStack(
_stacks[msg.sender].count,
_totalStacksOnInterval,
info.totalCountOnInterval
);
require(claimCount > 0, 'nothing to claim');
IERC20(erc20).safeTransfer(msg.sender, claimCount);
emit OnClaimErc20(msg.sender, _stacks[msg.sender], claimCount);
}
function batchClaim(bool claimEth, address[] calldata tokens) external {
if (claimEth) _claimEth();
for (uint256 i = 0; i < tokens.length; ++i) _claimErc20(tokens[i]);
}
}
文件 3 的 8:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from,
address to,
uint256 amount
) external returns (bool);
}
文件 4 的 8:IFarming.sol
pragma solidity ^0.8.17;
struct Stack {
uint256 count;
uint256 creationInterval;
}
interface IFarming {
event OnAddStack(address indexed account, Stack stack, uint256 count);
event OnRemoveStack(address indexed account, Stack stack, uint256 count);
event OnClaimEth(address indexed account, Stack stack, uint256 count);
event OnClaimErc20(address indexed account, Stack stack, uint256 count);
event OnNextInterval(uint256 interval);
function timeIntervalLength() external view returns (uint256);
function setTimeIntervalLengthHours(uint256 intervalHours) external;
function intervalNumber() external view returns (uint256);
function nextIntervalTime() external view returns (uint256);
function nextIntervalLapsedSeconds() external view returns (uint256);
function getStack(address account) external view returns (Stack memory);
function addStack(uint256 count) external returns (Stack memory);
function addFullStack() external returns (Stack memory);
function removeStack(uint256 count) external returns (Stack memory);
function removeFullStack() external returns (Stack memory);
function totalStacks() external view returns (uint256);
function totalStacksOnInterval() external view returns (uint256);
function ethTotalForRewards() external view returns (uint256);
function erc20TotalForRewards(address erc20) external view returns (uint256);
function ethOnInterval() external view returns (uint256);
function erc20OnInterval(address erc20) external view returns (uint256);
function ethClaimIntervalForAccount(
address account
) external view returns (uint256);
function erc20ClaimIntervalForAccount(
address account,
address erc20
) external view returns (uint256);
function ethClaimCountForAccount(
address account
) external view returns (uint256);
function erc20ClaimCountForAccount(
address account,
address erc20
) external view returns (uint256);
function ethClaimCountForAccountExpect(
address account
) external view returns (uint256);
function erc20ClaimCountForAccountExpect(
address account,
address erc20
) external view returns (uint256);
function ethClaimCountForStackExpect(
uint256 stackSize
) external view returns (uint256);
function erc20ClaimCountForStackExpect(
uint256 stackSize,
address erc20
) external view returns (uint256);
function ethClaimCountForNewStackExpect(
uint256 stackSize
) external view returns (uint256);
function erc20ClaimCountForNewStackExpect(
uint256 stackSize,
address erc20
) external view returns (uint256);
function ethClaimCountForStack(
uint256 stackSize
) external view returns (uint256);
function erc20ClaimCountForStack(
uint256 stackSize,
address erc20
) external view returns (uint256);
function claimEth() external;
function claimErc20(address erc20) external;
function batchClaim(bool claimEth, address[] calldata tokens) external;
}
文件 5 的 8:IOwnable.sol
pragma solidity ^0.8.17;
interface IOwnable {
function owner() external view returns (address);
function transferOwnership(address newOwner) external;
}
文件 6 的 8:Ownable.sol
pragma solidity ^0.8.17;
import './IOwnable.sol';
contract Ownable is IOwnable {
address _owner;
constructor() {
_owner = msg.sender;
}
modifier onlyOwner() {
require(_owner == msg.sender, 'caller is not the owner');
_;
}
function owner() external virtual view returns (address) {
return _owner;
}
function transferOwnership(address newOwner) external override onlyOwner {
_owner = newOwner;
}
}
文件 7 的 8:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 8 的 8:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"contracts/farming/Farming.sol": "Farming"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"stackingContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"indexed":false,"internalType":"struct Stack","name":"stack","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"OnAddStack","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"indexed":false,"internalType":"struct Stack","name":"stack","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"OnClaimErc20","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"indexed":false,"internalType":"struct Stack","name":"stack","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"OnClaimEth","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interval","type":"uint256"}],"name":"OnNextInterval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"indexed":false,"internalType":"struct Stack","name":"stack","type":"tuple"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"OnRemoveStack","type":"event"},{"inputs":[],"name":"addFullStack","outputs":[{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"internalType":"struct Stack","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"addStack","outputs":[{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"internalType":"struct Stack","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"claimEth","type":"bool"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"batchClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20","type":"address"}],"name":"claimErc20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20ClaimCountForAccount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20ClaimCountForAccountExpect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stackSize","type":"uint256"},{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20ClaimCountForNewStackExpect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stackSize","type":"uint256"},{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20ClaimCountForStack","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stackSize","type":"uint256"},{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20ClaimCountForStackExpect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc20","type":"address"},{"internalType":"uint256","name":"stackCount","type":"uint256"}],"name":"erc20ClaimForStack","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20ClaimIntervalForAccount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20OnInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc20","type":"address"}],"name":"erc20TotalForRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"ethClaimCountForAccount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"ethClaimCountForAccountExpect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stackSize","type":"uint256"}],"name":"ethClaimCountForNewStackExpect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stackSize","type":"uint256"}],"name":"ethClaimCountForStack","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"stackSize","type":"uint256"}],"name":"ethClaimCountForStackExpect","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"ethClaimIntervalForAccount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethOnInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethTotalForRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getStack","outputs":[{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"internalType":"struct Stack","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"intervalNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextIntervalLapsedSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextIntervalTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"removeFullStack","outputs":[{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"internalType":"struct Stack","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"removeStack","outputs":[{"components":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"creationInterval","type":"uint256"}],"internalType":"struct Stack","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"intervalHours","type":"uint256"}],"name":"setTimeIntervalLengthHours","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"timeIntervalLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStacks","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStacksOnInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]