false
false
0

Contract Address Details

0x11aB70d78f1Dd2c3F967180d8A64858Db03A0aBa

Contract Name
BlockManager
Creator
0xd73462–49788f at 0x32f220–484c9c
Balance
0
Tokens
Fetching tokens...
Transactions
641,660 Transactions
Transfers
0 Transfers
Gas Used
211,960,245,757
Last Balance Update
3545040
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
BlockManager




Optimization enabled
true
Compiler version
v0.8.4+commit.c7e474f2




Optimization runs
200
Verified at
2022-08-26T14:08:35.125634Z

contracts/Core/BlockManager.sol

Sol2uml
new
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "./interface/IBlockManager.sol";
import "./interface/IStakeManager.sol";
import "./interface/IRewardManager.sol";
import "./interface/IVoteManager.sol";
import "./interface/ICollectionManager.sol";
import "../randomNumber/IRandomNoProvider.sol";
import "./storage/BlockStorage.sol";
import "./parameters/child/BlockManagerParams.sol";
import "./StateManager.sol";
import "../lib/Random.sol";
import "../Initializable.sol";

/** @title BlockManager
 * @notice BlockManager manages the proposal, confirmation and dispute of blocks
 */

contract BlockManager is Initializable, BlockStorage, StateManager, BlockManagerParams, IBlockManager {
    IStakeManager public stakeManager;
    IRewardManager public rewardManager;
    IVoteManager public voteManager;
    ICollectionManager public collectionManager;
    IRandomNoProvider public randomNoProvider;

    /**
     * @dev Emitted when a block is confirmed
     * @param epoch epoch when the block was confirmed
     * @param stakerId id of the staker that confirmed the block
     * @param ids of the proposed block
     * @param medians of the confirmed block
     * @param timestamp time when the block was confirmed
     */
    event BlockConfirmed(uint32 epoch, uint32 indexed stakerId, uint16[] ids, uint256 timestamp, uint256[] medians);

    /**
     * @dev Emitted when a staker claims block reward
     * @param epoch epoch when the block reward was claimed
     * @param stakerId id of the staker that claimed the block reward
     * @param timestamp time when the block reward was claimed
     */
    event ClaimBlockReward(uint32 epoch, uint32 indexed stakerId, uint256 timestamp);

    /**
     * @dev Emitted when a block is proposed
     * @param epoch epoch when the block was proposed
     * @param stakerId id of the staker that proposed the block
     * @param ids of the proposed block
     * @param medians of the proposed block
     * @param iteration staker's iteration
     * @param biggestStakerId id of the staker that has the highest stake amongst the stakers that revealed
     * @param timestamp time when the block was proposed
     */
    event Proposed(
        uint32 epoch,
        uint32 indexed stakerId,
        uint32 biggestStakerId,
        uint16[] ids,
        uint256 iteration,
        uint256 timestamp,
        uint256[] medians
    );

    /**
     * @dev Emitted when the staker calls giveSorted
     * @param epoch epoch in which the dispute was setup and raised
     * @param leafId index of the collection that is to be disputed
     * @param sortedValues values reported by staker for a collection in ascending order
     */
    event GiveSorted(uint32 epoch, uint16 indexed leafId, uint256[] sortedValues);

    /**
     * @dev Emitted when the disputer raise dispute for biggestStakeProposed
     * @param epoch epoch in which the dispute was raised
     * @param blockIndex index of the block that is to be disputed
     * @param correctBiggestStakerId the correct biggest staker id
     * @param disputer address that raised the dispute
     */
    event DisputeBiggestStakeProposed(uint32 epoch, uint8 blockIndex, uint32 indexed correctBiggestStakerId, address indexed disputer);

    /**
     * @dev Emitted when the disputer raise dispute for collection id that should be absent
     * @param epoch epoch in which the dispute was raised
     * @param blockIndex index of the block that is to be disputed
     * @param id collection id
     * @param postionOfCollectionInBlock position of collection id to be disputed inside ids proposed by block
     * @param disputer address that raised the dispute
     */
    event DisputeCollectionIdShouldBeAbsent(
        uint32 epoch,
        uint8 blockIndex,
        uint32 indexed id,
        uint256 postionOfCollectionInBlock,
        address indexed disputer
    );

    /**
     * @dev Emitted when the disputer raise dispute for collection id that should be present
     * @param epoch epoch in which the dispute was raised
     * @param blockIndex index of the block that is to be disputed
     * @param id collection id that should be present
     * @param disputer address that raised the dispute
     */
    event DisputeCollectionIdShouldBePresent(uint32 epoch, uint8 blockIndex, uint32 indexed id, address indexed disputer);

    /**
     * @dev Emitted when the disputer raise dispute for the ids passed are not sorted in ascend order, or there is duplication
     * @param epoch epoch in which the dispute was raised
     * @param blockIndex index of the block that is to be disputed
     * @param index0 lower
     * @param index1 upper
     * @param disputer address that raised the dispute
     */
    event DisputeOnOrderOfIds(uint32 epoch, uint8 blockIndex, uint256 index0, uint256 index1, address indexed disputer);

    /**
     * @dev Emitted when the disputer calls finalizeDispute
     * @param epoch epoch in which the dispute was raised
     * @param blockIndex index of the block that is to be disputed
     * @param postionOfCollectionInBlock position of collection id to be disputed inside ids proposed by block
     * @param disputer address that raised the dispute
     */
    event FinalizeDispute(uint32 epoch, uint8 blockIndex, uint256 postionOfCollectionInBlock, address indexed disputer);

    /**
     * @param stakeManagerAddress The address of the StakeManager contract
     * @param rewardManagerAddress The address of the RewardManager contract
     * @param voteManagerAddress The address of the VoteManager contract
     * @param collectionManagerAddress The address of the CollectionManager contract
     * @param randomNoManagerAddress The address of the RandomNoManager contract
     */
    function initialize(
        address stakeManagerAddress,
        address rewardManagerAddress,
        address voteManagerAddress,
        address collectionManagerAddress,
        address randomNoManagerAddress
    ) external initializer onlyRole(DEFAULT_ADMIN_ROLE) {
        stakeManager = IStakeManager(stakeManagerAddress);
        rewardManager = IRewardManager(rewardManagerAddress);
        voteManager = IVoteManager(voteManagerAddress);
        collectionManager = ICollectionManager(collectionManagerAddress);
        randomNoProvider = IRandomNoProvider(randomNoManagerAddress);
    }

    /**
     * @notice elected proposer proposes block.
     * we use a probabilistic method to elect stakers weighted by stake
     * protocol works like this.
     * to find the iteration of a staker, a bias coin is tossed such that
     * bias = hisStake/biggestStake revealed. if its heads, he can propose block
     * end of iteration. try next iteration
     * stakers elected in higher iterations can also propose hoping that
     * stakers with lower iteration do not propose for some reason
     * @dev The IDs being passed here, are only used for disputeForNonAssignedCollection
     * for delegator, we have seprate registry
     * If user passes invalid ids, disputeForProposedCollectionIds can happen
     * @param epoch in which the block was proposed
     * @param ids ids of the proposed block
     * @param medians medians of the proposed block
     * @param iteration number of times a biased coin was thrown to get a head
     * @param biggestStakerId id of the staker that has the biggest stake amongst the stakers that have revealed
     */
    function propose(
        uint32 epoch,
        uint16[] memory ids,
        uint256[] memory medians,
        uint256 iteration,
        uint32 biggestStakerId
    ) external initialized checkEpochAndState(State.Propose, epoch, buffer) {
        uint32 proposerId = stakeManager.getStakerId(msg.sender);
        //staker can just skip commit/reveal and only propose every epoch to avoid penalty.
        //following line is to prevent that
        require(voteManager.getEpochLastRevealed(proposerId) == epoch, "Cannot propose without revealing");
        require(_isElectedProposer(iteration, biggestStakerId, proposerId, epoch), "not elected");
        require(stakeManager.getStake(proposerId) >= minStake, "stake below minimum stake");
        require(epochLastProposed[proposerId] != epoch, "Already proposed");
        require(ids.length == medians.length, "Invalid block proposed");

        uint256 biggestStake = voteManager.getStakeSnapshot(epoch, biggestStakerId);
        if (sortedProposedBlockIds[epoch].length == 0) numProposedBlocks = 0;
        proposedBlocks[epoch][numProposedBlocks] = Structs.Block(true, proposerId, ids, iteration, biggestStake, medians);
        bool isAdded = _insertAppropriately(epoch, numProposedBlocks, iteration, biggestStake);
        epochLastProposed[proposerId] = epoch;
        if (isAdded) {
            numProposedBlocks = numProposedBlocks + 1;
        }
        emit Proposed(epoch, proposerId, biggestStakerId, ids, iteration, block.timestamp, medians);
    }

    /**
     * @notice if someone feels that median result of a collection in a block is not in accordance to the protocol,
     * giveSorted() needs to be called to setup the dispute where in, the correct median will be calculated based on the votes
     * reported by stakers
     * @param epoch in which the dispute was setup and raised
     * @param leafId index of the collection that is to be disputed
     * @param sortedValues values reported by staker for a collection in ascending order
     */
    function giveSorted(
        uint32 epoch,
        uint16 leafId,
        uint256[] memory sortedValues
    ) external initialized checkEpochAndState(State.Dispute, epoch, buffer) {
        require(leafId <= (collectionManager.getNumActiveCollections() - 1), "Invalid leafId");
        uint256 medianWeight = voteManager.getTotalInfluenceRevealed(epoch, leafId) / 2;
        uint256 accWeight = disputes[epoch][msg.sender].accWeight;
        uint256 lastVisitedValue = disputes[epoch][msg.sender].lastVisitedValue;

        if (disputes[epoch][msg.sender].accWeight == 0) {
            disputes[epoch][msg.sender].leafId = leafId;
        } else {
            require(disputes[epoch][msg.sender].leafId == leafId, "leafId mismatch");
            // require(disputes[epoch][msg.sender].median == 0, "median already found");
        }
        for (uint32 i = 0; i < sortedValues.length; i++) {
            require(sortedValues[i] > lastVisitedValue, "sortedValue <= LVV "); // LVV : Last Visited Value
            lastVisitedValue = sortedValues[i];

            // reason to ignore : has to be done, as each vote will have diff weight
            // slither-disable-next-line calls-loop
            uint256 weight = voteManager.getVoteWeight(epoch, leafId, sortedValues[i]);
            accWeight = accWeight + weight;
            if (disputes[epoch][msg.sender].median == 0 && accWeight > medianWeight) {
                disputes[epoch][msg.sender].median = sortedValues[i];
            }
        }
        disputes[epoch][msg.sender].lastVisitedValue = lastVisitedValue;
        disputes[epoch][msg.sender].accWeight = accWeight;
        emit GiveSorted(epoch, leafId, sortedValues);
    }

    /**
     * @notice if any mistake made during giveSorted, resetDispute will reset their dispute calculations
     * and they can start again
     * @param epoch in which the dispute was setup and raised
     */
    function resetDispute(uint32 epoch) external initialized checkEpochAndState(State.Dispute, epoch, buffer) {
        disputes[epoch][msg.sender] = Structs.Dispute(0, 0, 0, 0);
    }

    /**
     * @notice claimBlockReward() is to be called by the selected staker whose proposed block has the lowest iteration
     * and is valid. This will confirm the block and rewards the selected staker with the block reward
     */
    function claimBlockReward() external initialized checkState(State.Confirm, buffer) {
        uint32 epoch = _getEpoch();
        uint32 stakerId = stakeManager.getStakerId(msg.sender);
        require(stakerId > 0, "Structs.Staker does not exist");
        // slither-disable-next-line timestamp
        require(blocks[epoch].proposerId == 0, "Block already confirmed");
        // proposerId, epoch, timestamp

        if (sortedProposedBlockIds[epoch].length != 0 && blockIndexToBeConfirmed != -1) {
            uint32 proposerId = proposedBlocks[epoch][sortedProposedBlockIds[epoch][uint8(blockIndexToBeConfirmed)]].proposerId;
            require(proposerId == stakerId, "Block Proposer mismatches");
            emit ClaimBlockReward(epoch, stakerId, block.timestamp);
            _confirmBlock(epoch, proposerId);
        }
        uint32 updateRegistryEpoch = collectionManager.getUpdateRegistryEpoch();
        // slither-disable-next-line incorrect-equality, timestamp
        if (updateRegistryEpoch <= epoch) {
            collectionManager.updateDelayedRegistry();
        }
    }

    /// @inheritdoc IBlockManager
    function confirmPreviousEpochBlock(uint32 stakerId) external override initialized onlyRole(BLOCK_CONFIRMER_ROLE) {
        uint32 epoch = _getEpoch();

        if (sortedProposedBlockIds[epoch - 1].length != 0 && blockIndexToBeConfirmed != -1) {
            _confirmBlock(epoch - 1, stakerId);
        }
        uint32 updateRegistryEpoch = collectionManager.getUpdateRegistryEpoch();
        // slither-disable-next-line incorrect-equality,timestamp
        if (updateRegistryEpoch <= epoch - 1) {
            collectionManager.updateDelayedRegistry();
        }
    }

    /**
     * @notice a dispute can be raised on the block if the block proposed has the incorrect biggest Stake.
     * If the dispute is passed and executed, the stake of the staker who proposed such a block will be slashed.
     * The address that raised the dispute will receive a bounty on the staker's stake depending on SlashNums
     * @param epoch in which this dispute was raised
     * @param blockIndex index of the block that is to be disputed
     * @param correctBiggestStakerId the correct biggest staker id
     */
    function disputeBiggestStakeProposed(
        uint32 epoch,
        uint8 blockIndex,
        uint32 correctBiggestStakerId
    ) external initialized checkEpochAndState(State.Dispute, epoch, buffer) {
        uint32 blockId = sortedProposedBlockIds[epoch][blockIndex];
        require(proposedBlocks[epoch][blockId].valid, "Block already has been disputed");
        uint256 correctBiggestStake = voteManager.getStakeSnapshot(epoch, correctBiggestStakerId);
        require(correctBiggestStake > proposedBlocks[epoch][blockId].biggestStake, "Invalid dispute : Stake");
        emit DisputeBiggestStakeProposed(epoch, blockIndex, correctBiggestStakerId, msg.sender);
        _executeDispute(epoch, blockIndex, blockId);
    }

    /**
     * @notice Dispute to prove that id should be absent, when its present in a proposed block.
     * @param epoch in which the dispute was setup
     * @param blockIndex index of the block that is to be disputed
     * @param id collection id
     * @param postionOfCollectionInBlock position of collection id to be disputed inside ids proposed by block
     */
    function disputeCollectionIdShouldBeAbsent(
        uint32 epoch,
        uint8 blockIndex,
        uint16 id,
        uint256 postionOfCollectionInBlock
    ) external initialized checkEpochAndState(State.Dispute, epoch, buffer) {
        uint32 blockId = sortedProposedBlockIds[epoch][blockIndex];
        require(proposedBlocks[epoch][blockId].valid, "Block already has been disputed");
        // Step 1 : If its active collection, total influence revealed should be zero
        if (collectionManager.getCollectionStatus(id)) {
            // Get leafId from collectionId, as voting is done w.r.t leafIds
            uint16 leafId = collectionManager.getLeafIdOfCollection(id);
            uint256 totalInfluenceRevealed = voteManager.getTotalInfluenceRevealed(epoch, leafId);
            require(totalInfluenceRevealed == 0, "Dispute: ID should be present");
        }
        // Step 2: Prove that given id is indeed present in block
        require(proposedBlocks[epoch][blockId].ids[postionOfCollectionInBlock] == id, "Dispute: ID absent only");
        emit DisputeCollectionIdShouldBeAbsent(epoch, blockIndex, id, postionOfCollectionInBlock, msg.sender);
        _executeDispute(epoch, blockIndex, blockId);
    }

    /**
     * @notice Dispute to prove that id should be present, when its not in a proposed block.
     * @param epoch in which the dispute was setup
     * @param blockIndex index of the block that is to be disputed
     * @param id collection id
     */
    function disputeCollectionIdShouldBePresent(
        uint32 epoch,
        uint8 blockIndex,
        uint16 id
    ) external initialized checkEpochAndState(State.Dispute, epoch, buffer) {
        uint32 blockId = sortedProposedBlockIds[epoch][blockIndex];
        require(proposedBlocks[epoch][blockId].valid, "Block already has been disputed");
        // Get leafId from collectionId, as voting is done w.r.t leafIds
        uint16 leafId = collectionManager.getLeafIdOfCollection(id);
        uint256 totalInfluenceRevealed = voteManager.getTotalInfluenceRevealed(epoch, leafId);

        require(totalInfluenceRevealed != 0, "Dispute: ID should be absent");

        Structs.Block memory _block = proposedBlocks[epoch][blockId];
        bool toDispute = true;

        if (_block.ids.length != 0) {
            // normal search
            // for (uint256 i = 0; i < _block.ids.length; i++)
            //         if (_block.ids[i] == id) {
            //             toDispute = false;
            //             break;
            //         }

            // binary search
            // impl taken and modified from
            // https://github.com/compound-finance/compound-protocol/blob/4a8648ec0364d24c4ecfc7d6cae254f55030d65f/contracts/Governance/Comp.sol#L207
            uint256 lower = 0;
            uint256 upper = _block.ids.length - 1;

            while (upper > lower) {
                uint256 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
                uint16 _id = _block.ids[center];
                if (_id == id) {
                    toDispute = false;
                    break;
                } else if (_id < id) {
                    lower = center;
                } else {
                    upper = center - 1;
                }
            }
            if (_block.ids[lower] == id) toDispute = false;
        }

        require(toDispute, "Dispute: ID present only");
        emit DisputeCollectionIdShouldBePresent(epoch, blockIndex, id, msg.sender);
        _executeDispute(epoch, blockIndex, blockId);
    }

    /**
     * @notice Dispute to prove the ids passed or not sorted in ascend order, or there is duplication
     * @param epoch in which the dispute was setup
     * @param blockIndex index of the block that is to be disputed
     * @param index0 lower
     * @param index1 upper
     *  Valid Block :
     *  If index0 < index1 &&
     *  value0 < value1
     */
    function disputeOnOrderOfIds(
        uint32 epoch,
        uint8 blockIndex,
        uint256 index0,
        uint256 index1
    ) external initialized checkEpochAndState(State.Dispute, epoch, buffer) {
        uint32 blockId = sortedProposedBlockIds[epoch][blockIndex];
        require(proposedBlocks[epoch][blockId].valid, "Block already has been disputed");
        require(index0 < index1, "index1 not greater than index0 0");
        require(proposedBlocks[epoch][blockId].ids[index0] >= proposedBlocks[epoch][blockId].ids[index1], "ID at i0 not gt than of i1");
        emit DisputeOnOrderOfIds(epoch, blockIndex, index0, index1, msg.sender);
        _executeDispute(epoch, blockIndex, blockId);
    }

    /**
     * @notice dispute on median result of a collection in a particular block is finalized after giveSorted was
     * called by the address who setup the dispute. If the dispute is passed and executed, the stake of the staker who
     * proposed such a block will be slashed. The address that raised the dispute will receive a bounty on the
     * staker's stake depending on SlashNums
     * @param epoch in which the dispute was setup
     * @param blockIndex index of the block that is to be disputed
     * @param postionOfCollectionInBlock position of collection id to be disputed inside ids proposed by block
     */
    function finalizeDispute(
        uint32 epoch,
        uint8 blockIndex,
        uint256 postionOfCollectionInBlock
    ) external initialized checkEpochAndState(State.Dispute, epoch, buffer) {
        require(
            disputes[epoch][msg.sender].accWeight == voteManager.getTotalInfluenceRevealed(epoch, disputes[epoch][msg.sender].leafId),
            "TIR is wrong"
        ); // TIR : total influence revealed
        require(disputes[epoch][msg.sender].accWeight != 0, "Invalid dispute");
        // Would revert if no block is proposed, or the asset specifed was not revealed
        uint32 blockId = sortedProposedBlockIds[epoch][blockIndex];
        require(proposedBlocks[epoch][blockId].valid, "Block already has been disputed");
        uint16 leafId = disputes[epoch][msg.sender].leafId;
        // Get collection id from leafId, as propose happens w.r.t to ids
        uint16 id = collectionManager.getCollectionIdFromLeafId(leafId);

        Structs.Block memory _block = proposedBlocks[epoch][blockId];
        require(_block.ids[postionOfCollectionInBlock] == id, "Wrong Coll Index passed");
        uint256 proposedValue = proposedBlocks[epoch][blockId].medians[postionOfCollectionInBlock];

        require(proposedValue != disputes[epoch][msg.sender].median, "Block proposed with same medians");
        emit FinalizeDispute(epoch, blockIndex, postionOfCollectionInBlock, msg.sender);
        _executeDispute(epoch, blockIndex, blockId);
    }

    /// @inheritdoc IBlockManager
    function getBlock(uint32 epoch) external view override returns (Structs.Block memory _block) {
        return (blocks[epoch]);
    }

    /**
     * @notice return the struct of the proposed block
     * @param epoch in which this block was proposed
     * @param proposedBlock id of the proposed block
     * @return _block : struct of the proposed block
     */
    function getProposedBlock(uint32 epoch, uint32 proposedBlock) external view returns (Structs.Block memory _block) {
        _block = proposedBlocks[epoch][proposedBlock];
        return (_block);
    }

    /**
     * @notice returns number of the block proposed in a particular epoch
     * @param epoch in which blocks were proposed
     * @return number of the block proposed
     */
    function getNumProposedBlocks(uint32 epoch) external view returns (uint8) {
        return (uint8(sortedProposedBlockIds[epoch].length));
    }

    /// @inheritdoc IBlockManager
    function isBlockConfirmed(uint32 epoch) external view override returns (bool) {
        return (blocks[epoch].proposerId != 0);
    }

    /// @inheritdoc IBlockManager
    function getLatestResults(uint16 id) external view override returns (uint256) {
        return latestResults[id];
    }

    /**
     * @notice an internal function in which the block is confirmed.
     * @dev The staker who confirms the block receives the block reward, creates the salt for the next epoch and stores
     * it in the voteManager and provides this salt as secret to the random Manager to generate random number
     * @param epoch in which the block is being confirmed
     * @param stakerId id of the staker that is confirming the block
     */
    function _confirmBlock(uint32 epoch, uint32 stakerId) internal {
        uint32 blockId = sortedProposedBlockIds[epoch][uint8(blockIndexToBeConfirmed)];
        blocks[epoch] = proposedBlocks[epoch][blockId];
        bytes32 salt = keccak256(abi.encodePacked(epoch, blocks[epoch].medians)); // not iteration as it can be manipulated

        Structs.Block memory _block = blocks[epoch];
        for (uint256 i = 0; i < _block.ids.length; i++) {
            latestResults[_block.ids[i]] = _block.medians[i];
        }

        emit BlockConfirmed(epoch, _block.proposerId, _block.ids, block.timestamp, _block.medians);

        voteManager.storeSalt(salt);
        rewardManager.giveBlockReward(stakerId, epoch);
        randomNoProvider.provideSecret(epoch, salt);
    }

    /**
     * @dev inserts the block in the approporiate place based the iteration of each block proposed. the block
     * with the lowest iteration is given a higher priority to a lower value
     * @param epoch in which the block was proposed
     * @param blockId id of the proposed block
     * @param iteration number of tosses of a biased coin required for a head
     * @param biggestStake biggest Stake that was revealed
     * @return isAdded : whether the block was added to the array
     */
    function _insertAppropriately(
        uint32 epoch,
        uint32 blockId,
        uint256 iteration,
        uint256 biggestStake
    ) internal returns (bool isAdded) {
        uint8 sortedProposedBlockslength = uint8(sortedProposedBlockIds[epoch].length);

        if (sortedProposedBlockslength == 0) {
            sortedProposedBlockIds[epoch].push(0);
            blockIndexToBeConfirmed = 0;
            return true;
        }

        if (proposedBlocks[epoch][sortedProposedBlockIds[epoch][0]].biggestStake > biggestStake) {
            return false;
        }

        if (proposedBlocks[epoch][sortedProposedBlockIds[epoch][0]].biggestStake < biggestStake) {
            for (uint8 i = 0; i < sortedProposedBlockslength; i++) {
                sortedProposedBlockIds[epoch].pop();
            }
            sortedProposedBlockIds[epoch].push(blockId);
            return true;
        }

        for (uint8 i = 0; i < sortedProposedBlockslength; i++) {
            // Push and Shift
            if (proposedBlocks[epoch][sortedProposedBlockIds[epoch][i]].iteration > iteration) {
                sortedProposedBlockIds[epoch].push(blockId);

                sortedProposedBlockslength = sortedProposedBlockslength + 1;

                for (uint256 j = sortedProposedBlockslength - 1; j > i; j--) {
                    sortedProposedBlockIds[epoch][j] = sortedProposedBlockIds[epoch][j - 1];
                }

                sortedProposedBlockIds[epoch][i] = blockId;

                if (sortedProposedBlockIds[epoch].length > maxAltBlocks) {
                    sortedProposedBlockIds[epoch].pop();
                }

                return true;
            }
        }
        // Worst Iteration and for all other blocks, influence was >=
        if (sortedProposedBlockIds[epoch].length < maxAltBlocks) {
            sortedProposedBlockIds[epoch].push(blockId);
            return true;
        }
    }

    /**
     * @dev internal function executes dispute if a dispute has been passed
     * @param epoch in which the dispute was raised and passed
     * @param blockIndex index of the block that is disputed
     * @param blockId id of the block being disputed
     */
    function _executeDispute(
        uint32 epoch,
        uint8 blockIndex,
        uint32 blockId
    ) internal {
        proposedBlocks[epoch][blockId].valid = false;

        uint8 sortedProposedBlocksLength = uint8(sortedProposedBlockIds[epoch].length);
        if (uint8(blockIndexToBeConfirmed) == blockIndex) {
            // If the chosen one only is the culprit one, find successor
            // O(maxAltBlocks)

            blockIndexToBeConfirmed = -1;
            for (uint8 i = blockIndex + 1; i < sortedProposedBlocksLength; i++) {
                uint32 _blockId = sortedProposedBlockIds[epoch][i];
                if (proposedBlocks[epoch][_blockId].valid) {
                    // slither-disable-next-line costly-loop
                    blockIndexToBeConfirmed = int8(i);
                    break;
                }
            }
        }

        uint32 proposerId = proposedBlocks[epoch][blockId].proposerId;
        stakeManager.slash(epoch, proposerId, msg.sender);
    }

    /**
     * @dev an internal function that checks whether the iteration value sent by the staker is correct or no
     * @param iteration number of tosses of a biased coin required for a head
     * @param biggestStakerId id of the Staker that has the biggest stake amongst the stakers that have revealed
     * @param stakerId id of the staker
     * @param epoch in which the block was proposed
     */
    function _isElectedProposer(
        uint256 iteration,
        uint32 biggestStakerId,
        uint32 stakerId,
        uint32 epoch
    ) internal view initialized returns (bool) {
        // generating pseudo random number (range 0..(totalstake - 1)), add (+1) to the result,
        // since prng returns 0 to max-1 and staker start from 1

        bytes32 salt = voteManager.getSalt();
        //roll an n sided fair die where n == numStakers to select a staker pseudoRandomly
        bytes32 seed1 = Random.prngHash(salt, keccak256(abi.encode(iteration)));
        uint256 rand1 = Random.prng(stakeManager.getNumStakers(), seed1);
        if ((rand1 + 1) != stakerId) {
            return false;
        }
        //toss a biased coin with increasing iteration till the following equation returns true.
        // stake/biggest stake >= prng(iteration,stakerid, salt), staker wins
        // stake/biggest stake < prng(iteration,stakerid, salt), staker loses
        // simplified equation:- stake < prng * biggestStake
        // stake * 2^32 < prng * 2^32 * biggestStake
        // multiplying by 2^32 since seed2 is bytes32 so rand2 goes from 0 to 2^32
        bytes32 seed2 = Random.prngHash(salt, keccak256(abi.encode(stakerId, iteration)));
        uint256 rand2 = Random.prng(2**32, seed2);

        uint256 biggestStake = voteManager.getStakeSnapshot(epoch, biggestStakerId);
        uint256 stake = voteManager.getStakeSnapshot(epoch, stakerId);
        // Below line can't be tested since it can't be assured if it returns true or false
        if (rand2 * (biggestStake) > stake * (2**32)) return (false);
        return true;
    }
}
        

