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