Address Details
contract

0xb55c3DF43dB44492aF67743331d88cdC840CBE03

Contract Name
ETHTimeBondDepository
Creator
0x087927–0e4c89 at 0x2e831d–c3a4dd
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
1 Transactions
Transfers
0 Transfers
Gas Used
250,000
Last Balance Update
14998903
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
ETHTimeBondDepository




Optimization enabled
false
Compiler version
v0.7.5+commit.eb77ed08




EVM Version
istanbul




Verified at
2022-11-16T02:27:46.711369Z

.deps/EthBondDepository.sol

// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity 0.7.5;

interface IOwnable {
  function policy() external view returns (address);

  function renounceManagement() external;

  function pushManagement( address newOwner_ ) external;

  function pullManagement() external;
}

contract Ownable is IOwnable {

    address internal _owner;
    address internal _newOwner;

    event OwnershipPushed(address indexed previousOwner, address indexed newOwner);
    event OwnershipPulled(address indexed previousOwner, address indexed newOwner);

    constructor () {
        _owner = msg.sender;
        emit OwnershipPushed( address(0), _owner );
    }

    function policy() public view override returns (address) {
        return _owner;
    }

    modifier onlyPolicy() {
        require( _owner == msg.sender, "Ownable: caller is not the owner" );
        _;
    }

    function renounceManagement() public virtual override onlyPolicy() {
        emit OwnershipPushed( _owner, address(0) );
        _owner = address(0);
    }

    function pushManagement( address newOwner_ ) public virtual override onlyPolicy() {
        require( newOwner_ != address(0), "Ownable: new owner is the zero address");
        emit OwnershipPushed( _owner, newOwner_ );
        _newOwner = newOwner_;
    }

    function pullManagement() public virtual override {
        require( msg.sender == _newOwner, "Ownable: must be new owner to pull");
        emit OwnershipPulled( _owner, _newOwner );
        _owner = _newOwner;
    }
}

library LowGasSafeMath {
    /// @notice Returns x + y, reverts if sum overflows uint256
    /// @param x The augend
    /// @param y The addend
    /// @return z The sum of x and y
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x);
    }

    function add32(uint32 x, uint32 y) internal pure returns (uint32 z) {
        require((z = x + y) >= x);
    }

    /// @notice Returns x - y, reverts if underflows
    /// @param x The minuend
    /// @param y The subtrahend
    /// @return z The difference of x and y
    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x);
    }

    function sub32(uint32 x, uint32 y) internal pure returns (uint32 z) {
        require((z = x - y) <= x);
    }

    /// @notice Returns x * y, reverts if overflows
    /// @param x The multiplicand
    /// @param y The multiplier
    /// @return z The product of x and y
    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(x == 0 || (z = x * y) / x == y);
    }

    /// @notice Returns x + y, reverts if overflows or underflows
    /// @param x The augend
    /// @param y The addend
    /// @return z The sum of x and y
    function add(int256 x, int256 y) internal pure returns (int256 z) {
        require((z = x + y) >= x == (y >= 0));
    }

    /// @notice Returns x - y, reverts if overflows or underflows
    /// @param x The minuend
    /// @param y The subtrahend
    /// @return z The difference of x and y
    function sub(int256 x, int256 y) internal pure returns (int256 z) {
        require((z = x - y) <= x == (y >= 0));
    }
}

library Address {

    function isContract(address account) internal view returns (bool) {

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
      return functionCall(target, data, "Address: low-level call failed");
    }

    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return _functionCallWithValue(target, data, 0, errorMessage);
    }

    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _functionCallWithValue(
        address target,
        bytes memory data,
        uint256 weiValue,
        string memory errorMessage
    ) private returns (bytes memory) {
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: weiValue }(data);
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }

    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            if (returndata.length > 0) {

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }

    function addressToString(address _address) internal pure returns(string memory) {
        bytes32 _bytes = bytes32(uint256(_address));
        bytes memory HEX = "0123456789abcdef";
        bytes memory _addr = new bytes(42);

        _addr[0] = '0';
        _addr[1] = 'x';

        for(uint256 i = 0; i < 20; i++) {
            _addr[2+i*2] = HEX[uint8(_bytes[i + 12] >> 4)];
            _addr[3+i*2] = HEX[uint8(_bytes[i + 12] & 0x0f)];
        }

        return string(_addr);

    }
}

interface IERC20 {
    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address account) external view returns (uint256);

    function transfer(address recipient, uint256 amount) external returns (bool);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 amount) external returns (bool);

    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);
}

library SafeERC20 {
    using LowGasSafeMath for uint256;
    using Address for address;

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    function safeApprove(IERC20 token, address spender, uint256 value) internal {

        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).add(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender)
            .sub(value);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function _callOptionalReturn(IERC20 token, bytes memory data) private {

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

library FullMath {
    function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
        uint256 mm = mulmod(x, y, uint256(-1));
        l = x * y;
        h = mm - l;
        if (mm < l) h -= 1;
    }

    function fullDiv(
        uint256 l,
        uint256 h,
        uint256 d
    ) private pure returns (uint256) {
        uint256 pow2 = d & -d;
        d /= pow2;
        l /= pow2;
        l += h * ((-pow2) / pow2 + 1);
        uint256 r = 1;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        return l * r;
    }

    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 d
    ) internal pure returns (uint256) {
        (uint256 l, uint256 h) = fullMul(x, y);
        uint256 mm = mulmod(x, y, d);
        if (mm > l) h -= 1;
        l -= mm;
        require(h < d, 'FullMath::mulDiv: overflow');
        return fullDiv(l, h, d);
    }
}

library FixedPoint {

    struct uq112x112 {
        uint224 _x;
    }

    struct uq144x112 {
        uint256 _x;
    }

    uint8 private constant RESOLUTION = 112;
    uint256 private constant Q112 = 0x10000000000000000000000000000;
    uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;
    uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)

    function decode(uq112x112 memory self) internal pure returns (uint112) {
        return uint112(self._x >> RESOLUTION);
    }

    function decode112with18(uq112x112 memory self) internal pure returns (uint) {

        return uint(self._x) / 5192296858534827;
    }

    function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {
        require(denominator > 0, 'FixedPoint::fraction: division by zero');
        if (numerator == 0) return FixedPoint.uq112x112(0);

        if (numerator <= uint144(-1)) {
            uint256 result = (numerator << RESOLUTION) / denominator;
            require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
            return uq112x112(uint224(result));
        } else {
            uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
            require(result <= uint224(-1), 'FixedPoint::fraction: overflow');
            return uq112x112(uint224(result));
        }
    }
}

interface AggregatorV3Interface {

  function decimals() external view returns (uint8);
  function description() external view returns (string memory);
  function version() external view returns (uint256);

  // getRoundData and latestRoundData should both raise "No data present"
  // if they do not have data to report, instead of returning unset values
  // which could be misinterpreted as actual reported values.
  function getRoundData(uint80 _roundId)
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
  function latestRoundData()
    external
    view
    returns (
      uint80 roundId,
      int256 answer,
      uint256 startedAt,
      uint256 updatedAt,
      uint80 answeredInRound
    );
}

interface ITreasury {
    function deposit( uint _amount, address _token, uint _profit ) external returns ( bool );
    function valueOf( address _token, uint _amount ) external view returns ( uint value_ );
    function mintRewards( address _recipient, uint _amount ) external;
}

interface IStaking {
    function stake( uint _amount, address _recipient ) external returns ( bool );
}

interface IStakingHelper {
    function stake( uint _amount, address _recipient ) external;
}

interface IWAVAX9 is IERC20 {
    /// @notice Deposit ether to get wrapped ether
    function deposit() external payable;
}