@openzeppelin/contracts/utils/Context.sol

// 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;
    }
}
          

@openzeppelin/contracts/access/AccessControl.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;

import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * May emit a {RoleGranted} event.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}
          

@openzeppelin/contracts/access/IAccessControl.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}
          

@openzeppelin/contracts/utils/Strings.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}
          

@openzeppelin/contracts/utils/introspection/ERC165.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}
          

@openzeppelin/contracts/utils/introspection/IERC165.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
          

contracts/Core/StateManager.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "./storage/Constants.sol";

/** @title StateManager
 * @notice StateManager manages the state of the network
 */

contract StateManager is Constants {
    /**
     * @notice a check to ensure the epoch value sent in the function is of the currect epoch
     */
    modifier checkEpoch(uint32 epoch) {
        // slither-disable-next-line incorrect-equality
        require(epoch == _getEpoch(), "incorrect epoch");
        _;
    }

    /**
     * @notice a check to ensure the function was called in the state specified
     */
    modifier checkState(State state, uint8 buffer) {
        // slither-disable-next-line incorrect-equality
        require(state == _getState(buffer), "incorrect state");
        _;
    }

    /**
     * @notice a check to ensure the function was not called in the state specified
     */
    modifier notState(State state, uint8 buffer) {
        // slither-disable-next-line incorrect-equality
        require(state != _getState(buffer), "incorrect state");
        _;
    }

    /** @notice a check to ensure the epoch value sent in the function is of the currect epoch
     * and was called in the state specified
     */
    modifier checkEpochAndState(
        State state,
        uint32 epoch,
        uint8 buffer
    ) {
        // slither-disable-next-line incorrect-equality
        require(epoch == _getEpoch(), "incorrect epoch");
        // slither-disable-next-line incorrect-equality
        require(state == _getState(buffer), "incorrect state");
        _;
    }

    function _getEpoch() internal view returns (uint32) {
        return (uint32(block.timestamp) / (EPOCH_LENGTH));
    }

    function _getState(uint8 buffer) internal view returns (State) {
        uint8 lowerLimit = buffer;

        uint16 upperLimit = EPOCH_LENGTH / NUM_STATES - buffer;
        // slither-disable-next-line timestamp,weak-prng
        if (block.timestamp % (EPOCH_LENGTH / NUM_STATES) > upperLimit || block.timestamp % (EPOCH_LENGTH / NUM_STATES) < lowerLimit) {
            return State.Buffer;
        }
        // slither-disable-next-line timestamp,weak-prng
        uint8 state = uint8(((block.timestamp) / (EPOCH_LENGTH / NUM_STATES)) % (NUM_STATES));
        return State(state);
    }
}
          

contracts/Core/interface/IBlockManager.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "../../lib/Structs.sol";

interface IBlockManager {
    /**
     * @notice if the proposed staker, whose block is valid and has the lowest iteration, does not call claimBlockReward()
     * then in commit state, the staker who commits first will confirm this block and will receive the block reward inturn
     * @param stakerId id of the staker that is confirming the block
     */
    function confirmPreviousEpochBlock(uint32 stakerId) external;

    /**
     * @notice return the struct of the confirmed block
     * @param epoch in which this block was confirmed
     * @return _block : struct of the confirmed block
     */
    function getBlock(uint32 epoch) external view returns (Structs.Block memory _block);

    /**
     * @notice this is to check whether a block was confirmed in a particular epoch or not
     * @param epoch for which this check is being done
     * @return true or false. true if a block has been confirmed, else false
     */
    function isBlockConfirmed(uint32 epoch) external view returns (bool);

    /**
     * @notice Allows to get latest result of collection from id, used by delegator
     * @param id Collection ID
     */
    function getLatestResults(uint16 id) external view returns (uint256);
}
          

contracts/Core/interface/ICollectionManager.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface ICollectionManager {
    /**
     * @notice updates the collectionIdToLeafIdRegistryOfLastEpoch resgistries.
     * @dev It is called by the blockManager when a block is confirmed. It is only called if there was a change in the
     * status of collections in the network
     */
    function updateDelayedRegistry() external;

    /**
     * @param id the id of the collection
     * @return status of the collection
     */
    function getCollectionStatus(uint16 id) external view returns (bool);

    /**
     * @return total number of active collections
     */
    function getNumActiveCollections() external view returns (uint16);

    /**
     * @return ids of active collections
     */
    function getActiveCollections() external view returns (uint16[] memory);

    /**
     * @param id the id of the collection
     * @return power of the collection
     */
    function getCollectionPower(uint16 id) external view returns (int8);

    /**
     * @return total number of collections
     */
    function getNumCollections() external view returns (uint16);

    /**
     * @param i the leafId of the collection
     * @return tolerance of the collection
     */
    function getCollectionTolerance(uint16 i) external view returns (uint32);

    /**
     * @param id the id of the collection
     * @return the leafId of the collection from collectionIdToLeafIdRegistry
     */
    function getLeafIdOfCollection(uint16 id) external view returns (uint16);

    /**
     * @param leafId, the leafId of the collection
     * @return the id of the collection
     */
    function getCollectionIdFromLeafId(uint16 leafId) external view returns (uint16);

    /**
     * @param id the id of the collection
     * @return the leafId of the collection from collectionIdToLeafIdRegistryOfLastEpoch
     */
    function getLeafIdOfCollectionForLastEpoch(uint16 id) external view returns (uint16);

    /**
     * @param _name the name of the collection in bytes32
     * @return collection ID
     */
    function getCollectionID(bytes32 _name) external view returns (uint16);

    /**
     * @notice returns the result of the collection based on the name sent by the client
     * @param _name the name of the collection in bytes32
     * @return result of the collection
     * @return power of the resultant collection
     */
    function getResult(bytes32 _name) external view returns (uint256, int8);

    /**
     * @notice returns the result of the collection based on the id sent by the client
     * @param _id the id of the collection
     * @return result of the collection
     * @return power of the resultant collection
     */
    function getResultFromID(uint16 _id) external view returns (uint256, int8);

    /**
     * @return epoch in which the registry needs to be updated
     */
    function getUpdateRegistryEpoch() external view returns (uint32);
}
          

contracts/Core/interface/IRewardManager.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "../../lib/Structs.sol";

interface IRewardManager {
    /**
     * @notice gives penalty to stakers for failing to reveal or
     * reveal value deviations
     * @param stakerId The id of staker currently in consideration
     * @param epoch the epoch value
     */
    function givePenalties(uint32 epoch, uint32 stakerId) external;

    /**
     * @notice The function gives block reward for one valid proposer in the
     * previous epoch by increasing stake of staker
     * called from confirmBlock function of BlockManager contract. Commission
     * from the delegator's pool is given out to the staker from the block reward
     * @param stakerId The ID of the staker
     */
    function giveBlockReward(uint32 epoch, uint32 stakerId) external;

    /**
     * @notice The function gives out penalties to stakers during commit.
     * The penalties are given for inactivity, failing to reveal
     * , deviation from the median value of particular asset
     * @param stakerId The staker id
     * @param epoch The Epoch value in consideration
     */
    function giveInactivityPenalties(uint32 epoch, uint32 stakerId) external;
}
          

contracts/Core/interface/IStakeManager.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "../../lib/Structs.sol";
import "../storage/Constants.sol";

interface IStakeManager {
    /**
     * @notice External function for setting stake of the staker
     * Used by RewardManager
     * @param _epoch The epoch in which stake changes
     * @param _id of the staker
     * @param reason the reason for stake to change
     * @param prevStake previous stake of the staker
     * @param _stake updated stake of the staker
     */
    function setStakerStake(
        uint32 _epoch,
        uint32 _id,
        Constants.StakeChanged reason,
        uint256 prevStake,
        uint256 _stake
    ) external;

