false
false
0

Contract Address Details

0xe0bC695203d9C9f379bcdE9260B9F71B64B85298

Contract Name
StakeManager
Creator
0xd73462–49788f at 0xe154cc–96f0f8
Balance
0
Tokens
Fetching tokens...
Transactions
2,314 Transactions
Transfers
2,072 Transfers
Gas Used
206,053,629
Last Balance Update
3544990
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
StakeManager




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




Optimization runs
1300
Verified at
2022-08-26T14:19:40.529362Z

contracts/Core/StakeManager.sol

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

import "./interface/IStakeManager.sol";
import "./interface/IRewardManager.sol";
import "./interface/IVoteManager.sol";
import "../tokenization/IStakedTokenFactory.sol";
import "../tokenization/IStakedToken.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./storage/StakeStorage.sol";
import "./parameters/child/StakeManagerParams.sol";
import "../Initializable.sol";
import "./StateManager.sol";
import "../Pause.sol";

/** @title StakeManager
 * @notice StakeManager handles stake, unstake, withdraw, reward, functions
 * for stakers
 */

contract StakeManager is Initializable, StakeStorage, StateManager, Pause, StakeManagerParams, IStakeManager {
    IRewardManager public rewardManager;
    IVoteManager public voteManager;
    IERC20 public razor;
    IStakedTokenFactory public stakedTokenFactory;

    /**
     * @dev Emitted when sRZR are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     * @param amount amount of sRZR transferred
     * @param stakerId the id of the staker whose sRZR is involved in the transfer
     */
    event SrzrTransfer(address indexed from, address indexed to, uint256 amount, uint32 indexed stakerId);

    /**
     * @dev Emitted when there has been change in the stake of the staker.
     * @param epoch in which change of stake took place
     * @param stakerId id of the staker whose stake was changed
     * @param reason reason why the the change in stake took place
     * @param prevStake stake before the change took place
     * @param newStake updated stake
     * @param timestamp time at which the change took place
     */
    event StakeChange(
        uint32 epoch,
        uint32 indexed stakerId,
        Constants.StakeChanged reason,
        uint256 prevStake,
        uint256 newStake,
        uint256 timestamp
    );

    /**
     * @dev Emitted when stakerReward has been changed for the staker.
     * @param epoch in which stakerReward was changed
     * @param stakerId id of the staker whose stakerReward was changed
     * @param reason reason why the the change in stake took place
     * @param prevStakerReward stakerReward before the change took place
     * @param newStakerReward updated stakerReward
     * @param timestamp time at which the change took place
     */
    event StakerRewardChange(
        uint32 epoch,
        uint32 indexed stakerId,
        Constants.StakerRewardChanged reason,
        uint256 prevStakerReward,
        uint256 newStakerReward,
        uint256 timestamp
    );

    /**
     * @dev Emitted when there has been change in the age of the staker.
     * @param epoch in which change of age took place
     * @param stakerId id of the staker whose age was changed
     * @param newAge updated age
     * @param reason reason why the the change in age took place
     * @param timestamp time at which the change took place
     */
    event AgeChange(uint32 epoch, uint32 indexed stakerId, uint32 newAge, Constants.AgeChanged reason, uint256 timestamp);

    /**
     * @dev Emitted when staker stakes for the first time or adds stake.
     * @param staker address of the staker
     * @param sToken address of the staker's sRZR
     * @param epoch in which stake was added
     * @param stakerId id of the staker who staked
     * @param amount stake amount added
     * @param newStake current stake after staking
     * @param totalSupply total amount of staker's sRZRs minted
     * @param timestamp time at which the staker staked
     */
    event Staked(
        address indexed staker,
        address sToken,
        uint32 epoch,
        uint32 indexed stakerId,
        uint256 amount,
        uint256 newStake,
        uint256 totalSupply,
        uint256 timestamp
    );

    /**
     * @dev Emitted when staker/delegator unstakes.
     * @param staker address of the staker/delegator
     * @param epoch in which staker unstaked
     * @param stakerId id of the staker whose corresponding sRZR is being unstaked
     * @param amount amount of sRZR being unstaked
     * @param newStake current stake after unstaking
     * @param timestamp time at which the staker/delegator unstaked
     */
    event Unstaked(address indexed staker, uint32 epoch, uint32 indexed stakerId, uint256 amount, uint256 newStake, uint256 timestamp);

    /**
     * @dev Emitted when staker/delegator initiates withdraw.
     * @param staker address of the staker/delegator
     * @param epoch in which staker withdraw was initiated
     * @param stakerId id of the staker whose corresponding sRZR is being unstaked
     * @param amount amount of RZR being unstaked
     * @param newStake current stake after withdraw was initiated
     * @param timestamp time at which the staker/delegator initiated withdraw
     */
    event WithdrawInitiated(
        address indexed staker,
        uint32 epoch,
        uint32 indexed stakerId,
        uint256 amount,
        uint256 newStake,
        uint256 totalSupply,
        uint256 timestamp
    );

    /**
     * @dev Emitted when staker/delegator completes withdraw.
     * @param staker address of the staker/delegator
     * @param epoch in which staker withdrew
     * @param stakerId id of the staker whose corresponding sRZR is being withdrawn
     * @param amount amount of RZR being withdrawn
     * @param newStake current stake after withdraw process is completed
     * @param timestamp time at which the staker/delegator withdrew
     */
    event Withdrew(address indexed staker, uint32 epoch, uint32 indexed stakerId, uint256 amount, uint256 newStake, uint256 timestamp);

    /**
     * @dev Emitted when delegator delegates his RAZOR to a particular staker.
     * @param delegator address of the delegator
     * @param epoch in which delegator delegated
     * @param stakerId id of the staker whose corresponding sRZR is being delegated to
     * @param amount amount of RZR being delegated
     * @param newStake current stake after delegation by delegator
     * @param timestamp time at which the delegator delegated
     */
    event Delegated(
        address indexed delegator,
        uint32 epoch,
        uint32 indexed stakerId,
        uint256 amount,
        uint256 newStake,
        uint256 totalSupply,
        uint256 timestamp
    );

    /**
     * @dev Emitted when the staker updates delegation status
     * @param delegationEnabled updated delegation status
     * @param staker address of the staker/delegator
     * @param stakerId the stakerId for which extension took place
     */
    event DelegationAcceptanceChanged(bool delegationEnabled, address indexed staker, uint32 indexed stakerId);

    /**
     * @dev Emitted when the staker/delegator lock resets after successfully withdrawing
     * @param stakerId the stakerId for which the reset took place
     * @param staker address of the staker/delegator
     * @param epoch in which the reset took place
     */
    event ResetLock(uint32 indexed stakerId, address indexed staker, uint32 epoch);

    /**
     * @dev Emitted when the staker/delegator extends unstake lock
     * @param stakerId the stakerId for which extension took place
     * @param staker address of the staker/delegator
     * @param epoch in which the extension took place
     */
    event ResetUnstakeLock(uint32 indexed stakerId, address indexed staker, uint32 epoch);

    /**
     * @dev Emitted when the staker changes commission
     * @param stakerId the staker that changes commission
     * @param commission updated commission
     */
    event CommissionChanged(uint32 indexed stakerId, uint8 commission);

    /**
     * @dev Emitted when the staker is slashed
     * @param bountyId unique id for each bounty to be claimed by bounty hunter
     * @param bountyHunter address who will claim the bounty caused by slash
     */
    event Slashed(uint32 bountyId, address indexed bountyHunter);

    /**
     * @dev Emitted when the bountyHunter redeem bounty
     * @param bountyId unique id for each bounty to be claimed by bounty hunter
     * @param bountyHunter address who will claim the bounty
     */
    event RedeemBounty(uint32 bountyId, address indexed bountyHunter);

    /** @param razorAddress The address of the Razor token ERC20 contract
     * @param rewardManagerAddress The address of the RewardManager contract
     * @param voteManagersAddress The address of the VoteManager contract
     */
    function initialize(
        address razorAddress,
        address rewardManagerAddress,
        address voteManagersAddress,
        address stakedTokenFactoryAddress
    ) external initializer onlyRole(DEFAULT_ADMIN_ROLE) {
        razor = IERC20(razorAddress);
        rewardManager = IRewardManager(rewardManagerAddress);
        voteManager = IVoteManager(voteManagersAddress);
        stakedTokenFactory = IStakedTokenFactory(stakedTokenFactoryAddress);
    }

    /**
     * @notice stake during commit state only
     * we check epoch during every transaction to avoid withholding and rebroadcasting attacks
     * @dev An ERC20 token corresponding to each new staker is created called sRZRs.
     * For a new staker, amount of sRZR minted is equal to amount of RAZOR staked.
     * For adding stake, amount of sRZR minted depends on sRZR:(RAZOR staked) valuation.
     * @param epoch The Epoch value for which staker is requesting to stake
     * @param amount The amount in RZR
     */
    function stake(uint32 epoch, uint256 amount) external initialized checkEpoch(epoch) whenNotPaused {
        uint32 stakerId = stakerIds[msg.sender];
        uint256 totalSupply = 0;

        if (stakerId == 0) {
            require(amount >= minSafeRazor, "less than minimum safe Razor");
            numStakers = numStakers + (1);
            stakerId = numStakers;
            stakerIds[msg.sender] = stakerId;
            // slither-disable-next-line reentrancy-benign
            IStakedToken sToken = IStakedToken(stakedTokenFactory.createStakedToken(address(this), numStakers));
            stakers[numStakers] = Structs.Staker(false, false, 0, numStakers, 10000, msg.sender, address(sToken), epoch, 0, amount, 0);
            _setupRole(STOKEN_ROLE, address(sToken));
            // Minting
            // Ignoring below line for testing as this is standard erc20 function
            require(sToken.mint(msg.sender, amount, amount), "tokens not minted"); // as 1RZR = 1 sRZR
            totalSupply = amount;
        } else {
            require(!stakers[stakerId].isSlashed, "staker is slashed");
            IStakedToken sToken = IStakedToken(stakers[stakerId].tokenAddress);
            totalSupply = sToken.totalSupply();
            uint256 toMint = _convertRZRtoSRZR(amount, stakers[stakerId].stake, totalSupply); // RZRs to sRZRs
            stakers[stakerId].stake = stakers[stakerId].stake + (amount);

            // Mint sToken as Amount * (totalSupplyOfToken/previousStake)
            // Ignoring below line for testing as this is standard erc20 function
            require(sToken.mint(msg.sender, toMint, amount), "tokens not minted");
            totalSupply = totalSupply + toMint;
        }
        // slither-disable-next-line reentrancy-events
        emit Staked(
            msg.sender,
            stakers[stakerId].tokenAddress,
            epoch,
            stakerId,
            amount,
            stakers[stakerId].stake,
            totalSupply,
            block.timestamp
        );
        // Ignoring below line for testing as this is standard erc20 function
        require(razor.transferFrom(msg.sender, address(this), amount), "razor transfer failed");
    }

    /**
     * @notice delegators can delegate their funds to staker if they do not have the adequate resources to start a node
     * @dev the delegator receives the sRZR for the stakerID to which he/she delegates.
     * The amount of sRZR minted depends on depends on sRZR:(RAZOR staked) valuation at the time of delegation
     * @param amount The amount in RZR
     * @param stakerId The Id of staker whom you want to delegate
     */
    function delegate(uint32 stakerId, uint256 amount) external initialized whenNotPaused {
        uint32 epoch = _getEpoch();
        require(stakers[stakerId].acceptDelegation, "Delegetion not accpected");
        require(stakers[stakerId]._address != msg.sender, "Staker cannot delegate themself");
        require(!stakers[stakerId].isSlashed, "Staker is slashed");
        // Step 1 : Calculate Mintable amount
        IStakedToken sToken = IStakedToken(stakers[stakerId].tokenAddress);
        uint256 totalSupply = sToken.totalSupply();
        uint256 toMint = _convertRZRtoSRZR(amount, stakers[stakerId].stake, totalSupply);

        // Step 2: Increase given stakers stake by : Amount
        stakers[stakerId].stake = stakers[stakerId].stake + (amount);

        // Step 3:  Mint sToken as Amount * (totalSupplyOfToken/previousStake)
        // Ignoring below line for testing as this is standard erc20 function
        require(sToken.mint(msg.sender, toMint, amount), "tokens not minted");
        totalSupply = totalSupply + toMint;

        // slither-disable-next-line reentrancy-events
        emit Delegated(msg.sender, epoch, stakerId, amount, stakers[stakerId].stake, totalSupply, block.timestamp);

        // Step 4:  Razor Token Transfer : Amount
        // Ignoring below line for testing as this is standard erc20 function
        require(razor.transferFrom(msg.sender, address(this), amount), "RZR token transfer failed");
    }

    /** @notice staker/delegator must call unstake() to lock their sRZRs
     * and should wait for params.withdraw_after period
     * after which he/she can call initiateWithdraw() in withdrawInitiationPeriod.
     * If this period pass, lock expires and she will have to resetUnstakeLock() to able to initiateWithdraw again
     * @param stakerId The Id of staker associated with sRZR which user want to unstake
     * @param sAmount The Amount in sRZR
     */
    function unstake(uint32 stakerId, uint256 sAmount) external initialized whenNotPaused {
        require(sAmount > 0, "Non-Positive Amount");
        require(stakerId != 0, "staker.id = 0");
        require(stakers[stakerId].stake > 0, "Nonpositive stake");
        // slither-disable-next-line timestamp
        require(locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Withdraw].unlockAfter == 0, "Existing Withdraw Lock");
        require(locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Unstake].amount == 0, "Existing Unstake Lock");
        uint32 epoch = _getEpoch();
        Structs.Staker storage staker = stakers[stakerId];
        IStakedToken sToken = IStakedToken(staker.tokenAddress);

        require(sToken.balanceOf(msg.sender) >= sAmount, "Invalid Amount");

        locks[msg.sender][staker.tokenAddress][LockType.Unstake] = Structs.Lock(sAmount, epoch + unstakeLockPeriod);
        emit Unstaked(msg.sender, epoch, stakerId, sAmount, staker.stake, block.timestamp);
        // Ignoring below line for testing as this is standard erc20 function
        require(sToken.transferFrom(msg.sender, address(this), sAmount), "sToken transfer failed");
    }

    /** @notice staker/delegator call initiateWithdraw() to burn their locked sRZRs and lock their RAZORS
     * RAZORS is separated from the staker's stake but can be claimed only after withdrawLockPeriod passes
     * after which he/she can call unlockWithdraw() to claim the locked RAZORS.
     * @param stakerId The Id of staker associated with sRZR which user want to initiateWithdraw
     */
    function initiateWithdraw(uint32 stakerId) external initialized whenNotPaused {
        State currentState = _getState(buffer);
        // slither-disable-next-line timestamp
        require(currentState != State.Propose, "Unstake: NA Propose");
        // slither-disable-next-line timestamp
        require(currentState != State.Dispute, "Unstake: NA Dispute");

        require(stakerId != 0, "staker doesnt exist");
        // slither-disable-next-line timestamp
        uint32 epoch = _getEpoch();
        Structs.Staker storage staker = stakers[stakerId];
        Structs.Lock storage lock = locks[msg.sender][staker.tokenAddress][LockType.Unstake];
        require(locks[msg.sender][staker.tokenAddress][LockType.Withdraw].unlockAfter == 0, "Withdraw lock present");
        require(lock.unlockAfter != 0, "Did not unstake");
        // slither-disable-next-line timestamp
        require(lock.unlockAfter <= epoch, "Withdraw epoch not reached");
        require(lock.unlockAfter + withdrawInitiationPeriod >= epoch, "Initiation Period Passed"); // Can Use ExtendLock

        IStakedToken sToken = IStakedToken(staker.tokenAddress);

        // slither-disable-next-line reentrancy-events,reentrancy-no-eth
        rewardManager.giveInactivityPenalties(epoch, stakerId);

        uint256 rAmount = _convertSRZRToRZR(lock.amount, staker.stake, sToken.totalSupply());
        require(rAmount > 0, "No razor to withdraw");

        staker.stake = staker.stake - rAmount;

        locks[msg.sender][staker.tokenAddress][LockType.Withdraw] = Structs.Lock(rAmount, epoch + withdrawLockPeriod);
        // Ignoring below line for testing as this is standard erc20 function
        require(sToken.burn(address(this), lock.amount), "Token burn Failed");
        //emit event here
        emit WithdrawInitiated(msg.sender, epoch, stakerId, rAmount, staker.stake, sToken.totalSupply(), block.timestamp);
    }

    /**
     * @notice staker/delegator can claim their locked RAZORS.
     * @param stakerId The Id of staker associated with sRZR which user want to unlockWithdraw
     */
    function unlockWithdraw(uint32 stakerId) external initialized whenNotPaused {
        // slither-disable-next-line timestamp
        uint32 epoch = _getEpoch();
        require(stakerId != 0, "staker doesnt exist");

        Structs.Staker storage staker = stakers[stakerId];
        Structs.Lock storage lock = locks[msg.sender][staker.tokenAddress][LockType.Withdraw];
        require(lock.unlockAfter != 0, "Did not initiate withdraw");
        // slither-disable-next-line timestamp
        require(lock.unlockAfter <= epoch, "Withdraw epoch not reached");

        uint256 withdrawAmount = lock.amount;
        // Reset lock
        _resetLock(stakerId);

        emit Withdrew(msg.sender, epoch, stakerId, withdrawAmount, staker.stake, block.timestamp);
        //Transfer Razor Back
        // Ignoring below line for testing as this is standard erc20 function
        require(razor.transfer(msg.sender, withdrawAmount), "couldnt transfer");
    }

    /**
     * @notice staker can claim the rewards earned from delegator's pool share as commission.
     */
    function claimStakerReward() external initialized whenNotPaused {
        uint32 stakerId = stakerIds[msg.sender];
        require(stakerId != 0, "staker doesnt exist");
        require(stakers[stakerId].stakerReward != 0, "no stakerReward to transfer");
        uint32 epoch = _getEpoch();
        uint256 stakerRewardToBeClaimed = stakers[stakerId].stakerReward;
        _setStakerReward(epoch, stakerId, StakerRewardChanged.StakerRewardClaimed, stakers[stakerId].stakerReward, 0);
        require(razor.transfer(msg.sender, stakerRewardToBeClaimed), "couldnt transfer");
    }

    /// @inheritdoc IStakeManager
    function escape(address _address) external override initialized onlyRole(ESCAPE_HATCH_ROLE) whenPaused {
        if (escapeHatchEnabled) {
            // Ignoring below line for testing as this is standard erc20 function
            require(razor.transfer(_address, razor.balanceOf(address(this))), "razor transfer failed");
        } else {
            revert("escape hatch is disabled");
        }
    }

    /// @inheritdoc IStakeManager
    function srzrTransfer(
        address from,
        address to,
        uint256 amount,
        uint32 stakerId
    ) external override initialized onlyRole(STOKEN_ROLE) {
        emit SrzrTransfer(from, to, amount, stakerId);
    }

    /**
     * @notice Used by staker to set delegation acceptance, its set as False by default
     */
    function setDelegationAcceptance(bool status) external initialized {
        uint32 stakerId = stakerIds[msg.sender];
        require(stakerId != 0, "staker id = 0");
        require(stakers[stakerId].commission != 0, "comission not set");
        stakers[stakerId].acceptDelegation = status;
        emit DelegationAcceptanceChanged(status, msg.sender, stakerId);
    }

    /**
     * @notice Used by staker to update commision for delegation
     */
    function updateCommission(uint8 commission) external initialized {
        require(commission <= maxCommission, "Commission exceeds maxlimit");
        uint32 stakerId = stakerIds[msg.sender];
        require(stakerId != 0, "staker id = 0");
        uint32 epoch = _getEpoch();
        if (stakers[stakerId].epochCommissionLastUpdated != 0) {
            // slither-disable-next-line timestamp
            require((stakers[stakerId].epochCommissionLastUpdated + epochLimitForUpdateCommission) <= epoch, "Invalid Epoch For Updation");
            require(commission <= (stakers[stakerId].commission + deltaCommission), "Invalid Commission Update");
        }
        stakers[stakerId].epochCommissionLastUpdated = epoch;
        stakers[stakerId].commission = commission;
        emit CommissionChanged(stakerId, commission);
    }

    /**
     * @notice Used by anyone whose has not initiated withdraw within the WithdrawInitiationPeriod
     * or someone who just wants to extend unstake lock.
     * Here we have added penalty to avoid repeating front-running
     */
    function resetUnstakeLock(uint32 stakerId) external initialized whenNotPaused {
        // Lock should be expired if you want to extend
        uint32 epoch = _getEpoch();
        // slither-disable-next-line timestamp
        require(locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Unstake].amount != 0, "Unstake Lock doesnt exist");
        require(locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Withdraw].unlockAfter == 0, "Withdraw Lock exists");

        Structs.Staker storage staker = stakers[stakerId];
        Structs.Lock storage lock = locks[msg.sender][staker.tokenAddress][LockType.Unstake];
        IStakedToken sToken = IStakedToken(staker.tokenAddress);

        //Giving out the extendLock penalty
        uint256 penalty = (lock.amount * resetUnstakeLockPenalty) / BASE_DENOMINATOR;
        uint256 rPenalty = _convertSRZRToRZR(penalty, staker.stake, sToken.totalSupply());

        lock.amount = lock.amount - penalty;
        staker.stake = staker.stake - rPenalty;
        lock.unlockAfter = epoch + unstakeLockPeriod;
        emit ResetUnstakeLock(stakerId, msg.sender, _getEpoch());
        // Ignoring below line for testing as this is standard erc20 function
        require(sToken.burn(address(this), penalty), "Token burn Failed");
    }

    /// @inheritdoc IStakeManager
    function setStakerStake(
        uint32 _epoch,
        uint32 _id,
        Constants.StakeChanged reason,
        uint256 prevStake,
        uint256 _stake
    ) external override initialized onlyRole(STAKE_MODIFIER_ROLE) {
        _setStakerStake(_epoch, _id, reason, prevStake, _stake);
    }

    /// @inheritdoc IStakeManager
    function setStakerReward(
        uint32 _epoch,
        uint32 _id,
        Constants.StakerRewardChanged reason,
        uint256 prevStakerReward,
        uint256 _stakerReward
    ) external override initialized onlyRole(STAKE_MODIFIER_ROLE) {
        _setStakerReward(_epoch, _id, reason, prevStakerReward, _stakerReward);
    }

    /// @inheritdoc IStakeManager
    function slash(
        uint32 epoch,
        uint32 stakerId,
        address bountyHunter
    ) external override initialized onlyRole(STAKE_MODIFIER_ROLE) {
        uint256 _stake = stakers[stakerId].stake;

        uint256 bounty;
        uint256 amountToBeBurned;
        uint256 amountToBeKept;

        // Block Scoping
        // Done for stack too deep issue
        // https://soliditydeveloper.com/stacktoodeep
        {
            (uint32 bountyNum, uint32 burnSlashNum, uint32 keepSlashNum) = (slashNums.bounty, slashNums.burn, slashNums.keep);
            bounty = (_stake * bountyNum) / BASE_DENOMINATOR;
            amountToBeBurned = (_stake * burnSlashNum) / BASE_DENOMINATOR;
            amountToBeKept = (_stake * keepSlashNum) / BASE_DENOMINATOR;
        }

        uint256 slashPenaltyAmount = bounty + amountToBeBurned + amountToBeKept;
        _stake = _stake - slashPenaltyAmount;
        stakers[stakerId].isSlashed = true;
        _setStakerStake(epoch, stakerId, StakeChanged.Slashed, _stake + slashPenaltyAmount, _stake);

        if (bounty == 0) return;
        bountyCounter = bountyCounter + 1;
        bountyLocks[bountyCounter] = Structs.BountyLock(epoch + withdrawLockPeriod, bountyHunter, bounty);

        emit Slashed(bountyCounter, bountyHunter);
        //please note that since slashing is a critical part of consensus algorithm,
        //the following transfers are not `reuquire`d. even if the transfers fail, the slashing
        //tx should complete.
        // Ignoring below line for testing as this is standard erc20 function
        require(razor.transfer(BURN_ADDRESS, amountToBeBurned), "couldn't burn");
    }

    /**
     * @notice Allows bountyHunter to redeem their bounty once its locking period is over
     * @param bountyId The ID of the bounty
     */
    function redeemBounty(uint32 bountyId) external initialized whenNotPaused {
        uint32 epoch = _getEpoch();
        uint256 bounty = bountyLocks[bountyId].amount;

        require(msg.sender == bountyLocks[bountyId].bountyHunter, "Incorrect Caller");
        // slither-disable-next-line timestamp
        require(bountyLocks[bountyId].redeemAfter <= epoch, "Redeem epoch not reached");
        delete bountyLocks[bountyId];
        emit RedeemBounty(bountyId, msg.sender);
        // Ignoring below line for testing as this is standard erc20 function
        require(razor.transfer(msg.sender, bounty), "couldnt transfer");
    }

    /// @inheritdoc IStakeManager
    function setStakerEpochFirstStakedOrLastPenalized(uint32 _epoch, uint32 _id) external override onlyRole(STAKE_MODIFIER_ROLE) {
        stakers[_id].epochFirstStakedOrLastPenalized = _epoch;
    }

    /// @inheritdoc IStakeManager
    function setStakerAge(
        uint32 _epoch,
        uint32 _id,
        uint32 _age,
        Constants.AgeChanged reason
    ) external override initialized onlyRole(STAKE_MODIFIER_ROLE) {
        stakers[_id].age = _age;
        emit AgeChange(_epoch, _id, _age, reason, block.timestamp);
    }

    /// @inheritdoc IStakeManager
    function getStakerId(address _address) external view override returns (uint32) {
        return (stakerIds[_address]);
    }

    /// @inheritdoc IStakeManager
    function getStaker(uint32 _id) external view override returns (Structs.Staker memory staker) {
        return (stakers[_id]);
    }

    /// @inheritdoc IStakeManager
    function getNumStakers() external view override returns (uint32) {
        return (numStakers);
    }

    /**
     * @return age of staker
     */
    function getAge(uint32 stakerId) external view returns (uint32) {
        return stakers[stakerId].age;
    }

    /// @inheritdoc IStakeManager
    function getInfluence(uint32 stakerId) external view override returns (uint256) {
        return _getMaturity(stakerId) * stakers[stakerId].stake;
    }

    /// @inheritdoc IStakeManager
    function getStake(uint32 stakerId) external view override returns (uint256) {
        return stakers[stakerId].stake;
    }

    /// @inheritdoc IStakeManager
    function getEpochFirstStakedOrLastPenalized(uint32 stakerId) external view override returns (uint32) {
        return stakers[stakerId].epochFirstStakedOrLastPenalized;
    }

    /// @inheritdoc IStakeManager
    function maturitiesLength() external view override returns (uint32) {
        return uint32(maturities.length);
    }

    /**
     * @notice Internal function for setting stake of the staker
     * @param _id of the staker
     * @param _stake the amount of Razor tokens staked
     */
    function _setStakerStake(
        uint32 _epoch,
        uint32 _id,
        Constants.StakeChanged reason,
        uint256 _prevStake,
        uint256 _stake
    ) internal {
        stakers[_id].stake = _stake;
        emit StakeChange(_epoch, _id, reason, _prevStake, _stake, block.timestamp);
    }

    function _setStakerReward(
        uint32 _epoch,
        uint32 _id,
        Constants.StakerRewardChanged reason,
        uint256 prevStakerReward,
        uint256 _stakerReward
    ) internal {
        stakers[_id].stakerReward = _stakerReward;
        emit StakerRewardChange(_epoch, _id, reason, prevStakerReward, _stakerReward, block.timestamp);
    }

    /**
     * @return maturity of staker
     */
    function _getMaturity(uint32 stakerId) internal view returns (uint256) {
        uint256 index = stakers[stakerId].age / 10000;

        return maturities[index];
    }

    /** @notice 1 sRZR = ? RZR
     * Used to calcualte sRZR into RZR value
     * @param _sAmount The Amount in sRZR
     * @param _currentStake The cuurent stake of associated staker
     */
    function _convertSRZRToRZR(
        uint256 _sAmount,
        uint256 _currentStake,
        uint256 _totalSupply
    ) internal pure returns (uint256) {
        return ((_sAmount * _currentStake) / _totalSupply);
    }

    /** @notice 1 RZR = ? sRZR
     * Used to calcualte RZR into sRZR value
     * @param _amount The Amount in RZR
     * @param _currentStake The cuurent stake of associated staker
     * @param _totalSupply The totalSupply of sRZR
     */
    function _convertRZRtoSRZR(
        uint256 _amount,
        uint256 _currentStake,
        uint256 _totalSupply
    ) internal pure returns (uint256) {
        // Follwoing require is included to cover case where
        // CurrentStake Becomes zero beacues of penalties,
        //this is likely scenario when staker stakes is slashed to 0 for invalid block.
        require(_currentStake != 0, "Stakers Stake is 0");
        return ((_amount * _totalSupply) / _currentStake);
    }

    /** @notice a private function being called when the staker
     * successfully withdraws his funds from the network. This is
     * being done so that the staker can unstake and withdraw his remaining funds
     * incase of partial unstake
     * @param stakerId of the staker
     */
    function _resetLock(uint32 stakerId) private {
        locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Unstake] = Structs.Lock({amount: 0, unlockAfter: 0});
        locks[msg.sender][stakers[stakerId].tokenAddress][LockType.Withdraw] = Structs.Lock({amount: 0, unlockAfter: 0});
        emit ResetLock(stakerId, msg.sender, _getEpoch());
    }
}
        

