Source Code
Overview
GLMR Balance
GLMR Value
$0.00View more zero value Internal Transactions in Advanced View mode
Cross-Chain Transactions
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
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 _secondsPerBlock; // 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
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 secondsPerBlock; // 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
uint128 submissionCounter; // how many result hashes an operator has submitted
}
struct BlockResultSession {
mapping(bytes32 => BlockSpecimenProperties) blockSpecimenProperties;
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 requiresAudit; // auditor can arbitrate the session only if this is set to true
}
event OperatorAdded(address operator, uint128 validatorId, bytes32 role);
event OperatorRemoved(address operator);
event OperatorEnabled(address operator);
event OperatorDisabled(address operator);
event BlockResultProductionProofSubmitted(
uint64 chainId,
uint64 blockHeight,
bytes32 blockSpecimenHash,
bytes32 resultHash, // SHA-256 content-hash of result object file;
string storageURL, // URL of result storage
uint128 submittedStake
);
event SessionStarted(uint64 indexed chainId, uint64 indexed blockHeight, uint64 deadline);
event BlockResultRewardAwarded(uint64 indexed chainId, uint64 indexed blockHeight, bytes32 indexed blockSpecimenHash, bytes32 resulthash);
event QuorumNotReached(uint64 indexed chainId, uint64 blockHeight);
event BlockResultRewardChanged(uint128 newBlockResultRewardAllocation);
event MinimumRequiredStakeChanged(uint128 newStakeRequirement);
event StakingInterfaceChanged(address newInterfaceAddress);
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 secondsPerBlock);
event SecondsPerBlockChanged(uint64 indexed secondsPerBlock);
event BlockHeightSubmissionThresholdChanged(uint64 indexed chainId, uint64 threshold);
modifier onlyGovernor() {
require(_governors.contains(msg.sender), "Sender is not GOVERNANCE_ROLE");
_;
}
/**
* Operators will have multiple addresses: the address they submit the proofs from and the address that manages staking and operator instances
*/
modifier onlyOperatorManager(address operator) {
(address validatorAddress, , , ) = _stakingInterface.getValidatorMetadata(validatorIDs[operator]);
require(validatorAddress == msg.sender, "Sender is not operator manager");
_;
}
function initialize(address initialOwner, address stakingContract) public initializer {
__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);
setStakingInterface(stakingContract);
_governors.remove(msg.sender);
operatorRoles[initialOwner] = GOVERNANCE_ROLE;
_governors.add(initialOwner);
emit OperatorAdded(initialOwner, 0, GOVERNANCE_ROLE);
}
/**
* Adds operator on the staking contract
*/
function addValidator(address validator, uint128 commissionRate) external onlyGovernor {
_stakingInterface.addValidator(validator, commissionRate);
}
/**
* Disables the given operator on the staking contract
*/
function disableValidator(uint128 validatorId, uint256 blockNumber) external onlyGovernor {
_stakingInterface.disableValidator(validatorId, blockNumber);
}
/**
* 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]--;
// if there are not more enabled operators left we need to disable the validator instance too
if (_validatorActiveOperatorsCounters[validatorId] == 0) _stakingInterface.disableValidator(validatorId, block.number);
}
/**
* Enables the operator instance. The operators need to call that function before they can start submitting proofs
*/
function enableBRPOperator(address operator) external onlyOperatorManager(operator) {
require(operatorRoles[operator] == BLOCK_RESULT_PRODUCER_ROLE, "Operator is not BRP");
require(!_blockResultProducers.contains(operator), "Operator is already enabled");
uint128 validatorId = validatorIDs[operator];
_blockResultProducers.add(operator);
_validatorActiveOperatorsCounters[validatorId]++;
// attempt to enable the validator, or ensure that it is still enabled
_stakingInterface.enableValidator(validatorId);
emit OperatorEnabled(operator);
}
/**
* Disables the operator instance. The operator cannot submit proofs its instance got disabled.
* If all addresses of the operator are disabled, then the operator (validator) instance will get disabled on the staking contract
*/
function disableBRPOperator(address operator) external onlyOperatorManager(operator) {
require(operatorRoles[operator] == BLOCK_RESULT_PRODUCER_ROLE, "Operator is not BRP");
require(_blockResultProducers.contains(operator), "Operator is already disabled");
_removeBRPOperatorFromActiveInstances(operator);
emit OperatorDisabled(operator);
}
/**
* Adds the given address to the block result producers set
*/
function addBRPOperator(address operator, uint128 validatorId) external onlyGovernor {
require(operatorRoles[operator] == 0, "Operator already exists");
operatorRoles[operator] = BLOCK_RESULT_PRODUCER_ROLE;
validatorIDs[operator] = validatorId;
_validatorOperators[validatorId].add(operator);
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");
if (_blockResultProducers.contains(operator)) _removeBRPOperatorFromActiveInstances(operator);
_validatorOperators[validatorIDs[operator]].remove(operator);
validatorIDs[operator] = 0;
operatorRoles[operator] = 0;
emit OperatorRemoved(operator);
}
/**
* Adds the given address to the auditors set
*/
function addAuditor(address auditor) external onlyGovernor {
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);
}
/**
* Adds the given address to the governors set
*/
function addGovernor(address governor) external onlyOwner {
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);
}
/**
* Updates the address of the staking contract
*/
function setStakingInterface(address stakingContractAddress) public onlyGovernor {
_stakingInterface = IOperationalStaking(stakingContractAddress);
emit StakingInterfaceChanged(stakingContractAddress);
}
/**
* Update the Block Result Quorum Threshold.
*/
function setQuorumThreshold(uint256 quorum) public onlyGovernor {
_blockResultQuorum = quorum;
emit ResultSessionQuorumChanged(quorum);
}
/**
* Update block divisor
*/
function setNthBlock(uint64 chainId, uint64 n) public onlyGovernor {
_chainData[chainId].nthBlock = n;
emit NthBlockChanged(chainId, n);
}
/**
* Update the reward allocation per block result.
*/
function setBlockResultReward(uint128 newBlockResultReward) public onlyGovernor {
_blockResultRewardAllocation = newBlockResultReward;
emit BlockResultRewardChanged(newBlockResultReward);
}
/**
* Update the duration of a result session in blocks
*/
function setBlockResultSessionDuration(uint64 newSessionDuration) public onlyGovernor {
_blockResultSessionDuration = newSessionDuration;
emit ResultSessionDurationChanged(newSessionDuration);
}
/**
* Update the minimum # of submissions required in order to reach quorum
*/
function setMinSubmissionsRequired(uint64 minSubmissions) public onlyGovernor {
_minSubmissionsRequired = minSubmissions;
emit ResultSessionMinSubmissionChanged(minSubmissions);
}
/**
* Update the max # of submissions per operator per block height
*/
function setMaxSubmissionsPerBlockHeight(uint64 chainId, uint64 maxSubmissions) public onlyGovernor {
_chainData[chainId].maxSubmissionsPerBlockHeight = maxSubmissions;
emit MaxSubmissionsPerBlockHeightChanged(maxSubmissions);
}
/**
* Update chain sync data
*/
function setChainSyncData(
uint64 chainId,
uint256 blockOnTargetChain,
uint256 blockOnCurrentChain,
uint256 secondsPerBlock
) external onlyGovernor {
ChainData storage cd = _chainData[chainId];
require(secondsPerBlock > 0, "Seconds per block cannot be 0");
cd.blockOnTargetChain = blockOnTargetChain;
cd.blockOnCurrentChain = blockOnCurrentChain;
cd.secondsPerBlock = secondsPerBlock;
emit ChainSyncDataChanged(chainId, blockOnTargetChain, blockOnCurrentChain, secondsPerBlock);
}
/**
* Update block height submission threshold for live sync
*/
function setBlockHeightSubmissionsThreshold(uint64 chainId, uint64 threshold) external onlyGovernor {
_chainData[chainId].allowedThreshold = threshold;
emit BlockHeightSubmissionThresholdChanged(chainId, threshold);
}
/**
* Update seconds per block on the chain where the ProofChain is deployed
*/
function setSecondsPerBlock(uint64 secondsPerBlock) external onlyGovernor {
_secondsPerBlock = secondsPerBlock;
emit SecondsPerBlockChanged(secondsPerBlock);
}
/**
* 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(_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.requiresAudit, "Session submissions have closed");
uint256 currentBlockOnTargetChain = cd.blockOnTargetChain + (((block.number - cd.blockOnCurrentChain) * _secondsPerBlock) / cd.secondsPerBlock);
uint256 lowerBound = currentBlockOnTargetChain >= cd.allowedThreshold ? currentBlockOnTargetChain - cd.allowedThreshold : 0;
require(lowerBound <= blockHeight && blockHeight <= currentBlockOnTargetChain + cd.allowedThreshold, "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(_stakingInterface.isValidatorEnabled(validatorID), "Validator is not enabled");
(uint128 baseStake, uint128 delegateStakes) = _stakingInterface.getValidatorCompoundedStakingData(validatorID);
participantsData.stake = baseStake + delegateStakes;
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;
if (participantsData.stake != 0) {
// check if it was submitted for the same block hash
// this should be at most 10 iterations
for (uint256 j = 0; j < resultHashes.length; 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");
}
} else {
uint128 validatorID = validatorIDs[msg.sender];
require(_stakingInterface.isValidatorEnabled(validatorID), "Validator is not enabled");
(uint128 baseStake, uint128 delegateStakes) = _stakingInterface.getValidatorCompoundedStakingData(validatorID);
participantsData.stake = baseStake + delegateStakes;
}
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, participantsData.stake);
}
/**
* This function is called when a quorum of equivalent hashes have been submitted for a Block Result Session.
*/
function finalizeAndRewardResultSession(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.requiresAudit, "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;
// find the block hash and result hashes that the quorum agrees on by finding the result hash with the highest number of participants
for (uint256 i = 0; i < blockSpecimenHashesRaw.length; 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)
_rewardParticipants(session, chainId, blockHeight, agreedBlockSpecimenHash, agreedResultHash);
else emit QuorumNotReached(chainId, blockHeight);
session.requiresAudit = true;
// set session deadline to 0 to release gas
session.sessionDeadline = 0;
}
/**
* Called by Auditor role when a quorum is not reached. The auditor's submitted hash is
* the definitive truth.
*/
function arbitrateBlockResultSession(
uint64 chainId,
uint64 blockHeight,
bytes32 blockSpecimenHash,
bytes32 definitiveResultHash
) public {
require(_auditors.contains(msg.sender), "Sender is not AUDITOR_ROLE");
BlockResultSession storage session = _sessions[chainId][blockHeight];
require(session.requiresAudit, "Session must be finalized before audit");
_rewardParticipants(session, chainId, blockHeight, blockSpecimenHash, definitiveResultHash);
}
function _rewardParticipants(
BlockResultSession storage session,
uint64 chainId,
uint64 blockHeight,
bytes32 blockSpecimenHash,
bytes32 resultHash
) internal {
address participant;
address[] storage participants = session.blockSpecimenProperties[blockSpecimenHash].participants[resultHash];
uint256 len = participants.length;
uint128[] memory ids = new uint128[](len);
uint128[] memory rewards = new uint128[](len);
uint128 totalStake;
mapping(address => SessionParticipantData) storage participantsData = session.participantsData;
for (uint256 i = 0; i < len; i++) {
totalStake += participantsData[participants[i]].stake;
}
for (uint256 i = 0; i < len; i++) {
participant = participants[i];
SessionParticipantData storage pd = participantsData[participant];
ids[i] = validatorIDs[participant];
rewards[i] = uint128((uint256(pd.stake) * uint256(_blockResultRewardAllocation)) / totalStake);
// release gas if possible
if (pd.submissionCounter == 1) {
pd.submissionCounter = 0;
pd.stake = 0;
}
}
_stakingInterface.rewardValidators(ids, rewards);
emit BlockResultRewardAwarded(chainId, blockHeight, blockSpecimenHash, resultHash);
delete session.blockSpecimenProperties[blockSpecimenHash]; // release gas
}
/**
* Returns contract meta data
*/
function getMetadata()
public
view
returns (
address stakingInterface,
uint128 blockResultRewardAllocation,
uint64 blockResultSessionDuration,
uint64 minSubmissionsRequired,
uint256 blockResultQuorum,
uint256 secondsPerBlock
)
{
return (address(_stakingInterface), _blockResultRewardAllocation, _blockResultSessionDuration, _minSubmissionsRequired, _blockResultQuorum, _secondsPerBlock);
}
/**
* Returns data used for chain sync
*/
function getChainData(uint64 chainId)
external
view
returns (
uint256 blockOnTargetChain,
uint256 blockOnCurrentChain,
uint256 secondsPerBlock,
uint128 allowedThreshold,
uint128 maxSubmissionsPerBlockHeight,
uint64 nthBlock
)
{
ChainData memory cd = _chainData[chainId];
return (cd.blockOnTargetChain, cd.blockOnCurrentChain, cd.secondsPerBlock, 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 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 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.requiresAudit);
}
}//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.13;
interface IOperationalStaking {
function getValidatorMetadata(uint128 validatorId)
external
view
returns (
address _address,
uint128 staked,
uint128 delegated,
uint128 commissionRate
);
function getValidatorStakingData(uint128 validatorId) external view returns (uint128 staked, uint128 delegated);
function getValidatorCompoundedStakingData(uint128 validatorId) external view returns (uint128 staked, uint128 delegated);
function rewardValidators(uint128[] calldata validatorId, uint128[] calldata amount) external;
function addValidator(address validator, uint128 commissionRate) external returns (uint256 id);
function disableValidator(uint128 validatorId, uint256 blockNumber) external;
function enableValidator(uint128 validatorId) external;
function isValidatorEnabled(uint128 validatorId) external returns (bool);
}// 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": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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"},{"indexed":false,"internalType":"uint128","name":"submittedStake","type":"uint128"}],"name":"BlockResultProductionProofSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint64","name":"chainId","type":"uint64"},{"indexed":true,"internalType":"uint64","name":"blockHeight","type":"uint64"},{"indexed":true,"internalType":"bytes32","name":"blockSpecimenHash","type":"bytes32"},{"indexed":false,"internalType":"bytes32","name":"resulthash","type":"bytes32"}],"name":"BlockResultRewardAwarded","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":"secondsPerBlock","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"}],"name":"OperatorDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"name":"OperatorEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"}],"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":"secondsPerBlock","type":"uint64"}],"name":"SecondsPerBlockChanged","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":"newInterfaceAddress","type":"address"}],"name":"StakingInterfaceChanged","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":"address","name":"validator","type":"address"},{"internalType":"uint128","name":"commissionRate","type":"uint128"}],"name":"addValidator","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":"definitiveResultHash","type":"bytes32"}],"name":"arbitrateBlockResultSession","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"disableBRPOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"validatorId","type":"uint128"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"disableValidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"enableBRPOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"chainId","type":"uint64"},{"internalType":"uint64","name":"blockHeight","type":"uint64"}],"name":"finalizeAndRewardResultSession","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":"secondsPerBlock","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":[],"name":"getMetadata","outputs":[{"internalType":"address","name":"stakingInterface","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":"secondsPerBlock","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":"initialOwner","type":"address"},{"internalType":"address","name":"stakingContract","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":"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":"secondsPerBlock","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":"secondsPerBlock","type":"uint64"}],"name":"setSecondsPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"stakingContractAddress","type":"address"}],"name":"setStakingInterface","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
608060405234801561001057600080fd5b50613a83806100206000396000f3fe608060405234801561001057600080fd5b50600436106101d85760003560e01c80630d92f4ed146101dd578063222388c21461021c5780632c58ed42146102315780633646aded146102445780633c4a25d01461025757806341c1278d1461026a57806341ca4a551461028d5780634524c7e1146102a0578063485cc955146102b357806354cfa69f146102c657806355791fea146103945780635a5e84f2146103a75780636543413a146103ba57806367585e44146103cd5780636ab9d8e8146103e05780636b7511cb146104005780636e1d616e14610413578063715018a61461042857806372ab8568146104305780637a5b4f59146104435780638cb0356e146104d15780638da5cb5b146104e45780639015d371146104f9578063920036b71461051c57806393742b56146105325780639914628414610545578063a2e7e44114610558578063ad9e91ee1461056b578063ba75fd2f1461057e578063c384678914610591578063d3a8b2a8146105a4578063d5839da9146105c4578063d911c632146105e4578063dd36a8d5146105fb578063e32014091461060e578063e429cef114610621578063e6116cfd14610634578063eecdac8814610647578063f2fde38b1461065a578063f36c8f5c1461066d575b600080fd5b6102066101eb36600461301d565b6072602052600090815260409020546001600160801b031681565b604051610213919061303a565b60405180910390f35b61022f61022a366004613063565b610682565b005b61022f61023f3660046130b8565b610786565b61022f61025236600461301d565b61081c565b61022f61026536600461301d565b610899565b61027f600080516020613a2e83398151915281565b604051908152602001610213565b61022f61029b36600461301d565b61093c565b61022f6102ae3660046130eb565b610baf565b61022f6102c1366004613104565b610c0b565b6103526102d4366004613132565b6001600160401b03908116600090815260776020908152604091829020825160c08101845281548082526001830154938201849052600283015494820185905260038301546001600160801b0380821660608501819052600160801b909204166080840181905260049094015490961660a090920182905295929492565b604080519687526020870195909552938501929092526001600160801b0390811660608501521660808301526001600160401b031660a082015260c001610213565b61022f6103a2366004613132565b610e34565b61022f6103b536600461314d565b610ea6565b61022f6103c836600461316a565b610f18565b61022f6103db3660046130b8565b611927565b61027f6103ee36600461301d565b60746020526000908152604090205481565b61022f61040e36600461301d565b6119b5565b61027f600080516020613a0e83398151915281565b61022f611ac4565b61022f61043e36600461301d565b611ad8565b6104856065546068546069546066546067546001600160a01b03909416946001600160801b03909316936001600160401b0380841694600160401b9094041692565b604080516001600160a01b0390971687526001600160801b0390951660208701526001600160401b039384169486019490945291166060840152608083015260a082015260c001610213565b61022f6104df3660046130b8565b611c6a565b6104ec611f15565b604051610213919061320f565b61050c61050736600461301d565b611f24565b6040519015158152602001610213565b610524611f37565b604051610213929190613267565b61022f610540366004613132565b611f62565b61022f610553366004613293565b611fdd565b61022f610566366004613063565b6120cd565b61022f6105793660046132cc565b612173565b61050c61058c3660046132f8565b612202565b61022f61059f36600461333f565b6122c2565b6105b76105b236600461314d565b6123b9565b6040516102139190613381565b6105d76105d23660046130eb565b6123dd565b6040516102139190613394565b6105ec6124c9565b6040516102139392919061342f565b61022f610609366004613132565b6124f7565b61022f61061c3660046130b8565b612559565b61022f61062f36600461301d565b6125da565b61022f61064236600461301d565b61269c565b61022f61065536600461301d565b612774565b61022f61066836600461301d565b612810565b61027f6000805160206139ce83398151915281565b61068d606e33612889565b6106b25760405162461bcd60e51b81526004016106a990613472565b60405180910390fd5b6001600160a01b038216600090815260746020526040902054156106e85760405162461bcd60e51b81526004016106a9906134a9565b6001600160a01b0382166000908152607460209081526040808320600080516020613a2e83398151915290556072825280832080546001600160801b0319166001600160801b03861690811790915583526073909152902061074a90836128a5565b506000805160206139ae8339815191528282600080516020613a2e83398151915260405161077a939291906134da565b60405180910390a15050565b610791606e33612889565b6107ad5760405162461bcd60e51b81526004016106a990613472565b6001600160401b038281166000818152607760205260409081902060030180546001600160801b0319169385169390931790925590517f4e4c0afc3a2b327c2f061f8ff5190a491f1042ba8f292a887bab97840947b7a990610810908490613504565b60405180910390a25050565b610827606e33612889565b6108435760405162461bcd60e51b81526004016106a990613472565b606580546001600160a01b0319166001600160a01b0383161790556040517f70016f37fc9a299f674d1e3083a27743406649810887ed947a79884b064d2de99061088e90839061320f565b60405180910390a150565b6108a16128ba565b6001600160a01b038116600090815260746020526040902054156108d75760405162461bcd60e51b81526004016106a9906134a9565b6001600160a01b03811660009081526074602052604090206000805160206139ce833981519152905561090b606e826128a5565b506000805160206139ae8339815191528160006000805160206139ce83398151915260405161088e939291906134da565b6065546001600160a01b038083166000908152607260205260408082205490516321cc9a8360e21b815285949293909216916387326a0c9161098c916001600160801b039091169060040161303a565b608060405180830381865afa1580156109a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cd9190613518565b5091925050506001600160a01b03811633146109fb5760405162461bcd60e51b81526004016106a990613577565b6001600160a01b038316600090815260746020526040902054600080516020613a2e83398151915214610a405760405162461bcd60e51b81526004016106a9906135ae565b610a4b606c84612889565b15610a965760405162461bcd60e51b815260206004820152601b60248201527a13dc195c985d1bdc881a5cc8185b1c9958591e48195b98589b1959602a1b60448201526064016106a9565b6001600160a01b0383166000908152607260205260409020546001600160801b0316610ac3606c856128a5565b506001600160801b03808216600090815260756020526040812080549092169190610aed836135f1565b82546001600160801b039182166101009390930a92830291909202199091161790555060655460405163edff4b6160e01b81526001600160a01b039091169063edff4b6190610b4090849060040161303a565b600060405180830381600087803b158015610b5a57600080fd5b505af1158015610b6e573d6000803e3d6000fd5b505050507f9e532d260bd7dde07708a6b1f7c64042546243d79bac23514cd74fcfc1a01fe484604051610ba1919061320f565b60405180910390a150505050565b610bba606e33612889565b610bd65760405162461bcd60e51b81526004016106a990613472565b60668190556040518181527fe8c66e2621de650a92131e007d8bbc4cbf3bb8d4df7471d1f93eb20d70039a7c9060200161088e565b600054610100900460ff1615808015610c2b5750600054600160ff909116105b80610c455750303b158015610c45575060005460ff166001145b610ca85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a9565b6000805460ff191660011790558015610ccb576000805461ff0019166101001790555b610cd3612919565b610cde606e336128a5565b50610cf8606a6000805160206139ce833981519152612948565b50610d12606a600080516020613a2e833981519152612948565b50610d2c606a600080516020613a0e833981519152612948565b50610d436102ae6002670de0b6b3a7640000613635565b610d52655af3107a4000610ea6565b610d5c60f0610e34565b610d666002611f62565b610d6f8261081c565b610d7a606e33612954565b506001600160a01b03831660009081526074602052604090206000805160206139ce8339815191529055610daf606e846128a5565b506000805160206139ae8339815191528360006000805160206139ce833981519152604051610de0939291906134da565b60405180910390a18015610e2f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b505050565b610e3f606e33612889565b610e5b5760405162461bcd60e51b81526004016106a990613472565b606980546001600160401b0319166001600160401b0383161790556040517f80972f2be3a50171fc4fb48963f365cbd47dc216ace7f3628a584503a80a9f979061088e908390613504565b610eb1606e33612889565b610ecd5760405162461bcd60e51b81526004016106a990613472565b606880546001600160801b0319166001600160801b0383161790556040517fa425d7d9b858a4250625446e4504257053202ae93ba0d1dea68dce7ec87a05c59061088e90839061303a565b610f23606c33612889565b610f805760405162461bcd60e51b815260206004820152602860248201527f53656e646572206973206e6f7420424c4f434b5f524553554c545f50524f44556044820152674345525f524f4c4560c01b60648201526084016106a9565b6001600160401b03808716600090815260776020526040812060048101549092169003610fe25760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a590818da185a5b88125160821b60448201526064016106a9565b6004810154610ffa906001600160401b031687613649565b6001600160401b0316156110475760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908189b1bd8dac81a195a59da1d60621b60448201526064016106a9565b6001600160401b0380881660009081526076602090815260408083208a851684528252808320600381015433855260028201909352908320909391909116918290036114b5576003830154600160401b900460ff16156110b95760405162461bcd60e51b81526004016106a99061366f565b600084600201546067548660010154436110d391906136a6565b6110dd91906136bd565b6110e79190613635565b85546110f391906136dc565b60038601549091506000906001600160801b031682101561111557600061112d565b600386015461112d906001600160801b0316836136a6565b90508a6001600160401b031681111580156111685750600386015461115b906001600160801b0316836136dc565b8b6001600160401b031611155b6111c85760405162461bcd60e51b815260206004820152602b60248201527f426c6f636b20686569676874206973206f7574206f6620626f756e647320666f60448201526a72206c6976652073796e6360a81b60648201526084016106a9565b6069546111de906001600160401b0316436136dc565b6003860180546001600160401b0319166001600160401b039283169081179091556040518d8316928f16917f8b1f889addbfa41db5227bae3b091bd5c8b9a9122f874dfe54ba2f75aabe1f4c916112359190613504565b60405180910390a3336000908152607260205260409081902054606554915163429a481b60e01b81526001600160801b03909116916001600160a01b03169063429a481b9061128890849060040161303a565b6020604051808303816000875af11580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb91906136f4565b6112e75760405162461bcd60e51b81526004016106a990613716565b606554604051634c4a170960e01b815260009182916001600160a01b0390911690634c4a17099061131c90869060040161303a565b6040805180830381865afa158015611338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061135c9190613748565b909250905061136b8183613777565b8660000160006101000a8154816001600160801b0302191690836001600160801b03160217905550876001018d908060018154018082558091505060019003906000526020600020016000909190919091505560008860000160008f81526020019081526020016000209050806001018d90806001815401808255809150506001900390600052602060002001600090919091909150558060000160008e8152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555086600001601081819054906101000a90046001600160801b031680929190611485906135f1565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050506118a1565b816001600160401b03164311156114de5760405162461bcd60e51b81526004016106a99061366f565b600384015481546001600160801b03600160801b92839004811692909104161061154a5760405162461bcd60e51b815260206004820152601e60248201527f4d6178207375626d697373696f6e73206c696d6974206578636565646564000060448201526064016106a9565b6000888152602084905260409020815460018201906001600160801b0316156116845760005b815481101561167e576000836000016000848481548110611593576115936137a2565b90600052602060002001548152602001908152602001600020905060005b815481101561166957336001600160a01b03168282815481106115d6576115d66137a2565b6000918252602090912001546001600160a01b0316036116575760405162461bcd60e51b815260206004820152603660248201527f4f70657261746f7220616c7265616479207375626d697474656420666f7220746044820152750d0ca40e0e4deecd2c8cac840c4d8dec6d640d0c2e6d60531b60648201526084016106a9565b80611661816137b8565b9150506115b1565b50508080611676906137b8565b915050611570565b506117d1565b336000908152607260205260409081902054606554915163429a481b60e01b81526001600160801b03909116916001600160a01b03169063429a481b906116cf90849060040161303a565b6020604051808303816000875af11580156116ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171291906136f4565b61172e5760405162461bcd60e51b81526004016106a990613716565b606554604051634c4a170960e01b815260009182916001600160a01b0390911690634c4a17099061176390869060040161303a565b6040805180830381865afa15801561177f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a39190613748565b90925090506117b28183613777565b86546001600160801b0319166001600160801b03919091161786555050505b600089815260208390526040902081541561180a578054600003611805578154600181018355600083815260209020018a90555b611837565b600180870180548083018255600091825260208083209091018e9055845492830185558482529020018a90555b80546001810182556000828152602090200180546001600160a01b0319163317905583546001600160801b03600160801b90910416846010611878836135f1565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505b60008781526078602090815260408220805460018101825590835291206118ca91018787612f55565b5080546040517f8741f5bf89731b15f24deb1e84e2bbd381947f009ee378a2daa15ed8abfb948591611913918d918d918d918d918d918d916001600160801b03909116906137d1565b60405180910390a150505050505050505050565b611932606e33612889565b61194e5760405162461bcd60e51b81526004016106a990613472565b6001600160401b038281166000908152607760205260409081902060030180546001600160801b0316928416600160801b0292909217909155517f1bca1fb481202bb14258ce1030d54e9e7bafc8b696d96b9eb733826e58a3a0309061077a908390613504565b6119c0606e33612889565b6119dc5760405162461bcd60e51b81526004016106a990613472565b6001600160a01b038116600090815260746020526040902054600080516020613a2e83398151915214611a215760405162461bcd60e51b81526004016106a9906135ae565b611a2c606c82612889565b15611a3a57611a3a81612969565b6001600160a01b0381166000908152607260209081526040808320546001600160801b0316835260739091529020611a729082612954565b506001600160a01b038116600090815260726020908152604080832080546001600160801b0319169055607490915280822091909155516000805160206139ee8339815191529061088e90839061320f565b611acc6128ba565b611ad66000612a2c565b565b6065546001600160a01b038083166000908152607260205260408082205490516321cc9a8360e21b815285949293909216916387326a0c91611b28916001600160801b039091169060040161303a565b608060405180830381865afa158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190613518565b5091925050506001600160a01b0381163314611b975760405162461bcd60e51b81526004016106a990613577565b6001600160a01b038316600090815260746020526040902054600080516020613a2e83398151915214611bdc5760405162461bcd60e51b81526004016106a9906135ae565b611be7606c84612889565b611c325760405162461bcd60e51b815260206004820152601c60248201527b13dc195c985d1bdc881a5cc8185b1c9958591e48191a5cd8589b195960221b60448201526064016106a9565b611c3b83612969565b7f23cd406c7cafe6d88c3f1c1cc16e438745a4236aec25906be2046ca16c36bd1e83604051610e26919061320f565b6001600160401b038083166000908152607660209081526040808320858516845290915290206003810154909116438110611ce35760405162461bcd60e51b815260206004820152601960248201527853657373696f6e206e6f74207061737420646561646c696e6560381b60448201526064016106a9565b6003820154600160401b900460ff1615611d3d5760405162461bcd60e51b815260206004820152601b60248201527a14d95cdcda5bdb8818d85b9b9bdd08189948199a5b985b1a5e9959602a1b60448201526064016106a9565b806001600160401b0316600003611d8c5760405162461bcd60e51b815260206004820152601360248201527214d95cdcda5bdb881b9bdd081cdd185c9d1959606a1b60448201526064016106a9565b6000808080806001870181805b8254811015611e5757828181548110611db457611db46137a2565b6000918252602080832090910154808352908c905260408220909350905b6001820154811015611e4257816001018181548110611df357611df36137a2565b600091825260208083209091015480835290849052604090912054909950611e1b818c6136dc565b9a5088811115611e2f578098508497508996505b5080611e3a816137b8565b915050611dd2565b50508080611e4f906137b8565b915050611d99565b50606954600160401b90046001600160401b03168510801590611e97575060665487611e8b670de0b6b3a7640000886136bd565b611e959190613635565b115b15611eae57611ea9898c8c8787612a7e565b611ef0565b8a6001600160401b03167f398fd8f638a7242217f011fd0720a06747f7a85b7d28d7276684b841baea40218b604051611ee79190613504565b60405180910390a25b505050600390950180546001600160481b031916600160401b17905550505050505050565b6033546001600160a01b031690565b6000611f31606c83612889565b92915050565b606854600090606090600160801b90046001600160801b0316611f5a606c612d67565b915091509091565b611f6d606e33612889565b611f895760405162461bcd60e51b81526004016106a990613472565b60698054600160401b600160801b031916600160401b6001600160401b038416021790556040517febd426f3d605bdf7e97ba7cd4a971371661140ad0acc8e0081f067d2004a71769061088e908390613504565b611fe8606e33612889565b6120045760405162461bcd60e51b81526004016106a990613472565b6001600160401b0384166000908152607760205260409020816120695760405162461bcd60e51b815260206004820152601d60248201527f5365636f6e64732070657220626c6f636b2063616e6e6f74206265203000000060448201526064016106a9565b838155600181018390556002810182905560408051858152602081018590529081018390526001600160401b038616907ffd97af399d19e6be9256c99c8e52b1809cdbc4dc96816739612b6fd4e6d940b09060600160405180910390a25050505050565b6120d8606e33612889565b6120f45760405162461bcd60e51b81526004016106a990613472565b60655460405163a2e7e44160e01b81526001600160a01b0384811660048301526001600160801b03841660248301529091169063a2e7e441906044016020604051808303816000875af115801561214f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f9190613840565b61217e606e33612889565b61219a5760405162461bcd60e51b81526004016106a990613472565b6065546040516356cf48f760e11b81526001600160a01b039091169063ad9e91ee906121cc9085908590600401613859565b600060405180830381600087803b1580156121e657600080fd5b505af11580156121fa573d6000803e3d6000fd5b505050505050565b6001600160401b038381166000818152607660209081526040808320878616845282528083206003808201546001600160a01b03891686526002830185528386209686526077909452918420909101548454939591949290911692600160801b918290046001600160801b0390811692909104161480158161228d5750826001600160401b03164311155b806122b657506001600160401b0383161580156122b657506003840154600160401b900460ff16155b98975050505050505050565b6122cd607033612889565b6123165760405162461bcd60e51b815260206004820152601a60248201527953656e646572206973206e6f742041554449544f525f524f4c4560301b60448201526064016106a9565b6001600160401b0384811660009081526076602090815260408083209387168352929052206003810154600160401b900460ff166123a55760405162461bcd60e51b815260206004820152602660248201527f53657373696f6e206d7573742062652066696e616c697a6564206265666f726560448201526508185d591a5d60d21b60648201526084016106a9565b6123b28186868686612a7e565b5050505050565b6001600160801b0381166000908152607360205260409020606090611f3190612d67565b606060786000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156124be57838290600052602060002001805461243190613872565b80601f016020809104026020016040519081016040528092919081815260200182805461245d90613872565b80156124aa5780601f1061247f576101008083540402835291602001916124aa565b820191906000526020600020905b81548152906001019060200180831161248d57829003601f168201915b505050505081526020019060010190612412565b505050509050919050565b60608060606124d8606c612d67565b6124e2606e612d67565b6124ec6070612d67565b925092509250909192565b612502606e33612889565b61251e5760405162461bcd60e51b81526004016106a990613472565b6001600160401b03811660678190556040517fcaf46ba335d93b98398af7142ea3e362a6b8e91c57da6bf1e8a704f86374dde090600090a250565b612564606e33612889565b6125805760405162461bcd60e51b81526004016106a990613472565b6001600160401b0382811660008181526077602052604080822060040180546001600160401b0319169486169485179055517fbbfa9310306e8a8485d109f8be6b0a808473ce55d2e94b8ca3447c9ddb2854b49190a35050565b6125e5606e33612889565b6126015760405162461bcd60e51b81526004016106a990613472565b6001600160a01b038116600090815260746020526040902054156126375760405162461bcd60e51b81526004016106a9906134a9565b6001600160a01b0381166000908152607460205260409020600080516020613a0e833981519152905561266b6070826128a5565b506000805160206139ae833981519152816000600080516020613a0e83398151915260405161088e939291906134da565b6126a7606e33612889565b6126c35760405162461bcd60e51b81526004016106a990613472565b6001600160a01b038116600090815260746020526040902054600080516020613a0e833981519152146127325760405162461bcd60e51b815260206004820152601760248201527627b832b930ba37b91034b9903737ba1030bab234ba37b960491b60448201526064016106a9565b6001600160a01b038116600090815260746020526040812055612756607082612954565b506000805160206139ee8339815191528160405161088e919061320f565b61277c6128ba565b6001600160a01b0381166000908152607460205260409020546000805160206139ce833981519152146127ec5760405162461bcd60e51b815260206004820152601860248201527727b832b930ba37b91034b9903737ba1033b7bb32b93737b960411b60448201526064016106a9565b6001600160a01b038116600090815260746020526040812055612756606e82612954565b6128186128ba565b6001600160a01b03811661287d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106a9565b61288681612a2c565b50565b600061289e836001600160a01b038416612d74565b9392505050565b600061289e836001600160a01b038416612d8c565b336128c3611f15565b6001600160a01b031614611ad65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106a9565b600054610100900460ff166129405760405162461bcd60e51b81526004016106a9906138ac565b611ad6612dd6565b600061289e8383612d8c565b600061289e836001600160a01b038416612e06565b612974606c82612954565b506001600160a01b0381166000908152607260209081526040808320546001600160801b0390811680855260759093529083208054929392909116916129b9836138f7565b82546101009290920a6001600160801b0381810219909316918316021790915582811660009081526075602052604081205490911690039050612a28576065546040516356cf48f760e11b81526001600160a01b039091169063ad9e91ee906121cc9084904390600401613859565b5050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000828152602086815260408083208484529091528120805482816001600160401b03811115612ab057612ab061391a565b604051908082528060200260200182016040528015612ad9578160200160208202803683370190505b5090506000826001600160401b03811115612af657612af661391a565b604051908082528060200260200182016040528015612b1f578160200160208202803683370190505b509050600060028b01815b85811015612b9357816000888381548110612b4757612b476137a2565b60009182526020808320909101546001600160a01b03168352820192909252604001902054612b7f906001600160801b031684613777565b925080612b8b816137b8565b915050612b2a565b5060005b85811015612c8857868181548110612bb157612bb16137a2565b60009182526020808320909101546001600160a01b031680835284825260408084206072909352909220548751929a5090916001600160801b0390911690879084908110612c0157612c016137a2565b6001600160801b039283166020918202929092010152606854825486831692612c2d92811691166136bd565b612c379190613635565b858381518110612c4957612c496137a2565b6001600160801b0392831660209182029290920101528154600160801b900416600103612c7557600081555b5080612c80816137b8565b915050612b97565b5060655460405163605a501760e01b81526001600160a01b039091169063605a501790612cbb9087908790600401613969565b600060405180830381600087803b158015612cd557600080fd5b505af1158015612ce9573d6000803e3d6000fd5b50505050888a6001600160401b03168c6001600160401b03167f93dcf9329a330cb95723152c05719560f2fbd50e215c542854b27acc80c9108d8b604051612d3391815260200190565b60405180910390a4600089815260208d90526040812090612d576001830182612fd9565b5050505050505050505050505050565b6060600061289e83612ef9565b60009081526001919091016020526040902054151590565b6000612d988383612d74565b612dce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611f31565b506000611f31565b600054610100900460ff16612dfd5760405162461bcd60e51b81526004016106a9906138ac565b611ad633612a2c565b60008181526001830160205260408120548015612eef576000612e2a6001836136a6565b8554909150600090612e3e906001906136a6565b9050818114612ea3576000866000018281548110612e5e57612e5e6137a2565b9060005260206000200154905080876000018481548110612e8157612e816137a2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612eb457612eb4613997565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611f31565b6000915050611f31565b606081600001805480602002602001604051908101604052809291908181526020018280548015612f4957602002820191906000526020600020905b815481526020019060010190808311612f35575b50505050509050919050565b828054612f6190613872565b90600052602060002090601f016020900481019282612f835760008555612fc9565b82601f10612f9c5782800160ff19823516178555612fc9565b82800160010185558215612fc9579182015b82811115612fc9578235825591602001919060010190612fae565b50612fd5929150612ff3565b5090565b508054600082559060005260206000209081019061288691905b5b80821115612fd55760008155600101612ff4565b6001600160a01b038116811461288657600080fd5b60006020828403121561302f57600080fd5b813561289e81613008565b6001600160801b0391909116815260200190565b6001600160801b038116811461288657600080fd5b6000806040838503121561307657600080fd5b823561308181613008565b915060208301356130918161304e565b809150509250929050565b80356001600160401b03811681146130b357600080fd5b919050565b600080604083850312156130cb57600080fd5b6130d48361309c565b91506130e26020840161309c565b90509250929050565b6000602082840312156130fd57600080fd5b5035919050565b6000806040838503121561311757600080fd5b823561312281613008565b9150602083013561309181613008565b60006020828403121561314457600080fd5b61289e8261309c565b60006020828403121561315f57600080fd5b813561289e8161304e565b60008060008060008060a0878903121561318357600080fd5b61318c8761309c565b955061319a6020880161309c565b9450604087013593506060870135925060808701356001600160401b03808211156131c457600080fd5b818901915089601f8301126131d857600080fd5b8135818111156131e757600080fd5b8a60208285010111156131f957600080fd5b6020830194508093505050509295509295509295565b6001600160a01b0391909116815260200190565b600081518084526020808501945080840160005b8381101561325c5781516001600160a01b031687529582019590820190600101613237565b509495945050505050565b6001600160801b038316815260406020820181905260009061328b90830184613223565b949350505050565b600080600080608085870312156132a957600080fd5b6132b28561309c565b966020860135965060408601359560600135945092505050565b600080604083850312156132df57600080fd5b82356132ea8161304e565b946020939093013593505050565b60008060006060848603121561330d57600080fd5b6133168461309c565b92506133246020850161309c565b9150604084013561333481613008565b809150509250925092565b6000806000806080858703121561335557600080fd5b61335e8561309c565b935061336c6020860161309c565b93969395505050506040820135916060013590565b60208152600061289e6020830184613223565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b8381101561342157888603603f1901855282518051808852835b818110156133f1578281018a01518982018b015289016133d6565b8181111561340157848a838b0101525b50601f01601f1916969096018701955093860193918601916001016133bc565b509398975050505050505050565b6060815260006134426060830186613223565b82810360208401526134548186613223565b905082810360408401526134688185613223565b9695505050505050565b6020808252601d908201527f53656e646572206973206e6f7420474f5645524e414e43455f524f4c45000000604082015260600190565b6020808252601790820152764f70657261746f7220616c72656164792065786973747360481b604082015260600190565b6001600160a01b039390931683526001600160801b03919091166020830152604082015260600190565b6001600160401b0391909116815260200190565b6000806000806080858703121561352e57600080fd5b845161353981613008565b602086015190945061354a8161304e565b604086015190935061355b8161304e565b606086015190925061356c8161304e565b939692955090935050565b6020808252601e908201527f53656e646572206973206e6f74206f70657261746f72206d616e616765720000604082015260600190565b60208082526013908201527204f70657261746f72206973206e6f742042525606c1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b038281166002600160801b03198101613615576136156135db565b6001019392505050565b634e487b7160e01b600052601260045260246000fd5b6000826136445761364461361f565b500490565b60006001600160401b03838116806136635761366361361f565b92169190910692915050565b6020808252601f908201527f53657373696f6e207375626d697373696f6e73206861766520636c6f73656400604082015260600190565b6000828210156136b8576136b86135db565b500390565b60008160001904831182151516156136d7576136d76135db565b500290565b600082198211156136ef576136ef6135db565b500190565b60006020828403121561370657600080fd5b8151801515811461289e57600080fd5b60208082526018908201527715985b1a59185d1bdc881a5cc81b9bdd08195b98589b195960421b604082015260600190565b6000806040838503121561375b57600080fd5b82516137668161304e565b60208401519092506130918161304e565b60006001600160801b03828116848216808303821115613799576137996135db565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016137ca576137ca6135db565b5060010190565b6001600160401b03888116825287166020820152604081018690526060810185905260c06080820181905281018390526000838560e084013750600081840160e0908101919091526001600160801b039290921660a0820152601f909201601f19169091010195945050505050565b60006020828403121561385257600080fd5b5051919050565b6001600160801b03929092168252602082015260400190565b600181811c9082168061388657607f821691505b6020821081036138a657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160801b03821680613910576139106135db565b6000190192915050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501945080840160005b8381101561325c5781516001600160801b031687529582019590820190600101613944565b60408152600061397c6040830185613930565b828103602084015261398e8185613930565b95945050505050565b634e487b7160e01b600052603160045260246000fdfe797ca55fc7be0f65c71f10996f7a16f801094f8ae3811874afc5a39730772a4271840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb180c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d59a1c48e5837ad7a7f3dcedcbe129bf3249ec4fbf651fd4f5e2600ead39fe2f577ae3b5d012484be69eeed881350adb3189b651fac6e88b31ddff30c833a8b7fa2646970667358221220e720bb6d0e325a223aac177fcaaa778e1382d880fdf7b87e40ff8dbab6c7f3ab64736f6c634300080d0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101d85760003560e01c80630d92f4ed146101dd578063222388c21461021c5780632c58ed42146102315780633646aded146102445780633c4a25d01461025757806341c1278d1461026a57806341ca4a551461028d5780634524c7e1146102a0578063485cc955146102b357806354cfa69f146102c657806355791fea146103945780635a5e84f2146103a75780636543413a146103ba57806367585e44146103cd5780636ab9d8e8146103e05780636b7511cb146104005780636e1d616e14610413578063715018a61461042857806372ab8568146104305780637a5b4f59146104435780638cb0356e146104d15780638da5cb5b146104e45780639015d371146104f9578063920036b71461051c57806393742b56146105325780639914628414610545578063a2e7e44114610558578063ad9e91ee1461056b578063ba75fd2f1461057e578063c384678914610591578063d3a8b2a8146105a4578063d5839da9146105c4578063d911c632146105e4578063dd36a8d5146105fb578063e32014091461060e578063e429cef114610621578063e6116cfd14610634578063eecdac8814610647578063f2fde38b1461065a578063f36c8f5c1461066d575b600080fd5b6102066101eb36600461301d565b6072602052600090815260409020546001600160801b031681565b604051610213919061303a565b60405180910390f35b61022f61022a366004613063565b610682565b005b61022f61023f3660046130b8565b610786565b61022f61025236600461301d565b61081c565b61022f61026536600461301d565b610899565b61027f600080516020613a2e83398151915281565b604051908152602001610213565b61022f61029b36600461301d565b61093c565b61022f6102ae3660046130eb565b610baf565b61022f6102c1366004613104565b610c0b565b6103526102d4366004613132565b6001600160401b03908116600090815260776020908152604091829020825160c08101845281548082526001830154938201849052600283015494820185905260038301546001600160801b0380821660608501819052600160801b909204166080840181905260049094015490961660a090920182905295929492565b604080519687526020870195909552938501929092526001600160801b0390811660608501521660808301526001600160401b031660a082015260c001610213565b61022f6103a2366004613132565b610e34565b61022f6103b536600461314d565b610ea6565b61022f6103c836600461316a565b610f18565b61022f6103db3660046130b8565b611927565b61027f6103ee36600461301d565b60746020526000908152604090205481565b61022f61040e36600461301d565b6119b5565b61027f600080516020613a0e83398151915281565b61022f611ac4565b61022f61043e36600461301d565b611ad8565b6104856065546068546069546066546067546001600160a01b03909416946001600160801b03909316936001600160401b0380841694600160401b9094041692565b604080516001600160a01b0390971687526001600160801b0390951660208701526001600160401b039384169486019490945291166060840152608083015260a082015260c001610213565b61022f6104df3660046130b8565b611c6a565b6104ec611f15565b604051610213919061320f565b61050c61050736600461301d565b611f24565b6040519015158152602001610213565b610524611f37565b604051610213929190613267565b61022f610540366004613132565b611f62565b61022f610553366004613293565b611fdd565b61022f610566366004613063565b6120cd565b61022f6105793660046132cc565b612173565b61050c61058c3660046132f8565b612202565b61022f61059f36600461333f565b6122c2565b6105b76105b236600461314d565b6123b9565b6040516102139190613381565b6105d76105d23660046130eb565b6123dd565b6040516102139190613394565b6105ec6124c9565b6040516102139392919061342f565b61022f610609366004613132565b6124f7565b61022f61061c3660046130b8565b612559565b61022f61062f36600461301d565b6125da565b61022f61064236600461301d565b61269c565b61022f61065536600461301d565b612774565b61022f61066836600461301d565b612810565b61027f6000805160206139ce83398151915281565b61068d606e33612889565b6106b25760405162461bcd60e51b81526004016106a990613472565b60405180910390fd5b6001600160a01b038216600090815260746020526040902054156106e85760405162461bcd60e51b81526004016106a9906134a9565b6001600160a01b0382166000908152607460209081526040808320600080516020613a2e83398151915290556072825280832080546001600160801b0319166001600160801b03861690811790915583526073909152902061074a90836128a5565b506000805160206139ae8339815191528282600080516020613a2e83398151915260405161077a939291906134da565b60405180910390a15050565b610791606e33612889565b6107ad5760405162461bcd60e51b81526004016106a990613472565b6001600160401b038281166000818152607760205260409081902060030180546001600160801b0319169385169390931790925590517f4e4c0afc3a2b327c2f061f8ff5190a491f1042ba8f292a887bab97840947b7a990610810908490613504565b60405180910390a25050565b610827606e33612889565b6108435760405162461bcd60e51b81526004016106a990613472565b606580546001600160a01b0319166001600160a01b0383161790556040517f70016f37fc9a299f674d1e3083a27743406649810887ed947a79884b064d2de99061088e90839061320f565b60405180910390a150565b6108a16128ba565b6001600160a01b038116600090815260746020526040902054156108d75760405162461bcd60e51b81526004016106a9906134a9565b6001600160a01b03811660009081526074602052604090206000805160206139ce833981519152905561090b606e826128a5565b506000805160206139ae8339815191528160006000805160206139ce83398151915260405161088e939291906134da565b6065546001600160a01b038083166000908152607260205260408082205490516321cc9a8360e21b815285949293909216916387326a0c9161098c916001600160801b039091169060040161303a565b608060405180830381865afa1580156109a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109cd9190613518565b5091925050506001600160a01b03811633146109fb5760405162461bcd60e51b81526004016106a990613577565b6001600160a01b038316600090815260746020526040902054600080516020613a2e83398151915214610a405760405162461bcd60e51b81526004016106a9906135ae565b610a4b606c84612889565b15610a965760405162461bcd60e51b815260206004820152601b60248201527a13dc195c985d1bdc881a5cc8185b1c9958591e48195b98589b1959602a1b60448201526064016106a9565b6001600160a01b0383166000908152607260205260409020546001600160801b0316610ac3606c856128a5565b506001600160801b03808216600090815260756020526040812080549092169190610aed836135f1565b82546001600160801b039182166101009390930a92830291909202199091161790555060655460405163edff4b6160e01b81526001600160a01b039091169063edff4b6190610b4090849060040161303a565b600060405180830381600087803b158015610b5a57600080fd5b505af1158015610b6e573d6000803e3d6000fd5b505050507f9e532d260bd7dde07708a6b1f7c64042546243d79bac23514cd74fcfc1a01fe484604051610ba1919061320f565b60405180910390a150505050565b610bba606e33612889565b610bd65760405162461bcd60e51b81526004016106a990613472565b60668190556040518181527fe8c66e2621de650a92131e007d8bbc4cbf3bb8d4df7471d1f93eb20d70039a7c9060200161088e565b600054610100900460ff1615808015610c2b5750600054600160ff909116105b80610c455750303b158015610c45575060005460ff166001145b610ca85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016106a9565b6000805460ff191660011790558015610ccb576000805461ff0019166101001790555b610cd3612919565b610cde606e336128a5565b50610cf8606a6000805160206139ce833981519152612948565b50610d12606a600080516020613a2e833981519152612948565b50610d2c606a600080516020613a0e833981519152612948565b50610d436102ae6002670de0b6b3a7640000613635565b610d52655af3107a4000610ea6565b610d5c60f0610e34565b610d666002611f62565b610d6f8261081c565b610d7a606e33612954565b506001600160a01b03831660009081526074602052604090206000805160206139ce8339815191529055610daf606e846128a5565b506000805160206139ae8339815191528360006000805160206139ce833981519152604051610de0939291906134da565b60405180910390a18015610e2f576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15b505050565b610e3f606e33612889565b610e5b5760405162461bcd60e51b81526004016106a990613472565b606980546001600160401b0319166001600160401b0383161790556040517f80972f2be3a50171fc4fb48963f365cbd47dc216ace7f3628a584503a80a9f979061088e908390613504565b610eb1606e33612889565b610ecd5760405162461bcd60e51b81526004016106a990613472565b606880546001600160801b0319166001600160801b0383161790556040517fa425d7d9b858a4250625446e4504257053202ae93ba0d1dea68dce7ec87a05c59061088e90839061303a565b610f23606c33612889565b610f805760405162461bcd60e51b815260206004820152602860248201527f53656e646572206973206e6f7420424c4f434b5f524553554c545f50524f44556044820152674345525f524f4c4560c01b60648201526084016106a9565b6001600160401b03808716600090815260776020526040812060048101549092169003610fe25760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a590818da185a5b88125160821b60448201526064016106a9565b6004810154610ffa906001600160401b031687613649565b6001600160401b0316156110475760405162461bcd60e51b8152602060048201526014602482015273125b9d985b1a5908189b1bd8dac81a195a59da1d60621b60448201526064016106a9565b6001600160401b0380881660009081526076602090815260408083208a851684528252808320600381015433855260028201909352908320909391909116918290036114b5576003830154600160401b900460ff16156110b95760405162461bcd60e51b81526004016106a99061366f565b600084600201546067548660010154436110d391906136a6565b6110dd91906136bd565b6110e79190613635565b85546110f391906136dc565b60038601549091506000906001600160801b031682101561111557600061112d565b600386015461112d906001600160801b0316836136a6565b90508a6001600160401b031681111580156111685750600386015461115b906001600160801b0316836136dc565b8b6001600160401b031611155b6111c85760405162461bcd60e51b815260206004820152602b60248201527f426c6f636b20686569676874206973206f7574206f6620626f756e647320666f60448201526a72206c6976652073796e6360a81b60648201526084016106a9565b6069546111de906001600160401b0316436136dc565b6003860180546001600160401b0319166001600160401b039283169081179091556040518d8316928f16917f8b1f889addbfa41db5227bae3b091bd5c8b9a9122f874dfe54ba2f75aabe1f4c916112359190613504565b60405180910390a3336000908152607260205260409081902054606554915163429a481b60e01b81526001600160801b03909116916001600160a01b03169063429a481b9061128890849060040161303a565b6020604051808303816000875af11580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb91906136f4565b6112e75760405162461bcd60e51b81526004016106a990613716565b606554604051634c4a170960e01b815260009182916001600160a01b0390911690634c4a17099061131c90869060040161303a565b6040805180830381865afa158015611338573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061135c9190613748565b909250905061136b8183613777565b8660000160006101000a8154816001600160801b0302191690836001600160801b03160217905550876001018d908060018154018082558091505060019003906000526020600020016000909190919091505560008860000160008f81526020019081526020016000209050806001018d90806001815401808255809150506001900390600052602060002001600090919091909150558060000160008e8152602001908152602001600020339080600181540180825580915050600190039060005260206000200160009091909190916101000a8154816001600160a01b0302191690836001600160a01b0316021790555086600001601081819054906101000a90046001600160801b031680929190611485906135f1565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505050506118a1565b816001600160401b03164311156114de5760405162461bcd60e51b81526004016106a99061366f565b600384015481546001600160801b03600160801b92839004811692909104161061154a5760405162461bcd60e51b815260206004820152601e60248201527f4d6178207375626d697373696f6e73206c696d6974206578636565646564000060448201526064016106a9565b6000888152602084905260409020815460018201906001600160801b0316156116845760005b815481101561167e576000836000016000848481548110611593576115936137a2565b90600052602060002001548152602001908152602001600020905060005b815481101561166957336001600160a01b03168282815481106115d6576115d66137a2565b6000918252602090912001546001600160a01b0316036116575760405162461bcd60e51b815260206004820152603660248201527f4f70657261746f7220616c7265616479207375626d697474656420666f7220746044820152750d0ca40e0e4deecd2c8cac840c4d8dec6d640d0c2e6d60531b60648201526084016106a9565b80611661816137b8565b9150506115b1565b50508080611676906137b8565b915050611570565b506117d1565b336000908152607260205260409081902054606554915163429a481b60e01b81526001600160801b03909116916001600160a01b03169063429a481b906116cf90849060040161303a565b6020604051808303816000875af11580156116ee573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171291906136f4565b61172e5760405162461bcd60e51b81526004016106a990613716565b606554604051634c4a170960e01b815260009182916001600160a01b0390911690634c4a17099061176390869060040161303a565b6040805180830381865afa15801561177f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117a39190613748565b90925090506117b28183613777565b86546001600160801b0319166001600160801b03919091161786555050505b600089815260208390526040902081541561180a578054600003611805578154600181018355600083815260209020018a90555b611837565b600180870180548083018255600091825260208083209091018e9055845492830185558482529020018a90555b80546001810182556000828152602090200180546001600160a01b0319163317905583546001600160801b03600160801b90910416846010611878836135f1565b91906101000a8154816001600160801b0302191690836001600160801b03160217905550505050505b60008781526078602090815260408220805460018101825590835291206118ca91018787612f55565b5080546040517f8741f5bf89731b15f24deb1e84e2bbd381947f009ee378a2daa15ed8abfb948591611913918d918d918d918d918d918d916001600160801b03909116906137d1565b60405180910390a150505050505050505050565b611932606e33612889565b61194e5760405162461bcd60e51b81526004016106a990613472565b6001600160401b038281166000908152607760205260409081902060030180546001600160801b0316928416600160801b0292909217909155517f1bca1fb481202bb14258ce1030d54e9e7bafc8b696d96b9eb733826e58a3a0309061077a908390613504565b6119c0606e33612889565b6119dc5760405162461bcd60e51b81526004016106a990613472565b6001600160a01b038116600090815260746020526040902054600080516020613a2e83398151915214611a215760405162461bcd60e51b81526004016106a9906135ae565b611a2c606c82612889565b15611a3a57611a3a81612969565b6001600160a01b0381166000908152607260209081526040808320546001600160801b0316835260739091529020611a729082612954565b506001600160a01b038116600090815260726020908152604080832080546001600160801b0319169055607490915280822091909155516000805160206139ee8339815191529061088e90839061320f565b611acc6128ba565b611ad66000612a2c565b565b6065546001600160a01b038083166000908152607260205260408082205490516321cc9a8360e21b815285949293909216916387326a0c91611b28916001600160801b039091169060040161303a565b608060405180830381865afa158015611b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b699190613518565b5091925050506001600160a01b0381163314611b975760405162461bcd60e51b81526004016106a990613577565b6001600160a01b038316600090815260746020526040902054600080516020613a2e83398151915214611bdc5760405162461bcd60e51b81526004016106a9906135ae565b611be7606c84612889565b611c325760405162461bcd60e51b815260206004820152601c60248201527b13dc195c985d1bdc881a5cc8185b1c9958591e48191a5cd8589b195960221b60448201526064016106a9565b611c3b83612969565b7f23cd406c7cafe6d88c3f1c1cc16e438745a4236aec25906be2046ca16c36bd1e83604051610e26919061320f565b6001600160401b038083166000908152607660209081526040808320858516845290915290206003810154909116438110611ce35760405162461bcd60e51b815260206004820152601960248201527853657373696f6e206e6f74207061737420646561646c696e6560381b60448201526064016106a9565b6003820154600160401b900460ff1615611d3d5760405162461bcd60e51b815260206004820152601b60248201527a14d95cdcda5bdb8818d85b9b9bdd08189948199a5b985b1a5e9959602a1b60448201526064016106a9565b806001600160401b0316600003611d8c5760405162461bcd60e51b815260206004820152601360248201527214d95cdcda5bdb881b9bdd081cdd185c9d1959606a1b60448201526064016106a9565b6000808080806001870181805b8254811015611e5757828181548110611db457611db46137a2565b6000918252602080832090910154808352908c905260408220909350905b6001820154811015611e4257816001018181548110611df357611df36137a2565b600091825260208083209091015480835290849052604090912054909950611e1b818c6136dc565b9a5088811115611e2f578098508497508996505b5080611e3a816137b8565b915050611dd2565b50508080611e4f906137b8565b915050611d99565b50606954600160401b90046001600160401b03168510801590611e97575060665487611e8b670de0b6b3a7640000886136bd565b611e959190613635565b115b15611eae57611ea9898c8c8787612a7e565b611ef0565b8a6001600160401b03167f398fd8f638a7242217f011fd0720a06747f7a85b7d28d7276684b841baea40218b604051611ee79190613504565b60405180910390a25b505050600390950180546001600160481b031916600160401b17905550505050505050565b6033546001600160a01b031690565b6000611f31606c83612889565b92915050565b606854600090606090600160801b90046001600160801b0316611f5a606c612d67565b915091509091565b611f6d606e33612889565b611f895760405162461bcd60e51b81526004016106a990613472565b60698054600160401b600160801b031916600160401b6001600160401b038416021790556040517febd426f3d605bdf7e97ba7cd4a971371661140ad0acc8e0081f067d2004a71769061088e908390613504565b611fe8606e33612889565b6120045760405162461bcd60e51b81526004016106a990613472565b6001600160401b0384166000908152607760205260409020816120695760405162461bcd60e51b815260206004820152601d60248201527f5365636f6e64732070657220626c6f636b2063616e6e6f74206265203000000060448201526064016106a9565b838155600181018390556002810182905560408051858152602081018590529081018390526001600160401b038616907ffd97af399d19e6be9256c99c8e52b1809cdbc4dc96816739612b6fd4e6d940b09060600160405180910390a25050505050565b6120d8606e33612889565b6120f45760405162461bcd60e51b81526004016106a990613472565b60655460405163a2e7e44160e01b81526001600160a01b0384811660048301526001600160801b03841660248301529091169063a2e7e441906044016020604051808303816000875af115801561214f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e2f9190613840565b61217e606e33612889565b61219a5760405162461bcd60e51b81526004016106a990613472565b6065546040516356cf48f760e11b81526001600160a01b039091169063ad9e91ee906121cc9085908590600401613859565b600060405180830381600087803b1580156121e657600080fd5b505af11580156121fa573d6000803e3d6000fd5b505050505050565b6001600160401b038381166000818152607660209081526040808320878616845282528083206003808201546001600160a01b03891686526002830185528386209686526077909452918420909101548454939591949290911692600160801b918290046001600160801b0390811692909104161480158161228d5750826001600160401b03164311155b806122b657506001600160401b0383161580156122b657506003840154600160401b900460ff16155b98975050505050505050565b6122cd607033612889565b6123165760405162461bcd60e51b815260206004820152601a60248201527953656e646572206973206e6f742041554449544f525f524f4c4560301b60448201526064016106a9565b6001600160401b0384811660009081526076602090815260408083209387168352929052206003810154600160401b900460ff166123a55760405162461bcd60e51b815260206004820152602660248201527f53657373696f6e206d7573742062652066696e616c697a6564206265666f726560448201526508185d591a5d60d21b60648201526084016106a9565b6123b28186868686612a7e565b5050505050565b6001600160801b0381166000908152607360205260409020606090611f3190612d67565b606060786000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156124be57838290600052602060002001805461243190613872565b80601f016020809104026020016040519081016040528092919081815260200182805461245d90613872565b80156124aa5780601f1061247f576101008083540402835291602001916124aa565b820191906000526020600020905b81548152906001019060200180831161248d57829003601f168201915b505050505081526020019060010190612412565b505050509050919050565b60608060606124d8606c612d67565b6124e2606e612d67565b6124ec6070612d67565b925092509250909192565b612502606e33612889565b61251e5760405162461bcd60e51b81526004016106a990613472565b6001600160401b03811660678190556040517fcaf46ba335d93b98398af7142ea3e362a6b8e91c57da6bf1e8a704f86374dde090600090a250565b612564606e33612889565b6125805760405162461bcd60e51b81526004016106a990613472565b6001600160401b0382811660008181526077602052604080822060040180546001600160401b0319169486169485179055517fbbfa9310306e8a8485d109f8be6b0a808473ce55d2e94b8ca3447c9ddb2854b49190a35050565b6125e5606e33612889565b6126015760405162461bcd60e51b81526004016106a990613472565b6001600160a01b038116600090815260746020526040902054156126375760405162461bcd60e51b81526004016106a9906134a9565b6001600160a01b0381166000908152607460205260409020600080516020613a0e833981519152905561266b6070826128a5565b506000805160206139ae833981519152816000600080516020613a0e83398151915260405161088e939291906134da565b6126a7606e33612889565b6126c35760405162461bcd60e51b81526004016106a990613472565b6001600160a01b038116600090815260746020526040902054600080516020613a0e833981519152146127325760405162461bcd60e51b815260206004820152601760248201527627b832b930ba37b91034b9903737ba1030bab234ba37b960491b60448201526064016106a9565b6001600160a01b038116600090815260746020526040812055612756607082612954565b506000805160206139ee8339815191528160405161088e919061320f565b61277c6128ba565b6001600160a01b0381166000908152607460205260409020546000805160206139ce833981519152146127ec5760405162461bcd60e51b815260206004820152601860248201527727b832b930ba37b91034b9903737ba1033b7bb32b93737b960411b60448201526064016106a9565b6001600160a01b038116600090815260746020526040812055612756606e82612954565b6128186128ba565b6001600160a01b03811661287d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016106a9565b61288681612a2c565b50565b600061289e836001600160a01b038416612d74565b9392505050565b600061289e836001600160a01b038416612d8c565b336128c3611f15565b6001600160a01b031614611ad65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016106a9565b600054610100900460ff166129405760405162461bcd60e51b81526004016106a9906138ac565b611ad6612dd6565b600061289e8383612d8c565b600061289e836001600160a01b038416612e06565b612974606c82612954565b506001600160a01b0381166000908152607260209081526040808320546001600160801b0390811680855260759093529083208054929392909116916129b9836138f7565b82546101009290920a6001600160801b0381810219909316918316021790915582811660009081526075602052604081205490911690039050612a28576065546040516356cf48f760e11b81526001600160a01b039091169063ad9e91ee906121cc9084904390600401613859565b5050565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000828152602086815260408083208484529091528120805482816001600160401b03811115612ab057612ab061391a565b604051908082528060200260200182016040528015612ad9578160200160208202803683370190505b5090506000826001600160401b03811115612af657612af661391a565b604051908082528060200260200182016040528015612b1f578160200160208202803683370190505b509050600060028b01815b85811015612b9357816000888381548110612b4757612b476137a2565b60009182526020808320909101546001600160a01b03168352820192909252604001902054612b7f906001600160801b031684613777565b925080612b8b816137b8565b915050612b2a565b5060005b85811015612c8857868181548110612bb157612bb16137a2565b60009182526020808320909101546001600160a01b031680835284825260408084206072909352909220548751929a5090916001600160801b0390911690879084908110612c0157612c016137a2565b6001600160801b039283166020918202929092010152606854825486831692612c2d92811691166136bd565b612c379190613635565b858381518110612c4957612c496137a2565b6001600160801b0392831660209182029290920101528154600160801b900416600103612c7557600081555b5080612c80816137b8565b915050612b97565b5060655460405163605a501760e01b81526001600160a01b039091169063605a501790612cbb9087908790600401613969565b600060405180830381600087803b158015612cd557600080fd5b505af1158015612ce9573d6000803e3d6000fd5b50505050888a6001600160401b03168c6001600160401b03167f93dcf9329a330cb95723152c05719560f2fbd50e215c542854b27acc80c9108d8b604051612d3391815260200190565b60405180910390a4600089815260208d90526040812090612d576001830182612fd9565b5050505050505050505050505050565b6060600061289e83612ef9565b60009081526001919091016020526040902054151590565b6000612d988383612d74565b612dce57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155611f31565b506000611f31565b600054610100900460ff16612dfd5760405162461bcd60e51b81526004016106a9906138ac565b611ad633612a2c565b60008181526001830160205260408120548015612eef576000612e2a6001836136a6565b8554909150600090612e3e906001906136a6565b9050818114612ea3576000866000018281548110612e5e57612e5e6137a2565b9060005260206000200154905080876000018481548110612e8157612e816137a2565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612eb457612eb4613997565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050611f31565b6000915050611f31565b606081600001805480602002602001604051908101604052809291908181526020018280548015612f4957602002820191906000526020600020905b815481526020019060010190808311612f35575b50505050509050919050565b828054612f6190613872565b90600052602060002090601f016020900481019282612f835760008555612fc9565b82601f10612f9c5782800160ff19823516178555612fc9565b82800160010185558215612fc9579182015b82811115612fc9578235825591602001919060010190612fae565b50612fd5929150612ff3565b5090565b508054600082559060005260206000209081019061288691905b5b80821115612fd55760008155600101612ff4565b6001600160a01b038116811461288657600080fd5b60006020828403121561302f57600080fd5b813561289e81613008565b6001600160801b0391909116815260200190565b6001600160801b038116811461288657600080fd5b6000806040838503121561307657600080fd5b823561308181613008565b915060208301356130918161304e565b809150509250929050565b80356001600160401b03811681146130b357600080fd5b919050565b600080604083850312156130cb57600080fd5b6130d48361309c565b91506130e26020840161309c565b90509250929050565b6000602082840312156130fd57600080fd5b5035919050565b6000806040838503121561311757600080fd5b823561312281613008565b9150602083013561309181613008565b60006020828403121561314457600080fd5b61289e8261309c565b60006020828403121561315f57600080fd5b813561289e8161304e565b60008060008060008060a0878903121561318357600080fd5b61318c8761309c565b955061319a6020880161309c565b9450604087013593506060870135925060808701356001600160401b03808211156131c457600080fd5b818901915089601f8301126131d857600080fd5b8135818111156131e757600080fd5b8a60208285010111156131f957600080fd5b6020830194508093505050509295509295509295565b6001600160a01b0391909116815260200190565b600081518084526020808501945080840160005b8381101561325c5781516001600160a01b031687529582019590820190600101613237565b509495945050505050565b6001600160801b038316815260406020820181905260009061328b90830184613223565b949350505050565b600080600080608085870312156132a957600080fd5b6132b28561309c565b966020860135965060408601359560600135945092505050565b600080604083850312156132df57600080fd5b82356132ea8161304e565b946020939093013593505050565b60008060006060848603121561330d57600080fd5b6133168461309c565b92506133246020850161309c565b9150604084013561333481613008565b809150509250925092565b6000806000806080858703121561335557600080fd5b61335e8561309c565b935061336c6020860161309c565b93969395505050506040820135916060013590565b60208152600061289e6020830184613223565b6000602080830181845280855180835260408601915060408160051b87010192508387016000805b8381101561342157888603603f1901855282518051808852835b818110156133f1578281018a01518982018b015289016133d6565b8181111561340157848a838b0101525b50601f01601f1916969096018701955093860193918601916001016133bc565b509398975050505050505050565b6060815260006134426060830186613223565b82810360208401526134548186613223565b905082810360408401526134688185613223565b9695505050505050565b6020808252601d908201527f53656e646572206973206e6f7420474f5645524e414e43455f524f4c45000000604082015260600190565b6020808252601790820152764f70657261746f7220616c72656164792065786973747360481b604082015260600190565b6001600160a01b039390931683526001600160801b03919091166020830152604082015260600190565b6001600160401b0391909116815260200190565b6000806000806080858703121561352e57600080fd5b845161353981613008565b602086015190945061354a8161304e565b604086015190935061355b8161304e565b606086015190925061356c8161304e565b939692955090935050565b6020808252601e908201527f53656e646572206973206e6f74206f70657261746f72206d616e616765720000604082015260600190565b60208082526013908201527204f70657261746f72206973206e6f742042525606c1b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b038281166002600160801b03198101613615576136156135db565b6001019392505050565b634e487b7160e01b600052601260045260246000fd5b6000826136445761364461361f565b500490565b60006001600160401b03838116806136635761366361361f565b92169190910692915050565b6020808252601f908201527f53657373696f6e207375626d697373696f6e73206861766520636c6f73656400604082015260600190565b6000828210156136b8576136b86135db565b500390565b60008160001904831182151516156136d7576136d76135db565b500290565b600082198211156136ef576136ef6135db565b500190565b60006020828403121561370657600080fd5b8151801515811461289e57600080fd5b60208082526018908201527715985b1a59185d1bdc881a5cc81b9bdd08195b98589b195960421b604082015260600190565b6000806040838503121561375b57600080fd5b82516137668161304e565b60208401519092506130918161304e565b60006001600160801b03828116848216808303821115613799576137996135db565b01949350505050565b634e487b7160e01b600052603260045260246000fd5b6000600182016137ca576137ca6135db565b5060010190565b6001600160401b03888116825287166020820152604081018690526060810185905260c06080820181905281018390526000838560e084013750600081840160e0908101919091526001600160801b039290921660a0820152601f909201601f19169091010195945050505050565b60006020828403121561385257600080fd5b5051919050565b6001600160801b03929092168252602082015260400190565b600181811c9082168061388657607f821691505b6020821081036138a657634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b60006001600160801b03821680613910576139106135db565b6000190192915050565b634e487b7160e01b600052604160045260246000fd5b600081518084526020808501945080840160005b8381101561325c5781516001600160801b031687529582019590820190600101613944565b60408152600061397c6040830185613930565b828103602084015261398e8185613930565b95945050505050565b634e487b7160e01b600052603160045260246000fdfe797ca55fc7be0f65c71f10996f7a16f801094f8ae3811874afc5a39730772a4271840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb180c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d59a1c48e5837ad7a7f3dcedcbe129bf3249ec4fbf651fd4f5e2600ead39fe2f577ae3b5d012484be69eeed881350adb3189b651fac6e88b31ddff30c833a8b7fa2646970667358221220e720bb6d0e325a223aac177fcaaa778e1382d880fdf7b87e40ff8dbab6c7f3ab64736f6c634300080d0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.