    /**
     * @notice The function is used by the Votemanager reveal function and BlockManager FinalizeDispute
     * to penalise the staker who lost his secret and make his stake less by "slashPenaltyAmount" and
     * transfer to bounty hunter half the "slashPenaltyAmount" of the staker
     * @param stakerId The ID of the staker who is penalised
     * @param bountyHunter The address of the bounty hunter
     */
    function slash(
        uint32 epoch,
        uint32 stakerId,
        address bountyHunter
    ) external;

    /**
     * @notice External function for setting staker age of the staker
     * Used by RewardManager
     * @param _epoch The epoch in which age changes
     * @param _id of the staker
     * @param _age the updated new age
     * @param reason the reason for age change
     */
    function setStakerAge(
        uint32 _epoch,
        uint32 _id,
        uint32 _age,
        Constants.AgeChanged reason
    ) external;

    /**
     * @notice External function for setting stakerReward of the staker
     * Used by RewardManager
     * @param _epoch The epoch in which stakerReward changes
     * @param _id of the staker
     * @param reason the reason for stakerReward to change
     * @param prevStakerReward previous stakerReward of the staker
     * @param _stakerReward updated stakerReward of the staker
     */
    function setStakerReward(
        uint32 _epoch,
        uint32 _id,
        Constants.StakerRewardChanged reason,
        uint256 prevStakerReward,
        uint256 _stakerReward
    ) external;

    /**
     * @notice External function for setting epochLastPenalized of the staker
     * Used by RewardManager
     * @param _id of the staker
     */
    function setStakerEpochFirstStakedOrLastPenalized(uint32 _epoch, uint32 _id) external;

    /**
     * @notice remove all funds in case of emergency
     */
    function escape(address _address) external;

    /**
     * @notice event being thrown after every successful sRZR transfer taking place
     * @param from sender
     * @param to recepient
     * @param amount srzr amount being transferred
     * @param stakerId of the staker
     */
    function srzrTransfer(
        address from,
        address to,
        uint256 amount,
        uint32 stakerId
    ) external;

    /**
     * @param _address Address of the staker
     * @return The staker ID
     */
    function getStakerId(address _address) external view returns (uint32);

    /**
     * @param _id The staker ID
     * @return staker The Struct of staker information
     */
    function getStaker(uint32 _id) external view returns (Structs.Staker memory staker);

    /**
     * @return The number of stakers in the razor network
     */
    function getNumStakers() external view returns (uint32);

    /**
     * @return influence of staker
     */
    function getInfluence(uint32 stakerId) external view returns (uint256);

    /**
     * @return stake of staker
     */
    function getStake(uint32 stakerId) external view returns (uint256);

    /**
     * @return epochFirstStakedOrLastPenalized of staker
     */
    function getEpochFirstStakedOrLastPenalized(uint32 stakerId) external view returns (uint32);

    /**
     * @return length of maturities array
     */
    function maturitiesLength() external view returns (uint32);
}
          

contracts/Core/interface/IVoteManager.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "../../lib/Structs.sol";

interface IVoteManager {
    /**
     * @notice stores the salt calculated in block manager
     * @param _salt the hash of the last epoch and medians of the block
     */
    function storeSalt(bytes32 _salt) external;

    /**
     * @notice stores the depth of a valid merkle tree. Depth of the merkle tree sent by the stakers should match with this
     * for a valid commit/reveal
     * @param _depth depth of the merkle tree
     */
    function storeDepth(uint256 _depth) external;

    /**
     * @notice returns vote value of a collection reported by a particular staker
     * @param epoch in which the staker reveal this value
     * @param stakerId id of the staker
     * @param leafId seq position of collection in merkle tree
     * @return vote value
     */
    function getVoteValue(
        uint32 epoch,
        uint32 stakerId,
        uint16 leafId
    ) external view returns (uint256);

    /**
     * @notice returns vote weight of the value of the collection reported
     * @param epoch in which the staker reveal this value
     * @param leafId seq position of collection in merkle tree
     * @param voteValue one of the values of the collection being reported
     * @return vote weight of the vote
     */
    function getVoteWeight(
        uint32 epoch,
        uint16 leafId,
        uint256 voteValue
    ) external view returns (uint256);

    /**
     * @notice returns snapshot of influence of the staker when they revealed
     * @param epoch when the snapshot was taken
     * @param stakerId id of the staker
     * @return influence of the staker
     */
    function getInfluenceSnapshot(uint32 epoch, uint32 stakerId) external view returns (uint256);

    /**
     * @notice returns snapshot of stake of the staker when they revealed
     * @param epoch when the snapshot was taken
     * @param stakerId id of the staker
     * @return stake of the staker
     */
    function getStakeSnapshot(uint32 epoch, uint32 stakerId) external view returns (uint256);

    /**
     * @notice returns the total influence revealed of the collection
     * @param epoch when asset was being revealed
     * @param leafId seq position of collection in merkle tree
     * @return total influence revealed of the collection
     */
    function getTotalInfluenceRevealed(uint32 epoch, uint16 leafId) external view returns (uint256);

    /**
     * @notice returns the epoch a staker last revealed their votes
     * @param stakerId id of the staker
     * @return epoch last revealed
     */
    function getEpochLastRevealed(uint32 stakerId) external view returns (uint32);

    /**
     * @notice returns the epoch a staker last committed their votes
     * @param stakerId id of the staker
     * @return epoch last committed
     */
    function getEpochLastCommitted(uint32 stakerId) external view returns (uint32);

    /**
     * @return the salt
     */
    function getSalt() external view returns (bytes32);
}
          

contracts/Core/parameters/ACL.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/AccessControl.sol";

contract ACL is AccessControl {
    /**
     * @dev the deployer of the network is given to the default admin role which gives other roles to contracts
     */
    constructor() {
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
    }
}
          

contracts/Core/parameters/child/BlockManagerParams.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "../interfaces/IBlockManagerParams.sol";
import "../ACL.sol";
import "../../storage/Constants.sol";

abstract contract BlockManagerParams is ACL, IBlockManagerParams, Constants {
    /// @notice maximum number of best proposed blocks to be considered for dispute
    uint8 public maxAltBlocks = 5;
    uint8 public buffer = 5;
    /// @notice reward given to staker whose block is confirmed
    uint256 public blockReward = 100 * (10**18);
    /// @notice minimum amount of stake required to participate
    uint256 public minStake = 20000 * (10**18);

    /// @inheritdoc IBlockManagerParams
    function setMaxAltBlocks(uint8 _maxAltBlocks) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        maxAltBlocks = _maxAltBlocks;
    }

    function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        buffer = _bufferLength;
    }

    /// @inheritdoc IBlockManagerParams
    function setBlockReward(uint256 _blockReward) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        blockReward = _blockReward;
    }

    /// @inheritdoc IBlockManagerParams
    function setMinStake(uint256 _minStake) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        minStake = _minStake;
    }
}
          

contracts/Core/parameters/interfaces/IBlockManagerParams.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IBlockManagerParams {
    /**
     * @notice changing the maximum number of best proposed blocks to be considered for dispute
     * @dev can be called only by the the address that has the governance role
     * @param _maxAltBlocks updated value to be set for maxAltBlocks
     */
    function setMaxAltBlocks(uint8 _maxAltBlocks) external;

    /**
     * @notice changing the block reward given out to stakers
     * @dev can be called only by the the address that has the governance role
     * @param _blockReward updated value to be set for blockReward
     */
    function setBlockReward(uint256 _blockReward) external;

    /**
     * @notice changing minimum amount that to be staked for participation
     * @dev can be called only by the the address that has the governance role
     * @param _minStake updated value to be set for minStake
     */
    function setMinStake(uint256 _minStake) external;

    /**
     * @notice changing buffer length between the states
     * @dev can be called only by the the address that has the governance role
     * @param _bufferLength updated value to be set for buffer
     */
    function setBufferLength(uint8 _bufferLength) external;
}
          

contracts/Core/storage/BlockStorage.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "../../lib/Structs.sol";

contract BlockStorage {
    /// @notice mapping of epoch -> address -> dispute
    mapping(uint32 => mapping(address => Structs.Dispute)) public disputes;
    /// @notice mapping of epoch -> blockId -> block
    mapping(uint32 => mapping(uint32 => Structs.Block)) public proposedBlocks;
    /// @notice mapping of epoch->blockId
    mapping(uint32 => uint32[]) public sortedProposedBlockIds;
    /// @notice mapping of stakerId->epoch
    mapping(uint32 => uint32) public epochLastProposed;
    // @notice mapping for latest results of collection id->result
    mapping(uint16 => uint256) public latestResults;
    /// @notice total number of proposed blocks in an epoch
    // slither-disable-next-line constable-states
    uint32 public numProposedBlocks;
    /// @notice block index that is to be confirmed if not disputed
    // slither-disable-next-line constable-states
    int8 public blockIndexToBeConfirmed; // Index in sortedProposedBlockIds
    /// @notice mapping of  epoch -> blocks
    mapping(uint32 => Structs.Block) public blocks;
}
          

contracts/Core/storage/Constants.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

contract Constants {
    enum State {
        Commit,
        Reveal,
        Propose,
        Dispute,
        Confirm,
        Buffer
    }

    enum StakeChanged {
        BlockReward,
        InactivityPenalty,
        Slashed
    }

    enum StakerRewardChanged {
        StakerRewardAdded,
        StakerRewardClaimed
    }

    enum AgeChanged {
        InactivityPenalty,
        VotingRewardOrPenalty
    }

    uint8 public constant NUM_STATES = 5;

    uint16 public constant EPOCH_LENGTH = 1200;

    // slither-disable-next-line too-many-digits
    address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
    uint32 public constant BASE_DENOMINATOR = 10_000_000;
    // keccak256("BLOCK_CONFIRMER_ROLE")
    bytes32 public constant BLOCK_CONFIRMER_ROLE = 0x18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f;

    // keccak256("STAKE_MODIFIER_ROLE")
    bytes32 public constant STAKE_MODIFIER_ROLE = 0xdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc804;

    // keccak256("REWARD_MODIFIER_ROLE")
    bytes32 public constant REWARD_MODIFIER_ROLE = 0xcabcaf259dd9a27f23bd8a92bacd65983c2ebf027c853f89f941715905271a8d;

    // keccak256("COLLECTION_MODIFIER_ROLE")
    bytes32 public constant COLLECTION_MODIFIER_ROLE = 0xa3a75e7cd2b78fcc3ae2046ab93bfa4ac0b87ed7ea56646a312cbcb73eabd294;

    // keccak256("VOTE_MODIFIER_ROLE")
    bytes32 public constant VOTE_MODIFIER_ROLE = 0x912208965b92edeb3eb82a612c87b38b5e844f7539cb396f0d08ec012e511b07;

    // keccak256("DELEGATOR_MODIFIER_ROLE")
    bytes32 public constant DELEGATOR_MODIFIER_ROLE = 0x6b7da7a33355c6e035439beb2ac6a052f1558db73f08690b1c9ef5a4e8389597;

    // keccak256("REGISTRY_MODIFIER_ROLE")
    bytes32 public constant REGISTRY_MODIFIER_ROLE = 0xca51085219bef34771da292cb24ee4fcf0ae6bdba1a62c17d1fb7d58be802883;

    // keccak256("SECRETS_MODIFIER_ROLE")
    bytes32 public constant SECRETS_MODIFIER_ROLE = 0x46aaf8a125792dfff6db03d74f94fe1acaf55c8cab22f65297c15809c364465c;

    // keccak256("PAUSE_ROLE")
    bytes32 public constant PAUSE_ROLE = 0x139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d;

    // keccak256("GOVERNANCE_ROLE")
    bytes32 public constant GOVERNANCE_ROLE = 0x71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1;

    // keccak256("STOKEN_ROLE")
    bytes32 public constant STOKEN_ROLE = 0xce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc;

    // keccak256("SALT_MODIFIER_ROLE")
    bytes32 public constant SALT_MODIFIER_ROLE = 0xf31dda80d37c96a1a0852ace387dda52a75487d7d4eb74895e749ede3e0987b4;

    // keccak256("DEPTH_MODIFIER_ROLE)")
    bytes32 public constant DEPTH_MODIFIER_ROLE = 0x91f5d9ea80c4d04985e669bc72870410b28b57afdf61c0d50d377766d86a3748;

    // keccak256("ESCAPE_HATCH_ROLE")
    bytes32 public constant ESCAPE_HATCH_ROLE = 0x518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba8043;
}
          

contracts/Initializable.sol

// SPDX-License-Identifier: MIT

// solhint-disable-next-line compiler-version
pragma solidity ^0.8.0;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * Forked from OZ's (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/b9125001f0a1c44d596ca3a47536f1a467e3a29d/contracts/proxy/utils/Initializable.sol)
 */

abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || !_initialized, "contract already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

    modifier initialized() {
        require(_initialized, "Contract should be initialized");
        _;
    }
}
          

contracts/lib/Random.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

library Random {
    // pseudo random number generator based on hash. returns 0 -> max-1
    // slither ignore reason : Internal library
    // slither-disable-next-line dead-code
    function prng(uint256 max, bytes32 randHash) internal pure returns (uint256) {
        uint256 sum = uint256(randHash);
        return (sum % max);
    }

    // pseudo random hash generator based on hashes.
    // slither ignore reason : Internal library
    // slither-disable-next-line dead-code
    function prngHash(bytes32 seed, bytes32 salt) internal pure returns (bytes32) {
        bytes32 prngHashVal = keccak256(abi.encodePacked(seed, salt));
        return (prngHashVal);
    }
}
          

contracts/lib/Structs.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

library Structs {
    struct Commitment {
        uint32 epoch;
        bytes32 commitmentHash;
    }
    struct Staker {
        // Slot 1
        bool acceptDelegation;
        bool isSlashed;
        uint8 commission;
        uint32 id;
        uint32 age;
        address _address;
        // Slot 2
        address tokenAddress;
        uint32 epochFirstStakedOrLastPenalized;
        uint32 epochCommissionLastUpdated;
        // Slot 3
        uint256 stake;
        uint256 stakerReward;
    }

    struct Lock {
        uint256 amount; //amount in sRZR/RZR
        uint256 unlockAfter; // Can be made uint32 later if packing is possible
    }

    struct BountyLock {
        uint32 redeemAfter;
        address bountyHunter;
        uint256 amount; //amount in RZR
    }

    struct Block {
        bool valid;
        uint32 proposerId;
        uint16[] ids;
        uint256 iteration;
        uint256 biggestStake;
        uint256[] medians;
    }

    struct Dispute {
        uint16 leafId;
        uint256 lastVisitedValue;
        uint256 accWeight;
        uint256 median;
    }

    struct Job {
        uint16 id;
        uint8 selectorType; // 0-1
        uint8 weight; // 1-100
        int8 power;
        string name;
        string selector;
        string url;
    }

    struct Collection {
        bool active;
        uint16 id;
        int8 power;
        uint32 tolerance;
        uint32 aggregationMethod;
        uint16[] jobIDs;
        string name;
    }

    struct AssignedAsset {
        uint16 leafId;
        uint256 value;
    }

    struct MerkleTree {
        Structs.AssignedAsset[] values;
        bytes32[][] proofs;
        bytes32 root;
    }
}
          

contracts/randomNumber/IRandomNoProvider.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

interface IRandomNoProvider {
    /**
     * @notice Called by BlockManager in ClaimBlockReward or ConfirmBlockLastEpoch
     * @param epoch current epoch
     * @param _secret hash of encoded rando secret from stakers
     */
    function provideSecret(uint32 epoch, bytes32 _secret) external;
}
          

Contract ABI