@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/security/Pausable.sol

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

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}
          

@openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
}
          

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

@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/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/child/StakeManagerParams.sol

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

abstract contract StakeManagerParams is ACL, IStakeManagerParams, Constants {
    struct SlashNums {
        // percent bounty from staker's stake to be received by the bounty hunter
        uint32 bounty;
        // percent RAZOR burn from staker's stake
        uint32 burn;
        // percent from staker's stake to be kept by staker
        uint32 keep;
    }
    /// @notice a boolean, if true, the default admin role can remove all the funds incase of emergency
    bool public escapeHatchEnabled = true;

    uint8 public buffer = 5;
    /// @notice the number of epochs for which the sRZRs are locked for calling unstake()
    uint16 public unstakeLockPeriod = 1;
    /// @notice the number of epochs for which the RAZORs are locked after initiating withdraw
    uint16 public withdrawLockPeriod = 1;
    /// @notice the number of epochs where staker/delegator needs to initiate withdraw
    uint16 public withdrawInitiationPeriod = 5;
    /**
     * @notice percentage stake penalty from the locked amount for extending unstake lock
     * incase withdrawInitiationPeriod was missed
     */
    uint32 public resetUnstakeLockPenalty = 100_000;
    /// @notice maximum commission stakers can charge from delegators on their profits
    uint8 public maxCommission = 20;
    /// @notice maximum commission change a staker can do
    uint8 public deltaCommission = 3;
    /// @notice the number of epochs for which a staker cant change commission once set/change
    uint16 public epochLimitForUpdateCommission = 100;
    /// @notice slashing params being used if staker is slashed. Slash Penalty = bounty + burned + kept == 100%
    SlashNums public slashNums = SlashNums(500_000, 9_500_000, 0);
    /// @notice minimum amount of stake required to participate
    uint256 public minStake = 20000 * (10**18);
    /// @notice minimum amount of stake required to become a staker
    uint256 public minSafeRazor = 10000 * (10**18);

    /// @inheritdoc IStakeManagerParams
    function setSlashParams(
        uint32 _bounty,
        uint32 _burn,
        uint32 _keep
    ) external override onlyRole(GOVERNANCE_ROLE) {
        require(_bounty + _burn + _keep <= BASE_DENOMINATOR, "params sum exceeds denominator");
        // slither-disable-next-line events-maths
        slashNums = SlashNums(_bounty, _burn, _keep);
    }

    /// @inheritdoc IStakeManagerParams
    function setDeltaCommission(uint8 _deltaCommission) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        deltaCommission = _deltaCommission;
    }

    /// @inheritdoc IStakeManagerParams
    function setEpochLimitForUpdateCommission(uint16 _epochLimitForUpdateCommission) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        epochLimitForUpdateCommission = _epochLimitForUpdateCommission;
    }

    /// @inheritdoc IStakeManagerParams
    function setUnstakeLockPeriod(uint16 _unstakeLockPeriod) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        unstakeLockPeriod = _unstakeLockPeriod;
    }

    /// @inheritdoc IStakeManagerParams
    function setWithdrawLockPeriod(uint16 _withdrawLockPeriod) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        withdrawLockPeriod = _withdrawLockPeriod;
    }

    /// @inheritdoc IStakeManagerParams
    function setWithdrawInitiationPeriod(uint16 _withdrawInitiationPeriod) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        withdrawInitiationPeriod = _withdrawInitiationPeriod;
    }

    /// @inheritdoc IStakeManagerParams
    function setResetUnstakeLockPenalty(uint32 _resetUnstakeLockPenalty) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        resetUnstakeLockPenalty = _resetUnstakeLockPenalty;
    }

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

    /// @inheritdoc IStakeManagerParams
    function setMinSafeRazor(uint256 _minSafeRazor) external override onlyRole(GOVERNANCE_ROLE) {
        require(_minSafeRazor <= minStake, "minSafeRazor beyond minStake");
        // slither-disable-next-line events-maths
        minSafeRazor = _minSafeRazor;
    }

    /// @inheritdoc IStakeManagerParams
    function setMaxCommission(uint8 _maxCommission) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        maxCommission = _maxCommission;
    }

    /// @inheritdoc IStakeManagerParams
    function disableEscapeHatch() external override onlyRole(GOVERNANCE_ROLE) {
        // slither-disable-next-line events-maths
        escapeHatchEnabled = false;
    }

    function setBufferLength(uint8 _bufferLength) external override onlyRole(GOVERNANCE_ROLE) {
        // slither-reason: Disabled across all params childs
        // as they are being called by governance contract only
        // and their before setting, we are emitting event
        // slither-disable-next-line events-maths
        buffer = _bufferLength;
    }
}
          

