编译器
0.6.12+commit.27d51765
文件 1 的 9:BeaconStakingOracle.sol
pragma solidity >=0.6.10 <0.8.0;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/EnumerableSet.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "../../utils/SafeDecimalMath.sol";
import "../../interfaces/IFundV3.sol";
interface IEthStakingStrategy {
struct OperatorData {
uint256 id;
uint256 beaconBalance;
uint256 validatorCount;
uint256 executionLayerReward;
}
function fund() external view returns (address);
function batchReport(
uint256 epoch,
OperatorData[] calldata operatorData,
uint256 finalizationCount
) external;
}
contract BeaconStakingOracle is Ownable {
using SafeMath for uint256;
using SafeDecimalMath for uint256;
using EnumerableSet for EnumerableSet.AddressSet;
event BeaconReported(uint256 epochId, bytes32 report, address caller);
event MemberAdded(address member);
event MemberRemoved(address member);
event AnnualMaxChangeUpdated(uint256 newAnnualMaxChange);
event QuorumUpdated(uint256 newQuorum);
IEthStakingStrategy public immutable strategy;
IFundV3 public immutable fund;
uint256 public immutable reportableEpochInterval;
uint256 public immutable secondsPerEpoch;
uint256 public immutable genesisTime;
uint256 public annualMaxChange;
uint256 public quorum;
uint256 public nonce;
uint256 public lastCompletedEpoch;
mapping(uint256 => mapping(bytes32 => uint256)) public reports;
mapping(address => uint256) public lastReportedEpoch;
EnumerableSet.AddressSet private _members;
constructor(
address strategy_,
uint256 reportableEpochInterval_,
uint256 secondsPerEpoch_,
uint256 genesisTime_,
uint256 annualMaxChange_
) public {
strategy = IEthStakingStrategy(strategy_);
fund = IFundV3(IEthStakingStrategy(strategy_).fund());
reportableEpochInterval = reportableEpochInterval_;
secondsPerEpoch = secondsPerEpoch_;
require(genesisTime_ < block.timestamp);
genesisTime = genesisTime_;
_updateAnnualMaxChange(annualMaxChange_);
}
function batchReport(
uint256 epoch,
IEthStakingStrategy.OperatorData[] calldata operatorData,
uint256 finalizationCount
) external onlyMember {
require(
epoch <= getLatestReportableEpoch() &&
epoch > lastCompletedEpoch &&
epoch % reportableEpochInterval == 0,
"Invalid epoch"
);
require(lastReportedEpoch[msg.sender] < epoch, "Already reported");
lastReportedEpoch[msg.sender] = epoch;
bytes32 report = encodeBatchReport(operatorData, finalizationCount);
uint256 currentCount = reports[epoch][report] + 1;
emit BeaconReported(epoch, report, msg.sender);
if (currentCount >= quorum) {
uint256 preTotalUnderlying = fund.getTotalUnderlying();
uint256 preEquivalentTotalQ = fund.getEquivalentTotalQ();
strategy.batchReport(epoch, operatorData, finalizationCount);
uint256 postTotalUnderlying = fund.getTotalUnderlying();
uint256 postEquivalentTotalQ = fund.getEquivalentTotalQ();
uint256 timeElapsed = (epoch - lastCompletedEpoch) * secondsPerEpoch;
_sanityCheck(
postTotalUnderlying,
postEquivalentTotalQ,
preTotalUnderlying,
preEquivalentTotalQ,
timeElapsed
);
lastCompletedEpoch = epoch;
if (currentCount > 1) {
reports[epoch][report] = 0;
}
} else {
reports[epoch][report] = currentCount;
}
}
function _sanityCheck(
uint256 postTotalUnderlying,
uint256 postEquivalentTotalQ,
uint256 preTotalUnderlying,
uint256 preEquivalentTotalQ,
uint256 timeElapsed
) private view {
if (postEquivalentTotalQ == 0 || preEquivalentTotalQ == 0) {
return;
}
uint256 postNav = postTotalUnderlying.divideDecimal(postEquivalentTotalQ);
uint256 preNav = preTotalUnderlying.divideDecimal(preEquivalentTotalQ);
uint256 delta = postNav >= preNav ? postNav - preNav : preNav - postNav;
require(
delta.mul(365 days) / timeElapsed <= preNav.multiplyDecimal(annualMaxChange),
"Annual max delta"
);
}
function getLatestReportableEpoch() public view returns (uint256) {
uint256 latestEpoch = (block.timestamp - genesisTime) / secondsPerEpoch;
return (latestEpoch / reportableEpochInterval) * reportableEpochInterval;
}
function encodeBatchReport(
IEthStakingStrategy.OperatorData[] calldata operatorData,
uint256 finalizationCount
) public view returns (bytes32) {
return keccak256(abi.encode(operatorData, finalizationCount, nonce));
}
function getNextEpochByMember(address member) external view returns (uint256) {
uint256 epoch = getLatestReportableEpoch();
uint256 last = lastReportedEpoch[member];
return epoch > last ? epoch : 0;
}
modifier onlyMember() {
require(_members.contains(msg.sender), "Member not found");
_;
}
function getMemberCount() external view returns (uint256) {
return _members.length();
}
function getMembers() external view returns (address[] memory members) {
uint256 length = _members.length();
members = new address[](length);
for (uint256 i = 0; i < length; i++) {
members[i] = _members.at(i);
}
}
function addMember(address member, uint256 newQuorum) external onlyOwner {
require(member != address(0), "Invalid address");
require(!_members.contains(member), "Already a member");
_members.add(member);
emit MemberAdded(member);
_updateQuorum(newQuorum);
}
function removeMember(address member, uint256 newQuorum) external onlyOwner {
require(_members.contains(member), "Not a member");
_members.remove(member);
emit MemberRemoved(member);
_updateQuorum(newQuorum);
nonce++;
}
function updateAnnualMaxChange(uint256 newAnnualMaxChange) external onlyOwner {
_updateAnnualMaxChange(newAnnualMaxChange);
}
function updateQuorum(uint256 newQuorum) external onlyOwner {
_updateQuorum(newQuorum);
}
function _updateAnnualMaxChange(uint256 newAnnualMaxChange) private {
annualMaxChange = newAnnualMaxChange;
emit AnnualMaxChangeUpdated(newAnnualMaxChange);
}
function _updateQuorum(uint256 newQuorum) private {
quorum = newQuorum;
emit QuorumUpdated(newQuorum);
}
}
文件 2 的 9: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;
}
}
文件 3 的 9:EnumerableSet.sol
pragma solidity >=0.6.0 <0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping (bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = toDeleteIndex + 1;
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
文件 4 的 9:IFundV3.sol
pragma solidity >=0.6.10 <0.8.0;
pragma experimental ABIEncoderV2;
import "./ITwapOracleV2.sol";
interface IFundV3 {
struct Rebalance {
uint256 ratioB2Q;
uint256 ratioR2Q;
uint256 ratioBR;
uint256 timestamp;
}
function tokenUnderlying() external view returns (address);
function tokenQ() external view returns (address);
function tokenB() external view returns (address);
function tokenR() external view returns (address);
function tokenShare(uint256 tranche) external view returns (address);
function primaryMarket() external view returns (address);
function primaryMarketUpdateProposal() external view returns (address, uint256);
function strategy() external view returns (address);
function strategyUpdateProposal() external view returns (address, uint256);
function underlyingDecimalMultiplier() external view returns (uint256);
function twapOracle() external view returns (ITwapOracleV2);
function feeCollector() external view returns (address);
function endOfDay(uint256 timestamp) external pure returns (uint256);
function trancheTotalSupply(uint256 tranche) external view returns (uint256);
function trancheBalanceOf(uint256 tranche, address account) external view returns (uint256);
function trancheAllBalanceOf(address account)
external
view
returns (
uint256,
uint256,
uint256
);
function trancheBalanceVersion(address account) external view returns (uint256);
function trancheAllowance(
uint256 tranche,
address owner,
address spender
) external view returns (uint256);
function trancheAllowanceVersion(address owner, address spender)
external
view
returns (uint256);
function trancheTransfer(
uint256 tranche,
address recipient,
uint256 amount,
uint256 version
) external;
function trancheTransferFrom(
uint256 tranche,
address sender,
address recipient,
uint256 amount,
uint256 version
) external;
function trancheApprove(
uint256 tranche,
address spender,
uint256 amount,
uint256 version
) external;
function getRebalanceSize() external view returns (uint256);
function getRebalance(uint256 index) external view returns (Rebalance memory);
function getRebalanceTimestamp(uint256 index) external view returns (uint256);
function currentDay() external view returns (uint256);
function splitRatio() external view returns (uint256);
function historicalSplitRatio(uint256 version) external view returns (uint256);
function fundActivityStartTime() external view returns (uint256);
function isFundActive(uint256 timestamp) external view returns (bool);
function getEquivalentTotalB() external view returns (uint256);
function getEquivalentTotalQ() external view returns (uint256);
function historicalEquivalentTotalB(uint256 timestamp) external view returns (uint256);
function historicalNavs(uint256 timestamp) external view returns (uint256 navB, uint256 navR);
function extrapolateNav(uint256 price)
external
view
returns (
uint256,
uint256,
uint256
);
function doRebalance(
uint256 amountQ,
uint256 amountB,
uint256 amountR,
uint256 index
)
external
view
returns (
uint256 newAmountQ,
uint256 newAmountB,
uint256 newAmountR
);
function batchRebalance(
uint256 amountQ,
uint256 amountB,
uint256 amountR,
uint256 fromIndex,
uint256 toIndex
)
external
view
returns (
uint256 newAmountQ,
uint256 newAmountB,
uint256 newAmountR
);
function refreshBalance(address account, uint256 targetVersion) external;
function refreshAllowance(
address owner,
address spender,
uint256 targetVersion
) external;
function shareTransfer(
address sender,
address recipient,
uint256 amount
) external;
function shareTransferFrom(
address spender,
address sender,
address recipient,
uint256 amount
) external returns (uint256 newAllowance);
function shareIncreaseAllowance(
address sender,
address spender,
uint256 addedValue
) external returns (uint256 newAllowance);
function shareDecreaseAllowance(
address sender,
address spender,
uint256 subtractedValue
) external returns (uint256 newAllowance);
function shareApprove(
address owner,
address spender,
uint256 amount
) external;
function historicalUnderlying(uint256 timestamp) external view returns (uint256);
function getTotalUnderlying() external view returns (uint256);
function getStrategyUnderlying() external view returns (uint256);
function getTotalDebt() external view returns (uint256);
event RebalanceTriggered(
uint256 indexed index,
uint256 indexed day,
uint256 navSum,
uint256 navB,
uint256 navROrZero,
uint256 ratioB2Q,
uint256 ratioR2Q,
uint256 ratioBR
);
event Settled(uint256 indexed day, uint256 navB, uint256 navR, uint256 interestRate);
event InterestRateUpdated(uint256 baseInterestRate, uint256 floatingInterestRate);
event BalancesRebalanced(
address indexed account,
uint256 version,
uint256 balanceQ,
uint256 balanceB,
uint256 balanceR
);
event AllowancesRebalanced(
address indexed owner,
address indexed spender,
uint256 version,
uint256 allowanceQ,
uint256 allowanceB,
uint256 allowanceR
);
}
文件 5 的 9:ITwapOracle.sol
pragma solidity >=0.6.10 <0.8.0;
interface ITwapOracle {
enum UpdateType {PRIMARY, SECONDARY, OWNER, CHAINLINK, UNISWAP_V2}
function getTwap(uint256 timestamp) external view returns (uint256);
}
文件 6 的 9:ITwapOracleV2.sol
pragma solidity >=0.6.10 <0.8.0;
import "./ITwapOracle.sol";
interface ITwapOracleV2 is ITwapOracle {
function getLatest() external view returns (uint256);
}
文件 7 的 9:Ownable.sol
pragma solidity >=0.6.0 <0.8.0;
import "../utils/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;
}
}
文件 8 的 9:SafeDecimalMath.sol
pragma solidity >=0.6.10 <0.8.0;
import "@openzeppelin/contracts/math/SafeMath.sol";
library SafeDecimalMath {
using SafeMath for uint256;
uint256 private constant decimals = 18;
uint256 private constant highPrecisionDecimals = 27;
uint256 private constant UNIT = 10**uint256(decimals);
uint256 private constant PRECISE_UNIT = 10**uint256(highPrecisionDecimals);
uint256 private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR =
10**uint256(highPrecisionDecimals - decimals);
function multiplyDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(y).div(UNIT);
}
function multiplyDecimalPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(y).div(PRECISE_UNIT);
}
function divideDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(UNIT).div(y);
}
function divideDecimalPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
return x.mul(PRECISE_UNIT).div(y);
}
function decimalToPreciseDecimal(uint256 i) internal pure returns (uint256) {
return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR);
}
function preciseDecimalToDecimal(uint256 i) internal pure returns (uint256) {
uint256 quotientTimesTen = i.mul(10).div(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR);
if (quotientTimesTen % 10 >= 5) {
quotientTimesTen = quotientTimesTen.add(10);
}
return quotientTimesTen.div(10);
}
function saturatingMul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
return c / a != b ? type(uint256).max : c;
}
function saturatingMultiplyDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
return saturatingMul(x, y).div(UNIT);
}
}
文件 9 的 9:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) return 0;
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
{
"compilationTarget": {
"contracts/strategy/eth/BeaconStakingOracle.sol": "BeaconStakingOracle"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"strategy_","type":"address"},{"internalType":"uint256","name":"reportableEpochInterval_","type":"uint256"},{"internalType":"uint256","name":"secondsPerEpoch_","type":"uint256"},{"internalType":"uint256","name":"genesisTime_","type":"uint256"},{"internalType":"uint256","name":"annualMaxChange_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newAnnualMaxChange","type":"uint256"}],"name":"AnnualMaxChangeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"epochId","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"report","type":"bytes32"},{"indexed":false,"internalType":"address","name":"caller","type":"address"}],"name":"BeaconReported","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"member","type":"address"}],"name":"MemberAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"member","type":"address"}],"name":"MemberRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"QuorumUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"member","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"addMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"annualMaxChange","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"epoch","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"beaconBalance","type":"uint256"},{"internalType":"uint256","name":"validatorCount","type":"uint256"},{"internalType":"uint256","name":"executionLayerReward","type":"uint256"}],"internalType":"struct IEthStakingStrategy.OperatorData[]","name":"operatorData","type":"tuple[]"},{"internalType":"uint256","name":"finalizationCount","type":"uint256"}],"name":"batchReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"beaconBalance","type":"uint256"},{"internalType":"uint256","name":"validatorCount","type":"uint256"},{"internalType":"uint256","name":"executionLayerReward","type":"uint256"}],"internalType":"struct IEthStakingStrategy.OperatorData[]","name":"operatorData","type":"tuple[]"},{"internalType":"uint256","name":"finalizationCount","type":"uint256"}],"name":"encodeBatchReport","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fund","outputs":[{"internalType":"contract IFundV3","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"genesisTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestReportableEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMembers","outputs":[{"internalType":"address[]","name":"members","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"member","type":"address"}],"name":"getNextEpochByMember","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastCompletedEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastReportedEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","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":"quorum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"member","type":"address"},{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"removeMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reportableEpochInterval","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"reports","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"secondsPerEpoch","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strategy","outputs":[{"internalType":"contract IEthStakingStrategy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newAnnualMaxChange","type":"uint256"}],"name":"updateAnnualMaxChange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newQuorum","type":"uint256"}],"name":"updateQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"}]