Contract
0x8d8675c9292bf61fa45f1ff3cb4b041f7487651d
1
Contract Overview
Balance:
0 AVAX
AVAX Value:
$0.00
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
ForeignChain
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./Chain.sol"; /// @dev contract for foreign chains contract ForeignChain is Chain { error NotSupported(); /// @param _contractRegistry Registry address /// @param _padding required "space" between blocks in seconds /// @param _requiredSignatures number of required signatures for accepting consensus submission constructor( IRegistry _contractRegistry, uint32 _padding, uint16 _requiredSignatures, bool _allowForMixedType ) Chain(_contractRegistry, _padding, _requiredSignatures, _allowForMixedType) { // no additional configuration needed } /// @inheritdoc BaseChain function isForeign() external pure override returns (bool) { return true; } /// @inheritdoc Chain /// @notice this method is made to be compatible with MasterChain, but it does not return full data eg validators /// data will be missing. /// @return blockNumber `block.number` /// @return timePadding `this.padding` /// @return lastDataTimestamp timestamp for last submitted consensus /// @return lastId ID of last submitted consensus /// @return nextLeader will be always address(0) /// @return nextBlockId block ID for `block.timestamp + padding` /// @return validators array will be always empty /// @return powers array will be always empty /// @return locations array will be always empty /// @return staked total UMB staked by validators /// @return minSignatures `this.requiredSignatures` function getStatus() external view override returns( uint256 blockNumber, uint32 timePadding, uint32 lastDataTimestamp, uint32 lastId, address nextLeader, uint32 nextBlockId, address[] memory validators, uint256[] memory powers, string[] memory locations, uint256 staked, uint16 minSignatures ) { ConsensusData memory data = _consensusData; blockNumber = block.number; timePadding = data.padding; lastId = data.lastTimestamp; lastDataTimestamp = lastId; minSignatures = _REQUIRED_SIGNATURES; staked = stakingBank.totalSupply(); uint256 numberOfValidators = 0; powers = new uint256[](numberOfValidators); validators = new address[](numberOfValidators); locations = new string[](numberOfValidators); nextLeader = address(0); unchecked { // we will not overflow with timestamp in a lifetime nextBlockId = lastId + data.padding + 1; } } function getLeaderIndex(uint256, uint256) public pure override returns (uint256) { revert NotSupported(); } function getLeaderAddressAtTime(uint256) public pure override returns (address) { revert NotSupported(); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "./BaseChain.sol"; contract Chain is BaseChain { IStakingBank public immutable stakingBank; event LogMint(address indexed minter, uint256 blockId, uint256 staked, uint256 power); event LogVoter(uint256 indexed blockId, address indexed voter, uint256 vote); error NotEnoughSignatures(); error SignaturesOutOfOrder(); /// @param _contractRegistry Registry address /// @param _padding required "space" between blocks in seconds /// @param _requiredSignatures number of required signatures for accepting consensus submission /// @param _allowForMixedType we have two "types" of Chain: HomeChain and ForeignChain, when we redeploying /// we don't want to mix up them, so we checking, if new Chain has the same type as current one. /// However, when we will be switching from one homechain to another one, we have to allow for this mixing up. /// This flag will tell contract, if this is the case. constructor( IRegistry _contractRegistry, uint32 _padding, uint16 _requiredSignatures, bool _allowForMixedType ) BaseChain(_contractRegistry, _padding, _requiredSignatures, _allowForMixedType) { stakingBank = IStakingBank(_contractRegistry.requireAndGetAddress("StakingBank")); } /// @dev method for submitting consensus data /// @param _dataTimestamp consensus timestamp, this is time for all data in merkle tree including FCDs /// @param _root merkle root /// @param _keys FCDs keys /// @param _values FCDs values /// @param _v array of `v` part of validators signatures /// @param _r array of `r` part of validators signatures /// @param _s array of `s` part of validators signatures // solhint-disable-next-line function-max-lines, code-complexity function submit( uint32 _dataTimestamp, bytes32 _root, bytes32[] memory _keys, uint256[] memory _values, uint8[] memory _v, bytes32[] memory _r, bytes32[] memory _s ) external { // below two checks are only for pretty errors, so we can safe gas and allow for raw revert // if (_keys.length != _values.length) revert ArraysDataDoNotMatch(); // if (_v.length != _r.length || _r.length != _s.length) revert ArraysDataDoNotMatch(); _verifySubmitTimestampAndIncSequence(_dataTimestamp); // we can't expect minter will have exactly the same timestamp // but for sure we can demand not to be off by a lot, that's why +3sec // temporary remove this condition, because recently on ropsten we see cases when minter/node // can be even 100sec behind // require(_dataTimestamp <= block.timestamp + 3, // string(abi.encodePacked("oh, so you can predict the future:", _dataTimestamp - block.timestamp + 48))); bytes memory testimony = abi.encodePacked(_dataTimestamp, _root); for (uint256 i = 0; i < _keys.length;) { if (uint224(_values[i]) != _values[i]) revert FCDOverflow(); fcds[_keys[i]] = FirstClassData(uint224(_values[i]), _dataTimestamp); testimony = abi.encodePacked(testimony, _keys[i], _values[i]); unchecked { // we can't pass enough data to overflow i++; } } uint256 signatures = 0; uint256 power = 0; //uint256 staked = stakingBank.totalSupply(); bytes32 affidavit = keccak256(testimony); address prevSigner = address(0x0); for (uint256 i; i < _v.length;) { address signer = recoverSigner(affidavit, _v[i], _r[i], _s[i]); uint256 balance = stakingBank.balanceOf(signer); if (prevSigner >= signer) revert SignaturesOutOfOrder(); prevSigner = signer; if (balance == 0) { unchecked { i++; } continue; } signatures++; emit LogVoter(uint256(_dataTimestamp), signer, balance); unchecked { // we can't overflow because that means token overflowed // and even if we do, we will get lower power power += balance; i++; } } if (signatures < _REQUIRED_SIGNATURES) revert NotEnoughSignatures(); emit LogMint(msg.sender, _dataTimestamp, stakingBank.totalSupply(), power); // TODO remember to protect against flash loans when DPoS will be in place // we turn on power once we have DPoS in action, we have PoA now // require(power * 100 / staked >= 66, "not enough power was gathered"); roots[_dataTimestamp] = _root; _consensusData.lastTimestamp = _dataTimestamp; } /// @inheritdoc BaseChain function isForeign() external pure virtual override returns (bool) { return false; } /// @dev helper method that returns all important data about current state of contract /// @return blockNumber `block.number` /// @return timePadding `this.padding` /// @return lastDataTimestamp timestamp for last submitted consensus /// @return lastId ID of last submitted consensus /// @return nextLeader leader for `block.timestamp + 1` /// @return nextBlockId block ID for `block.timestamp + padding` /// @return validators array of all validators addresses /// @return powers array of all validators powers /// @return locations array of all validators locations /// @return staked total UMB staked by validators /// @return minSignatures `this.requiredSignatures` function getStatus() external view virtual returns( uint256 blockNumber, uint32 timePadding, uint32 lastDataTimestamp, uint32 lastId, address nextLeader, uint32 nextBlockId, address[] memory validators, uint256[] memory powers, string[] memory locations, uint256 staked, uint16 minSignatures ) { ConsensusData memory data = _consensusData; blockNumber = block.number; timePadding = data.padding; lastId = data.lastTimestamp; lastDataTimestamp = lastId; minSignatures = _REQUIRED_SIGNATURES; staked = stakingBank.totalSupply(); uint256 numberOfValidators = stakingBank.getNumberOfValidators(); powers = new uint256[](numberOfValidators); validators = new address[](numberOfValidators); locations = new string[](numberOfValidators); for (uint256 i = 0; i < numberOfValidators;) { validators[i] = stakingBank.addresses(i); (, locations[i]) = stakingBank.validators(validators[i]); powers[i] = stakingBank.balanceOf(validators[i]); unchecked { // we will run out of gas before overflow happen i++; } } unchecked { // we will not overflow with timestamp in a lifetime nextBlockId = lastId + data.padding + 1; nextLeader = numberOfValidators > 0 // we will not overflow with timestamp in a lifetime ? validators[getLeaderIndex(numberOfValidators, block.timestamp + 1)] : address(0); } } /// @return address of leader for next second function getNextLeaderAddress() external view returns (address) { return getLeaderAddressAtTime(block.timestamp + 1); } /// @return address of current leader function getLeaderAddress() external view returns (address) { return getLeaderAddressAtTime(block.timestamp); } /// @param _numberOfValidators total number of validators /// @param _timestamp timestamp for which you want to calculate index /// @return leader index, use it for StakingBank.addresses[index] to fetch leader address function getLeaderIndex(uint256 _numberOfValidators, uint256 _timestamp) public view virtual returns (uint256) { ConsensusData memory data = _consensusData; unchecked { // we will not overflow on `timestamp` and `padding` in a life time // timePadding + 1 => because padding is a space between blocks, // so next round starts on first block after padding // TODO will it work for off-chain?? uint256 validatorIndex = data.sequence + (_timestamp - data.lastTimestamp) / (data.padding + 1); return validatorIndex % _numberOfValidators; } } // @todo - properly handled non-enabled validators, newly added validators, and validators with low stake /// @param _timestamp timestamp for which you want to calculate leader address /// @return leader address for provider timestamp function getLeaderAddressAtTime(uint256 _timestamp) public view virtual returns (address) { uint256 numberOfValidators = stakingBank.getNumberOfValidators(); if (numberOfValidators == 0) { return address(0x0); } uint256 validatorIndex = getLeaderIndex(numberOfValidators, _timestamp); return stakingBank.addresses(validatorIndex); } /// @dev we had stack too deep in `submit` so this method was created as a solution // we increasing `_consensusData.sequence` here so we don't have to read sequence again in other place function _verifySubmitTimestampAndIncSequence(uint256 _dataTimestamp) internal { ConsensusData memory data = _consensusData; // `data.lastTimestamp` must be setup either on deployment // or via cloning from previous contract if (data.lastTimestamp == 0) revert ContractNotReady(); unchecked { // we will not overflow with timestamp and padding in a life time if (data.lastTimestamp + data.padding >= _dataTimestamp) revert BlockSubmittedToFastOrDataToOld(); } unchecked { // we will not overflow in a life time _consensusData.sequence = uint32(data.sequence + 1); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@umb-network/toolbox/dist/contracts/lib/ValueDecoder.sol"; import "./interfaces/IBaseChainV1.sol"; import "./interfaces/IStakingBank.sol"; import "./extensions/Registrable.sol"; import "./Registry.sol"; abstract contract BaseChain is Registrable, Ownable { using ValueDecoder for bytes; using ValueDecoder for uint224; using MerkleProof for bytes32[]; /// @param root merkle root for consensus /// @param dataTimestamp consensus timestamp struct Block { bytes32 root; uint32 dataTimestamp; } /// @param value FCD value /// @param dataTimestamp FCD timestamp struct FirstClassData { uint224 value; uint32 dataTimestamp; } /// @param blocksCountOffset number of all blocks that were generated before switching to this contract /// @param sequence is a total number of blocks (consensus rounds) including previous contracts /// @param lastTimestamp is a timestamp of last submitted block /// @param padding number of seconds that need to pass before new submit will be possible /// @param deprecated flag that changes to TRUE on `unregister`, when TRUE submissions are not longer available struct ConsensusData { uint32 blocksCountOffset; uint32 sequence; uint32 lastTimestamp; uint32 padding; bool deprecated; } uint256 constant public VERSION = 2; bool internal immutable _ALLOW_FOR_MIXED_TYPE; // solhint-disable-line var-name-mixedcase bytes4 constant private _VERSION_SELECTOR = bytes4(keccak256("VERSION()")); /// @dev minimal number of signatures required for accepting submission (PoA) uint16 internal immutable _REQUIRED_SIGNATURES; // solhint-disable-line var-name-mixedcase ConsensusData internal _consensusData; bytes constant public ETH_PREFIX = "\x19Ethereum Signed Message:\n32"; /// @dev block id (consensus ID) => root /// consensus ID is at the same time consensus timestamp mapping(uint256 => bytes32) public roots; /// @dev FCD key => FCD data mapping(bytes32 => FirstClassData) public fcds; event LogDeprecation(address indexed deprecator); event LogPadding(address indexed executor, uint32 timePadding); error ArraysDataDoNotMatch(); error AlreadyDeprecated(); error AlreadyRegistered(); error BlockSubmittedToFastOrDataToOld(); error ContractNotReady(); error FCDOverflow(); error InvalidContractType(); error NoChangeToState(); error OnlyOwnerOrRegistry(); error UnregisterFirst(); modifier onlyOwnerOrRegistry () { if (msg.sender != address(contractRegistry) && msg.sender != owner()) revert OnlyOwnerOrRegistry(); _; } /// @param _contractRegistry Registry address /// @param _padding required "space" between blocks in seconds /// @param _requiredSignatures number of required signatures for accepting consensus submission constructor( IRegistry _contractRegistry, uint32 _padding, uint16 _requiredSignatures, bool _allowForMixedType ) Registrable(_contractRegistry) { _ALLOW_FOR_MIXED_TYPE = _allowForMixedType; _REQUIRED_SIGNATURES = _requiredSignatures; _setPadding(_padding); BaseChain oldChain = BaseChain(_contractRegistry.getAddress("Chain")); if (address(oldChain) == address(0)) { // if this is first contract in sidechain, then we need to initialise lastTimestamp so submission // can be possible _consensusData.lastTimestamp = uint32(block.timestamp) - _padding - 1; } } /// @dev setter for `padding` function setPadding(uint16 _padding) external { _setPadding(_padding); } /// @notice if this method needs to be called manually (not from Registry) /// it is important to do it as part of tx batch /// eg using multisig, we should prepare set of transactions and confirm them all at once /// @inheritdoc Registrable function register() external override onlyOwnerOrRegistry { address oldChain = contractRegistry.getAddress("Chain"); // registration must be done before address in registry is replaced if (oldChain == address(this)) revert AlreadyRegistered(); if (oldChain == address(0x0)) { return; } _cloneLastDataFromPrevChain(oldChain); } /// @inheritdoc Registrable function unregister() external override onlyOwnerOrRegistry { // in case we deprecated contract manually, we simply return if (_consensusData.deprecated) return; address newChain = contractRegistry.getAddress("Chain"); // unregistering must be done after address in registry is replaced if (newChain == address(this)) revert UnregisterFirst(); // TODO: // I think we need to remove restriction for type (at least once) // when we will switch to multichain architecture if (!_ALLOW_FOR_MIXED_TYPE) { // can not be replaced with chain of different type if (BaseChain(newChain).isForeign() != this.isForeign()) revert InvalidContractType(); } _consensusData.deprecated = true; emit LogDeprecation(msg.sender); } /// @notice it allows to deprecate contract manually /// Only new Registry calls `unregister()` where we set deprecated to true /// In old Registries we don't have this feature, so in order to safely redeploy new Chain /// we will have to first deprecate current contract manually, then register new contract function deprecate() external onlyOwnerOrRegistry { if (_consensusData.deprecated) revert AlreadyDeprecated(); _consensusData.deprecated = true; emit LogDeprecation(msg.sender); } /// @dev getter for `_consensusData` function getConsensusData() external view returns (ConsensusData memory) { return _consensusData; } /// @dev number of blocks (consensus rounds) saved in this contract function blocksCount() external view returns (uint256) { return _consensusData.sequence - _consensusData.blocksCountOffset; } function blocksCountOffset() external view returns (uint32) { return _consensusData.blocksCountOffset; } function lastBlockId() external view returns (uint256) { return _consensusData.lastTimestamp; } /// @return TRUE if contract is ForeignChain, FALSE otherwise function isForeign() external pure virtual returns (bool); /// @inheritdoc Registrable function getName() external pure override returns (bytes32) { return "Chain"; } /// @param _affidavit root and FCDs hashed together /// @param _v part of signature /// @param _r part of signature /// @param _s part of signature /// @return signer address function recoverSigner(bytes32 _affidavit, uint8 _v, bytes32 _r, bytes32 _s) public pure returns (address) { bytes32 hash = keccak256(abi.encodePacked(ETH_PREFIX, _affidavit)); return ecrecover(hash, _v, _r, _s); } /// @param _blockId ID of submitted block /// @return block data (root + timestamp) function blocks(uint256 _blockId) external view returns (Block memory) { return Block(roots[_blockId], uint32(_blockId)); } /// @return current block ID /// please note, that current ID is not the same as last ID, current means that once padding pass, /// ID will switch to next one and it will be pointing to empty submit until submit for that ID is done function getBlockId() external view returns (uint32) { if (_consensusData.lastTimestamp == 0) return 0; return getBlockIdAtTimestamp(block.timestamp); } function requiredSignatures() external view returns (uint16) { return _REQUIRED_SIGNATURES; } /// @dev calculates block ID for provided timestamp /// this function does not works for past timestamps /// @param _timestamp current or future timestamp /// @return block ID for provided timestamp function getBlockIdAtTimestamp(uint256 _timestamp) virtual public view returns (uint32) { ConsensusData memory data = _consensusData; unchecked { // we can't overflow because we adding two `uint32` if (data.lastTimestamp + data.padding < _timestamp) { return uint32(_timestamp); } } return data.lastTimestamp; } /// @return last submitted block ID, please note, that on deployment, when there is no submission for this contract /// block for last ID will be available in previous contract function getLatestBlockId() virtual public view returns (uint32) { return _consensusData.lastTimestamp; } /// @dev verifies if the leaf is valid leaf for merkle tree /// @param _proof merkle proof for merkle tree /// @param _root merkle root /// @param _leaf leaf hash /// @return TRUE if `_leaf` is valid, FALSE otherwise function verifyProof(bytes32[] memory _proof, bytes32 _root, bytes32 _leaf) public pure returns (bool) { if (_root == bytes32(0)) { return false; } return _proof.verify(_root, _leaf); } /// @dev creates leaf hash, that has is used in merkle tree /// @param _key key under which we store the value /// @param _value value itself as bytes /// @return leaf hash function hashLeaf(bytes memory _key, bytes memory _value) public pure returns (bytes32) { return keccak256(abi.encodePacked(_key, _value)); } /// @dev verifies, if provided key-value pair was part of consensus /// @param _blockId consensus ID for which we doing a check /// @param _proof merkle proof for pair /// @param _key pair key /// @param _value pair value /// @return TRUE if key-value par was part of consensus, FALSE otherwise function verifyProofForBlock( uint256 _blockId, bytes32[] memory _proof, bytes memory _key, bytes memory _value ) public view returns (bool) { return _proof.verify(roots[_blockId], keccak256(abi.encodePacked(_key, _value))); } /// @dev this is helper method, that extracts one merkle proof from many hashed provided as bytes /// @param _data many hashes as bytes /// @param _offset this is starting point for extraction /// @param _items how many hashes to extract /// @return merkle proof (array of bytes32 hashes) function bytesToBytes32Array( bytes memory _data, uint256 _offset, uint256 _items ) public pure returns (bytes32[] memory) { bytes32[] memory dataList = new bytes32[](_items); // we can unchecked because we working only with `i` and `_offset` // in case of wrong `_offset` it will throw unchecked { for (uint256 i = 0; i < _items; i++) { bytes32 temp; uint256 idx = (i + 1 + _offset) * 32; // solhint-disable-next-line no-inline-assembly assembly { temp := mload(add(_data, idx)) } dataList[i] = temp; } } return (dataList); } /// @dev batch method for data verification /// @param _blockIds consensus IDs for which we doing a checks /// @param _proofs merkle proofs for all pair, sequence of hashes provided as bytes /// @param _proofItemsCounter array of counters, each counter tells how many hashes proof for each leaf has /// @param _leaves array of merkle leaves /// @return results array of verification results, TRUE if leaf is part of consensus, FALSE otherwise function verifyProofs( uint32[] memory _blockIds, bytes memory _proofs, uint256[] memory _proofItemsCounter, bytes32[] memory _leaves ) public view returns (bool[] memory results) { results = new bool[](_leaves.length); uint256 offset = 0; for (uint256 i = 0; i < _leaves.length;) { results[i] = bytesToBytes32Array(_proofs, offset, _proofItemsCounter[i]).verify( roots[_blockIds[i]], _leaves[i] ); unchecked { // we can uncheck because it will not overflow in a lifetime, and if someone provide invalid counter // we verification will not be valid (or we throw because of invalid memory access) offset += _proofItemsCounter[i]; // we can uncheck because `i` will not overflow in a lifetime i++; } } } /// @param _blockId consensus ID /// @return root for provided consensus ID function getBlockRoot(uint32 _blockId) external view returns (bytes32) { return roots[_blockId]; } /// @param _blockId consensus ID /// @return timestamp for provided consensus ID function getBlockTimestamp(uint32 _blockId) external view returns (uint32) { return roots[_blockId] == bytes32(0) ? 0 : _blockId; } /// @dev batch getter for FCDs /// @param _keys FCDs keys to fetch /// @return values array of FCDs values /// @return timestamps array of FCDs timestamps function getCurrentValues(bytes32[] calldata _keys) external view returns (uint256[] memory values, uint32[] memory timestamps) { timestamps = new uint32[](_keys.length); values = new uint256[](_keys.length); for (uint i=0; i<_keys.length;) { FirstClassData storage numericFCD = fcds[_keys[i]]; values[i] = uint256(numericFCD.value); timestamps[i] = numericFCD.dataTimestamp; unchecked { // we can uncheck because `i` will not overflow in a lifetime i++; } } } /// @dev getter for single FCD value /// @param _key FCD key /// @return value FCD value /// @return timestamp FCD timestamp function getCurrentValue(bytes32 _key) external view returns (uint256 value, uint256 timestamp) { FirstClassData storage numericFCD = fcds[_key]; return (uint256(numericFCD.value), numericFCD.dataTimestamp); } /// @dev getter for single FCD value in case its type is `int` /// @param _key FCD key /// @return value FCD value /// @return timestamp FCD timestamp function getCurrentIntValue(bytes32 _key) external view returns (int256 value, uint256 timestamp) { FirstClassData storage numericFCD = fcds[_key]; return (numericFCD.value.toInt(), numericFCD.dataTimestamp); } function _setPadding(uint32 _padding) internal onlyOwner { if (_consensusData.padding == _padding) revert NoChangeToState(); _consensusData.padding = _padding; emit LogPadding(msg.sender, _padding); } /// @dev we cloning last block time, because we will need reference point for next submissions function _cloneLastDataFromPrevChain(address _prevChain) internal { (bool success, bytes memory v) = _prevChain.staticcall(abi.encode(_VERSION_SELECTOR)); uint256 prevVersion = success ? abi.decode(v, (uint256)) : 1; if (prevVersion == 1) { uint32 latestId = IBaseChainV1(address(_prevChain)).getLatestBlockId(); _consensusData.lastTimestamp = IBaseChainV1(address(_prevChain)).getBlockTimestamp(latestId); // +1 because getLatestBlockId subtracts 1 // +1 because it might be situation when tx is already in progress in old contract // and old contract do not have deprecated flag _consensusData.sequence = latestId + 2; _consensusData.blocksCountOffset = latestId + 2; } else { // VERSION 2 // with new Registry, we have register/unregister methods // Chain will be deprecated, so there is no need to do "+1" as in old version // TODO what with current Registries?? // we need a way to make it deprecated! ConsensusData memory data = BaseChain(_prevChain).getConsensusData(); _consensusData.sequence = data.sequence; _consensusData.blocksCountOffset = data.sequence; _consensusData.lastTimestamp = data.lastTimestamp; } } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.13; // Inheritance import "@openzeppelin/contracts/access/Ownable.sol"; import "./extensions/Registrable.sol"; import "./interfaces/IRegistry.sol"; /// @dev contracts registry /// protocol uses this registry to fetch current contract addresses contract Registry is IRegistry, Ownable { /// name => contract address mapping(bytes32 => address) public registry; error NameNotRegistered(); error ArraysDataDoNotMatch(); /// @inheritdoc IRegistry function importAddresses(bytes32[] calldata _names, address[] calldata _destinations) external onlyOwner { if (_names.length != _destinations.length) revert ArraysDataDoNotMatch(); for (uint i = 0; i < _names.length;) { registry[_names[i]] = _destinations[i]; emit LogRegistered(_destinations[i], _names[i]); unchecked { i++; } } } /// @inheritdoc IRegistry function importContracts(address[] calldata _destinations) external onlyOwner { for (uint i = 0; i < _destinations.length;) { bytes32 name = Registrable(_destinations[i]).getName(); registry[name] = _destinations[i]; emit LogRegistered(_destinations[i], name); unchecked { i++; } } } /// @inheritdoc IRegistry function atomicUpdate(address _newContract) external onlyOwner { Registrable(_newContract).register(); bytes32 name = Registrable(_newContract).getName(); address oldContract = registry[name]; registry[name] = _newContract; Registrable(oldContract).unregister(); emit LogRegistered(_newContract, name); } /// @inheritdoc IRegistry function requireAndGetAddress(bytes32 name) external view returns (address) { address _foundAddress = registry[name]; if (_foundAddress == address(0)) revert NameNotRegistered(); return _foundAddress; } /// @inheritdoc IRegistry function getAddress(bytes32 _bytes) external view returns (address) { return registry[_bytes]; } /// @inheritdoc IRegistry function getAddressByString(string memory _name) public view returns (address) { return registry[stringToBytes32(_name)]; } /// @inheritdoc IRegistry function stringToBytes32(string memory _string) public pure returns (bytes32 result) { bytes memory tempEmptyStringTest = bytes(_string); if (tempEmptyStringTest.length == 0) { return 0x0; } // solhint-disable-next-line no-inline-assembly assembly { result := mload(add(_string, 32)) } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IBaseChainV1 { /// @dev number of blocks (consensus rounds) saved in this contract function blocksCount() external returns (uint32); /// @dev number of all blocks that were generated before switching to this contract /// please note, that there might be a gap of one block when we switching from old to new contract /// see constructor for details function blocksCountOffset() external returns (uint32); function getLatestBlockId() external view returns (uint32); function getBlockTimestamp(uint32 _blockId) external view returns (uint32); function getStatus() external view returns ( uint256 blockNumber, uint16 timePadding, uint32 lastDataTimestamp, uint32 lastId, uint32 nextBlockId ); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IStakingBank is IERC20 { /// @param id address of validator wallet /// @param location URL of the validator API struct Validator { address id; string location; } event LogValidatorRegistered(address indexed id); event LogValidatorUpdated(address indexed id); event LogValidatorRemoved(address indexed id); event LogMinAmountForStake(uint256 minAmountForStake); /// @dev setter for `minAmountForStake` function setMinAmountForStake(uint256 _minAmountForStake) external; /// @dev allows to stake `token` by validators /// Validator needs to approve StakingBank beforehand /// @param _value amount of tokens to stake function stake(uint256 _value) external; /// @dev notification about approval from `_from` address on UMB token /// Staking bank will stake max approved amount from `_from` address /// @param _from address which approved token spend for IStakingBank function receiveApproval(address _from) external returns (bool success); /// @dev withdraws stake tokens /// it throws, when balance will be less than required minimum for stake /// to withdraw all use `exit` function withdraw(uint256 _value) external returns (bool success); /// @dev unstake and withdraw all tokens function exit() external returns (bool success); /// @dev creates (register) new validator /// @param _id validator address /// @param _location location URL of the validator API function create(address _id, string calldata _location) external; /// @dev removes validator /// @param _id validator wallet function remove(address _id) external; /// @dev updates validator location /// @param _id validator wallet /// @param _location new validator URL function update(address _id, string calldata _location) external; /// @return total number of registered validators (with and without balance) function getNumberOfValidators() external view returns (uint256); /// @dev gets validator address for provided index /// @param _ix index in array of list of all validators wallets function addresses(uint256 _ix) external view returns (address); /// @param _id address of validator /// @return id address of validator /// @return location URL of validator function validators(address _id) external view returns (address id, string memory location); }
//SPDX-License-Identifier: MIT pragma solidity 0.8.13; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "../interfaces/IRegistry.sol"; import "../interfaces/IStakingBank.sol"; /// @dev Any contract that we want to register in ContractRegistry, must inherit from Registrable abstract contract Registrable { IRegistry public immutable contractRegistry; modifier onlyFromContract(address _msgSender, bytes32 _contractName) { require( contractRegistry.getAddress(_contractName) == _msgSender, string(abi.encodePacked("caller is not ", _contractName)) ); _; } modifier withRegistrySetUp() { require(address(contractRegistry) != address(0x0), "_registry is empty"); _; } constructor(IRegistry _contractRegistry) { require(address(_contractRegistry) != address(0x0), "_registry is empty"); contractRegistry = _contractRegistry; } /// @dev this method will be called as a first method in registration process when old contract will be replaced /// when called, old contract address is still in registry function register() virtual external; /// @dev this method will be called as a last method in registration process when old contract will be replaced /// when called, new contract address is already in registry function unregister() virtual external; /// @return contract name as bytes32 function getName() virtual external pure returns (bytes32); /// @dev helper method for fetching StakingBank address function stakingBankContract() public view returns (IStakingBank) { return IStakingBank(contractRegistry.requireAndGetAddress("StakingBank")); } /// @dev helper method for fetching UMB address function tokenContract() public view withRegistrySetUp returns (ERC20) { return ERC20(contractRegistry.requireAndGetAddress("UMB")); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.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 Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Trees proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = _efficientHash(computedHash, proofElement); } else { // Hash(current element of the proof + current computed hash) computedHash = _efficientHash(proofElement, computedHash); } } return computedHash; } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
//SPDX-License-Identifier: Unlicensed pragma solidity >=0.6.8; library ValueDecoder { function toUint(bytes memory _bytes) internal pure returns (uint256 value) { assembly { value := mload(add(_bytes, 32)) } } function toUint(bytes32 _bytes) internal pure returns (uint256 value) { assembly { value := _bytes } } function toInt(uint224 u) internal pure returns (int256) { int224 i; uint224 max = type(uint224).max; if (u <= (max - 1) / 2) { // positive values assembly { i := add(u, 0) } return i; } else { // negative values assembly { i := sub(sub(u, max), 1) } } return i; } }
//SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IRegistry { event LogRegistered(address indexed destination, bytes32 name); /// @dev imports new contract addresses and override old addresses, if they exist under provided name /// This method can be used for contracts that for some reason do not have `getName` method /// @param _names array of contract names that we want to register /// @param _destinations array of contract addresses function importAddresses(bytes32[] calldata _names, address[] calldata _destinations) external; /// @dev imports new contracts and override old addresses, if they exist. /// Names of contracts are fetched directly from each contract by calling `getName` /// @param _destinations array of contract addresses function importContracts(address[] calldata _destinations) external; /// @dev this method ensure, that old and new contract is aware of it state in registry /// Note: BSC registry does not have this method. This method was introduced in later stage. /// @param _newContract address of contract that will replace old one function atomicUpdate(address _newContract) external; /// @dev similar to `getAddress` but throws when contract name not exists /// @param name contract name /// @return contract address registered under provided name or throws, if does not exists function requireAndGetAddress(bytes32 name) external view returns (address); /// @param name contract name in a form of bytes32 /// @return contract address registered under provided name function getAddress(bytes32 name) external view returns (address); /// @param _name contract name /// @return contract address assigned to the name or address(0) if not exists function getAddressByString(string memory _name) external view returns (address); /// @dev helper method that converts string to bytes32, /// you can use to to generate contract name function stringToBytes32(string memory _string) external pure returns (bytes32 result); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, allowance(owner, spender) + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Updates `owner` s allowance for `spender` based on spent `amount`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"inputs":[{"internalType":"contract IRegistry","name":"_contractRegistry","type":"address"},{"internalType":"uint32","name":"_padding","type":"uint32"},{"internalType":"uint16","name":"_requiredSignatures","type":"uint16"},{"internalType":"bool","name":"_allowForMixedType","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyDeprecated","type":"error"},{"inputs":[],"name":"AlreadyRegistered","type":"error"},{"inputs":[],"name":"ArraysDataDoNotMatch","type":"error"},{"inputs":[],"name":"BlockSubmittedToFastOrDataToOld","type":"error"},{"inputs":[],"name":"ContractNotReady","type":"error"},{"inputs":[],"name":"FCDOverflow","type":"error"},{"inputs":[],"name":"InvalidContractType","type":"error"},{"inputs":[],"name":"NoChangeToState","type":"error"},{"inputs":[],"name":"NotEnoughSignatures","type":"error"},{"inputs":[],"name":"NotSupported","type":"error"},{"inputs":[],"name":"OnlyOwnerOrRegistry","type":"error"},{"inputs":[],"name":"SignaturesOutOfOrder","type":"error"},{"inputs":[],"name":"UnregisterFirst","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"deprecator","type":"address"}],"name":"LogDeprecation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"staked","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"power","type":"uint256"}],"name":"LogMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint32","name":"timePadding","type":"uint32"}],"name":"LogPadding","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"blockId","type":"uint256"},{"indexed":true,"internalType":"address","name":"voter","type":"address"},{"indexed":false,"internalType":"uint256","name":"vote","type":"uint256"}],"name":"LogVoter","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"},{"inputs":[],"name":"ETH_PREFIX","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockId","type":"uint256"}],"name":"blocks","outputs":[{"components":[{"internalType":"bytes32","name":"root","type":"bytes32"},{"internalType":"uint32","name":"dataTimestamp","type":"uint32"}],"internalType":"struct BaseChain.Block","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blocksCountOffset","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_data","type":"bytes"},{"internalType":"uint256","name":"_offset","type":"uint256"},{"internalType":"uint256","name":"_items","type":"uint256"}],"name":"bytesToBytes32Array","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"contractRegistry","outputs":[{"internalType":"contract IRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deprecate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"fcds","outputs":[{"internalType":"uint224","name":"value","type":"uint224"},{"internalType":"uint32","name":"dataTimestamp","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getBlockIdAtTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_blockId","type":"uint32"}],"name":"getBlockRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_blockId","type":"uint32"}],"name":"getBlockTimestamp","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getConsensusData","outputs":[{"components":[{"internalType":"uint32","name":"blocksCountOffset","type":"uint32"},{"internalType":"uint32","name":"sequence","type":"uint32"},{"internalType":"uint32","name":"lastTimestamp","type":"uint32"},{"internalType":"uint32","name":"padding","type":"uint32"},{"internalType":"bool","name":"deprecated","type":"bool"}],"internalType":"struct BaseChain.ConsensusData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getCurrentIntValue","outputs":[{"internalType":"int256","name":"value","type":"int256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_key","type":"bytes32"}],"name":"getCurrentValue","outputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_keys","type":"bytes32[]"}],"name":"getCurrentValues","outputs":[{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"uint32[]","name":"timestamps","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLatestBlockId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLeaderAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getLeaderAddressAtTime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"getLeaderIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getName","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getNextLeaderAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStatus","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint32","name":"timePadding","type":"uint32"},{"internalType":"uint32","name":"lastDataTimestamp","type":"uint32"},{"internalType":"uint32","name":"lastId","type":"uint32"},{"internalType":"address","name":"nextLeader","type":"address"},{"internalType":"uint32","name":"nextBlockId","type":"uint32"},{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"string[]","name":"locations","type":"string[]"},{"internalType":"uint256","name":"staked","type":"uint256"},{"internalType":"uint16","name":"minSignatures","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"hashLeaf","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"isForeign","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"lastBlockId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_affidavit","type":"bytes32"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"recoverSigner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"register","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requiredSignatures","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"roots","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_padding","type":"uint16"}],"name":"setPadding","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakingBank","outputs":[{"internalType":"contract IStakingBank","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stakingBankContract","outputs":[{"internalType":"contract IStakingBank","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dataTimestamp","type":"uint32"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"bytes32[]","name":"_keys","type":"bytes32[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"uint8[]","name":"_v","type":"uint8[]"},{"internalType":"bytes32[]","name":"_r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_s","type":"bytes32[]"}],"name":"submit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tokenContract","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unregister","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"bytes32","name":"_root","type":"bytes32"},{"internalType":"bytes32","name":"_leaf","type":"bytes32"}],"name":"verifyProof","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockId","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"bytes","name":"_key","type":"bytes"},{"internalType":"bytes","name":"_value","type":"bytes"}],"name":"verifyProofForBlock","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_blockIds","type":"uint32[]"},{"internalType":"bytes","name":"_proofs","type":"bytes"},{"internalType":"uint256[]","name":"_proofItemsCounter","type":"uint256[]"},{"internalType":"bytes32[]","name":"_leaves","type":"bytes32[]"}],"name":"verifyProofs","outputs":[{"internalType":"bool[]","name":"results","type":"bool[]"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b506040516200586a3803806200586a83398181016040528101906200003891906200067f565b838383838383838383600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620000b3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000aa9062000752565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250505062000108620000fc620002ee60201b60201c565b620002f660201b60201c565b80151560a0811515815250508161ffff1660c08161ffff16815250506200013583620003ba60201b60201c565b60008473ffffffffffffffffffffffffffffffffffffffff166321f8a7216040518163ffffffff1660e01b815260040162000170906200079a565b602060405180830381865afa1580156200018e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001b49190620007e6565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200022b5760018442620001fb919062000847565b62000207919062000847565b600160000160086101000a81548163ffffffff021916908363ffffffff1602179055505b50505050508373ffffffffffffffffffffffffffffffffffffffff166346bcb49d6040518163ffffffff1660e01b81526004016200026990620008a8565b602060405180830381865afa15801562000287573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002ad9190620007e6565b73ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1681525050505050505050505062000963565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b620003ca620002ee60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620003f06200051b60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000449576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004409062000913565b60405180910390fd5b8063ffffffff166001600001600c9054906101000a900463ffffffff1663ffffffff1603620004a4576040517f96f56f6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600001600c6101000a81548163ffffffff021916908363ffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167f02ff77a0f68d11f7efb906f331b2dda82916de8ba9c37dda2a95817936a530ec8260405162000510919062000946565b60405180910390a250565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620005768262000549565b9050919050565b60006200058a8262000569565b9050919050565b6200059c816200057d565b8114620005a857600080fd5b50565b600081519050620005bc8162000591565b92915050565b600063ffffffff82169050919050565b620005dd81620005c2565b8114620005e957600080fd5b50565b600081519050620005fd81620005d2565b92915050565b600061ffff82169050919050565b6200061c8162000603565b81146200062857600080fd5b50565b6000815190506200063c8162000611565b92915050565b60008115159050919050565b620006598162000642565b81146200066557600080fd5b50565b60008151905062000679816200064e565b92915050565b600080600080608085870312156200069c576200069b62000544565b5b6000620006ac87828801620005ab565b9450506020620006bf87828801620005ec565b9350506040620006d2878288016200062b565b9250506060620006e58782880162000668565b91505092959194509250565b600082825260208201905092915050565b7f5f726567697374727920697320656d7074790000000000000000000000000000600082015250565b60006200073a601283620006f1565b9150620007478262000702565b602082019050919050565b600060208201905081810360008301526200076d816200072b565b9050919050565b7f436861696e000000000000000000000000000000000000000000000000000000815250565b6000602082019050620007b06000830162000774565b919050565b620007c08162000569565b8114620007cc57600080fd5b50565b600081519050620007e081620007b5565b92915050565b600060208284031215620007ff57620007fe62000544565b5b60006200080f84828501620007cf565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006200085482620005c2565b91506200086183620005c2565b92508282101562000877576200087662000818565b5b828203905092915050565b7f5374616b696e6742616e6b000000000000000000000000000000000000000000815250565b6000602082019050620008be6000830162000882565b919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620008fb602083620006f1565b91506200090882620008c3565b602082019050919050565b600060208201905081810360008301526200092e81620008ec565b9050919050565b6200094081620005c2565b82525050565b60006020820190506200095d600083018462000935565b92915050565b60805160a05160c05160e051614e72620009f860003960008181610f1c01528181611296015281816114c101526116f801526000818161142a015281816116d50152611c430152600061237f01526000818161089701528181610a8d01528181610b55015281816118a901528181611920015281816119bf01528181611d7b015281816121a101526122800152614e726000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c80638d06804311610151578063ca4d29d2116100c3578063e79a198f11610087578063e79a198f146107a0578063ed9975c3146107aa578063ef19f3e7146107c8578063f25b3f99146107f8578063f2fde38b14610828578063ffa1ad741461084457610269565b8063ca4d29d2146106d3578063cbb1b2c714610703578063d3d3ea0814610734578063d45167d014610752578063e76c0b571461078257610269565b8063adf1639d11610115578063adf1639d146105c4578063bef9f8a1146105f5578063bf66e3ba14610625578063c2a4250b14610655578063c2b40ae414610673578063c3369db8146106a357610269565b80638d0680431461052e5780638da5cb5b1461054c5780639f6119d71461056a578063a0bc937414610588578063abf410e5146105a657610269565b806340a9e5e3116101ea578063637180a8116101ae578063637180a81461047c5780636d046c3e1461049a578063715018a6146104b85780637353cbcb146104c257806377839fe6146104e0578063805d3432146104fe57610269565b806340a9e5e3146103ce578063485e055d146103ea5780634bc935d7146104065780634e69d5601461043657806355a373d61461045e57610269565b8063243b68f911610231578063243b68f91461030057806324c89a491461033057806326f3ab8b1461034e57806334ba34811461037f5780633bb8819d1461039d57610269565b80630f2acc3e1461026e5780630fcc0c281461029e57806317d7de7c146102a8578063199dadc5146102c65780631aa3a008146102f6575b600080fd5b61028860048036038101906102839190613087565b610862565b6040516102959190613118565b60405180910390f35b6102a6610895565b005b6102b0610a07565b6040516102bd9190613118565b60405180910390f35b6102e060048036038101906102db919061325d565b610a2f565b6040516102ed9190613333565b60405180910390f35b6102fe610a8b565b005b61031a6004803603810190610315919061334e565b610c99565b604051610327919061347b565b60405180910390f35b610338610d42565b6040516103459190613525565b60405180910390f35b610368600480360381019061036391906135a2565b610d7b565b60405161037692919061377b565b60405180910390f35b610387610f1a565b6040516103949190613831565b60405180910390f35b6103b760048036038101906103b2919061384c565b610f3e565b6040516103c59291906138a1565b60405180910390f35b6103e860048036038101906103e39190613904565b610fd3565b005b61040460048036038101906103ff9190613b1c565b610fe3565b005b610420600480360381019061041b9190613c4a565b6115b6565b60405161042d9190613333565b60405180910390f35b61043e6115ea565b6040516104559b9a99989796959493929190613ecd565b60405180910390f35b61046661188e565b6040516104739190613fae565b60405180910390f35b6104846119bb565b6040516104919190613831565b60405180910390f35b6104a2611a5a565b6040516104af9190613333565b60405180910390f35b6104c0611a63565b005b6104ca611aeb565b6040516104d79190613fc9565b60405180910390f35b6104e8611b2e565b6040516104f59190613fe4565b60405180910390f35b61051860048036038101906105139190613fff565b611b4b565b6040516105259190613fe4565b60405180910390f35b610536611c3f565b604051610543919061402c565b60405180910390f35b610554611c67565b6040516105619190614047565b60405180910390f35b610572611c90565b60405161057f9190614047565b60405180910390f35b610590611cac565b60405161059d91906140d9565b60405180910390f35b6105ae611d79565b6040516105bb9190614115565b60405180910390f35b6105de60048036038101906105d9919061384c565b611d9d565b6040516105ec929190614130565b60405180910390f35b61060f600480360381019061060a9190614159565b611e2a565b60405161061c9190613118565b60405180910390f35b61063f600480360381019061063a9190614249565b611e4d565b60405161064c91906143cf565b60405180910390f35b61065d611f89565b60405161066a9190613fc9565b60405180910390f35b61068d60048036038101906106889190613fff565b611fac565b60405161069a9190613118565b60405180910390f35b6106bd60048036038101906106b89190614159565b611fc4565b6040516106ca9190613fe4565b60405180910390f35b6106ed60048036038101906106e891906143f1565b611ff9565b6040516106fa9190613fc9565b60405180910390f35b61071d6004803603810190610718919061384c565b61202d565b60405161072b929190614468565b60405180910390f35b61073c612089565b6040516107499190613fe4565b60405180910390f35b61076c60048036038101906107679190614491565b6120a6565b6040516107799190614047565b60405180910390f35b61078a612163565b6040516107979190613fe4565b60405180910390f35b6107a861219f565b005b6107b2612520565b6040516107bf9190614047565b60405180910390f35b6107e260048036038101906107dd9190613fff565b612530565b6040516107ef9190614047565b60405180910390f35b610812600480360381019061080d9190613fff565b612564565b60405161081f9190614527565b60405180910390f35b610842600480360381019061083d919061456e565b6125a1565b005b61084c612698565b6040516108599190613fc9565b60405180910390f35b600082826040516020016108779291906145d7565b60405160208183030381529060405280519060200120905092915050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415801561092457506108f4611c67565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b1561095b576040517f0daa173600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160000160109054906101000a900460ff16156109a5576040517f764c143b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60018060000160106101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167fd4ae81319f0b4df100dcda9ce971671b97278c7a5ce6b37a8331a44700679fd460405160405180910390a2565b60007f436861696e000000000000000000000000000000000000000000000000000000905090565b6000610a8160026000878152602001908152602001600020548484604051602001610a5b9291906145d7565b604051602081830303815290604052805190602001208661269d9092919063ffffffff16565b9050949350505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614158015610b1a5750610aea611c67565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15610b51576040517f0daa173600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166321f8a7216040518163ffffffff1660e01b8152600401610baa90614621565b602060405180830381865afa158015610bc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610beb919061464f565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c52576040517f3a81d6fc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610c8c5750610c97565b610c95816126b4565b505b565b606060008267ffffffffffffffff811115610cb757610cb6612f5c565b5b604051908082528060200260200182016040528015610ce55781602001602082028036833780820191505090505b50905060005b83811015610d3657600080602087600185010102905080880151915081848481518110610d1b57610d1a61467c565b5b60200260200101818152505050508080600101915050610ceb565b50809150509392505050565b6040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a33320000000081525081565b6060808383905067ffffffffffffffff811115610d9b57610d9a612f5c565b5b604051908082528060200260200182016040528015610dc95781602001602082028036833780820191505090505b5090508383905067ffffffffffffffff811115610de957610de8612f5c565b5b604051908082528060200260200182016040528015610e175781602001602082028036833780820191505090505b50915060005b84849050811015610f1257600060036000878785818110610e4157610e4061467c565b5b90506020020135815260200190815260200160002090508060000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16848381518110610eb657610eb561467c565b5b60200260200101818152505080600001601c9054906101000a900463ffffffff16838381518110610eea57610ee961467c565b5b602002602001019063ffffffff16908163ffffffff1681525050818060010192505050610e1d565b509250929050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000806000600360008581526020019081526020016000209050610fab8160000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166129f6565b81600001601c9054906101000a900463ffffffff168063ffffffff1690509250925050915091565b610fe08161ffff16612a9e565b50565b610ff28763ffffffff16612be9565b60008787604051602001611007929190614702565b604051602081830303815290604052905060005b8651811015611217578581815181106110375761103661467c565b5b60200260200101518682815181106110525761105161467c565b5b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16146110af576040517f6980091000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405180604001604052808783815181106110cd576110cc61467c565b5b60200260200101517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681526020018a63ffffffff16815250600360008984815181106111195761111861467c565b5b6020026020010151815260200190815260200160002060008201518160000160006101000a8154817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff02191690837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff160217905550602082015181600001601c6101000a81548163ffffffff021916908363ffffffff160217905550905050818782815181106111c4576111c361467c565b5b60200260200101518783815181106111df576111de61467c565b5b60200260200101516040516020016111f99392919061474f565b6040516020818303038152906040529150808060010191505061101b565b506000806000838051906020012090506000805b8851811015611427576000611290848b848151811061124d5761124c61467c565b5b60200260200101518b85815181106112685761126761467c565b5b60200260200101518b86815181106112835761128261467c565b5b60200260200101516120a6565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231836040518263ffffffff1660e01b81526004016112ed9190614047565b602060405180830381865afa15801561130a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061132e919061479d565b90508173ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610611395576040517f9079f69b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b819350600081036113af5782806001019350505050611422565b86806113ba906147f9565b9750508173ffffffffffffffffffffffffffffffffffffffff168f63ffffffff167fbac7552ab5da8d0588709ddb75aceec28520646f54bca1cc5e6e104db61935ec8360405161140a9190613fc9565b60405180910390a38086019550828060010193505050505b61122b565b507f000000000000000000000000000000000000000000000000000000000000000061ffff16841015611486576040517fe246dc6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f5f11830295067c4bcc7d02d4e3b048cd7427be50a3aeb6afc9d3d559ee64bcfa8d7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561152a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061154e919061479d565b8660405161155e93929190614872565b60405180910390a28a600260008e63ffffffff168152602001908152602001600020819055508b600160000160086101000a81548163ffffffff021916908363ffffffff160217905550505050505050505050505050565b60008060001b83036115cb57600090506115e3565b6115e083838661269d9092919063ffffffff16565b90505b9392505050565b6000806000806000806060806060600080600060016040518060a00160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160089054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900460ff1615151515815250509050439b5080606001519a50806040015198508899507f000000000000000000000000000000000000000000000000000000000000000091507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611761573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611785919061479d565b925060008067ffffffffffffffff8111156117a3576117a2612f5c565b5b6040519080825280602002602001820160405280156117d15781602001602082028036833780820191505090505b5095508067ffffffffffffffff8111156117ee576117ed612f5c565b5b60405190808252806020026020018201604052801561181c5781602001602082028036833780820191505090505b5096508067ffffffffffffffff81111561183957611838612f5c565b5b60405190808252806020026020018201604052801561186c57816020015b60608152602001906001900390816118575790505b50945060009850600182606001518b010197505050909192939495969798999a565b60008073ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff160361191e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191590614906565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166346bcb49d6040518163ffffffff1660e01b81526004016119759061494c565b602060405180830381865afa158015611992573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b6919061464f565b905090565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166346bcb49d6040518163ffffffff1660e01b8152600401611a149061498b565b602060405180830381865afa158015611a31573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a55919061464f565b905090565b60006001905090565b611a6b612d69565b73ffffffffffffffffffffffffffffffffffffffff16611a89611c67565b73ffffffffffffffffffffffffffffffffffffffff1614611adf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ad6906149f0565b60405180910390fd5b611ae96000612d71565b565b6000600160000160009054906101000a900463ffffffff16600160000160049054906101000a900463ffffffff16611b239190614a10565b63ffffffff16905090565b6000600160000160009054906101000a900463ffffffff16905090565b60008060016040518060a00160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160089054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900460ff161515151581525050905082816060015182604001510163ffffffff161015611c315782915050611c3a565b80604001519150505b919050565b60007f0000000000000000000000000000000000000000000000000000000000000000905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000611ca7600142611ca29190614a44565b612530565b905090565b611cb4612ec1565b60016040518060a00160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160089054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900460ff161515151581525050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008060006003600085815260200190815260200160002090508060000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681600001601c9054906101000a900463ffffffff168063ffffffff1690509250925050915091565b6000600260008363ffffffff168152602001908152602001600020549050919050565b6060815167ffffffffffffffff811115611e6a57611e69612f5c565b5b604051908082528060200260200182016040528015611e985781602001602082028036833780820191505090505b5090506000805b8351811015611f7f57611f2e60026000898481518110611ec257611ec161467c565b5b602002602001015163ffffffff16815260200190815260200160002054858381518110611ef257611ef161467c565b5b6020026020010151611f1f89868a8781518110611f1257611f1161467c565b5b6020026020010151610c99565b61269d9092919063ffffffff16565b838281518110611f4157611f4061467c565b5b602002602001019015159081151581525050848181518110611f6657611f6561467c565b5b6020026020010151820191508080600101915050611e9f565b5050949350505050565b6000600160000160089054906101000a900463ffffffff1663ffffffff16905090565b60026020528060005260406000206000915090505481565b60008060001b600260008463ffffffff1681526020019081526020016000205414611fef5781611ff2565b60005b9050919050565b60006040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60036020528060005260406000206000915090508060000160009054906101000a90047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169080600001601c9054906101000a900463ffffffff16905082565b6000600160000160089054906101000a900463ffffffff16905090565b6000806040518060400160405280601c81526020017f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250866040516020016120f1929190614a9a565b6040516020818303038152906040528051906020012090506001818686866040516000815260200160405260405161212c9493929190614ad1565b6020604051602081039080840390855afa15801561214e573d6000803e3d6000fd5b50505060206040510351915050949350505050565b600080600160000160089054906101000a900463ffffffff1663ffffffff1603612190576000905061219c565b61219942611b4b565b90505b90565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415801561222e57506121fe611c67565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614155b15612265576040517f0daa173600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600160000160109054906101000a900460ff1661251e5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166321f8a7216040518163ffffffff1660e01b81526004016122d590614621565b602060405180830381865afa1580156122f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612316919061464f565b90503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361237d576040517ff8e0084400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006124bc573073ffffffffffffffffffffffffffffffffffffffff16636d046c3e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124119190614b42565b15158173ffffffffffffffffffffffffffffffffffffffff16636d046c3e6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561245e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124829190614b42565b1515146124bb576040517f07b72f5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b60018060000160106101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167fd4ae81319f0b4df100dcda9ce971671b97278c7a5ce6b37a8331a44700679fd460405160405180910390a2505b565b600061252b42612530565b905090565b60006040517fa038794000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61256c612f0a565b6040518060400160405280600260008581526020019081526020016000205481526020018363ffffffff168152509050919050565b6125a9612d69565b73ffffffffffffffffffffffffffffffffffffffff166125c7611c67565b73ffffffffffffffffffffffffffffffffffffffff161461261d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612614906149f0565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361268c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161268390614be1565b60405180910390fd5b61269581612d71565b50565b600281565b6000826126aa8584612e35565b1490509392505050565b6000808273ffffffffffffffffffffffffffffffffffffffff167fffa1ad74ba96b4c159a84d090433911c3991c54f629eb60d0c84aed3be5f067c6040516020016126ff9190614c3c565b60405160208183030381529060405260405161271b9190614c57565b600060405180830381855afa9150503d8060008114612756576040519150601f19603f3d011682016040523d82523d6000602084013e61275b565b606091505b509150915060008261276e576001612783565b81806020019051810190612782919061479d565b5b9050600181036129035760008473ffffffffffffffffffffffffffffffffffffffff1663d3d3ea086040518163ffffffff1660e01b8152600401602060405180830381865afa1580156127da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127fe9190614c83565b90508473ffffffffffffffffffffffffffffffffffffffff1663c3369db8826040518263ffffffff1660e01b81526004016128399190613fe4565b602060405180830381865afa158015612856573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061287a9190614c83565b600160000160086101000a81548163ffffffff021916908363ffffffff1602179055506002816128aa9190614cb0565b600160000160046101000a81548163ffffffff021916908363ffffffff1602179055506002816128da9190614cb0565b600160000160006101000a81548163ffffffff021916908363ffffffff160217905550506129f0565b60008473ffffffffffffffffffffffffffffffffffffffff1663a0bc93746040518163ffffffff1660e01b815260040160a060405180830381865afa158015612950573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129749190614d7b565b90508060200151600160000160046101000a81548163ffffffff021916908363ffffffff1602179055508060200151600160000160006101000a81548163ffffffff021916908363ffffffff1602179055508060400151600160000160086101000a81548163ffffffff021916908363ffffffff160217905550505b50505050565b60008060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90506002600182612a299190614da8565b612a339190614e0b565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16847bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1611612a885760008401915081601b0b92505050612a99565b600181850303915081601b0b925050505b919050565b612aa6612d69565b73ffffffffffffffffffffffffffffffffffffffff16612ac4611c67565b73ffffffffffffffffffffffffffffffffffffffff1614612b1a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b11906149f0565b60405180910390fd5b8063ffffffff166001600001600c9054906101000a900463ffffffff1663ffffffff1603612b74576040517f96f56f6a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600001600c6101000a81548163ffffffff021916908363ffffffff1602179055503373ffffffffffffffffffffffffffffffffffffffff167f02ff77a0f68d11f7efb906f331b2dda82916de8ba9c37dda2a95817936a530ec82604051612bde9190613fe4565b60405180910390a250565b600060016040518060a00160405290816000820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160049054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160089054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200160008201600c9054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016000820160109054906101000a900460ff16151515158152505090506000816040015163ffffffff1603612cf1576040517f96a96e1700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81816060015182604001510163ffffffff1610612d3a576040517ff886149e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001816020015101600160000160046101000a81548163ffffffff021916908363ffffffff1602179055505050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008082905060005b8451811015612e9f576000858281518110612e5c57612e5b61467c565b5b60200260200101519050808311612e7e57612e778382612eaa565b9250612e8b565b612e888184612eaa565b92505b508080612e97906147f9565b915050612e3e565b508091505092915050565b600082600052816020526040600020905092915050565b6040518060a00160405280600063ffffffff168152602001600063ffffffff168152602001600063ffffffff168152602001600063ffffffff1681526020016000151581525090565b604051806040016040528060008019168152602001600063ffffffff1681525090565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612f9482612f4b565b810181811067ffffffffffffffff82111715612fb357612fb2612f5c565b5b80604052505050565b6000612fc6612f2d565b9050612fd28282612f8b565b919050565b600067ffffffffffffffff821115612ff257612ff1612f5c565b5b612ffb82612f4b565b9050602081019050919050565b82818337600083830152505050565b600061302a61302584612fd7565b612fbc565b90508281526020810184848401111561304657613045612f46565b5b613051848285613008565b509392505050565b600082601f83011261306e5761306d612f41565b5b813561307e848260208601613017565b91505092915050565b6000806040838503121561309e5761309d612f37565b5b600083013567ffffffffffffffff8111156130bc576130bb612f3c565b5b6130c885828601613059565b925050602083013567ffffffffffffffff8111156130e9576130e8612f3c565b5b6130f585828601613059565b9150509250929050565b6000819050919050565b613112816130ff565b82525050565b600060208201905061312d6000830184613109565b92915050565b6000819050919050565b61314681613133565b811461315157600080fd5b50565b6000813590506131638161313d565b92915050565b600067ffffffffffffffff82111561318457613183612f5c565b5b602082029050602081019050919050565b600080fd5b6131a3816130ff565b81146131ae57600080fd5b50565b6000813590506131c08161319a565b92915050565b60006131d96131d484613169565b612fbc565b905080838252602082019050602084028301858111156131fc576131fb613195565b5b835b81811015613225578061321188826131b1565b8452602084019350506020810190506131fe565b5050509392505050565b600082601f83011261324457613243612f41565b5b81356132548482602086016131c6565b91505092915050565b6000806000806080858703121561327757613276612f37565b5b600061328587828801613154565b945050602085013567ffffffffffffffff8111156132a6576132a5612f3c565b5b6132b28782880161322f565b935050604085013567ffffffffffffffff8111156132d3576132d2612f3c565b5b6132df87828801613059565b925050606085013567ffffffffffffffff811115613300576132ff612f3c565b5b61330c87828801613059565b91505092959194509250565b60008115159050919050565b61332d81613318565b82525050565b60006020820190506133486000830184613324565b92915050565b60008060006060848603121561336757613366612f37565b5b600084013567ffffffffffffffff81111561338557613384612f3c565b5b61339186828701613059565b93505060206133a286828701613154565b92505060406133b386828701613154565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6133f2816130ff565b82525050565b600061340483836133e9565b60208301905092915050565b6000602082019050919050565b6000613428826133bd565b61343281856133c8565b935061343d836133d9565b8060005b8381101561346e57815161345588826133f8565b975061346083613410565b925050600181019050613441565b5085935050505092915050565b60006020820190508181036000830152613495818461341d565b905092915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156134d75780820151818401526020810190506134bc565b838111156134e6576000848401525b50505050565b60006134f78261349d565b61350181856134a8565b93506135118185602086016134b9565b61351a81612f4b565b840191505092915050565b6000602082019050818103600083015261353f81846134ec565b905092915050565b600080fd5b60008083601f84011261356257613561612f41565b5b8235905067ffffffffffffffff81111561357f5761357e613547565b5b60208301915083602082028301111561359b5761359a613195565b5b9250929050565b600080602083850312156135b9576135b8612f37565b5b600083013567ffffffffffffffff8111156135d7576135d6612f3c565b5b6135e38582860161354c565b92509250509250929050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61362481613133565b82525050565b6000613636838361361b565b60208301905092915050565b6000602082019050919050565b600061365a826135ef565b61366481856135fa565b935061366f8361360b565b8060005b838110156136a0578151613687888261362a565b975061369283613642565b925050600181019050613673565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600063ffffffff82169050919050565b6136f2816136d9565b82525050565b600061370483836136e9565b60208301905092915050565b6000602082019050919050565b6000613728826136ad565b61373281856136b8565b935061373d836136c9565b8060005b8381101561376e57815161375588826136f8565b975061376083613710565b925050600181019050613741565b5085935050505092915050565b60006040820190508181036000830152613795818561364f565b905081810360208301526137a9818461371d565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006137f76137f26137ed846137b2565b6137d2565b6137b2565b9050919050565b6000613809826137dc565b9050919050565b600061381b826137fe565b9050919050565b61382b81613810565b82525050565b60006020820190506138466000830184613822565b92915050565b60006020828403121561386257613861612f37565b5b6000613870848285016131b1565b91505092915050565b6000819050919050565b61388c81613879565b82525050565b61389b81613133565b82525050565b60006040820190506138b66000830185613883565b6138c36020830184613892565b9392505050565b600061ffff82169050919050565b6138e1816138ca565b81146138ec57600080fd5b50565b6000813590506138fe816138d8565b92915050565b60006020828403121561391a57613919612f37565b5b6000613928848285016138ef565b91505092915050565b61393a816136d9565b811461394557600080fd5b50565b60008135905061395781613931565b92915050565b600067ffffffffffffffff82111561397857613977612f5c565b5b602082029050602081019050919050565b600061399c6139978461395d565b612fbc565b905080838252602082019050602084028301858111156139bf576139be613195565b5b835b818110156139e857806139d48882613154565b8452602084019350506020810190506139c1565b5050509392505050565b600082601f830112613a0757613a06612f41565b5b8135613a17848260208601613989565b91505092915050565b600067ffffffffffffffff821115613a3b57613a3a612f5c565b5b602082029050602081019050919050565b600060ff82169050919050565b613a6281613a4c565b8114613a6d57600080fd5b50565b600081359050613a7f81613a59565b92915050565b6000613a98613a9384613a20565b612fbc565b90508083825260208201905060208402830185811115613abb57613aba613195565b5b835b81811015613ae45780613ad08882613a70565b845260208401935050602081019050613abd565b5050509392505050565b600082601f830112613b0357613b02612f41565b5b8135613b13848260208601613a85565b91505092915050565b600080600080600080600060e0888a031215613b3b57613b3a612f37565b5b6000613b498a828b01613948565b9750506020613b5a8a828b016131b1565b965050604088013567ffffffffffffffff811115613b7b57613b7a612f3c565b5b613b878a828b0161322f565b955050606088013567ffffffffffffffff811115613ba857613ba7612f3c565b5b613bb48a828b016139f2565b945050608088013567ffffffffffffffff811115613bd557613bd4612f3c565b5b613be18a828b01613aee565b93505060a088013567ffffffffffffffff811115613c0257613c01612f3c565b5b613c0e8a828b0161322f565b92505060c088013567ffffffffffffffff811115613c2f57613c2e612f3c565b5b613c3b8a828b0161322f565b91505092959891949750929550565b600080600060608486031215613c6357613c62612f37565b5b600084013567ffffffffffffffff811115613c8157613c80612f3c565b5b613c8d8682870161322f565b9350506020613c9e868287016131b1565b9250506040613caf868287016131b1565b9150509250925092565b613cc2816136d9565b82525050565b6000613cd3826137b2565b9050919050565b613ce381613cc8565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613d1e81613cc8565b82525050565b6000613d308383613d15565b60208301905092915050565b6000602082019050919050565b6000613d5482613ce9565b613d5e8185613cf4565b9350613d6983613d05565b8060005b83811015613d9a578151613d818882613d24565b9750613d8c83613d3c565b925050600181019050613d6d565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b6000613dfa82613dd3565b613e048185613dde565b9350613e148185602086016134b9565b613e1d81612f4b565b840191505092915050565b6000613e348383613def565b905092915050565b6000602082019050919050565b6000613e5482613da7565b613e5e8185613db2565b935083602082028501613e7085613dc3565b8060005b85811015613eac5784840389528151613e8d8582613e28565b9450613e9883613e3c565b925060208a01995050600181019050613e74565b50829750879550505050505092915050565b613ec7816138ca565b82525050565b600061016082019050613ee3600083018e613892565b613ef0602083018d613cb9565b613efd604083018c613cb9565b613f0a606083018b613cb9565b613f17608083018a613cda565b613f2460a0830189613cb9565b81810360c0830152613f368188613d49565b905081810360e0830152613f4a818761364f565b9050818103610100830152613f5f8186613e49565b9050613f6f610120830185613892565b613f7d610140830184613ebe565b9c9b505050505050505050505050565b6000613f98826137fe565b9050919050565b613fa881613f8d565b82525050565b6000602082019050613fc36000830184613f9f565b92915050565b6000602082019050613fde6000830184613892565b92915050565b6000602082019050613ff96000830184613cb9565b92915050565b60006020828403121561401557614014612f37565b5b600061402384828501613154565b91505092915050565b60006020820190506140416000830184613ebe565b92915050565b600060208201905061405c6000830184613cda565b92915050565b61406b81613318565b82525050565b60a08201600082015161408760008501826136e9565b50602082015161409a60208501826136e9565b5060408201516140ad60408501826136e9565b5060608201516140c060608501826136e9565b5060808201516140d36080850182614062565b50505050565b600060a0820190506140ee6000830184614071565b92915050565b60006140ff826137fe565b9050919050565b61410f816140f4565b82525050565b600060208201905061412a6000830184614106565b92915050565b60006040820190506141456000830185613892565b6141526020830184613892565b9392505050565b60006020828403121561416f5761416e612f37565b5b600061417d84828501613948565b91505092915050565b600067ffffffffffffffff8211156141a1576141a0612f5c565b5b602082029050602081019050919050565b60006141c56141c084614186565b612fbc565b905080838252602082019050602084028301858111156141e8576141e7613195565b5b835b8181101561421157806141fd8882613948565b8452602084019350506020810190506141ea565b5050509392505050565b600082601f8301126142305761422f612f41565b5b81356142408482602086016141b2565b91505092915050565b6000806000806080858703121561426357614262612f37565b5b600085013567ffffffffffffffff81111561428157614280612f3c565b5b61428d8782880161421b565b945050602085013567ffffffffffffffff8111156142ae576142ad612f3c565b5b6142ba87828801613059565b935050604085013567ffffffffffffffff8111156142db576142da612f3c565b5b6142e7878288016139f2565b925050606085013567ffffffffffffffff81111561430857614307612f3c565b5b6143148782880161322f565b91505092959194509250565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006143588383614062565b60208301905092915050565b6000602082019050919050565b600061437c82614320565b614386818561432b565b93506143918361433c565b8060005b838110156143c25781516143a9888261434c565b97506143b483614364565b925050600181019050614395565b5085935050505092915050565b600060208201905081810360008301526143e98184614371565b905092915050565b6000806040838503121561440857614407612f37565b5b600061441685828601613154565b925050602061442785828601613154565b9150509250929050565b60007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff82169050919050565b61446281614431565b82525050565b600060408201905061447d6000830185614459565b61448a6020830184613cb9565b9392505050565b600080600080608085870312156144ab576144aa612f37565b5b60006144b9878288016131b1565b94505060206144ca87828801613a70565b93505060406144db878288016131b1565b92505060606144ec878288016131b1565b91505092959194509250565b60408201600082015161450e60008501826133e9565b50602082015161452160208501826136e9565b50505050565b600060408201905061453c60008301846144f8565b92915050565b61454b81613cc8565b811461455657600080fd5b50565b60008135905061456881614542565b92915050565b60006020828403121561458457614583612f37565b5b600061459284828501614559565b91505092915050565b600081905092915050565b60006145b18261349d565b6145bb818561459b565b93506145cb8185602086016134b9565b80840191505092915050565b60006145e382856145a6565b91506145ef82846145a6565b91508190509392505050565b7f436861696e000000000000000000000000000000000000000000000000000000815250565b6000602082019050614635600083016145fb565b919050565b60008151905061464981614542565b92915050565b60006020828403121561466557614664612f37565b5b60006146738482850161463a565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008160e01b9050919050565b60006146c3826146ab565b9050919050565b6146db6146d6826136d9565b6146b8565b82525050565b6000819050919050565b6146fc6146f7826130ff565b6146e1565b82525050565b600061470e82856146ca565b60048201915061471e82846146eb565b6020820191508190509392505050565b6000819050919050565b61474961474482613133565b61472e565b82525050565b600061475b82866145a6565b915061476782856146eb565b6020820191506147778284614738565b602082019150819050949350505050565b6000815190506147978161313d565b92915050565b6000602082840312156147b3576147b2612f37565b5b60006147c184828501614788565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061480482613133565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614836576148356147ca565b5b600182019050919050565b600061485c614857614852846136d9565b6137d2565b613133565b9050919050565b61486c81614841565b82525050565b60006060820190506148876000830186614863565b6148946020830185613892565b6148a16040830184613892565b949350505050565b600082825260208201905092915050565b7f5f726567697374727920697320656d7074790000000000000000000000000000600082015250565b60006148f06012836148a9565b91506148fb826148ba565b602082019050919050565b6000602082019050818103600083015261491f816148e3565b9050919050565b7f554d420000000000000000000000000000000000000000000000000000000000815250565b600060208201905061496060008301614926565b919050565b7f5374616b696e6742616e6b000000000000000000000000000000000000000000815250565b600060208201905061499f60008301614965565b919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006149da6020836148a9565b91506149e5826149a4565b602082019050919050565b60006020820190508181036000830152614a09816149cd565b9050919050565b6000614a1b826136d9565b9150614a26836136d9565b925082821015614a3957614a386147ca565b5b828203905092915050565b6000614a4f82613133565b9150614a5a83613133565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614a8f57614a8e6147ca565b5b828201905092915050565b6000614aa682856145a6565b9150614ab282846146eb565b6020820191508190509392505050565b614acb81613a4c565b82525050565b6000608082019050614ae66000830187613109565b614af36020830186614ac2565b614b006040830185613109565b614b0d6060830184613109565b95945050505050565b614b1f81613318565b8114614b2a57600080fd5b50565b600081519050614b3c81614b16565b92915050565b600060208284031215614b5857614b57612f37565b5b6000614b6684828501614b2d565b91505092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614bcb6026836148a9565b9150614bd682614b6f565b604082019050919050565b60006020820190508181036000830152614bfa81614bbe565b9050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b614c3681614c01565b82525050565b6000602082019050614c516000830184614c2d565b92915050565b6000614c6382846145a6565b915081905092915050565b600081519050614c7d81613931565b92915050565b600060208284031215614c9957614c98612f37565b5b6000614ca784828501614c6e565b91505092915050565b6000614cbb826136d9565b9150614cc6836136d9565b92508263ffffffff03821115614cdf57614cde6147ca565b5b828201905092915050565b600080fd5b600060a08284031215614d0557614d04614cea565b5b614d0f60a0612fbc565b90506000614d1f84828501614c6e565b6000830152506020614d3384828501614c6e565b6020830152506040614d4784828501614c6e565b6040830152506060614d5b84828501614c6e565b6060830152506080614d6f84828501614b2d565b60808301525092915050565b600060a08284031215614d9157614d90612f37565b5b6000614d9f84828501614cef565b91505092915050565b6000614db382614431565b9150614dbe83614431565b925082821015614dd157614dd06147ca565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614e1682614431565b9150614e2183614431565b925082614e3157614e30614ddc565b5b82820490509291505056fea264697066735822122065b2747aa4bc97adbc2040a13531d80d4ff97afc9eb19e88b8e8d069bf467d9164736f6c634300080d0033000000000000000000000000da9a63d77406faa09d265413f4e128b54b5057e0000000000000000000000000000000000000000000000000000000000000070800000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000da9a63d77406faa09d265413f4e128b54b5057e0000000000000000000000000000000000000000000000000000000000000070800000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _contractRegistry (address): 0xda9a63d77406faa09d265413f4e128b54b5057e0
Arg [1] : _padding (uint32): 1800
Arg [2] : _requiredSignatures (uint16): 6
Arg [3] : _allowForMixedType (bool): False
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000da9a63d77406faa09d265413f4e128b54b5057e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000708
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.