contracts/Core/parameters/interfaces/IStakeManagerParams.sol

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

interface IStakeManagerParams {
    /**
     * @notice changing slashing parameters
     * @dev can be called only by the the address that has the governance role
     * @param _bounty updated percent value to be set for bounty
     * @param _burn updated percent value to be set for burn
     * @param _keep updated percent value to be set for keep
     */
    function setSlashParams(
        uint32 _bounty,
        uint32 _burn,
        uint32 _keep
    ) external;

    /**
     * @notice changing the number of epochs for which the RAZORs are locked after initiating withdraw
     * @dev can be called only by the the address that has the governance role
     * @param _withdrawLockPeriod updated value to be set for withdrawLockPeriod
     */
    function setWithdrawLockPeriod(uint16 _withdrawLockPeriod) external;

    /**
     * @notice changing the number of epochs for which the sRZRs are locked for calling unstake()
     * @dev can be called only by the the address that has the governance role
     * @param _unstakeLockPeriod updated value to be set for unstakeLockPeriod
     */
    function setUnstakeLockPeriod(uint16 _unstakeLockPeriod) external;

    /**
     * @notice changing the number of epochs where staker/delegator needs to initiate withdraw
     * @dev can be called only by the the address that has the governance role
     * @param _withdrawInitiationPeriod updated value to be set for withdrawInitiationPeriod
     */
    function setWithdrawInitiationPeriod(uint16 _withdrawInitiationPeriod) external;

    /**
     * @notice changing percentage stake penalty from the locked amount for extending unstake lock
     * incase withdrawInitiationPeriod was missed
     * @dev can be called only by the the address that has the governance role
     * @param _resetUnstakePenalty updated value to be set for resetUnstakePenalty
     */
    function setResetUnstakeLockPenalty(uint32 _resetUnstakePenalty) 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 minimum amount that to be staked to become a staker
     * @dev can be called only by the the address that has the governance role
     * @param _minSafeRazor updated value to be set for minSafeRazor
     */
    function setMinSafeRazor(uint256 _minSafeRazor) external;

    /**
     * @notice changing maximum commission stakers can charge from delegators on their profits
     * @dev can be called only by the the address that has the governance role
     * @param _maxCommission updated value to be set for maxCommission
     */
    function setMaxCommission(uint8 _maxCommission) external;

    /**
     * @notice changing maximum commission change a staker can do
     * @dev can be called only by the the address that has the governance role
     * @param _deltaCommission updated value to be set for deltaCommission
     */
    function setDeltaCommission(uint8 _deltaCommission) external;

    /**
     * @notice changing the number of epochs for which a staker cant change commission once set/change
     * @dev can be called only by the the address that has the governance role
     * @param _epochLimitForUpdateCommission updated value to be set for epochLimitForUpdateCommission
     */
    function setEpochLimitForUpdateCommission(uint16 _epochLimitForUpdateCommission) external;