[{"type":"event","name":"BlockConfirmed","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint16[]","name":"ids","internalType":"uint16[]","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false},{"type":"uint256[]","name":"medians","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"ClaimBlockReward","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DisputeBiggestStakeProposed","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint8","name":"blockIndex","internalType":"uint8","indexed":false},{"type":"uint32","name":"correctBiggestStakerId","internalType":"uint32","indexed":true},{"type":"address","name":"disputer","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"DisputeCollectionIdShouldBeAbsent","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint8","name":"blockIndex","internalType":"uint8","indexed":false},{"type":"uint32","name":"id","internalType":"uint32","indexed":true},{"type":"uint256","name":"postionOfCollectionInBlock","internalType":"uint256","indexed":false},{"type":"address","name":"disputer","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"DisputeCollectionIdShouldBePresent","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint8","name":"blockIndex","internalType":"uint8","indexed":false},{"type":"uint32","name":"id","internalType":"uint32","indexed":true},{"type":"address","name":"disputer","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"DisputeOnOrderOfIds","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint8","name":"blockIndex","internalType":"uint8","indexed":false},{"type":"uint256","name":"index0","internalType":"uint256","indexed":false},{"type":"uint256","name":"index1","internalType":"uint256","indexed":false},{"type":"address","name":"disputer","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"FinalizeDispute","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint8","name":"blockIndex","internalType":"uint8","indexed":false},{"type":"uint256","name":"postionOfCollectionInBlock","internalType":"uint256","indexed":false},{"type":"address","name":"disputer","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"GiveSorted","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint16","name":"leafId","internalType":"uint16","indexed":true},{"type":"uint256[]","name":"sortedValues","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"Proposed","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint32","name":"biggestStakerId","internalType":"uint32","indexed":false},{"type":"uint16[]","name":"ids","internalType":"uint16[]","indexed":false},{"type":"uint256","name":"iteration","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false},{"type":"uint256[]","name":"medians","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"RoleAdminChanged","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"previousAdminRole","internalType":"bytes32","indexed":true},{"type":"bytes32","name":"newAdminRole","internalType":"bytes32","indexed":true}],"anonymous":false},{"type":"event","name":"RoleGranted","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"RoleRevoked","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32","indexed":true},{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"address","name":"sender","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"BASE_DENOMINATOR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"BLOCK_CONFIRMER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"BURN_ADDRESS","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"COLLECTION_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DEFAULT_ADMIN_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DELEGATOR_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"DEPTH_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"EPOCH_LENGTH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"ESCAPE_HATCH_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"GOVERNANCE_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"NUM_STATES","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"PAUSE_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"REGISTRY_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"REWARD_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"SALT_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"SECRETS_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"STAKE_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"STOKEN_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"VOTE_MODIFIER_ROLE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"int8","name":"","internalType":"int8"}],"name":"blockIndexToBeConfirmed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"blockReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"valid","internalType":"bool"},{"type":"uint32","name":"proposerId","internalType":"uint32"},{"type":"uint256","name":"iteration","internalType":"uint256"},{"type":"uint256","name":"biggestStake","internalType":"uint256"}],"name":"blocks","inputs":[{"type":"uint32","name":"","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"buffer","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimBlockReward","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ICollectionManager"}],"name":"collectionManager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"confirmPreviousEpochBlock","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disputeBiggestStakeProposed","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint8","name":"blockIndex","internalType":"uint8"},{"type":"uint32","name":"correctBiggestStakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disputeCollectionIdShouldBeAbsent","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint8","name":"blockIndex","internalType":"uint8"},{"type":"uint16","name":"id","internalType":"uint16"},{"type":"uint256","name":"postionOfCollectionInBlock","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disputeCollectionIdShouldBePresent","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint8","name":"blockIndex","internalType":"uint8"},{"type":"uint16","name":"id","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disputeOnOrderOfIds","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint8","name":"blockIndex","internalType":"uint8"},{"type":"uint256","name":"index0","internalType":"uint256"},{"type":"uint256","name":"index1","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"leafId","internalType":"uint16"},{"type":"uint256","name":"lastVisitedValue","internalType":"uint256"},{"type":"uint256","name":"accWeight","internalType":"uint256"},{"type":"uint256","name":"median","internalType":"uint256"}],"name":"disputes","inputs":[{"type":"uint32","name":"","internalType":"uint32"},{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"epochLastProposed","inputs":[{"type":"uint32","name":"","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"finalizeDispute","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint8","name":"blockIndex","internalType":"uint8"},{"type":"uint256","name":"postionOfCollectionInBlock","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"_block","internalType":"struct Structs.Block","components":[{"type":"bool","name":"valid","internalType":"bool"},{"type":"uint32","name":"proposerId","internalType":"uint32"},{"type":"uint16[]","name":"ids","internalType":"uint16[]"},{"type":"uint256","name":"iteration","internalType":"uint256"},{"type":"uint256","name":"biggestStake","internalType":"uint256"},{"type":"uint256[]","name":"medians","internalType":"uint256[]"}]}],"name":"getBlock","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLatestResults","inputs":[{"type":"uint16","name":"id","internalType":"uint16"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"getNumProposedBlocks","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"_block","internalType":"struct Structs.Block","components":[{"type":"bool","name":"valid","internalType":"bool"},{"type":"uint32","name":"proposerId","internalType":"uint32"},{"type":"uint16[]","name":"ids","internalType":"uint16[]"},{"type":"uint256","name":"iteration","internalType":"uint256"},{"type":"uint256","name":"biggestStake","internalType":"uint256"},{"type":"uint256[]","name":"medians","internalType":"uint256[]"}]}],"name":"getProposedBlock","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint32","name":"proposedBlock","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoleAdmin","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"giveSorted","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint16","name":"leafId","internalType":"uint16"},{"type":"uint256[]","name":"sortedValues","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"grantRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"hasRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"stakeManagerAddress","internalType":"address"},{"type":"address","name":"rewardManagerAddress","internalType":"address"},{"type":"address","name":"voteManagerAddress","internalType":"address"},{"type":"address","name":"collectionManagerAddress","internalType":"address"},{"type":"address","name":"randomNoManagerAddress","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isBlockConfirmed","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestResults","inputs":[{"type":"uint16","name":"","internalType":"uint16"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"maxAltBlocks","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minStake","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"numProposedBlocks","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"propose","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint16[]","name":"ids","internalType":"uint16[]"},{"type":"uint256[]","name":"medians","internalType":"uint256[]"},{"type":"uint256","name":"iteration","internalType":"uint256"},{"type":"uint32","name":"biggestStakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"valid","internalType":"bool"},{"type":"uint32","name":"proposerId","internalType":"uint32"},{"type":"uint256","name":"iteration","internalType":"uint256"},{"type":"uint256","name":"biggestStake","internalType":"uint256"}],"name":"proposedBlocks","inputs":[{"type":"uint32","name":"","internalType":"uint32"},{"type":"uint32","name":"","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IRandomNoProvider"}],"name":"randomNoProvider","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"resetDispute","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revokeRole","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"},{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IRewardManager"}],"name":"rewardManager","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBlockReward","inputs":[{"type":"uint256","name":"_blockReward","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBufferLength","inputs":[{"type":"uint8","name":"_bufferLength","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxAltBlocks","inputs":[{"type":"uint8","name":"_maxAltBlocks","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinStake","inputs":[{"type":"uint256","name":"_minStake","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"sortedProposedBlockIds","inputs":[{"type":"uint32","name":"","internalType":"uint32"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IStakeManager"}],"name":"stakeManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IVoteManager"}],"name":"voteManager","inputs":[]}]
              

Contract Creation Code

0x60806040526009805461ffff191661050517905568056bc75e2d63100000600a5569043c33c1937564800000600b553480156200003b57600080fd5b50620000496000336200004f565b62000103565b6200005b82826200005f565b5050565b60008281526008602090815260408083206001600160a01b038516845290915290205460ff166200005b5760008281526008602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620000bf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b615b8d80620001136000396000f3fe608060405234801561001057600080fd5b50600436106103ba5760003560e01c806367ba825c116101f4578063bd8595841161011a578063dc82a745116100ad578063ef8bf6841161007c578063ef8bf68414610a93578063f36c8f5c14610aba578063f454620f14610acf578063fccc281314610ae257600080fd5b8063dc82a74514610a34578063dde784d514610a47578063ed6c935d14610a5a578063edaafe2014610a8157600080fd5b8063c9e99c25116100e9578063c9e99c25146109d4578063d547741f146109e7578063da984295146109fa578063db7b499614610a2157600080fd5b8063bd85958414610927578063be436df114610931578063bf897a9a14610957578063c1a2bab51461096a57600080fd5b80638c80fd90116101925780639fdf8469116101615780639fdf8469146108c9578063a217fddf146108dc578063ac4746ab146108e4578063b0daafef1461090057600080fd5b80638c80fd901461084857806391d148541461085b5780639493aff81461086e57806397788d06146108b657600080fd5b806381d96db8116101ce57806381d96db8146107cb57806385a9777c146107de5780638622f3a9146107f1578063885fc0941461082157600080fd5b806367ba825c1461076d5780637542ff9514610791578063776076e7146107a457600080fd5b80632d93b9a0116102e457806342a1035f116102775780634a8aace5116102465780634a8aace5146106a65780635b070278146106b95780635cd0783e146106e0578063622f93301461074657600080fd5b806342a1035f1461064957806342c1e58714610659578063474a1ae11461066c5780634912b72a1461067f57600080fd5b8063375b3c0a116102b3578063375b3c0a146105e5578063379597e0146105ee578063389ed267146105fb57806341d296f71461062257600080fd5b80632d93b9a0146105715780632f2ff15d146105985780632f50bcc4146105ab57806336568abe146105d257600080fd5b8063123047011161035c5780631a18e7071161032b5780631a18e707146104ed5780631bea14e9146105005780632023d0be14610513578063248a9ca31461054e57600080fd5b8063123047011461049f5780631459457a146104bf57806316391253146104d2578063171fe294146104da57600080fd5b80630ac168a1116103985780630ac168a1146104215780630c92ad7d146104385780630f4ef8a61461044d57806311e29f521461047857600080fd5b806301ffc9a7146103bf57806305db56df146103e757806309f2f13d14610401575b600080fd5b6103d26103cd366004615168565b610aeb565b60405190151581526020015b60405180910390f35b6103ef600581565b60405160ff90911681526020016103de565b61041461040f36600461539c565b610b22565b6040516103de9190615760565b61042a600a5481565b6040519081526020016103de565b61044b6104463660046154ea565b610c92565b005b600d54610460906001600160a01b031681565b6040516001600160a01b0390911681526020016103de565b60065461048c90600160201b900460000b81565b60405160009190910b81526020016103de565b61042a6104ad366004615190565b60056020526000908152604090205481565b61044b6104cd366004615089565b610f5a565b61044b61105d565b61044b6104e83660046153d4565b6114a9565b61044b6104fb36600461510d565b611a53565b61041461050e3660046151c8565b611a71565b6105396105213660046151c8565b60046020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016103de565b61042a61055c36600461510d565b60009081526008602052604090206001015490565b61042a7f912208965b92edeb3eb82a612c87b38b5e844f7539cb396f0d08ec012e511b0781565b61044b6105a636600461513d565b611bd6565b61042a7f46aaf8a125792dfff6db03d74f94fe1acaf55c8cab22f65297c15809c364465c81565b61044b6105e036600461513d565b611c00565b61042a600b5481565b6009546103ef9060ff1681565b61042a7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d81565b61042a7f91f5d9ea80c4d04985e669bc72870410b28b57afdf61c0d50d377766d86a374881565b6006546105399063ffffffff1681565b600e54610460906001600160a01b031681565b61044b61067a36600461522b565b611c7e565b61042a7f6b7da7a33355c6e035439beb2ac6a052f1558db73f08690b1c9ef5a4e838959781565b61044b6106b4366004615311565b6122f8565b61042a7fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc81565b61071f6106ee3660046151c8565b60076020526000908152604090208054600282015460039092015460ff82169261010090920463ffffffff16919084565b60408051941515855263ffffffff90931660208501529183015260608201526080016103de565b61042a7f518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba804381565b61042a61077b366004615190565b61ffff1660009081526005602052604090205490565b600c54610460906001600160a01b031681565b61042a7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80481565b61044b6107d93660046151c8565b6128b0565b6105396107ec366004615371565b6129e9565b6103d26107ff3660046151c8565b63ffffffff908116600090815260076020526040902054610100900416151590565b61042a7fa3a75e7cd2b78fcc3ae2046ab93bfa4ac0b87ed7ea56646a312cbcb73eabd29481565b61044b61085636600461510d565b612a32565b6103d261086936600461513d565b612a50565b61071f61087c36600461539c565b6002602081815260009384526040808520909152918352912080549181015460039091015460ff831692610100900463ffffffff16919084565b61044b6108c4366004615527565b612a7b565b600f54610460906001600160a01b031681565b61042a600081565b6108ed6104b081565b60405161ffff90911681526020016103de565b61042a7ff31dda80d37c96a1a0852ace387dda52a75487d7d4eb74895e749ede3e0987b481565b6105396298968081565b6103ef61093f3660046151c8565b63ffffffff1660009081526003602052604090205490565b601054610460906001600160a01b031681565b6109af610978366004615200565b60016020818152600093845260408085209091529183529120805491810154600282015460039092015461ffff9093169290919084565b6040805161ffff909516855260208501939093529183015260608201526080016103de565b61044b6109e23660046151c8565b612aaa565b61044b6109f536600461513d565b612c67565b61042a7f18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f81565b61044b610a2f366004615527565b612c8c565b61044b610a4236600461541c565b612cc1565b61044b610a553660046154a7565b613121565b61042a7fca51085219bef34771da292cb24ee4fcf0ae6bdba1a62c17d1fb7d58be80288381565b6009546103ef90610100900460ff1681565b61042a7fcabcaf259dd9a27f23bd8a92bacd65983c2ebf027c853f89f941715905271a8d81565b61042a600080516020615b3883398151915281565b61044b610add36600461546a565b61344b565b61046061dead81565b60006001600160e01b03198216637965db0b60e01b1480610b1c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610b636040518060c00160405280600015158152602001600063ffffffff168152602001606081526020016000815260200160008152602001606081525090565b63ffffffff80841660009081526002602090815260408083208685168452825291829020825160c081018452815460ff81161515825261010090049094168483015260018101805484518185028101850186528181529294860193830182828015610c1557602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610bdc5790505b50505050508152602001600282015481526020016003820154815260200160048201805480602002602001604051908101604052809291908181526020018280548015610c8157602002820191906000526020600020905b815481526020019060010190808311610c6d575b505050505081525050905092915050565b60005460ff16610cbd5760405162461bcd60e51b8152600401610cb4906156d7565b60405180910390fd5b6009546003908490610100900460ff16610cd5613a88565b63ffffffff168263ffffffff1614610cff5760405162461bcd60e51b8152600401610cb49061570e565b610d0881613a9b565b6005811115610d2757634e487b7160e01b600052602160045260246000fd5b836005811115610d4757634e487b7160e01b600052602160045260246000fd5b14610d645760405162461bcd60e51b8152600401610cb490615737565b63ffffffff86166000908152600360205260408120805460ff8816908110610d9c57634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8b8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff16610dfc5760405162461bcd60e51b8152600401610cb4906156a0565b600e546040516370b9856360e11b815263ffffffff808a166004830152871660248201526000916001600160a01b03169063e1730ac69060440160206040518083038186803b158015610e4e57600080fd5b505afa158015610e62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e869190615125565b63ffffffff808a166000908152600260209081526040808320938716835292905220600301549091508111610efd5760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642064697370757465203a205374616b650000000000000000006044820152606401610cb4565b6040805163ffffffff8a8116825260ff8a1660208301523392908916917fe236f3a69f3f4080c6762e1b5212e97fe7b5ff198bd2612d590b3bae699389e2910160405180910390a3610f50888884613b69565b5050505050505050565b600054610100900460ff1680610f73575060005460ff16155b610fbf5760405162461bcd60e51b815260206004820152601c60248201527f636f6e747261637420616c726561647920696e697469616c697a6564000000006044820152606401610cb4565b600054610100900460ff16158015610fe1576000805461ffff19166101011790555b6000610fec81613d2a565b50600c80546001600160a01b03199081166001600160a01b0389811691909117909255600d80548216888416179055600e80548216878416179055600f80548216868416179055601080549091169184169190911790558015611055576000805461ff00191690555b505050505050565b60005460ff1661107f5760405162461bcd60e51b8152600401610cb4906156d7565b600954600490610100900460ff1661109681613a9b565b60058111156110b557634e487b7160e01b600052602160045260246000fd5b8260058111156110d557634e487b7160e01b600052602160045260246000fd5b146110f25760405162461bcd60e51b8152600401610cb490615737565b60006110fc613a88565b600c54604051636022a48560e01b81523360048201529192506000916001600160a01b0390911690636022a4859060240160206040518083038186803b15801561114557600080fd5b505afa158015611159573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117d91906151e4565b905060008163ffffffff16116111d55760405162461bcd60e51b815260206004820152601d60248201527f537472756374732e5374616b657220646f6573206e6f742065786973740000006044820152606401610cb4565b63ffffffff8083166000908152600760205260409020546101009004161561123f5760405162461bcd60e51b815260206004820152601760248201527f426c6f636b20616c726561647920636f6e6669726d65640000000000000000006044820152606401610cb4565b63ffffffff8216600090815260036020526040902054158015906112755750600654600160201b9004600090810b900b60001914155b156113a75763ffffffff82166000908152600260209081526040808320600390925282206006548154849291600160201b9004830b60ff169081106112ca57634e487b7160e01b600052603260045260246000fd5b60009182526020808320600883040154600790921660040261010090810a90920463ffffffff90811685529084019490945260409092019020540481169150821681146113595760405162461bcd60e51b815260206004820152601960248201527f426c6f636b2050726f706f736572206d69736d617463686573000000000000006044820152606401610cb4565b6040805163ffffffff85811682524260208301528416917f6bf7d26513a0f410d2e9f5e8e878ef1ff0ce51b47d75f0c221cb597878baaa73910160405180910390a26113a58382613d37565b505b600f546040805163113df3d760e21b815290516000926001600160a01b0316916344f7cf5c916004808301926020929190829003018186803b1580156113ec57600080fd5b505afa158015611400573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142491906151e4565b90508263ffffffff168163ffffffff16116114a257600f60009054906101000a90046001600160a01b03166001600160a01b03166342e8e34e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561148957600080fd5b505af115801561149d573d6000803e3d6000fd5b505050505b5050505050565b60005460ff166114cb5760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908490610100900460ff166114e3613a88565b63ffffffff168263ffffffff161461150d5760405162461bcd60e51b8152600401610cb49061570e565b61151681613a9b565b600581111561153557634e487b7160e01b600052602160045260246000fd5b83600581111561155557634e487b7160e01b600052602160045260246000fd5b146115725760405162461bcd60e51b8152600401610cb490615737565b63ffffffff86166000908152600360205260408120805460ff88169081106115aa57634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8b8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff1661160a5760405162461bcd60e51b8152600401610cb4906156a0565b600f54604051631bc8002760e11b815261ffff871660048201526000916001600160a01b031690633790004e9060240160206040518083038186803b15801561165257600080fd5b505afa158015611666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168a91906151ac565b600e54604051631dab515760e21b815263ffffffff8b16600482015261ffff831660248201529192506000916001600160a01b03909116906376ad455c9060440160206040518083038186803b1580156116e357600080fd5b505afa1580156116f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171b9190615125565b90508061176a5760405162461bcd60e51b815260206004820152601c60248201527f446973707574653a2049442073686f756c6420626520616273656e74000000006044820152606401610cb4565b63ffffffff808a16600090815260026020908152604080832087851684528252808320815160c081018352815460ff811615158252610100900490951685840152600181018054835181860281018601855281815295969592949386019383018282801561181f57602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff16815260200190600201906020826001010492830192600103820291508084116117e65790505b5050505050815260200160028201548152602001600382015481526020016004820180548060200260200160405190810160405280929190818152602001828054801561188b57602002820191906000526020600020905b815481526020019060010190808311611877575b50505091909252505050604081015151909150600190156119a55760008060018460400151516118bb91906159c6565b90505b8181111561196257600060026118d484846159c6565b6118de9190615959565b6118e890836159c6565b905060008560400151828151811061191057634e487b7160e01b600052603260045260246000fd5b602002602001015190508c61ffff168161ffff16141561193557600094505050611962565b8c61ffff168161ffff16101561194d5781935061195b565b6119586001836159c6565b92505b50506118be565b8a61ffff168460400151838151811061198b57634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff1614156119a257600092505b50505b806119f25760405162461bcd60e51b815260206004820152601860248201527f446973707574653a2049442070726573656e74206f6e6c7900000000000000006044820152606401610cb4565b6040805163ffffffff8d16815260ff8c166020820152339161ffff8c16917febc0bc7a021fb6273a69f0d80c14d8489e54d04923760056155a184100fbca42910160405180910390a3611a468b8b87613b69565b5050505050505050505050565b600080516020615b38833981519152611a6b81613d2a565b50600a55565b611ab26040518060c00160405280600015158152602001600063ffffffff168152602001606081526020016000815260200160008152602001606081525090565b63ffffffff808316600090815260076020908152604091829020825160c081018452815460ff81161515825261010090049094168483015260018101805484518185028101850186528181529294860193830182828015611b5a57602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411611b215790505b50505050508152602001600282015481526020016003820154815260200160048201805480602002602001604051908101604052809291908181526020018280548015611bc657602002820191906000526020600020905b815481526020019060010190808311611bb2575b5050505050815250509050919050565b600082815260086020526040902060010154611bf181613d2a565b611bfb83836141a2565b505050565b6001600160a01b0381163314611c705760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610cb4565b611c7a8282614228565b5050565b60005460ff16611ca05760405162461bcd60e51b8152600401610cb4906156d7565b6009546002908690610100900460ff16611cb8613a88565b63ffffffff168263ffffffff1614611ce25760405162461bcd60e51b8152600401610cb49061570e565b611ceb81613a9b565b6005811115611d0a57634e487b7160e01b600052602160045260246000fd5b836005811115611d2a57634e487b7160e01b600052602160045260246000fd5b14611d475760405162461bcd60e51b8152600401610cb490615737565b600c54604051636022a48560e01b81523360048201526000916001600160a01b031690636022a4859060240160206040518083038186803b158015611d8b57600080fd5b505afa158015611d9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc391906151e4565b600e546040516305d9a7ab60e11b815263ffffffff8084166004830152929350918b16916001600160a01b0390911690630bb34f569060240160206040518083038186803b158015611e1457600080fd5b505afa158015611e28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4c91906151e4565b63ffffffff1614611e9f5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f742070726f706f736520776974686f75742072657665616c696e676044820152606401610cb4565b611eab8686838c61428f565b611ee55760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195b1958dd195960aa1b6044820152606401610cb4565b600b54600c5460405162dd998160e01b815263ffffffff841660048201526001600160a01b039091169062dd99819060240160206040518083038186803b158015611f2f57600080fd5b505afa158015611f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f679190615125565b1015611fb55760405162461bcd60e51b815260206004820152601960248201527f7374616b652062656c6f77206d696e696d756d207374616b65000000000000006044820152606401610cb4565b63ffffffff8181166000908152600460205260409020548116908a1614156120125760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e481c1c9bdc1bdcd95960821b6044820152606401610cb4565b865188511461205c5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a5908189b1bd8dac81c1c9bdc1bdcd95960521b6044820152606401610cb4565b600e546040516370b9856360e11b815263ffffffff808c166004830152871660248201526000916001600160a01b03169063e1730ac69060440160206040518083038186803b1580156120ae57600080fd5b505afa1580156120c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e69190615125565b63ffffffff8b16600090815260036020526040902054909150612111576006805463ffffffff191690555b6040518060c001604052806001151581526020018363ffffffff1681526020018a815260200188815260200182815260200189815250600260008c63ffffffff1663ffffffff1681526020019081526020016000206000600660009054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160010190805190602001906121f8929190614e5c565b50606082015160028201556080820151600382015560a08201518051612228916004840191602090910190614f05565b505060065460009150612244908c9063ffffffff168a856145be565b63ffffffff8481166000908152600460205260409020805463ffffffff1916918e16919091179055905080156122a3576006546122889063ffffffff1660016158eb565b6006805463ffffffff191663ffffffff929092169190911790555b8263ffffffff167fb7d2284027e2ae07189ff137e4fec5f9193d8c785f72dbc2511ca59e7d5319f58c898d8c428f6040516122e39695949392919061582a565b60405180910390a25050505050505050505050565b60005460ff1661231a5760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908490610100900460ff16612332613a88565b63ffffffff168263ffffffff161461235c5760405162461bcd60e51b8152600401610cb49061570e565b61236581613a9b565b600581111561238457634e487b7160e01b600052602160045260246000fd5b8360058111156123a457634e487b7160e01b600052602160045260246000fd5b146123c15760405162461bcd60e51b8152600401610cb490615737565b600f546040805163618b0bb760e01b815290516001926001600160a01b03169163618b0bb7916004808301926020929190829003018186803b15801561240657600080fd5b505afa15801561241a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243e91906151ac565b61244891906159a3565b61ffff168561ffff1611156124905760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a59081b195859925960921b6044820152606401610cb4565b600e54604051631dab515760e21b815263ffffffff8816600482015261ffff871660248201526000916002916001600160a01b03909116906376ad455c9060440160206040518083038186803b1580156124e957600080fd5b505afa1580156124fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125219190615125565b61252b9190615959565b63ffffffff88166000908152600160208181526040808420338552909152909120600281015491015491925090816125915763ffffffff891660009081526001602090815260408083203384529091529020805461ffff191661ffff8a161790556125f9565b63ffffffff8916600090815260016020908152604080832033845290915290205461ffff8981169116146125f95760405162461bcd60e51b815260206004820152600f60248201526e0d8cac2cc92c840dad2e6dac2e8c6d608b1b6044820152606401610cb4565b60005b87518163ffffffff1610156128385781888263ffffffff168151811061263257634e487b7160e01b600052603260045260246000fd5b60200260200101511161267d5760405162461bcd60e51b8152602060048201526013602482015272039b7b93a32b22b30b63ab2901e1e90262b2b1606d1b6044820152606401610cb4565b878163ffffffff16815181106126a357634e487b7160e01b600052603260045260246000fd5b602002602001015191506000600e60009054906101000a90046001600160a01b03166001600160a01b0316635c809a238c8c8c8663ffffffff16815181106126fb57634e487b7160e01b600052603260045260246000fd5b60209081029190910101516040516001600160e01b031960e086901b16815263ffffffff93909316600484015261ffff9091166024830152604482015260640160206040518083038186803b15801561275357600080fd5b505afa158015612767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278b9190615125565b905061279781856158d3565b63ffffffff8c1660009081526001602090815260408083203384529091529020600301549094501580156127ca57508484115b1561282557888263ffffffff16815181106127f557634e487b7160e01b600052603260045260246000fd5b60209081029190910181015163ffffffff8d16600090815260018352604080822033835290935291909120600301555b508061283081615a7b565b9150506125fc565b5063ffffffff89166000908152600160208181526040808420338552909152918290209081018390556002018390555161ffff8916907ff7027a4896f62ae9d7300cb8dc18cb015f1a4450d90a6a108248a298ebce8b509061289d908c908b9061580b565b60405180910390a2505050505050505050565b60005460ff166128d25760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908290610100900460ff166128ea613a88565b63ffffffff168263ffffffff16146129145760405162461bcd60e51b8152600401610cb49061570e565b61291d81613a9b565b600581111561293c57634e487b7160e01b600052602160045260246000fd5b83600581111561295c57634e487b7160e01b600052602160045260246000fd5b146129795760405162461bcd60e51b8152600401610cb490615737565b505060408051608081018252600080825260208083018281528385018381526060850184815263ffffffff9890981684526001808452868520338652909352949092209251835461ffff191661ffff90911617835590519082015590516002820155915160039092019190915550565b60036020528160005260406000208181548110612a0557600080fd5b9060005260206000209060089182820401919006600402915091509054906101000a900463ffffffff1681565b600080516020615b38833981519152612a4a81613d2a565b50600b55565b60009182526008602090815260408084206001600160a01b0393909316845291905290205460ff1690565b600080516020615b38833981519152612a9381613d2a565b506009805460ff191660ff92909216919091179055565b60005460ff16612acc5760405162461bcd60e51b8152600401610cb4906156d7565b7f18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f612af681613d2a565b6000612b00613a88565b905060036000612b116001846159dd565b63ffffffff16815260208101919091526040016000205415801590612b485750600654600160201b9004600090810b900b60001914155b15612b6157612b61612b5b6001836159dd565b84613d37565b600f546040805163113df3d760e21b815290516000926001600160a01b0316916344f7cf5c916004808301926020929190829003018186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bde91906151e4565b9050612beb6001836159dd565b63ffffffff168163ffffffff1611612c6157600f60009054906101000a90046001600160a01b03166001600160a01b03166342e8e34e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612c4d57600080fd5b505af1158015610f50573d6000803e3d6000fd5b50505050565b600082815260086020526040902060010154612c8281613d2a565b611bfb8383614228565b600080516020615b38833981519152612ca481613d2a565b506009805460ff9092166101000261ff0019909216919091179055565b60005460ff16612ce35760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908590610100900460ff16612cfb613a88565b63ffffffff168263ffffffff1614612d255760405162461bcd60e51b8152600401610cb49061570e565b612d2e81613a9b565b6005811115612d4d57634e487b7160e01b600052602160045260246000fd5b836005811115612d6d57634e487b7160e01b600052602160045260246000fd5b14612d8a5760405162461bcd60e51b8152600401610cb490615737565b63ffffffff87166000908152600360205260408120805460ff8916908110612dc257634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8c8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff16612e225760405162461bcd60e51b8152600401610cb4906156a0565b600f546040516347d0c1c560e11b815261ffff881660048201526001600160a01b0390911690638fa1838a9060240160206040518083038186803b158015612e6957600080fd5b505afa158015612e7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ea191906150ed565b1561300a57600f54604051631bc8002760e11b815261ffff881660048201526000916001600160a01b031690633790004e9060240160206040518083038186803b158015612eee57600080fd5b505afa158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2691906151ac565b600e54604051631dab515760e21b815263ffffffff8c16600482015261ffff831660248201529192506000916001600160a01b03909116906376ad455c9060440160206040518083038186803b158015612f7f57600080fd5b505afa158015612f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb79190615125565b905080156130075760405162461bcd60e51b815260206004820152601d60248201527f446973707574653a2049442073686f756c642062652070726573656e740000006044820152606401610cb4565b50505b63ffffffff8089166000908152600260209081526040808320938516835292905220600101805461ffff881691908790811061305657634e487b7160e01b600052603260045260246000fd5b60009182526020909120601082040154600f9091166002026101000a900461ffff16146130c55760405162461bcd60e51b815260206004820152601760248201527f446973707574653a20494420616273656e74206f6e6c790000000000000000006044820152606401610cb4565b6040805163ffffffff8a16815260ff89166020820152908101869052339061ffff8816907f3ae0c7a5044017e0013cc6614c9e03c3f8369f35b1b815d800e4859c228d04109060600160405180910390a3610f50888883613b69565b60005460ff166131435760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908590610100900460ff1661315b613a88565b63ffffffff168263ffffffff16146131855760405162461bcd60e51b8152600401610cb49061570e565b61318e81613a9b565b60058111156131ad57634e487b7160e01b600052602160045260246000fd5b8360058111156131cd57634e487b7160e01b600052602160045260246000fd5b146131ea5760405162461bcd60e51b8152600401610cb490615737565b63ffffffff87166000908152600360205260408120805460ff891690811061322257634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8c8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff166132825760405162461bcd60e51b8152600401610cb4906156a0565b8486106132d15760405162461bcd60e51b815260206004820181905260248201527f696e64657831206e6f742067726561746572207468616e20696e6465783020306044820152606401610cb4565b63ffffffff808916600090815260026020908152604080832093851683529290522060010180548690811061331657634e487b7160e01b600052603260045260246000fd5b6000918252602080832060108304015463ffffffff8c81168552600280845260408087209288168752919093529093206001018054600f9093169091026101000a90920461ffff1691908890811061337e57634e487b7160e01b600052603260045260246000fd5b60009182526020909120601082040154600f9091166002026101000a900461ffff1610156133ee5760405162461bcd60e51b815260206004820152601a60248201527f4944206174206930206e6f74206774207468616e206f662069310000000000006044820152606401610cb4565b6040805163ffffffff8a16815260ff891660208201529081018790526060810186905233907f9f1915bb320aae8cfdf7c6a0f5a138ff0da41d0cfc97721d09ea59177d0c30259060800160405180910390a2610f50888883613b69565b60005460ff1661346d5760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908490610100900460ff16613485613a88565b63ffffffff168263ffffffff16146134af5760405162461bcd60e51b8152600401610cb49061570e565b6134b881613a9b565b60058111156134d757634e487b7160e01b600052602160045260246000fd5b8360058111156134f757634e487b7160e01b600052602160045260246000fd5b146135145760405162461bcd60e51b8152600401610cb490615737565b600e5463ffffffff8716600081815260016020908152604080832033845290915290819020549051631dab515760e21b8152600481019290925261ffff1660248201526001600160a01b03909116906376ad455c9060440160206040518083038186803b15801561358457600080fd5b505afa158015613598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135bc9190615125565b63ffffffff871660009081526001602090815260408083203384529091529020600201541461361c5760405162461bcd60e51b815260206004820152600c60248201526b5449522069732077726f6e6760a01b6044820152606401610cb4565b63ffffffff8616600090815260016020908152604080832033845290915290206002015461367e5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206469737075746560881b6044820152606401610cb4565b63ffffffff86166000908152600360205260408120805460ff88169081106136b657634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8b8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff166137165760405162461bcd60e51b8152600401610cb4906156a0565b63ffffffff8716600090815260016020908152604080832033845290915280822054600f54915163462f32c160e11b815261ffff9091166004820181905292916001600160a01b031690638c5e65829060240160206040518083038186803b15801561378157600080fd5b505afa158015613795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137b991906151ac565b63ffffffff808b16600090815260026020908152604080832088851684528252808320815160c081018352815460ff811615158252610100900490951685840152600181018054835181860281018601855281815297985094969194928601939192909183018282801561387457602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161383b5790505b505050505081526020016002820154815260200160038201548152602001600482018054806020026020016040519081016040528092919081815260200182805480156138e057602002820191906000526020600020905b8154815260200190600101908083116138cc575b50505050508152505090508161ffff168160400151898151811061391457634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff161461396d5760405162461bcd60e51b815260206004820152601760248201527f57726f6e6720436f6c6c20496e646578207061737365640000000000000000006044820152606401610cb4565b63ffffffff808b166000908152600260209081526040808320938816835292905290812060040180548a9081106139b457634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015463ffffffff8e168352600182526040808420338552909252912060030154909150811415613a325760405162461bcd60e51b815260206004820181905260248201527f426c6f636b2070726f706f73656420776974682073616d65206d656469616e736044820152606401610cb4565b6040805163ffffffff8d16815260ff8c1660208201529081018a905233907ff7cac5758f33a2ff5e5f8054ed55fa64c70cd7fa0a99c510abc4be3b5421a6489060600160405180910390a2611a468b8b87613b69565b6000613a966104b04261596d565b905090565b6000818160ff8216613ab060056104b0615938565b613aba91906159a3565b905061ffff8116613ace60056104b0615938565b613adc9061ffff1642615abf565b1180613b04575060ff8216613af460056104b0615938565b613b029061ffff1642615abf565b105b15613b13575060059392505050565b60006005613b23816104b0615938565b613b319061ffff1642615959565b613b3b9190615abf565b90508060ff166005811115613b6057634e487b7160e01b600052602160045260246000fd5b95945050505050565b63ffffffff83811660008181526002602090815260408083209486168352938152838220805460ff19169055918152600390915290812054600654909160ff858116600160201b90930490910b161415613ca9576006805464ff00000000191664ff000000001790556000613bdf846001615913565b90505b8160ff168160ff161015613ca75763ffffffff85166000908152600360205260408120805460ff8416908110613c2857634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8a8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff1615613c9457506006805464ff000000001916600160201b60ff600085900b1602179055613ca7565b5080613c9f81615a9f565b915050613be2565b505b63ffffffff848116600081815260026020908152604080832087861684529091529081902054600c5491516323dd933d60e21b81526004810193909352610100900490921660248201819052336044830152916001600160a01b031690638f764cf4906064015b600060405180830381600087803b15801561148957600080fd5b613d348133614bc3565b50565b63ffffffff821660009081526003602052604081206006548154600160201b909104830b60ff16908110613d7b57634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff878116808652600284526040808720600460079788160261010090810a909504841680895290865281882092885295909452929094208254815460ff909116151560ff19821681178355845484900490961690920264ffffffff001990951664ffffffffff199092169190911793909317835560018082018054939550919392613e1e929184019190614f40565b5060028201548160020155600382015481600301556004820181600401908054613e49929190614f8e565b50505063ffffffff831660009081526007602090815260408083209051613e769287926004019101615623565b60408051601f19818403018152828252805160209182012063ffffffff80891660009081526007845284812060c087018652805460ff811615158852610100900490921686850152600182018054865181870281018701885281815294985091969592949286019392909190830182828015613f3957602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411613f005790505b50505050508152602001600282015481526020016003820154815260200160048201805480602002602001604051908101604052809291908181526020018280548015613fa557602002820191906000526020600020905b815481526020019060010190808311613f91575b505050505081525050905060005b816040015151811015614049578160a001518181518110613fe457634e487b7160e01b600052603260045260246000fd5b6020026020010151600560008460400151848151811061401457634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff1661ffff16815260200190815260200160002081905550808061404190615a60565b915050613fb3565b50806020015163ffffffff167f3e421e040ebd474d10ce46694a45bec4208dbbd12ee37843712e352fb009419e868360400151428560a0015160405161409294939291906157c9565b60405180910390a2600e54604051631ddd754160e31b8152600481018490526001600160a01b039091169063eeebaa0890602401600060405180830381600087803b1580156140e057600080fd5b505af11580156140f4573d6000803e3d6000fd5b5050600d54604051623e8fc760e31b815263ffffffff8089166004830152891660248201526001600160a01b0390911692506301f47e389150604401600060405180830381600087803b15801561414a57600080fd5b505af115801561415e573d6000803e3d6000fd5b50506010546040516001621789db60e01b0319815263ffffffff89166004820152602481018690526001600160a01b03909116925063ffe876259150604401613d10565b6141ac8282612a50565b611c7a5760008281526008602090815260408083206001600160a01b03851684529091529020805460ff191660011790556141e43390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6142328282612a50565b15611c7a5760008281526008602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000805460ff166142b25760405162461bcd60e51b8152600401610cb4906156d7565b600e54604080516304ea562760e21b815290516000926001600160a01b0316916313a9589c916004808301926020929190829003018186803b1580156142f757600080fd5b505afa15801561430b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061432f9190615125565b90506000614365828860405160200161434a91815260200190565b60405160208183030381529060405280519060200120614c27565b905060006143fe600c60009054906101000a90046001600160a01b03166001600160a01b031663bc788d466040518163ffffffff1660e01b815260040160206040518083038186803b1580156143ba57600080fd5b505afa1580156143ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143f291906151e4565b63ffffffff1683614c66565b905063ffffffff86166144128260016158d3565b1461442357600093505050506145b6565b6040805163ffffffff8816602082015290810189905260009061444a90859060600161434a565b9050600061445c600160201b83614c66565b600e546040516370b9856360e11b815263ffffffff808b1660048301528c1660248201529192506000916001600160a01b039091169063e1730ac69060440160206040518083038186803b1580156144b357600080fd5b505afa1580156144c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144eb9190615125565b600e546040516370b9856360e11b815263ffffffff808c1660048301528c1660248201529192506000916001600160a01b039091169063e1730ac69060440160206040518083038186803b15801561454257600080fd5b505afa158015614556573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061457a9190615125565b905061458a81600160201b615984565b6145948385615984565b11156145aa5760009750505050505050506145b6565b60019750505050505050505b949350505050565b63ffffffff841660009081526003602052604081205460ff811661463457505063ffffffff84811660009081526003602090815260408220805460018082018355918452919092206008820401805460079092166004026101000a90930219169091556006805464ff00000000191690556145b6565b63ffffffff8616600090815260026020908152604080832060039092528220805486939190829061467557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020019081526020016000206003015411156146c95760009150506145b6565b63ffffffff8616600090815260026020908152604080832060039092528220805486939190829061470a57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060030154101561482f5760005b8160ff168160ff1610156147d75763ffffffff8716600090815260036020526040902080548061479757634e487b7160e01b600052603160045260246000fd5b600082815260209020600860001990920191820401805463ffffffff600460078516026101000a02191690559055806147cf81615a9f565b915050614757565b50505063ffffffff80851660009081526003602090815260408220805460018181018355918452919092206008820401805487851660046007909416939093026101000a9283029290940219909316179091556145b6565b60005b8160ff168160ff161015614b3e5763ffffffff871660009081526002602090815260408083206003909252822080548893919060ff861690811061488657634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020600201541115614b2c5763ffffffff8088166000908152600360209081526040822080546001818101835591845291909220600882040180548a851660046007909416939093026101000a92830292909402199093161790915561492b908390615913565b9150600061493a6001846159fa565b60ff1690505b8160ff16811115614a335763ffffffff8816600090815260036020526040902061496b6001836159c6565b8154811061498957634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff16600360008a63ffffffff1663ffffffff16815260200190815260200160002082815481106149ed57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508080614a2b90615a49565b915050614940565b5063ffffffff87166000908152600360205260409020805487919060ff8416908110614a6f57634e487b7160e01b600052603260045260246000fd5b600091825260208083206008830401805460079093166004026101000a63ffffffff818102199094169584160294909417909355600954908a1682526003909252604090205460ff9091161015614b215763ffffffff87166000908152600360205260409020805480614af257634e487b7160e01b600052603160045260246000fd5b600082815260209020600860001990920191820401805463ffffffff600460078516026101000a021916905590555b6001925050506145b6565b80614b3681615a9f565b915050614832565b5060095463ffffffff871660009081526003602052604090205460ff9091161115614bba57505063ffffffff80851660009081526003602090815260408220805460018181018355918452919092206008820401805487851660046007909416939093026101000a9283029290940219909316179091556145b6565b50949350505050565b614bcd8282612a50565b611c7a57614be5816001600160a01b03166014614c73565b614bf0836020614c73565b604051602001614c019291906155ae565b60408051601f198184030181529082905262461bcd60e51b8252610cb49160040161566d565b6000808383604051602001614c46929190918252602082015260400190565b60408051808303601f190181529190528051602090910120949350505050565b6000816145b68482615abf565b60606000614c82836002615984565b614c8d9060026158d3565b67ffffffffffffffff811115614cb357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614cdd576020820181803683370190505b509050600360fc1b81600081518110614d0657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110614d4357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000614d67846002615984565b614d729060016158d3565b90505b6001811115614e06576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110614db457634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110614dd857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93614dff81615a49565b9050614d75565b508315614e555760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610cb4565b9392505050565b82805482825590600052602060002090600f01601090048101928215614ef55791602002820160005b83821115614ec557835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302614e85565b8015614ef35782816101000a81549061ffff0219169055600201602081600101049283019260010302614ec5565b505b50614f01929150614fcd565b5090565b828054828255906000526020600020908101928215614ef5579160200282015b82811115614ef5578251825591602001919060010190614f25565b82805482825590600052602060002090600f01601090048101928215614ef557600052602060002091600f016010900482015b82811115614ef5578254825591600101919060010190614f73565b828054828255906000526020600020908101928215614ef557600052602060002091820182811115614ef5578254825591600101919060010190614f73565b5b80821115614f015760008155600101614fce565b80356001600160a01b0381168114614ff957600080fd5b919050565b600082601f83011261500e578081fd5b8135602061502361501e836158af565b61587e565b80838252828201915082860187848660051b8901011115615042578586fd5b855b8581101561506057813584529284019290840190600101615044565b5090979650505050505050565b8035614ff981615b25565b803560ff81168114614ff957600080fd5b600080600080600060a086880312156150a0578081fd5b6150a986614fe2565b94506150b760208701614fe2565b93506150c560408701614fe2565b92506150d360608701614fe2565b91506150e160808701614fe2565b90509295509295909350565b6000602082840312156150fe578081fd5b81518015158114614e55578182fd5b60006020828403121561511e578081fd5b5035919050565b600060208284031215615136578081fd5b5051919050565b6000806040838503121561514f578182fd5b8235915061515f60208401614fe2565b90509250929050565b600060208284031215615179578081fd5b81356001600160e01b031981168114614e55578182fd5b6000602082840312156151a1578081fd5b8135614e5581615b15565b6000602082840312156151bd578081fd5b8151614e5581615b15565b6000602082840312156151d9578081fd5b8135614e5581615b25565b6000602082840312156151f5578081fd5b8151614e5581615b25565b60008060408385031215615212578182fd5b823561521d81615b25565b915061515f60208401614fe2565b600080600080600060a08688031215615242578283fd5b853561524d81615b25565b945060208681013567ffffffffffffffff8082111561526a578586fd5b818901915089601f83011261527d578586fd5b813561528b61501e826158af565b8082825285820191508585018d878560051b88010111156152aa57898afd5b8995505b838610156152d55780356152c181615b15565b8352600195909501949186019186016152ae565b509850505060408901359250808311156152ed578586fd5b50506152fb88828901614ffe565b935050606086013591506150e16080870161506d565b600080600060608486031215615325578081fd5b833561533081615b25565b9250602084013561534081615b15565b9150604084013567ffffffffffffffff81111561535b578182fd5b61536786828701614ffe565b9150509250925092565b60008060408385031215615383578182fd5b823561538e81615b25565b946020939093013593505050565b600080604083850312156153ae578182fd5b82356153b981615b25565b915060208301356153c981615b25565b809150509250929050565b6000806000606084860312156153e8578081fd5b83356153f381615b25565b925061540160208501615078565b9150604084013561541181615b15565b809150509250925092565b60008060008060808587031215615431578182fd5b843561543c81615b25565b935061544a60208601615078565b9250604085013561545a81615b15565b9396929550929360600135925050565b60008060006060848603121561547e578081fd5b833561548981615b25565b925061549760208501615078565b9150604084013590509250925092565b600080600080608085870312156154bc578182fd5b84356154c781615b25565b93506154d560208601615078565b93969395505050506040820135916060013590565b6000806000606084860312156154fe578081fd5b833561550981615b25565b925061551760208501615078565b9150604084013561541181615b25565b600060208284031215615538578081fd5b614e5582615078565b6000815180845260208085019450808401835b8381101561557457815161ffff1687529582019590820190600101615554565b509495945050505050565b6000815180845260208085019450808401835b8381101561557457815187529582019590820190600101615592565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516155e6816017850160208801615a1d565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351615617816028840160208801615a1d565b01602801949350505050565b63ffffffff60e01b8360e01b16815260006004820183548483526020808420845b8381101561566057815485529382019360019182019101615644565b5092979650505050505050565b602081526000825180602084015261568c816040850160208701615a1d565b601f01601f19169190910160400192915050565b6020808252601f908201527f426c6f636b20616c726561647920686173206265656e20646973707574656400604082015260600190565b6020808252601e908201527f436f6e74726163742073686f756c6420626520696e697469616c697a65640000604082015260600190565b6020808252600f908201526e0d2dcc6dee4e4cac6e840cae0dec6d608b1b604082015260600190565b6020808252600f908201526e696e636f727265637420737461746560881b604082015260600190565b6020815281511515602082015263ffffffff60208301511660408201526000604083015160c0606084015261579860e0840182615541565b905060608401516080840152608084015160a084015260a0840151601f198483030160c0850152613b60828261557f565b63ffffffff851681526080602082015260006157e86080830186615541565b8460408401528281036060840152615800818561557f565b979650505050505050565b63ffffffff831681526040602082015260006145b6604083018461557f565b600063ffffffff808916835280881660208401525060c0604083015261585360c0830187615541565b85606084015284608084015282810360a0840152615871818561557f565b9998505050505050505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156158a7576158a7615aff565b604052919050565b600067ffffffffffffffff8211156158c9576158c9615aff565b5060051b60200190565b600082198211156158e6576158e6615ad3565b500190565b600063ffffffff80831681851680830382111561590a5761590a615ad3565b01949350505050565b600060ff821660ff84168060ff0382111561593057615930615ad3565b019392505050565b600061ffff8084168061594d5761594d615ae9565b92169190910492915050565b60008261596857615968615ae9565b500490565b600063ffffffff8084168061594d5761594d615ae9565b600081600019048311821515161561599e5761599e615ad3565b500290565b600061ffff838116908316818110156159be576159be615ad3565b039392505050565b6000828210156159d8576159d8615ad3565b500390565b600063ffffffff838116908316818110156159be576159be615ad3565b600060ff821660ff841680821015615a1457615a14615ad3565b90039392505050565b60005b83811015615a38578181015183820152602001615a20565b83811115612c615750506000910152565b600081615a5857615a58615ad3565b506000190190565b6000600019821415615a7457615a74615ad3565b5060010190565b600063ffffffff80831681811415615a9557615a95615ad3565b6001019392505050565b600060ff821660ff811415615ab657615ab6615ad3565b60010192915050565b600082615ace57615ace615ae9565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b61ffff81168114613d3457600080fd5b63ffffffff81168114613d3457600080fdfe71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1a2646970667358221220b0227113721919669b803359160e259183e96a1762f35c8d11f91a30f7b614d564736f6c63430008040033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106103ba5760003560e01c806367ba825c116101f4578063bd8595841161011a578063dc82a745116100ad578063ef8bf6841161007c578063ef8bf68414610a93578063f36c8f5c14610aba578063f454620f14610acf578063fccc281314610ae257600080fd5b8063dc82a74514610a34578063dde784d514610a47578063ed6c935d14610a5a578063edaafe2014610a8157600080fd5b8063c9e99c25116100e9578063c9e99c25146109d4578063d547741f146109e7578063da984295146109fa578063db7b499614610a2157600080fd5b8063bd85958414610927578063be436df114610931578063bf897a9a14610957578063c1a2bab51461096a57600080fd5b80638c80fd90116101925780639fdf8469116101615780639fdf8469146108c9578063a217fddf146108dc578063ac4746ab146108e4578063b0daafef1461090057600080fd5b80638c80fd901461084857806391d148541461085b5780639493aff81461086e57806397788d06146108b657600080fd5b806381d96db8116101ce57806381d96db8146107cb57806385a9777c146107de5780638622f3a9146107f1578063885fc0941461082157600080fd5b806367ba825c1461076d5780637542ff9514610791578063776076e7146107a457600080fd5b80632d93b9a0116102e457806342a1035f116102775780634a8aace5116102465780634a8aace5146106a65780635b070278146106b95780635cd0783e146106e0578063622f93301461074657600080fd5b806342a1035f1461064957806342c1e58714610659578063474a1ae11461066c5780634912b72a1461067f57600080fd5b8063375b3c0a116102b3578063375b3c0a146105e5578063379597e0146105ee578063389ed267146105fb57806341d296f71461062257600080fd5b80632d93b9a0146105715780632f2ff15d146105985780632f50bcc4146105ab57806336568abe146105d257600080fd5b8063123047011161035c5780631a18e7071161032b5780631a18e707146104ed5780631bea14e9146105005780632023d0be14610513578063248a9ca31461054e57600080fd5b8063123047011461049f5780631459457a146104bf57806316391253146104d2578063171fe294146104da57600080fd5b80630ac168a1116103985780630ac168a1146104215780630c92ad7d146104385780630f4ef8a61461044d57806311e29f521461047857600080fd5b806301ffc9a7146103bf57806305db56df146103e757806309f2f13d14610401575b600080fd5b6103d26103cd366004615168565b610aeb565b60405190151581526020015b60405180910390f35b6103ef600581565b60405160ff90911681526020016103de565b61041461040f36600461539c565b610b22565b6040516103de9190615760565b61042a600a5481565b6040519081526020016103de565b61044b6104463660046154ea565b610c92565b005b600d54610460906001600160a01b031681565b6040516001600160a01b0390911681526020016103de565b60065461048c90600160201b900460000b81565b60405160009190910b81526020016103de565b61042a6104ad366004615190565b60056020526000908152604090205481565b61044b6104cd366004615089565b610f5a565b61044b61105d565b61044b6104e83660046153d4565b6114a9565b61044b6104fb36600461510d565b611a53565b61041461050e3660046151c8565b611a71565b6105396105213660046151c8565b60046020526000908152604090205463ffffffff1681565b60405163ffffffff90911681526020016103de565b61042a61055c36600461510d565b60009081526008602052604090206001015490565b61042a7f912208965b92edeb3eb82a612c87b38b5e844f7539cb396f0d08ec012e511b0781565b61044b6105a636600461513d565b611bd6565b61042a7f46aaf8a125792dfff6db03d74f94fe1acaf55c8cab22f65297c15809c364465c81565b61044b6105e036600461513d565b611c00565b61042a600b5481565b6009546103ef9060ff1681565b61042a7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d81565b61042a7f91f5d9ea80c4d04985e669bc72870410b28b57afdf61c0d50d377766d86a374881565b6006546105399063ffffffff1681565b600e54610460906001600160a01b031681565b61044b61067a36600461522b565b611c7e565b61042a7f6b7da7a33355c6e035439beb2ac6a052f1558db73f08690b1c9ef5a4e838959781565b61044b6106b4366004615311565b6122f8565b61042a7fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc81565b61071f6106ee3660046151c8565b60076020526000908152604090208054600282015460039092015460ff82169261010090920463ffffffff16919084565b60408051941515855263ffffffff90931660208501529183015260608201526080016103de565b61042a7f518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba804381565b61042a61077b366004615190565b61ffff1660009081526005602052604090205490565b600c54610460906001600160a01b031681565b61042a7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80481565b61044b6107d93660046151c8565b6128b0565b6105396107ec366004615371565b6129e9565b6103d26107ff3660046151c8565b63ffffffff908116600090815260076020526040902054610100900416151590565b61042a7fa3a75e7cd2b78fcc3ae2046ab93bfa4ac0b87ed7ea56646a312cbcb73eabd29481565b61044b61085636600461510d565b612a32565b6103d261086936600461513d565b612a50565b61071f61087c36600461539c565b6002602081815260009384526040808520909152918352912080549181015460039091015460ff831692610100900463ffffffff16919084565b61044b6108c4366004615527565b612a7b565b600f54610460906001600160a01b031681565b61042a600081565b6108ed6104b081565b60405161ffff90911681526020016103de565b61042a7ff31dda80d37c96a1a0852ace387dda52a75487d7d4eb74895e749ede3e0987b481565b6105396298968081565b6103ef61093f3660046151c8565b63ffffffff1660009081526003602052604090205490565b601054610460906001600160a01b031681565b6109af610978366004615200565b60016020818152600093845260408085209091529183529120805491810154600282015460039092015461ffff9093169290919084565b6040805161ffff909516855260208501939093529183015260608201526080016103de565b61044b6109e23660046151c8565b612aaa565b61044b6109f536600461513d565b612c67565b61042a7f18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f81565b61044b610a2f366004615527565b612c8c565b61044b610a4236600461541c565b612cc1565b61044b610a553660046154a7565b613121565b61042a7fca51085219bef34771da292cb24ee4fcf0ae6bdba1a62c17d1fb7d58be80288381565b6009546103ef90610100900460ff1681565b61042a7fcabcaf259dd9a27f23bd8a92bacd65983c2ebf027c853f89f941715905271a8d81565b61042a600080516020615b3883398151915281565b61044b610add36600461546a565b61344b565b61046061dead81565b60006001600160e01b03198216637965db0b60e01b1480610b1c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b610b636040518060c00160405280600015158152602001600063ffffffff168152602001606081526020016000815260200160008152602001606081525090565b63ffffffff80841660009081526002602090815260408083208685168452825291829020825160c081018452815460ff81161515825261010090049094168483015260018101805484518185028101850186528181529294860193830182828015610c1557602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411610bdc5790505b50505050508152602001600282015481526020016003820154815260200160048201805480602002602001604051908101604052809291908181526020018280548015610c8157602002820191906000526020600020905b815481526020019060010190808311610c6d575b505050505081525050905092915050565b60005460ff16610cbd5760405162461bcd60e51b8152600401610cb4906156d7565b60405180910390fd5b6009546003908490610100900460ff16610cd5613a88565b63ffffffff168263ffffffff1614610cff5760405162461bcd60e51b8152600401610cb49061570e565b610d0881613a9b565b6005811115610d2757634e487b7160e01b600052602160045260246000fd5b836005811115610d4757634e487b7160e01b600052602160045260246000fd5b14610d645760405162461bcd60e51b8152600401610cb490615737565b63ffffffff86166000908152600360205260408120805460ff8816908110610d9c57634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8b8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff16610dfc5760405162461bcd60e51b8152600401610cb4906156a0565b600e546040516370b9856360e11b815263ffffffff808a166004830152871660248201526000916001600160a01b03169063e1730ac69060440160206040518083038186803b158015610e4e57600080fd5b505afa158015610e62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e869190615125565b63ffffffff808a166000908152600260209081526040808320938716835292905220600301549091508111610efd5760405162461bcd60e51b815260206004820152601760248201527f496e76616c69642064697370757465203a205374616b650000000000000000006044820152606401610cb4565b6040805163ffffffff8a8116825260ff8a1660208301523392908916917fe236f3a69f3f4080c6762e1b5212e97fe7b5ff198bd2612d590b3bae699389e2910160405180910390a3610f50888884613b69565b5050505050505050565b600054610100900460ff1680610f73575060005460ff16155b610fbf5760405162461bcd60e51b815260206004820152601c60248201527f636f6e747261637420616c726561647920696e697469616c697a6564000000006044820152606401610cb4565b600054610100900460ff16158015610fe1576000805461ffff19166101011790555b6000610fec81613d2a565b50600c80546001600160a01b03199081166001600160a01b0389811691909117909255600d80548216888416179055600e80548216878416179055600f80548216868416179055601080549091169184169190911790558015611055576000805461ff00191690555b505050505050565b60005460ff1661107f5760405162461bcd60e51b8152600401610cb4906156d7565b600954600490610100900460ff1661109681613a9b565b60058111156110b557634e487b7160e01b600052602160045260246000fd5b8260058111156110d557634e487b7160e01b600052602160045260246000fd5b146110f25760405162461bcd60e51b8152600401610cb490615737565b60006110fc613a88565b600c54604051636022a48560e01b81523360048201529192506000916001600160a01b0390911690636022a4859060240160206040518083038186803b15801561114557600080fd5b505afa158015611159573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117d91906151e4565b905060008163ffffffff16116111d55760405162461bcd60e51b815260206004820152601d60248201527f537472756374732e5374616b657220646f6573206e6f742065786973740000006044820152606401610cb4565b63ffffffff8083166000908152600760205260409020546101009004161561123f5760405162461bcd60e51b815260206004820152601760248201527f426c6f636b20616c726561647920636f6e6669726d65640000000000000000006044820152606401610cb4565b63ffffffff8216600090815260036020526040902054158015906112755750600654600160201b9004600090810b900b60001914155b156113a75763ffffffff82166000908152600260209081526040808320600390925282206006548154849291600160201b9004830b60ff169081106112ca57634e487b7160e01b600052603260045260246000fd5b60009182526020808320600883040154600790921660040261010090810a90920463ffffffff90811685529084019490945260409092019020540481169150821681146113595760405162461bcd60e51b815260206004820152601960248201527f426c6f636b2050726f706f736572206d69736d617463686573000000000000006044820152606401610cb4565b6040805163ffffffff85811682524260208301528416917f6bf7d26513a0f410d2e9f5e8e878ef1ff0ce51b47d75f0c221cb597878baaa73910160405180910390a26113a58382613d37565b505b600f546040805163113df3d760e21b815290516000926001600160a01b0316916344f7cf5c916004808301926020929190829003018186803b1580156113ec57600080fd5b505afa158015611400573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142491906151e4565b90508263ffffffff168163ffffffff16116114a257600f60009054906101000a90046001600160a01b03166001600160a01b03166342e8e34e6040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561148957600080fd5b505af115801561149d573d6000803e3d6000fd5b505050505b5050505050565b60005460ff166114cb5760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908490610100900460ff166114e3613a88565b63ffffffff168263ffffffff161461150d5760405162461bcd60e51b8152600401610cb49061570e565b61151681613a9b565b600581111561153557634e487b7160e01b600052602160045260246000fd5b83600581111561155557634e487b7160e01b600052602160045260246000fd5b146115725760405162461bcd60e51b8152600401610cb490615737565b63ffffffff86166000908152600360205260408120805460ff88169081106115aa57634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8b8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff1661160a5760405162461bcd60e51b8152600401610cb4906156a0565b600f54604051631bc8002760e11b815261ffff871660048201526000916001600160a01b031690633790004e9060240160206040518083038186803b15801561165257600080fd5b505afa158015611666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061168a91906151ac565b600e54604051631dab515760e21b815263ffffffff8b16600482015261ffff831660248201529192506000916001600160a01b03909116906376ad455c9060440160206040518083038186803b1580156116e357600080fd5b505afa1580156116f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171b9190615125565b90508061176a5760405162461bcd60e51b815260206004820152601c60248201527f446973707574653a2049442073686f756c6420626520616273656e74000000006044820152606401610cb4565b63ffffffff808a16600090815260026020908152604080832087851684528252808320815160c081018352815460ff811615158252610100900490951685840152600181018054835181860281018601855281815295969592949386019383018282801561181f57602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff16815260200190600201906020826001010492830192600103820291508084116117e65790505b5050505050815260200160028201548152602001600382015481526020016004820180548060200260200160405190810160405280929190818152602001828054801561188b57602002820191906000526020600020905b815481526020019060010190808311611877575b50505091909252505050604081015151909150600190156119a55760008060018460400151516118bb91906159c6565b90505b8181111561196257600060026118d484846159c6565b6118de9190615959565b6118e890836159c6565b905060008560400151828151811061191057634e487b7160e01b600052603260045260246000fd5b602002602001015190508c61ffff168161ffff16141561193557600094505050611962565b8c61ffff168161ffff16101561194d5781935061195b565b6119586001836159c6565b92505b50506118be565b8a61ffff168460400151838151811061198b57634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff1614156119a257600092505b50505b806119f25760405162461bcd60e51b815260206004820152601860248201527f446973707574653a2049442070726573656e74206f6e6c7900000000000000006044820152606401610cb4565b6040805163ffffffff8d16815260ff8c166020820152339161ffff8c16917febc0bc7a021fb6273a69f0d80c14d8489e54d04923760056155a184100fbca42910160405180910390a3611a468b8b87613b69565b5050505050505050505050565b600080516020615b38833981519152611a6b81613d2a565b50600a55565b611ab26040518060c00160405280600015158152602001600063ffffffff168152602001606081526020016000815260200160008152602001606081525090565b63ffffffff808316600090815260076020908152604091829020825160c081018452815460ff81161515825261010090049094168483015260018101805484518185028101850186528181529294860193830182828015611b5a57602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411611b215790505b50505050508152602001600282015481526020016003820154815260200160048201805480602002602001604051908101604052809291908181526020018280548015611bc657602002820191906000526020600020905b815481526020019060010190808311611bb2575b5050505050815250509050919050565b600082815260086020526040902060010154611bf181613d2a565b611bfb83836141a2565b505050565b6001600160a01b0381163314611c705760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610cb4565b611c7a8282614228565b5050565b60005460ff16611ca05760405162461bcd60e51b8152600401610cb4906156d7565b6009546002908690610100900460ff16611cb8613a88565b63ffffffff168263ffffffff1614611ce25760405162461bcd60e51b8152600401610cb49061570e565b611ceb81613a9b565b6005811115611d0a57634e487b7160e01b600052602160045260246000fd5b836005811115611d2a57634e487b7160e01b600052602160045260246000fd5b14611d475760405162461bcd60e51b8152600401610cb490615737565b600c54604051636022a48560e01b81523360048201526000916001600160a01b031690636022a4859060240160206040518083038186803b158015611d8b57600080fd5b505afa158015611d9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc391906151e4565b600e546040516305d9a7ab60e11b815263ffffffff8084166004830152929350918b16916001600160a01b0390911690630bb34f569060240160206040518083038186803b158015611e1457600080fd5b505afa158015611e28573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e4c91906151e4565b63ffffffff1614611e9f5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f742070726f706f736520776974686f75742072657665616c696e676044820152606401610cb4565b611eab8686838c61428f565b611ee55760405162461bcd60e51b815260206004820152600b60248201526a1b9bdd08195b1958dd195960aa1b6044820152606401610cb4565b600b54600c5460405162dd998160e01b815263ffffffff841660048201526001600160a01b039091169062dd99819060240160206040518083038186803b158015611f2f57600080fd5b505afa158015611f43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f679190615125565b1015611fb55760405162461bcd60e51b815260206004820152601960248201527f7374616b652062656c6f77206d696e696d756d207374616b65000000000000006044820152606401610cb4565b63ffffffff8181166000908152600460205260409020548116908a1614156120125760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e481c1c9bdc1bdcd95960821b6044820152606401610cb4565b865188511461205c5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a5908189b1bd8dac81c1c9bdc1bdcd95960521b6044820152606401610cb4565b600e546040516370b9856360e11b815263ffffffff808c166004830152871660248201526000916001600160a01b03169063e1730ac69060440160206040518083038186803b1580156120ae57600080fd5b505afa1580156120c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e69190615125565b63ffffffff8b16600090815260036020526040902054909150612111576006805463ffffffff191690555b6040518060c001604052806001151581526020018363ffffffff1681526020018a815260200188815260200182815260200189815250600260008c63ffffffff1663ffffffff1681526020019081526020016000206000600660009054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548163ffffffff021916908363ffffffff16021790555060408201518160010190805190602001906121f8929190614e5c565b50606082015160028201556080820151600382015560a08201518051612228916004840191602090910190614f05565b505060065460009150612244908c9063ffffffff168a856145be565b63ffffffff8481166000908152600460205260409020805463ffffffff1916918e16919091179055905080156122a3576006546122889063ffffffff1660016158eb565b6006805463ffffffff191663ffffffff929092169190911790555b8263ffffffff167fb7d2284027e2ae07189ff137e4fec5f9193d8c785f72dbc2511ca59e7d5319f58c898d8c428f6040516122e39695949392919061582a565b60405180910390a25050505050505050505050565b60005460ff1661231a5760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908490610100900460ff16612332613a88565b63ffffffff168263ffffffff161461235c5760405162461bcd60e51b8152600401610cb49061570e565b61236581613a9b565b600581111561238457634e487b7160e01b600052602160045260246000fd5b8360058111156123a457634e487b7160e01b600052602160045260246000fd5b146123c15760405162461bcd60e51b8152600401610cb490615737565b600f546040805163618b0bb760e01b815290516001926001600160a01b03169163618b0bb7916004808301926020929190829003018186803b15801561240657600080fd5b505afa15801561241a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243e91906151ac565b61244891906159a3565b61ffff168561ffff1611156124905760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a59081b195859925960921b6044820152606401610cb4565b600e54604051631dab515760e21b815263ffffffff8816600482015261ffff871660248201526000916002916001600160a01b03909116906376ad455c9060440160206040518083038186803b1580156124e957600080fd5b505afa1580156124fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125219190615125565b61252b9190615959565b63ffffffff88166000908152600160208181526040808420338552909152909120600281015491015491925090816125915763ffffffff891660009081526001602090815260408083203384529091529020805461ffff191661ffff8a161790556125f9565b63ffffffff8916600090815260016020908152604080832033845290915290205461ffff8981169116146125f95760405162461bcd60e51b815260206004820152600f60248201526e0d8cac2cc92c840dad2e6dac2e8c6d608b1b6044820152606401610cb4565b60005b87518163ffffffff1610156128385781888263ffffffff168151811061263257634e487b7160e01b600052603260045260246000fd5b60200260200101511161267d5760405162461bcd60e51b8152602060048201526013602482015272039b7b93a32b22b30b63ab2901e1e90262b2b1606d1b6044820152606401610cb4565b878163ffffffff16815181106126a357634e487b7160e01b600052603260045260246000fd5b602002602001015191506000600e60009054906101000a90046001600160a01b03166001600160a01b0316635c809a238c8c8c8663ffffffff16815181106126fb57634e487b7160e01b600052603260045260246000fd5b60209081029190910101516040516001600160e01b031960e086901b16815263ffffffff93909316600484015261ffff9091166024830152604482015260640160206040518083038186803b15801561275357600080fd5b505afa158015612767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061278b9190615125565b905061279781856158d3565b63ffffffff8c1660009081526001602090815260408083203384529091529020600301549094501580156127ca57508484115b1561282557888263ffffffff16815181106127f557634e487b7160e01b600052603260045260246000fd5b60209081029190910181015163ffffffff8d16600090815260018352604080822033835290935291909120600301555b508061283081615a7b565b9150506125fc565b5063ffffffff89166000908152600160208181526040808420338552909152918290209081018390556002018390555161ffff8916907ff7027a4896f62ae9d7300cb8dc18cb015f1a4450d90a6a108248a298ebce8b509061289d908c908b9061580b565b60405180910390a2505050505050505050565b60005460ff166128d25760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908290610100900460ff166128ea613a88565b63ffffffff168263ffffffff16146129145760405162461bcd60e51b8152600401610cb49061570e565b61291d81613a9b565b600581111561293c57634e487b7160e01b600052602160045260246000fd5b83600581111561295c57634e487b7160e01b600052602160045260246000fd5b146129795760405162461bcd60e51b8152600401610cb490615737565b505060408051608081018252600080825260208083018281528385018381526060850184815263ffffffff9890981684526001808452868520338652909352949092209251835461ffff191661ffff90911617835590519082015590516002820155915160039092019190915550565b60036020528160005260406000208181548110612a0557600080fd5b9060005260206000209060089182820401919006600402915091509054906101000a900463ffffffff1681565b600080516020615b38833981519152612a4a81613d2a565b50600b55565b60009182526008602090815260408084206001600160a01b0393909316845291905290205460ff1690565b600080516020615b38833981519152612a9381613d2a565b506009805460ff191660ff92909216919091179055565b60005460ff16612acc5760405162461bcd60e51b8152600401610cb4906156d7565b7f18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f612af681613d2a565b6000612b00613a88565b905060036000612b116001846159dd565b63ffffffff16815260208101919091526040016000205415801590612b485750600654600160201b9004600090810b900b60001914155b15612b6157612b61612b5b6001836159dd565b84613d37565b600f546040805163113df3d760e21b815290516000926001600160a01b0316916344f7cf5c916004808301926020929190829003018186803b158015612ba657600080fd5b505afa158015612bba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bde91906151e4565b9050612beb6001836159dd565b63ffffffff168163ffffffff1611612c6157600f60009054906101000a90046001600160a01b03166001600160a01b03166342e8e34e6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612c4d57600080fd5b505af1158015610f50573d6000803e3d6000fd5b50505050565b600082815260086020526040902060010154612c8281613d2a565b611bfb8383614228565b600080516020615b38833981519152612ca481613d2a565b506009805460ff9092166101000261ff0019909216919091179055565b60005460ff16612ce35760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908590610100900460ff16612cfb613a88565b63ffffffff168263ffffffff1614612d255760405162461bcd60e51b8152600401610cb49061570e565b612d2e81613a9b565b6005811115612d4d57634e487b7160e01b600052602160045260246000fd5b836005811115612d6d57634e487b7160e01b600052602160045260246000fd5b14612d8a5760405162461bcd60e51b8152600401610cb490615737565b63ffffffff87166000908152600360205260408120805460ff8916908110612dc257634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8c8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff16612e225760405162461bcd60e51b8152600401610cb4906156a0565b600f546040516347d0c1c560e11b815261ffff881660048201526001600160a01b0390911690638fa1838a9060240160206040518083038186803b158015612e6957600080fd5b505afa158015612e7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ea191906150ed565b1561300a57600f54604051631bc8002760e11b815261ffff881660048201526000916001600160a01b031690633790004e9060240160206040518083038186803b158015612eee57600080fd5b505afa158015612f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2691906151ac565b600e54604051631dab515760e21b815263ffffffff8c16600482015261ffff831660248201529192506000916001600160a01b03909116906376ad455c9060440160206040518083038186803b158015612f7f57600080fd5b505afa158015612f93573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fb79190615125565b905080156130075760405162461bcd60e51b815260206004820152601d60248201527f446973707574653a2049442073686f756c642062652070726573656e740000006044820152606401610cb4565b50505b63ffffffff8089166000908152600260209081526040808320938516835292905220600101805461ffff881691908790811061305657634e487b7160e01b600052603260045260246000fd5b60009182526020909120601082040154600f9091166002026101000a900461ffff16146130c55760405162461bcd60e51b815260206004820152601760248201527f446973707574653a20494420616273656e74206f6e6c790000000000000000006044820152606401610cb4565b6040805163ffffffff8a16815260ff89166020820152908101869052339061ffff8816907f3ae0c7a5044017e0013cc6614c9e03c3f8369f35b1b815d800e4859c228d04109060600160405180910390a3610f50888883613b69565b60005460ff166131435760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908590610100900460ff1661315b613a88565b63ffffffff168263ffffffff16146131855760405162461bcd60e51b8152600401610cb49061570e565b61318e81613a9b565b60058111156131ad57634e487b7160e01b600052602160045260246000fd5b8360058111156131cd57634e487b7160e01b600052602160045260246000fd5b146131ea5760405162461bcd60e51b8152600401610cb490615737565b63ffffffff87166000908152600360205260408120805460ff891690811061322257634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8c8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff166132825760405162461bcd60e51b8152600401610cb4906156a0565b8486106132d15760405162461bcd60e51b815260206004820181905260248201527f696e64657831206e6f742067726561746572207468616e20696e6465783020306044820152606401610cb4565b63ffffffff808916600090815260026020908152604080832093851683529290522060010180548690811061331657634e487b7160e01b600052603260045260246000fd5b6000918252602080832060108304015463ffffffff8c81168552600280845260408087209288168752919093529093206001018054600f9093169091026101000a90920461ffff1691908890811061337e57634e487b7160e01b600052603260045260246000fd5b60009182526020909120601082040154600f9091166002026101000a900461ffff1610156133ee5760405162461bcd60e51b815260206004820152601a60248201527f4944206174206930206e6f74206774207468616e206f662069310000000000006044820152606401610cb4565b6040805163ffffffff8a16815260ff891660208201529081018790526060810186905233907f9f1915bb320aae8cfdf7c6a0f5a138ff0da41d0cfc97721d09ea59177d0c30259060800160405180910390a2610f50888883613b69565b60005460ff1661346d5760405162461bcd60e51b8152600401610cb4906156d7565b6009546003908490610100900460ff16613485613a88565b63ffffffff168263ffffffff16146134af5760405162461bcd60e51b8152600401610cb49061570e565b6134b881613a9b565b60058111156134d757634e487b7160e01b600052602160045260246000fd5b8360058111156134f757634e487b7160e01b600052602160045260246000fd5b146135145760405162461bcd60e51b8152600401610cb490615737565b600e5463ffffffff8716600081815260016020908152604080832033845290915290819020549051631dab515760e21b8152600481019290925261ffff1660248201526001600160a01b03909116906376ad455c9060440160206040518083038186803b15801561358457600080fd5b505afa158015613598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135bc9190615125565b63ffffffff871660009081526001602090815260408083203384529091529020600201541461361c5760405162461bcd60e51b815260206004820152600c60248201526b5449522069732077726f6e6760a01b6044820152606401610cb4565b63ffffffff8616600090815260016020908152604080832033845290915290206002015461367e5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206469737075746560881b6044820152606401610cb4565b63ffffffff86166000908152600360205260408120805460ff88169081106136b657634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8b8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff166137165760405162461bcd60e51b8152600401610cb4906156a0565b63ffffffff8716600090815260016020908152604080832033845290915280822054600f54915163462f32c160e11b815261ffff9091166004820181905292916001600160a01b031690638c5e65829060240160206040518083038186803b15801561378157600080fd5b505afa158015613795573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137b991906151ac565b63ffffffff808b16600090815260026020908152604080832088851684528252808320815160c081018352815460ff811615158252610100900490951685840152600181018054835181860281018601855281815297985094969194928601939192909183018282801561387457602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff168152602001906002019060208260010104928301926001038202915080841161383b5790505b505050505081526020016002820154815260200160038201548152602001600482018054806020026020016040519081016040528092919081815260200182805480156138e057602002820191906000526020600020905b8154815260200190600101908083116138cc575b50505050508152505090508161ffff168160400151898151811061391457634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff161461396d5760405162461bcd60e51b815260206004820152601760248201527f57726f6e6720436f6c6c20496e646578207061737365640000000000000000006044820152606401610cb4565b63ffffffff808b166000908152600260209081526040808320938816835292905290812060040180548a9081106139b457634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015463ffffffff8e168352600182526040808420338552909252912060030154909150811415613a325760405162461bcd60e51b815260206004820181905260248201527f426c6f636b2070726f706f73656420776974682073616d65206d656469616e736044820152606401610cb4565b6040805163ffffffff8d16815260ff8c1660208201529081018a905233907ff7cac5758f33a2ff5e5f8054ed55fa64c70cd7fa0a99c510abc4be3b5421a6489060600160405180910390a2611a468b8b87613b69565b6000613a966104b04261596d565b905090565b6000818160ff8216613ab060056104b0615938565b613aba91906159a3565b905061ffff8116613ace60056104b0615938565b613adc9061ffff1642615abf565b1180613b04575060ff8216613af460056104b0615938565b613b029061ffff1642615abf565b105b15613b13575060059392505050565b60006005613b23816104b0615938565b613b319061ffff1642615959565b613b3b9190615abf565b90508060ff166005811115613b6057634e487b7160e01b600052602160045260246000fd5b95945050505050565b63ffffffff83811660008181526002602090815260408083209486168352938152838220805460ff19169055918152600390915290812054600654909160ff858116600160201b90930490910b161415613ca9576006805464ff00000000191664ff000000001790556000613bdf846001615913565b90505b8160ff168160ff161015613ca75763ffffffff85166000908152600360205260408120805460ff8416908110613c2857634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff8a8116855260028352604080862060079095166004026101000a90920416808552929091529091205490915060ff1615613c9457506006805464ff000000001916600160201b60ff600085900b1602179055613ca7565b5080613c9f81615a9f565b915050613be2565b505b63ffffffff848116600081815260026020908152604080832087861684529091529081902054600c5491516323dd933d60e21b81526004810193909352610100900490921660248201819052336044830152916001600160a01b031690638f764cf4906064015b600060405180830381600087803b15801561148957600080fd5b613d348133614bc3565b50565b63ffffffff821660009081526003602052604081206006548154600160201b909104830b60ff16908110613d7b57634e487b7160e01b600052603260045260246000fd5b6000918252602080832060088304015463ffffffff878116808652600284526040808720600460079788160261010090810a909504841680895290865281882092885295909452929094208254815460ff909116151560ff19821681178355845484900490961690920264ffffffff001990951664ffffffffff199092169190911793909317835560018082018054939550919392613e1e929184019190614f40565b5060028201548160020155600382015481600301556004820181600401908054613e49929190614f8e565b50505063ffffffff831660009081526007602090815260408083209051613e769287926004019101615623565b60408051601f19818403018152828252805160209182012063ffffffff80891660009081526007845284812060c087018652805460ff811615158852610100900490921686850152600182018054865181870281018701885281815294985091969592949286019392909190830182828015613f3957602002820191906000526020600020906000905b82829054906101000a900461ffff1661ffff1681526020019060020190602082600101049283019260010382029150808411613f005790505b50505050508152602001600282015481526020016003820154815260200160048201805480602002602001604051908101604052809291908181526020018280548015613fa557602002820191906000526020600020905b815481526020019060010190808311613f91575b505050505081525050905060005b816040015151811015614049578160a001518181518110613fe457634e487b7160e01b600052603260045260246000fd5b6020026020010151600560008460400151848151811061401457634e487b7160e01b600052603260045260246000fd5b602002602001015161ffff1661ffff16815260200190815260200160002081905550808061404190615a60565b915050613fb3565b50806020015163ffffffff167f3e421e040ebd474d10ce46694a45bec4208dbbd12ee37843712e352fb009419e868360400151428560a0015160405161409294939291906157c9565b60405180910390a2600e54604051631ddd754160e31b8152600481018490526001600160a01b039091169063eeebaa0890602401600060405180830381600087803b1580156140e057600080fd5b505af11580156140f4573d6000803e3d6000fd5b5050600d54604051623e8fc760e31b815263ffffffff8089166004830152891660248201526001600160a01b0390911692506301f47e389150604401600060405180830381600087803b15801561414a57600080fd5b505af115801561415e573d6000803e3d6000fd5b50506010546040516001621789db60e01b0319815263ffffffff89166004820152602481018690526001600160a01b03909116925063ffe876259150604401613d10565b6141ac8282612a50565b611c7a5760008281526008602090815260408083206001600160a01b03851684529091529020805460ff191660011790556141e43390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6142328282612a50565b15611c7a5760008281526008602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000805460ff166142b25760405162461bcd60e51b8152600401610cb4906156d7565b600e54604080516304ea562760e21b815290516000926001600160a01b0316916313a9589c916004808301926020929190829003018186803b1580156142f757600080fd5b505afa15801561430b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061432f9190615125565b90506000614365828860405160200161434a91815260200190565b60405160208183030381529060405280519060200120614c27565b905060006143fe600c60009054906101000a90046001600160a01b03166001600160a01b031663bc788d466040518163ffffffff1660e01b815260040160206040518083038186803b1580156143ba57600080fd5b505afa1580156143ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143f291906151e4565b63ffffffff1683614c66565b905063ffffffff86166144128260016158d3565b1461442357600093505050506145b6565b6040805163ffffffff8816602082015290810189905260009061444a90859060600161434a565b9050600061445c600160201b83614c66565b600e546040516370b9856360e11b815263ffffffff808b1660048301528c1660248201529192506000916001600160a01b039091169063e1730ac69060440160206040518083038186803b1580156144b357600080fd5b505afa1580156144c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144eb9190615125565b600e546040516370b9856360e11b815263ffffffff808c1660048301528c1660248201529192506000916001600160a01b039091169063e1730ac69060440160206040518083038186803b15801561454257600080fd5b505afa158015614556573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061457a9190615125565b905061458a81600160201b615984565b6145948385615984565b11156145aa5760009750505050505050506145b6565b60019750505050505050505b949350505050565b63ffffffff841660009081526003602052604081205460ff811661463457505063ffffffff84811660009081526003602090815260408220805460018082018355918452919092206008820401805460079092166004026101000a90930219169091556006805464ff00000000191690556145b6565b63ffffffff8616600090815260026020908152604080832060039092528220805486939190829061467557634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020019081526020016000206003015411156146c95760009150506145b6565b63ffffffff8616600090815260026020908152604080832060039092528220805486939190829061470a57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060030154101561482f5760005b8160ff168160ff1610156147d75763ffffffff8716600090815260036020526040902080548061479757634e487b7160e01b600052603160045260246000fd5b600082815260209020600860001990920191820401805463ffffffff600460078516026101000a02191690559055806147cf81615a9f565b915050614757565b50505063ffffffff80851660009081526003602090815260408220805460018181018355918452919092206008820401805487851660046007909416939093026101000a9283029290940219909316179091556145b6565b60005b8160ff168160ff161015614b3e5763ffffffff871660009081526002602090815260408083206003909252822080548893919060ff861690811061488657634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff1663ffffffff1663ffffffff168152602001908152602001600020600201541115614b2c5763ffffffff8088166000908152600360209081526040822080546001818101835591845291909220600882040180548a851660046007909416939093026101000a92830292909402199093161790915561492b908390615913565b9150600061493a6001846159fa565b60ff1690505b8160ff16811115614a335763ffffffff8816600090815260036020526040902061496b6001836159c6565b8154811061498957634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004029054906101000a900463ffffffff16600360008a63ffffffff1663ffffffff16815260200190815260200160002082815481106149ed57634e487b7160e01b600052603260045260246000fd5b90600052602060002090600891828204019190066004026101000a81548163ffffffff021916908363ffffffff1602179055508080614a2b90615a49565b915050614940565b5063ffffffff87166000908152600360205260409020805487919060ff8416908110614a6f57634e487b7160e01b600052603260045260246000fd5b600091825260208083206008830401805460079093166004026101000a63ffffffff818102199094169584160294909417909355600954908a1682526003909252604090205460ff9091161015614b215763ffffffff87166000908152600360205260409020805480614af257634e487b7160e01b600052603160045260246000fd5b600082815260209020600860001990920191820401805463ffffffff600460078516026101000a021916905590555b6001925050506145b6565b80614b3681615a9f565b915050614832565b5060095463ffffffff871660009081526003602052604090205460ff9091161115614bba57505063ffffffff80851660009081526003602090815260408220805460018181018355918452919092206008820401805487851660046007909416939093026101000a9283029290940219909316179091556145b6565b50949350505050565b614bcd8282612a50565b611c7a57614be5816001600160a01b03166014614c73565b614bf0836020614c73565b604051602001614c019291906155ae565b60408051601f198184030181529082905262461bcd60e51b8252610cb49160040161566d565b6000808383604051602001614c46929190918252602082015260400190565b60408051808303601f190181529190528051602090910120949350505050565b6000816145b68482615abf565b60606000614c82836002615984565b614c8d9060026158d3565b67ffffffffffffffff811115614cb357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015614cdd576020820181803683370190505b509050600360fc1b81600081518110614d0657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110614d4357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a9053506000614d67846002615984565b614d729060016158d3565b90505b6001811115614e06576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110614db457634e487b7160e01b600052603260045260246000fd5b1a60f81b828281518110614dd857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c93614dff81615a49565b9050614d75565b508315614e555760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610cb4565b9392505050565b82805482825590600052602060002090600f01601090048101928215614ef55791602002820160005b83821115614ec557835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302614e85565b8015614ef35782816101000a81549061ffff0219169055600201602081600101049283019260010302614ec5565b505b50614f01929150614fcd565b5090565b828054828255906000526020600020908101928215614ef5579160200282015b82811115614ef5578251825591602001919060010190614f25565b82805482825590600052602060002090600f01601090048101928215614ef557600052602060002091600f016010900482015b82811115614ef5578254825591600101919060010190614f73565b828054828255906000526020600020908101928215614ef557600052602060002091820182811115614ef5578254825591600101919060010190614f73565b5b80821115614f015760008155600101614fce565b80356001600160a01b0381168114614ff957600080fd5b919050565b600082601f83011261500e578081fd5b8135602061502361501e836158af565b61587e565b80838252828201915082860187848660051b8901011115615042578586fd5b855b8581101561506057813584529284019290840190600101615044565b5090979650505050505050565b8035614ff981615b25565b803560ff81168114614ff957600080fd5b600080600080600060a086880312156150a0578081fd5b6150a986614fe2565b94506150b760208701614fe2565b93506150c560408701614fe2565b92506150d360608701614fe2565b91506150e160808701614fe2565b90509295509295909350565b6000602082840312156150fe578081fd5b81518015158114614e55578182fd5b60006020828403121561511e578081fd5b5035919050565b600060208284031215615136578081fd5b5051919050565b6000806040838503121561514f578182fd5b8235915061515f60208401614fe2565b90509250929050565b600060208284031215615179578081fd5b81356001600160e01b031981168114614e55578182fd5b6000602082840312156151a1578081fd5b8135614e5581615b15565b6000602082840312156151bd578081fd5b8151614e5581615b15565b6000602082840312156151d9578081fd5b8135614e5581615b25565b6000602082840312156151f5578081fd5b8151614e5581615b25565b60008060408385031215615212578182fd5b823561521d81615b25565b915061515f60208401614fe2565b600080600080600060a08688031215615242578283fd5b853561524d81615b25565b945060208681013567ffffffffffffffff8082111561526a578586fd5b818901915089601f83011261527d578586fd5b813561528b61501e826158af565b8082825285820191508585018d878560051b88010111156152aa57898afd5b8995505b838610156152d55780356152c181615b15565b8352600195909501949186019186016152ae565b509850505060408901359250808311156152ed578586fd5b50506152fb88828901614ffe565b935050606086013591506150e16080870161506d565b600080600060608486031215615325578081fd5b833561533081615b25565b9250602084013561534081615b15565b9150604084013567ffffffffffffffff81111561535b578182fd5b61536786828701614ffe565b9150509250925092565b60008060408385031215615383578182fd5b823561538e81615b25565b946020939093013593505050565b600080604083850312156153ae578182fd5b82356153b981615b25565b915060208301356153c981615b25565b809150509250929050565b6000806000606084860312156153e8578081fd5b83356153f381615b25565b925061540160208501615078565b9150604084013561541181615b15565b809150509250925092565b60008060008060808587031215615431578182fd5b843561543c81615b25565b935061544a60208601615078565b9250604085013561545a81615b15565b9396929550929360600135925050565b60008060006060848603121561547e578081fd5b833561548981615b25565b925061549760208501615078565b9150604084013590509250925092565b600080600080608085870312156154bc578182fd5b84356154c781615b25565b93506154d560208601615078565b93969395505050506040820135916060013590565b6000806000606084860312156154fe578081fd5b833561550981615b25565b925061551760208501615078565b9150604084013561541181615b25565b600060208284031215615538578081fd5b614e5582615078565b6000815180845260208085019450808401835b8381101561557457815161ffff1687529582019590820190600101615554565b509495945050505050565b6000815180845260208085019450808401835b8381101561557457815187529582019590820190600101615592565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516155e6816017850160208801615a1d565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351615617816028840160208801615a1d565b01602801949350505050565b63ffffffff60e01b8360e01b16815260006004820183548483526020808420845b8381101561566057815485529382019360019182019101615644565b5092979650505050505050565b602081526000825180602084015261568c816040850160208701615a1d565b601f01601f19169190910160400192915050565b6020808252601f908201527f426c6f636b20616c726561647920686173206265656e20646973707574656400604082015260600190565b6020808252601e908201527f436f6e74726163742073686f756c6420626520696e697469616c697a65640000604082015260600190565b6020808252600f908201526e0d2dcc6dee4e4cac6e840cae0dec6d608b1b604082015260600190565b6020808252600f908201526e696e636f727265637420737461746560881b604082015260600190565b6020815281511515602082015263ffffffff60208301511660408201526000604083015160c0606084015261579860e0840182615541565b905060608401516080840152608084015160a084015260a0840151601f198483030160c0850152613b60828261557f565b63ffffffff851681526080602082015260006157e86080830186615541565b8460408401528281036060840152615800818561557f565b979650505050505050565b63ffffffff831681526040602082015260006145b6604083018461557f565b600063ffffffff808916835280881660208401525060c0604083015261585360c0830187615541565b85606084015284608084015282810360a0840152615871818561557f565b9998505050505050505050565b604051601f8201601f1916810167ffffffffffffffff811182821017156158a7576158a7615aff565b604052919050565b600067ffffffffffffffff8211156158c9576158c9615aff565b5060051b60200190565b600082198211156158e6576158e6615ad3565b500190565b600063ffffffff80831681851680830382111561590a5761590a615ad3565b01949350505050565b600060ff821660ff84168060ff0382111561593057615930615ad3565b019392505050565b600061ffff8084168061594d5761594d615ae9565b92169190910492915050565b60008261596857615968615ae9565b500490565b600063ffffffff8084168061594d5761594d615ae9565b600081600019048311821515161561599e5761599e615ad3565b500290565b600061ffff838116908316818110156159be576159be615ad3565b039392505050565b6000828210156159d8576159d8615ad3565b500390565b600063ffffffff838116908316818110156159be576159be615ad3565b600060ff821660ff841680821015615a1457615a14615ad3565b90039392505050565b60005b83811015615a38578181015183820152602001615a20565b83811115612c615750506000910152565b600081615a5857615a58615ad3565b506000190190565b6000600019821415615a7457615a74615ad3565b5060010190565b600063ffffffff80831681811415615a9557615a95615ad3565b6001019392505050565b600060ff821660ff811415615ab657615ab6615ad3565b60010192915050565b600082615ace57615ace615ae9565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b61ffff81168114613d3457600080fd5b63ffffffff81168114613d3457600080fdfe71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1a2646970667358221220b0227113721919669b803359160e259183e96a1762f35c8d11f91a30f7b614d564736f6c63430008040033