Source Code
Overview
DEV Balance
0 DEV
More Info
ContractCreator
Multichain Info
N/A
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
9888166 | 6 mins ago | 0 DEV | ||||
9888149 | 8 mins ago | 0 DEV | ||||
9888100 | 13 mins ago | 0 DEV | ||||
9888079 | 15 mins ago | 0 DEV | ||||
9888028 | 20 mins ago | 0 DEV | ||||
9888011 | 22 mins ago | 0 DEV | ||||
9887960 | 27 mins ago | 0 DEV | ||||
9887939 | 29 mins ago | 0 DEV | ||||
9887887 | 34 mins ago | 0 DEV | ||||
9887870 | 36 mins ago | 0 DEV | ||||
9887816 | 41 mins ago | 0 DEV | ||||
9887802 | 43 mins ago | 0 DEV | ||||
9887748 | 48 mins ago | 0 DEV | ||||
9887732 | 50 mins ago | 0 DEV | ||||
9887678 | 55 mins ago | 0 DEV | ||||
9887660 | 57 mins ago | 0 DEV | ||||
9887609 | 1 hr ago | 0 DEV | ||||
9887594 | 1 hr ago | 0 DEV | ||||
9887541 | 1 hr ago | 0 DEV | ||||
9887520 | 1 hr ago | 0 DEV | ||||
9887471 | 1 hr ago | 0 DEV | ||||
9887455 | 1 hr ago | 0 DEV | ||||
9887397 | 1 hr ago | 0 DEV | ||||
9887380 | 1 hr ago | 0 DEV | ||||
9887327 | 1 hr ago | 0 DEV |
Loading...
Loading
Contract Name:
BlockResultProofChain
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 1 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./IOperationalStaking.sol"; import "@openzeppelin/contracts-upgradeable/utils/structs/EnumerableSetUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; contract BlockResultProofChain is OwnableUpgradeable { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; using EnumerableSetUpgradeable for EnumerableSetUpgradeable.Bytes32Set; IOperationalStaking _stakingInterface; // staking contract (deprecated) bytes32 public constant GOVERNANCE_ROLE = keccak256("GOVERNANCE_ROLE"); bytes32 public constant BLOCK_RESULT_PRODUCER_ROLE = keccak256("BLOCK_RESULT_PRODUCER_ROLE"); bytes32 public constant AUDITOR_ROLE = keccak256("AUDITOR_ROLE"); uint256 private constant _DIVIDER = 10 ** 18; // 18 decimals used for scaling uint256 private _blockResultQuorum; // The value is represented as a uint <= 10**18. The threshold value will later be divided by 10**18 to represent it as a percentage. e.g.) 10**18 == 100%; 5 * 10**17 == 50%; uint256 private _secondsPerBlockCurrentChain; // average block time on the chain where the ProofChain is deployed uint128 private _blockResultRewardAllocation; // the reward allocated per block hash uint128 private _brpRequiredStake; // how much a validator should have staked in order to run an operator uint64 private _blockResultSessionDuration; // the length of a session in blocks uint64 private _minSubmissionsRequired; // min number of participants who submitted the agreed result hash in order for the quorum to be achieved EnumerableSetUpgradeable.Bytes32Set private _roleNames; // set of all role names EnumerableSetUpgradeable.AddressSet private _blockResultProducers; // currently enabled block result producer operators EnumerableSetUpgradeable.AddressSet private _governors; // governor operators EnumerableSetUpgradeable.AddressSet private _auditors; // auditor operators mapping(address => uint128) public validatorIDs; // maps an operator address to validatorId mapping(uint128 => EnumerableSetUpgradeable.AddressSet) private _validatorOperators; // operator addresses that validator owns mapping(address => bytes32) public operatorRoles; // operator address => role mapping(uint128 => uint128) private _validatorActiveOperatorsCounters; // how many operators are enabled per validator given validator id mapping(uint64 => mapping(uint64 => BlockResultSession)) private _sessions; // chainId => blockHeight mapping(uint64 => ChainData) private _chainData; // by chain id mapping(bytes32 => string[]) private _urls; // hash => urls mapping(uint128 => address) private _validatorAddresses; // validatorId => validator address (deprecated) mapping(uint128 => bool) private _validatorEnabled; // validatorId => enabled? address private _stakingManager; struct ChainData { uint256 blockOnTargetChain; // block number on the chain for which BRP are produced which is mapped to the current chain block uint256 blockOnCurrentChain; // block number on the chain where the ProofChain is deployed. it is mapped to the target chain block uint256 secondsPerBlockTargetChain; // average block time on the chain for which BRP is generated uint128 allowedThreshold; // block offsett threshold, used to handle minor de-synchronization over time uint128 maxSubmissionsPerBlockHeight; // max number of block hashes allowed to submit per block height uint64 nthBlock; // block divisor } struct BlockSpecimenProperties { mapping(bytes32 => address[]) participants; // result hash => operators who submitted the result hash bytes32[] resultHashes; // raw result hashes } struct SessionParticipantData { uint128 stake; // stake at the time when an operator submitted the first result hash (deprecate now (always 0)) uint128 submissionCounter; // how many result hashes an operator has submitted } struct BlockResultSession { mapping(bytes32 => BlockSpecimenProperties) blockSpecimenProperties; // block specimen hash => block specimen properties bytes32[] blockSpecimenHashesRaw; mapping(address => SessionParticipantData) participantsData; // stake and submission counter, pack these together to save gas uint64 sessionDeadline; // the last block when an operator can submit a result hash bool isSessionDone; // marker for session finalization } event OperatorAdded(address operator, uint128 validatorId, bytes32 role); event OperatorRemoved(address operator, uint128 validatorId, uint128 activeOperatorCount, bytes32 role); event ValidatorEnabled(uint128 validatorId); event ValidatorDisabled(uint128 validatorId); event BlockResultProductionProofSubmitted( uint64 chainId, uint64 blockHeight, bytes32 blockSpecimenHash, bytes32 resultHash, // SHA-256 content-hash of result object file; string storageURL // URL of result storage ); event SessionStarted(uint64 indexed chainId, uint64 indexed blockHeight, uint64 deadline); event QuorumNotReached(uint64 indexed chainId, uint64 blockHeight); event BlockResultRewardChanged(uint128 newBlockResultRewardAllocation); event MinimumRequiredStakeChanged(uint128 newStakeRequirement); event StakingManagerChanged(address newStakingManager); event ResultSessionQuorumChanged(uint256 newQuorumThreshold); event ResultSessionDurationChanged(uint64 newSessionDuration); event ResultSessionMinSubmissionChanged(uint64 minSubmissions); event NthBlockChanged(uint64 indexed chainId, uint64 indexed nthBlock); event MaxSubmissionsPerBlockHeightChanged(uint256 maxSubmissions); event ChainSyncDataChanged(uint64 indexed chainId, uint256 blockOnTargetChain, uint256 blockOnCurrentChain, uint256 secondsPerBlockTargetChain); event SecondsPerBlockCurrentChainChanged(uint64 indexed secondsPerBlockCurrentChain); event BlockHeightSubmissionThresholdChanged(uint64 indexed chainId, uint64 threshold); event BlockResultQuorum(uint64 indexed chainId, uint64 indexed blockHeight, uint256 validatorBitMap, bytes32 indexed blockSpecimenHash, bytes32 resulthash); modifier onlyGovernor() { require(_governors.contains(msg.sender), "Sender is not GOVERNANCE_ROLE"); _; } modifier onlyStakingManager() { require(msg.sender == _stakingManager, "Sender is not staking manager"); _; } function initialize(address initialGovernor, address stakingManager) public initializer { require(initialGovernor != address(0), "Invalid governor address"); __Ownable_init(); _governors.add(msg.sender); _roleNames.add(GOVERNANCE_ROLE); _roleNames.add(BLOCK_RESULT_PRODUCER_ROLE); _roleNames.add(AUDITOR_ROLE); setQuorumThreshold(_DIVIDER / 2); // 50% setBlockResultReward(10 ** 14); // 0.0001 setBlockResultSessionDuration(240); // blocks setMinSubmissionsRequired(2); setStakingManagerAddress(stakingManager); _governors.remove(msg.sender); operatorRoles[initialGovernor] = GOVERNANCE_ROLE; _governors.add(initialGovernor); emit OperatorAdded(initialGovernor, 0, GOVERNANCE_ROLE); } function disableValidator(uint128 validatorId) external onlyStakingManager { // when remove/disable Brp is called, it emits an event, which might then cause bridge agent to // disable this. require(validatorId < 256, "validatorId out of range"); _validatorEnabled[validatorId] = false; emit ValidatorDisabled(validatorId); } /** * Enables the given operator on the staking contract */ function enableValidator(uint128 validatorId) external onlyStakingManager { // when addBRP is done, it emits an event, which might then cause bridge agent // to enable this. require(validatorId < 256, "validatorId out of range"); _validatorEnabled[validatorId] = true; emit ValidatorEnabled(validatorId); } /** * Disables the operator instance. * If all addresses of the operator are disabled, then the operator (validator) instance will get disabled on the staking contract */ function _removeBRPOperatorFromActiveInstances(address operator) internal { _blockResultProducers.remove(operator); uint128 validatorId = validatorIDs[operator]; _validatorActiveOperatorsCounters[validatorId]--; } /** * Adds the given address to the block result producers set */ function addBRPOperator(address operator, uint128 validatorId) external onlyGovernor { require(operator != address(0), "Invalid operator address"); require(operatorRoles[operator] == 0, "Operator already exists"); require(validatorId <= 255, "Validator ID cannot be greater than 255"); operatorRoles[operator] = BLOCK_RESULT_PRODUCER_ROLE; validatorIDs[operator] = validatorId; _validatorOperators[validatorId].add(operator); _blockResultProducers.add(operator); _validatorActiveOperatorsCounters[validatorId]++; emit OperatorAdded(operator, validatorId, BLOCK_RESULT_PRODUCER_ROLE); } /** * Removes the given address from the block result producers set */ function removeBRPOperator(address operator) external onlyGovernor { require(operatorRoles[operator] == BLOCK_RESULT_PRODUCER_ROLE, "Operator is not BRP"); require(_blockResultProducers.contains(operator), "Operator not found in active instances"); _removeBRPOperatorFromActiveInstances(operator); uint128 validatorID = validatorIDs[operator]; _validatorOperators[validatorID].remove(operator); validatorIDs[operator] = 0; operatorRoles[operator] = 0; emit OperatorRemoved(operator, validatorID, _validatorActiveOperatorsCounters[validatorID], BLOCK_RESULT_PRODUCER_ROLE); } /** * Adds the given address to the auditors set */ function addAuditor(address auditor) external onlyGovernor { require(auditor != address(0), "Invalid auditor address"); require(operatorRoles[auditor] == 0, "Operator already exists"); operatorRoles[auditor] = AUDITOR_ROLE; _auditors.add(auditor); emit OperatorAdded(auditor, 0, AUDITOR_ROLE); } /** * Removes the given address from the auditors set */ function removeAuditor(address auditor) external onlyGovernor { require(operatorRoles[auditor] == AUDITOR_ROLE, "Operator is not auditor"); operatorRoles[auditor] = 0; _auditors.remove(auditor); emit OperatorRemoved(auditor, 0, 0, AUDITOR_ROLE); } /** * Adds the given address to the governors set */ function addGovernor(address governor) external onlyOwner { require(governor != address(0), "Invalid governor address"); require(operatorRoles[governor] == 0, "Operator already exists"); operatorRoles[governor] = GOVERNANCE_ROLE; _governors.add(governor); emit OperatorAdded(governor, 0, GOVERNANCE_ROLE); } /** * Removes the given address from the governors set */ function removeGovernor(address governor) external onlyOwner { require(operatorRoles[governor] == GOVERNANCE_ROLE, "Operator is not governor"); operatorRoles[governor] = 0; _governors.remove(governor); emit OperatorRemoved(governor, 0, 0, GOVERNANCE_ROLE); } /** * Updates the address of the staking manager */ function setStakingManagerAddress(address stakingManagerAddress) public onlyGovernor { require(stakingManagerAddress != address(0), "Invalid address"); _stakingManager = stakingManagerAddress; emit StakingManagerChanged(stakingManagerAddress); } /** * Update the Block Result Quorum Threshold. */ function setQuorumThreshold(uint256 quorum) public onlyGovernor { require(quorum <= _DIVIDER, "Quorum cannot be greater than 100%"); _blockResultQuorum = quorum; emit ResultSessionQuorumChanged(quorum); } /** * Update block divisor */ function setNthBlock(uint64 chainId, uint64 n) public onlyGovernor { require(n > 0, "Nth block cannot be 0"); _chainData[chainId].nthBlock = n; emit NthBlockChanged(chainId, n); } /** * Update the reward allocation per block result. */ function setBlockResultReward(uint128 newBlockResultReward) public onlyGovernor { require(newBlockResultReward <= 1000 * _DIVIDER, "Block result reward cannot be greater than 1000*DIVIDER"); _blockResultRewardAllocation = newBlockResultReward; emit BlockResultRewardChanged(newBlockResultReward); } /** * Update the duration of a result session in blocks */ function setBlockResultSessionDuration(uint64 newSessionDuration) public onlyGovernor { require(newSessionDuration > 0, "Session duration cannot be 0"); _blockResultSessionDuration = newSessionDuration; emit ResultSessionDurationChanged(newSessionDuration); } /** * Update the minimum # of submissions required in order to reach quorum */ function setMinSubmissionsRequired(uint64 minSubmissions) public onlyGovernor { require(minSubmissions >= 1, "Minimum submissions must be at least 1"); require(minSubmissions <= 255, "Maximum allowed minimum submissions is 255"); _minSubmissionsRequired = minSubmissions; emit ResultSessionMinSubmissionChanged(minSubmissions); } /** * Update the max # of submissions per operator per block height */ function setMaxSubmissionsPerBlockHeight(uint64 chainId, uint64 maxSubmissions) public onlyGovernor { require(maxSubmissions > 0, "Max submissions cannot be 0"); require(maxSubmissions <= 3, "Max submissions cannot be more than 3"); require(_chainData[chainId].nthBlock != 0, "Invalid chain ID"); _chainData[chainId].maxSubmissionsPerBlockHeight = maxSubmissions; emit MaxSubmissionsPerBlockHeightChanged(maxSubmissions); } /** * Update chain sync data */ function setChainSyncData(uint64 chainId, uint256 blockOnTargetChain, uint256 blockOnCurrentChain, uint256 secondsPerBlockTargetChain) external onlyGovernor { ChainData storage cd = _chainData[chainId]; require(secondsPerBlockTargetChain > 0, "Seconds per block cannot be 0"); cd.blockOnTargetChain = blockOnTargetChain; cd.blockOnCurrentChain = blockOnCurrentChain; cd.secondsPerBlockTargetChain = secondsPerBlockTargetChain; emit ChainSyncDataChanged(chainId, blockOnTargetChain, blockOnCurrentChain, secondsPerBlockTargetChain); } /** * Update block height submission threshold for live sync */ function setBlockHeightSubmissionsThreshold(uint64 chainId, uint64 threshold) external onlyGovernor { require(threshold > 0, "Threshold cannot be 0"); _chainData[chainId].allowedThreshold = threshold; emit BlockHeightSubmissionThresholdChanged(chainId, threshold); } /** * Update seconds per block on the chain where the ProofChain is deployed */ function setSecondsPerBlockCurrentChain(uint64 secondsPerBlockCurrentChain) external onlyGovernor { require(secondsPerBlockCurrentChain > 0, "Seconds per block cannot be 0"); _secondsPerBlockCurrentChain = secondsPerBlockCurrentChain; emit SecondsPerBlockCurrentChainChanged(secondsPerBlockCurrentChain); } /** * Block Result Producers submit their block result proofs using this function. */ function submitBlockResultProof(uint64 chainId, uint64 blockHeight, bytes32 blockSpecimenHash, bytes32 resultHash, string calldata storageURL) external { require(_isValidSpecimenHash(blockSpecimenHash), "Invalid specimen hash"); require(_isValidResultHash(resultHash), "Invalid result hash"); require(_isValidStorageURL(storageURL), "Invalid storage URL"); require(_blockResultProducers.contains(msg.sender), "Sender is not BLOCK_RESULT_PRODUCER_ROLE"); ChainData storage cd = _chainData[chainId]; require(cd.nthBlock != 0, "Invalid chain ID"); require(blockHeight % cd.nthBlock == 0, "Invalid block height"); BlockResultSession storage session = _sessions[chainId][blockHeight]; uint64 sessionDeadline = session.sessionDeadline; SessionParticipantData storage participantsData = session.participantsData[msg.sender]; // if this is the first result to be submitted for a block, initialize a new session if (sessionDeadline == 0) { require(!session.isSessionDone, "Session submissions have closed"); uint256 currentBlockOnTargetChain = cd.blockOnTargetChain + (((block.number - cd.blockOnCurrentChain) * _secondsPerBlockCurrentChain) / cd.secondsPerBlockTargetChain); uint256 lowerBound = currentBlockOnTargetChain >= cd.allowedThreshold ? currentBlockOnTargetChain - (cd.allowedThreshold / 2) : 0; uint256 upperBound = currentBlockOnTargetChain + (cd.allowedThreshold / 2); require(lowerBound <= blockHeight && blockHeight <= upperBound, "Block height is out of bounds for live sync"); session.sessionDeadline = uint64(block.number + _blockResultSessionDuration); emit SessionStarted(chainId, blockHeight, session.sessionDeadline); uint128 validatorID = validatorIDs[msg.sender]; require(_validatorEnabled[validatorID], "Validator is not enabled"); session.blockSpecimenHashesRaw.push(blockSpecimenHash); BlockSpecimenProperties storage bh = session.blockSpecimenProperties[blockSpecimenHash]; bh.resultHashes.push(resultHash); bh.participants[resultHash].push(msg.sender); participantsData.submissionCounter++; } else { require(block.number <= sessionDeadline, "Session submissions have closed"); require(participantsData.submissionCounter < cd.maxSubmissionsPerBlockHeight, "Max submissions limit exceeded"); BlockSpecimenProperties storage bh = session.blockSpecimenProperties[blockSpecimenHash]; bytes32[] storage resultHashes = bh.resultHashes; uint128 validatorID = validatorIDs[msg.sender]; require(_validatorEnabled[validatorID], "Validator is not enabled"); // check if proof submission was made for this block specimen hash // this should be at about (nValidators * maxSubmissionsPerBlockHeight) iterations // which would typically be less than 50 for (uint256 j = 0; j < resultHashes.length && j < 50; j++) { address[] storage resultHashParticipants = bh.participants[resultHashes[j]]; for (uint256 k = 0; k < resultHashParticipants.length; k++) require(resultHashParticipants[k] != msg.sender, "Operator already submitted for the provided block hash"); } address[] storage participants = bh.participants[resultHash]; if (resultHashes.length != 0) { if (participants.length == 0) resultHashes.push(resultHash); } else { session.blockSpecimenHashesRaw.push(blockSpecimenHash); resultHashes.push(resultHash); } participants.push(msg.sender); participantsData.submissionCounter++; } _urls[resultHash].push(storageURL); emit BlockResultProductionProofSubmitted(chainId, blockHeight, blockSpecimenHash, resultHash, storageURL); } /** * This is the new finalize function that works with staking contract in ethereum */ function finalizeResultSession(uint64 chainId, uint64 blockHeight) public { BlockResultSession storage session = _sessions[chainId][blockHeight]; uint64 sessionDeadline = session.sessionDeadline; require(block.number > sessionDeadline, "Session not past deadline"); require(!session.isSessionDone, "Session cannot be finalized"); require(sessionDeadline != 0, "Session not started"); uint256 contributorsN; bytes32 resultHash; uint256 max; bytes32 agreedBlockSpecimenHash; bytes32 agreedResultHash; bytes32[] storage blockSpecimenHashesRaw = session.blockSpecimenHashesRaw; bytes32 rawBlockSpecimenHash; uint256 blockSpecimenHashesLength = blockSpecimenHashesRaw.length; for (uint256 i = 0; i < blockSpecimenHashesLength; i++) { rawBlockSpecimenHash = blockSpecimenHashesRaw[i]; BlockSpecimenProperties storage bh = session.blockSpecimenProperties[rawBlockSpecimenHash]; for (uint256 j = 0; j < bh.resultHashes.length; j++) { resultHash = bh.resultHashes[j]; uint256 len = bh.participants[resultHash].length; contributorsN += len; if (len > max) { max = len; agreedBlockSpecimenHash = rawBlockSpecimenHash; agreedResultHash = resultHash; } } } // check if the number of submissions is sufficient and if the quorum is achieved if (_minSubmissionsRequired <= max && (max * _DIVIDER) / contributorsN >= _blockResultQuorum) { _finalizeWithParticipants(session, chainId, blockHeight, agreedBlockSpecimenHash, agreedResultHash); } else emit QuorumNotReached(chainId, blockHeight); // prevent further session finalization calls session.isSessionDone = true; session.sessionDeadline = 0; } function _finalizeWithParticipants(BlockResultSession storage session, uint64 chainId, uint64 blockHeight, bytes32 agreedBlockSpecimenHash, bytes32 agreedResultHash) internal { address[] storage participants = session.blockSpecimenProperties[agreedBlockSpecimenHash].participants[agreedResultHash]; uint256 validatorBitMap; // sets the ith bit to 1 if the ith validator submits the agreed result hash mapping(address => SessionParticipantData) storage participantsData = session.participantsData; for (uint256 i = 0; i < participants.length; i++) { address participant = participants[i]; SessionParticipantData storage pd = participantsData[participant]; validatorBitMap |= (1 << (255 - validatorIDs[participant])); // release gas if possible if (pd.submissionCounter > 0) { pd.submissionCounter = 0; } } emit BlockResultQuorum(chainId, blockHeight, validatorBitMap, agreedBlockSpecimenHash, agreedResultHash); // release gas // clear blockSpecimenProperties map for (uint256 i = 0; i < session.blockSpecimenHashesRaw.length; i++) { bytes32 key = session.blockSpecimenHashesRaw[i]; BlockSpecimenProperties storage blockSpecimenProperty = session.blockSpecimenProperties[key]; for (uint256 j = 0; j < blockSpecimenProperty.resultHashes.length; j++) { bytes32 resultHash = blockSpecimenProperty.resultHashes[j]; address[] memory participantsTemp = blockSpecimenProperty.participants[resultHash]; for (uint256 k = 0; k < participantsTemp.length; k++) { delete session.participantsData[participantsTemp[k]]; } delete blockSpecimenProperty.participants[resultHash]; } delete session.blockSpecimenProperties[key]; } delete session.blockSpecimenHashesRaw; } /** * Returns contract meta data */ function getMetadata() public view returns ( address stakingManager, uint128 blockResultRewardAllocation, uint64 blockResultSessionDuration, uint64 minSubmissionsRequired, uint256 blockResultQuorum, uint256 secondsPerBlockCurrentChain ) { return ( address(_stakingManager), _blockResultRewardAllocation, _blockResultSessionDuration, _minSubmissionsRequired, _blockResultQuorum, _secondsPerBlockCurrentChain ); } /** * Returns data used for chain sync */ function getChainData( uint64 chainId ) external view returns ( uint256 blockOnTargetChain, uint256 blockOnCurrentChain, uint256 secondsPerBlockTargetChain, uint128 allowedThreshold, uint128 maxSubmissionsPerBlockHeight, uint64 nthBlock ) { ChainData memory cd = _chainData[chainId]; return (cd.blockOnTargetChain, cd.blockOnCurrentChain, cd.secondsPerBlockTargetChain, cd.allowedThreshold, cd.maxSubmissionsPerBlockHeight, cd.nthBlock); } /** * Returns all brp operator addresses (disabled and enabled) of a given validator */ function getOperators(uint128 validatorId) external view returns (address[] memory) { return _validatorOperators[validatorId].values(); } /** * Returns all enabled operators by role type */ function getAllOperators() external view returns (address[] memory _brps, address[] memory __governors, address[] memory __auditors) { return (_blockResultProducers.values(), _governors.values(), _auditors.values()); } /** * returns enabled operator count for a validator */ function getEnabledOperatorCount(uint128 validatorId) external view returns (uint128) { return _validatorActiveOperatorsCounters[validatorId]; } /** * Returns required stake and enabled block result producer operators */ function getBRPRoleData() external view returns (uint128 requiredStake, address[] memory activeMembers) { return (_brpRequiredStake, _blockResultProducers.values()); } /** * Returns true if the given operator is enabled. * Returns false if the operator is disabled or does not exist */ function isEnabled(address operator) external view returns (bool) { return _blockResultProducers.contains(operator); } /** * Returns true if the given validator is enabled. * Returns false if the validator is disabled or does not exist */ function isValidatorEnabled(uint128 validatorId) external view returns (bool) { return _validatorEnabled[validatorId]; } /** * Returns IPFS urls where results reside */ function getURLS(bytes32 resulthash) external view returns (string[] memory) { return _urls[resulthash]; } /** * This function is called to check whether the sesion is open for the given chain id and block height */ function isSessionOpen(uint64 chainId, uint64 blockHeight, address operator) public view returns (bool) { BlockResultSession storage session = _sessions[chainId][blockHeight]; uint64 sessionDeadline = session.sessionDeadline; SessionParticipantData storage participantsData = session.participantsData[operator]; bool submissionLimitExceeded = participantsData.submissionCounter == _chainData[chainId].maxSubmissionsPerBlockHeight; return (!submissionLimitExceeded && block.number <= sessionDeadline) || (sessionDeadline == 0 && !session.isSessionDone); } function _isValidResultHash(bytes32 resultHash) internal pure returns (bool) { bytes32 zeroHash = bytes32(0); // Check if the input is a valid hash require(resultHash != zeroHash, "Invalid result hash"); return true; } function _isValidSpecimenHash(bytes32 specimenHash) internal pure returns (bool) { bytes32 zeroHash = bytes32(0); // Check if the input is a valid hash require(specimenHash != zeroHash, "Invalid specimen hash"); return true; } function _isValidStorageURL(string memory storageURL) internal pure returns (bool) { // Check if the input is not an empty string return bytes(storageURL).length > 0; } }
//SPDX-License-Identifier: Unlicense pragma solidity ^0.8.13; // blank interface contract which earlier at interface of OperationalStaking.sol which needed to be exposed to proof chain contracts. // but now this is not needed anymore -- the functions are removed, but due to the upgrade rules of smart contract, we cannot remove the interface. interface IOperationalStaking {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. * * [WARNING] * ==== * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable. * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. * * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet. * ==== */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastValue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastValue; // Update the index for the moved value set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; /// @solidity memory-safe-assembly assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing 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 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.7.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] * ``` * 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. Equivalent to `reinitializer(1)`. */ 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. * * `initializer` is equivalent to `reinitializer(1)`, so 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. * * 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. */ 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. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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); } } } }
{ "optimizer": { "enabled": true, "runs": 1 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"threshold","type":"uint64"}],"name":"BlockHeightSubmissionThresholdChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"blockHeight","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"blockSpecimenHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"resultHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"storageURL","type":"string"}],"name":"BlockResultProductionProofSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"blockHeight","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"validatorBitMap","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"blockSpecimenHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"resulthash","type":"bytes32"}],"name":"BlockResultQuorum","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"newBlockResultRewardAllocation","type":"uint128"}],"name":"BlockResultRewardChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"blockOnTargetChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockOnCurrentChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"secondsPerBlockTargetChain","type":"uint256"}],"name":"ChainSyncDataChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxSubmissions","type":"uint256"}],"name":"MaxSubmissionsPerBlockHeightChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"newStakeRequirement","type":"uint128"}],"name":"MinimumRequiredStakeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"nthBlock","type":"uint64"}],"name":"NthBlockChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"OperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"activeOperatorCount","type":"uint128"},{"indexed":false,"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"OperatorRemoved","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":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"blockHeight","type":"uint64"}],"name":"QuorumNotReached","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"newSessionDuration","type":"uint64"}],"name":"ResultSessionDurationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"minSubmissions","type":"uint64"}],"name":"ResultSessionMinSubmissionChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newQuorumThreshold","type":"uint256"}],"name":"ResultSessionQuorumChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"secondsPerBlockCurrentChain","type":"uint64"}],"name":"SecondsPerBlockCurrentChainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"blockHeight","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"deadline","type":"uint64"}],"name":"SessionStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newStakingManager","type":"address"}],"name":"StakingManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"ValidatorDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"ValidatorEnabled","type":"event"},{"inputs":[],"name":"AUDITOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BLOCK_RESULT_PRODUCER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNANCE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"auditor","type":"address"}],"name":"addAuditor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"addBRPOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governor","type":"address"}],"name":"addGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"disableValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"enableValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"blockHeight","type":"uint64"}],"name":"finalizeResultSession","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAllOperators","outputs":[{"internalType":"address[]","name":"_brps","type":"address[]"},{"internalType":"address[]","name":"__governors","type":"address[]"},{"internalType":"address[]","name":"__auditors","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBRPRoleData","outputs":[{"internalType":"uint128","name":"requiredStake","type":"uint128"},{"internalType":"address[]","name":"activeMembers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"}],"name":"getChainData","outputs":[{"internalType":"uint256","name":"blockOnTargetChain","type":"uint256"},{"internalType":"uint256","name":"blockOnCurrentChain","type":"uint256"},{"internalType":"uint256","name":"secondsPerBlockTargetChain","type":"uint256"},{"internalType":"uint128","name":"allowedThreshold","type":"uint128"},{"internalType":"uint128","name":"maxSubmissionsPerBlockHeight","type":"uint128"},{"internalType":"uint64","name":"nthBlock","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"getEnabledOperatorCount","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMetadata","outputs":[{"internalType":"address","name":"stakingManager","type":"address"},{"internalType":"uint128","name":"blockResultRewardAllocation","type":"uint128"},{"internalType":"uint64","name":"blockResultSessionDuration","type":"uint64"},{"internalType":"uint64","name":"minSubmissionsRequired","type":"uint64"},{"internalType":"uint256","name":"blockResultQuorum","type":"uint256"},{"internalType":"uint256","name":"secondsPerBlockCurrentChain","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"getOperators","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"resulthash","type":"bytes32"}],"name":"getURLS","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"initialGovernor","type":"address"},{"internalType":"address","name":"stakingManager","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"isEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"blockHeight","type":"uint64"},{"internalType":"address","name":"operator","type":"address"}],"name":"isSessionOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"}],"name":"isValidatorEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"operatorRoles","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"auditor","type":"address"}],"name":"removeAuditor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"removeBRPOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"governor","type":"address"}],"name":"removeGovernor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"threshold","type":"uint64"}],"name":"setBlockHeightSubmissionsThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"newBlockResultReward","type":"uint128"}],"name":"setBlockResultReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"newSessionDuration","type":"uint64"}],"name":"setBlockResultSessionDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint256","name":"blockOnTargetChain","type":"uint256"},{"internalType":"uint256","name":"blockOnCurrentChain","type":"uint256"},{"internalType":"uint256","name":"secondsPerBlockTargetChain","type":"uint256"}],"name":"setChainSyncData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"maxSubmissions","type":"uint64"}],"name":"setMaxSubmissionsPerBlockHeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"minSubmissions","type":"uint64"}],"name":"setMinSubmissionsRequired","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"n","type":"uint64"}],"name":"setNthBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quorum","type":"uint256"}],"name":"setQuorumThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"secondsPerBlockCurrentChain","type":"uint64"}],"name":"setSecondsPerBlockCurrentChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingManagerAddress","type":"address"}],"name":"setStakingManagerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"blockHeight","type":"uint64"},{"internalType":"bytes32","name":"blockSpecimenHash","type":"bytes32"},{"internalType":"bytes32","name":"resultHash","type":"bytes32"},{"internalType":"string","name":"storageURL","type":"string"}],"name":"submitBlockResultProof","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validatorIDs","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613a60806100206000396000f3fe608060405234801561001057600080fd5b50600436106101cd5760003560e01c80630d92f4ed146101d2578063222388c2146102115780632ba719ad146102265780632c58ed421461023957806337e15bce1461024c5780633c4a25d01461025f57806341c1278d14610272578063429a481b1461029557806342e45079146102d157806343b845b5146102e45780634524c7e114610310578063485cc9551461032357806354cfa69f1461033657806355791fea146104045780635a5e84f2146104175780636543413a1461042a57806367585e441461043d5780636ab9d8e8146104505780636b7511cb146104705780636e1d616e14610483578063715018a6146104985780637a5b4f59146104a05780638da5cb5b1461052e5780639015d37114610543578063920036b71461055657806393742b561461056c578063991462841461057f578063ba75fd2f14610592578063d09796bd146105a5578063d3a8b2a8146105b8578063d5839da9146105d8578063d911c632146105f8578063e32014091461060f578063e429cef114610622578063e6116cfd14610635578063edff4b6114610648578063eecdac881461065b578063f2fde38b1461066e578063f36c8f5c14610681575b600080fd5b6101fb6101e03660046130b1565b6072602052600090815260409020546001600160801b031681565b60405161020891906130cc565b60405180910390f35b61022461021f3660046130f7565b610696565b005b610224610234366004613141565b6108af565b61022461024736600461315c565b61093a565b61022461025a3660046130b1565b610a21565b61022461026d3660046130b1565b610ae6565b610287600080516020613a0b83398151915281565b604051908152602001610208565b6102c16102a3366004613186565b6001600160801b03166000908152607a602052604090205460ff1690565b6040519015158152602001610208565b6102246102df366004613186565b610baf565b6101fb6102f2366004613186565b6001600160801b039081166000908152607560205260409020541690565b61022461031e3660046131a1565b610c53565b6102246103313660046131ba565b610d12565b6103c2610344366004613141565b6001600160401b03908116600090815260776020908152604091829020825160c08101845281548082526001830154938201849052600283015494820185905260038301546001600160801b0380821660608501819052600160801b909204166080840181905260049094015490961660a090920182905295929492565b604080519687526020870195909552938501929092526001600160801b0390811660608501521660808301526001600160401b031660a082015260c001610208565b610224610412366004613141565b610f60565b610224610425366004613186565b61102a565b6102246104383660046131e4565b611128565b61022461044b36600461315c565b611a07565b61028761045e3660046130b1565b60746020526000908152604090205481565b61022461047e3660046130b1565b611b92565b6102876000805160206139cb83398151915281565b610224611d4b565b6104e2607b546068546069546066546067546001600160a01b03909416946001600160801b03909316936001600160401b0380841694600160401b9094041692565b604080516001600160a01b0390971687526001600160801b0390951660208701526001600160401b039384169486019490945291166060840152608083015260a082015260c001610208565b610536611d5f565b6040516102089190613289565b6102c16105513660046130b1565b611d6e565b61055e611d81565b6040516102089291906132e1565b61022461057a366004613141565b611dac565b61022461058d36600461330d565b611efd565b6102c16105a0366004613346565b611fbd565b6102246105b336600461315c565b61207d565b6105cb6105c6366004613186565b612332565b6040516102089190613389565b6105eb6105e63660046131a1565b612356565b604051610208919061339c565b610600612442565b60405161020893929190613437565b61022461061d36600461315c565b612470565b6102246106303660046130b1565b612542565b6102246106433660046130b1565b612654565b610224610656366004613186565b612741565b6102246106693660046130b1565b6127e8565b61022461067c3660046130b1565b6128b7565b6102876000805160206139ab83398151915281565b6106a1606e33612930565b6106c65760405162461bcd60e51b81526004016106bd9061347a565b60405180910390fd5b6001600160a01b0382166107175760405162461bcd60e51b8152602060048201526018602482015277496e76616c6964206f70657261746f72206164647265737360401b60448201526064016106bd565b6001600160a01b0382166000908152607460205260409020541561074d5760405162461bcd60e51b81526004016106bd906134b1565b60ff816001600160801b031611156107b75760405162461bcd60e51b815260206004820152602760248201527f56616c696461746f722049442063616e6e6f742062652067726561746572207460448201526668616e2032353560c81b60648201526084016106bd565b6001600160a01b0382166000908152607460209081526040808320600080516020613a0b83398151915290556072825280832080546001600160801b0319166001600160801b038616908117909155835260739091529020610819908361294c565b50610825606c8361294c565b506001600160801b0380821660009081526075602052604081208054909216919061084f836134f8565b91906101000a8154816001600160801b0302191690836001600160801b031602179055505060008051602061398b8339815191528282600080516020613a0b8339815191526040516108a393929190613526565b60405180910390a15050565b6108ba606e33612930565b6108d65760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b0316116108ff5760405162461bcd60e51b81526004016106bd90613550565b6001600160401b03811660678190556040517f52eb144349cf62d6190a9e1cbb6a601848aa63df834dd2a2e75bb0be3fef86f490600090a250565b610945606e33612930565b6109615760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b0316116109b25760405162461bcd60e51b815260206004820152601560248201527405468726573686f6c642063616e6e6f74206265203605c1b60448201526064016106bd565b6001600160401b038281166000818152607760205260409081902060030180546001600160801b0319169385169390931790925590517f4e4c0afc3a2b327c2f061f8ff5190a491f1042ba8f292a887bab97840947b7a990610a15908490613587565b60405180910390a25050565b610a2c606e33612930565b610a485760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b038116610a905760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016106bd565b607b80546001600160a01b0319166001600160a01b0383161790556040517ff725afeae606c3f3c4c0ac3963e5c76a046bc4f386be98100c54e55bf5aeab3690610adb908390613289565b60405180910390a150565b610aee612961565b6001600160a01b038116610b145760405162461bcd60e51b81526004016106bd9061359b565b6001600160a01b03811660009081526074602052604090205415610b4a5760405162461bcd60e51b81526004016106bd906134b1565b6001600160a01b03811660009081526074602052604090206000805160206139ab8339815191529055610b7e606e8261294c565b5060008051602061398b8339815191528160006000805160206139ab833981519152604051610adb93929190613526565b607b546001600160a01b03163314610bd95760405162461bcd60e51b81526004016106bd906135cd565b610100816001600160801b031610610c035760405162461bcd60e51b81526004016106bd90613604565b6001600160801b0381166000908152607a602052604090819020805460ff19169055517ff97fbe9a37a2eae093c44e9bbcd9afde23ba64215e8fd80b9c49b1fbd4d58e5490610adb9083906130cc565b610c5e606e33612930565b610c7a5760405162461bcd60e51b81526004016106bd9061347a565b670de0b6b3a7640000811115610cdd5760405162461bcd60e51b815260206004820152602260248201527f51756f72756d2063616e6e6f742062652067726561746572207468616e203130604482015261302560f01b60648201526084016106bd565b60668190556040518181527fe8c66e2621de650a92131e007d8bbc4cbf3bb8d4df7471d1f93eb20d70039a7c90602001610adb565b600054610100900460ff1615808015610d325750600054600160ff909116105b80610d4c5750303b158015610d4c575060005460ff166001145b610daf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106bd565b6000805460ff191660011790558015610dd2576000805461ff0019166101001790555b6001600160a01b038316610df85760405162461bcd60e51b81526004016106bd9061359b565b610e006129c0565b610e0b606e3361294c565b50610e25606a6000805160206139ab8339815191526129ef565b50610e3f606a600080516020613a0b8339815191526129ef565b50610e59606a6000805160206139cb8339815191526129ef565b50610e7061031e6002670de0b6b3a764000061364c565b610e7f655af3107a400061102a565b610e8960f0610f60565b610e936002611dac565b610e9c82610a21565b610ea7606e336129fb565b506001600160a01b03831660009081526074602052604090206000805160206139ab8339815191529055610edc606e8461294c565b5060008051602061398b8339815191528360006000805160206139ab833981519152604051610f0d93929190613526565b60405180910390a18015610f5b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610f6b606e33612930565b610f875760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b031611610fdf5760405162461bcd60e51b815260206004820152601c60248201527b053657373696f6e206475726174696f6e2063616e6e6f7420626520360241b60448201526064016106bd565b606980546001600160401b0319166001600160401b0383161790556040517f80972f2be3a50171fc4fb48963f365cbd47dc216ace7f3628a584503a80a9f9790610adb908390613587565b611035606e33612930565b6110515760405162461bcd60e51b81526004016106bd9061347a565b611065670de0b6b3a76400006103e8613660565b816001600160801b031611156110dd5760405162461bcd60e51b815260206004820152603760248201527f426c6f636b20726573756c74207265776172642063616e6e6f7420626520677260448201527632b0ba32b9103a3430b71018981818152224ab24a222a960491b60648201526084016106bd565b606880546001600160801b0319166001600160801b0383161790556040517fa425d7d9b858a4250625446e4504257053202ae93ba0d1dea68dce7ec87a05c590610adb9083906130cc565b61113184612a10565b61114d5760405162461bcd60e51b81526004016106bd9061367f565b61115683612a39565b6111725760405162461bcd60e51b81526004016106bd906136ae565b6111b182828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a5992505050565b6111f35760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081cdd1bdc9859d948155493606a1b60448201526064016106bd565b6111fe606c33612930565b61125b5760405162461bcd60e51b815260206004820152602860248201527f53656e646572206973206e6f7420424c4f434b5f524553554c545f50524f44556044820152674345525f524f4c4560c01b60648201526084016106bd565b6001600160401b0380871660009081526077602052604081206004810154909216900361129a5760405162461bcd60e51b81526004016106bd906136db565b60048101546112b2906001600160401b031687613705565b6001600160401b0316156112ff5760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908189b1bd8dac81a195a59da1d60621b60448201526064016106bd565b6001600160401b0380881660009081526076602090815260408083208a851684528252808320600381015433855260028201909352908320909391909116918290036116b9576003830154600160401b900460ff16156113715760405162461bcd60e51b81526004016106bd9061372b565b6000846002015460675486600101544361138b9190613762565b6113959190613660565b61139f919061364c565b85546113ab9190613779565b60038601549091506000906001600160801b03168210156113cd5760006113fa565b60038601546113e7906002906001600160801b0316613791565b6113fa906001600160801b031683613762565b600387015490915060009061141a906002906001600160801b0316613791565b61142d906001600160801b031684613779565b90508b6001600160401b031682111580156114515750808c6001600160401b031611155b6114b15760405162461bcd60e51b815260206004820152602b60248201527f426c6f636b20686569676874206973206f7574206f6620626f756e647320666f60448201526a72206c6976652073796e6360a81b60648201526084016106bd565b6069546114c7906001600160401b031643613779565b8660030160006101000a8154816001600160401b0302191690836001600160401b031602179055508b6001600160401b03168d6001600160401b03167f8b1f889addbfa41db5227bae3b091bd5c8b9a9122f874dfe54ba2f75aabe1f4c8860030160009054906101000a90046001600160401b03166040516115499190613587565b60405180910390a3336000908152607260209081526040808320546001600160801b0316808452607a9092529091205460ff166115985760405162461bcd60e51b81526004016106bd906137b7565b866001018c908060018154018082558091505060019003906000526020600020016000909190919091505560008760000160008e81526020019081526020016000209050806001018c90806001815401808255809150506001900390600052602060002001600090919091909150558060000160008d8152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555085600001601081819054906101000a90046001600160801b03168092919061168a906134f8565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050611990565b816001600160401b03164311156116e25760405162461bcd60e51b81526004016106bd9061372b565b600384015481546001600160801b03600160801b92839004811692909104161061174e5760405162461bcd60e51b815260206004820152601e60248201527f4d6178207375626d697373696f6e73206c696d6974206578636565646564000060448201526064016106bd565b60008881526020848152604080832033845260728352818420546001600160801b0316808552607a90935292205460018301919060ff166117a15760405162461bcd60e51b81526004016106bd906137b7565b60005b8254811080156117b45750603281105b156118be5760008460000160008584815481106117d3576117d36137e9565b90600052602060002001548152602001908152602001600020905060005b81548110156118a957336001600160a01b0316828281548110611816576118166137e9565b6000918252602090912001546001600160a01b0316036118975760405162461bcd60e51b815260206004820152603660248201527f4f70657261746f7220616c7265616479207375626d697474656420666f7220746044820152750d0ca40e0e4deecd2c8cac840c4d8dec6d640d0c2e6d60531b60648201526084016106bd565b806118a1816137ff565b9150506117f1565b505080806118b6906137ff565b9150506117a4565b5060008a81526020849052604090208254156118f85780546000036118f3578254600181018455600084815260209020018b90555b611925565b600180880180548083018255600091825260208083209091018f9055855492830186558582529020018b90555b80546001810182556000828152602090200180546001600160a01b0319163317905584546001600160801b03600160801b90910416856010611966836134f8565b91906101000a8154816001600160801b0302191690836001600160801b0316021790555050505050505b60008781526078602090815260408220805460018101825590835291206119b991018787612fe2565b507f508f479d80dbbd88c8372648a5a1cf88212d9a3e8aa0f7f516c32c6ae970ebbc8a8a8a8a8a8a6040516119f396959493929190613818565b60405180910390a150505050505050505050565b611a12606e33612930565b611a2e5760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b031611611a855760405162461bcd60e51b815260206004820152601b60248201527a04d6178207375626d697373696f6e732063616e6e6f74206265203602c1b60448201526064016106bd565b6003816001600160401b03161115611aed5760405162461bcd60e51b815260206004820152602560248201527f4d6178207375626d697373696f6e732063616e6e6f74206265206d6f7265207460448201526468616e203360d81b60648201526084016106bd565b6001600160401b038083166000908152607760205260408120600401549091169003611b2b5760405162461bcd60e51b81526004016106bd906136db565b6001600160401b038281166000908152607760205260409081902060030180546001600160801b0316928416600160801b0292909217909155517f1bca1fb481202bb14258ce1030d54e9e7bafc8b696d96b9eb733826e58a3a030906108a3908390613587565b611b9d606e33612930565b611bb95760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b038116600090815260746020526040902054600080516020613a0b83398151915214611c245760405162461bcd60e51b815260206004820152601360248201527204f70657261746f72206973206e6f742042525606c1b60448201526064016106bd565b611c2f606c82612930565b611c8a5760405162461bcd60e51b815260206004820152602660248201527f4f70657261746f72206e6f7420666f756e6420696e2061637469766520696e7360448201526574616e63657360d01b60648201526084016106bd565b611c9381612a5f565b6001600160a01b0381166000908152607260209081526040808320546001600160801b03168084526073909252909120611ccd90836129fb565b506001600160a01b038216600090815260726020908152604080832080546001600160801b0319169055607482528083208390556001600160801b0384811684526075909252918290205491516000805160206139eb833981519152926108a3928692869290911690600080516020613a0b83398151915290613874565b611d53612961565b611d5d6000612ad8565b565b6033546001600160a01b031690565b6000611d7b606c83612930565b92915050565b606854600090606090600160801b90046001600160801b0316611da4606c612b2a565b915091509091565b611db7606e33612930565b611dd35760405162461bcd60e51b81526004016106bd9061347a565b6001816001600160401b03161015611e3c5760405162461bcd60e51b815260206004820152602660248201527f4d696e696d756d207375626d697373696f6e73206d757374206265206174206c60448201526565617374203160d01b60648201526084016106bd565b60ff816001600160401b03161115611ea95760405162461bcd60e51b815260206004820152602a60248201527f4d6178696d756d20616c6c6f776564206d696e696d756d207375626d697373696044820152696f6e732069732032353560b01b60648201526084016106bd565b60698054600160401b600160801b031916600160401b6001600160401b038416021790556040517febd426f3d605bdf7e97ba7cd4a971371661140ad0acc8e0081f067d2004a717690610adb908390613587565b611f08606e33612930565b611f245760405162461bcd60e51b81526004016106bd9061347a565b6001600160401b038416600090815260776020526040902081611f595760405162461bcd60e51b81526004016106bd90613550565b838155600181018390556002810182905560408051858152602081018590529081018390526001600160401b038616907ffd97af399d19e6be9256c99c8e52b1809cdbc4dc96816739612b6fd4e6d940b09060600160405180910390a25050505050565b6001600160401b038381166000818152607660209081526040808320878616845282528083206003808201546001600160a01b03891686526002830185528386209686526077909452918420909101548454939591949290911692600160801b918290046001600160801b039081169290910416148015816120485750826001600160401b03164311155b8061207157506001600160401b03831615801561207157506003840154600160401b900460ff16155b98975050505050505050565b6001600160401b0380831660009081526076602090815260408083208585168452909152902060038101549091164381106120f65760405162461bcd60e51b815260206004820152601960248201527853657373696f6e206e6f74207061737420646561646c696e6560381b60448201526064016106bd565b6003820154600160401b900460ff16156121505760405162461bcd60e51b815260206004820152601b60248201527a14d95cdcda5bdb8818d85b9b9bdd08189948199a5b985b1a5e9959602a1b60448201526064016106bd565b806001600160401b031660000361219f5760405162461bcd60e51b815260206004820152601360248201527214d95cdcda5bdb881b9bdd081cdd185c9d1959606a1b60448201526064016106bd565b6001820180546000918291829182918291908290815b81811015612272578381815481106121cf576121cf6137e9565b6000918252602080832090910154808352908d905260408220909450905b600182015481101561225d5781600101818154811061220e5761220e6137e9565b600091825260208083209091015480835290849052604090912054909a50612236818d613779565b9b508981111561224a578099508598508a97505b5080612255816137ff565b9150506121ed565b5050808061226a906137ff565b9150506121b5565b50606954600160401b90046001600160401b031686108015906122b35750606654886122a6670de0b6b3a764000089613660565b6122b0919061364c565b10155b156122ca576122c58a8d8d8888612b37565b61230c565b8b6001600160401b03167f398fd8f638a7242217f011fd0720a06747f7a85b7d28d7276684b841baea40218c6040516123039190613587565b60405180910390a25b505050600390960180546001600160481b031916600160401b1790555050505050505050565b6001600160801b0381166000908152607360205260409020606090611d7b90612b2a565b606060786000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156124375783829060005260206000200180546123aa906138a4565b80601f01602080910402602001604051908101604052809291908181526020018280546123d6906138a4565b80156124235780601f106123f857610100808354040283529160200191612423565b820191906000526020600020905b81548152906001019060200180831161240657829003601f168201915b50505050508152602001906001019061238b565b505050509050919050565b6060806060612451606c612b2a565b61245b606e612b2a565b6124656070612b2a565b925092509250909192565b61247b606e33612930565b6124975760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b0316116124e85760405162461bcd60e51b815260206004820152601560248201527404e746820626c6f636b2063616e6e6f74206265203605c1b60448201526064016106bd565b6001600160401b0382811660008181526077602052604080822060040180546001600160401b0319169486169485179055517fbbfa9310306e8a8485d109f8be6b0a808473ce55d2e94b8ca3447c9ddb2854b49190a35050565b61254d606e33612930565b6125695760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b0381166125b95760405162461bcd60e51b8152602060048201526017602482015276496e76616c69642061756469746f72206164647265737360481b60448201526064016106bd565b6001600160a01b038116600090815260746020526040902054156125ef5760405162461bcd60e51b81526004016106bd906134b1565b6001600160a01b03811660009081526074602052604090206000805160206139cb833981519152905561262360708261294c565b5060008051602061398b8339815191528160006000805160206139cb833981519152604051610adb93929190613526565b61265f606e33612930565b61267b5760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b0381166000908152607460205260409020546000805160206139cb833981519152146126ea5760405162461bcd60e51b815260206004820152601760248201527627b832b930ba37b91034b9903737ba1030bab234ba37b960491b60448201526064016106bd565b6001600160a01b03811660009081526074602052604081205561270e6070826129fb565b506000805160206139eb833981519152816000806000805160206139cb833981519152604051610adb9493929190613874565b607b546001600160a01b0316331461276b5760405162461bcd60e51b81526004016106bd906135cd565b610100816001600160801b0316106127955760405162461bcd60e51b81526004016106bd90613604565b6001600160801b0381166000908152607a602052604090819020805460ff19166001179055517f553b029ba5c74688a5da732136d246f722502db24ed6b4aaf1cdc9f2f9ef23ef90610adb9083906130cc565b6127f0612961565b6001600160a01b0381166000908152607460205260409020546000805160206139ab833981519152146128605760405162461bcd60e51b815260206004820152601860248201527727b832b930ba37b91034b9903737ba1033b7bb32b93737b960411b60448201526064016106bd565b6001600160a01b038116600090815260746020526040812055612884606e826129fb565b506000805160206139eb833981519152816000806000805160206139ab833981519152604051610adb9493929190613874565b6128bf612961565b6001600160a01b0381166129245760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106bd565b61292d81612ad8565b50565b6000612945836001600160a01b038416612e01565b9392505050565b6000612945836001600160a01b038416612e19565b3361296a611d5f565b6001600160a01b031614611d5d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106bd565b600054610100900460ff166129e75760405162461bcd60e51b81526004016106bd906138de565b611d5d612e63565b60006129458383612e19565b6000612945836001600160a01b038416612e93565b60008082612a305760405162461bcd60e51b81526004016106bd9061367f565b50600192915050565b60008082612a305760405162461bcd60e51b81526004016106bd906136ae565b51151590565b612a6a606c826129fb565b506001600160a01b0381166000908152607260209081526040808320546001600160801b039081168085526075909352908320805492939290911691612aaf83613929565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6060600061294583612f86565b60008281526020868152604080832084845290915281209060028701815b8354811015612bfa576000848281548110612b7257612b726137e9565b60009182526020808320909101546001600160a01b0316808352858252604080842060729093529092205491925090612bb5906001600160801b031660ff61394c565b815460016001600160801b039283161b9690961795600160801b90041615612be55780546001600160801b031681555b50508080612bf2906137ff565b915050612b55565b5084866001600160401b0316886001600160401b03167fab2d4a77e5823abb8d239b8a7c25c6f53f7239af1ccdb18dfd27c7da0db24a228588604051612c4a929190918252602082015260400190565b60405180910390a460005b6001890154811015612de8576000896001018281548110612c7857612c786137e9565b6000918252602080832090910154808352908c905260408220909250905b6001820154811015612db4576000826001018281548110612cb957612cb96137e9565b6000918252602080832090910154808352858252604080842080548251818602810186019093528083529295509092909190830182828015612d2457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d06575b5050505050905060005b8151811015612d87578e6002016000838381518110612d4f57612d4f6137e9565b6020908102919091018101516001600160a01b0316825281019190915260400160009081205580612d7f816137ff565b915050612d2e565b506000828152602085905260408120612d9f91613066565b50508080612dac906137ff565b915050612c96565b50600082815260208c90526040812090612dd16001830182613066565b505050508080612de0906137ff565b915050612c55565b50612df7600189016000613066565b5050505050505050565b60009081526001919091016020526040902054151590565b6000612e258383612e01565b612e5b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611d7b565b506000611d7b565b600054610100900460ff16612e8a5760405162461bcd60e51b81526004016106bd906138de565b611d5d33612ad8565b60008181526001830160205260408120548015612f7c576000612eb7600183613762565b8554909150600090612ecb90600190613762565b9050818114612f30576000866000018281548110612eeb57612eeb6137e9565b9060005260206000200154905080876000018481548110612f0e57612f0e6137e9565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f4157612f41613974565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611d7b565b6000915050611d7b565b606081600001805480602002602001604051908101604052809291908181526020018280548015612fd657602002820191906000526020600020905b815481526020019060010190808311612fc2575b50505050509050919050565b828054612fee906138a4565b90600052602060002090601f0160209004810192826130105760008555613056565b82601f106130295782800160ff19823516178555613056565b82800160010185558215613056579182015b8281111561305657823582559160200191906001019061303b565b50613062929150613080565b5090565b508054600082559060005260206000209081019061292d91905b5b808211156130625760008155600101613081565b80356001600160a01b03811681146130ac57600080fd5b919050565b6000602082840312156130c357600080fd5b61294582613095565b6001600160801b0391909116815260200190565b80356001600160801b03811681146130ac57600080fd5b6000806040838503121561310a57600080fd5b61311383613095565b9150613121602084016130e0565b90509250929050565b80356001600160401b03811681146130ac57600080fd5b60006020828403121561315357600080fd5b6129458261312a565b6000806040838503121561316f57600080fd5b6131788361312a565b91506131216020840161312a565b60006020828403121561319857600080fd5b612945826130e0565b6000602082840312156131b357600080fd5b5035919050565b600080604083850312156131cd57600080fd5b6131d683613095565b915061312160208401613095565b60008060008060008060a087890312156131fd57600080fd5b6132068761312a565b95506132146020880161312a565b9450604087013593506060870135925060808701356001600160401b038082111561323e57600080fd5b818901915089601f83011261325257600080fd5b81358181111561326157600080fd5b8a602082850101111561327357600080fd5b6020830194508093505050509295509295509295565b6001600160a01b0391909116815260200190565b600081518084526020808501945080840160005b838110156132d65781516001600160a01b0316875295820195908201906001016132b1565b509495945050505050565b6001600160801b03831681526040602082018190526000906133059083018461329d565b949350505050565b6000806000806080858703121561332357600080fd5b61332c8561312a565b966020860135965060408601359560600135945092505050565b60008060006060848603121561335b57600080fd5b6133648461312a565b92506133726020850161312a565b915061338060408501613095565b90509250925092565b602081526000612945602083018461329d565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b8381101561342957888603603f1901855282518051808852835b818110156133f9578281018a01518982018b015289016133de565b8181111561340957848a838b0101525b50601f01601f1916969096018701955093860193918601916001016133c4565b509398975050505050505050565b60608152600061344a606083018661329d565b828103602084015261345c818661329d565b90508281036040840152613470818561329d565b9695505050505050565b6020808252601d908201527f53656e646572206973206e6f7420474f5645524e414e43455f524f4c45000000604082015260600190565b6020808252601790820152764f70657261746f7220616c72656164792065786973747360481b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b038281166002600160801b0319810161351c5761351c6134e2565b6001019392505050565b6001600160a01b039390931683526001600160801b03919091166020830152604082015260600190565b6020808252601d908201527f5365636f6e64732070657220626c6f636b2063616e6e6f742062652030000000604082015260600190565b6001600160401b0391909116815260200190565b602080825260189082015277496e76616c696420676f7665726e6f72206164647265737360401b604082015260600190565b6020808252601d908201527f53656e646572206973206e6f74207374616b696e67206d616e61676572000000604082015260600190565b60208082526018908201527776616c696461746f724964206f7574206f662072616e676560401b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b60008261365b5761365b613636565b500490565b600081600019048311821515161561367a5761367a6134e2565b500290565b602080825260159082015274092dcecc2d8d2c840e6e0cac6d2dacadc40d0c2e6d605b1b604082015260600190565b602080825260139082015272092dcecc2d8d2c840e4cae6ead8e840d0c2e6d606b1b604082015260600190565b60208082526010908201526f125b9d985b1a590818da185a5b88125160821b604082015260600190565b60006001600160401b038381168061371f5761371f613636565b92169190910692915050565b6020808252601f908201527f53657373696f6e207375626d697373696f6e73206861766520636c6f73656400604082015260600190565b600082821015613774576137746134e2565b500390565b6000821982111561378c5761378c6134e2565b500190565b60006001600160801b03838116806137ab576137ab613636565b92169190910492915050565b60208082526018908201527715985b1a59185d1bdc881a5cc81b9bdd08195b98589b195960421b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060018201613811576138116134e2565b5060010190565b6001600160401b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b6001600160a01b039490941684526001600160801b03928316602085015291166040830152606082015260800190565b600181811c908216806138b857607f821691505b6020821081036138d857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160801b03821680613942576139426134e2565b6000190192915050565b60006001600160801b038381169083168181101561396c5761396c6134e2565b039392505050565b634e487b7160e01b600052603160045260246000fdfe797ca55fc7be0f65c71f10996f7a16f801094f8ae3811874afc5a39730772a4271840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb159a1c48e5837ad7a7f3dcedcbe129bf3249ec4fbf651fd4f5e2600ead39fe2f5ca6d116f31cc5d708ae73029e1d63d1be48afdfd99819a3405bfbaf229748d9077ae3b5d012484be69eeed881350adb3189b651fac6e88b31ddff30c833a8b7fa26469706673582212206fc52d74f1c5b6810c4638fedaa212de106baefde7ed127e44f19ba1fa64d7e464736f6c634300080d0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101cd5760003560e01c80630d92f4ed146101d2578063222388c2146102115780632ba719ad146102265780632c58ed421461023957806337e15bce1461024c5780633c4a25d01461025f57806341c1278d14610272578063429a481b1461029557806342e45079146102d157806343b845b5146102e45780634524c7e114610310578063485cc9551461032357806354cfa69f1461033657806355791fea146104045780635a5e84f2146104175780636543413a1461042a57806367585e441461043d5780636ab9d8e8146104505780636b7511cb146104705780636e1d616e14610483578063715018a6146104985780637a5b4f59146104a05780638da5cb5b1461052e5780639015d37114610543578063920036b71461055657806393742b561461056c578063991462841461057f578063ba75fd2f14610592578063d09796bd146105a5578063d3a8b2a8146105b8578063d5839da9146105d8578063d911c632146105f8578063e32014091461060f578063e429cef114610622578063e6116cfd14610635578063edff4b6114610648578063eecdac881461065b578063f2fde38b1461066e578063f36c8f5c14610681575b600080fd5b6101fb6101e03660046130b1565b6072602052600090815260409020546001600160801b031681565b60405161020891906130cc565b60405180910390f35b61022461021f3660046130f7565b610696565b005b610224610234366004613141565b6108af565b61022461024736600461315c565b61093a565b61022461025a3660046130b1565b610a21565b61022461026d3660046130b1565b610ae6565b610287600080516020613a0b83398151915281565b604051908152602001610208565b6102c16102a3366004613186565b6001600160801b03166000908152607a602052604090205460ff1690565b6040519015158152602001610208565b6102246102df366004613186565b610baf565b6101fb6102f2366004613186565b6001600160801b039081166000908152607560205260409020541690565b61022461031e3660046131a1565b610c53565b6102246103313660046131ba565b610d12565b6103c2610344366004613141565b6001600160401b03908116600090815260776020908152604091829020825160c08101845281548082526001830154938201849052600283015494820185905260038301546001600160801b0380821660608501819052600160801b909204166080840181905260049094015490961660a090920182905295929492565b604080519687526020870195909552938501929092526001600160801b0390811660608501521660808301526001600160401b031660a082015260c001610208565b610224610412366004613141565b610f60565b610224610425366004613186565b61102a565b6102246104383660046131e4565b611128565b61022461044b36600461315c565b611a07565b61028761045e3660046130b1565b60746020526000908152604090205481565b61022461047e3660046130b1565b611b92565b6102876000805160206139cb83398151915281565b610224611d4b565b6104e2607b546068546069546066546067546001600160a01b03909416946001600160801b03909316936001600160401b0380841694600160401b9094041692565b604080516001600160a01b0390971687526001600160801b0390951660208701526001600160401b039384169486019490945291166060840152608083015260a082015260c001610208565b610536611d5f565b6040516102089190613289565b6102c16105513660046130b1565b611d6e565b61055e611d81565b6040516102089291906132e1565b61022461057a366004613141565b611dac565b61022461058d36600461330d565b611efd565b6102c16105a0366004613346565b611fbd565b6102246105b336600461315c565b61207d565b6105cb6105c6366004613186565b612332565b6040516102089190613389565b6105eb6105e63660046131a1565b612356565b604051610208919061339c565b610600612442565b60405161020893929190613437565b61022461061d36600461315c565b612470565b6102246106303660046130b1565b612542565b6102246106433660046130b1565b612654565b610224610656366004613186565b612741565b6102246106693660046130b1565b6127e8565b61022461067c3660046130b1565b6128b7565b6102876000805160206139ab83398151915281565b6106a1606e33612930565b6106c65760405162461bcd60e51b81526004016106bd9061347a565b60405180910390fd5b6001600160a01b0382166107175760405162461bcd60e51b8152602060048201526018602482015277496e76616c6964206f70657261746f72206164647265737360401b60448201526064016106bd565b6001600160a01b0382166000908152607460205260409020541561074d5760405162461bcd60e51b81526004016106bd906134b1565b60ff816001600160801b031611156107b75760405162461bcd60e51b815260206004820152602760248201527f56616c696461746f722049442063616e6e6f742062652067726561746572207460448201526668616e2032353560c81b60648201526084016106bd565b6001600160a01b0382166000908152607460209081526040808320600080516020613a0b83398151915290556072825280832080546001600160801b0319166001600160801b038616908117909155835260739091529020610819908361294c565b50610825606c8361294c565b506001600160801b0380821660009081526075602052604081208054909216919061084f836134f8565b91906101000a8154816001600160801b0302191690836001600160801b031602179055505060008051602061398b8339815191528282600080516020613a0b8339815191526040516108a393929190613526565b60405180910390a15050565b6108ba606e33612930565b6108d65760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b0316116108ff5760405162461bcd60e51b81526004016106bd90613550565b6001600160401b03811660678190556040517f52eb144349cf62d6190a9e1cbb6a601848aa63df834dd2a2e75bb0be3fef86f490600090a250565b610945606e33612930565b6109615760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b0316116109b25760405162461bcd60e51b815260206004820152601560248201527405468726573686f6c642063616e6e6f74206265203605c1b60448201526064016106bd565b6001600160401b038281166000818152607760205260409081902060030180546001600160801b0319169385169390931790925590517f4e4c0afc3a2b327c2f061f8ff5190a491f1042ba8f292a887bab97840947b7a990610a15908490613587565b60405180910390a25050565b610a2c606e33612930565b610a485760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b038116610a905760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016106bd565b607b80546001600160a01b0319166001600160a01b0383161790556040517ff725afeae606c3f3c4c0ac3963e5c76a046bc4f386be98100c54e55bf5aeab3690610adb908390613289565b60405180910390a150565b610aee612961565b6001600160a01b038116610b145760405162461bcd60e51b81526004016106bd9061359b565b6001600160a01b03811660009081526074602052604090205415610b4a5760405162461bcd60e51b81526004016106bd906134b1565b6001600160a01b03811660009081526074602052604090206000805160206139ab8339815191529055610b7e606e8261294c565b5060008051602061398b8339815191528160006000805160206139ab833981519152604051610adb93929190613526565b607b546001600160a01b03163314610bd95760405162461bcd60e51b81526004016106bd906135cd565b610100816001600160801b031610610c035760405162461bcd60e51b81526004016106bd90613604565b6001600160801b0381166000908152607a602052604090819020805460ff19169055517ff97fbe9a37a2eae093c44e9bbcd9afde23ba64215e8fd80b9c49b1fbd4d58e5490610adb9083906130cc565b610c5e606e33612930565b610c7a5760405162461bcd60e51b81526004016106bd9061347a565b670de0b6b3a7640000811115610cdd5760405162461bcd60e51b815260206004820152602260248201527f51756f72756d2063616e6e6f742062652067726561746572207468616e203130604482015261302560f01b60648201526084016106bd565b60668190556040518181527fe8c66e2621de650a92131e007d8bbc4cbf3bb8d4df7471d1f93eb20d70039a7c90602001610adb565b600054610100900460ff1615808015610d325750600054600160ff909116105b80610d4c5750303b158015610d4c575060005460ff166001145b610daf5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106bd565b6000805460ff191660011790558015610dd2576000805461ff0019166101001790555b6001600160a01b038316610df85760405162461bcd60e51b81526004016106bd9061359b565b610e006129c0565b610e0b606e3361294c565b50610e25606a6000805160206139ab8339815191526129ef565b50610e3f606a600080516020613a0b8339815191526129ef565b50610e59606a6000805160206139cb8339815191526129ef565b50610e7061031e6002670de0b6b3a764000061364c565b610e7f655af3107a400061102a565b610e8960f0610f60565b610e936002611dac565b610e9c82610a21565b610ea7606e336129fb565b506001600160a01b03831660009081526074602052604090206000805160206139ab8339815191529055610edc606e8461294c565b5060008051602061398b8339815191528360006000805160206139ab833981519152604051610f0d93929190613526565b60405180910390a18015610f5b576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610f6b606e33612930565b610f875760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b031611610fdf5760405162461bcd60e51b815260206004820152601c60248201527b053657373696f6e206475726174696f6e2063616e6e6f7420626520360241b60448201526064016106bd565b606980546001600160401b0319166001600160401b0383161790556040517f80972f2be3a50171fc4fb48963f365cbd47dc216ace7f3628a584503a80a9f9790610adb908390613587565b611035606e33612930565b6110515760405162461bcd60e51b81526004016106bd9061347a565b611065670de0b6b3a76400006103e8613660565b816001600160801b031611156110dd5760405162461bcd60e51b815260206004820152603760248201527f426c6f636b20726573756c74207265776172642063616e6e6f7420626520677260448201527632b0ba32b9103a3430b71018981818152224ab24a222a960491b60648201526084016106bd565b606880546001600160801b0319166001600160801b0383161790556040517fa425d7d9b858a4250625446e4504257053202ae93ba0d1dea68dce7ec87a05c590610adb9083906130cc565b61113184612a10565b61114d5760405162461bcd60e51b81526004016106bd9061367f565b61115683612a39565b6111725760405162461bcd60e51b81526004016106bd906136ae565b6111b182828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a5992505050565b6111f35760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081cdd1bdc9859d948155493606a1b60448201526064016106bd565b6111fe606c33612930565b61125b5760405162461bcd60e51b815260206004820152602860248201527f53656e646572206973206e6f7420424c4f434b5f524553554c545f50524f44556044820152674345525f524f4c4560c01b60648201526084016106bd565b6001600160401b0380871660009081526077602052604081206004810154909216900361129a5760405162461bcd60e51b81526004016106bd906136db565b60048101546112b2906001600160401b031687613705565b6001600160401b0316156112ff5760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908189b1bd8dac81a195a59da1d60621b60448201526064016106bd565b6001600160401b0380881660009081526076602090815260408083208a851684528252808320600381015433855260028201909352908320909391909116918290036116b9576003830154600160401b900460ff16156113715760405162461bcd60e51b81526004016106bd9061372b565b6000846002015460675486600101544361138b9190613762565b6113959190613660565b61139f919061364c565b85546113ab9190613779565b60038601549091506000906001600160801b03168210156113cd5760006113fa565b60038601546113e7906002906001600160801b0316613791565b6113fa906001600160801b031683613762565b600387015490915060009061141a906002906001600160801b0316613791565b61142d906001600160801b031684613779565b90508b6001600160401b031682111580156114515750808c6001600160401b031611155b6114b15760405162461bcd60e51b815260206004820152602b60248201527f426c6f636b20686569676874206973206f7574206f6620626f756e647320666f60448201526a72206c6976652073796e6360a81b60648201526084016106bd565b6069546114c7906001600160401b031643613779565b8660030160006101000a8154816001600160401b0302191690836001600160401b031602179055508b6001600160401b03168d6001600160401b03167f8b1f889addbfa41db5227bae3b091bd5c8b9a9122f874dfe54ba2f75aabe1f4c8860030160009054906101000a90046001600160401b03166040516115499190613587565b60405180910390a3336000908152607260209081526040808320546001600160801b0316808452607a9092529091205460ff166115985760405162461bcd60e51b81526004016106bd906137b7565b866001018c908060018154018082558091505060019003906000526020600020016000909190919091505560008760000160008e81526020019081526020016000209050806001018c90806001815401808255809150506001900390600052602060002001600090919091909150558060000160008d8152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555085600001601081819054906101000a90046001600160801b03168092919061168a906134f8565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050611990565b816001600160401b03164311156116e25760405162461bcd60e51b81526004016106bd9061372b565b600384015481546001600160801b03600160801b92839004811692909104161061174e5760405162461bcd60e51b815260206004820152601e60248201527f4d6178207375626d697373696f6e73206c696d6974206578636565646564000060448201526064016106bd565b60008881526020848152604080832033845260728352818420546001600160801b0316808552607a90935292205460018301919060ff166117a15760405162461bcd60e51b81526004016106bd906137b7565b60005b8254811080156117b45750603281105b156118be5760008460000160008584815481106117d3576117d36137e9565b90600052602060002001548152602001908152602001600020905060005b81548110156118a957336001600160a01b0316828281548110611816576118166137e9565b6000918252602090912001546001600160a01b0316036118975760405162461bcd60e51b815260206004820152603660248201527f4f70657261746f7220616c7265616479207375626d697474656420666f7220746044820152750d0ca40e0e4deecd2c8cac840c4d8dec6d640d0c2e6d60531b60648201526084016106bd565b806118a1816137ff565b9150506117f1565b505080806118b6906137ff565b9150506117a4565b5060008a81526020849052604090208254156118f85780546000036118f3578254600181018455600084815260209020018b90555b611925565b600180880180548083018255600091825260208083209091018f9055855492830186558582529020018b90555b80546001810182556000828152602090200180546001600160a01b0319163317905584546001600160801b03600160801b90910416856010611966836134f8565b91906101000a8154816001600160801b0302191690836001600160801b0316021790555050505050505b60008781526078602090815260408220805460018101825590835291206119b991018787612fe2565b507f508f479d80dbbd88c8372648a5a1cf88212d9a3e8aa0f7f516c32c6ae970ebbc8a8a8a8a8a8a6040516119f396959493929190613818565b60405180910390a150505050505050505050565b611a12606e33612930565b611a2e5760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b031611611a855760405162461bcd60e51b815260206004820152601b60248201527a04d6178207375626d697373696f6e732063616e6e6f74206265203602c1b60448201526064016106bd565b6003816001600160401b03161115611aed5760405162461bcd60e51b815260206004820152602560248201527f4d6178207375626d697373696f6e732063616e6e6f74206265206d6f7265207460448201526468616e203360d81b60648201526084016106bd565b6001600160401b038083166000908152607760205260408120600401549091169003611b2b5760405162461bcd60e51b81526004016106bd906136db565b6001600160401b038281166000908152607760205260409081902060030180546001600160801b0316928416600160801b0292909217909155517f1bca1fb481202bb14258ce1030d54e9e7bafc8b696d96b9eb733826e58a3a030906108a3908390613587565b611b9d606e33612930565b611bb95760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b038116600090815260746020526040902054600080516020613a0b83398151915214611c245760405162461bcd60e51b815260206004820152601360248201527204f70657261746f72206973206e6f742042525606c1b60448201526064016106bd565b611c2f606c82612930565b611c8a5760405162461bcd60e51b815260206004820152602660248201527f4f70657261746f72206e6f7420666f756e6420696e2061637469766520696e7360448201526574616e63657360d01b60648201526084016106bd565b611c9381612a5f565b6001600160a01b0381166000908152607260209081526040808320546001600160801b03168084526073909252909120611ccd90836129fb565b506001600160a01b038216600090815260726020908152604080832080546001600160801b0319169055607482528083208390556001600160801b0384811684526075909252918290205491516000805160206139eb833981519152926108a3928692869290911690600080516020613a0b83398151915290613874565b611d53612961565b611d5d6000612ad8565b565b6033546001600160a01b031690565b6000611d7b606c83612930565b92915050565b606854600090606090600160801b90046001600160801b0316611da4606c612b2a565b915091509091565b611db7606e33612930565b611dd35760405162461bcd60e51b81526004016106bd9061347a565b6001816001600160401b03161015611e3c5760405162461bcd60e51b815260206004820152602660248201527f4d696e696d756d207375626d697373696f6e73206d757374206265206174206c60448201526565617374203160d01b60648201526084016106bd565b60ff816001600160401b03161115611ea95760405162461bcd60e51b815260206004820152602a60248201527f4d6178696d756d20616c6c6f776564206d696e696d756d207375626d697373696044820152696f6e732069732032353560b01b60648201526084016106bd565b60698054600160401b600160801b031916600160401b6001600160401b038416021790556040517febd426f3d605bdf7e97ba7cd4a971371661140ad0acc8e0081f067d2004a717690610adb908390613587565b611f08606e33612930565b611f245760405162461bcd60e51b81526004016106bd9061347a565b6001600160401b038416600090815260776020526040902081611f595760405162461bcd60e51b81526004016106bd90613550565b838155600181018390556002810182905560408051858152602081018590529081018390526001600160401b038616907ffd97af399d19e6be9256c99c8e52b1809cdbc4dc96816739612b6fd4e6d940b09060600160405180910390a25050505050565b6001600160401b038381166000818152607660209081526040808320878616845282528083206003808201546001600160a01b03891686526002830185528386209686526077909452918420909101548454939591949290911692600160801b918290046001600160801b039081169290910416148015816120485750826001600160401b03164311155b8061207157506001600160401b03831615801561207157506003840154600160401b900460ff16155b98975050505050505050565b6001600160401b0380831660009081526076602090815260408083208585168452909152902060038101549091164381106120f65760405162461bcd60e51b815260206004820152601960248201527853657373696f6e206e6f74207061737420646561646c696e6560381b60448201526064016106bd565b6003820154600160401b900460ff16156121505760405162461bcd60e51b815260206004820152601b60248201527a14d95cdcda5bdb8818d85b9b9bdd08189948199a5b985b1a5e9959602a1b60448201526064016106bd565b806001600160401b031660000361219f5760405162461bcd60e51b815260206004820152601360248201527214d95cdcda5bdb881b9bdd081cdd185c9d1959606a1b60448201526064016106bd565b6001820180546000918291829182918291908290815b81811015612272578381815481106121cf576121cf6137e9565b6000918252602080832090910154808352908d905260408220909450905b600182015481101561225d5781600101818154811061220e5761220e6137e9565b600091825260208083209091015480835290849052604090912054909a50612236818d613779565b9b508981111561224a578099508598508a97505b5080612255816137ff565b9150506121ed565b5050808061226a906137ff565b9150506121b5565b50606954600160401b90046001600160401b031686108015906122b35750606654886122a6670de0b6b3a764000089613660565b6122b0919061364c565b10155b156122ca576122c58a8d8d8888612b37565b61230c565b8b6001600160401b03167f398fd8f638a7242217f011fd0720a06747f7a85b7d28d7276684b841baea40218c6040516123039190613587565b60405180910390a25b505050600390960180546001600160481b031916600160401b1790555050505050505050565b6001600160801b0381166000908152607360205260409020606090611d7b90612b2a565b606060786000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156124375783829060005260206000200180546123aa906138a4565b80601f01602080910402602001604051908101604052809291908181526020018280546123d6906138a4565b80156124235780601f106123f857610100808354040283529160200191612423565b820191906000526020600020905b81548152906001019060200180831161240657829003601f168201915b50505050508152602001906001019061238b565b505050509050919050565b6060806060612451606c612b2a565b61245b606e612b2a565b6124656070612b2a565b925092509250909192565b61247b606e33612930565b6124975760405162461bcd60e51b81526004016106bd9061347a565b6000816001600160401b0316116124e85760405162461bcd60e51b815260206004820152601560248201527404e746820626c6f636b2063616e6e6f74206265203605c1b60448201526064016106bd565b6001600160401b0382811660008181526077602052604080822060040180546001600160401b0319169486169485179055517fbbfa9310306e8a8485d109f8be6b0a808473ce55d2e94b8ca3447c9ddb2854b49190a35050565b61254d606e33612930565b6125695760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b0381166125b95760405162461bcd60e51b8152602060048201526017602482015276496e76616c69642061756469746f72206164647265737360481b60448201526064016106bd565b6001600160a01b038116600090815260746020526040902054156125ef5760405162461bcd60e51b81526004016106bd906134b1565b6001600160a01b03811660009081526074602052604090206000805160206139cb833981519152905561262360708261294c565b5060008051602061398b8339815191528160006000805160206139cb833981519152604051610adb93929190613526565b61265f606e33612930565b61267b5760405162461bcd60e51b81526004016106bd9061347a565b6001600160a01b0381166000908152607460205260409020546000805160206139cb833981519152146126ea5760405162461bcd60e51b815260206004820152601760248201527627b832b930ba37b91034b9903737ba1030bab234ba37b960491b60448201526064016106bd565b6001600160a01b03811660009081526074602052604081205561270e6070826129fb565b506000805160206139eb833981519152816000806000805160206139cb833981519152604051610adb9493929190613874565b607b546001600160a01b0316331461276b5760405162461bcd60e51b81526004016106bd906135cd565b610100816001600160801b0316106127955760405162461bcd60e51b81526004016106bd90613604565b6001600160801b0381166000908152607a602052604090819020805460ff19166001179055517f553b029ba5c74688a5da732136d246f722502db24ed6b4aaf1cdc9f2f9ef23ef90610adb9083906130cc565b6127f0612961565b6001600160a01b0381166000908152607460205260409020546000805160206139ab833981519152146128605760405162461bcd60e51b815260206004820152601860248201527727b832b930ba37b91034b9903737ba1033b7bb32b93737b960411b60448201526064016106bd565b6001600160a01b038116600090815260746020526040812055612884606e826129fb565b506000805160206139eb833981519152816000806000805160206139ab833981519152604051610adb9493929190613874565b6128bf612961565b6001600160a01b0381166129245760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106bd565b61292d81612ad8565b50565b6000612945836001600160a01b038416612e01565b9392505050565b6000612945836001600160a01b038416612e19565b3361296a611d5f565b6001600160a01b031614611d5d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106bd565b600054610100900460ff166129e75760405162461bcd60e51b81526004016106bd906138de565b611d5d612e63565b60006129458383612e19565b6000612945836001600160a01b038416612e93565b60008082612a305760405162461bcd60e51b81526004016106bd9061367f565b50600192915050565b60008082612a305760405162461bcd60e51b81526004016106bd906136ae565b51151590565b612a6a606c826129fb565b506001600160a01b0381166000908152607260209081526040808320546001600160801b039081168085526075909352908320805492939290911691612aaf83613929565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6060600061294583612f86565b60008281526020868152604080832084845290915281209060028701815b8354811015612bfa576000848281548110612b7257612b726137e9565b60009182526020808320909101546001600160a01b0316808352858252604080842060729093529092205491925090612bb5906001600160801b031660ff61394c565b815460016001600160801b039283161b9690961795600160801b90041615612be55780546001600160801b031681555b50508080612bf2906137ff565b915050612b55565b5084866001600160401b0316886001600160401b03167fab2d4a77e5823abb8d239b8a7c25c6f53f7239af1ccdb18dfd27c7da0db24a228588604051612c4a929190918252602082015260400190565b60405180910390a460005b6001890154811015612de8576000896001018281548110612c7857612c786137e9565b6000918252602080832090910154808352908c905260408220909250905b6001820154811015612db4576000826001018281548110612cb957612cb96137e9565b6000918252602080832090910154808352858252604080842080548251818602810186019093528083529295509092909190830182828015612d2457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d06575b5050505050905060005b8151811015612d87578e6002016000838381518110612d4f57612d4f6137e9565b6020908102919091018101516001600160a01b0316825281019190915260400160009081205580612d7f816137ff565b915050612d2e565b506000828152602085905260408120612d9f91613066565b50508080612dac906137ff565b915050612c96565b50600082815260208c90526040812090612dd16001830182613066565b505050508080612de0906137ff565b915050612c55565b50612df7600189016000613066565b5050505050505050565b60009081526001919091016020526040902054151590565b6000612e258383612e01565b612e5b57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611d7b565b506000611d7b565b600054610100900460ff16612e8a5760405162461bcd60e51b81526004016106bd906138de565b611d5d33612ad8565b60008181526001830160205260408120548015612f7c576000612eb7600183613762565b8554909150600090612ecb90600190613762565b9050818114612f30576000866000018281548110612eeb57612eeb6137e9565b9060005260206000200154905080876000018481548110612f0e57612f0e6137e9565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612f4157612f41613974565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611d7b565b6000915050611d7b565b606081600001805480602002602001604051908101604052809291908181526020018280548015612fd657602002820191906000526020600020905b815481526020019060010190808311612fc2575b50505050509050919050565b828054612fee906138a4565b90600052602060002090601f0160209004810192826130105760008555613056565b82601f106130295782800160ff19823516178555613056565b82800160010185558215613056579182015b8281111561305657823582559160200191906001019061303b565b50613062929150613080565b5090565b508054600082559060005260206000209081019061292d91905b5b808211156130625760008155600101613081565b80356001600160a01b03811681146130ac57600080fd5b919050565b6000602082840312156130c357600080fd5b61294582613095565b6001600160801b0391909116815260200190565b80356001600160801b03811681146130ac57600080fd5b6000806040838503121561310a57600080fd5b61311383613095565b9150613121602084016130e0565b90509250929050565b80356001600160401b03811681146130ac57600080fd5b60006020828403121561315357600080fd5b6129458261312a565b6000806040838503121561316f57600080fd5b6131788361312a565b91506131216020840161312a565b60006020828403121561319857600080fd5b612945826130e0565b6000602082840312156131b357600080fd5b5035919050565b600080604083850312156131cd57600080fd5b6131d683613095565b915061312160208401613095565b60008060008060008060a087890312156131fd57600080fd5b6132068761312a565b95506132146020880161312a565b9450604087013593506060870135925060808701356001600160401b038082111561323e57600080fd5b818901915089601f83011261325257600080fd5b81358181111561326157600080fd5b8a602082850101111561327357600080fd5b6020830194508093505050509295509295509295565b6001600160a01b0391909116815260200190565b600081518084526020808501945080840160005b838110156132d65781516001600160a01b0316875295820195908201906001016132b1565b509495945050505050565b6001600160801b03831681526040602082018190526000906133059083018461329d565b949350505050565b6000806000806080858703121561332357600080fd5b61332c8561312a565b966020860135965060408601359560600135945092505050565b60008060006060848603121561335b57600080fd5b6133648461312a565b92506133726020850161312a565b915061338060408501613095565b90509250925092565b602081526000612945602083018461329d565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b8381101561342957888603603f1901855282518051808852835b818110156133f9578281018a01518982018b015289016133de565b8181111561340957848a838b0101525b50601f01601f1916969096018701955093860193918601916001016133c4565b509398975050505050505050565b60608152600061344a606083018661329d565b828103602084015261345c818661329d565b90508281036040840152613470818561329d565b9695505050505050565b6020808252601d908201527f53656e646572206973206e6f7420474f5645524e414e43455f524f4c45000000604082015260600190565b6020808252601790820152764f70657261746f7220616c72656164792065786973747360481b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b038281166002600160801b0319810161351c5761351c6134e2565b6001019392505050565b6001600160a01b039390931683526001600160801b03919091166020830152604082015260600190565b6020808252601d908201527f5365636f6e64732070657220626c6f636b2063616e6e6f742062652030000000604082015260600190565b6001600160401b0391909116815260200190565b602080825260189082015277496e76616c696420676f7665726e6f72206164647265737360401b604082015260600190565b6020808252601d908201527f53656e646572206973206e6f74207374616b696e67206d616e61676572000000604082015260600190565b60208082526018908201527776616c696461746f724964206f7574206f662072616e676560401b604082015260600190565b634e487b7160e01b600052601260045260246000fd5b60008261365b5761365b613636565b500490565b600081600019048311821515161561367a5761367a6134e2565b500290565b602080825260159082015274092dcecc2d8d2c840e6e0cac6d2dacadc40d0c2e6d605b1b604082015260600190565b602080825260139082015272092dcecc2d8d2c840e4cae6ead8e840d0c2e6d606b1b604082015260600190565b60208082526010908201526f125b9d985b1a590818da185a5b88125160821b604082015260600190565b60006001600160401b038381168061371f5761371f613636565b92169190910692915050565b6020808252601f908201527f53657373696f6e207375626d697373696f6e73206861766520636c6f73656400604082015260600190565b600082821015613774576137746134e2565b500390565b6000821982111561378c5761378c6134e2565b500190565b60006001600160801b03838116806137ab576137ab613636565b92169190910492915050565b60208082526018908201527715985b1a59185d1bdc881a5cc81b9bdd08195b98589b195960421b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b600060018201613811576138116134e2565b5060010190565b6001600160401b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b6001600160a01b039490941684526001600160801b03928316602085015291166040830152606082015260800190565b600181811c908216806138b857607f821691505b6020821081036138d857634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160801b03821680613942576139426134e2565b6000190192915050565b60006001600160801b038381169083168181101561396c5761396c6134e2565b039392505050565b634e487b7160e01b600052603160045260246000fdfe797ca55fc7be0f65c71f10996f7a16f801094f8ae3811874afc5a39730772a4271840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb159a1c48e5837ad7a7f3dcedcbe129bf3249ec4fbf651fd4f5e2600ead39fe2f5ca6d116f31cc5d708ae73029e1d63d1be48afdfd99819a3405bfbaf229748d9077ae3b5d012484be69eeed881350adb3189b651fac6e88b31ddff30c833a8b7fa26469706673582212206fc52d74f1c5b6810c4638fedaa212de106baefde7ed127e44f19ba1fa64d7e464736f6c634300080d0033
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.