Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
DappnodeSmoothingPool
Compiler Version
v0.8.21+commit.d9974bed
Optimization Enabled:
Yes with 999999 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0 pragma solidity 0.8.21; import {MerkleProofUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/cryptography/MerkleProofUpgradeable.sol"; import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; /** * Contract responsible to manage the subscriptions and rewards of the dappnode smoothing pool */ contract DappnodeSmoothingPool is OwnableUpgradeable { /** * @notice Struct to store voted reports * @param slot Slot of the report * @param votes Current votes of this report */ struct Report { uint64 slot; uint64 votes; } // This value is reserved as an initial voted report to mark an oracle address as active bytes32 public constant INITIAL_REPORT_HASH = bytes32(uint256(1)); // 0x0000000000000000000000000000000000000000000000000000000000000001; // Subscription collateral uint256 public subscriptionCollateral; // Rewards merkle root, aggregate together all the validatorIDs with the same withdrawal address // Leaf:keccak256(abi.encodePacked(withdrawalAddress, availableBalance) bytes32 public rewardsRoot; // withdrawalAddress --> claimedBalance mapping(address => uint256) public claimedBalance; // Allow a withdrawal address to delegate his rewards to another address // withdrawalAddress --> rewardAddress mapping(address => address) public rewardRecipient; // The following parameters are used only to synch information on the oracle // And do not have any direct effect on the smart contract functions // Smoothing pool fee expressed in % with 2 decimals uint256 public poolFee; // Smoothing pool fee recipient address public poolFeeRecipient; // Indicates the deployment block number uint256 public deploymentBlockNumber; // The following parameters are relative to the oracle functions // Indicates the last consolidated slot uint64 public lastConsolidatedSlot; // Indicates how many slots must be between checkpoints uint64 public checkpointSlotSize; // Number of reports that must match to consolidate a new rewards root (N/M) uint64 public quorum; // Will be able to add/remove members of the oracle and update the quorum address public governance; // Will be able to accept the governance address public pendingGovernance; // Oracle member address --> current voted reportHash // reportHash: keccak256(abi.encodePacked(slot, rewardsRoot)) mapping(address => bytes32) public addressToVotedReportHash; // reportHash --> Report(slot | votes) mapping(bytes32 => Report) public reportHashToReport; // This array is used only to easily get the current oracle members information address[] public oracleMembers; /** * @dev Emitted when the contract receives ether */ event EtherReceived(address sender, uint256 donationAmount); /** * @dev Emitted when a new users subscribes */ event SubscribeValidator( address sender, uint256 subscriptionCollateral, uint64 validatorID ); /** * @dev Emitted when a user claim his rewards */ event ClaimRewards( address withdrawalAddress, address rewardAddress, uint256 claimableBalance ); /** * @dev Emitted when a validator address sets his rewards recipient */ event SetRewardRecipient(address withdrawalAddress, address poolRecipient); /** * @dev Emitted when a validator unsubscribes */ event UnsubscribeValidator(address sender, uint64 validatorID); /** * @dev Emitted when a the smoothing pool is initialized */ event InitSmoothingPool(uint64 initialSmoothingPoolSlot); /** * @dev Emitted when the pool fee is updated */ event UpdatePoolFee(uint256 newPoolFee); /** * @dev Emitted when the pool fee recipient is updated */ event UpdatePoolFeeRecipient(address newPoolFeeRecipient); /** * @dev Emitted when the checkpoint slot size is updated */ event UpdateCheckpointSlotSize(uint64 newCheckpointSlotSize); /** * @dev Emitted when the subscription collateral is update */ event UpdateSubscriptionCollateral(uint256 newSubscriptionCollateral); /** * @dev Emitted when a report is submitted */ event SubmitReport( uint256 slotNumber, bytes32 newRewardsRoot, address oracleMember ); /** * @dev Emitted when a report is consolidated */ event ReportConsolidated(uint256 slotNumber, bytes32 newRewardsRoot); /** * @dev Emitted when the quorum is updated */ event UpdateQuorum(uint64 newQuorum); /** * @dev Emitted when a new oracle member is added */ event AddOracleMember(address newOracleMember); /** * @dev Emitted when a new oracle member is removed */ event RemoveOracleMember(address oracleMemberRemoved); /** * @dev Emitted when the governance starts the two-step transfer setting a new pending governance */ event TransferGovernance(address newPendingGovernance); /** * @dev Emitted when the pending governance accepts the governance */ event AcceptGovernance(address newGovernance); /** * @param _governance Governance address * @param _subscriptionCollateral Subscription collateral * @param _poolFee Pool Fee * @param _poolFeeRecipient Pool fee recipient * @param _checkpointSlotSize Checkpoint slot size */ function initialize( address _governance, uint256 _subscriptionCollateral, uint256 _poolFee, address _poolFeeRecipient, uint64 _checkpointSlotSize, uint64 _quorum ) external initializer { // Initialize requires require( _poolFee <= 10000, "DappnodeSmoothingPool::initialize: Pool fee cannot be greater than 100%" ); require( _quorum != 0, "DappnodeSmoothingPool::initialize: Quorum cannot be 0" ); // Set initialize parameters governance = _governance; subscriptionCollateral = _subscriptionCollateral; checkpointSlotSize = _checkpointSlotSize; quorum = _quorum; poolFee = _poolFee; poolFeeRecipient = _poolFeeRecipient; deploymentBlockNumber = block.number; // Initialize OZ libs __Ownable_init(); // Emit events emit UpdatePoolFee(_poolFee); emit UpdatePoolFeeRecipient(_poolFeeRecipient); emit UpdateCheckpointSlotSize(_checkpointSlotSize); emit UpdateQuorum(_quorum); } /** * @dev Governance modifier */ modifier onlyGovernance() { require( governance == msg.sender, "DappnodeSmoothingPool::onlyGovernance: Only governance" ); _; } /** * @notice Be able to receive ether donations and MEV rewards * Oracle will be able to differentiate between MEV rewards and donations and distribute rewards accordingly **/ fallback() external payable { emit EtherReceived(msg.sender, msg.value); } //////////////////////// // Validators functions /////////////////////// /** * @notice Subscribe multiple validators to the smoothing pool * The function won't check if there are duplicated validatorIDs * @param validatorIDArray Validator ID array */ function subscribeValidators( uint64[] calldata validatorIDArray ) external payable { // Check collateral require( msg.value == subscriptionCollateral * validatorIDArray.length, "DappnodeSmoothingPool::subscribeValidator: msg.value does not equal subscription collateral" ); // Emit a single event for every validator ID subscribed for (uint256 i = 0; i < validatorIDArray.length; ) { emit SubscribeValidator( msg.sender, subscriptionCollateral, validatorIDArray[i] ); unchecked { i += 1; } } } /** * @notice Subscribe a validator ID to the smoothing pool * @param validatorID Validator ID */ function subscribeValidator(uint64 validatorID) external payable { // Check collateral require( msg.value == subscriptionCollateral, "DappnodeSmoothingPool::subscribeValidator: msg.value does not equal subscription collateral" ); emit SubscribeValidator( msg.sender, subscriptionCollateral, validatorID ); } /** * @notice Claim available rewards * All the rewards that has the same withdrawal address and pool recipient are aggregated in the same leaf * @param withdrawalAddress Withdrawal address * @param accumulatedBalance Total available balance to claim * @param merkleProof Merkle proof against rewardsRoot */ function claimRewards( address withdrawalAddress, uint256 accumulatedBalance, bytes32[] memory merkleProof ) external { // Verify the merkle proof bytes32 node = keccak256( abi.encodePacked(withdrawalAddress, accumulatedBalance) ); require( MerkleProofUpgradeable.verify(merkleProof, rewardsRoot, node), "DappnodeSmoothingPool::claimRewards: Invalid merkle proof" ); // Get claimable ether uint256 claimableBalance = accumulatedBalance - claimedBalance[withdrawalAddress]; // Update claimed balance mapping claimedBalance[withdrawalAddress] = accumulatedBalance; // Load first the reward recipient for gas saving, to avoid load twice from storage address currentRewardRecipient = rewardRecipient[withdrawalAddress]; address rewardAddress = currentRewardRecipient == address(0) ? withdrawalAddress : currentRewardRecipient; // Send ether (bool success, ) = rewardAddress.call{value: claimableBalance}( new bytes(0) ); require( success, "DappnodeSmoothingPool::claimRewards: Eth transfer failed" ); emit ClaimRewards(withdrawalAddress, rewardAddress, claimableBalance); } /** * @notice Allow a withdrawal address to set a reward recipient * @param rewardAddress Reward recipient */ function setRewardRecipient(address rewardAddress) external { rewardRecipient[msg.sender] = rewardAddress; emit SetRewardRecipient(msg.sender, rewardAddress); } /** * @notice Unsubscribe a validator ID from smoothing pool * This call will only take effect in the oracle * if the msg.sender is the withdrawal address of that validator * @param validatorID Validator ID */ function unsubscribeValidator(uint64 validatorID) external { emit UnsubscribeValidator(msg.sender, validatorID); } //////////////////// // Oracle functions /////////////////// /** * @notice Submit a report for a new rewards root * If the quorum is reached, consolidate the rewards root * @param slotNumber Slot number * @param proposedRewardsRoot Proposed rewards root */ function submitReport( uint64 slotNumber, bytes32 proposedRewardsRoot ) external { // Check that the report contains the correct slot number uint64 cacheLastConsolidatedSlot = lastConsolidatedSlot; require( cacheLastConsolidatedSlot != 0, "DappnodeSmoothingPool::submitReport: Smoothing pool not initialized" ); require( slotNumber == cacheLastConsolidatedSlot + checkpointSlotSize, "DappnodeSmoothingPool::submitReport: Slot number invalid" ); // Check the last voted report bytes32 lastVotedReportHash = addressToVotedReportHash[msg.sender]; // Check if it's a valid oracle member require( lastVotedReportHash != bytes32(0), "DappnodeSmoothingPool::submitReport: Not a oracle member" ); // If it's not the initial report hash, check last report voted if (lastVotedReportHash != INITIAL_REPORT_HASH) { Report storage lastVotedReport = reportHashToReport[ lastVotedReportHash ]; // Subtract a vote on the last voted report // That report could have 0 votes because: // - The report was already consolidated // - Were subtracted all the votes from that report if (lastVotedReport.votes > 0) { unchecked { lastVotedReport.votes--; } } } // Get the current report bytes32 currentReportHash = getReportHash( slotNumber, proposedRewardsRoot ); Report memory currentVotedReport = reportHashToReport[ currentReportHash ]; // Check if it's a new report if (currentVotedReport.slot == 0) { // It's a new report, set slot and votes currentVotedReport.slot = slotNumber; currentVotedReport.votes = 1; } else { // It's an existing report, add a new vote currentVotedReport.votes++; } // Emit Submit report before check the quorum emit SubmitReport(slotNumber, proposedRewardsRoot, msg.sender); // Check if it reaches the quorum if (currentVotedReport.votes >= quorum) { delete reportHashToReport[currentReportHash]; // Consolidate report lastConsolidatedSlot = slotNumber; rewardsRoot = proposedRewardsRoot; emit ReportConsolidated(slotNumber, proposedRewardsRoot); } else { // Store submitted report with a new added vote reportHashToReport[currentReportHash] = currentVotedReport; // Store voted report hash addressToVotedReportHash[msg.sender] = currentReportHash; } } //////////////////////// // Governance functions //////////////////////// /** * @notice Add an oracle member * Only the governance can call this function * @param newOracleMember Address of the new oracle member */ function addOracleMember(address newOracleMember) external onlyGovernance { require( addressToVotedReportHash[newOracleMember] == bytes32(0), "DappnodeSmoothingPool::addOracleMember: Already oracle member" ); // Add oracle member addressToVotedReportHash[newOracleMember] = INITIAL_REPORT_HASH; // Add oracle member to the oracleMembers array oracleMembers.push(newOracleMember); emit AddOracleMember(newOracleMember); } /** * @notice Remove an oracle member * Only the governance can call this function * @param oracleMemberAddress Address of the removed oracle member * @param oracleMemberIndex Index of the removed oracle member */ function removeOracleMember( address oracleMemberAddress, uint256 oracleMemberIndex ) external onlyGovernance { bytes32 lastVotedReportHash = addressToVotedReportHash[ oracleMemberAddress ]; require( lastVotedReportHash != bytes32(0), "DappnodeSmoothingPool::removeOracleMember: Was not an oracle member" ); require( oracleMembers[oracleMemberIndex] == oracleMemberAddress, "DappnodeSmoothingPool::removeOracleMember: Oracle member index does not match" ); // If it's not the initial report hash, check last report voted if (lastVotedReportHash != INITIAL_REPORT_HASH) { Report storage lastVotedReport = reportHashToReport[ lastVotedReportHash ]; // Subtract a vote of this oracle member // If the votes == 0, that report was already consolidated if (lastVotedReport.votes > 0) { unchecked { lastVotedReport.votes--; } } } // Remove oracle member addressToVotedReportHash[oracleMemberAddress] = bytes32(0); // Remove the oracle member from the oracleMembers array oracleMembers[oracleMemberIndex] = oracleMembers[ oracleMembers.length - 1 ]; oracleMembers.pop(); emit RemoveOracleMember(oracleMemberAddress); } /** * @notice Update the quorum value * Only the governance can call this function * @param newQuorum new quorum */ function updateQuorum(uint64 newQuorum) external onlyGovernance { require( newQuorum != 0, "DappnodeSmoothingPool::updateQuorum: Quorum cannot be 0" ); quorum = newQuorum; emit UpdateQuorum(newQuorum); } /** * @notice Starts the governance transfer * This is a two step process, the pending governance must accepted to finalize the process * Only the governance can call this function * @param newPendingGovernance new governance address */ function transferGovernance( address newPendingGovernance ) external onlyGovernance { pendingGovernance = newPendingGovernance; emit TransferGovernance(newPendingGovernance); } /** * @notice Allow the current pending governance to accept the governance */ function acceptGovernance() external { require( pendingGovernance == msg.sender, "DappnodeSmoothingPool::acceptGovernance: Only pending governance" ); governance = pendingGovernance; emit AcceptGovernance(pendingGovernance); } /////////////////// // Owner functions /////////////////// /** * @notice Initialize smoothing pool * Only the owner can call this function * @param initialSmoothingPoolSlot Initial smoothing pool slot */ function initSmoothingPool( uint64 initialSmoothingPoolSlot ) external onlyOwner { // Smoothing pool must not have been initialized require( lastConsolidatedSlot == 0, "DappnodeSmoothingPool::initSmoothingPool: Smoothing pool already initialized" ); // Cannot initialize smoothing pool to slot 0 require( initialSmoothingPoolSlot != 0, "DappnodeSmoothingPool::initSmoothingPool: Cannot initialize to slot 0" ); lastConsolidatedSlot = initialSmoothingPoolSlot; emit InitSmoothingPool(initialSmoothingPoolSlot); } /** * @notice Update pool fee * Only the owner can call this function * @param newPoolFee new pool fee */ function updatePoolFee(uint256 newPoolFee) external onlyOwner { require( newPoolFee <= 10000, "DappnodeSmoothingPool::updatePoolFee: Pool fee cannot be greater than 100%" ); poolFee = newPoolFee; emit UpdatePoolFee(newPoolFee); } /** * @notice Update the pool fee recipient * Only the owner can call this function * @param newPoolFeeRecipient new pool fee recipient */ function updatePoolFeeRecipient( address newPoolFeeRecipient ) external onlyOwner { poolFeeRecipient = newPoolFeeRecipient; emit UpdatePoolFeeRecipient(newPoolFeeRecipient); } /** * @notice Update the checkpoint slot size * Only the owner can call this function * @param newCheckpointSlotSize new checkpoint slot size */ function updateCheckpointSlotSize( uint64 newCheckpointSlotSize ) external onlyOwner { checkpointSlotSize = newCheckpointSlotSize; emit UpdateCheckpointSlotSize(newCheckpointSlotSize); } /** * @notice Update the collateral needed to subscribe a validator * Only the owner can call this function * @param newSubscriptionCollateral new subscription collateral */ function updateCollateral( uint256 newSubscriptionCollateral ) external onlyOwner { subscriptionCollateral = newSubscriptionCollateral; emit UpdateSubscriptionCollateral(newSubscriptionCollateral); } /////////////////// // View functions /////////////////// /** * @notice Return oracle member index * @param oracleMember oracle member address */ function getOracleMemberIndex( address oracleMember ) external view returns (uint256) { for (uint256 i = 0; i < oracleMembers.length; ++i) { if (oracleMembers[i] == oracleMember) { return i; } } // In case the oracle member does not exist, revert revert( "DappnodeSmoothingPool::getOracleMemberIndex: Oracle member not found" ); } /** * @notice Return all the oracle members */ function getAllOracleMembers() external view returns (address[] memory) { return oracleMembers; } /** * @notice Return oracle members count */ function getOracleMembersCount() external view returns (uint256) { return oracleMembers.length; } /** * @notice Get the report hash given the rewards root and slot * @param _slot Slot * @param _rewardsRoot Rewards root */ function getReportHash( uint64 _slot, bytes32 _rewardsRoot ) public pure returns (bytes32) { return keccak256(abi.encodePacked(_slot, _rewardsRoot)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ 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"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ 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"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ 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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.2) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Tree proofs. * * The tree and the proofs can be generated using our * https://github.com/OpenZeppelin/merkle-tree[JavaScript library]. * You will find a quickstart guide in the readme. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. * OpenZeppelin's JavaScript library generates merkle trees that are safe * against this attack out of the box. */ library MerkleProofUpgradeable { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify(bytes32[] memory proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Calldata version of {verify} * * _Available since v4.7._ */ function verifyCalldata(bytes32[] calldata proof, bytes32 root, bytes32 leaf) internal pure returns (bool) { return processProofCalldata(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Calldata version of {processProof} * * _Available since v4.7._ */ function processProofCalldata(bytes32[] calldata proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { computedHash = _hashPair(computedHash, proof[i]); } return computedHash; } /** * @dev Returns true if the `leaves` can be simultaneously proven to be a part of a merkle tree defined by * `root`, according to `proof` and `proofFlags` as described in {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerify( bytes32[] memory proof, bool[] memory proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProof(proof, proofFlags, leaves) == root; } /** * @dev Calldata version of {multiProofVerify} * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function multiProofVerifyCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32 root, bytes32[] memory leaves ) internal pure returns (bool) { return processMultiProofCalldata(proof, proofFlags, leaves) == root; } /** * @dev Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`. The reconstruction * proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another * leaf/inner node or a proof sibling node, depending on whether each `proofFlags` item is true or false * respectively. * * CAUTION: Not all merkle trees admit multiproofs. To use multiproofs, it is sufficient to ensure that: 1) the tree * is complete (but not necessarily perfect), 2) the leaves to be proven are in the opposite order they are in the * tree (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer). * * _Available since v4.7._ */ function processMultiProof( bytes32[] memory proof, bool[] memory proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } /** * @dev Calldata version of {processMultiProof}. * * CAUTION: Not all merkle trees admit multiproofs. See {processMultiProof} for details. * * _Available since v4.7._ */ function processMultiProofCalldata( bytes32[] calldata proof, bool[] calldata proofFlags, bytes32[] memory leaves ) internal pure returns (bytes32 merkleRoot) { // This function rebuilds the root hash by traversing the tree up from the leaves. The root is rebuilt by // consuming and producing values on a queue. The queue starts with the `leaves` array, then goes onto the // `hashes` array. At the end of the process, the last hash in the `hashes` array should contain the root of // the merkle tree. uint256 leavesLen = leaves.length; uint256 proofLen = proof.length; uint256 totalHashes = proofFlags.length; // Check proof validity. require(leavesLen + proofLen - 1 == totalHashes, "MerkleProof: invalid multiproof"); // The xxxPos values are "pointers" to the next value to consume in each array. All accesses are done using // `xxx[xxxPos++]`, which return the current value and increment the pointer, thus mimicking a queue's "pop". bytes32[] memory hashes = new bytes32[](totalHashes); uint256 leafPos = 0; uint256 hashPos = 0; uint256 proofPos = 0; // At each step, we compute the next hash using two values: // - a value from the "main queue". If not all leaves have been consumed, we get the next leaf, otherwise we // get the next hash. // - depending on the flag, either another value from the "main queue" (merging branches) or an element from the // `proof` array. for (uint256 i = 0; i < totalHashes; i++) { bytes32 a = leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]; bytes32 b = proofFlags[i] ? (leafPos < leavesLen ? leaves[leafPos++] : hashes[hashPos++]) : proof[proofPos++]; hashes[i] = _hashPair(a, b); } if (totalHashes > 0) { require(proofPos == proofLen, "MerkleProof: invalid multiproof"); unchecked { return hashes[totalHashes - 1]; } } else if (leavesLen > 0) { return leaves[0]; } else { return proof[0]; } } function _hashPair(bytes32 a, bytes32 b) private pure returns (bytes32) { return a < b ? _efficientHash(a, b) : _efficientHash(b, a); } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { /// @solidity memory-safe-assembly assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
{ "optimizer": { "enabled": true, "runs": 999999 }, "evmVersion": "shanghai", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newGovernance","type":"address"}],"name":"AcceptGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOracleMember","type":"address"}],"name":"AddOracleMember","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":false,"internalType":"address","name":"rewardAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimableBalance","type":"uint256"}],"name":"ClaimRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"donationAmount","type":"uint256"}],"name":"EtherReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"initialSmoothingPoolSlot","type":"uint64"}],"name":"InitSmoothingPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","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":"address","name":"oracleMemberRemoved","type":"address"}],"name":"RemoveOracleMember","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"slotNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"newRewardsRoot","type":"bytes32"}],"name":"ReportConsolidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"withdrawalAddress","type":"address"},{"indexed":false,"internalType":"address","name":"poolRecipient","type":"address"}],"name":"SetRewardRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"slotNumber","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"newRewardsRoot","type":"bytes32"},{"indexed":false,"internalType":"address","name":"oracleMember","type":"address"}],"name":"SubmitReport","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"subscriptionCollateral","type":"uint256"},{"indexed":false,"internalType":"uint64","name":"validatorID","type":"uint64"}],"name":"SubscribeValidator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPendingGovernance","type":"address"}],"name":"TransferGovernance","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint64","name":"validatorID","type":"uint64"}],"name":"UnsubscribeValidator","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"newCheckpointSlotSize","type":"uint64"}],"name":"UpdateCheckpointSlotSize","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newPoolFee","type":"uint256"}],"name":"UpdatePoolFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newPoolFeeRecipient","type":"address"}],"name":"UpdatePoolFeeRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"newQuorum","type":"uint64"}],"name":"UpdateQuorum","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newSubscriptionCollateral","type":"uint256"}],"name":"UpdateSubscriptionCollateral","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"INITIAL_REPORT_HASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOracleMember","type":"address"}],"name":"addOracleMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressToVotedReportHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"checkpointSlotSize","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"withdrawalAddress","type":"address"},{"internalType":"uint256","name":"accumulatedBalance","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"claimRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"claimedBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentBlockNumber","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllOracleMembers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oracleMember","type":"address"}],"name":"getOracleMemberIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOracleMembersCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"_slot","type":"uint64"},{"internalType":"bytes32","name":"_rewardsRoot","type":"bytes32"}],"name":"getReportHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"governance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"initialSmoothingPoolSlot","type":"uint64"}],"name":"initSmoothingPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_governance","type":"address"},{"internalType":"uint256","name":"_subscriptionCollateral","type":"uint256"},{"internalType":"uint256","name":"_poolFee","type":"uint256"},{"internalType":"address","name":"_poolFeeRecipient","type":"address"},{"internalType":"uint64","name":"_checkpointSlotSize","type":"uint64"},{"internalType":"uint64","name":"_quorum","type":"uint64"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastConsolidatedSlot","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"oracleMembers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingGovernance","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolFeeRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quorum","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oracleMemberAddress","type":"address"},{"internalType":"uint256","name":"oracleMemberIndex","type":"uint256"}],"name":"removeOracleMember","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"reportHashToReport","outputs":[{"internalType":"uint64","name":"slot","type":"uint64"},{"internalType":"uint64","name":"votes","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"rewardAddress","type":"address"}],"name":"setRewardRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"slotNumber","type":"uint64"},{"internalType":"bytes32","name":"proposedRewardsRoot","type":"bytes32"}],"name":"submitReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"validatorID","type":"uint64"}],"name":"subscribeValidator","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint64[]","name":"validatorIDArray","type":"uint64[]"}],"name":"subscribeValidators","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"subscriptionCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newPendingGovernance","type":"address"}],"name":"transferGovernance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"validatorID","type":"uint64"}],"name":"unsubscribeValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newCheckpointSlotSize","type":"uint64"}],"name":"updateCheckpointSlotSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newSubscriptionCollateral","type":"uint256"}],"name":"updateCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newPoolFee","type":"uint256"}],"name":"updatePoolFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newPoolFeeRecipient","type":"address"}],"name":"updatePoolFeeRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newQuorum","type":"uint64"}],"name":"updateQuorum","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561000f575f80fd5b506131338061001d5f395ff3fe6080604052600436106102ba575f3560e01c80638da5cb5b1161016d578063c7f75d3f116100ca578063e521136f1161007e578063f372c0c911610063578063f372c0c914610809578063f39c38a01461084a578063f93558e314610876576102ba565b8063e521136f146107cb578063f2fde38b146107ea576102ba565b8063d38bfff4116100af578063d38bfff41461076e578063d64bc3311461078d578063e1a80493146107ac576102ba565b8063c7f75d3f1461072d578063cf00421714610759576102ba565b8063b9cd552e11610121578063c1542c5211610106578063c1542c52146106db578063c2cac04b146106fa578063c37f45bf14610719576102ba565b8063b9cd552e1461069d578063c1269650146106b0576102ba565b8063a119d68711610152578063a119d6871461063f578063b164e4371461065f578063b539f38b1461067e576102ba565b80638da5cb5b146105ea5780639886c2a514610614576102ba565b80633964bdca1161021b5780636cf9dfad116101cf57806375f678a0116101b457806375f678a01461058b578063781f5855146105b75780637b5c2f88146105d6576102ba565b80636cf9dfad14610558578063715018a614610577576102ba565b80635aa6e675116102005780635aa6e675146104fa5780635bc37534146105265780636721de2614610539576102ba565b80633964bdca146104bc57806353985e5a146104db576102ba565b8063238efcbc1161027257806329218b611161025757806329218b611461043a57806337215ebd1461045957806338d092b91461049d576102ba565b8063238efcbc146104055780632827acf314610419576102ba565b8063151e4d3d116102a3578063151e4d3d146103825780631703a018146103a3578063217863b7146103f0576102ba565b806303ef4aff146102f4578063089fe6aa1461035f575b604080513381523460208201527f1e57e3bb474320be3d2c77138f75b7c3941292d647f5f9634e33a8e94e0e069b910160405180910390a1005b3480156102ff575f80fd5b5061033961030e366004612c88565b60706020525f908152604090205467ffffffffffffffff808216916801000000000000000090041682565b6040805167ffffffffffffffff9384168152929091166020830152015b60405180910390f35b34801561036a575f80fd5b5061037460695481565b604051908152602001610356565b34801561038d575f80fd5b506103a161039c366004612cde565b61088b565b005b3480156103ae575f80fd5b50606c546103d790700100000000000000000000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610356565b3480156103fb575f80fd5b5061037460665481565b348015610410575f80fd5b506103a1610d4d565b348015610424575f80fd5b5061042d610e71565b6040516103569190612d40565b348015610445575f80fd5b506103a1610454366004612d99565b610ede565b348015610464575f80fd5b50610478610473366004612c88565b6110a2565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610356565b3480156104a8575f80fd5b506103a16104b7366004612d99565b6110d7565b3480156104c7575f80fd5b506103a16104d6366004612d99565b611154565b3480156104e6575f80fd5b506103a16104f5366004612db2565b611342565b348015610505575f80fd5b50606d546104789073ffffffffffffffffffffffffffffffffffffffff1681565b6103a1610534366004612dda565b6117d7565b348015610544575f80fd5b506103a1610553366004612c88565b61193b565b348015610563575f80fd5b506103a1610572366004612e49565b611978565b348015610582575f80fd5b506103a16119f3565b348015610596575f80fd5b50606a546104789073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105c2575f80fd5b506103746105d1366004612e62565b611a06565b3480156105e1575f80fd5b50610374600181565b3480156105f5575f80fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610478565b34801561061f575f80fd5b5061037461062e366004612e49565b60676020525f908152604090205481565b34801561064a575f80fd5b50606c546103d79067ffffffffffffffff1681565b34801561066a575f80fd5b506103a1610679366004612e49565b611a60565b348015610689575f80fd5b506103a1610698366004612e62565b611c6b565b6103a16106ab366004612d99565b61214c565b3480156106bb575f80fd5b506103746106ca366004612e49565b606f6020525f908152604090205481565b3480156106e6575f80fd5b506103a16106f5366004612d99565b61224e565b348015610705575f80fd5b506103a1610714366004612c88565b61228d565b348015610724575f80fd5b50607154610374565b348015610738575f80fd5b50606c546103d79068010000000000000000900467ffffffffffffffff1681565b348015610764575f80fd5b50610374606b5481565b348015610779575f80fd5b506103a1610788366004612e49565b612382565b348015610798575f80fd5b506103a16107a7366004612ea9565b61249c565b3480156107b7575f80fd5b506103746107c6366004612e49565b612766565b3480156107d6575f80fd5b506103a16107e5366004612e49565b612889565b3480156107f5575f80fd5b506103a1610804366004612e49565b61290d565b348015610814575f80fd5b50610478610823366004612e49565b60686020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610855575f80fd5b50606e546104789073ffffffffffffffffffffffffffffffffffffffff1681565b348015610881575f80fd5b5061037460655481565b5f54610100900460ff16158080156108a957505f54600160ff909116105b806108c25750303b1580156108c257505f5460ff166001145b610953576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156109af575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b612710851115610a67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e697469616c697a60448201527f653a20506f6f6c206665652063616e6e6f74206265206772656174657220746860648201527f616e203130302500000000000000000000000000000000000000000000000000608482015260a40161094a565b8167ffffffffffffffff165f03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e697469616c697a60448201527f653a2051756f72756d2063616e6e6f7420626520300000000000000000000000606482015260840161094a565b606d805473ffffffffffffffffffffffffffffffffffffffff808a167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556065889055606c805467ffffffffffffffff868116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9189166801000000000000000002919091167fffffffffffffffff00000000000000000000000000000000ffffffffffffffff909216919091171790556069879055606a80549287169290911691909117905543606b55610bec6129c4565b6040518581527f19d74da91b7de020180f04c1c60faba431bd76ecf962935e6f65ecbf0223ecfc9060200160405180910390a160405173ffffffffffffffffffffffffffffffffffffffff851681527fae901f1a96a9fc6852e6b162ea0b9887c37b667fb5d2d925b6e4a607aac0bf629060200160405180910390a160405167ffffffffffffffff841681527f8e0e8e986a04eea90f6e33488f9756f53cb482049ca8269e6864c797b8bcae6e9060200160405180910390a160405167ffffffffffffffff831681527fb600f3cf7f38a4b49bb0c75f722ef69f7e3e39ef3bb4aa8207fd86e724a232499060200160405180910390a18015610d44575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b606e5473ffffffffffffffffffffffffffffffffffffffff163314610df657604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a616363657074476f7660448201527f65726e616e63653a204f6e6c792070656e64696e6720676f7665726e616e6365606482015260840161094a565b606e54606d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691821790556040519081527f0e5e627abed15db8c4841ff7db9a3fb94e105b243564c206bf485362210eee079060200160405180910390a1565b60606071805480602002602001604051908101604052809291908181526020018280548015610ed457602002820191905f5260205f20905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ea9575b5050505050905090565b606d5473ffffffffffffffffffffffffffffffffffffffff163314610f85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b8067ffffffffffffffff165f0361101e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a75706461746551756f60448201527f72756d3a2051756f72756d2063616e6e6f742062652030000000000000000000606482015260840161094a565b606c80547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fb600f3cf7f38a4b49bb0c75f722ef69f7e3e39ef3bb4aa8207fd86e724a23249906020015b60405180910390a150565b607181815481106110b1575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6110df612a62565b606c80547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8416908102919091179091556040519081527f8e0e8e986a04eea90f6e33488f9756f53cb482049ca8269e6864c797b8bcae6e90602001611097565b61115c612a62565b606c5467ffffffffffffffff161561121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e6974536d6f6f7460448201527f68696e67506f6f6c3a20536d6f6f7468696e6720706f6f6c20616c726561647960648201527f20696e697469616c697a65640000000000000000000000000000000000000000608482015260a40161094a565b8067ffffffffffffffff165f036112db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e6974536d6f6f7460448201527f68696e67506f6f6c3a2043616e6e6f7420696e697469616c697a6520746f207360648201527f6c6f742030000000000000000000000000000000000000000000000000000000608482015260a40161094a565b606c80547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040519081527f517462a977504b91ea9a39b7a880cff34a3a13d734f1b294ae4eb0e5c603c7d090602001611097565b606d5473ffffffffffffffffffffffffffffffffffffffff1633146113e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff82165f908152606f6020526040902054806114c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a72656d6f76654f726160448201527f636c654d656d6265723a20576173206e6f7420616e206f7261636c65206d656d60648201527f6265720000000000000000000000000000000000000000000000000000000000608482015260a40161094a565b8273ffffffffffffffffffffffffffffffffffffffff16607183815481106114eb576114eb612f9b565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16146115bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a72656d6f76654f726160448201527f636c654d656d6265723a204f7261636c65206d656d62657220696e646578206460648201527f6f6573206e6f74206d6174636800000000000000000000000000000000000000608482015260a40161094a565b6001811461165c575f818152607060205260409020805468010000000000000000900467ffffffffffffffff161561165a5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff6801000000000000000080840482169290920116027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781555b505b73ffffffffffffffffffffffffffffffffffffffff83165f908152606f60205260408120556071805461169190600190612ff5565b815481106116a1576116a1612f9b565b5f918252602090912001546071805473ffffffffffffffffffffffffffffffffffffffff90921691849081106116d9576116d9612f9b565b905f5260205f20015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550607180548061172f5761172f613008565b5f8281526020908190207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908301810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff851681527fc8391e8d83bfa93da9636d7a7928b59021752c6e0b74afba127e74914af730a2910160405180910390a1505050565b6065546117e5908290613035565b3414611899576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605b60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a73756273637269626560448201527f56616c696461746f723a206d73672e76616c756520646f6573206e6f7420657160648201527f75616c20737562736372697074696f6e20636f6c6c61746572616c0000000000608482015260a40161094a565b5f5b81811015611936577f1094f8cfeb6abd0fd67e4ce1e1d3999c0176a4d8c7f8325e3ecddb5a1249fde9336065548585858181106118da576118da612f9b565b90506020020160208101906118ef9190612d99565b6040805173ffffffffffffffffffffffffffffffffffffffff9094168452602084019290925267ffffffffffffffff169082015260600160405180910390a160010161189b565b505050565b611943612a62565b60658190556040518181527fdb50d3f51ff6294ba829f0d7f6b99b5b606a52807d5106ef44151d929772021790602001611097565b611980612a62565b606a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fae901f1a96a9fc6852e6b162ea0b9887c37b667fb5d2d925b6e4a607aac0bf6290602001611097565b6119fb612a62565b611a045f612ae3565b565b6040517fffffffffffffffff00000000000000000000000000000000000000000000000060c084901b166020820152602881018290525f906048016040516020818303038152906040528051906020012090505b92915050565b606d5473ffffffffffffffffffffffffffffffffffffffff163314611b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff81165f908152606f602052604090205415611bb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6164644f7261636c6560448201527f4d656d6265723a20416c7265616479206f7261636c65206d656d626572000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff81165f818152606f602090815260408083206001908190556071805491820181559093527fa1fcd19bfe8c32a61095b6bfbb2664842857e148fcbb5188386c8cd40348d5b690920180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905590519182527f82ebad05b594f3bb43fed0280ee782c47f15549310ffb9de21ad790a03dbab189101611097565b606c5467ffffffffffffffff165f819003611d2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a7375626d697452657060448201527f6f72743a20536d6f6f7468696e6720706f6f6c206e6f7420696e697469616c6960648201527f7a65640000000000000000000000000000000000000000000000000000000000608482015260a40161094a565b606c54611d519068010000000000000000900467ffffffffffffffff168261304c565b67ffffffffffffffff168367ffffffffffffffff1614611df3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a7375626d697452657060448201527f6f72743a20536c6f74206e756d62657220696e76616c69640000000000000000606482015260840161094a565b335f908152606f602052604090205480611e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a7375626d697452657060448201527f6f72743a204e6f742061206f7261636c65206d656d6265720000000000000000606482015260840161094a565b60018114611f2c575f818152607060205260409020805468010000000000000000900467ffffffffffffffff1615611f2a5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff6801000000000000000080840482169290920116027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781555b505b5f611f378585611a06565b5f81815260706020908152604080832081518083019092525467ffffffffffffffff8082168084526801000000000000000090920416928201929092529293509003611f965767ffffffffffffffff8616815260016020820152611fb4565b60208101805190611fa682613074565b67ffffffffffffffff169052505b6040805167ffffffffffffffff8816815260208101879052338183015290517fa28058c376f3af4acde9ae77dfe7fc66bc12abc2ad14e37fe60d51e19a6305719181900360600190a1606c54602082015167ffffffffffffffff70010000000000000000000000000000000090920482169116106120da575f8281526070602090815260409182902080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055606c80547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff8a16908117909155606688905582519081529081018790527f92f1a3bddcbec48ac79b5809ed37bf0491f0ad9e89ed4ff2f1ccd4dd9e5b5064910160405180910390a1612144565b5f828152607060209081526040808320845181548487015167ffffffffffffffff90811668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216921691909117179055338352606f90915290208290555b505050505050565b6065543414612203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605b60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a73756273637269626560448201527f56616c696461746f723a206d73672e76616c756520646f6573206e6f7420657160648201527f75616c20737562736372697074696f6e20636f6c6c61746572616c0000000000608482015260a40161094a565b60655460408051338152602081019290925267ffffffffffffffff8316908201527f1094f8cfeb6abd0fd67e4ce1e1d3999c0176a4d8c7f8325e3ecddb5a1249fde990606001611097565b6040805133815267ffffffffffffffff831660208201527f5a984d13ffecb21f69de43956dcd971abcff8e187fac09a0ce3209562da14e0a9101611097565b612295612a62565b61271081111561234d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a757064617465506f6f60448201527f6c4665653a20506f6f6c206665652063616e6e6f74206265206772656174657260648201527f207468616e203130302500000000000000000000000000000000000000000000608482015260a40161094a565b60698190556040518181527f19d74da91b7de020180f04c1c60faba431bd76ecf962935e6f65ecbf0223ecfc90602001611097565b606d5473ffffffffffffffffffffffffffffffffffffffff163314612429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b606e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fde4aabcd09171142d82dd9e667db43bf0dca12f30fa0aec30859875d35ecb5d690602001611097565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390525f906054016040516020818303038152906040528051906020012090506124fc8260665483612b59565b612588576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a636c61696d5265776160448201527f7264733a20496e76616c6964206d65726b6c652070726f6f6600000000000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff84165f908152606760205260408120546125b79085612ff5565b73ffffffffffffffffffffffffffffffffffffffff8087165f908152606760209081526040808320899055606890915281205492935091169081156125fc57816125fe565b865b604080515f808252602082019283905292935073ffffffffffffffffffffffffffffffffffffffff84169186916126349161309a565b5f6040518083038185875af1925050503d805f811461266e576040519150601f19603f3d011682016040523d82523d5f602084013e612673565b606091505b5050905080612704576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a636c61696d5265776160448201527f7264733a20457468207472616e73666572206661696c65640000000000000000606482015260840161094a565b6040805173ffffffffffffffffffffffffffffffffffffffff808b168252841660208201529081018590527f9aa05b3d70a9e3e2f004f039648839560576334fb45c81f91b6db03ad9e2efc99060600160405180910390a15050505050505050565b5f805b6071548110156127d9578273ffffffffffffffffffffffffffffffffffffffff166071828154811061279d5761279d612f9b565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036127c95792915050565b6127d2816130c6565b9050612769565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6765744f7261636c65908201527f4d656d626572496e6465783a204f7261636c65206d656d626572206e6f74206660648201527f6f756e6400000000000000000000000000000000000000000000000000000000608482015260a40161094a565b335f8181526068602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091558251938452908301527fc6b66e0e282673c442421e1c6b89458b7631f26f5dcd0b2b216c45831ca1d7d59101611097565b612915612a62565b73ffffffffffffffffffffffffffffffffffffffff81166129b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161094a565b6129c181612ae3565b50565b5f54610100900460ff16612a5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161094a565b611a04612b6e565b60335473ffffffffffffffffffffffffffffffffffffffff163314611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161094a565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f82612b658584612c0d565b14949350505050565b5f54610100900460ff16612c04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161094a565b611a0433612ae3565b5f81815b8451811015612c5157612c3d82868381518110612c3057612c30612f9b565b6020026020010151612c59565b915080612c49816130c6565b915050612c11565b509392505050565b5f818310612c73575f828152602084905260409020612c81565b5f8381526020839052604090205b9392505050565b5f60208284031215612c98575f80fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612cc2575f80fd5b919050565b803567ffffffffffffffff81168114612cc2575f80fd5b5f805f805f8060c08789031215612cf3575f80fd5b612cfc87612c9f565b95506020870135945060408701359350612d1860608801612c9f565b9250612d2660808801612cc7565b9150612d3460a08801612cc7565b90509295509295509295565b602080825282518282018190525f9190848201906040850190845b81811015612d8d57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d5b565b50909695505050505050565b5f60208284031215612da9575f80fd5b612c8182612cc7565b5f8060408385031215612dc3575f80fd5b612dcc83612c9f565b946020939093013593505050565b5f8060208385031215612deb575f80fd5b823567ffffffffffffffff80821115612e02575f80fd5b818501915085601f830112612e15575f80fd5b813581811115612e23575f80fd5b8660208260051b8501011115612e37575f80fd5b60209290920196919550909350505050565b5f60208284031215612e59575f80fd5b612c8182612c9f565b5f8060408385031215612e73575f80fd5b612dcc83612cc7565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f805f60608486031215612ebb575f80fd5b612ec484612c9f565b92506020808501359250604085013567ffffffffffffffff80821115612ee8575f80fd5b818701915087601f830112612efb575f80fd5b813581811115612f0d57612f0d612e7c565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715612f5057612f50612e7c565b60405291825284820192508381018501918a831115612f6d575f80fd5b938501935b82851015612f8b57843584529385019392850192612f72565b8096505050505050509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115611a5a57611a5a612fc8565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b8082028115828204841417611a5a57611a5a612fc8565b67ffffffffffffffff81811683821601908082111561306d5761306d612fc8565b5092915050565b5f67ffffffffffffffff80831681810361309057613090612fc8565b6001019392505050565b5f82515f5b818110156130b9576020818601810151858301520161309f565b505f920191825250919050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036130f6576130f6612fc8565b506001019056fea264697066735822122001fe83dd7276405b3e1764a6cf08f299bdf1aa813f34ff04a9aa8715e167413764736f6c63430008150033
Deployed Bytecode
0x6080604052600436106102ba575f3560e01c80638da5cb5b1161016d578063c7f75d3f116100ca578063e521136f1161007e578063f372c0c911610063578063f372c0c914610809578063f39c38a01461084a578063f93558e314610876576102ba565b8063e521136f146107cb578063f2fde38b146107ea576102ba565b8063d38bfff4116100af578063d38bfff41461076e578063d64bc3311461078d578063e1a80493146107ac576102ba565b8063c7f75d3f1461072d578063cf00421714610759576102ba565b8063b9cd552e11610121578063c1542c5211610106578063c1542c52146106db578063c2cac04b146106fa578063c37f45bf14610719576102ba565b8063b9cd552e1461069d578063c1269650146106b0576102ba565b8063a119d68711610152578063a119d6871461063f578063b164e4371461065f578063b539f38b1461067e576102ba565b80638da5cb5b146105ea5780639886c2a514610614576102ba565b80633964bdca1161021b5780636cf9dfad116101cf57806375f678a0116101b457806375f678a01461058b578063781f5855146105b75780637b5c2f88146105d6576102ba565b80636cf9dfad14610558578063715018a614610577576102ba565b80635aa6e675116102005780635aa6e675146104fa5780635bc37534146105265780636721de2614610539576102ba565b80633964bdca146104bc57806353985e5a146104db576102ba565b8063238efcbc1161027257806329218b611161025757806329218b611461043a57806337215ebd1461045957806338d092b91461049d576102ba565b8063238efcbc146104055780632827acf314610419576102ba565b8063151e4d3d116102a3578063151e4d3d146103825780631703a018146103a3578063217863b7146103f0576102ba565b806303ef4aff146102f4578063089fe6aa1461035f575b604080513381523460208201527f1e57e3bb474320be3d2c77138f75b7c3941292d647f5f9634e33a8e94e0e069b910160405180910390a1005b3480156102ff575f80fd5b5061033961030e366004612c88565b60706020525f908152604090205467ffffffffffffffff808216916801000000000000000090041682565b6040805167ffffffffffffffff9384168152929091166020830152015b60405180910390f35b34801561036a575f80fd5b5061037460695481565b604051908152602001610356565b34801561038d575f80fd5b506103a161039c366004612cde565b61088b565b005b3480156103ae575f80fd5b50606c546103d790700100000000000000000000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff9091168152602001610356565b3480156103fb575f80fd5b5061037460665481565b348015610410575f80fd5b506103a1610d4d565b348015610424575f80fd5b5061042d610e71565b6040516103569190612d40565b348015610445575f80fd5b506103a1610454366004612d99565b610ede565b348015610464575f80fd5b50610478610473366004612c88565b6110a2565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610356565b3480156104a8575f80fd5b506103a16104b7366004612d99565b6110d7565b3480156104c7575f80fd5b506103a16104d6366004612d99565b611154565b3480156104e6575f80fd5b506103a16104f5366004612db2565b611342565b348015610505575f80fd5b50606d546104789073ffffffffffffffffffffffffffffffffffffffff1681565b6103a1610534366004612dda565b6117d7565b348015610544575f80fd5b506103a1610553366004612c88565b61193b565b348015610563575f80fd5b506103a1610572366004612e49565b611978565b348015610582575f80fd5b506103a16119f3565b348015610596575f80fd5b50606a546104789073ffffffffffffffffffffffffffffffffffffffff1681565b3480156105c2575f80fd5b506103746105d1366004612e62565b611a06565b3480156105e1575f80fd5b50610374600181565b3480156105f5575f80fd5b5060335473ffffffffffffffffffffffffffffffffffffffff16610478565b34801561061f575f80fd5b5061037461062e366004612e49565b60676020525f908152604090205481565b34801561064a575f80fd5b50606c546103d79067ffffffffffffffff1681565b34801561066a575f80fd5b506103a1610679366004612e49565b611a60565b348015610689575f80fd5b506103a1610698366004612e62565b611c6b565b6103a16106ab366004612d99565b61214c565b3480156106bb575f80fd5b506103746106ca366004612e49565b606f6020525f908152604090205481565b3480156106e6575f80fd5b506103a16106f5366004612d99565b61224e565b348015610705575f80fd5b506103a1610714366004612c88565b61228d565b348015610724575f80fd5b50607154610374565b348015610738575f80fd5b50606c546103d79068010000000000000000900467ffffffffffffffff1681565b348015610764575f80fd5b50610374606b5481565b348015610779575f80fd5b506103a1610788366004612e49565b612382565b348015610798575f80fd5b506103a16107a7366004612ea9565b61249c565b3480156107b7575f80fd5b506103746107c6366004612e49565b612766565b3480156107d6575f80fd5b506103a16107e5366004612e49565b612889565b3480156107f5575f80fd5b506103a1610804366004612e49565b61290d565b348015610814575f80fd5b50610478610823366004612e49565b60686020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610855575f80fd5b50606e546104789073ffffffffffffffffffffffffffffffffffffffff1681565b348015610881575f80fd5b5061037460655481565b5f54610100900460ff16158080156108a957505f54600160ff909116105b806108c25750303b1580156108c257505f5460ff166001145b610953576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156109af575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b612710851115610a67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e697469616c697a60448201527f653a20506f6f6c206665652063616e6e6f74206265206772656174657220746860648201527f616e203130302500000000000000000000000000000000000000000000000000608482015260a40161094a565b8167ffffffffffffffff165f03610b00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603560248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e697469616c697a60448201527f653a2051756f72756d2063616e6e6f7420626520300000000000000000000000606482015260840161094a565b606d805473ffffffffffffffffffffffffffffffffffffffff808a167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556065889055606c805467ffffffffffffffff868116700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9189166801000000000000000002919091167fffffffffffffffff00000000000000000000000000000000ffffffffffffffff909216919091171790556069879055606a80549287169290911691909117905543606b55610bec6129c4565b6040518581527f19d74da91b7de020180f04c1c60faba431bd76ecf962935e6f65ecbf0223ecfc9060200160405180910390a160405173ffffffffffffffffffffffffffffffffffffffff851681527fae901f1a96a9fc6852e6b162ea0b9887c37b667fb5d2d925b6e4a607aac0bf629060200160405180910390a160405167ffffffffffffffff841681527f8e0e8e986a04eea90f6e33488f9756f53cb482049ca8269e6864c797b8bcae6e9060200160405180910390a160405167ffffffffffffffff831681527fb600f3cf7f38a4b49bb0c75f722ef69f7e3e39ef3bb4aa8207fd86e724a232499060200160405180910390a18015610d44575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b606e5473ffffffffffffffffffffffffffffffffffffffff163314610df657604080517f08c379a00000000000000000000000000000000000000000000000000000000081526020600482015260248101919091527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a616363657074476f7660448201527f65726e616e63653a204f6e6c792070656e64696e6720676f7665726e616e6365606482015260840161094a565b606e54606d80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff90921691821790556040519081527f0e5e627abed15db8c4841ff7db9a3fb94e105b243564c206bf485362210eee079060200160405180910390a1565b60606071805480602002602001604051908101604052809291908181526020018280548015610ed457602002820191905f5260205f20905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311610ea9575b5050505050905090565b606d5473ffffffffffffffffffffffffffffffffffffffff163314610f85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b8067ffffffffffffffff165f0361101e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a75706461746551756f60448201527f72756d3a2051756f72756d2063616e6e6f742062652030000000000000000000606482015260840161094a565b606c80547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fb600f3cf7f38a4b49bb0c75f722ef69f7e3e39ef3bb4aa8207fd86e724a23249906020015b60405180910390a150565b607181815481106110b1575f80fd5b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16905081565b6110df612a62565b606c80547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8416908102919091179091556040519081527f8e0e8e986a04eea90f6e33488f9756f53cb482049ca8269e6864c797b8bcae6e90602001611097565b61115c612a62565b606c5467ffffffffffffffff161561121c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e6974536d6f6f7460448201527f68696e67506f6f6c3a20536d6f6f7468696e6720706f6f6c20616c726561647960648201527f20696e697469616c697a65640000000000000000000000000000000000000000608482015260a40161094a565b8067ffffffffffffffff165f036112db576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604560248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a696e6974536d6f6f7460448201527f68696e67506f6f6c3a2043616e6e6f7420696e697469616c697a6520746f207360648201527f6c6f742030000000000000000000000000000000000000000000000000000000608482015260a40161094a565b606c80547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff83169081179091556040519081527f517462a977504b91ea9a39b7a880cff34a3a13d734f1b294ae4eb0e5c603c7d090602001611097565b606d5473ffffffffffffffffffffffffffffffffffffffff1633146113e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff82165f908152606f6020526040902054806114c1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a72656d6f76654f726160448201527f636c654d656d6265723a20576173206e6f7420616e206f7261636c65206d656d60648201527f6265720000000000000000000000000000000000000000000000000000000000608482015260a40161094a565b8273ffffffffffffffffffffffffffffffffffffffff16607183815481106114eb576114eb612f9b565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16146115bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604d60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a72656d6f76654f726160448201527f636c654d656d6265723a204f7261636c65206d656d62657220696e646578206460648201527f6f6573206e6f74206d6174636800000000000000000000000000000000000000608482015260a40161094a565b6001811461165c575f818152607060205260409020805468010000000000000000900467ffffffffffffffff161561165a5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff6801000000000000000080840482169290920116027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781555b505b73ffffffffffffffffffffffffffffffffffffffff83165f908152606f60205260408120556071805461169190600190612ff5565b815481106116a1576116a1612f9b565b5f918252602090912001546071805473ffffffffffffffffffffffffffffffffffffffff90921691849081106116d9576116d9612f9b565b905f5260205f20015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550607180548061172f5761172f613008565b5f8281526020908190207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908301810180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905590910190915560405173ffffffffffffffffffffffffffffffffffffffff851681527fc8391e8d83bfa93da9636d7a7928b59021752c6e0b74afba127e74914af730a2910160405180910390a1505050565b6065546117e5908290613035565b3414611899576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605b60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a73756273637269626560448201527f56616c696461746f723a206d73672e76616c756520646f6573206e6f7420657160648201527f75616c20737562736372697074696f6e20636f6c6c61746572616c0000000000608482015260a40161094a565b5f5b81811015611936577f1094f8cfeb6abd0fd67e4ce1e1d3999c0176a4d8c7f8325e3ecddb5a1249fde9336065548585858181106118da576118da612f9b565b90506020020160208101906118ef9190612d99565b6040805173ffffffffffffffffffffffffffffffffffffffff9094168452602084019290925267ffffffffffffffff169082015260600160405180910390a160010161189b565b505050565b611943612a62565b60658190556040518181527fdb50d3f51ff6294ba829f0d7f6b99b5b606a52807d5106ef44151d929772021790602001611097565b611980612a62565b606a80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fae901f1a96a9fc6852e6b162ea0b9887c37b667fb5d2d925b6e4a607aac0bf6290602001611097565b6119fb612a62565b611a045f612ae3565b565b6040517fffffffffffffffff00000000000000000000000000000000000000000000000060c084901b166020820152602881018290525f906048016040516020818303038152906040528051906020012090505b92915050565b606d5473ffffffffffffffffffffffffffffffffffffffff163314611b07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff81165f908152606f602052604090205415611bb9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6164644f7261636c6560448201527f4d656d6265723a20416c7265616479206f7261636c65206d656d626572000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff81165f818152606f602090815260408083206001908190556071805491820181559093527fa1fcd19bfe8c32a61095b6bfbb2664842857e148fcbb5188386c8cd40348d5b690920180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905590519182527f82ebad05b594f3bb43fed0280ee782c47f15549310ffb9de21ad790a03dbab189101611097565b606c5467ffffffffffffffff165f819003611d2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a7375626d697452657060448201527f6f72743a20536d6f6f7468696e6720706f6f6c206e6f7420696e697469616c6960648201527f7a65640000000000000000000000000000000000000000000000000000000000608482015260a40161094a565b606c54611d519068010000000000000000900467ffffffffffffffff168261304c565b67ffffffffffffffff168367ffffffffffffffff1614611df3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a7375626d697452657060448201527f6f72743a20536c6f74206e756d62657220696e76616c69640000000000000000606482015260840161094a565b335f908152606f602052604090205480611e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a7375626d697452657060448201527f6f72743a204e6f742061206f7261636c65206d656d6265720000000000000000606482015260840161094a565b60018114611f2c575f818152607060205260409020805468010000000000000000900467ffffffffffffffff1615611f2a5780547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff6801000000000000000080840482169290920116027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781555b505b5f611f378585611a06565b5f81815260706020908152604080832081518083019092525467ffffffffffffffff8082168084526801000000000000000090920416928201929092529293509003611f965767ffffffffffffffff8616815260016020820152611fb4565b60208101805190611fa682613074565b67ffffffffffffffff169052505b6040805167ffffffffffffffff8816815260208101879052338183015290517fa28058c376f3af4acde9ae77dfe7fc66bc12abc2ad14e37fe60d51e19a6305719181900360600190a1606c54602082015167ffffffffffffffff70010000000000000000000000000000000090920482169116106120da575f8281526070602090815260409182902080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000169055606c80547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff8a16908117909155606688905582519081529081018790527f92f1a3bddcbec48ac79b5809ed37bf0491f0ad9e89ed4ff2f1ccd4dd9e5b5064910160405180910390a1612144565b5f828152607060209081526040808320845181548487015167ffffffffffffffff90811668010000000000000000027fffffffffffffffffffffffffffffffff00000000000000000000000000000000909216921691909117179055338352606f90915290208290555b505050505050565b6065543414612203576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605b60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a73756273637269626560448201527f56616c696461746f723a206d73672e76616c756520646f6573206e6f7420657160648201527f75616c20737562736372697074696f6e20636f6c6c61746572616c0000000000608482015260a40161094a565b60655460408051338152602081019290925267ffffffffffffffff8316908201527f1094f8cfeb6abd0fd67e4ce1e1d3999c0176a4d8c7f8325e3ecddb5a1249fde990606001611097565b6040805133815267ffffffffffffffff831660208201527f5a984d13ffecb21f69de43956dcd971abcff8e187fac09a0ce3209562da14e0a9101611097565b612295612a62565b61271081111561234d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a757064617465506f6f60448201527f6c4665653a20506f6f6c206665652063616e6e6f74206265206772656174657260648201527f207468616e203130302500000000000000000000000000000000000000000000608482015260a40161094a565b60698190556040518181527f19d74da91b7de020180f04c1c60faba431bd76ecf962935e6f65ecbf0223ecfc90602001611097565b606d5473ffffffffffffffffffffffffffffffffffffffff163314612429576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6f6e6c79476f76657260448201527f6e616e63653a204f6e6c7920676f7665726e616e636500000000000000000000606482015260840161094a565b606e80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fde4aabcd09171142d82dd9e667db43bf0dca12f30fa0aec30859875d35ecb5d690602001611097565b6040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606085901b166020820152603481018390525f906054016040516020818303038152906040528051906020012090506124fc8260665483612b59565b612588576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603960248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a636c61696d5265776160448201527f7264733a20496e76616c6964206d65726b6c652070726f6f6600000000000000606482015260840161094a565b73ffffffffffffffffffffffffffffffffffffffff84165f908152606760205260408120546125b79085612ff5565b73ffffffffffffffffffffffffffffffffffffffff8087165f908152606760209081526040808320899055606890915281205492935091169081156125fc57816125fe565b865b604080515f808252602082019283905292935073ffffffffffffffffffffffffffffffffffffffff84169186916126349161309a565b5f6040518083038185875af1925050503d805f811461266e576040519150601f19603f3d011682016040523d82523d5f602084013e612673565b606091505b5050905080612704576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a636c61696d5265776160448201527f7264733a20457468207472616e73666572206661696c65640000000000000000606482015260840161094a565b6040805173ffffffffffffffffffffffffffffffffffffffff808b168252841660208201529081018590527f9aa05b3d70a9e3e2f004f039648839560576334fb45c81f91b6db03ad9e2efc99060600160405180910390a15050505050505050565b5f805b6071548110156127d9578273ffffffffffffffffffffffffffffffffffffffff166071828154811061279d5761279d612f9b565b5f9182526020909120015473ffffffffffffffffffffffffffffffffffffffff16036127c95792915050565b6127d2816130c6565b9050612769565b506040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526044602482018190527f446170706e6f6465536d6f6f7468696e67506f6f6c3a3a6765744f7261636c65908201527f4d656d626572496e6465783a204f7261636c65206d656d626572206e6f74206660648201527f6f756e6400000000000000000000000000000000000000000000000000000000608482015260a40161094a565b335f8181526068602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091558251938452908301527fc6b66e0e282673c442421e1c6b89458b7631f26f5dcd0b2b216c45831ca1d7d59101611097565b612915612a62565b73ffffffffffffffffffffffffffffffffffffffff81166129b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161094a565b6129c181612ae3565b50565b5f54610100900460ff16612a5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161094a565b611a04612b6e565b60335473ffffffffffffffffffffffffffffffffffffffff163314611a04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161094a565b6033805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a35050565b5f82612b658584612c0d565b14949350505050565b5f54610100900460ff16612c04576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161094a565b611a0433612ae3565b5f81815b8451811015612c5157612c3d82868381518110612c3057612c30612f9b565b6020026020010151612c59565b915080612c49816130c6565b915050612c11565b509392505050565b5f818310612c73575f828152602084905260409020612c81565b5f8381526020839052604090205b9392505050565b5f60208284031215612c98575f80fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff81168114612cc2575f80fd5b919050565b803567ffffffffffffffff81168114612cc2575f80fd5b5f805f805f8060c08789031215612cf3575f80fd5b612cfc87612c9f565b95506020870135945060408701359350612d1860608801612c9f565b9250612d2660808801612cc7565b9150612d3460a08801612cc7565b90509295509295509295565b602080825282518282018190525f9190848201906040850190845b81811015612d8d57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101612d5b565b50909695505050505050565b5f60208284031215612da9575f80fd5b612c8182612cc7565b5f8060408385031215612dc3575f80fd5b612dcc83612c9f565b946020939093013593505050565b5f8060208385031215612deb575f80fd5b823567ffffffffffffffff80821115612e02575f80fd5b818501915085601f830112612e15575f80fd5b813581811115612e23575f80fd5b8660208260051b8501011115612e37575f80fd5b60209290920196919550909350505050565b5f60208284031215612e59575f80fd5b612c8182612c9f565b5f8060408385031215612e73575f80fd5b612dcc83612cc7565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b5f805f60608486031215612ebb575f80fd5b612ec484612c9f565b92506020808501359250604085013567ffffffffffffffff80821115612ee8575f80fd5b818701915087601f830112612efb575f80fd5b813581811115612f0d57612f0d612e7c565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715612f5057612f50612e7c565b60405291825284820192508381018501918a831115612f6d575f80fd5b938501935b82851015612f8b57843584529385019392850192612f72565b8096505050505050509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115611a5a57611a5a612fc8565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b8082028115828204841417611a5a57611a5a612fc8565b67ffffffffffffffff81811683821601908082111561306d5761306d612fc8565b5092915050565b5f67ffffffffffffffff80831681810361309057613090612fc8565b6001019392505050565b5f82515f5b818110156130b9576020818601810151858301520161309f565b505f920191825250919050565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036130f6576130f6612fc8565b506001019056fea264697066735822122001fe83dd7276405b3e1764a6cf08f299bdf1aa813f34ff04a9aa8715e167413764736f6c63430008150033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.