contract ETHTimeBondDepository is Ownable {

    using FixedPoint for *;
    using SafeERC20 for IERC20;
    using SafeERC20 for IWAVAX9;
    using LowGasSafeMath for uint;
    using LowGasSafeMath for uint32;




    /* ======== EVENTS ======== */

    event BondCreated( uint deposit, uint indexed payout, uint indexed expires, uint indexed priceInUSD );
    event BondRedeemed( address indexed recipient, uint payout, uint remaining );
    event BondPriceChanged( uint indexed priceInUSD, uint indexed internalPrice, uint indexed debtRatio );
    event ControlVariableAdjustment( uint initialBCV, uint newBCV, uint adjustment, bool addition );




    /* ======== STATE VARIABLES ======== */
    IERC20 public immutable Time; // token given as payment for bond
    IWAVAX9 public immutable principle; // token used to create bond
    ITreasury public immutable treasury; // mints Time when receives principle
    address public immutable DAO; // receives profit share from bond

    AggregatorV3Interface public priceFeed;

    IStaking public staking; // to auto-stake payout
    IStakingHelper public stakingHelper; // to stake and claim if no staking warmup
    bool public useHelper;

    Terms public terms; // stores terms for new bonds
    Adjust public adjustment; // stores adjustment to BCV data

    mapping( address => Bond ) public bondInfo; // stores bond information for depositors

    uint public totalDebt; // total value of outstanding bonds; used for pricing
    uint32 public lastDecay; // reference time for debt decay


    mapping (address => bool) public allowedZappers;


    /* ======== STRUCTS ======== */

    // Info for creating new bonds
    struct Terms {
        uint controlVariable; // scaling variable for price
        uint minimumPrice; // vs principle value. 4 decimals (1500 = 0.15)
        uint maxPayout; // in thousandths of a %. i.e. 500 = 0.5%
        uint maxDebt; // 9 decimal debt ratio, max % total supply created as debt
        uint32 vestingTerm; // in seconds
    }

    // Info for bond holder
    struct Bond {
        uint payout; // Time remaining to be paid
        uint pricePaid; // In DAI, for front end viewing
        uint32 vesting; // Seconds left to vest
        uint32 lastTime; // Last interaction
    }

    // Info for incremental adjustments to control variable
    struct Adjust {
        bool add; // addition or subtraction
        uint rate; // increment
        uint target; // BCV when adjustment finished
        uint32 buffer; // minimum length (in seconds) between adjustments
        uint32 lastTime; // time when last adjustment made
    }




    /* ======== INITIALIZATION ======== */

    constructor (
        address _Time,
        address _principle,
        address _treasury,
        address _DAO,
        address _feed
    ) {
        require( _Time != address(0) );
        Time = IERC20(_Time);
        require( _principle != address(0) );
        principle = IWAVAX9(_principle);
        require( _treasury != address(0) );
        treasury = ITreasury(_treasury);
        require( _DAO != address(0) );
        DAO = _DAO;
        require( _feed != address(0) );
        priceFeed = AggregatorV3Interface( _feed );
    }

    /**
     *  @notice initializes bond parameters
     *  @param _controlVariable uint
     *  @param _vestingTerm uint
     *  @param _minimumPrice uint
     *  @param _maxPayout uint
     *  @param _maxDebt uint
     */
    function initializeBondTerms(
        uint _controlVariable,
        uint _minimumPrice,
        uint _maxPayout,
        uint _maxDebt,
        uint32 _vestingTerm
    ) external onlyPolicy() {
        require( currentDebt() == 0, "Debt must be 0 for initialization" );
        require( _controlVariable >= 40, "Can lock adjustment" );
        require( _maxPayout <= 1000, "Payout cannot be above 1 percent" );
        require( _vestingTerm >= 129600, "Vesting must be longer than 36 hours" );
        terms = Terms ({
            controlVariable: _controlVariable,
            vestingTerm: _vestingTerm,
            minimumPrice: _minimumPrice,
            maxPayout: _maxPayout,
            maxDebt: _maxDebt
        });
        lastDecay = uint32(block.timestamp);
    }




    /* ======== POLICY FUNCTIONS ======== */

    enum PARAMETER { VESTING, PAYOUT, DEBT, MINPRICE }
    /**
     *  @notice set parameters for new bonds
     *  @param _parameter PARAMETER
     *  @param _input uint
     */
    function setBondTerms ( PARAMETER _parameter, uint _input ) external onlyPolicy() {
        if ( _parameter == PARAMETER.VESTING ) { // 0
            require( _input >= 129600, "Vesting must be longer than 36 hours" );
            terms.vestingTerm = uint32(_input);
        } else if ( _parameter == PARAMETER.PAYOUT ) { // 1
            require( _input <= 1000, "Payout cannot be above 1 percent" );
            terms.maxPayout = _input;
        } else if ( _parameter == PARAMETER.DEBT ) { // 2
            terms.maxDebt = _input;
        } else if ( _parameter == PARAMETER.MINPRICE ) { // 3
            terms.minimumPrice = _input;
        }
    }

    /**
     *  @notice set control variable adjustment
     *  @param _addition bool
     *  @param _increment uint
     *  @param _target uint
     *  @param _buffer uint
     */
    function setAdjustment (
        bool _addition,
        uint _increment,
        uint _target,
        uint32 _buffer
    ) external onlyPolicy() {
        require( _increment <= terms.controlVariable.mul( 25 )/ 1000, "Increment too large" );
        require(_target >= 40, "Next Adjustment could be locked");
        adjustment = Adjust({
            add: _addition,
            rate: _increment,
            target: _target,
            buffer: _buffer,
            lastTime: uint32(block.timestamp)
        });
    }

    /**
     *  @notice set contract for auto stake
     *  @param _staking address
     *  @param _helper bool
     */
    function setStaking( address _staking, bool _helper ) external onlyPolicy() {
        require( _staking != address(0) , "IA");
        if ( _helper ) {
            useHelper = true;
            stakingHelper = IStakingHelper(_staking);
        } else {
            useHelper = false;
            staking = IStaking(_staking);
        }
    }

    function allowZapper(address zapper) external onlyPolicy {
        require(zapper != address(0), "ZNA");

        allowedZappers[zapper] = true;
    }

    function removeZapper(address zapper) external onlyPolicy {

        allowedZappers[zapper] = false;
    }




    /* ======== USER FUNCTIONS ======== */

    /**
     *  @notice deposit bond
     *  @param _amount uint
     *  @param _maxPrice uint
     *  @param _depositor address
     *  @return uint
     */
    function deposit(
        uint _amount,
        uint _maxPrice,
        address _depositor
    ) external payable returns ( uint ) {
        require( _depositor != address(0), "Invalid address" );
        require(msg.sender == _depositor || allowedZappers[msg.sender], "LFNA");
        decayDebt();
        require( totalDebt <= terms.maxDebt, "Max capacity reached" );

        uint priceInUSD = bondPriceInUSD(); // Stored in bond info
        uint nativePrice = _bondPrice();

        require( _maxPrice >= nativePrice, "Slippage limit: more than max price" ); // slippage protection

        uint value = treasury.valueOf( address(principle), _amount );
        uint payout = payoutFor( value ); // payout to bonder is computed

        require( payout >= 10000000, "Bond too small" ); // must be > 0.01 Time ( underflow protection )
        require( payout <= maxPayout(), "Bond too large"); // size protection because there is no slippage

        /**
            asset carries risk and is not minted against
            asset transfered to treasury and rewards minted as payout
         */
        if (address(this).balance >= _amount) {
            // pay with WETH9
            require(msg.value == _amount, "UA");
            principle.deposit{value: _amount}(); // wrap only what is needed to pay
            principle.transfer(address(treasury), _amount);
        } else {
            principle.safeTransferFrom( msg.sender, address(treasury), _amount );
        }

        treasury.mintRewards( address(this), payout );

        // total debt is increased
        totalDebt = totalDebt.add( value );

        // depositor info is stored
        bondInfo[ _depositor ] = Bond({
            payout: bondInfo[ _depositor ].payout.add( payout ),
            vesting: terms.vestingTerm,
            lastTime: uint32(block.timestamp),
            pricePaid: priceInUSD
        });

        // indexed events are emitted
        emit BondCreated( _amount, payout, block.timestamp.add( terms.vestingTerm ), priceInUSD );
        emit BondPriceChanged( bondPriceInUSD(), _bondPrice(), debtRatio() );

        adjust(); // control variable is adjusted
        return payout;
    }

    /**
     *  @notice redeem bond for user
     *  @param _recipient address
     *  @param _stake bool
     *  @return uint
     */
    function redeem( address _recipient, bool _stake ) external returns ( uint ) {
        require(msg.sender == _recipient, "NA");
        Bond memory info = bondInfo[ _recipient ];
        uint percentVested = percentVestedFor( _recipient ); // (seconds since last interaction / vesting term remaining)

        if ( percentVested >= 10000 ) { // if fully vested
            delete bondInfo[ _recipient ]; // delete user info
            emit BondRedeemed( _recipient, info.payout, 0 ); // emit bond data
            return stakeOrSend( _recipient, _stake, info.payout ); // pay user everything due

        } else { // if unfinished
            // calculate payout vested
            uint payout = info.payout.mul( percentVested )/ 10000;

            // store updated deposit info
            bondInfo[ _recipient ] = Bond({
                payout: info.payout.sub( payout ),
                vesting: info.vesting.sub32( uint32( block.timestamp ).sub32( info.lastTime ) ),
                lastTime: uint32( block.timestamp ),
                pricePaid: info.pricePaid
            });

            emit BondRedeemed( _recipient, payout, bondInfo[ _recipient ].payout );
            return stakeOrSend( _recipient, _stake, payout );
        }
    }




    /* ======== INTERNAL HELPER FUNCTIONS ======== */

    /**
     *  @notice allow user to stake payout automatically
     *  @param _stake bool
     *  @param _amount uint
     *  @return uint
     */
    function stakeOrSend( address _recipient, bool _stake, uint _amount ) internal returns ( uint ) {
        if ( !_stake ) { // if user does not want to stake
            Time.transfer( _recipient, _amount ); // send payout
        } else { // if user wants to stake
            if ( useHelper ) { // use if staking warmup is 0
                Time.approve( address(stakingHelper), _amount );
                stakingHelper.stake( _amount, _recipient );
            } else {
                Time.approve( address(staking), _amount );
                staking.stake( _amount, _recipient );
            }
        }
        return _amount;
    }

    /**
     *  @notice makes incremental adjustment to control variable
     */
    function adjust() internal {
         uint timeCanAdjust = adjustment.lastTime.add32( adjustment.buffer );
         if( adjustment.rate != 0 && block.timestamp >= timeCanAdjust ) {
            uint initial = terms.controlVariable;
            if ( adjustment.add ) {
                terms.controlVariable = terms.controlVariable.add( adjustment.rate );
                if ( terms.controlVariable >= adjustment.target ) {
                    adjustment.rate = 0;
                }
            } else {
                terms.controlVariable = terms.controlVariable.sub( adjustment.rate );
                if ( terms.controlVariable <= adjustment.target ) {
                    adjustment.rate = 0;
                }
            }
            adjustment.lastTime = uint32(block.timestamp);
            emit ControlVariableAdjustment( initial, terms.controlVariable, adjustment.rate, adjustment.add );
        }
    }

    /**
     *  @notice reduce total debt
     */
    function decayDebt() internal {
        totalDebt = totalDebt.sub( debtDecay() );
        lastDecay = uint32(block.timestamp);
    }




    /* ======== VIEW FUNCTIONS ======== */

    /**
     *  @notice determine maximum bond size
     *  @return uint
     */
    function maxPayout() public view returns ( uint ) {
        return Time.totalSupply().mul( terms.maxPayout )/ 100000;
    }

    /**
     *  @notice calculate interest due for new bond
     *  @param _value uint
     *  @return uint
     */
    function payoutFor( uint _value ) public view returns ( uint ) {
        return FixedPoint.fraction( _value, bondPrice() ).decode112with18()/ 1e14;
    }


    /**
     *  @notice calculate current bond premium
     *  @return price_ uint
     */
    function bondPrice() public view returns ( uint price_ ) {
        price_ = terms.controlVariable.mul( debtRatio() )/ 1e5;
        if ( price_ < terms.minimumPrice ) {
            price_ = terms.minimumPrice;
        }
    }

    /**
     *  @notice calculate current bond price and remove floor if above
     *  @return price_ uint
     */
    function _bondPrice() internal returns ( uint price_ ) {
        price_ = terms.controlVariable.mul( debtRatio() ).add( 1000000000 ) / 1e7;
        if ( price_ < terms.minimumPrice ) {
            price_ = terms.minimumPrice;
        } else if ( terms.minimumPrice != 0 ) {
            terms.minimumPrice = 0;
        }
    }

    /**
     *  @notice get asset price from chainlink
     */
    function assetPrice() public view returns (int) {
        ( , int price, , , ) = priceFeed.latestRoundData();
        return price;
    }

    /**
     *  @notice converts bond price to DAI value
     *  @return price_ uint
     */
    function bondPriceInUSD() public view returns ( uint price_ ) {
        price_ = bondPrice().mul( uint( assetPrice() ) ).mul( 1e6 );
    }


    /**
     *  @notice calculate current ratio of debt to Time supply
     *  @return debtRatio_ uint
     */
    function debtRatio() public view returns ( uint debtRatio_ ) {
        uint supply = Time.totalSupply();
        debtRatio_ = FixedPoint.fraction(
            currentDebt().mul( 1e9 ),
            supply
        ).decode112with18()/ 1e18;
    }

    /**
     *  @notice debt ratio in same terms as reserve bonds
     *  @return uint
     */
    function standardizedDebtRatio() external view returns ( uint ) {
        return debtRatio().mul( uint( assetPrice() ) )/ 10**priceFeed.decimals(); // ETH feed is 8 decimals
    }

    /**
     *  @notice calculate debt factoring in decay
     *  @return uint
     */
    function currentDebt() public view returns ( uint ) {
        return totalDebt.sub( debtDecay() );
    }

    /**
     *  @notice amount to decay total debt by
     *  @return decay_ uint
     */
    function debtDecay() public view returns ( uint decay_ ) {
        uint32 timeSinceLast = uint32(block.timestamp).sub32( lastDecay );
        decay_ = totalDebt.mul( timeSinceLast )/ terms.vestingTerm;
        if ( decay_ > totalDebt ) {
            decay_ = totalDebt;
        }
    }


    /**
     *  @notice calculate how far into vesting a depositor is
     *  @param _depositor address
     *  @return percentVested_ uint
     */
    function percentVestedFor( address _depositor ) public view returns ( uint percentVested_ ) {
        Bond memory bond = bondInfo[ _depositor ];
        uint secondsSinceLast = uint32(block.timestamp).sub32( bond.lastTime );
        uint vesting = bond.vesting;

        if ( vesting > 0 ) {
            percentVested_ = secondsSinceLast.mul( 10000 )/vesting;
        } else {
            percentVested_ = 0;
        }
    }

    /**
     *  @notice calculate amount of Time available for claim by depositor
     *  @param _depositor address
     *  @return pendingPayout_ uint
     */
    function pendingPayoutFor( address _depositor ) external view returns ( uint pendingPayout_ ) {
        uint percentVested = percentVestedFor( _depositor );
        uint payout = bondInfo[ _depositor ].payout;

        if ( percentVested >= 10000 ) {
            pendingPayout_ = payout;
        } else {
            pendingPayout_ = payout.mul( percentVested )/ 10000;
        }
    }




    /* ======= AUXILLIARY ======= */

    /**
     *  @notice allow anyone to send lost tokens (excluding principle or Time) to the DAO
     *  @return bool
     */
    function recoverLostToken( IERC20 _token ) external returns ( bool ) {
        require( _token != Time, "NAT" );
        require( _token != principle, "NAP" );
        _token.safeTransfer( DAO, _token.balanceOf( address(this) ) );
        return true;
    }

    function recoverLostETH() internal {
        if (address(this).balance > 0) safeTransferETH(DAO, address(this).balance);
    }

    /// @notice Transfers ETH to the recipient address
    /// @dev Fails with `STE`
    /// @param to The destination of the transfer
    /// @param value The value to be transferred
    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, 'STE');
    }
}
        

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_Time","internalType":"address"},{"type":"address","name":"_principle","internalType":"address"},{"type":"address","name":"_treasury","internalType":"address"},{"type":"address","name":"_DAO","internalType":"address"},{"type":"address","name":"_feed","internalType":"address"}]},{"type":"event","name":"BondCreated","inputs":[{"type":"uint256","name":"deposit","internalType":"uint256","indexed":false},{"type":"uint256","name":"payout","internalType":"uint256","indexed":true},{"type":"uint256","name":"expires","internalType":"uint256","indexed":true},{"type":"uint256","name":"priceInUSD","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"BondPriceChanged","inputs":[{"type":"uint256","name":"priceInUSD","internalType":"uint256","indexed":true},{"type":"uint256","name":"internalPrice","internalType":"uint256","indexed":true},{"type":"uint256","name":"debtRatio","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"BondRedeemed","inputs":[{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"payout","internalType":"uint256","indexed":false},{"type":"uint256","name":"remaining","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ControlVariableAdjustment","inputs":[{"type":"uint256","name":"initialBCV","internalType":"uint256","indexed":false},{"type":"uint256","name":"newBCV","internalType":"uint256","indexed":false},{"type":"uint256","name":"adjustment","internalType":"uint256","indexed":false},{"type":"bool","name":"addition","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipPulled","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"OwnershipPushed","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"DAO","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IERC20"}],"name":"Time","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"add","internalType":"bool"},{"type":"uint256","name":"rate","internalType":"uint256"},{"type":"uint256","name":"target","internalType":"uint256"},{"type":"uint32","name":"buffer","internalType":"uint32"},{"type":"uint32","name":"lastTime","internalType":"uint32"}],"name":"adjustment","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"allowZapper","inputs":[{"type":"address","name":"zapper","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"allowedZappers","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int256","name":"","internalType":"int256"}],"name":"assetPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"payout","internalType":"uint256"},{"type":"uint256","name":"pricePaid","internalType":"uint256"},{"type":"uint32","name":"vesting","internalType":"uint32"},{"type":"uint32","name":"lastTime","internalType":"uint32"}],"name":"bondInfo","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"price_","internalType":"uint256"}],"name":"bondPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"price_","internalType":"uint256"}],"name":"bondPriceInUSD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentDebt","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"decay_","internalType":"uint256"}],"name":"debtDecay","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"debtRatio_","internalType":"uint256"}],"name":"debtRatio","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"deposit","inputs":[{"type":"uint256","name":"_amount","internalType":"uint256"},{"type":"uint256","name":"_maxPrice","internalType":"uint256"},{"type":"address","name":"_depositor","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initializeBondTerms","inputs":[{"type":"uint256","name":"_controlVariable","internalType":"uint256"},{"type":"uint256","name":"_minimumPrice","internalType":"uint256"},{"type":"uint256","name":"_maxPayout","internalType":"uint256"},{"type":"uint256","name":"_maxDebt","internalType":"uint256"},{"type":"uint32","name":"_vestingTerm","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"lastDecay","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxPayout","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"payoutFor","inputs":[{"type":"uint256","name":"_value","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"pendingPayout_","internalType":"uint256"}],"name":"pendingPayoutFor","inputs":[{"type":"address","name":"_depositor","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"percentVested_","internalType":"uint256"}],"name":"percentVestedFor","inputs":[{"type":"address","name":"_depositor","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"policy","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract AggregatorV3Interface"}],"name":"priceFeed","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IWAVAX9"}],"name":"principle","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pullManagement","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pushManagement","inputs":[{"type":"address","name":"newOwner_","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"recoverLostToken","inputs":[{"type":"address","name":"_token","internalType":"contract IERC20"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"redeem","inputs":[{"type":"address","name":"_recipient","internalType":"address"},{"type":"bool","name":"_stake","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeZapper","inputs":[{"type":"address","name":"zapper","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceManagement","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAdjustment","inputs":[{"type":"bool","name":"_addition","internalType":"bool"},{"type":"uint256","name":"_increment","internalType":"uint256"},{"type":"uint256","name":"_target","internalType":"uint256"},{"type":"uint32","name":"_buffer","internalType":"uint32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setBondTerms","inputs":[{"type":"uint8","name":"_parameter","internalType":"enum ETHTimeBondDepository.PARAMETER"},{"type":"uint256","name":"_input","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setStaking","inputs":[{"type":"address","name":"_staking","internalType":"address"},{"type":"bool","name":"_helper","internalType":"bool"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IStaking"}],"name":"staking","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IStakingHelper"}],"name":"stakingHelper","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"standardizedDebtRatio","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"controlVariable","internalType":"uint256"},{"type":"uint256","name":"minimumPrice","internalType":"uint256"},{"type":"uint256","name":"maxPayout","internalType":"uint256"},{"type":"uint256","name":"maxDebt","internalType":"uint256"},{"type":"uint32","name":"vestingTerm","internalType":"uint32"}],"name":"terms","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalDebt","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ITreasury"}],"name":"treasury","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"useHelper","inputs":[]}]
              

Contract Creation Code

0x6101006040523480156200001257600080fd5b5060405162004e7738038062004e77833981810160405260a08110156200003857600080fd5b810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a3600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614156200016757600080fd5b8473ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415620001d957600080fd5b8373ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200024b57600080fd5b8273ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620002bd57600080fd5b8173ffffffffffffffffffffffffffffffffffffffff1660e08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156200032f57600080fd5b80600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050505060805160601c60a05160601c60c05160601c60e05160601c614a706200040760003980612c7452806130b4525080611f3f528061249052806127b8528061287252806128dc525080610c9152806124cc52806126fb528061277c52806128945280612fef525080612f2d52806131f9528061369452806137eb5280613848528061392f5280613ace5250614a706000f3fe6080604052600436106102255760003560e01c80637927ebf811610123578063d24378eb116100ab578063e0176de81161006f578063e0176de814610b9c578063e392a26214610bc7578063f5c2ab5b14610bf2578063f8e157ea14610c23578063fc7b9c1814610c6457610225565b8063d24378eb14610a35578063d4d863ce14610a60578063d502562514610abd578063d7ccfb0b14610b0a578063dc6549fb14610b3557610225565b806398fabd3a116100f257806398fabd3a1461087b578063ae9832cf146108bc578063b4abccba1461091d578063cd1234b314610984578063cea55f5714610a0a57610225565b80637927ebf81461076a578063844b5c7c146107b95780638dbdbe6d146107e4578063904b3ece1461085057610225565b8063451ee4a1116101b157806361d027b31161017557806361d027b31461062b57806363b3256b1461066c578063741bef1a146106bd578063759076e5146106fe57806377b818951461072957610225565b8063451ee4a1146104c857806346f68ee91461051d5780634cf088d91461056e578063507930ec146105af5780635a96ac0a1461061457610225565b80630ab69367116101f85780630ab69367146103285780631e321a0f146103915780631ed2d71a146103d95780631feed31f1461042a5780632f3f470a1461049b57610225565b8063016a42841461022a57806301b88ee81461026b5780630505c8c9146102d0578063089208d814610311575b600080fd5b34801561023657600080fd5b5061023f610c8f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561027757600080fd5b506102ba6004803603602081101561028e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cb3565b6040518082815260200191505060405180910390f35b3480156102dc57600080fd5b506102e5610d41565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561031d57600080fd5b50610326610d6a565b005b34801561033457600080fd5b5061038f600480360360a081101561034b57600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190803563ffffffff169060200190929190505050610ee9565b005b34801561039d57600080fd5b506103d7600480360360408110156103b457600080fd5b81019080803560ff16906020019092919080359060200190929190505050611204565b005b3480156103e557600080fd5b50610428600480360360208110156103fc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061146d565b005b34801561043657600080fd5b506104856004803603604081101561044d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611589565b6040518082815260200191505060405180910390f35b3480156104a757600080fd5b506104b06119e1565b60405180821515815260200191505060405180910390f35b3480156104d457600080fd5b506104dd6119f4565b6040518086151581526020018581526020018481526020018363ffffffff1681526020018263ffffffff1681526020019550505050505060405180910390f35b34801561052957600080fd5b5061056c6004803603602081101561054057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a45565b005b34801561057a57600080fd5b50610583611c4a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156105bb57600080fd5b506105fe600480360360208110156105d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c70565b6040518082815260200191505060405180910390f35b34801561062057600080fd5b50610629611d97565b005b34801561063757600080fd5b50610640611f3d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561067857600080fd5b506106bb6004803603602081101561068f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f61565b005b3480156106c957600080fd5b506106d2612120565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561070a57600080fd5b50610713612146565b6040518082815260200191505060405180910390f35b34801561073557600080fd5b5061073e612169565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561077657600080fd5b506107a36004803603602081101561078d57600080fd5b810190808035906020019092919050505061218f565b6040518082815260200191505060405180910390f35b3480156107c557600080fd5b506107ce6121c0565b6040518082815260200191505060405180910390f35b61083a600480360360608110156107fa57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121fd565b6040518082815260200191505060405180910390f35b34801561085c57600080fd5b50610865612b99565b6040518082815260200191505060405180910390f35b34801561088757600080fd5b50610890612c72565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156108c857600080fd5b5061091b600480360360808110156108df57600080fd5b810190808035151590602001909291908035906020019092919080359060200190929190803563ffffffff169060200190929190505050612c96565b005b34801561092957600080fd5b5061096c6004803603602081101561094057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f29565b60405180821515815260200191505060405180910390f35b34801561099057600080fd5b506109d3600480360360208110156109a757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131a4565b604051808581526020018481526020018363ffffffff1681526020018263ffffffff16815260200194505050505060405180910390f35b348015610a1657600080fd5b50610a1f6131f4565b6040518082815260200191505060405180910390f35b348015610a4157600080fd5b50610a4a6132e0565b6040518082815260200191505060405180910390f35b348015610a6c57600080fd5b50610abb60048036036040811015610a8357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506133bb565b005b348015610ac957600080fd5b50610ad26135e7565b604051808681526020018581526020018481526020018381526020018263ffffffff1681526020019550505050505060405180910390f35b348015610b1657600080fd5b50610b1f61361b565b6040518082815260200191505060405180910390f35b348015610b4157600080fd5b50610b8460048036036020811015610b5857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613663565b60405180821515815260200191505060405180910390f35b348015610ba857600080fd5b50610bb1613683565b6040518082815260200191505060405180910390f35b348015610bd357600080fd5b50610bdc61374e565b6040518082815260200191505060405180910390f35b348015610bfe57600080fd5b50610c076137d3565b604051808263ffffffff16815260200191505060405180910390f35b348015610c2f57600080fd5b50610c386137e9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610c7057600080fd5b50610c7961380d565b6040518082815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b600080610cbf83611c70565b90506000600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610d1957809250610d3a565b612710610d2f838361381390919063ffffffff16565b81610d3657fe5b0492505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610faa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000610fb4612146565b1461100a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806149a96021913960400191505060405180910390fd5b6028851015611081576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616e206c6f636b2061646a7573746d656e740000000000000000000000000081525060200191505060405180910390fd5b6103e88311156110f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b6201fa408163ffffffff16101561115b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806149ed6024913960400191505060405180910390fd5b6040518060a001604052808681526020018581526020018481526020018381526020018263ffffffff1681525060056000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548163ffffffff021916908363ffffffff16021790555090505042601060006101000a81548163ffffffff021916908363ffffffff1602179055505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060038111156112d257fe5b8260038111156112de57fe5b1415611369576201fa40811015611340576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806149ed6024913960400191505060405180910390fd5b80600560040160006101000a81548163ffffffff021916908363ffffffff160217905550611469565b6001600381111561137657fe5b82600381111561138257fe5b141561140f576103e8811115611400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b80600560020181905550611468565b6002600381111561141c57fe5b82600381111561142857fe5b141561143d5780600560030181905550611467565b60038081111561144957fe5b82600381111561145557fe5b141561146657806005600101819055505b5b5b5b5050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461152e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461162c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f4e4100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6116346148d5565b600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180608001604052908160008201548152602001600182015481526020016002820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160049054906101000a900463ffffffff1663ffffffff1663ffffffff1681525050905060006116eb85611c70565b905061271081106117e957600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160006101000a81549063ffffffff02191690556002820160046101000a81549063ffffffff021916905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a26117e08585846000015161383f565b925050506119db565b600061271061180583856000015161381390919063ffffffff16565b8161180c57fe5b0490506040518060800160405280611831838660000151613c9690919063ffffffff16565b81526020018460200151815260200161187961186086606001514263ffffffff16613cb090919063ffffffff16565b866040015163ffffffff16613cb090919063ffffffff16565b63ffffffff1681526020014263ffffffff16815250600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548163ffffffff021916908363ffffffff16021790555060608201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055509050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600e60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26119d586868361383f565b93505050505b92915050565b600460149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030160009054906101000a900463ffffffff16908060030160049054906101000a900463ffffffff16905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061493b6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611c7a6148d5565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180608001604052908160008201548152602001600182015481526020016002820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090506000611d4582606001514263ffffffff16613cb090919063ffffffff16565b63ffffffff1690506000826040015163ffffffff1690506000811115611d8a5780611d7b6127108461381390919063ffffffff16565b81611d8257fe5b049350611d8f565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149616022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612022576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156120c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f5a4e41000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061216461215361374e565b600f54613c9690919063ffffffff16565b905090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000655af3107a40006121b16121ac846121a761361b565b613cd6565b613fb7565b816121b857fe5b049050919050565b60006121f8620f42406121ea6121d46132e0565b6121dc61361b565b61381390919063ffffffff16565b61381390919063ffffffff16565b905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806123245750601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b612396576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f4c464e410000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61239e613ff3565b600560030154600f54111561241b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b60006124256121c0565b90506000612431614038565b90508085101561248c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806149ca6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f0000000000000000000000000000000000000000000000000000000000000000896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b15801561253d57600080fd5b505afa158015612551573d6000803e3d6000fd5b505050506040513d602081101561256757600080fd5b8101908080519060200190929190505050905060006125858261218f565b905062989680811015612600576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b612608613683565b81111561267d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b87471061286c578734146126f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f554100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0896040518263ffffffff1660e01b81526004016000604051808303818588803b15801561276157600080fd5b505af1158015612775573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb7f00000000000000000000000000000000000000000000000000000000000000008a6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561282b57600080fd5b505af115801561283f573d6000803e3d6000fd5b505050506040513d602081101561285557600080fd5b8101908080519060200190929190505050506128da565b6128d9337f00000000000000000000000000000000000000000000000000000000000000008a7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166140b4909392919063ffffffff16565b5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16636a20de9230836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561296b57600080fd5b505af115801561297f573d6000803e3d6000fd5b5050505061299882600f5461417590919063ffffffff16565b600f8190555060405180608001604052806129fe83600e60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461417590919063ffffffff16565b8152602001858152602001600560040160009054906101000a900463ffffffff1663ffffffff1681526020014263ffffffff16815250600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548163ffffffff021916908363ffffffff16021790555060608201518160020160046101000a81548163ffffffff021916908363ffffffff16021790555090505083612b07600560040160009054906101000a900463ffffffff1663ffffffff164261417590919063ffffffff16565b827f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58b6040518082815260200191505060405180910390a4612b476131f4565b612b4f614038565b612b576121c0565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a4612b8b61418f565b809450505050509392505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612c0357600080fd5b505afa158015612c17573d6000803e3d6000fd5b505050506040513d6020811015612c2d57600080fd5b810190808051906020019092919050505060ff16600a0a612c65612c4f6132e0565b612c576131f4565b61381390919063ffffffff16565b81612c6c57fe5b04905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612d57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6103e8612d73601960056000015461381390919063ffffffff16565b81612d7a57fe5b04831115612df0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6028821015612e67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6578742041646a7573746d656e7420636f756c64206265206c6f636b65640081525060200191505060405180910390fd5b6040518060a0016040528085151581526020018481526020018381526020018263ffffffff1681526020014263ffffffff16815250600a60008201518160000160006101000a81548160ff021916908315150217905550602082015181600101556040820151816002015560608201518160030160006101000a81548163ffffffff021916908363ffffffff16021790555060808201518160030160046101000a81548163ffffffff021916908363ffffffff16021790555090505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612fed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f4e4154000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156130af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f4e4150000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61319b7f00000000000000000000000000000000000000000000000000000000000000008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561313a57600080fd5b505afa15801561314e573d6000803e3d6000fd5b505050506040513d602081101561316457600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff1661433b9092919063ffffffff16565b60019050919050565b600e6020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900463ffffffff16908060020160049054906101000a900463ffffffff16905084565b6000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561325d57600080fd5b505afa158015613271573d6000803e3d6000fd5b505050506040513d602081101561328757600080fd5b81019080805190602001909291905050509050670de0b6b3a76400006132d26132cd6132c7633b9aca006132b9612146565b61381390919063ffffffff16565b84613cd6565b613fb7565b816132d957fe5b0491505090565b600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561334b57600080fd5b505afa15801561335f573d6000803e3d6000fd5b505050506040513d60a081101561337557600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050505050509150508091505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461347c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561351f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f494100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8015613586576001600460146101000a81548160ff02191690831515021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506135e3565b6000600460146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60058060000154908060010154908060020154908060030154908060040160009054906101000a900463ffffffff16905085565b6000620186a061364061362c6131f4565b60056000015461381390919063ffffffff16565b8161364757fe5b0490506005600101548110156136605760056001015490505b90565b60116020528060005260406000206000915054906101000a900460ff1681565b6000620186a06137416005600201547f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136f857600080fd5b505afa15801561370c573d6000803e3d6000fd5b505050506040513d602081101561372257600080fd5b810190808051906020019092919050505061381390919063ffffffff16565b8161374857fe5b04905090565b60008061377c601060009054906101000a900463ffffffff164263ffffffff16613cb090919063ffffffff16565b9050600560040160009054906101000a900463ffffffff1663ffffffff166137b58263ffffffff16600f5461381390919063ffffffff16565b816137bc57fe5b049150600f548211156137cf57600f5491505b5090565b601060009054906101000a900463ffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b600f5481565b600080831480613830575081838385029250828161382d57fe5b04145b61383957600080fd5b92915050565b600082613918577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156138d757600080fd5b505af11580156138eb573d6000803e3d6000fd5b505050506040513d602081101561390157600080fd5b810190808051906020019092919050505050613c8c565b600460149054906101000a900460ff1615613acc577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156139e057600080fd5b505af11580156139f4573d6000803e3d6000fd5b505050506040513d6020811015613a0a57600080fd5b810190808051906020019092919050505050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015613aaf57600080fd5b505af1158015613ac3573d6000803e3d6000fd5b50505050613c8b565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015613b7f57600080fd5b505af1158015613b93573d6000803e3d6000fd5b505050506040513d6020811015613ba957600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015613c4e57600080fd5b505af1158015613c62573d6000803e3d6000fd5b505050506040513d6020811015613c7857600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b6000828284039150811115613caa57600080fd5b92915050565b60008263ffffffff1682840391508163ffffffff161115613cd057600080fd5b92915050565b613cde614909565b60008211613d37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806149836026913960400191505060405180910390fd5b6000831415613d7557604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050613fb1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff168311613eae57600082607060ff1685901b81613dc257fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115613e79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250915050613fb1565b6000613eca846e010000000000000000000000000000856143dd565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115613f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681613feb57fe5b049050919050565b61400f613ffe61374e565b600f54613c9690919063ffffffff16565b600f8190555042601060006101000a81548163ffffffff021916908363ffffffff160217905550565b600062989680614073633b9aca006140656140516131f4565b60056000015461381390919063ffffffff16565b61417590919063ffffffff16565b8161407a57fe5b0490506005600101548110156140975760056001015490506140b1565b6000600560010154146140b05760006005600101819055505b5b90565b61416f846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061449f565b50505050565b600082828401915081101561418957600080fd5b92915050565b60006141d4600a60030160009054906101000a900463ffffffff16600a60030160049054906101000a900463ffffffff1663ffffffff1661458e90919063ffffffff16565b63ffffffff1690506000600a60010154141580156141f25750804210155b156143385760006005600001549050600a60000160009054906101000a900460ff161561426157614236600a6001015460056000015461417590919063ffffffff16565b600560000181905550600a600201546005600001541061425c576000600a600101819055505b6142a5565b61427e600a60010154600560000154613c9690919063ffffffff16565b600560000181905550600a60020154600560000154116142a4576000600a600101819055505b5b42600a60030160046101000a81548163ffffffff021916908363ffffffff1602179055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600560000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b6143d88363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061449f565b505050565b60008060006143ec86866145b4565b91509150600084806143fa57fe5b86880990508281111561440e576001820391505b8083039250848210614488576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b614493838387614607565b93505050509392505050565b6060614501826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166146a49092919063ffffffff16565b90506000815111156145895780806020019051602081101561452257600080fd5b8101908080519060200190929190505050614588576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614a11602a913960400191505060405180910390fd5b5b505050565b60008263ffffffff1682840191508163ffffffff1610156145ae57600080fd5b92915050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff806145e157fe5b848609905083850292508281039150828110156145ff576001820391505b509250929050565b600080826000038316905080838161461b57fe5b04925080858161462757fe5b049450600181826000038161463857fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b60606146b384846000856146bc565b90509392505050565b60606146c7856148c2565b614739576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106147895780518252602082019150602081019050602083039250614766565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146147eb576040519150601f19603f3d011682016040523d82523d6000602084013e6147f0565b606091505b509150915081156148055780925050506148ba565b6000815111156148185780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561487f578082015181840152602081019050614864565b50505050905090810190601f1680156148ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b60405180608001604052806000815260200160008152602001600063ffffffff168152602001600063ffffffff1681525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f44656274206d757374206265203020666f7220696e697469616c697a6174696f6e536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212204df0ba713b23133555d6844107438e5e66e8ad5be491f98f4909ea044653a3c864736f6c63430007050033000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a000000000000000000000000471ece3750da237f93b8e339c536989b8978a438000000000000000000000000ce78d38e71b5a0461e1bfe945fe62aa2b88aa6d50000000000000000000000000879270f8ba78126628595bec8d10dcdad0e4c890000000000000000000000000879270f8ba78126628595bec8d10dcdad0e4c89

Deployed ByteCode

0x6080604052600436106102255760003560e01c80637927ebf811610123578063d24378eb116100ab578063e0176de81161006f578063e0176de814610b9c578063e392a26214610bc7578063f5c2ab5b14610bf2578063f8e157ea14610c23578063fc7b9c1814610c6457610225565b8063d24378eb14610a35578063d4d863ce14610a60578063d502562514610abd578063d7ccfb0b14610b0a578063dc6549fb14610b3557610225565b806398fabd3a116100f257806398fabd3a1461087b578063ae9832cf146108bc578063b4abccba1461091d578063cd1234b314610984578063cea55f5714610a0a57610225565b80637927ebf81461076a578063844b5c7c146107b95780638dbdbe6d146107e4578063904b3ece1461085057610225565b8063451ee4a1116101b157806361d027b31161017557806361d027b31461062b57806363b3256b1461066c578063741bef1a146106bd578063759076e5146106fe57806377b818951461072957610225565b8063451ee4a1146104c857806346f68ee91461051d5780634cf088d91461056e578063507930ec146105af5780635a96ac0a1461061457610225565b80630ab69367116101f85780630ab69367146103285780631e321a0f146103915780631ed2d71a146103d95780631feed31f1461042a5780632f3f470a1461049b57610225565b8063016a42841461022a57806301b88ee81461026b5780630505c8c9146102d0578063089208d814610311575b600080fd5b34801561023657600080fd5b5061023f610c8f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561027757600080fd5b506102ba6004803603602081101561028e57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610cb3565b6040518082815260200191505060405180910390f35b3480156102dc57600080fd5b506102e5610d41565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561031d57600080fd5b50610326610d6a565b005b34801561033457600080fd5b5061038f600480360360a081101561034b57600080fd5b8101908080359060200190929190803590602001909291908035906020019092919080359060200190929190803563ffffffff169060200190929190505050610ee9565b005b34801561039d57600080fd5b506103d7600480360360408110156103b457600080fd5b81019080803560ff16906020019092919080359060200190929190505050611204565b005b3480156103e557600080fd5b50610428600480360360208110156103fc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061146d565b005b34801561043657600080fd5b506104856004803603604081101561044d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050611589565b6040518082815260200191505060405180910390f35b3480156104a757600080fd5b506104b06119e1565b60405180821515815260200191505060405180910390f35b3480156104d457600080fd5b506104dd6119f4565b6040518086151581526020018581526020018481526020018363ffffffff1681526020018263ffffffff1681526020019550505050505060405180910390f35b34801561052957600080fd5b5061056c6004803603602081101561054057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a45565b005b34801561057a57600080fd5b50610583611c4a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156105bb57600080fd5b506105fe600480360360208110156105d257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c70565b6040518082815260200191505060405180910390f35b34801561062057600080fd5b50610629611d97565b005b34801561063757600080fd5b50610640611f3d565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561067857600080fd5b506106bb6004803603602081101561068f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f61565b005b3480156106c957600080fd5b506106d2612120565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561070a57600080fd5b50610713612146565b6040518082815260200191505060405180910390f35b34801561073557600080fd5b5061073e612169565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561077657600080fd5b506107a36004803603602081101561078d57600080fd5b810190808035906020019092919050505061218f565b6040518082815260200191505060405180910390f35b3480156107c557600080fd5b506107ce6121c0565b6040518082815260200191505060405180910390f35b61083a600480360360608110156107fa57600080fd5b810190808035906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506121fd565b6040518082815260200191505060405180910390f35b34801561085c57600080fd5b50610865612b99565b6040518082815260200191505060405180910390f35b34801561088757600080fd5b50610890612c72565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156108c857600080fd5b5061091b600480360360808110156108df57600080fd5b810190808035151590602001909291908035906020019092919080359060200190929190803563ffffffff169060200190929190505050612c96565b005b34801561092957600080fd5b5061096c6004803603602081101561094057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f29565b60405180821515815260200191505060405180910390f35b34801561099057600080fd5b506109d3600480360360208110156109a757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131a4565b604051808581526020018481526020018363ffffffff1681526020018263ffffffff16815260200194505050505060405180910390f35b348015610a1657600080fd5b50610a1f6131f4565b6040518082815260200191505060405180910390f35b348015610a4157600080fd5b50610a4a6132e0565b6040518082815260200191505060405180910390f35b348015610a6c57600080fd5b50610abb60048036036040811015610a8357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035151590602001909291905050506133bb565b005b348015610ac957600080fd5b50610ad26135e7565b604051808681526020018581526020018481526020018381526020018263ffffffff1681526020019550505050505060405180910390f35b348015610b1657600080fd5b50610b1f61361b565b6040518082815260200191505060405180910390f35b348015610b4157600080fd5b50610b8460048036036020811015610b5857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613663565b60405180821515815260200191505060405180910390f35b348015610ba857600080fd5b50610bb1613683565b6040518082815260200191505060405180910390f35b348015610bd357600080fd5b50610bdc61374e565b6040518082815260200191505060405180910390f35b348015610bfe57600080fd5b50610c076137d3565b604051808263ffffffff16815260200191505060405180910390f35b348015610c2f57600080fd5b50610c386137e9565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610c7057600080fd5b50610c7961380d565b6040518082815260200191505060405180910390f35b7f000000000000000000000000471ece3750da237f93b8e339c536989b8978a43881565b600080610cbf83611c70565b90506000600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015490506127108210610d1957809250610d3a565b612710610d2f838361381390919063ffffffff16565b81610d3657fe5b0492505b5050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610e2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610faa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000610fb4612146565b1461100a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806149a96021913960400191505060405180910390fd5b6028851015611081576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616e206c6f636b2061646a7573746d656e740000000000000000000000000081525060200191505060405180910390fd5b6103e88311156110f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b6201fa408163ffffffff16101561115b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806149ed6024913960400191505060405180910390fd5b6040518060a001604052808681526020018581526020018481526020018381526020018263ffffffff1681525060056000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548163ffffffff021916908363ffffffff16021790555090505042601060006101000a81548163ffffffff021916908363ffffffff1602179055505050505050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600060038111156112d257fe5b8260038111156112de57fe5b1415611369576201fa40811015611340576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806149ed6024913960400191505060405180910390fd5b80600560040160006101000a81548163ffffffff021916908363ffffffff160217905550611469565b6001600381111561137657fe5b82600381111561138257fe5b141561140f576103e8811115611400576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f5061796f75742063616e6e6f742062652061626f766520312070657263656e7481525060200191505060405180910390fd5b80600560020181905550611468565b6002600381111561141c57fe5b82600381111561142857fe5b141561143d5780600560030181905550611467565b60038081111561144957fe5b82600381111561145557fe5b141561146657806005600101819055505b5b5b5b5050565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461152e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461162c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f4e4100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6116346148d5565b600e60008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180608001604052908160008201548152602001600182015481526020016002820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160049054906101000a900463ffffffff1663ffffffff1663ffffffff1681525050905060006116eb85611c70565b905061271081106117e957600e60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008082016000905560018201600090556002820160006101000a81549063ffffffff02191690556002820160046101000a81549063ffffffff021916905550508473ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b183600001516000604051808381526020018281526020019250505060405180910390a26117e08585846000015161383f565b925050506119db565b600061271061180583856000015161381390919063ffffffff16565b8161180c57fe5b0490506040518060800160405280611831838660000151613c9690919063ffffffff16565b81526020018460200151815260200161187961186086606001514263ffffffff16613cb090919063ffffffff16565b866040015163ffffffff16613cb090919063ffffffff16565b63ffffffff1681526020014263ffffffff16815250600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548163ffffffff021916908363ffffffff16021790555060608201518160020160046101000a81548163ffffffff021916908363ffffffff1602179055509050508573ffffffffffffffffffffffffffffffffffffffff167f51c99f515c87b0d95ba97f616edd182e8f161c4932eac17c6fefe9dab58b77b182600e60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154604051808381526020018281526020019250505060405180910390a26119d586868361383f565b93505050505b92915050565b600460149054906101000a900460ff1681565b600a8060000160009054906101000a900460ff16908060010154908060020154908060030160009054906101000a900463ffffffff16908060030160049054906101000a900463ffffffff16905085565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b8c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061493b6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167fea8258f2d9ddb679928cf34b78cf645b7feda9acc828e4dd82d014eaae270eba60405160405180910390a380600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000611c7a6148d5565b600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180608001604052908160008201548152602001600182015481526020016002820160009054906101000a900463ffffffff1663ffffffff1663ffffffff1681526020016002820160049054906101000a900463ffffffff1663ffffffff1663ffffffff168152505090506000611d4582606001514263ffffffff16613cb090919063ffffffff16565b63ffffffff1690506000826040015163ffffffff1690506000811115611d8a5780611d7b6127108461381390919063ffffffff16565b81611d8257fe5b049350611d8f565b600093505b505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e3d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149616022913960400191505060405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167faa151555690c956fc3ea32f106bb9f119b5237a061eaa8557cff3e51e3792c8d60405160405180910390a3600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b7f000000000000000000000000ce78d38e71b5a0461e1bfe945fe62aa2b88aa6d581565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612022576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156120c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f5a4e41000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6001601160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600061216461215361374e565b600f54613c9690919063ffffffff16565b905090565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000655af3107a40006121b16121ac846121a761361b565b613cd6565b613fb7565b816121b857fe5b049050919050565b60006121f8620f42406121ea6121d46132e0565b6121dc61361b565b61381390919063ffffffff16565b61381390919063ffffffff16565b905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156122a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f496e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806123245750601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b612396576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f4c464e410000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61239e613ff3565b600560030154600f54111561241b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f4d6178206361706163697479207265616368656400000000000000000000000081525060200191505060405180910390fd5b60006124256121c0565b90506000612431614038565b90508085101561248c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806149ca6023913960400191505060405180910390fd5b60007f000000000000000000000000ce78d38e71b5a0461e1bfe945fe62aa2b88aa6d573ffffffffffffffffffffffffffffffffffffffff16631eec5a9a7f000000000000000000000000471ece3750da237f93b8e339c536989b8978a438896040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060206040518083038186803b15801561253d57600080fd5b505afa158015612551573d6000803e3d6000fd5b505050506040513d602081101561256757600080fd5b8101908080519060200190929190505050905060006125858261218f565b905062989680811015612600576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f20736d616c6c00000000000000000000000000000000000081525060200191505060405180910390fd5b612608613683565b81111561267d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f426f6e6420746f6f206c6172676500000000000000000000000000000000000081525060200191505060405180910390fd5b87471061286c578734146126f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f554100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000471ece3750da237f93b8e339c536989b8978a43873ffffffffffffffffffffffffffffffffffffffff1663d0e30db0896040518263ffffffff1660e01b81526004016000604051808303818588803b15801561276157600080fd5b505af1158015612775573d6000803e3d6000fd5b50505050507f000000000000000000000000471ece3750da237f93b8e339c536989b8978a43873ffffffffffffffffffffffffffffffffffffffff1663a9059cbb7f000000000000000000000000ce78d38e71b5a0461e1bfe945fe62aa2b88aa6d58a6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561282b57600080fd5b505af115801561283f573d6000803e3d6000fd5b505050506040513d602081101561285557600080fd5b8101908080519060200190929190505050506128da565b6128d9337f000000000000000000000000ce78d38e71b5a0461e1bfe945fe62aa2b88aa6d58a7f000000000000000000000000471ece3750da237f93b8e339c536989b8978a43873ffffffffffffffffffffffffffffffffffffffff166140b4909392919063ffffffff16565b5b7f000000000000000000000000ce78d38e71b5a0461e1bfe945fe62aa2b88aa6d573ffffffffffffffffffffffffffffffffffffffff16636a20de9230836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561296b57600080fd5b505af115801561297f573d6000803e3d6000fd5b5050505061299882600f5461417590919063ffffffff16565b600f8190555060405180608001604052806129fe83600e60008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000015461417590919063ffffffff16565b8152602001858152602001600560040160009054906101000a900463ffffffff1663ffffffff1681526020014263ffffffff16815250600e60008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082015181600001556020820151816001015560408201518160020160006101000a81548163ffffffff021916908363ffffffff16021790555060608201518160020160046101000a81548163ffffffff021916908363ffffffff16021790555090505083612b07600560040160009054906101000a900463ffffffff1663ffffffff164261417590919063ffffffff16565b827f1fec6dc81f140574bf43f6b1e420ae1dd47928b9d57db8cbd7b8611063b85ae58b6040518082815260200191505060405180910390a4612b476131f4565b612b4f614038565b612b576121c0565b7f375b221f40939bfd8f49723a17cf7bc6d576ebf72efe2cc3e991826f5b3f390a60405160405180910390a4612b8b61418f565b809450505050509392505050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015612c0357600080fd5b505afa158015612c17573d6000803e3d6000fd5b505050506040513d6020811015612c2d57600080fd5b810190808051906020019092919050505060ff16600a0a612c65612c4f6132e0565b612c576131f4565b61381390919063ffffffff16565b81612c6c57fe5b04905090565b7f0000000000000000000000000879270f8ba78126628595bec8d10dcdad0e4c8981565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612d57576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6103e8612d73601960056000015461381390919063ffffffff16565b81612d7a57fe5b04831115612df0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f496e6372656d656e7420746f6f206c617267650000000000000000000000000081525060200191505060405180910390fd5b6028821015612e67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f4e6578742041646a7573746d656e7420636f756c64206265206c6f636b65640081525060200191505060405180910390fd5b6040518060a0016040528085151581526020018481526020018381526020018263ffffffff1681526020014263ffffffff16815250600a60008201518160000160006101000a81548160ff021916908315150217905550602082015181600101556040820151816002015560608201518160030160006101000a81548163ffffffff021916908363ffffffff16021790555060808201518160030160046101000a81548163ffffffff021916908363ffffffff16021790555090505050505050565b60007f000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612fed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f4e4154000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000471ece3750da237f93b8e339c536989b8978a43873ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156130af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f4e4150000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61319b7f0000000000000000000000000879270f8ba78126628595bec8d10dcdad0e4c898373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561313a57600080fd5b505afa15801561314e573d6000803e3d6000fd5b505050506040513d602081101561316457600080fd5b81019080805190602001909291905050508473ffffffffffffffffffffffffffffffffffffffff1661433b9092919063ffffffff16565b60019050919050565b600e6020528060005260406000206000915090508060000154908060010154908060020160009054906101000a900463ffffffff16908060020160049054906101000a900463ffffffff16905084565b6000807f000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561325d57600080fd5b505afa158015613271573d6000803e3d6000fd5b505050506040513d602081101561328757600080fd5b81019080805190602001909291905050509050670de0b6b3a76400006132d26132cd6132c7633b9aca006132b9612146565b61381390919063ffffffff16565b84613cd6565b613fb7565b816132d957fe5b0491505090565b600080600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561334b57600080fd5b505afa15801561335f573d6000803e3d6000fd5b505050506040513d60a081101561337557600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291905050505050509150508091505090565b3373ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461347c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561351f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f494100000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8015613586576001600460146101000a81548160ff02191690831515021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506135e3565b6000600460146101000a81548160ff02191690831515021790555081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b60058060000154908060010154908060020154908060030154908060040160009054906101000a900463ffffffff16905085565b6000620186a061364061362c6131f4565b60056000015461381390919063ffffffff16565b8161364757fe5b0490506005600101548110156136605760056001015490505b90565b60116020528060005260406000206000915054906101000a900460ff1681565b6000620186a06137416005600201547f000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156136f857600080fd5b505afa15801561370c573d6000803e3d6000fd5b505050506040513d602081101561372257600080fd5b810190808051906020019092919050505061381390919063ffffffff16565b8161374857fe5b04905090565b60008061377c601060009054906101000a900463ffffffff164263ffffffff16613cb090919063ffffffff16565b9050600560040160009054906101000a900463ffffffff1663ffffffff166137b58263ffffffff16600f5461381390919063ffffffff16565b816137bc57fe5b049150600f548211156137cf57600f5491505b5090565b601060009054906101000a900463ffffffff1681565b7f000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a81565b600f5481565b600080831480613830575081838385029250828161382d57fe5b04145b61383957600080fd5b92915050565b600082613918577f000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb85846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156138d757600080fd5b505af11580156138eb573d6000803e3d6000fd5b505050506040513d602081101561390157600080fd5b810190808051906020019092919050505050613c8c565b600460149054906101000a900460ff1615613acc577f000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a73ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156139e057600080fd5b505af11580156139f4573d6000803e3d6000fd5b505050506040513d6020811015613a0a57600080fd5b810190808051906020019092919050505050600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050600060405180830381600087803b158015613aaf57600080fd5b505af1158015613ac3573d6000803e3d6000fd5b50505050613c8b565b7f000000000000000000000000768c665e57ee879a61a3253cb319f484489b0f9a73ffffffffffffffffffffffffffffffffffffffff1663095ea7b3600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b158015613b7f57600080fd5b505af1158015613b93573d6000803e3d6000fd5b505050506040513d6020811015613ba957600080fd5b810190808051906020019092919050505050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16637acb775783866040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b158015613c4e57600080fd5b505af1158015613c62573d6000803e3d6000fd5b505050506040513d6020811015613c7857600080fd5b8101908080519060200190929190505050505b5b8190509392505050565b6000828284039150811115613caa57600080fd5b92915050565b60008263ffffffff1682840391508163ffffffff161115613cd057600080fd5b92915050565b613cde614909565b60008211613d37576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806149836026913960400191505060405180910390fd5b6000831415613d7557604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509050613fb1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff71ffffffffffffffffffffffffffffffffffff168311613eae57600082607060ff1685901b81613dc257fe5b0490507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115613e79576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250915050613fb1565b6000613eca846e010000000000000000000000000000856143dd565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16811115613f80576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f4669786564506f696e743a3a6672616374696f6e3a206f766572666c6f77000081525060200191505060405180910390fd5b6040518060200160405280827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509150505b92915050565b60006612725dd1d243ab82600001517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681613feb57fe5b049050919050565b61400f613ffe61374e565b600f54613c9690919063ffffffff16565b600f8190555042601060006101000a81548163ffffffff021916908363ffffffff160217905550565b600062989680614073633b9aca006140656140516131f4565b60056000015461381390919063ffffffff16565b61417590919063ffffffff16565b8161407a57fe5b0490506005600101548110156140975760056001015490506140b1565b6000600560010154146140b05760006005600101819055505b5b90565b61416f846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061449f565b50505050565b600082828401915081101561418957600080fd5b92915050565b60006141d4600a60030160009054906101000a900463ffffffff16600a60030160049054906101000a900463ffffffff1663ffffffff1661458e90919063ffffffff16565b63ffffffff1690506000600a60010154141580156141f25750804210155b156143385760006005600001549050600a60000160009054906101000a900460ff161561426157614236600a6001015460056000015461417590919063ffffffff16565b600560000181905550600a600201546005600001541061425c576000600a600101819055505b6142a5565b61427e600a60010154600560000154613c9690919063ffffffff16565b600560000181905550600a60020154600560000154116142a4576000600a600101819055505b5b42600a60030160046101000a81548163ffffffff021916908363ffffffff1602179055507fb923e581a0f83128e9e1d8297aa52b18d6744310476e0b54509c054cd7a93b2a81600560000154600a60010154600a60000160009054906101000a900460ff1660405180858152602001848152602001838152602001821515815260200194505050505060405180910390a1505b50565b6143d88363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505061449f565b505050565b60008060006143ec86866145b4565b91509150600084806143fa57fe5b86880990508281111561440e576001820391505b8083039250848210614488576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f46756c6c4d6174683a3a6d756c4469763a206f766572666c6f7700000000000081525060200191505060405180910390fd5b614493838387614607565b93505050509392505050565b6060614501826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166146a49092919063ffffffff16565b90506000815111156145895780806020019051602081101561452257600080fd5b8101908080519060200190929190505050614588576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614a11602a913960400191505060405180910390fd5b5b505050565b60008263ffffffff1682840191508163ffffffff1610156145ae57600080fd5b92915050565b60008060007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff806145e157fe5b848609905083850292508281039150828110156145ff576001820391505b509250929050565b600080826000038316905080838161461b57fe5b04925080858161462757fe5b049450600181826000038161463857fe5b04018402850194506000600190508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808402600203810290508084026002038102905080840260020381029050808602925050509392505050565b60606146b384846000856146bc565b90509392505050565b60606146c7856148c2565b614739576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106147895780518252602082019150602081019050602083039250614766565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146147eb576040519150601f19603f3d011682016040523d82523d6000602084013e6147f0565b606091505b509150915081156148055780925050506148ba565b6000815111156148185780518082602001fd5b836040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561487f578082015181840152602081019050614864565b50505050905090810190601f1680156148ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b949350505050565b600080823b905060008111915050919050565b60405180608001604052806000815260200160008152602001600063ffffffff168152602001600063ffffffff1681525090565b604051806020016040528060007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168152509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a206d757374206265206e6577206f776e657220746f2070756c6c4669786564506f696e743a3a6672616374696f6e3a206469766973696f6e206279207a65726f44656274206d757374206265203020666f7220696e697469616c697a6174696f6e536c697070616765206c696d69743a206d6f7265207468616e206d617820707269636556657374696e67206d757374206265206c6f6e676572207468616e20333620686f7572735361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212204df0ba713b23133555d6844107438e5e66e8ad5be491f98f4909ea044653a3c864736f6c63430007050033