    /**
     * @notice sets escape hatch to false permanently
     * @dev can be called only by the the address that has the governance role
     */
    function disableEscapeHatch() 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/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/Core/storage/StakeStorage.sol

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

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

contract StakeStorage {
    enum LockType {
        Unstake,
        Withdraw
    }
    /// @notice total number of stakers
    // slither-disable-next-line constable-states
    uint32 public numStakers;
    /// @notice total number of bounties given out
    // slither-disable-next-line constable-states
    uint32 public bountyCounter;

    /// @notice mapping of staker address -> staker id info
    mapping(address => uint32) public stakerIds;
    /// @notice mapping of staker id -> staker info
    mapping(uint32 => Structs.Staker) public stakers;
    /// @notice mapping of staker/delegator address -> staker sRZR address -> LockType -> Lock info
    mapping(address => mapping(address => mapping(LockType => Structs.Lock))) public locks;
    /// @notice mapping of bounty id -> bounty lock info
    mapping(uint32 => Structs.BountyLock) public bountyLocks;
    /// @notice maturity calculation for each index = [math.floor(math.sqrt(i*10000)/2) for i in range(1,100)]
    uint16[101] public maturities = [
        50,
        70,
        86,
        100,
        111,
        122,
        132,
        141,
        150,
        158,
        165,
        173,
        180,
        187,
        193,
        200,
        206,
        212,
        217,
        223,
        229,
        234,
        239,
        244,
        250,
        254,
        259,
        264,
        269,
        273,
        278,
        282,
        287,
        291,
        295,
        300,
        304,
        308,
        312,
        316,
        320,
        324,
        327,
        331,
        335,
        339,
        342,
        346,
        350,
        353,
        357,
        360,
        364,
        367,
        370,
        374,
        377,
        380,
        384,
        387,
        390,
        393,
        396,
        400,
        403,
        406,
        409,
        412,
        415,
        418,
        421,
        424,
        427,
        430,
        433,
        435,
        438,
        441,
        444,
        447,
        450,
        452,
        455,
        458,
        460,
        463,
        466,
        469,
        471,
        474,
        476,
        479,
        482,
        484,
        487,
        489,
        492,
        494,
        497,
        500,
        502
    ];
}
          

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/Pause.sol

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/security/Pausable.sol";
import "./Core/parameters/ACL.sol";
import "./Core/storage/Constants.sol";

contract Pause is Pausable, ACL, Constants {
    function pause() external onlyRole(PAUSE_ROLE) {
        Pausable._pause();
    }

    function unpause() external onlyRole(PAUSE_ROLE) {
        Pausable._unpause();
    }
}
          

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/tokenization/IStakedToken.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IStakedToken is IERC20 {
    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function mint(
        address account,
        uint256 amount,
        uint256 razorDeposited
    ) external returns (bool);

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function burn(address account, uint256 amount) external returns (bool);

    /// @notice Used in withdraw
    // At any time via calling this one can find out how much RZR was deposited for this much sRZR
    function getRZRDeposited(address delegator, uint256 sAmount) external view returns (uint256);
}
          

contracts/tokenization/IStakedTokenFactory.sol

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

interface IStakedTokenFactory {
    /**
     * @dev a factory contract where the sRZR for a new staker is being deployed
     * @param stakeManagerAddress address of the stake Manager contract
     * @param stakedID id of the staker whom the sRZR is being deployed
     */
    function createStakedToken(address stakeManagerAddress, uint32 stakedID) external returns (address);
}
          

Contract ABI

[{"type":"event","name":"AgeChange","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint32","name":"newAge","internalType":"uint32","indexed":false},{"type":"uint8","name":"reason","internalType":"enum Constants.AgeChanged","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"CommissionChanged","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint8","name":"commission","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"Delegated","inputs":[{"type":"address","name":"delegator","internalType":"address","indexed":true},{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newStake","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalSupply","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"DelegationAcceptanceChanged","inputs":[{"type":"bool","name":"delegationEnabled","internalType":"bool","indexed":false},{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"RedeemBounty","inputs":[{"type":"uint32","name":"bountyId","internalType":"uint32","indexed":false},{"type":"address","name":"bountyHunter","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"ResetLock","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false}],"anonymous":false},{"type":"event","name":"ResetUnstakeLock","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"uint32","name":"epoch","internalType":"uint32","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":"event","name":"Slashed","inputs":[{"type":"uint32","name":"bountyId","internalType":"uint32","indexed":false},{"type":"address","name":"bountyHunter","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"SrzrTransfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true}],"anonymous":false},{"type":"event","name":"StakeChange","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint8","name":"reason","internalType":"enum Constants.StakeChanged","indexed":false},{"type":"uint256","name":"prevStake","internalType":"uint256","indexed":false},{"type":"uint256","name":"newStake","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Staked","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"address","name":"sToken","internalType":"address","indexed":false},{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newStake","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalSupply","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"StakerRewardChange","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint8","name":"reason","internalType":"enum Constants.StakerRewardChanged","indexed":false},{"type":"uint256","name":"prevStakerReward","internalType":"uint256","indexed":false},{"type":"uint256","name":"newStakerReward","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"Unstaked","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newStake","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"WithdrawInitiated","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newStake","internalType":"uint256","indexed":false},{"type":"uint256","name":"totalSupply","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrew","inputs":[{"type":"address","name":"staker","internalType":"address","indexed":true},{"type":"uint32","name":"epoch","internalType":"uint32","indexed":false},{"type":"uint32","name":"stakerId","internalType":"uint32","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false},{"type":"uint256","name":"newStake","internalType":"uint256","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"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":"uint32","name":"","internalType":"uint32"}],"name":"bountyCounter","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"redeemAfter","internalType":"uint32"},{"type":"address","name":"bountyHunter","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}],"name":"bountyLocks","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":"claimStakerReward","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"delegate","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"deltaCommission","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"disableEscapeHatch","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"epochLimitForUpdateCommission","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"escape","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"escapeHatchEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"getAge","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"getEpochFirstStakedOrLastPenalized","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getInfluence","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"getNumStakers","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"getRoleAdmin","inputs":[{"type":"bytes32","name":"role","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getStake","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"staker","internalType":"struct Structs.Staker","components":[{"type":"bool","name":"acceptDelegation","internalType":"bool"},{"type":"bool","name":"isSlashed","internalType":"bool"},{"type":"uint8","name":"commission","internalType":"uint8"},{"type":"uint32","name":"id","internalType":"uint32"},{"type":"uint32","name":"age","internalType":"uint32"},{"type":"address","name":"_address","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint32","name":"epochFirstStakedOrLastPenalized","internalType":"uint32"},{"type":"uint32","name":"epochCommissionLastUpdated","internalType":"uint32"},{"type":"uint256","name":"stake","internalType":"uint256"},{"type":"uint256","name":"stakerReward","internalType":"uint256"}]}],"name":"getStaker","inputs":[{"type":"uint32","name":"_id","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"getStakerId","inputs":[{"type":"address","name":"_address","internalType":"address"}]},{"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":"razorAddress","internalType":"address"},{"type":"address","name":"rewardManagerAddress","internalType":"address"},{"type":"address","name":"voteManagersAddress","internalType":"address"},{"type":"address","name":"stakedTokenFactoryAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initiateWithdraw","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"unlockAfter","internalType":"uint256"}],"name":"locks","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"","internalType":"address"},{"type":"uint8","name":"","internalType":"enum StakeStorage.LockType"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"maturities","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"maturitiesLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"maxCommission","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minSafeRazor","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":"numStakers","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"razor","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"redeemBounty","inputs":[{"type":"uint32","name":"bountyId","internalType":"uint32"}]},{"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":"resetUnstakeLock","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"resetUnstakeLockPenalty","inputs":[]},{"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":"setBufferLength","inputs":[{"type":"uint8","name":"_bufferLength","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDelegationAcceptance","inputs":[{"type":"bool","name":"status","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDeltaCommission","inputs":[{"type":"uint8","name":"_deltaCommission","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setEpochLimitForUpdateCommission","inputs":[{"type":"uint16","name":"_epochLimitForUpdateCommission","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxCommission","inputs":[{"type":"uint8","name":"_maxCommission","internalType":"uint8"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinSafeRazor","inputs":[{"type":"uint256","name":"_minSafeRazor","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinStake","inputs":[{"type":"uint256","name":"_minStake","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setResetUnstakeLockPenalty","inputs":[{"type":"uint32","name":"_resetUnstakeLockPenalty","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSlashParams","inputs":[{"type":"uint32","name":"_bounty","internalType":"uint32"},{"type":"uint32","name":"_burn","internalType":"uint32"},{"type":"uint32","name":"_keep","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStakerAge","inputs":[{"type":"uint32","name":"_epoch","internalType":"uint32"},{"type":"uint32","name":"_id","internalType":"uint32"},{"type":"uint32","name":"_age","internalType":"uint32"},{"type":"uint8","name":"reason","internalType":"enum Constants.AgeChanged"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStakerEpochFirstStakedOrLastPenalized","inputs":[{"type":"uint32","name":"_epoch","internalType":"uint32"},{"type":"uint32","name":"_id","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStakerReward","inputs":[{"type":"uint32","name":"_epoch","internalType":"uint32"},{"type":"uint32","name":"_id","internalType":"uint32"},{"type":"uint8","name":"reason","internalType":"enum Constants.StakerRewardChanged"},{"type":"uint256","name":"prevStakerReward","internalType":"uint256"},{"type":"uint256","name":"_stakerReward","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStakerStake","inputs":[{"type":"uint32","name":"_epoch","internalType":"uint32"},{"type":"uint32","name":"_id","internalType":"uint32"},{"type":"uint8","name":"reason","internalType":"enum Constants.StakeChanged"},{"type":"uint256","name":"prevStake","internalType":"uint256"},{"type":"uint256","name":"_stake","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setUnstakeLockPeriod","inputs":[{"type":"uint16","name":"_unstakeLockPeriod","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWithdrawInitiationPeriod","inputs":[{"type":"uint16","name":"_withdrawInitiationPeriod","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWithdrawLockPeriod","inputs":[{"type":"uint16","name":"_withdrawLockPeriod","internalType":"uint16"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"slash","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint32","name":"stakerId","internalType":"uint32"},{"type":"address","name":"bountyHunter","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"bounty","internalType":"uint32"},{"type":"uint32","name":"burn","internalType":"uint32"},{"type":"uint32","name":"keep","internalType":"uint32"}],"name":"slashNums","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"srzrTransfer","inputs":[{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"stake","inputs":[{"type":"uint32","name":"epoch","internalType":"uint32"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IStakedTokenFactory"}],"name":"stakedTokenFactory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"stakerIds","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"acceptDelegation","internalType":"bool"},{"type":"bool","name":"isSlashed","internalType":"bool"},{"type":"uint8","name":"commission","internalType":"uint8"},{"type":"uint32","name":"id","internalType":"uint32"},{"type":"uint32","name":"age","internalType":"uint32"},{"type":"address","name":"_address","internalType":"address"},{"type":"address","name":"tokenAddress","internalType":"address"},{"type":"uint32","name":"epochFirstStakedOrLastPenalized","internalType":"uint32"},{"type":"uint32","name":"epochCommissionLastUpdated","internalType":"uint32"},{"type":"uint256","name":"stake","internalType":"uint256"},{"type":"uint256","name":"stakerReward","internalType":"uint256"}],"name":"stakers","inputs":[{"type":"uint32","name":"","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"supportsInterface","inputs":[{"type":"bytes4","name":"interfaceId","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unlockWithdraw","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unstake","inputs":[{"type":"uint32","name":"stakerId","internalType":"uint32"},{"type":"uint256","name":"sAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"unstakeLockPeriod","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateCommission","inputs":[{"type":"uint8","name":"commission","internalType":"uint8"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IVoteManager"}],"name":"voteManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"withdrawInitiationPeriod","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint16","name":"","internalType":"uint16"}],"name":"withdrawLockPeriod","inputs":[]}]
              

Contract Creation Code

0x610d2060405260326080908152604660a052605660c052606460e052606f61010052607a610120526084610140908152608d610160526096610180908152609e6101a05260a56101c05260ad6101e05260b46102005260bb6102205260c16102405260c86102605260ce6102805260d46102a05260d96102c05260df6102e05260e56103005260ea6103205260ef6103405260f46103605260fa6103805260fe6103a0526101036103c0526101086103e05261010d61040052610111610420526101166104405261011a6104605261011f610480526101236104a0526101276104c05261012c6104e05261013061050052610134610520526101386105405261013c61056052610580919091526101446105a0526101476105c05261014b6105e05261014f61060052610153610620526101566106405261015a6106605261015e610680526101616106a0526101656106c0526101686106e05261016c6107005261016f6107205261017261074052610176610760526101796107805261017c6107a0526107c0526101836107e052610186610800526101896108205261018c6108405261019061086052610193610880526101966108a0526101996108c05261019c6108e05261019f610900526101a2610920526101a5610940526101a8610960526101ab610980526101ae6109a0526101b16109c0526101b36109e0526101b6610a00526101b9610a20526101bc610a40526101bf610a60526101c2610a80526101c4610aa0526101c7610ac0526101ca610ae0526101cc610b00526101cf610b20526101d2610b40526101d5610b60526101d7610b80526101da610ba0526101dc610bc0526101df610be0526101e2610c00526101e4610c20526101e7610c40526101e9610c60526101ec610c80526101ee610ca0526101f1610cc0526101f4610ce0526101f6610d0052620002bd90600590606562000413565b50600e80546e640314000186a000050001000105016001600160801b0319909116179055604080516060810182526207a12081526290f56060208201526000910152600f80546001600160601b0319166690f5600007a12017905569043c33c193756480000060105569021e19e0c9bab24000006011553480156200034157600080fd5b50600c805460ff19169055620003596000336200035f565b620004c7565b6200036b82826200036f565b5050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff166200036b576000828152600d602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620003cf3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6007830191839082156200049e5791602002820160005b838211156200046c57835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026200042a565b80156200049c5782816101000a81549061ffff02191690556002016020816001010492830192600103026200046c565b505b50620004ac929150620004b0565b5090565b5b80821115620004ac5760008155600101620004b1565b615c3e80620004d76000396000f3fe608060405234801561001057600080fd5b50600436106105e25760003560e01c80638f764cf41161030e578063c49d7356116101a7578063ea8e156a116100f9578063f056357a116100a2578063f8c8765e1161007c578063f8c8765e14611149578063fccc28131461115c578063ff84dc351461116557600080fd5b8063f056357a146110ef578063f36c8f5c14611102578063f79ca9af1461112957600080fd5b8063ed6c935d116100d3578063ed6c935d1461108f578063edaafe20146110b6578063ef8bf684146110c857600080fd5b8063ea8e156a14610f31578063eb04d42a14610f44578063eb10dec71461108757600080fd5b8063d8a41b041161015b578063dde6700f11610135578063dde6700f14610dcd578063ddea853814610e20578063e3f8b90014610f2a57600080fd5b8063d8a41b0414610d80578063da98429514610d93578063db7b499614610dba57600080fd5b8063d1b705bd1161018c578063d1b705bd14610d47578063d394b4d214610d5a578063d547741f14610d6d57600080fd5b8063c49d735614610d0e578063c8ae0d7d14610d2157600080fd5b8063a4bc17b011610260578063b56c3f2e11610214578063bc788d46116101ee578063bc788d4614610cdd578063bd85958414610cf1578063c0f4c57114610cfb57600080fd5b8063b56c3f2e14610c9b578063b76daeb514610cb7578063b829ea5914610cca57600080fd5b8063ac9d82cf11610245578063ac9d82cf14610c44578063b0daafef14610c61578063b47b55cc14610c8857600080fd5b8063a4bc17b014610c28578063ac4746ab14610c3b57600080fd5b806396e2dc5a116102c25780639cd7b5821161029c5780639cd7b58214610be8578063a0d5978714610c06578063a217fddf14610c2057600080fd5b806396e2dc5a14610b755780639c2f614f14610bc25780639cb6ed7e14610bd557600080fd5b806391d14854116102f357806391d1485414610b16578063925beaf014610b4f578063928c91d514610b6257600080fd5b80638f764cf414610aeb57806391abbe8814610afe57600080fd5b806341d296f711610480578063622f9330116103d25780637efa4f5711610386578063862114bc11610360578063862114bc14610aa4578063885fc09414610ab15780638c80fd9014610ad857600080fd5b80637efa4f5714610a555780638456cb5914610a8957806385d628fd14610a9157600080fd5b806375b68471116103b757806375b6847114610a08578063776076e714610a1b5780637ec6840f14610a4257600080fd5b8063622f9330146109cb5780636c8b052a146109f257600080fd5b806352103b93116104345780635c6583341161040e5780635c6583341461097e5780635c975abb146109915780636022a4851461099c57600080fd5b806352103b931461093157806354276dbb146109445780635b0702781461095757600080fd5b806342c1e5871161046557806342c1e587146108e45780634912b72a146108f75780634c6671051461091e57600080fd5b806341d296f7146108aa578063426dbe4e146108d157600080fd5b80632e3cd0701161053957806331e96d3a116104ed578063375b3c0a116104c7578063375b3c0a14610872578063389ed2671461087b5780633f4ba83a146108a257600080fd5b806331e96d3a146107e1578063356392401461084c57806336568abe1461085f57600080fd5b80632f50bcc41161051e5780632f50bcc41461079f5780632f67beae146107c65780633190cb93146107ce57600080fd5b80632e3cd070146107835780632f2ff15d1461078c57600080fd5b80630f4ef8a61161059b57806326bf1c031161057557806326bf1c03146107005780632968e0e4146107145780632d93b9a01461075c57600080fd5b80630f4ef8a614610689578063248a9ca3146106b45780632628490f146106d757600080fd5b80630299a90e116105cc5780630299a90e1461064757806305065cd41461065c57806305db56df1461066f57600080fd5b8062dd9981146105e757806301ffc9a714610624575b600080fd5b6106116105f53660046155f8565b63ffffffff166000908152600260208190526040909120015490565b6040519081526020015b60405180910390f35b61063761063236600461557e565b611178565b604051901515815260200161061b565b61065a6106553660046155be565b611211565b005b61061161066a3660046155f8565b611264565b610677600581565b60405160ff909116815260200161061b565b60125461069c906001600160a01b031681565b6040516001600160a01b03909116815260200161061b565b6106116106c2366004615537565b6000908152600d602052604090206001015490565b600e546106ed90640100000000900461ffff1681565b60405161ffff909116815260200161061b565b600e546106ed9062010000900461ffff1681565b6107476107223660046155f8565b63ffffffff908116600090815260026020526040902060010154600160a01b90041690565b60405163ffffffff909116815260200161061b565b6106117f912208965b92edeb3eb82a612c87b38b5e844f7539cb396f0d08ec012e511b0781565b61061160115481565b61065a61079a36600461554f565b611290565b6106117f46aaf8a125792dfff6db03d74f94fe1acaf55c8cab22f65297c15809c364465c81565b61065a6112ba565b60155461069c906001600160a01b031681565b6108226107ef3660046155f8565b6004602052600090815260409020805460019091015463ffffffff82169164010000000090046001600160a01b03169083565b6040805163ffffffff90941684526001600160a01b0390921660208401529082015260600161061b565b61065a61085a366004615537565b6114d8565b61065a61086d36600461554f565b61155a565b61061160105481565b6106117f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d81565b61065a6115e6565b6106117f91f5d9ea80c4d04985e669bc72870410b28b57afdf61c0d50d377766d86a374881565b60145461069c906001600160a01b031681565b60135461069c906001600160a01b031681565b6106117f6b7da7a33355c6e035439beb2ac6a052f1558db73f08690b1c9ef5a4e838959781565b61065a61092c3660046155f8565b61161b565b61065a61093f3660046155be565b6119e7565b61065a61095236600461573f565b611a32565b6106117fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc81565b61065a61098c3660046157cb565b611b32565b600c5460ff16610637565b6107476109aa3660046153d2565b6001600160a01b031660009081526001602052604090205463ffffffff1690565b6106117f518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba804381565b6000546107479062010000900463ffffffff1681565b61065a610a163660046155f8565b611ba2565b6106117fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80481565b61065a610a50366004615612565b611e6f565b610747610a633660046155f8565b63ffffffff90811660009081526002602052604090205467010000000000000090041690565b61065a612771565b61065a610a9f3660046154ff565b6127a3565b600e546106379060ff1681565b6106117fa3a75e7cd2b78fcc3ae2046ab93bfa4ac0b87ed7ea56646a312cbcb73eabd29481565b61065a610ae6366004615537565b61290f565b61065a610af936600461566d565b61293f565b600e546106ed906601000000000000900461ffff1681565b610637610b2436600461554f565b6000918252600d602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61065a610b5d3660046154af565b612ccf565b6106ed610b70366004615537565b612d94565b610bad610b83366004615465565b60036020908152600093845260408085208252928452828420905282529020805460019091015482565b6040805192835260208301919091520161061b565b61065a610bd0366004615612565b612dc2565b61065a610be33660046153d2565b6132b8565b600e54610677906d0100000000000000000000000000900460ff1681565b600054610747906601000000000000900463ffffffff1681565b610611600081565b61065a610c363660046155f8565b6134e4565b6106ed6104b081565b600e54610677906c01000000000000000000000000900460ff1681565b6106117ff31dda80d37c96a1a0852ace387dda52a75487d7d4eb74895e749ede3e0987b481565b61065a610c963660046157cb565b613b9f565b600e546107479068010000000000000000900463ffffffff1681565b61065a610cc53660046157cb565b613eb9565b61065a610cd83660046155be565b613f28565b60005462010000900463ffffffff16610747565b6107476298968081565b61065a610d09366004615612565b613f77565b61065a610d1c3660046155f8565b614441565b610747610d2f3660046153d2565b60016020526000908152604090205463ffffffff1681565b61065a610d55366004615781565b61449c565b61065a610d683660046155be565b614588565b61065a610d7b36600461554f565b6145fa565b61065a610d8e36600461563b565b61461f565b6106117f18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f81565b61065a610dc83660046157cb565b614698565b600f54610df99063ffffffff808216916401000000008104821691680100000000000000009091041683565b6040805163ffffffff9485168152928416602084015292169181019190915260600161061b565b610ebb610e2e3660046155f8565b6002602081905260009182526040909120805460018201549282015460039092015460ff8083169461010084048216946201000085049092169363ffffffff6301000000820481169467010000000000000083048216946001600160a01b036b01000000000000000000000090940484169493841693600160a01b8104841693600160c01b90910416918b565b604080519b15158c5299151560208c015260ff909816988a019890985263ffffffff95861660608a015293851660808901526001600160a01b0392831660a0890152911660c0870152821660e0860152166101008401526101208301919091526101408201526101600161061b565b6065610747565b61065a610f3f366004615701565b6146df565b61107a610f523660046155f8565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091525063ffffffff908116600090815260026020818152604092839020835161016081018552815460ff808216151583526101008083048216151595840195909552620100008204169582019590955263010000008504861660608201526701000000000000008504861660808201526001600160a01b036b010000000000000000000000909504851660a0820152600182015494851660c0820152600160a01b8504861660e0820152600160c01b9094049094169083015282015461012082015260039091015461014082015290565b60405161061b91906158a0565b61065a614756565b6106117fca51085219bef34771da292cb24ee4fcf0ae6bdba1a62c17d1fb7d58be80288381565b600e5461067790610100900460ff1681565b6106117fcabcaf259dd9a27f23bd8a92bacd65983c2ebf027c853f89f941715905271a8d81565b61065a6110fd3660046156a8565b61478d565b6106117f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb181565b600e546106ed906e010000000000000000000000000000900461ffff1681565b61065a61115736600461540a565b614804565b61069c61dead81565b61065a6111733660046155f8565b614911565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061120b57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161123b81614afa565b50600e805461ffff90921666010000000000000267ffff00000000000019909216919091179055565b63ffffffff811660009081526002602081905260408220015461128683614b04565b61120b9190615ab6565b6000828152600d60205260409020600101546112ab81614afa565b6112b58383614b83565b505050565b60005460ff166112ff5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064015b60405180910390fd5b611307614c25565b3360009081526001602052604090205463ffffffff168061136a5760405162461bcd60e51b815260206004820152601360248201527f7374616b657220646f65736e742065786973740000000000000000000000000060448201526064016112f6565b63ffffffff81166000908152600260205260409020600301546113cf5760405162461bcd60e51b815260206004820152601b60248201527f6e6f207374616b657252657761726420746f207472616e73666572000000000060448201526064016112f6565b60006113d9614c7a565b63ffffffff831660009081526002602052604081206003015491925061140790839085906001908590614c8d565b60145460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044015b602060405180830381600087803b15801561145457600080fd5b505af1158015611468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148c919061551b565b6112b55760405162461bcd60e51b815260206004820152601060248201527f636f756c646e74207472616e736665720000000000000000000000000000000060448201526064016112f6565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161150281614afa565b6010548211156115545760405162461bcd60e51b815260206004820152601c60248201527f6d696e5361666552617a6f72206265796f6e64206d696e5374616b650000000060448201526064016112f6565b50601155565b6001600160a01b03811633146115d85760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016112f6565b6115e28282614ce0565b5050565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d61161081614afa565b611618614d63565b50565b60005460ff1661165b5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b611663614c25565b600061166d614c7a565b33600090815260036020908152604080832063ffffffff8716845260028352818420600101546001600160a01b0316845282528083208380529091529020549091506116fb5760405162461bcd60e51b815260206004820152601960248201527f556e7374616b65204c6f636b20646f65736e742065786973740000000000000060448201526064016112f6565b33600090815260036020908152604080832063ffffffff86168452600283528184206001908101546001600160a01b0316855290835281842081855290925290912001541561178c5760405162461bcd60e51b815260206004820152601460248201527f5769746864726177204c6f636b2065786973747300000000000000000000000060448201526064016112f6565b63ffffffff82811660009081526002602090815260408083203384526003835281842060018201546001600160a01b0316808652908452828520858052909352908320600e548154929591949262989680926117f5926801000000000000000090041690615ab6565b6117ff9190615a8b565b90506000611882828660020154856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561184557600080fd5b505afa158015611859573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187d91906155e0565b614db5565b8454909150611892908390615af8565b845560028501546118a4908290615af8565b6002860155600e546118c09062010000900461ffff1687615a1d565b63ffffffff9081166001860155339088167f7bce1b5e22977d5eccc84318ccce9be3cdcc08659d25b741128b4d6cdba8932b6118fa614c7a565b60405163ffffffff909116815260200160405180910390a3604051632770a7eb60e21b8152306004820152602481018390526001600160a01b03841690639dc29fac90604401602060405180830381600087803b15801561195a57600080fd5b505af115801561196e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611992919061551b565b6119de5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e206275726e204661696c656400000000000000000000000000000060448201526064016112f6565b50505050505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1611a1181614afa565b50600e805461ffff909216620100000263ffff000019909216919091179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1611a5c81614afa565b6298968082611a6b8587615a1d565b611a759190615a1d565b63ffffffff161115611ac95760405162461bcd60e51b815260206004820152601e60248201527f706172616d732073756d20657863656564732064656e6f6d696e61746f72000060448201526064016112f6565b506040805160608101825263ffffffff94851680825293851660208201819052929094169301839052600f805467ffffffffffffffff1916909217640100000000909102176bffffffff0000000000000000191668010000000000000000909202919091179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1611b5c81614afa565b50600e805460ff9092166d0100000000000000000000000000027fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff909216919091179055565b60005460ff16611be25760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b611bea614c25565b6000611bf4614c7a565b905063ffffffff8216611c495760405162461bcd60e51b815260206004820152601360248201527f7374616b657220646f65736e742065786973740000000000000000000000000060448201526064016112f6565b63ffffffff82166000908152600260209081526040808320338452600383528184206001808301546001600160a01b03168652908452828520818652909352922090810154611cda5760405162461bcd60e51b815260206004820152601960248201527f446964206e6f7420696e6974696174652077697468647261770000000000000060448201526064016112f6565b8263ffffffff1681600101541115611d345760405162461bcd60e51b815260206004820152601a60248201527f57697468647261772065706f6368206e6f74207265616368656400000000000060448201526064016112f6565b8054611d3f85614dd4565b60028301546040805163ffffffff8781168252602082018590529181019290925242606083015286169033907f7f7cfa74eff2f836ed8a3dc832273937c9d042fa42bb342c48e4027ff53615959060800160405180910390a360145460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015611de457600080fd5b505af1158015611df8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1c919061551b565b611e685760405162461bcd60e51b815260206004820152601060248201527f636f756c646e74207472616e736665720000000000000000000000000000000060448201526064016112f6565b5050505050565b60005460ff16611eaf5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b81611eb8614c7a565b63ffffffff168163ffffffff1614611f125760405162461bcd60e51b815260206004820152600f60248201527f696e636f72726563742065706f6368000000000000000000000000000000000060448201526064016112f6565b611f1a614c25565b3360009081526001602052604081205463ffffffff1690816123cd57601154841015611f885760405162461bcd60e51b815260206004820152601c60248201527f6c657373207468616e206d696e696d756d20736166652052617a6f720000000060448201526064016112f6565b600054611fa29062010000900463ffffffff166001615a1d565b6000805465ffffffff000019166201000063ffffffff93841681029190911780835533835260016020526040808420805492849004861663ffffffff1990931683179055601554845491517f798b18b1000000000000000000000000000000000000000000000000000000008152306004820152939091049094166024830152945090916001600160a01b03169063798b18b190604401602060405180830381600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208b91906153ee565b9050604051806101600160405280600015158152602001600015158152602001600060ff168152602001600060029054906101000a900463ffffffff1663ffffffff16815260200161271063ffffffff168152602001336001600160a01b03168152602001826001600160a01b031681526020018763ffffffff168152602001600063ffffffff1681526020018681526020016000815250600260008060029054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff021916908360ff16021790555060608201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160076101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600b6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160010160146101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff160217905550610120820151816002015561014082015181600301559050506122f17fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc60001b82614eaf565b604051630ab714fb60e11b815233600482015260248101869052604481018690526001600160a01b0382169063156e29f690606401602060405180830381600087803b15801561234057600080fd5b505af1158015612354573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612378919061551b565b6123c45760405162461bcd60e51b815260206004820152601160248201527f746f6b656e73206e6f74206d696e74656400000000000000000000000000000060448201526064016112f6565b84915050612618565b63ffffffff8216600090815260026020526040902054610100900460ff16156124385760405162461bcd60e51b815260206004820152601160248201527f7374616b657220697320736c617368656400000000000000000000000000000060448201526064016112f6565b63ffffffff82166000908152600260209081526040918290206001015482516318160ddd60e01b815292516001600160a01b039091169283926318160ddd92600480840193829003018186803b15801561249157600080fd5b505afa1580156124a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c991906155e0565b63ffffffff8416600090815260026020819052604082200154919350906124f290879085614eb9565b63ffffffff85166000908152600260208190526040909120015490915061251a908790615a05565b63ffffffff8516600090815260026020819052604091829020019190915551630ab714fb60e11b815233600482015260248101829052604481018790526001600160a01b0383169063156e29f690606401602060405180830381600087803b15801561258557600080fd5b505af1158015612599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125bd919061551b565b6126095760405162461bcd60e51b815260206004820152601160248201527f746f6b656e73206e6f74206d696e74656400000000000000000000000000000060448201526064016112f6565b6126138184615a05565b925050505b63ffffffff828116600081815260026020818152604092839020600181015492015483516001600160a01b039093168352948a16908201529081018790526060810192909252608082018390524260a08301529033907f69e4507c6adfbf284c6dc43ffa3cc3336fd256f4a634676d524c4af99b947afb9060c00160405180910390a36014546040516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156126ed57600080fd5b505af1158015612701573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612725919061551b565b611e685760405162461bcd60e51b815260206004820152601560248201527f72617a6f72207472616e73666572206661696c6564000000000000000000000060448201526064016112f6565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d61279b81614afa565b611618614f13565b60005460ff166127e35760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b3360009081526001602052604090205463ffffffff16806128465760405162461bcd60e51b815260206004820152600d60248201527f7374616b6572206964203d20300000000000000000000000000000000000000060448201526064016112f6565b63ffffffff811660009081526002602052604090205462010000900460ff166128b15760405162461bcd60e51b815260206004820152601160248201527f636f6d697373696f6e206e6f742073657400000000000000000000000000000060448201526064016112f6565b63ffffffff8116600081815260026020908152604091829020805460ff1916861515908117909155915191825233917f526af3cbfda76cfae739157f7f67f7817a1b18161aa15a3b411094832b438bad910160405180910390a35050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161293981614afa565b50601055565b60005460ff1661297f5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc8046129a981614afa565b63ffffffff808416600090815260026020819052604082200154600f549092829182918181169164010000000081048216916801000000000000000090910416629896806129f78489615ab6565b612a019190615a8b565b955062989680612a1763ffffffff841689615ab6565b612a219190615a8b565b945062989680612a3763ffffffff831689615ab6565b612a419190615a8b565b93505050506000818385612a559190615a05565b612a5f9190615a05565b9050612a6b8186615af8565b63ffffffff89166000908152600260208190526040909120805461ff001916610100179055909550612aab908a908a90612aa5858a615a05565b89614f50565b83612aba575050505050612cc9565b600054612ad8906601000000000000900463ffffffff166001615a1d565b6000805463ffffffff9290921666010000000000000269ffffffff000000000000199092169190911790556040805160608101909152600e548190612b2a9061ffff640100000000909104168c615a1d565b63ffffffff90811682526001600160a01b038a8116602080850182905260409485018a9052600080546601000000000000908190048616825260048352868220885181548a860151909716640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090971690881617959095178555968601516001909401939093559154935194909304909116835290917fa8fdbd27ff2638b5c6c65d5aaefb5594b2571a5a4b81ee9835039d29abd29bb3910160405180910390a260145460405163a9059cbb60e01b815261dead6004820152602481018590526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015612c3f57600080fd5b505af1158015612c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c77919061551b565b612cc35760405162461bcd60e51b815260206004820152600d60248201527f636f756c646e2774206275726e0000000000000000000000000000000000000060448201526064016112f6565b50505050505b50505050565b60005460ff16612d0f5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc612d3981614afa565b8163ffffffff16846001600160a01b0316866001600160a01b03167fa729df287ec9fa46a55db88805ff1e184be2d5603338edc7d34f0d1bd6ff545e86604051612d8591815260200190565b60405180910390a45050505050565b60058160658110612da457600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b60005460ff16612e025760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b612e0a614c25565b60008111612e5a5760405162461bcd60e51b815260206004820152601360248201527f4e6f6e2d506f73697469766520416d6f756e740000000000000000000000000060448201526064016112f6565b63ffffffff8216612ead5760405162461bcd60e51b815260206004820152600d60248201527f7374616b65722e6964203d20300000000000000000000000000000000000000060448201526064016112f6565b63ffffffff821660009081526002602081905260409091200154612f135760405162461bcd60e51b815260206004820152601160248201527f4e6f6e706f736974697665207374616b6500000000000000000000000000000060448201526064016112f6565b33600090815260036020908152604080832063ffffffff86168452600283528184206001908101546001600160a01b03168552908352818420818552909252909120015415612fa45760405162461bcd60e51b815260206004820152601660248201527f4578697374696e67205769746864726177204c6f636b0000000000000000000060448201526064016112f6565b33600090815260036020908152604080832063ffffffff8616845260028352818420600101546001600160a01b031684528252808320838052909152902054156130305760405162461bcd60e51b815260206004820152601560248201527f4578697374696e6720556e7374616b65204c6f636b000000000000000000000060448201526064016112f6565b600061303a614c7a565b63ffffffff841660009081526002602052604090819020600181015491516370a0823160e01b8152336004820152929350916001600160a01b0390911690849082906370a082319060240160206040518083038186803b15801561309d57600080fd5b505afa1580156130b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d591906155e0565b10156131235760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420416d6f756e7400000000000000000000000000000000000060448201526064016112f6565b60408051808201909152848152600e54602082019061314c9062010000900461ffff1686615a1d565b63ffffffff9081169091523360008181526003602090815260408083206001898101546001600160a01b031685529083528184208480528352928190208651815595820151959092019490945560028601548151888516815294850189905284820152426060850152519188169290917f284cf70c0addb0da244b01aad7772606172d0429ceebf8562346226da1f377209181900360800190a36040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038216906323b872dd90606401602060405180830381600087803b15801561323457600080fd5b505af1158015613248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061326c919061551b565b611e685760405162461bcd60e51b815260206004820152601660248201527f73546f6b656e207472616e73666572206661696c65640000000000000000000060448201526064016112f6565b60005460ff166132f85760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7f518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba804361332281614afa565b61332a614fa3565b600e5460ff161561349c576014546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90849083906370a082319060240160206040518083038186803b15801561338257600080fd5b505afa158015613396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ba91906155e0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561341857600080fd5b505af115801561342c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613450919061551b565b6115e25760405162461bcd60e51b815260206004820152601560248201527f72617a6f72207472616e73666572206661696c6564000000000000000000000060448201526064016112f6565b60405162461bcd60e51b815260206004820152601860248201527f6573636170652068617463682069732064697361626c6564000000000000000060448201526064016112f6565b60005460ff166135245760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b61352c614c25565b600e5460009061354390610100900460ff16614ff5565b9050600281600581111561356757634e487b7160e01b600052602160045260246000fd5b14156135b55760405162461bcd60e51b815260206004820152601360248201527f556e7374616b653a204e412050726f706f73650000000000000000000000000060448201526064016112f6565b60038160058111156135d757634e487b7160e01b600052602160045260246000fd5b14156136255760405162461bcd60e51b815260206004820152601360248201527f556e7374616b653a204e4120446973707574650000000000000000000000000060448201526064016112f6565b63ffffffff82166136785760405162461bcd60e51b815260206004820152601360248201527f7374616b657220646f65736e742065786973740000000000000000000000000060448201526064016112f6565b6000613682614c7a565b63ffffffff84166000908152600260209081526040808320338452600383528184206001808301546001600160a01b0316865290845282852085805280855283862082875294529190932001549293509091156137215760405162461bcd60e51b815260206004820152601560248201527f5769746864726177206c6f636b2070726573656e74000000000000000000000060448201526064016112f6565b60018101546137725760405162461bcd60e51b815260206004820152600f60248201527f446964206e6f7420756e7374616b65000000000000000000000000000000000060448201526064016112f6565b8263ffffffff16816001015411156137cc5760405162461bcd60e51b815260206004820152601a60248201527f57697468647261772065706f6368206e6f74207265616368656400000000000060448201526064016112f6565b600e54600182015463ffffffff8516916137f591660100000000000090910461ffff1690615a05565b10156138435760405162461bcd60e51b815260206004820152601860248201527f496e6974696174696f6e20506572696f6420506173736564000000000000000060448201526064016112f6565b60018201546012546040517fce55bf1c00000000000000000000000000000000000000000000000000000000815263ffffffff8087166004830152881660248201526001600160a01b03928316929091169063ce55bf1c90604401600060405180830381600087803b1580156138b857600080fd5b505af11580156138cc573d6000803e3d6000fd5b50505050600061391883600001548560020154846001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561184557600080fd5b90506000811161396a5760405162461bcd60e51b815260206004820152601460248201527f4e6f2072617a6f7220746f20776974686472617700000000000000000000000060448201526064016112f6565b80846002015461397a9190615af8565b600285015560408051808201909152818152600e5460208201906139aa90640100000000900461ffff1688615a1d565b63ffffffff1690523360009081526003602090815260408083206001898101546001600160a01b0390811686529184528285208186528452828520865181559584015195019490945586548151632770a7eb60e21b81523060048201526024810191909152905193861693639dc29fac93604480840194938390030190829087803b158015613a3857600080fd5b505af1158015613a4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a70919061551b565b613abc5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e206275726e204661696c656400000000000000000000000000000060448201526064016112f6565b8663ffffffff16336001600160a01b03167f01ddc4adbcaeefa855ddf0ff13d9ba01d2b2d502568b64e7877815a0febd164987848860020154876001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613b2e57600080fd5b505afa158015613b42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b6691906155e0565b6040805163ffffffff9095168552602085019390935291830152606082015242608082015260a00160405180910390a350505050505050565b60005460ff16613bdf5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b600e5460ff6c0100000000000000000000000090910481169082161115613c485760405162461bcd60e51b815260206004820152601b60248201527f436f6d6d697373696f6e2065786365656473206d61786c696d6974000000000060448201526064016112f6565b3360009081526001602052604090205463ffffffff1680613cab5760405162461bcd60e51b815260206004820152600d60248201527f7374616b6572206964203d20300000000000000000000000000000000000000060448201526064016112f6565b6000613cb5614c7a565b63ffffffff808416600090815260026020526040902060010154919250600160c01b9091041615613e1357600e5463ffffffff83811660009081526002602052604090206001015483821692613d2a926e01000000000000000000000000000090910461ffff1691600160c01b900416615a1d565b63ffffffff161115613d7e5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c69642045706f636820466f72205570646174696f6e00000000000060448201526064016112f6565b600e5463ffffffff8316600090815260026020526040902054613dbe9160ff6d010000000000000000000000000090910481169162010000900416615a45565b60ff168360ff161115613e135760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420436f6d6d697373696f6e205570646174650000000000000060448201526064016112f6565b63ffffffff8281166000818152600260209081526040918290206001810180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9688169690960295909517909455835462ff000019166201000060ff891690810291909117909455905192835290917fca3f22003ff9513eff75548d8109f994eeb18ed421ed045c8fcf9cb0ca4dc068910160405180910390a2505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1613ee381614afa565b50600e805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1613f5281614afa565b50600e805461ffff9092166401000000000265ffff0000000019909216919091179055565b60005460ff16613fb75760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b613fbf614c25565b6000613fc9614c7a565b63ffffffff841660009081526002602052604090205490915060ff166140315760405162461bcd60e51b815260206004820152601860248201527f44656c65676574696f6e206e6f7420616363706563746564000000000000000060448201526064016112f6565b63ffffffff83166000908152600260205260409020546b01000000000000000000000090046001600160a01b03163314156140ae5760405162461bcd60e51b815260206004820152601f60248201527f5374616b65722063616e6e6f742064656c6567617465207468656d73656c660060448201526064016112f6565b63ffffffff8316600090815260026020526040902054610100900460ff16156141195760405162461bcd60e51b815260206004820152601160248201527f5374616b657220697320736c617368656400000000000000000000000000000060448201526064016112f6565b63ffffffff831660009081526002602090815260408083206001015481516318160ddd60e01b815291516001600160a01b03909116939284926318160ddd9260048083019392829003018186803b15801561417357600080fd5b505afa158015614187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ab91906155e0565b63ffffffff8616600090815260026020819052604082200154919250906141d490869084614eb9565b63ffffffff8716600090815260026020819052604090912001549091506141fc908690615a05565b63ffffffff8716600090815260026020819052604091829020019190915551630ab714fb60e11b815233600482015260248101829052604481018690526001600160a01b0384169063156e29f690606401602060405180830381600087803b15801561426757600080fd5b505af115801561427b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061429f919061551b565b6142eb5760405162461bcd60e51b815260206004820152601160248201527f746f6b656e73206e6f74206d696e74656400000000000000000000000000000060448201526064016112f6565b6142f58183615a05565b63ffffffff878116600081815260026020818152604092839020909101548251948a1685529084018a9052908301526060820183905242608083015291935033907fe7f221a1e6eb11efd48f5e36eff056810f5f2566e58fb820b7c4513ad381184d9060a00160405180910390a36014546040516323b872dd60e01b8152336004820152306024820152604481018790526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156143b557600080fd5b505af11580156143c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143ed919061551b565b6144395760405162461bcd60e51b815260206004820152601960248201527f525a5220746f6b656e207472616e73666572206661696c65640000000000000060448201526064016112f6565b505050505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161446b81614afa565b50600e805463ffffffff90921668010000000000000000026bffffffff000000000000000019909216919091179055565b60005460ff166144dc5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80461450681614afa565b63ffffffff808516600081815260026020526040908190208054938716670100000000000000026affffffff00000000000000199094169390931790925590517fd1de6af207728ad9c729a4163576e5f33ea5ed0c658cbc1c38138b45cc9a3317906145799088908790879042906159d5565b60405180910390a25050505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb16145b281614afa565b50600e805461ffff9092166e010000000000000000000000000000027fffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffff909216919091179055565b6000828152600d602052604090206001015461461581614afa565b6112b58383614ce0565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80461464981614afa565b5063ffffffff9081166000908152600260205260409020600101805491909216600160a01b027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909116179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb16146c281614afa565b50600e805460ff9092166101000261ff0019909216919091179055565b60005460ff1661471f5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80461474981614afa565b6144398686868686614c8d565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161478081614afa565b50600e805460ff19169055565b60005460ff166147cd5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc8046147f781614afa565b6144398686868686614f50565b600054610100900460ff168061481d575060005460ff16155b6148695760405162461bcd60e51b815260206004820152601c60248201527f636f6e747261637420616c726561647920696e697469616c697a65640000000060448201526064016112f6565b600054610100900460ff1615801561488b576000805461ffff19166101011790555b600061489681614afa565b50601480546001600160a01b038088167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255601280548784169083161790556013805486841690831617905560158054928516929091169190911790558015611e68576000805461ff00191690555050505050565b60005460ff166149515760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b614959614c25565b6000614963614c7a565b63ffffffff83166000908152600460205260409020600181015490549192509064010000000090046001600160a01b031633146149e25760405162461bcd60e51b815260206004820152601060248201527f496e636f72726563742043616c6c65720000000000000000000000000000000060448201526064016112f6565b63ffffffff83811660009081526004602052604090205481841691161115614a4c5760405162461bcd60e51b815260206004820152601860248201527f52656465656d2065706f6368206e6f742072656163686564000000000000000060448201526064016112f6565b63ffffffff8316600081815260046020908152604080832080547fffffffffffffffff00000000000000000000000000000000000000000000000016815560010192909255905191825233917f402359748691cbd0907d9dea5e6ce80619847c0ea4c40d40d132c5636ab6f1fc910160405180910390a260145460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb9060440161143a565b61161881336150c3565b63ffffffff80821660009081526002602052604081205490918291614b389161271091670100000000000000900416615a9f565b63ffffffff16905060058160658110614b6157634e487b7160e01b600052603260045260246000fd5b601081049190910154600f9091166002026101000a900461ffff169392505050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff166115e2576000828152600d602090815260408083206001600160a01b03851684529091529020805460ff19166001179055614be13390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600c5460ff1615614c785760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016112f6565b565b6000614c886104b042615a9f565b905090565b63ffffffff841660008181526002602052604090819020600301839055517fde807b6c1f528debb0e99189e5577e5d58307590443829017efdc44827011e1b9061457990889087908790879042906159bf565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff16156115e2576000828152600d602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b614d6b614fa3565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600081614dc28486615ab6565b614dcc9190615a8b565b949350505050565b60408051808201825260008082526020808301828152338084526003835285842063ffffffff881680865260028552878620600190810180546001600160a01b0390811689528488528a892089805288528a892099518a559551988201989098558851808a018a5287815280870188815298549095168752918552878620828752909452959093209051815592519290930191909155907fac2d4e19831eccc191fbab912fe778578b1a24e52745e9213448aeb2e72698a9614e94614c7a565b60405163ffffffff909116815260200160405180910390a350565b6115e28282614b83565b600082614f085760405162461bcd60e51b815260206004820152601260248201527f5374616b657273205374616b652069732030000000000000000000000000000060448201526064016112f6565b82614dc28386615ab6565b614f1b614c25565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258614d983390565b63ffffffff841660008181526002602081905260409182902001839055517f1c2e5b86043d93dd9a8954cc56547e8e565077977597dfc4001def9ac3306fe6906145799088908790879087904290615980565b600c5460ff16614c785760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016112f6565b6000818160ff821661500a60056104b0615a6a565b6150149190615ad5565b905061ffff811661502860056104b0615a6a565b6150369061ffff1642615b52565b118061505e575060ff821661504e60056104b0615a6a565b61505c9061ffff1642615b52565b105b1561506d575060059392505050565b6000600561507d816104b0615a6a565b61508b9061ffff1642615a8b565b6150959190615b52565b90508060ff1660058111156150ba57634e487b7160e01b600052602160045260246000fd5b95945050505050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff166115e257615101816001600160a01b03166014615143565b61510c836020615143565b60405160200161511d9291906157ec565b60408051601f198184030181529082905262461bcd60e51b82526112f69160040161586d565b60606000615152836002615ab6565b61515d906002615a05565b67ffffffffffffffff81111561518357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156151ad576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106151f257634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061526357634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061529f846002615ab6565b6152aa906001615a05565b90505b6001811115615363577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106152f957634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061531d57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361535c81615b3b565b90506152ad565b5083156153b25760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016112f6565b9392505050565b803563ffffffff811681146153cd57600080fd5b919050565b6000602082840312156153e3578081fd5b81356153b281615bb8565b6000602082840312156153ff578081fd5b81516153b281615bb8565b6000806000806080858703121561541f578283fd5b843561542a81615bb8565b9350602085013561543a81615bb8565b9250604085013561544a81615bb8565b9150606085013561545a81615bb8565b939692955090935050565b600080600060608486031215615479578283fd5b833561548481615bb8565b9250602084013561549481615bb8565b915060408401356154a481615bdb565b809150509250925092565b600080600080608085870312156154c4578384fd5b84356154cf81615bb8565b935060208501356154df81615bb8565b9250604085013591506154f4606086016153b9565b905092959194509250565b600060208284031215615510578081fd5b81356153b281615bcd565b60006020828403121561552c578081fd5b81516153b281615bcd565b600060208284031215615548578081fd5b5035919050565b60008060408385031215615561578182fd5b82359150602083013561557381615bb8565b809150509250929050565b60006020828403121561558f578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146153b2578182fd5b6000602082840312156155cf578081fd5b813561ffff811681146153b2578182fd5b6000602082840312156155f1578081fd5b5051919050565b600060208284031215615609578081fd5b6153b2826153b9565b60008060408385031215615624578182fd5b61562d836153b9565b946020939093013593505050565b6000806040838503121561564d578182fd5b615656836153b9565b9150615664602084016153b9565b90509250929050565b600080600060608486031215615681578081fd5b61568a846153b9565b9250615698602085016153b9565b915060408401356154a481615bb8565b600080600080600060a086880312156156bf578283fd5b6156c8866153b9565b94506156d6602087016153b9565b93506040860135600381106156e9578384fd5b94979396509394606081013594506080013592915050565b600080600080600060a08688031215615718578283fd5b615721866153b9565b945061572f602087016153b9565b935060408601356156e981615bdb565b600080600060608486031215615753578081fd5b61575c846153b9565b925061576a602085016153b9565b9150615778604085016153b9565b90509250925092565b60008060008060808587031215615796578182fd5b61579f856153b9565b93506157ad602086016153b9565b92506157bb604086016153b9565b9150606085013561545a81615bdb565b6000602082840312156157dc578081fd5b813560ff811681146153b2578182fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615824816017850160208801615b0f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615861816028840160208801615b0f565b01602801949350505050565b602081526000825180602084015261588c816040850160208701615b0f565b601f01601f19169190910160400192915050565b815115158152610160810160208301516158be602084018215159052565b5060408301516158d3604084018260ff169052565b5060608301516158eb606084018263ffffffff169052565b506080830151615903608084018263ffffffff169052565b5060a083015161591e60a08401826001600160a01b03169052565b5060c083015161593960c08401826001600160a01b03169052565b5060e083015161595160e084018263ffffffff169052565b506101008381015163ffffffff1690830152610120808401519083015261014092830151929091019190915290565b63ffffffff8616815260a081016003861061599d5761599d615b92565b8560208301528460408301528360608301528260808301529695505050505050565b63ffffffff8616815260a0810161599d86615ba8565b63ffffffff858116825284166020820152608081016159f384615ba8565b60408201939093526060015292915050565b60008219821115615a1857615a18615b66565b500190565b600063ffffffff808316818516808303821115615a3c57615a3c615b66565b01949350505050565b600060ff821660ff84168060ff03821115615a6257615a62615b66565b019392505050565b600061ffff80841680615a7f57615a7f615b7c565b92169190910492915050565b600082615a9a57615a9a615b7c565b500490565b600063ffffffff80841680615a7f57615a7f615b7c565b6000816000190483118215151615615ad057615ad0615b66565b500290565b600061ffff83811690831681811015615af057615af0615b66565b039392505050565b600082821015615b0a57615b0a615b66565b500390565b60005b83811015615b2a578181015183820152602001615b12565b83811115612cc95750506000910152565b600081615b4a57615b4a615b66565b506000190190565b600082615b6157615b61615b7c565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6002811061161857611618615b92565b6001600160a01b038116811461161857600080fd5b801515811461161857600080fd5b6002811061161857600080fdfe436f6e74726163742073686f756c6420626520696e697469616c697a65640000a2646970667358221220157edf16def0dc2c3dd2874988bbcd9d78b024a7ead2c79d6d98b5506d94b3af64736f6c63430008040033

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106105e25760003560e01c80638f764cf41161030e578063c49d7356116101a7578063ea8e156a116100f9578063f056357a116100a2578063f8c8765e1161007c578063f8c8765e14611149578063fccc28131461115c578063ff84dc351461116557600080fd5b8063f056357a146110ef578063f36c8f5c14611102578063f79ca9af1461112957600080fd5b8063ed6c935d116100d3578063ed6c935d1461108f578063edaafe20146110b6578063ef8bf684146110c857600080fd5b8063ea8e156a14610f31578063eb04d42a14610f44578063eb10dec71461108757600080fd5b8063d8a41b041161015b578063dde6700f11610135578063dde6700f14610dcd578063ddea853814610e20578063e3f8b90014610f2a57600080fd5b8063d8a41b0414610d80578063da98429514610d93578063db7b499614610dba57600080fd5b8063d1b705bd1161018c578063d1b705bd14610d47578063d394b4d214610d5a578063d547741f14610d6d57600080fd5b8063c49d735614610d0e578063c8ae0d7d14610d2157600080fd5b8063a4bc17b011610260578063b56c3f2e11610214578063bc788d46116101ee578063bc788d4614610cdd578063bd85958414610cf1578063c0f4c57114610cfb57600080fd5b8063b56c3f2e14610c9b578063b76daeb514610cb7578063b829ea5914610cca57600080fd5b8063ac9d82cf11610245578063ac9d82cf14610c44578063b0daafef14610c61578063b47b55cc14610c8857600080fd5b8063a4bc17b014610c28578063ac4746ab14610c3b57600080fd5b806396e2dc5a116102c25780639cd7b5821161029c5780639cd7b58214610be8578063a0d5978714610c06578063a217fddf14610c2057600080fd5b806396e2dc5a14610b755780639c2f614f14610bc25780639cb6ed7e14610bd557600080fd5b806391d14854116102f357806391d1485414610b16578063925beaf014610b4f578063928c91d514610b6257600080fd5b80638f764cf414610aeb57806391abbe8814610afe57600080fd5b806341d296f711610480578063622f9330116103d25780637efa4f5711610386578063862114bc11610360578063862114bc14610aa4578063885fc09414610ab15780638c80fd9014610ad857600080fd5b80637efa4f5714610a555780638456cb5914610a8957806385d628fd14610a9157600080fd5b806375b68471116103b757806375b6847114610a08578063776076e714610a1b5780637ec6840f14610a4257600080fd5b8063622f9330146109cb5780636c8b052a146109f257600080fd5b806352103b93116104345780635c6583341161040e5780635c6583341461097e5780635c975abb146109915780636022a4851461099c57600080fd5b806352103b931461093157806354276dbb146109445780635b0702781461095757600080fd5b806342c1e5871161046557806342c1e587146108e45780634912b72a146108f75780634c6671051461091e57600080fd5b806341d296f7146108aa578063426dbe4e146108d157600080fd5b80632e3cd0701161053957806331e96d3a116104ed578063375b3c0a116104c7578063375b3c0a14610872578063389ed2671461087b5780633f4ba83a146108a257600080fd5b806331e96d3a146107e1578063356392401461084c57806336568abe1461085f57600080fd5b80632f50bcc41161051e5780632f50bcc41461079f5780632f67beae146107c65780633190cb93146107ce57600080fd5b80632e3cd070146107835780632f2ff15d1461078c57600080fd5b80630f4ef8a61161059b57806326bf1c031161057557806326bf1c03146107005780632968e0e4146107145780632d93b9a01461075c57600080fd5b80630f4ef8a614610689578063248a9ca3146106b45780632628490f146106d757600080fd5b80630299a90e116105cc5780630299a90e1461064757806305065cd41461065c57806305db56df1461066f57600080fd5b8062dd9981146105e757806301ffc9a714610624575b600080fd5b6106116105f53660046155f8565b63ffffffff166000908152600260208190526040909120015490565b6040519081526020015b60405180910390f35b61063761063236600461557e565b611178565b604051901515815260200161061b565b61065a6106553660046155be565b611211565b005b61061161066a3660046155f8565b611264565b610677600581565b60405160ff909116815260200161061b565b60125461069c906001600160a01b031681565b6040516001600160a01b03909116815260200161061b565b6106116106c2366004615537565b6000908152600d602052604090206001015490565b600e546106ed90640100000000900461ffff1681565b60405161ffff909116815260200161061b565b600e546106ed9062010000900461ffff1681565b6107476107223660046155f8565b63ffffffff908116600090815260026020526040902060010154600160a01b90041690565b60405163ffffffff909116815260200161061b565b6106117f912208965b92edeb3eb82a612c87b38b5e844f7539cb396f0d08ec012e511b0781565b61061160115481565b61065a61079a36600461554f565b611290565b6106117f46aaf8a125792dfff6db03d74f94fe1acaf55c8cab22f65297c15809c364465c81565b61065a6112ba565b60155461069c906001600160a01b031681565b6108226107ef3660046155f8565b6004602052600090815260409020805460019091015463ffffffff82169164010000000090046001600160a01b03169083565b6040805163ffffffff90941684526001600160a01b0390921660208401529082015260600161061b565b61065a61085a366004615537565b6114d8565b61065a61086d36600461554f565b61155a565b61061160105481565b6106117f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d81565b61065a6115e6565b6106117f91f5d9ea80c4d04985e669bc72870410b28b57afdf61c0d50d377766d86a374881565b60145461069c906001600160a01b031681565b60135461069c906001600160a01b031681565b6106117f6b7da7a33355c6e035439beb2ac6a052f1558db73f08690b1c9ef5a4e838959781565b61065a61092c3660046155f8565b61161b565b61065a61093f3660046155be565b6119e7565b61065a61095236600461573f565b611a32565b6106117fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc81565b61065a61098c3660046157cb565b611b32565b600c5460ff16610637565b6107476109aa3660046153d2565b6001600160a01b031660009081526001602052604090205463ffffffff1690565b6106117f518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba804381565b6000546107479062010000900463ffffffff1681565b61065a610a163660046155f8565b611ba2565b6106117fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80481565b61065a610a50366004615612565b611e6f565b610747610a633660046155f8565b63ffffffff90811660009081526002602052604090205467010000000000000090041690565b61065a612771565b61065a610a9f3660046154ff565b6127a3565b600e546106379060ff1681565b6106117fa3a75e7cd2b78fcc3ae2046ab93bfa4ac0b87ed7ea56646a312cbcb73eabd29481565b61065a610ae6366004615537565b61290f565b61065a610af936600461566d565b61293f565b600e546106ed906601000000000000900461ffff1681565b610637610b2436600461554f565b6000918252600d602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61065a610b5d3660046154af565b612ccf565b6106ed610b70366004615537565b612d94565b610bad610b83366004615465565b60036020908152600093845260408085208252928452828420905282529020805460019091015482565b6040805192835260208301919091520161061b565b61065a610bd0366004615612565b612dc2565b61065a610be33660046153d2565b6132b8565b600e54610677906d0100000000000000000000000000900460ff1681565b600054610747906601000000000000900463ffffffff1681565b610611600081565b61065a610c363660046155f8565b6134e4565b6106ed6104b081565b600e54610677906c01000000000000000000000000900460ff1681565b6106117ff31dda80d37c96a1a0852ace387dda52a75487d7d4eb74895e749ede3e0987b481565b61065a610c963660046157cb565b613b9f565b600e546107479068010000000000000000900463ffffffff1681565b61065a610cc53660046157cb565b613eb9565b61065a610cd83660046155be565b613f28565b60005462010000900463ffffffff16610747565b6107476298968081565b61065a610d09366004615612565b613f77565b61065a610d1c3660046155f8565b614441565b610747610d2f3660046153d2565b60016020526000908152604090205463ffffffff1681565b61065a610d55366004615781565b61449c565b61065a610d683660046155be565b614588565b61065a610d7b36600461554f565b6145fa565b61065a610d8e36600461563b565b61461f565b6106117f18797bc7973e1dadee1895be2f1003818e30eae3b0e7a01eb9b2e66f3ea2771f81565b61065a610dc83660046157cb565b614698565b600f54610df99063ffffffff808216916401000000008104821691680100000000000000009091041683565b6040805163ffffffff9485168152928416602084015292169181019190915260600161061b565b610ebb610e2e3660046155f8565b6002602081905260009182526040909120805460018201549282015460039092015460ff8083169461010084048216946201000085049092169363ffffffff6301000000820481169467010000000000000083048216946001600160a01b036b01000000000000000000000090940484169493841693600160a01b8104841693600160c01b90910416918b565b604080519b15158c5299151560208c015260ff909816988a019890985263ffffffff95861660608a015293851660808901526001600160a01b0392831660a0890152911660c0870152821660e0860152166101008401526101208301919091526101408201526101600161061b565b6065610747565b61065a610f3f366004615701565b6146df565b61107a610f523660046155f8565b6040805161016081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810182905261012081018290526101408101919091525063ffffffff908116600090815260026020818152604092839020835161016081018552815460ff808216151583526101008083048216151595840195909552620100008204169582019590955263010000008504861660608201526701000000000000008504861660808201526001600160a01b036b010000000000000000000000909504851660a0820152600182015494851660c0820152600160a01b8504861660e0820152600160c01b9094049094169083015282015461012082015260039091015461014082015290565b60405161061b91906158a0565b61065a614756565b6106117fca51085219bef34771da292cb24ee4fcf0ae6bdba1a62c17d1fb7d58be80288381565b600e5461067790610100900460ff1681565b6106117fcabcaf259dd9a27f23bd8a92bacd65983c2ebf027c853f89f941715905271a8d81565b61065a6110fd3660046156a8565b61478d565b6106117f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb181565b600e546106ed906e010000000000000000000000000000900461ffff1681565b61065a61115736600461540a565b614804565b61069c61dead81565b61065a6111733660046155f8565b614911565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b00000000000000000000000000000000000000000000000000000000148061120b57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161123b81614afa565b50600e805461ffff90921666010000000000000267ffff00000000000019909216919091179055565b63ffffffff811660009081526002602081905260408220015461128683614b04565b61120b9190615ab6565b6000828152600d60205260409020600101546112ab81614afa565b6112b58383614b83565b505050565b60005460ff166112ff5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064015b60405180910390fd5b611307614c25565b3360009081526001602052604090205463ffffffff168061136a5760405162461bcd60e51b815260206004820152601360248201527f7374616b657220646f65736e742065786973740000000000000000000000000060448201526064016112f6565b63ffffffff81166000908152600260205260409020600301546113cf5760405162461bcd60e51b815260206004820152601b60248201527f6e6f207374616b657252657761726420746f207472616e73666572000000000060448201526064016112f6565b60006113d9614c7a565b63ffffffff831660009081526002602052604081206003015491925061140790839085906001908590614c8d565b60145460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044015b602060405180830381600087803b15801561145457600080fd5b505af1158015611468573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148c919061551b565b6112b55760405162461bcd60e51b815260206004820152601060248201527f636f756c646e74207472616e736665720000000000000000000000000000000060448201526064016112f6565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161150281614afa565b6010548211156115545760405162461bcd60e51b815260206004820152601c60248201527f6d696e5361666552617a6f72206265796f6e64206d696e5374616b650000000060448201526064016112f6565b50601155565b6001600160a01b03811633146115d85760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084016112f6565b6115e28282614ce0565b5050565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d61161081614afa565b611618614d63565b50565b60005460ff1661165b5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b611663614c25565b600061166d614c7a565b33600090815260036020908152604080832063ffffffff8716845260028352818420600101546001600160a01b0316845282528083208380529091529020549091506116fb5760405162461bcd60e51b815260206004820152601960248201527f556e7374616b65204c6f636b20646f65736e742065786973740000000000000060448201526064016112f6565b33600090815260036020908152604080832063ffffffff86168452600283528184206001908101546001600160a01b0316855290835281842081855290925290912001541561178c5760405162461bcd60e51b815260206004820152601460248201527f5769746864726177204c6f636b2065786973747300000000000000000000000060448201526064016112f6565b63ffffffff82811660009081526002602090815260408083203384526003835281842060018201546001600160a01b0316808652908452828520858052909352908320600e548154929591949262989680926117f5926801000000000000000090041690615ab6565b6117ff9190615a8b565b90506000611882828660020154856001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561184557600080fd5b505afa158015611859573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061187d91906155e0565b614db5565b8454909150611892908390615af8565b845560028501546118a4908290615af8565b6002860155600e546118c09062010000900461ffff1687615a1d565b63ffffffff9081166001860155339088167f7bce1b5e22977d5eccc84318ccce9be3cdcc08659d25b741128b4d6cdba8932b6118fa614c7a565b60405163ffffffff909116815260200160405180910390a3604051632770a7eb60e21b8152306004820152602481018390526001600160a01b03841690639dc29fac90604401602060405180830381600087803b15801561195a57600080fd5b505af115801561196e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611992919061551b565b6119de5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e206275726e204661696c656400000000000000000000000000000060448201526064016112f6565b50505050505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1611a1181614afa565b50600e805461ffff909216620100000263ffff000019909216919091179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1611a5c81614afa565b6298968082611a6b8587615a1d565b611a759190615a1d565b63ffffffff161115611ac95760405162461bcd60e51b815260206004820152601e60248201527f706172616d732073756d20657863656564732064656e6f6d696e61746f72000060448201526064016112f6565b506040805160608101825263ffffffff94851680825293851660208201819052929094169301839052600f805467ffffffffffffffff1916909217640100000000909102176bffffffff0000000000000000191668010000000000000000909202919091179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1611b5c81614afa565b50600e805460ff9092166d0100000000000000000000000000027fffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffff909216919091179055565b60005460ff16611be25760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b611bea614c25565b6000611bf4614c7a565b905063ffffffff8216611c495760405162461bcd60e51b815260206004820152601360248201527f7374616b657220646f65736e742065786973740000000000000000000000000060448201526064016112f6565b63ffffffff82166000908152600260209081526040808320338452600383528184206001808301546001600160a01b03168652908452828520818652909352922090810154611cda5760405162461bcd60e51b815260206004820152601960248201527f446964206e6f7420696e6974696174652077697468647261770000000000000060448201526064016112f6565b8263ffffffff1681600101541115611d345760405162461bcd60e51b815260206004820152601a60248201527f57697468647261772065706f6368206e6f74207265616368656400000000000060448201526064016112f6565b8054611d3f85614dd4565b60028301546040805163ffffffff8781168252602082018590529181019290925242606083015286169033907f7f7cfa74eff2f836ed8a3dc832273937c9d042fa42bb342c48e4027ff53615959060800160405180910390a360145460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015611de457600080fd5b505af1158015611df8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e1c919061551b565b611e685760405162461bcd60e51b815260206004820152601060248201527f636f756c646e74207472616e736665720000000000000000000000000000000060448201526064016112f6565b5050505050565b60005460ff16611eaf5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b81611eb8614c7a565b63ffffffff168163ffffffff1614611f125760405162461bcd60e51b815260206004820152600f60248201527f696e636f72726563742065706f6368000000000000000000000000000000000060448201526064016112f6565b611f1a614c25565b3360009081526001602052604081205463ffffffff1690816123cd57601154841015611f885760405162461bcd60e51b815260206004820152601c60248201527f6c657373207468616e206d696e696d756d20736166652052617a6f720000000060448201526064016112f6565b600054611fa29062010000900463ffffffff166001615a1d565b6000805465ffffffff000019166201000063ffffffff93841681029190911780835533835260016020526040808420805492849004861663ffffffff1990931683179055601554845491517f798b18b1000000000000000000000000000000000000000000000000000000008152306004820152939091049094166024830152945090916001600160a01b03169063798b18b190604401602060405180830381600087803b15801561205357600080fd5b505af1158015612067573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061208b91906153ee565b9050604051806101600160405280600015158152602001600015158152602001600060ff168152602001600060029054906101000a900463ffffffff1663ffffffff16815260200161271063ffffffff168152602001336001600160a01b03168152602001826001600160a01b031681526020018763ffffffff168152602001600063ffffffff1681526020018681526020016000815250600260008060029054906101000a900463ffffffff1663ffffffff1663ffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548160ff021916908360ff16021790555060608201518160000160036101000a81548163ffffffff021916908363ffffffff16021790555060808201518160000160076101000a81548163ffffffff021916908363ffffffff16021790555060a082015181600001600b6101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160010160146101000a81548163ffffffff021916908363ffffffff1602179055506101008201518160010160186101000a81548163ffffffff021916908363ffffffff160217905550610120820151816002015561014082015181600301559050506122f17fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc60001b82614eaf565b604051630ab714fb60e11b815233600482015260248101869052604481018690526001600160a01b0382169063156e29f690606401602060405180830381600087803b15801561234057600080fd5b505af1158015612354573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612378919061551b565b6123c45760405162461bcd60e51b815260206004820152601160248201527f746f6b656e73206e6f74206d696e74656400000000000000000000000000000060448201526064016112f6565b84915050612618565b63ffffffff8216600090815260026020526040902054610100900460ff16156124385760405162461bcd60e51b815260206004820152601160248201527f7374616b657220697320736c617368656400000000000000000000000000000060448201526064016112f6565b63ffffffff82166000908152600260209081526040918290206001015482516318160ddd60e01b815292516001600160a01b039091169283926318160ddd92600480840193829003018186803b15801561249157600080fd5b505afa1580156124a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124c991906155e0565b63ffffffff8416600090815260026020819052604082200154919350906124f290879085614eb9565b63ffffffff85166000908152600260208190526040909120015490915061251a908790615a05565b63ffffffff8516600090815260026020819052604091829020019190915551630ab714fb60e11b815233600482015260248101829052604481018790526001600160a01b0383169063156e29f690606401602060405180830381600087803b15801561258557600080fd5b505af1158015612599573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125bd919061551b565b6126095760405162461bcd60e51b815260206004820152601160248201527f746f6b656e73206e6f74206d696e74656400000000000000000000000000000060448201526064016112f6565b6126138184615a05565b925050505b63ffffffff828116600081815260026020818152604092839020600181015492015483516001600160a01b039093168352948a16908201529081018790526060810192909252608082018390524260a08301529033907f69e4507c6adfbf284c6dc43ffa3cc3336fd256f4a634676d524c4af99b947afb9060c00160405180910390a36014546040516323b872dd60e01b8152336004820152306024820152604481018690526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156126ed57600080fd5b505af1158015612701573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612725919061551b565b611e685760405162461bcd60e51b815260206004820152601560248201527f72617a6f72207472616e73666572206661696c6564000000000000000000000060448201526064016112f6565b7f139c2898040ef16910dc9f44dc697df79363da767d8bc92f2e310312b816e46d61279b81614afa565b611618614f13565b60005460ff166127e35760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b3360009081526001602052604090205463ffffffff16806128465760405162461bcd60e51b815260206004820152600d60248201527f7374616b6572206964203d20300000000000000000000000000000000000000060448201526064016112f6565b63ffffffff811660009081526002602052604090205462010000900460ff166128b15760405162461bcd60e51b815260206004820152601160248201527f636f6d697373696f6e206e6f742073657400000000000000000000000000000060448201526064016112f6565b63ffffffff8116600081815260026020908152604091829020805460ff1916861515908117909155915191825233917f526af3cbfda76cfae739157f7f67f7817a1b18161aa15a3b411094832b438bad910160405180910390a35050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161293981614afa565b50601055565b60005460ff1661297f5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc8046129a981614afa565b63ffffffff808416600090815260026020819052604082200154600f549092829182918181169164010000000081048216916801000000000000000090910416629896806129f78489615ab6565b612a019190615a8b565b955062989680612a1763ffffffff841689615ab6565b612a219190615a8b565b945062989680612a3763ffffffff831689615ab6565b612a419190615a8b565b93505050506000818385612a559190615a05565b612a5f9190615a05565b9050612a6b8186615af8565b63ffffffff89166000908152600260208190526040909120805461ff001916610100179055909550612aab908a908a90612aa5858a615a05565b89614f50565b83612aba575050505050612cc9565b600054612ad8906601000000000000900463ffffffff166001615a1d565b6000805463ffffffff9290921666010000000000000269ffffffff000000000000199092169190911790556040805160608101909152600e548190612b2a9061ffff640100000000909104168c615a1d565b63ffffffff90811682526001600160a01b038a8116602080850182905260409485018a9052600080546601000000000000908190048616825260048352868220885181548a860151909716640100000000027fffffffffffffffff00000000000000000000000000000000000000000000000090971690881617959095178555968601516001909401939093559154935194909304909116835290917fa8fdbd27ff2638b5c6c65d5aaefb5594b2571a5a4b81ee9835039d29abd29bb3910160405180910390a260145460405163a9059cbb60e01b815261dead6004820152602481018590526001600160a01b039091169063a9059cbb90604401602060405180830381600087803b158015612c3f57600080fd5b505af1158015612c53573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c77919061551b565b612cc35760405162461bcd60e51b815260206004820152600d60248201527f636f756c646e2774206275726e0000000000000000000000000000000000000060448201526064016112f6565b50505050505b50505050565b60005460ff16612d0f5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fce3e6c780f179d7a08d28e380f7be9c36d990f56515174f8adb6287c543e30dc612d3981614afa565b8163ffffffff16846001600160a01b0316866001600160a01b03167fa729df287ec9fa46a55db88805ff1e184be2d5603338edc7d34f0d1bd6ff545e86604051612d8591815260200190565b60405180910390a45050505050565b60058160658110612da457600080fd5b60109182820401919006600202915054906101000a900461ffff1681565b60005460ff16612e025760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b612e0a614c25565b60008111612e5a5760405162461bcd60e51b815260206004820152601360248201527f4e6f6e2d506f73697469766520416d6f756e740000000000000000000000000060448201526064016112f6565b63ffffffff8216612ead5760405162461bcd60e51b815260206004820152600d60248201527f7374616b65722e6964203d20300000000000000000000000000000000000000060448201526064016112f6565b63ffffffff821660009081526002602081905260409091200154612f135760405162461bcd60e51b815260206004820152601160248201527f4e6f6e706f736974697665207374616b6500000000000000000000000000000060448201526064016112f6565b33600090815260036020908152604080832063ffffffff86168452600283528184206001908101546001600160a01b03168552908352818420818552909252909120015415612fa45760405162461bcd60e51b815260206004820152601660248201527f4578697374696e67205769746864726177204c6f636b0000000000000000000060448201526064016112f6565b33600090815260036020908152604080832063ffffffff8616845260028352818420600101546001600160a01b031684528252808320838052909152902054156130305760405162461bcd60e51b815260206004820152601560248201527f4578697374696e6720556e7374616b65204c6f636b000000000000000000000060448201526064016112f6565b600061303a614c7a565b63ffffffff841660009081526002602052604090819020600181015491516370a0823160e01b8152336004820152929350916001600160a01b0390911690849082906370a082319060240160206040518083038186803b15801561309d57600080fd5b505afa1580156130b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130d591906155e0565b10156131235760405162461bcd60e51b815260206004820152600e60248201527f496e76616c696420416d6f756e7400000000000000000000000000000000000060448201526064016112f6565b60408051808201909152848152600e54602082019061314c9062010000900461ffff1686615a1d565b63ffffffff9081169091523360008181526003602090815260408083206001898101546001600160a01b031685529083528184208480528352928190208651815595820151959092019490945560028601548151888516815294850189905284820152426060850152519188169290917f284cf70c0addb0da244b01aad7772606172d0429ceebf8562346226da1f377209181900360800190a36040516323b872dd60e01b8152336004820152306024820152604481018590526001600160a01b038216906323b872dd90606401602060405180830381600087803b15801561323457600080fd5b505af1158015613248573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061326c919061551b565b611e685760405162461bcd60e51b815260206004820152601660248201527f73546f6b656e207472616e73666572206661696c65640000000000000000000060448201526064016112f6565b60005460ff166132f85760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7f518d8c39717318f051dfb836a4ebe5b3c34aa2cb7fce26c21a89745422ba804361332281614afa565b61332a614fa3565b600e5460ff161561349c576014546040516370a0823160e01b81523060048201526001600160a01b039091169063a9059cbb90849083906370a082319060240160206040518083038186803b15801561338257600080fd5b505afa158015613396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ba91906155e0565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561341857600080fd5b505af115801561342c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613450919061551b565b6115e25760405162461bcd60e51b815260206004820152601560248201527f72617a6f72207472616e73666572206661696c6564000000000000000000000060448201526064016112f6565b60405162461bcd60e51b815260206004820152601860248201527f6573636170652068617463682069732064697361626c6564000000000000000060448201526064016112f6565b60005460ff166135245760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b61352c614c25565b600e5460009061354390610100900460ff16614ff5565b9050600281600581111561356757634e487b7160e01b600052602160045260246000fd5b14156135b55760405162461bcd60e51b815260206004820152601360248201527f556e7374616b653a204e412050726f706f73650000000000000000000000000060448201526064016112f6565b60038160058111156135d757634e487b7160e01b600052602160045260246000fd5b14156136255760405162461bcd60e51b815260206004820152601360248201527f556e7374616b653a204e4120446973707574650000000000000000000000000060448201526064016112f6565b63ffffffff82166136785760405162461bcd60e51b815260206004820152601360248201527f7374616b657220646f65736e742065786973740000000000000000000000000060448201526064016112f6565b6000613682614c7a565b63ffffffff84166000908152600260209081526040808320338452600383528184206001808301546001600160a01b0316865290845282852085805280855283862082875294529190932001549293509091156137215760405162461bcd60e51b815260206004820152601560248201527f5769746864726177206c6f636b2070726573656e74000000000000000000000060448201526064016112f6565b60018101546137725760405162461bcd60e51b815260206004820152600f60248201527f446964206e6f7420756e7374616b65000000000000000000000000000000000060448201526064016112f6565b8263ffffffff16816001015411156137cc5760405162461bcd60e51b815260206004820152601a60248201527f57697468647261772065706f6368206e6f74207265616368656400000000000060448201526064016112f6565b600e54600182015463ffffffff8516916137f591660100000000000090910461ffff1690615a05565b10156138435760405162461bcd60e51b815260206004820152601860248201527f496e6974696174696f6e20506572696f6420506173736564000000000000000060448201526064016112f6565b60018201546012546040517fce55bf1c00000000000000000000000000000000000000000000000000000000815263ffffffff8087166004830152881660248201526001600160a01b03928316929091169063ce55bf1c90604401600060405180830381600087803b1580156138b857600080fd5b505af11580156138cc573d6000803e3d6000fd5b50505050600061391883600001548560020154846001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561184557600080fd5b90506000811161396a5760405162461bcd60e51b815260206004820152601460248201527f4e6f2072617a6f7220746f20776974686472617700000000000000000000000060448201526064016112f6565b80846002015461397a9190615af8565b600285015560408051808201909152818152600e5460208201906139aa90640100000000900461ffff1688615a1d565b63ffffffff1690523360009081526003602090815260408083206001898101546001600160a01b0390811686529184528285208186528452828520865181559584015195019490945586548151632770a7eb60e21b81523060048201526024810191909152905193861693639dc29fac93604480840194938390030190829087803b158015613a3857600080fd5b505af1158015613a4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a70919061551b565b613abc5760405162461bcd60e51b815260206004820152601160248201527f546f6b656e206275726e204661696c656400000000000000000000000000000060448201526064016112f6565b8663ffffffff16336001600160a01b03167f01ddc4adbcaeefa855ddf0ff13d9ba01d2b2d502568b64e7877815a0febd164987848860020154876001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015613b2e57600080fd5b505afa158015613b42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b6691906155e0565b6040805163ffffffff9095168552602085019390935291830152606082015242608082015260a00160405180910390a350505050505050565b60005460ff16613bdf5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b600e5460ff6c0100000000000000000000000090910481169082161115613c485760405162461bcd60e51b815260206004820152601b60248201527f436f6d6d697373696f6e2065786365656473206d61786c696d6974000000000060448201526064016112f6565b3360009081526001602052604090205463ffffffff1680613cab5760405162461bcd60e51b815260206004820152600d60248201527f7374616b6572206964203d20300000000000000000000000000000000000000060448201526064016112f6565b6000613cb5614c7a565b63ffffffff808416600090815260026020526040902060010154919250600160c01b9091041615613e1357600e5463ffffffff83811660009081526002602052604090206001015483821692613d2a926e01000000000000000000000000000090910461ffff1691600160c01b900416615a1d565b63ffffffff161115613d7e5760405162461bcd60e51b815260206004820152601a60248201527f496e76616c69642045706f636820466f72205570646174696f6e00000000000060448201526064016112f6565b600e5463ffffffff8316600090815260026020526040902054613dbe9160ff6d010000000000000000000000000090910481169162010000900416615a45565b60ff168360ff161115613e135760405162461bcd60e51b815260206004820152601960248201527f496e76616c696420436f6d6d697373696f6e205570646174650000000000000060448201526064016112f6565b63ffffffff8281166000818152600260209081526040918290206001810180547fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9688169690960295909517909455835462ff000019166201000060ff891690810291909117909455905192835290917fca3f22003ff9513eff75548d8109f994eeb18ed421ed045c8fcf9cb0ca4dc068910160405180910390a2505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1613ee381614afa565b50600e805460ff9092166c01000000000000000000000000027fffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffff909216919091179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb1613f5281614afa565b50600e805461ffff9092166401000000000265ffff0000000019909216919091179055565b60005460ff16613fb75760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b613fbf614c25565b6000613fc9614c7a565b63ffffffff841660009081526002602052604090205490915060ff166140315760405162461bcd60e51b815260206004820152601860248201527f44656c65676574696f6e206e6f7420616363706563746564000000000000000060448201526064016112f6565b63ffffffff83166000908152600260205260409020546b01000000000000000000000090046001600160a01b03163314156140ae5760405162461bcd60e51b815260206004820152601f60248201527f5374616b65722063616e6e6f742064656c6567617465207468656d73656c660060448201526064016112f6565b63ffffffff8316600090815260026020526040902054610100900460ff16156141195760405162461bcd60e51b815260206004820152601160248201527f5374616b657220697320736c617368656400000000000000000000000000000060448201526064016112f6565b63ffffffff831660009081526002602090815260408083206001015481516318160ddd60e01b815291516001600160a01b03909116939284926318160ddd9260048083019392829003018186803b15801561417357600080fd5b505afa158015614187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141ab91906155e0565b63ffffffff8616600090815260026020819052604082200154919250906141d490869084614eb9565b63ffffffff8716600090815260026020819052604090912001549091506141fc908690615a05565b63ffffffff8716600090815260026020819052604091829020019190915551630ab714fb60e11b815233600482015260248101829052604481018690526001600160a01b0384169063156e29f690606401602060405180830381600087803b15801561426757600080fd5b505af115801561427b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061429f919061551b565b6142eb5760405162461bcd60e51b815260206004820152601160248201527f746f6b656e73206e6f74206d696e74656400000000000000000000000000000060448201526064016112f6565b6142f58183615a05565b63ffffffff878116600081815260026020818152604092839020909101548251948a1685529084018a9052908301526060820183905242608083015291935033907fe7f221a1e6eb11efd48f5e36eff056810f5f2566e58fb820b7c4513ad381184d9060a00160405180910390a36014546040516323b872dd60e01b8152336004820152306024820152604481018790526001600160a01b03909116906323b872dd90606401602060405180830381600087803b1580156143b557600080fd5b505af11580156143c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143ed919061551b565b6144395760405162461bcd60e51b815260206004820152601960248201527f525a5220746f6b656e207472616e73666572206661696c65640000000000000060448201526064016112f6565b505050505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161446b81614afa565b50600e805463ffffffff90921668010000000000000000026bffffffff000000000000000019909216919091179055565b60005460ff166144dc5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80461450681614afa565b63ffffffff808516600081815260026020526040908190208054938716670100000000000000026affffffff00000000000000199094169390931790925590517fd1de6af207728ad9c729a4163576e5f33ea5ed0c658cbc1c38138b45cc9a3317906145799088908790879042906159d5565b60405180910390a25050505050565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb16145b281614afa565b50600e805461ffff9092166e010000000000000000000000000000027fffffffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffff909216919091179055565b6000828152600d602052604090206001015461461581614afa565b6112b58383614ce0565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80461464981614afa565b5063ffffffff9081166000908152600260205260409020600101805491909216600160a01b027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909116179055565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb16146c281614afa565b50600e805460ff9092166101000261ff0019909216919091179055565b60005460ff1661471f5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc80461474981614afa565b6144398686868686614c8d565b7f71840dc4906352362b0cdaf79870196c8e42acafade72d5d5a6d59291253ceb161478081614afa565b50600e805460ff19169055565b60005460ff166147cd5760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b7fdbaaaff2c3744aa215ebd99971829e1c1b728703a0bf252f96685d29011fc8046147f781614afa565b6144398686868686614f50565b600054610100900460ff168061481d575060005460ff16155b6148695760405162461bcd60e51b815260206004820152601c60248201527f636f6e747261637420616c726561647920696e697469616c697a65640000000060448201526064016112f6565b600054610100900460ff1615801561488b576000805461ffff19166101011790555b600061489681614afa565b50601480546001600160a01b038088167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255601280548784169083161790556013805486841690831617905560158054928516929091169190911790558015611e68576000805461ff00191690555050505050565b60005460ff166149515760405162461bcd60e51b815260206004820152601e6024820152600080516020615be983398151915260448201526064016112f6565b614959614c25565b6000614963614c7a565b63ffffffff83166000908152600460205260409020600181015490549192509064010000000090046001600160a01b031633146149e25760405162461bcd60e51b815260206004820152601060248201527f496e636f72726563742043616c6c65720000000000000000000000000000000060448201526064016112f6565b63ffffffff83811660009081526004602052604090205481841691161115614a4c5760405162461bcd60e51b815260206004820152601860248201527f52656465656d2065706f6368206e6f742072656163686564000000000000000060448201526064016112f6565b63ffffffff8316600081815260046020908152604080832080547fffffffffffffffff00000000000000000000000000000000000000000000000016815560010192909255905191825233917f402359748691cbd0907d9dea5e6ce80619847c0ea4c40d40d132c5636ab6f1fc910160405180910390a260145460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb9060440161143a565b61161881336150c3565b63ffffffff80821660009081526002602052604081205490918291614b389161271091670100000000000000900416615a9f565b63ffffffff16905060058160658110614b6157634e487b7160e01b600052603260045260246000fd5b601081049190910154600f9091166002026101000a900461ffff169392505050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff166115e2576000828152600d602090815260408083206001600160a01b03851684529091529020805460ff19166001179055614be13390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600c5460ff1615614c785760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016112f6565b565b6000614c886104b042615a9f565b905090565b63ffffffff841660008181526002602052604090819020600301839055517fde807b6c1f528debb0e99189e5577e5d58307590443829017efdc44827011e1b9061457990889087908790879042906159bf565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff16156115e2576000828152600d602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b614d6b614fa3565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600081614dc28486615ab6565b614dcc9190615a8b565b949350505050565b60408051808201825260008082526020808301828152338084526003835285842063ffffffff881680865260028552878620600190810180546001600160a01b0390811689528488528a892089805288528a892099518a559551988201989098558851808a018a5287815280870188815298549095168752918552878620828752909452959093209051815592519290930191909155907fac2d4e19831eccc191fbab912fe778578b1a24e52745e9213448aeb2e72698a9614e94614c7a565b60405163ffffffff909116815260200160405180910390a350565b6115e28282614b83565b600082614f085760405162461bcd60e51b815260206004820152601260248201527f5374616b657273205374616b652069732030000000000000000000000000000060448201526064016112f6565b82614dc28386615ab6565b614f1b614c25565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258614d983390565b63ffffffff841660008181526002602081905260409182902001839055517f1c2e5b86043d93dd9a8954cc56547e8e565077977597dfc4001def9ac3306fe6906145799088908790879087904290615980565b600c5460ff16614c785760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016112f6565b6000818160ff821661500a60056104b0615a6a565b6150149190615ad5565b905061ffff811661502860056104b0615a6a565b6150369061ffff1642615b52565b118061505e575060ff821661504e60056104b0615a6a565b61505c9061ffff1642615b52565b105b1561506d575060059392505050565b6000600561507d816104b0615a6a565b61508b9061ffff1642615a8b565b6150959190615b52565b90508060ff1660058111156150ba57634e487b7160e01b600052602160045260246000fd5b95945050505050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff166115e257615101816001600160a01b03166014615143565b61510c836020615143565b60405160200161511d9291906157ec565b60408051601f198184030181529082905262461bcd60e51b82526112f69160040161586d565b60606000615152836002615ab6565b61515d906002615a05565b67ffffffffffffffff81111561518357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156151ad576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106151f257634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061526357634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600061529f846002615ab6565b6152aa906001615a05565b90505b6001811115615363577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106152f957634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061531d57634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361535c81615b3b565b90506152ad565b5083156153b25760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016112f6565b9392505050565b803563ffffffff811681146153cd57600080fd5b919050565b6000602082840312156153e3578081fd5b81356153b281615bb8565b6000602082840312156153ff578081fd5b81516153b281615bb8565b6000806000806080858703121561541f578283fd5b843561542a81615bb8565b9350602085013561543a81615bb8565b9250604085013561544a81615bb8565b9150606085013561545a81615bb8565b939692955090935050565b600080600060608486031215615479578283fd5b833561548481615bb8565b9250602084013561549481615bb8565b915060408401356154a481615bdb565b809150509250925092565b600080600080608085870312156154c4578384fd5b84356154cf81615bb8565b935060208501356154df81615bb8565b9250604085013591506154f4606086016153b9565b905092959194509250565b600060208284031215615510578081fd5b81356153b281615bcd565b60006020828403121561552c578081fd5b81516153b281615bcd565b600060208284031215615548578081fd5b5035919050565b60008060408385031215615561578182fd5b82359150602083013561557381615bb8565b809150509250929050565b60006020828403121561558f578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146153b2578182fd5b6000602082840312156155cf578081fd5b813561ffff811681146153b2578182fd5b6000602082840312156155f1578081fd5b5051919050565b600060208284031215615609578081fd5b6153b2826153b9565b60008060408385031215615624578182fd5b61562d836153b9565b946020939093013593505050565b6000806040838503121561564d578182fd5b615656836153b9565b9150615664602084016153b9565b90509250929050565b600080600060608486031215615681578081fd5b61568a846153b9565b9250615698602085016153b9565b915060408401356154a481615bb8565b600080600080600060a086880312156156bf578283fd5b6156c8866153b9565b94506156d6602087016153b9565b93506040860135600381106156e9578384fd5b94979396509394606081013594506080013592915050565b600080600080600060a08688031215615718578283fd5b615721866153b9565b945061572f602087016153b9565b935060408601356156e981615bdb565b600080600060608486031215615753578081fd5b61575c846153b9565b925061576a602085016153b9565b9150615778604085016153b9565b90509250925092565b60008060008060808587031215615796578182fd5b61579f856153b9565b93506157ad602086016153b9565b92506157bb604086016153b9565b9150606085013561545a81615bdb565b6000602082840312156157dc578081fd5b813560ff811681146153b2578182fd5b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615824816017850160208801615b0f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615861816028840160208801615b0f565b01602801949350505050565b602081526000825180602084015261588c816040850160208701615b0f565b601f01601f19169190910160400192915050565b815115158152610160810160208301516158be602084018215159052565b5060408301516158d3604084018260ff169052565b5060608301516158eb606084018263ffffffff169052565b506080830151615903608084018263ffffffff169052565b5060a083015161591e60a08401826001600160a01b03169052565b5060c083015161593960c08401826001600160a01b03169052565b5060e083015161595160e084018263ffffffff169052565b506101008381015163ffffffff1690830152610120808401519083015261014092830151929091019190915290565b63ffffffff8616815260a081016003861061599d5761599d615b92565b8560208301528460408301528360608301528260808301529695505050505050565b63ffffffff8616815260a0810161599d86615ba8565b63ffffffff858116825284166020820152608081016159f384615ba8565b60408201939093526060015292915050565b60008219821115615a1857615a18615b66565b500190565b600063ffffffff808316818516808303821115615a3c57615a3c615b66565b01949350505050565b600060ff821660ff84168060ff03821115615a6257615a62615b66565b019392505050565b600061ffff80841680615a7f57615a7f615b7c565b92169190910492915050565b600082615a9a57615a9a615b7c565b500490565b600063ffffffff80841680615a7f57615a7f615b7c565b6000816000190483118215151615615ad057615ad0615b66565b500290565b600061ffff83811690831681811015615af057615af0615b66565b039392505050565b600082821015615b0a57615b0a615b66565b500390565b60005b83811015615b2a578181015183820152602001615b12565b83811115612cc95750506000910152565b600081615b4a57615b4a615b66565b506000190190565b600082615b6157615b61615b7c565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b6002811061161857611618615b92565b6001600160a01b038116811461161857600080fd5b801515811461161857600080fd5b6002811061161857600080fdfe436f6e74726163742073686f756c6420626520696e697469616c697a65640000a2646970667358221220157edf16def0dc2c3dd2874988bbcd9d78b024a7ead2c79d6d98b5506d94b3af64736f6c63430008040033