ETH Price: $3,069.95 (-1.32%)
Gas: 3 Gwei

Token

 

Overview

Max Total Supply

0

Holders

0

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
Sablier

Compiler Version
v0.5.11+commit.c082d0b4

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU LGPLv3 license, Audited

Contract Source Code (Solidity)Audit Report

/**
 *Submitted for verification at Etherscan.io on 2019-11-12
*/

// File: @openzeppelin/contracts-ethereum-package/contracts/token/ERC20/IERC20.sol

pragma solidity ^0.5.2;

/**
 * @title ERC20 interface
 * @dev see https://eips.ethereum.org/EIPS/eip-20
 */
interface IERC20 {
    function transfer(address to, uint256 value) external returns (bool);

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

    function transferFrom(address from, address to, uint256 value) external returns (bool);

    function totalSupply() external view returns (uint256);

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

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

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

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

// File: @openzeppelin/upgrades/contracts/Initializable.sol

pragma solidity >=0.4.24 <0.6.0;


/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

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

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool isTopLevelCall = !initializing;
    if (isTopLevelCall) {
      initializing = true;
      initialized = true;
    }

    _;

    if (isTopLevelCall) {
      initializing = false;
    }
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    uint256 cs;
    assembly { cs := extcodesize(address) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

// File: @openzeppelin/contracts-ethereum-package/contracts/utils/ReentrancyGuard.sol

pragma solidity ^0.5.2;


/**
 * @title Helps contracts guard against reentrancy attacks.
 * @author Remco Bloemen <remco@2π.com>, Eenae <[email protected]>
 * @dev If you mark a function `nonReentrant`, you should also
 * mark it `external`.
 */
contract ReentrancyGuard is Initializable {
    /// @dev counter to allow mutex lock with only one SSTORE operation
    uint256 private _guardCounter;

    function initialize() public initializer {
        // The counter starts at one to prevent changing it from zero to a non-zero
        // value, which is a more expensive operation.
        _guardCounter = 1;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _guardCounter += 1;
        uint256 localCounter = _guardCounter;
        _;
        require(localCounter == _guardCounter);
    }

    uint256[50] private ______gap;
}

// File: @sablier/shared-contracts/compound/CarefulMath.sol

pragma solidity ^0.5.8;

/**
  * @title Careful Math
  * @author Compound
  * @notice Derived from OpenZeppelin's SafeMath library
  *         https://github.com/OpenZeppelin/openzeppelin-solidity/blob/master/contracts/math/SafeMath.sol
  */
contract CarefulMath {

    /**
     * @dev Possible error codes that we can return
     */
    enum MathError {
        NO_ERROR,
        DIVISION_BY_ZERO,
        INTEGER_OVERFLOW,
        INTEGER_UNDERFLOW
    }

    /**
    * @dev Multiplies two numbers, returns an error on overflow.
    */
    function mulUInt(uint a, uint b) internal pure returns (MathError, uint) {
        if (a == 0) {
            return (MathError.NO_ERROR, 0);
        }

        uint c = a * b;

        if (c / a != b) {
            return (MathError.INTEGER_OVERFLOW, 0);
        } else {
            return (MathError.NO_ERROR, c);
        }
    }

    /**
    * @dev Integer division of two numbers, truncating the quotient.
    */
    function divUInt(uint a, uint b) internal pure returns (MathError, uint) {
        if (b == 0) {
            return (MathError.DIVISION_BY_ZERO, 0);
        }

        return (MathError.NO_ERROR, a / b);
    }

    /**
    * @dev Subtracts two numbers, returns an error on overflow (i.e. if subtrahend is greater than minuend).
    */
    function subUInt(uint a, uint b) internal pure returns (MathError, uint) {
        if (b <= a) {
            return (MathError.NO_ERROR, a - b);
        } else {
            return (MathError.INTEGER_UNDERFLOW, 0);
        }
    }

    /**
    * @dev Adds two numbers, returns an error on overflow.
    */
    function addUInt(uint a, uint b) internal pure returns (MathError, uint) {
        uint c = a + b;

        if (c >= a) {
            return (MathError.NO_ERROR, c);
        } else {
            return (MathError.INTEGER_OVERFLOW, 0);
        }
    }

    /**
    * @dev add a and b and then subtract c
    */
    function addThenSubUInt(uint a, uint b, uint c) internal pure returns (MathError, uint) {
        (MathError err0, uint sum) = addUInt(a, b);

        if (err0 != MathError.NO_ERROR) {
            return (err0, 0);
        }

        return subUInt(sum, c);
    }
}

// File: @sablier/shared-contracts/compound/Exponential.sol

pragma solidity ^0.5.8;


/**
 * @title Exponential module for storing fixed-decision decimals
 * @author Compound
 * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.
 *         Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:
 *         `Exp({mantissa: 5100000000000000000})`.
 */
contract Exponential is CarefulMath {
    uint constant expScale = 1e18;
    uint constant halfExpScale = expScale/2;
    uint constant mantissaOne = expScale;

    struct Exp {
        uint mantissa;
    }

    /**
     * @dev Creates an exponential from numerator and denominator values.
     *      Note: Returns an error if (`num` * 10e18) > MAX_INT,
     *            or if `denom` is zero.
     */
    function getExp(uint num, uint denom) pure internal returns (MathError, Exp memory) {
        (MathError err0, uint scaledNumerator) = mulUInt(num, expScale);
        if (err0 != MathError.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        (MathError err1, uint rational) = divUInt(scaledNumerator, denom);
        if (err1 != MathError.NO_ERROR) {
            return (err1, Exp({mantissa: 0}));
        }

        return (MathError.NO_ERROR, Exp({mantissa: rational}));
    }

    /**
     * @dev Adds two exponentials, returning a new exponential.
     */
    function addExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
        (MathError error, uint result) = addUInt(a.mantissa, b.mantissa);

        return (error, Exp({mantissa: result}));
    }

    /**
     * @dev Subtracts two exponentials, returning a new exponential.
     */
    function subExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
        (MathError error, uint result) = subUInt(a.mantissa, b.mantissa);

        return (error, Exp({mantissa: result}));
    }

    /**
     * @dev Multiply an Exp by a scalar, returning a new Exp.
     */
    function mulScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) {
        (MathError err0, uint scaledMantissa) = mulUInt(a.mantissa, scalar);
        if (err0 != MathError.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        return (MathError.NO_ERROR, Exp({mantissa: scaledMantissa}));
    }

    /**
     * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.
     */
    function mulScalarTruncate(Exp memory a, uint scalar) pure internal returns (MathError, uint) {
        (MathError err, Exp memory product) = mulScalar(a, scalar);
        if (err != MathError.NO_ERROR) {
            return (err, 0);
        }

        return (MathError.NO_ERROR, truncate(product));
    }

    /**
     * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.
     */
    function mulScalarTruncateAddUInt(Exp memory a, uint scalar, uint addend) pure internal returns (MathError, uint) {
        (MathError err, Exp memory product) = mulScalar(a, scalar);
        if (err != MathError.NO_ERROR) {
            return (err, 0);
        }

        return addUInt(truncate(product), addend);
    }

    /**
     * @dev Divide an Exp by a scalar, returning a new Exp.
     */
    function divScalar(Exp memory a, uint scalar) pure internal returns (MathError, Exp memory) {
        (MathError err0, uint descaledMantissa) = divUInt(a.mantissa, scalar);
        if (err0 != MathError.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        return (MathError.NO_ERROR, Exp({mantissa: descaledMantissa}));
    }

    /**
     * @dev Divide a scalar by an Exp, returning a new Exp.
     */
    function divScalarByExp(uint scalar, Exp memory divisor) pure internal returns (MathError, Exp memory) {
        /*
          We are doing this as:
          getExp(mulUInt(expScale, scalar), divisor.mantissa)

          How it works:
          Exp = a / b;
          Scalar = s;
          `s / (a / b)` = `b * s / a` and since for an Exp `a = mantissa, b = expScale`
        */
        (MathError err0, uint numerator) = mulUInt(expScale, scalar);
        if (err0 != MathError.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }
        return getExp(numerator, divisor.mantissa);
    }

    /**
     * @dev Divide a scalar by an Exp, then truncate to return an unsigned integer.
     */
    function divScalarByExpTruncate(uint scalar, Exp memory divisor) pure internal returns (MathError, uint) {
        (MathError err, Exp memory fraction) = divScalarByExp(scalar, divisor);
        if (err != MathError.NO_ERROR) {
            return (err, 0);
        }

        return (MathError.NO_ERROR, truncate(fraction));
    }

    /**
     * @dev Multiplies two exponentials, returning a new exponential.
     */
    function mulExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {

        (MathError err0, uint doubleScaledProduct) = mulUInt(a.mantissa, b.mantissa);
        if (err0 != MathError.NO_ERROR) {
            return (err0, Exp({mantissa: 0}));
        }

        // We add half the scale before dividing so that we get rounding instead of truncation.
        //  See "Listing 6" and text above it at https://accu.org/index.php/journals/1717
        // Without this change, a result like 6.6...e-19 will be truncated to 0 instead of being rounded to 1e-18.
        (MathError err1, uint doubleScaledProductWithHalfScale) = addUInt(halfExpScale, doubleScaledProduct);
        if (err1 != MathError.NO_ERROR) {
            return (err1, Exp({mantissa: 0}));
        }

        (MathError err2, uint product) = divUInt(doubleScaledProductWithHalfScale, expScale);
        // The only error `div` can return is MathError.DIVISION_BY_ZERO but we control `expScale` and it is not zero.
        assert(err2 == MathError.NO_ERROR);

        return (MathError.NO_ERROR, Exp({mantissa: product}));
    }

    /**
     * @dev Multiplies two exponentials given their mantissas, returning a new exponential.
     */
    function mulExp(uint a, uint b) pure internal returns (MathError, Exp memory) {
        return mulExp(Exp({mantissa: a}), Exp({mantissa: b}));
    }

    /**
     * @dev Multiplies three exponentials, returning a new exponential.
     */
    function mulExp3(Exp memory a, Exp memory b, Exp memory c) pure internal returns (MathError, Exp memory) {
        (MathError err, Exp memory ab) = mulExp(a, b);
        if (err != MathError.NO_ERROR) {
            return (err, ab);
        }
        return mulExp(ab, c);
    }

    /**
     * @dev Divides two exponentials, returning a new exponential.
     *     (a/scale) / (b/scale) = (a/scale) * (scale/b) = a/b,
     *  which we can scale as an Exp by calling getExp(a.mantissa, b.mantissa)
     */
    function divExp(Exp memory a, Exp memory b) pure internal returns (MathError, Exp memory) {
        return getExp(a.mantissa, b.mantissa);
    }

    /**
     * @dev Truncates the given exp to a whole number value.
     *      For example, truncate(Exp{mantissa: 15 * expScale}) = 15
     */
    function truncate(Exp memory exp) pure internal returns (uint) {
        // Note: We are not using careful math here as we're performing a division that cannot fail
        return exp.mantissa / expScale;
    }

    /**
     * @dev Checks if first Exp is less than second Exp.
     */
    function lessThanExp(Exp memory left, Exp memory right) pure internal returns (bool) {
        return left.mantissa < right.mantissa; //TODO: Add some simple tests and this in another PR yo.
    }

    /**
     * @dev Checks if left Exp <= right Exp.
     */
    function lessThanOrEqualExp(Exp memory left, Exp memory right) pure internal returns (bool) {
        return left.mantissa <= right.mantissa;
    }

    /**
     * @dev Checks if left Exp > right Exp.
     */
    function greaterThanExp(Exp memory left, Exp memory right) pure internal returns (bool) {
        return left.mantissa > right.mantissa;
    }

    /**
     * @dev returns true if Exp is exactly zero
     */
    function isZeroExp(Exp memory value) pure internal returns (bool) {
        return value.mantissa == 0;
    }
}

// File: @sablier/shared-contracts/interfaces/ICERC20.sol

pragma solidity 0.5.11;

/**
 * @title CERC20 interface
 * @author Sablier
 * @dev See https://compound.finance/developers
 */
interface ICERC20 {
    function balanceOf(address who) external view returns (uint256);

    function isCToken() external view returns (bool);

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

    function balanceOfUnderlying(address account) external returns (uint256);

    function exchangeRateCurrent() external returns (uint256);

    function mint(uint256 mintAmount) external returns (uint256);

    function redeem(uint256 redeemTokens) external returns (uint256);

    function redeemUnderlying(uint256 redeemAmount) external returns (uint256);

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

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

// File: @openzeppelin/contracts-ethereum-package/contracts/GSN/Context.sol

pragma solidity ^0.5.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they not should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
contract Context {
    // Empty internal constructor, to prevent people from mistakenly deploying
    // an instance of this contract, with should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address) {
        return msg.sender;
    }

    function _msgData() internal view returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: @sablier/shared-contracts/lifecycle/OwnableWithoutRenounce.sol

pragma solidity 0.5.11;



/**
 * @title OwnableWithoutRenounce
 * @author Sablier
 * @dev Fork of OpenZeppelin's Ownable contract, which provides basic authorization control, but with
 *  the `renounceOwnership` function removed to avoid fat-finger errors.
 *  We inherit from `Context` to keep this contract compatible with the Gas Station Network.
 * See https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/blob/master/contracts/ownership/Ownable.sol
 * See https://forum.openzeppelin.com/t/contract-request-ownable-without-renounceownership/1400
 * See https://docs.openzeppelin.com/contracts/2.x/gsn#_msg_sender_and_msg_data
 */
contract OwnableWithoutRenounce is Initializable, Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    function initialize(address sender) public initializer {
        _owner = sender;
        emit OwnershipTransferred(address(0), _owner);
    }

    /**
     * @return the address of the owner.
     */
    function owner() public view returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner());
        _;
    }

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _owner;
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0));
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }

    uint256[50] private ______gap;
}

// File: @openzeppelin/contracts-ethereum-package/contracts/access/Roles.sol

pragma solidity ^0.5.2;

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    /**
     * @dev give an account access to this role
     */
    function add(Role storage role, address account) internal {
        require(account != address(0));
        require(!has(role, account));

        role.bearer[account] = true;
    }

    /**
     * @dev remove an account's access to this role
     */
    function remove(Role storage role, address account) internal {
        require(account != address(0));
        require(has(role, account));

        role.bearer[account] = false;
    }

    /**
     * @dev check if an account has this role
     * @return bool
     */
    function has(Role storage role, address account) internal view returns (bool) {
        require(account != address(0));
        return role.bearer[account];
    }
}

// File: @sablier/shared-contracts/lifecycle/PauserRoleWithoutRenounce.sol

pragma solidity ^0.5.0;




/**
 * @title PauserRoleWithoutRenounce
 * @author Sablier
 * @notice Fork of OpenZeppelin's PauserRole, but with the `renouncePauser` function removed to avoid fat-finger errors.
 *  We inherit from `Context` to keep this contract compatible with the Gas Station Network.
 * See https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/blob/master/contracts/access/roles/PauserRole.sol
 */

contract PauserRoleWithoutRenounce is Initializable, Context {
    using Roles for Roles.Role;

    event PauserAdded(address indexed account);
    event PauserRemoved(address indexed account);

    Roles.Role private _pausers;

    function initialize(address sender) public initializer {
        if (!isPauser(sender)) {
            _addPauser(sender);
        }
    }

    modifier onlyPauser() {
        require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role");
        _;
    }

    function isPauser(address account) public view returns (bool) {
        return _pausers.has(account);
    }

    function addPauser(address account) public onlyPauser {
        _addPauser(account);
    }

    function _addPauser(address account) internal {
        _pausers.add(account);
        emit PauserAdded(account);
    }

    function _removePauser(address account) internal {
        _pausers.remove(account);
        emit PauserRemoved(account);
    }

    uint256[50] private ______gap;
}

// File: @sablier/shared-contracts/lifecycle/PausableWithoutRenounce.sol

pragma solidity 0.5.11;




/**
 * @title PausableWithoutRenounce
 * @author Sablier
 * @notice Fork of OpenZeppelin's Pausable, a contract module which allows children to implement an
 *  emergency stop mechanism that can be triggered by an authorized account, but with the `renouncePauser`
 *  function removed to avoid fat-finger errors.
 *  We inherit from `Context` to keep this contract compatible with the Gas Station Network.
 * See https://github.com/OpenZeppelin/openzeppelin-contracts-ethereum-package/blob/master/contracts/lifecycle/Pausable.sol
 * See https://docs.openzeppelin.com/contracts/2.x/gsn#_msg_sender_and_msg_data
 */
contract PausableWithoutRenounce is Initializable, Context, PauserRoleWithoutRenounce {
    /**
     * @dev Emitted when the pause is triggered by a pauser (`account`).
     */
    event Paused(address account);

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

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state. Assigns the Pauser role
     * to the deployer.
     */
    function initialize(address sender) public initializer {
        PauserRoleWithoutRenounce.initialize(sender);
        _paused = false;
    }

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

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     */
    modifier whenNotPaused() {
        require(!_paused, "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     */
    modifier whenPaused() {
        require(_paused, "Pausable: not paused");
        _;
    }

    /**
     * @dev Called by a pauser to pause, triggers stopped state.
     */
    function pause() public onlyPauser whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Called by a pauser to unpause, returns to normal state.
     */
    function unpause() public onlyPauser whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

// File: contracts/interfaces/ICTokenManager.sol

pragma solidity 0.5.11;

/**
 * @title CTokenManager Interface
 * @author Sablier
 */
interface ICTokenManager {
    /**
     * @notice Emits when the owner discards a cToken.
     */
    event DiscardCToken(address indexed tokenAddress);

    /**
     * @notice Emits when the owner whitelists a cToken.
     */
    event WhitelistCToken(address indexed tokenAddress);

    function whitelistCToken(address tokenAddress) external;

    function discardCToken(address tokenAddress) external;

    function isCToken(address tokenAddress) external view returns (bool);
}

// File: contracts/interfaces/IERC1620.sol

pragma solidity 0.5.11;

/**
 * @title ERC-1620 Money Streaming Standard
 * @author Paul Razvan Berg - <[email protected]>
 * @dev See https://eips.ethereum.org/EIPS/eip-1620
 */
interface IERC1620 {
    /**
     * @notice Emits when a stream is successfully created.
     */
    event CreateStream(
        uint256 indexed streamId,
        address indexed sender,
        address indexed recipient,
        uint256 deposit,
        address tokenAddress,
        uint256 startTime,
        uint256 stopTime
    );

    /**
     * @notice Emits when the recipient of a stream withdraws a portion or all their pro rata share of the stream.
     */
    event WithdrawFromStream(uint256 indexed streamId, address indexed recipient, uint256 amount);

    /**
     * @notice Emits when a stream is successfully cancelled and tokens are transferred back on a pro rata basis.
     */
    event CancelStream(
        uint256 indexed streamId,
        address indexed sender,
        address indexed recipient,
        uint256 senderBalance,
        uint256 recipientBalance
    );

    function balanceOf(uint256 streamId, address who) external view returns (uint256 balance);

    function getStream(uint256 streamId)
        external
        view
        returns (
            address sender,
            address recipient,
            uint256 deposit,
            address token,
            uint256 startTime,
            uint256 stopTime,
            uint256 balance,
            uint256 rate
        );

    function createStream(address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime)
        external
        returns (uint256 streamId);

    function withdrawFromStream(uint256 streamId, uint256 funds) external returns (bool);

    function cancelStream(uint256 streamId) external returns (bool);
}

// File: contracts/Types.sol

pragma solidity 0.5.11;


/**
 * @title Sablier Types
 * @author Sablier
 */
library Types {
    struct Stream {
        uint256 deposit;
        uint256 ratePerSecond;
        uint256 remainingBalance;
        uint256 startTime;
        uint256 stopTime;
        address recipient;
        address sender;
        address tokenAddress;
        bool isEntity;
    }

    struct CompoundingStreamVars {
        Exponential.Exp exchangeRateInitial;
        Exponential.Exp senderShare;
        Exponential.Exp recipientShare;
        bool isEntity;
    }
}

// File: contracts/Sablier.sol

pragma solidity 0.5.11;










/**
 * @title Sablier's Money Streaming
 * @author Sablier
 */
contract Sablier is IERC1620, OwnableWithoutRenounce, PausableWithoutRenounce, Exponential, ReentrancyGuard {
    /*** Storage Properties ***/

    /**
     * @notice In Exp terms, 1e18 is 1, or 100%
     */
    uint256 constant hundredPercent = 1e18;

    /**
     * @notice In Exp terms, 1e16 is 0.01, or 1%
     */
    uint256 constant onePercent = 1e16;

    /**
     * @notice Stores information about the initial state of the underlying of the cToken.
     */
    mapping(uint256 => Types.CompoundingStreamVars) private compoundingStreamsVars;

    /**
     * @notice An instance of CTokenManager, responsible for whitelisting and discarding cTokens.
     */
    ICTokenManager public cTokenManager;

    /**
     * @notice The amount of interest has been accrued per token address.
     */
    mapping(address => uint256) private earnings;

    /**
     * @notice The percentage fee charged by the contract on the accrued interest.
     */
    Exp public fee;

    /**
     * @notice Counter for new stream ids.
     */
    uint256 public nextStreamId;

    /**
     * @notice The stream objects identifiable by their unsigned integer ids.
     */
    mapping(uint256 => Types.Stream) private streams;

    /*** Events ***/

    /**
     * @notice Emits when a compounding stream is successfully created.
     */
    event CreateCompoundingStream(
        uint256 indexed streamId,
        uint256 exchangeRate,
        uint256 senderSharePercentage,
        uint256 recipientSharePercentage
    );

    /**
     * @notice Emits when the owner discards a cToken.
     */
    event PayInterest(
        uint256 indexed streamId,
        uint256 senderInterest,
        uint256 recipientInterest,
        uint256 sablierInterest
    );

    /**
     * @notice Emits when the owner takes the earnings.
     */
    event TakeEarnings(address indexed tokenAddress, uint256 indexed amount);

    /**
     * @notice Emits when the owner updates the percentage fee.
     */
    event UpdateFee(uint256 indexed fee);

    /*** Modifiers ***/

    /**
     * @dev Throws if the caller is not the sender of the recipient of the stream.
     */
    modifier onlySenderOrRecipient(uint256 streamId) {
        require(
            msg.sender == streams[streamId].sender || msg.sender == streams[streamId].recipient,
            "caller is not the sender or the recipient of the stream"
        );
        _;
    }

    /**
     * @dev Throws if the id does not point to a valid stream.
     */
    modifier streamExists(uint256 streamId) {
        require(streams[streamId].isEntity, "stream does not exist");
        _;
    }

    /**
     * @dev Throws if the id does not point to a valid compounding stream.
     */
    modifier compoundingStreamExists(uint256 streamId) {
        require(compoundingStreamsVars[streamId].isEntity, "compounding stream does not exist");
        _;
    }

    /*** Contract Logic Starts Here */

    constructor(address cTokenManagerAddress) public {
        require(cTokenManagerAddress != address(0x00), "cTokenManager contract is the zero address");
        OwnableWithoutRenounce.initialize(msg.sender);
        PausableWithoutRenounce.initialize(msg.sender);
        cTokenManager = ICTokenManager(cTokenManagerAddress);
        nextStreamId = 1;
    }

    /*** Owner Functions ***/

    struct UpdateFeeLocalVars {
        MathError mathErr;
        uint256 feeMantissa;
    }

    /**
     * @notice Updates the Sablier fee.
     * @dev Throws if the caller is not the owner of the contract.
     *  Throws if `feePercentage` is not lower or equal to 100.
     * @param feePercentage The new fee as a percentage.
     */
    function updateFee(uint256 feePercentage) external onlyOwner {
        require(feePercentage <= 100, "fee percentage higher than 100%");
        UpdateFeeLocalVars memory vars;

        /* `feePercentage` will be stored as a mantissa, so we scale it up by one percent in Exp terms. */
        (vars.mathErr, vars.feeMantissa) = mulUInt(feePercentage, onePercent);
        /*
         * `mulUInt` can only return MathError.INTEGER_OVERFLOW but we control `onePercent`
         * and we know `feePercentage` is maximum 100.
         */
        assert(vars.mathErr == MathError.NO_ERROR);

        fee = Exp({ mantissa: vars.feeMantissa });
        emit UpdateFee(feePercentage);
    }

    struct TakeEarningsLocalVars {
        MathError mathErr;
    }

    /**
     * @notice Withdraws the earnings for the given token address.
     * @dev Throws if `amount` exceeds the available balance.
     * @param tokenAddress The address of the token to withdraw earnings for.
     * @param amount The amount of tokens to withdraw.
     */
    function takeEarnings(address tokenAddress, uint256 amount) external onlyOwner nonReentrant {
        require(cTokenManager.isCToken(tokenAddress), "cToken is not whitelisted");
        require(amount > 0, "amount is zero");
        require(earnings[tokenAddress] >= amount, "amount exceeds the available balance");

        TakeEarningsLocalVars memory vars;
        (vars.mathErr, earnings[tokenAddress]) = subUInt(earnings[tokenAddress], amount);
        /*
         * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know `earnings[tokenAddress]`
         * is at least as big as `amount`.
         */
        assert(vars.mathErr == MathError.NO_ERROR);

        emit TakeEarnings(tokenAddress, amount);
        require(IERC20(tokenAddress).transfer(msg.sender, amount), "token transfer failure");
    }

    /*** View Functions ***/

    /**
     * @notice Returns the compounding stream with all its properties.
     * @dev Throws if the id does not point to a valid stream.
     * @param streamId The id of the stream to query.
     * @return The stream object.
     */
    function getStream(uint256 streamId)
        external
        view
        streamExists(streamId)
        returns (
            address sender,
            address recipient,
            uint256 deposit,
            address tokenAddress,
            uint256 startTime,
            uint256 stopTime,
            uint256 remainingBalance,
            uint256 ratePerSecond
        )
    {
        sender = streams[streamId].sender;
        recipient = streams[streamId].recipient;
        deposit = streams[streamId].deposit;
        tokenAddress = streams[streamId].tokenAddress;
        startTime = streams[streamId].startTime;
        stopTime = streams[streamId].stopTime;
        remainingBalance = streams[streamId].remainingBalance;
        ratePerSecond = streams[streamId].ratePerSecond;
    }

    /**
     * @notice Returns either the delta in seconds between `block.timestamp` and `startTime` or
     *  between `stopTime` and `startTime, whichever is smaller. If `block.timestamp` is before
     *  `startTime`, it returns 0.
     * @dev Throws if the id does not point to a valid stream.
     * @param streamId The id of the stream for whom to query the delta.
     * @return The time delta in seconds.
     */
    function deltaOf(uint256 streamId) public view streamExists(streamId) returns (uint256 delta) {
        Types.Stream memory stream = streams[streamId];
        if (block.timestamp <= stream.startTime) return 0;
        if (block.timestamp < stream.stopTime) return block.timestamp - stream.startTime;
        return stream.stopTime - stream.startTime;
    }

    struct BalanceOfLocalVars {
        MathError mathErr;
        uint256 recipientBalance;
        uint256 withdrawalAmount;
        uint256 senderBalance;
    }

    /**
     * @notice Returns the available funds for the given stream id and address.
     * @dev Throws if the id does not point to a valid stream.
     * @param streamId The id of the stream for whom to query the balance.
     * @param who The address for whom to query the balance.
     * @return The total funds allocated to `who` as uint256.
     */
    function balanceOf(uint256 streamId, address who) public view streamExists(streamId) returns (uint256 balance) {
        Types.Stream memory stream = streams[streamId];
        BalanceOfLocalVars memory vars;

        uint256 delta = deltaOf(streamId);
        (vars.mathErr, vars.recipientBalance) = mulUInt(delta, stream.ratePerSecond);
        require(vars.mathErr == MathError.NO_ERROR, "recipient balance calculation error");

        /*
         * If the stream `balance` does not equal `deposit`, it means there have been withdrawals.
         * We have to subtract the total amount withdrawn from the amount of money that has been
         * streamed until now.
         */
        if (stream.deposit > stream.remainingBalance) {
            (vars.mathErr, vars.withdrawalAmount) = subUInt(stream.deposit, stream.remainingBalance);
            assert(vars.mathErr == MathError.NO_ERROR);
            (vars.mathErr, vars.recipientBalance) = subUInt(vars.recipientBalance, vars.withdrawalAmount);
            /* `withdrawalAmount` cannot and should not be bigger than `recipientBalance`. */
            assert(vars.mathErr == MathError.NO_ERROR);
        }

        if (who == stream.recipient) return vars.recipientBalance;
        if (who == stream.sender) {
            (vars.mathErr, vars.senderBalance) = subUInt(stream.remainingBalance, vars.recipientBalance);
            /* `recipientBalance` cannot and should not be bigger than `remainingBalance`. */
            assert(vars.mathErr == MathError.NO_ERROR);
            return vars.senderBalance;
        }
        return 0;
    }

    /**
     * @notice Checks if the given id points to a compounding stream.
     * @param streamId The id of the compounding stream to check.
     * @return bool true=it is compounding stream, otherwise false.
     */
    function isCompoundingStream(uint256 streamId) public view returns (bool) {
        return compoundingStreamsVars[streamId].isEntity;
    }

    /**
     * @notice Returns the compounding stream object with all its properties.
     * @dev Throws if the id does not point to a valid compounding stream.
     * @param streamId The id of the compounding stream to query.
     * @return The compounding stream object.
     */
    function getCompoundingStream(uint256 streamId)
        external
        view
        streamExists(streamId)
        compoundingStreamExists(streamId)
        returns (
            address sender,
            address recipient,
            uint256 deposit,
            address tokenAddress,
            uint256 startTime,
            uint256 stopTime,
            uint256 remainingBalance,
            uint256 ratePerSecond,
            uint256 exchangeRateInitial,
            uint256 senderSharePercentage,
            uint256 recipientSharePercentage
        )
    {
        sender = streams[streamId].sender;
        recipient = streams[streamId].recipient;
        deposit = streams[streamId].deposit;
        tokenAddress = streams[streamId].tokenAddress;
        startTime = streams[streamId].startTime;
        stopTime = streams[streamId].stopTime;
        remainingBalance = streams[streamId].remainingBalance;
        ratePerSecond = streams[streamId].ratePerSecond;
        exchangeRateInitial = compoundingStreamsVars[streamId].exchangeRateInitial.mantissa;
        senderSharePercentage = compoundingStreamsVars[streamId].senderShare.mantissa;
        recipientSharePercentage = compoundingStreamsVars[streamId].recipientShare.mantissa;
    }

    struct InterestOfLocalVars {
        MathError mathErr;
        Exp exchangeRateDelta;
        Exp underlyingInterest;
        Exp netUnderlyingInterest;
        Exp senderUnderlyingInterest;
        Exp recipientUnderlyingInterest;
        Exp sablierUnderlyingInterest;
        Exp senderInterest;
        Exp recipientInterest;
        Exp sablierInterest;
    }

    /**
     * @notice Computes the interest accrued by keeping the amount of tokens in the contract. Returns (0, 0, 0) if
     *  the stream is not a compounding stream.
     * @dev Throws if there is a math error. We do not assert the calculations which involve the current
     *  exchange rate, because we can't know what value we'll get back from the cToken contract.
     * @return The interest accrued by the sender, the recipient and sablier, respectively, as uint256s.
     */
    function interestOf(uint256 streamId, uint256 amount)
        public
        streamExists(streamId)
        returns (uint256 senderInterest, uint256 recipientInterest, uint256 sablierInterest)
    {
        if (!compoundingStreamsVars[streamId].isEntity) {
            return (0, 0, 0);
        }
        Types.Stream memory stream = streams[streamId];
        Types.CompoundingStreamVars memory compoundingStreamVars = compoundingStreamsVars[streamId];
        InterestOfLocalVars memory vars;

        /*
         * The exchange rate delta is a key variable, since it leads us to how much interest has been earned
         * since the compounding stream was created.
         */
        Exp memory exchangeRateCurrent = Exp({ mantissa: ICERC20(stream.tokenAddress).exchangeRateCurrent() });
        if (exchangeRateCurrent.mantissa <= compoundingStreamVars.exchangeRateInitial.mantissa) {
            return (0, 0, 0);
        }
        (vars.mathErr, vars.exchangeRateDelta) = subExp(exchangeRateCurrent, compoundingStreamVars.exchangeRateInitial);
        assert(vars.mathErr == MathError.NO_ERROR);

        /* Calculate how much interest has been earned by holding `amount` in the smart contract. */
        (vars.mathErr, vars.underlyingInterest) = mulScalar(vars.exchangeRateDelta, amount);
        require(vars.mathErr == MathError.NO_ERROR, "interest calculation error");

        /* Calculate our share from that interest. */
        if (fee.mantissa == hundredPercent) {
            (vars.mathErr, vars.sablierInterest) = divExp(vars.underlyingInterest, exchangeRateCurrent);
            require(vars.mathErr == MathError.NO_ERROR, "sablier interest conversion error");
            return (0, 0, truncate(vars.sablierInterest));
        } else if (fee.mantissa == 0) {
            vars.sablierUnderlyingInterest = Exp({ mantissa: 0 });
            vars.netUnderlyingInterest = vars.underlyingInterest;
        } else {
            (vars.mathErr, vars.sablierUnderlyingInterest) = mulExp(vars.underlyingInterest, fee);
            require(vars.mathErr == MathError.NO_ERROR, "sablier interest calculation error");

            /* Calculate how much interest is left for the sender and the recipient. */
            (vars.mathErr, vars.netUnderlyingInterest) = subExp(
                vars.underlyingInterest,
                vars.sablierUnderlyingInterest
            );
            /*
             * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know that `sablierUnderlyingInterest`
             * is less or equal than `underlyingInterest`, because we control the value of `fee`.
             */
            assert(vars.mathErr == MathError.NO_ERROR);
        }

        /* Calculate the sender's share of the interest. */
        (vars.mathErr, vars.senderUnderlyingInterest) = mulExp(
            vars.netUnderlyingInterest,
            compoundingStreamVars.senderShare
        );
        require(vars.mathErr == MathError.NO_ERROR, "sender interest calculation error");

        /* Calculate the recipient's share of the interest. */
        (vars.mathErr, vars.recipientUnderlyingInterest) = subExp(
            vars.netUnderlyingInterest,
            vars.senderUnderlyingInterest
        );
        /*
         * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know that `senderUnderlyingInterest`
         * is less or equal than `netUnderlyingInterest`, because `senderShare` is bounded between 1e16 and 1e18.
         */
        assert(vars.mathErr == MathError.NO_ERROR);

        /* Convert the interest to the equivalent cToken denomination. */
        (vars.mathErr, vars.senderInterest) = divExp(vars.senderUnderlyingInterest, exchangeRateCurrent);
        require(vars.mathErr == MathError.NO_ERROR, "sender interest conversion error");

        (vars.mathErr, vars.recipientInterest) = divExp(vars.recipientUnderlyingInterest, exchangeRateCurrent);
        require(vars.mathErr == MathError.NO_ERROR, "recipient interest conversion error");

        (vars.mathErr, vars.sablierInterest) = divExp(vars.sablierUnderlyingInterest, exchangeRateCurrent);
        require(vars.mathErr == MathError.NO_ERROR, "sablier interest conversion error");

        /* Truncating the results means losing everything on the last 1e18 positions of the mantissa */
        return (truncate(vars.senderInterest), truncate(vars.recipientInterest), truncate(vars.sablierInterest));
    }

    /**
     * @notice Returns the amount of interest that has been accrued for the given token address.
     * @param tokenAddress The address of the token to get the earnings for.
     * @return The amount of interest as uint256.
     */
    function getEarnings(address tokenAddress) external view returns (uint256) {
        require(cTokenManager.isCToken(tokenAddress), "token is not cToken");
        return earnings[tokenAddress];
    }

    /*** Public Effects & Interactions Functions ***/

    struct CreateStreamLocalVars {
        MathError mathErr;
        uint256 duration;
        uint256 ratePerSecond;
    }

    /**
     * @notice Creates a new stream funded by `msg.sender` and paid towards `recipient`.
     * @dev Throws if paused.
     *  Throws if the recipient is the zero address, the contract itself or the caller.
     *  Throws if the deposit is 0.
     *  Throws if the start time is before `block.timestamp`.
     *  Throws if the stop time is before the start time.
     *  Throws if the duration calculation has a math error.
     *  Throws if the deposit is smaller than the duration.
     *  Throws if the deposit is not a multiple of the duration.
     *  Throws if the rate calculation has a math error.
     *  Throws if the next stream id calculation has a math error.
     *  Throws if the contract is not allowed to transfer enough tokens.
     *  Throws if there is a token transfer failure.
     * @param recipient The address towards which the money is streamed.
     * @param deposit The amount of money to be streamed.
     * @param tokenAddress The ERC20 token to use as streaming currency.
     * @param startTime The unix timestamp for when the stream starts.
     * @param stopTime The unix timestamp for when the stream stops.
     * @return The uint256 id of the newly created stream.
     */
    function createStream(address recipient, uint256 deposit, address tokenAddress, uint256 startTime, uint256 stopTime)
        public
        whenNotPaused
        returns (uint256)
    {
        require(recipient != address(0x00), "stream to the zero address");
        require(recipient != address(this), "stream to the contract itself");
        require(recipient != msg.sender, "stream to the caller");
        require(deposit > 0, "deposit is zero");
        require(startTime >= block.timestamp, "start time before block.timestamp");
        require(stopTime > startTime, "stop time before the start time");

        CreateStreamLocalVars memory vars;
        (vars.mathErr, vars.duration) = subUInt(stopTime, startTime);
        /* `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know `stopTime` is higher than `startTime`. */
        assert(vars.mathErr == MathError.NO_ERROR);

        /* Without this, the rate per second would be zero. */
        require(deposit >= vars.duration, "deposit smaller than time delta");

        /* This condition avoids dealing with remainders */
        require(deposit % vars.duration == 0, "deposit not multiple of time delta");

        (vars.mathErr, vars.ratePerSecond) = divUInt(deposit, vars.duration);
        /* `divUInt` can only return MathError.DIVISION_BY_ZERO but we know `duration` is not zero. */
        assert(vars.mathErr == MathError.NO_ERROR);

        /* Create and store the stream object. */
        uint256 streamId = nextStreamId;
        streams[streamId] = Types.Stream({
            remainingBalance: deposit,
            deposit: deposit,
            isEntity: true,
            ratePerSecond: vars.ratePerSecond,
            recipient: recipient,
            sender: msg.sender,
            startTime: startTime,
            stopTime: stopTime,
            tokenAddress: tokenAddress
        });

        /* Increment the next stream id. */
        (vars.mathErr, nextStreamId) = addUInt(nextStreamId, uint256(1));
        require(vars.mathErr == MathError.NO_ERROR, "next stream id calculation error");

        require(IERC20(tokenAddress).transferFrom(msg.sender, address(this), deposit), "token transfer failure");
        emit CreateStream(streamId, msg.sender, recipient, deposit, tokenAddress, startTime, stopTime);
        return streamId;
    }

    struct CreateCompoundingStreamLocalVars {
        MathError mathErr;
        uint256 shareSum;
        uint256 underlyingBalance;
        uint256 senderShareMantissa;
        uint256 recipientShareMantissa;
    }

    /**
     * @notice Creates a new compounding stream funded by `msg.sender` and paid towards `recipient`.
     * @dev Inherits all security checks from `createStream`.
     *  Throws if the cToken is not whitelisted.
     *  Throws if the sender share percentage and the recipient share percentage do not sum up to 100.
     *  Throws if the the sender share mantissa calculation has a math error.
     *  Throws if the the recipient share mantissa calculation has a math error.
     * @param recipient The address towards which the money is streamed.
     * @param deposit The amount of money to be streamed.
     * @param tokenAddress The ERC20 token to use as streaming currency.
     * @param startTime The unix timestamp for when the stream starts.
     * @param stopTime The unix timestamp for when the stream stops.
     * @param senderSharePercentage The sender's share of the interest, as a percentage.
     * @param recipientSharePercentage The recipient's share of the interest, as a percentage.
     * @return The uint256 id of the newly created compounding stream.
     */
    function createCompoundingStream(
        address recipient,
        uint256 deposit,
        address tokenAddress,
        uint256 startTime,
        uint256 stopTime,
        uint256 senderSharePercentage,
        uint256 recipientSharePercentage
    ) external whenNotPaused returns (uint256) {
        require(cTokenManager.isCToken(tokenAddress), "cToken is not whitelisted");
        CreateCompoundingStreamLocalVars memory vars;

        /* Ensure that the interest shares sum up to 100%. */
        (vars.mathErr, vars.shareSum) = addUInt(senderSharePercentage, recipientSharePercentage);
        require(vars.mathErr == MathError.NO_ERROR, "share sum calculation error");
        require(vars.shareSum == 100, "shares do not sum up to 100");

        uint256 streamId = createStream(recipient, deposit, tokenAddress, startTime, stopTime);

        /*
         * `senderSharePercentage` and `recipientSharePercentage` will be stored as mantissas, so we scale them up
         * by one percent in Exp terms.
         */
        (vars.mathErr, vars.senderShareMantissa) = mulUInt(senderSharePercentage, onePercent);
        /*
         * `mulUInt` can only return MathError.INTEGER_OVERFLOW but we control `onePercent` and
         * we know `senderSharePercentage` is maximum 100.
         */
        assert(vars.mathErr == MathError.NO_ERROR);

        (vars.mathErr, vars.recipientShareMantissa) = mulUInt(recipientSharePercentage, onePercent);
        /*
         * `mulUInt` can only return MathError.INTEGER_OVERFLOW but we control `onePercent` and
         * we know `recipientSharePercentage` is maximum 100.
         */
        assert(vars.mathErr == MathError.NO_ERROR);

        /* Create and store the compounding stream vars. */
        uint256 exchangeRateCurrent = ICERC20(tokenAddress).exchangeRateCurrent();
        compoundingStreamsVars[streamId] = Types.CompoundingStreamVars({
            exchangeRateInitial: Exp({ mantissa: exchangeRateCurrent }),
            isEntity: true,
            recipientShare: Exp({ mantissa: vars.recipientShareMantissa }),
            senderShare: Exp({ mantissa: vars.senderShareMantissa })
        });

        emit CreateCompoundingStream(streamId, exchangeRateCurrent, senderSharePercentage, recipientSharePercentage);
        return streamId;
    }

    /**
     * @notice Withdraws from the contract to the recipient's account.
     * @dev Throws if the id does not point to a valid stream.
     *  Throws if the caller is not the sender or the recipient of the stream.
     *  Throws if the amount exceeds the available balance.
     *  Throws if there is a token transfer failure.
     * @param streamId The id of the stream to withdraw tokens from.
     * @param amount The amount of tokens to withdraw.
     * @return bool true=success, otherwise false.
     */
    function withdrawFromStream(uint256 streamId, uint256 amount)
        external
        whenNotPaused
        nonReentrant
        streamExists(streamId)
        onlySenderOrRecipient(streamId)
        returns (bool)
    {
        require(amount > 0, "amount is zero");
        Types.Stream memory stream = streams[streamId];
        uint256 balance = balanceOf(streamId, stream.recipient);
        require(balance >= amount, "amount exceeds the available balance");

        if (!compoundingStreamsVars[streamId].isEntity) {
            withdrawFromStreamInternal(streamId, amount);
        } else {
            withdrawFromCompoundingStreamInternal(streamId, amount);
        }
        return true;
    }

    /**
     * @notice Cancels the stream and transfers the tokens back on a pro rata basis.
     * @dev Throws if the id does not point to a valid stream.
     *  Throws if the caller is not the sender or the recipient of the stream.
     *  Throws if there is a token transfer failure.
     * @param streamId The id of the stream to cancel.
     * @return bool true=success, otherwise false.
     */
    function cancelStream(uint256 streamId)
        external
        nonReentrant
        streamExists(streamId)
        onlySenderOrRecipient(streamId)
        returns (bool)
    {
        if (!compoundingStreamsVars[streamId].isEntity) {
            cancelStreamInternal(streamId);
        } else {
            cancelCompoundingStreamInternal(streamId);
        }
        return true;
    }

    /*** Internal Effects & Interactions Functions ***/

    struct WithdrawFromStreamInternalLocalVars {
        MathError mathErr;
    }

    /**
     * @notice Makes the withdrawal to the recipient of the stream.
     * @dev If the stream balance has been depleted to 0, the stream object is deleted
     *  to save gas and optimise contract storage.
     *  Throws if the stream balance calculation has a math error.
     *  Throws if there is a token transfer failure.
     */
    function withdrawFromStreamInternal(uint256 streamId, uint256 amount) internal {
        Types.Stream memory stream = streams[streamId];
        WithdrawFromStreamInternalLocalVars memory vars;
        (vars.mathErr, streams[streamId].remainingBalance) = subUInt(stream.remainingBalance, amount);
        /**
         * `subUInt` can only return MathError.INTEGER_UNDERFLOW but we know that `remainingBalance` is at least
         * as big as `amount`. See the `require` check in `withdrawFromInternal`.
         */
        assert(vars.mathErr == MathError.NO_ERROR);

        if (streams[streamId].remainingBalance == 0) delete streams[streamId];

        require(IERC20(stream.tokenAddress).transfer(stream.recipient, amount), "token transfer failure");
        emit WithdrawFromStream(streamId, stream.recipient, amount);
    }

    struct WithdrawFromCompoundingStreamInternalLocalVars {
        MathError mathErr;
        uint256 amountWithoutSenderInterest;
        uint256 netWithdrawalAmount;
    }

    /**
     * @notice Withdraws to the recipient's account and pays the accrued interest to all parties.
     * @dev If the stream balance has been depleted to 0, the stream object to save gas and optimise
     *  contract storage.
     *  Throws if there is a math error.
     *  Throws if there is a token transfer failure.
     */
    function withdrawFromCompoundingStreamInternal(uint256 streamId, uint256 amount) internal {
        Types.Stream memory stream = streams[streamId];
        WithdrawFromCompoundingStreamInternalLocalVars memory vars;

        /* Calculate the interest earned by each party for keeping `stream.balance` in the smart contract. */
        (uint256 senderInterest, uint256 recipientInterest, uint256 sablierInterest) = interestOf(streamId, amount);

        /*
         * Calculate the net withdrawal amount by subtracting `senderInterest` and `sablierInterest`.
         * Because the decimal points are lost when we truncate Exponentials, the recipient will implicitly earn
         * `recipientInterest` plus a tiny-weeny amount of interest, max 2e-8 in cToken denomination.
         */
        (vars.mathErr, vars.amountWithoutSenderInterest) = subUInt(amount, senderInterest);
        require(vars.mathErr == MathError.NO_ERROR, "amount without sender interest calculation error");
        (vars.mathErr, vars.netWithdrawalAmount) = subUInt(vars.amountWithoutSenderInterest, sablierInterest);
        require(vars.mathErr == MathError.NO_ERROR, "net withdrawal amount calculation error");

        /* Subtract `amount` from the remaining balance of the stream. */
        (vars.mathErr, streams[streamId].remainingBalance) = subUInt(stream.remainingBalance, amount);
        require(vars.mathErr == MathError.NO_ERROR, "balance subtraction calculation error");

        /* Delete the objects from storage if the remaining balance has been depleted to 0. */
        if (streams[streamId].remainingBalance == 0) {
            delete streams[streamId];
            delete compoundingStreamsVars[streamId];
        }

        /* Add the sablier interest to the earnings for this cToken. */
        (vars.mathErr, earnings[stream.tokenAddress]) = addUInt(earnings[stream.tokenAddress], sablierInterest);
        require(vars.mathErr == MathError.NO_ERROR, "earnings addition calculation error");

        /* Transfer the tokens to the sender and the recipient. */
        ICERC20 cToken = ICERC20(stream.tokenAddress);
        if (senderInterest > 0)
            require(cToken.transfer(stream.sender, senderInterest), "sender token transfer failure");
        require(cToken.transfer(stream.recipient, vars.netWithdrawalAmount), "recipient token transfer failure");

        emit WithdrawFromStream(streamId, stream.recipient, vars.netWithdrawalAmount);
        emit PayInterest(streamId, senderInterest, recipientInterest, sablierInterest);
    }

    /**
     * @notice Cancels the stream and transfers the tokens back on a pro rata basis.
     * @dev The stream and compounding stream vars objects get deleted to save gas
     *  and optimise contract storage.
     *  Throws if there is a token transfer failure.
     */
    function cancelStreamInternal(uint256 streamId) internal {
        Types.Stream memory stream = streams[streamId];
        uint256 senderBalance = balanceOf(streamId, stream.sender);
        uint256 recipientBalance = balanceOf(streamId, stream.recipient);

        delete streams[streamId];

        IERC20 token = IERC20(stream.tokenAddress);
        if (recipientBalance > 0)
            require(token.transfer(stream.recipient, recipientBalance), "recipient token transfer failure");
        if (senderBalance > 0) require(token.transfer(stream.sender, senderBalance), "sender token transfer failure");

        emit CancelStream(streamId, stream.sender, stream.recipient, senderBalance, recipientBalance);
    }

    struct CancelCompoundingStreamInternal {
        MathError mathErr;
        uint256 netSenderBalance;
        uint256 recipientBalanceWithoutSenderInterest;
        uint256 netRecipientBalance;
    }

    /**
     * @notice Cancels the stream, transfers the tokens back on a pro rata basis and pays the accrued
     * interest to all parties.
     * @dev Importantly, the money that has not been streamed yet is not considered chargeable.
     *  All the interest generated by that underlying will be returned to the sender.
     *  Throws if there is a math error.
     *  Throws if there is a token transfer failure.
     */
    function cancelCompoundingStreamInternal(uint256 streamId) internal {
        Types.Stream memory stream = streams[streamId];
        CancelCompoundingStreamInternal memory vars;

        /*
         * The sender gets back all the money that has not been streamed so far. By that, we mean both
         * the underlying amount and the interest generated by it.
         */
        uint256 senderBalance = balanceOf(streamId, stream.sender);
        uint256 recipientBalance = balanceOf(streamId, stream.recipient);

        /* Calculate the interest earned by each party for keeping `recipientBalance` in the smart contract. */
        (uint256 senderInterest, uint256 recipientInterest, uint256 sablierInterest) = interestOf(
            streamId,
            recipientBalance
        );

        /*
         * We add `senderInterest` to `senderBalance` to compute the net balance for the sender.
         * After this, the rest of the function is similar to `withdrawFromCompoundingStreamInternal`, except
         * we add the sender's share of the interest generated by `recipientBalance` to `senderBalance`.
         */
        (vars.mathErr, vars.netSenderBalance) = addUInt(senderBalance, senderInterest);
        require(vars.mathErr == MathError.NO_ERROR, "net sender balance calculation error");

        /*
         * Calculate the net withdrawal amount by subtracting `senderInterest` and `sablierInterest`.
         * Because the decimal points are lost when we truncate Exponentials, the recipient will implicitly earn
         * `recipientInterest` plus a tiny-weeny amount of interest, max 2e-8 in cToken denomination.
         */
        (vars.mathErr, vars.recipientBalanceWithoutSenderInterest) = subUInt(recipientBalance, senderInterest);
        require(vars.mathErr == MathError.NO_ERROR, "recipient balance without sender interest calculation error");
        (vars.mathErr, vars.netRecipientBalance) = subUInt(vars.recipientBalanceWithoutSenderInterest, sablierInterest);
        require(vars.mathErr == MathError.NO_ERROR, "net recipient balance calculation error");

        /* Add the sablier interest to the earnings attributed to this cToken. */
        (vars.mathErr, earnings[stream.tokenAddress]) = addUInt(earnings[stream.tokenAddress], sablierInterest);
        require(vars.mathErr == MathError.NO_ERROR, "earnings addition calculation error");

        /* Delete the objects from storage. */
        delete streams[streamId];
        delete compoundingStreamsVars[streamId];

        /* Transfer the tokens to the sender and the recipient. */
        IERC20 token = IERC20(stream.tokenAddress);
        if (vars.netSenderBalance > 0)
            require(token.transfer(stream.sender, vars.netSenderBalance), "sender token transfer failure");
        if (vars.netRecipientBalance > 0)
            require(token.transfer(stream.recipient, vars.netRecipientBalance), "recipient token transfer failure");

        emit CancelStream(streamId, stream.sender, stream.recipient, vars.netSenderBalance, vars.netRecipientBalance);
        emit PayInterest(streamId, senderInterest, recipientInterest, sablierInterest);
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"getEarnings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"nextStreamId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"getCompoundingStream","outputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"},{"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"internalType":"uint256","name":"ratePerSecond","type":"uint256"},{"internalType":"uint256","name":"exchangeRateInitial","type":"uint256"},{"internalType":"uint256","name":"senderSharePercentage","type":"uint256"},{"internalType":"uint256","name":"recipientSharePercentage","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"},{"internalType":"address","name":"who","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isPauser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"cancelStream","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFromStream","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"},{"internalType":"uint256","name":"senderSharePercentage","type":"uint256"},{"internalType":"uint256","name":"recipientSharePercentage","type":"uint256"}],"name":"createCompoundingStream","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addPauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"getStream","outputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"},{"internalType":"uint256","name":"remainingBalance","type":"uint256"},{"internalType":"uint256","name":"ratePerSecond","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"interestOf","outputs":[{"internalType":"uint256","name":"senderInterest","type":"uint256"},{"internalType":"uint256","name":"recipientInterest","type":"uint256"},{"internalType":"uint256","name":"sablierInterest","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"feePercentage","type":"uint256"}],"name":"updateFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"isCompoundingStream","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"streamId","type":"uint256"}],"name":"deltaOf","outputs":[{"internalType":"uint256","name":"delta","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"takeEarnings","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"initialize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"stopTime","type":"uint256"}],"name":"createStream","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cTokenManager","outputs":[{"internalType":"contract ICTokenManager","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"mantissa","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cTokenManagerAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exchangeRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"senderSharePercentage","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recipientSharePercentage","type":"uint256"}],"name":"CreateCompoundingStream","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"senderInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recipientInterest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"sablierInterest","type":"uint256"}],"name":"PayInterest","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TakeEarnings","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"UpdateFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"PauserAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"PauserRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"deposit","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"stopTime","type":"uint256"}],"name":"CreateStream","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawFromStream","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"streamId","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"senderBalance","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"recipientBalance","type":"uint256"}],"name":"CancelStream","type":"event"}]

60806040523480156200001157600080fd5b5060405162004d7a38038062004d7a833981810160405260208110156200003757600080fd5b50516001600160a01b0381166200009a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018062004d50602a913960400191505060405180910390fd5b620000b033620000f160201b620043e11760201c565b620000c6336200020e60201b6200239f1760201c565b60ce80546001600160a01b0319166001600160a01b0392909216919091179055600160d155620004ff565b600054610100900460ff1680620001165750620001166001600160e01b03620002fb16565b8062000125575060005460ff16155b6200017c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018062004d22602e913960400191505060405180910390fd5b600054610100900460ff16158015620001a8576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a380156200020a576000805461ff00191690555b5050565b600054610100900460ff1680620002335750620002336001600160e01b03620002fb16565b8062000242575060005460ff16155b62000299576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018062004d22602e913960400191505060405180910390fd5b600054610100900460ff16158015620002c5576000805460ff1961ff0019909116610100171660011790555b620002db826200030160201b62003faf1760201c565b6099805460ff1916905580156200020a576000805461ff00191690555050565b303b1590565b600054610100900460ff1680620003265750620003266001600160e01b03620002fb16565b8062000335575060005460ff16155b6200038c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602e81526020018062004d22602e913960400191505060405180910390fd5b600054610100900460ff16158015620003b8576000805460ff1961ff0019909116610100171660011790555b620003cc826001600160e01b03620003fb16565b620003e557620003e5826001600160e01b036200041e16565b80156200020a576000805461ff00191690555050565b6000620004188260666200047060201b62002b711790919060201c565b92915050565b62000439816066620004a660201b620041011790919060201c565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b60006001600160a01b0382166200048657600080fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b6001600160a01b038116620004ba57600080fd5b620004cf82826001600160e01b036200047016565b15620004da57600080fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b614813806200050f6000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c8063894e9a0d116100de578063a82ccd4d11610097578063cc1b4bf611610071578063cc1b4bf614610518578063d2cba55c14610558578063ddca3f4314610560578063f2fde38b146105685761018e565b8063a82ccd4d146104a9578063c1eb9ee0146104c6578063c4d66de8146104f25761018e565b8063894e9a0d146103925780638c9a3252146104025780638da5cb5b146104435780638f32d59b146104675780639012c4a81461046f578063a734d51b1461048c5761018e565b80635c975abb1161014b5780638129fc1c116101255780638129fc1c146103105780638195aeaa1461031857806382dc1ec4146103645780638456cb591461038a5761018e565b80635c975abb146102c85780636db9241b146102d05780637a9b2c6c146102ed5761018e565b8063131b9c04146101935780631e99d569146101cb5780632b8a119d146101d35780633656eec2146102585780633f4ba83a1461028457806346fbf68e1461028e575b600080fd5b6101b9600480360360208110156101a957600080fd5b50356001600160a01b031661058e565b60408051918252519081900360200190f35b6101b961066e565b6101f0600480360360208110156101e957600080fd5b5035610674565b604080516001600160a01b039c8d1681529a8c1660208c01528a810199909952969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b6101b96004803603604081101561026e57600080fd5b50803590602001356001600160a01b03166108a1565b61028c610b7e565b005b6102b4600480360360208110156102a457600080fd5b50356001600160a01b0316610c67565b604080519115158252519081900360200190f35b6102b4610c80565b6102b4600480360360208110156102e657600080fd5b5035610c89565b6102b46004803603604081101561030357600080fd5b5080359060200135610dbc565b61028c611063565b6101b9600480360360e081101561032e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060808101359060a08101359060c0013561110a565b61028c6004803603602081101561037a57600080fd5b50356001600160a01b03166114ec565b61028c61153b565b6103af600480360360208110156103a857600080fd5b5035611602565b604080516001600160a01b03998a168152978916602089015287810196909652939096166060860152608085019190915260a084015260c083019390935260e08201929092529051908190036101000190f35b6104256004803603604081101561041857600080fd5b50803590602001356116ce565b60408051938452602084019290925282820152519081900360600190f35b61044b611e1d565b604080516001600160a01b039092168252519081900360200190f35b6102b4611e2c565b61028c6004803603602081101561048557600080fd5b5035611e52565b6102b4600480360360208110156104a257600080fd5b5035611f4e565b6101b9600480360360208110156104bf57600080fd5b5035611f66565b61028c600480360360408110156104dc57600080fd5b506001600160a01b038135169060200135612098565b61028c6004803603602081101561050857600080fd5b50356001600160a01b031661239f565b6101b9600480360360a081101561052e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135612455565b61044b612ad9565b6101b9612ae8565b61028c6004803603602081101561057e57600080fd5b50356001600160a01b0316612aee565b60ce5460408051632f52e59560e01b81526001600160a01b03848116600483015291516000939290921691632f52e59591602480820192602092909190829003018186803b1580156105df57600080fd5b505afa1580156105f3573d6000803e3d6000fd5b505050506040513d602081101561060957600080fd5b5051610652576040805162461bcd60e51b81526020600482015260136024820152723a37b5b2b71034b9903737ba1031aa37b5b2b760691b604482015290519081900360640190fd5b506001600160a01b0316600090815260cf602052604090205490565b60d15481565b60008060008060008060008060008060008b60d2600082815260200190815260200160002060070160149054906101000a900460ff166106e9576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b60008d815260cd60205260409020600301548d9060ff1661073b5760405162461bcd60e51b81526004018080602001828103825260218152602001806144d36021913960400191505060405180910390fd5b60d260008f815260200190815260200160002060060160009054906101000a90046001600160a01b03169c5060d260008f815260200190815260200160002060050160009054906101000a90046001600160a01b03169b5060d260008f8152602001908152602001600020600001549a5060d260008f815260200190815260200160002060070160009054906101000a90046001600160a01b0316995060d260008f815260200190815260200160002060030154985060d260008f815260200190815260200160002060040154975060d260008f815260200190815260200160002060020154965060d260008f815260200190815260200160002060010154955060cd60008f815260200190815260200160002060000160000154945060cd60008f815260200190815260200160002060010160000154935060cd60008f8152602001908152602001600020600201600001549250505091939597999b90929496989a50565b600082815260d260205260408120600701548390600160a01b900460ff166108fe576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b6109066141fd565b50600084815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff16151561010082015261099c614266565b60006109a787611f66565b90506109b7818460200151612b08565b60208401819052838260038111156109cb57fe5b60038111156109d657fe5b90525060009050825160038111156109ea57fe5b14610a265760405162461bcd60e51b81526004018080602001828103825260238152602001806147856023913960400191505060405180910390fd5b604083015183511115610acb57610a4583600001518460400151612b4a565b6040840181905283826003811115610a5957fe5b6003811115610a6457fe5b9052506000905082516003811115610a7857fe5b14610a7f57fe5b610a9182602001518360400151612b4a565b6020840181905283826003811115610aa557fe5b6003811115610ab057fe5b9052506000905082516003811115610ac457fe5b14610acb57fe5b8260a001516001600160a01b0316866001600160a01b03161415610af75750602001519250610b779050565b8260c001516001600160a01b0316866001600160a01b03161415610b6f57610b2783604001518360200151612b4a565b6060840181905283826003811115610b3b57fe5b6003811115610b4657fe5b9052506000905082516003811115610b5a57fe5b14610b6157fe5b50606001519250610b779050565b600094505050505b5092915050565b610b8e610b89612b6d565b610c67565b610bc95760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16610c17576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6099805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610c4a612b6d565b604080516001600160a01b039092168252519081900360200190a1565b6000610c7a60668363ffffffff612b7116565b92915050565b60995460ff1690565b609a805460010190819055600082815260d260205260408120600701549091908390600160a01b900460ff16610cf4576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600084815260d2602052604090206006015484906001600160a01b0316331480610d375750600081815260d260205260409020600501546001600160a01b031633145b610d725760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b600085815260cd602052604090206003015460ff16610d9957610d9485612ba6565b610da2565b610da285612ef4565b600193505050609a548114610db657600080fd5b50919050565b60995460009060ff1615610e0a576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b609a805460010190819055600084815260d260205260409020600701548490600160a01b900460ff16610e72576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600085815260d2602052604090206006015485906001600160a01b0316331480610eb55750600081815260d260205260409020600501546001600160a01b031633145b610ef05760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b60008511610f36576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b610f3e6141fd565b50600086815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a084018190526006830154821660c085015260079092015490811660e0840152600160a01b900460ff161515610100830152909190610fda9089906108a1565b90508681101561101b5760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b600088815260cd602052604090206003015460ff166110435761103e8888613504565b61104d565b61104d8888613797565b6001955050505050609a548114610b7757600080fd5b600054610100900460ff168061107c575061107c613d7e565b8061108a575060005460ff16155b6110c55760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff161580156110f0576000805460ff1961ff0019909116610100171660011790555b6001609a558015611107576000805461ff00191690555b50565b60995460009060ff1615611158576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b60ce5460408051632f52e59560e01b81526001600160a01b03898116600483015291519190921691632f52e595916024808301926020929190829003018186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d60208110156111cf57600080fd5b505161121e576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b61122661428f565b6112308484613d84565b602083018190528282600381111561124457fe5b600381111561124f57fe5b905250600090508151600381111561126357fe5b146112b5576040805162461bcd60e51b815260206004820152601b60248201527f73686172652073756d2063616c63756c6174696f6e206572726f720000000000604482015290519081900360640190fd5b806020015160641461130e576040805162461bcd60e51b815260206004820152601b60248201527f73686172657320646f206e6f742073756d20757020746f203130300000000000604482015290519081900360640190fd5b600061131d8a8a8a8a8a612455565b905061133085662386f26fc10000612b08565b606084018190528382600381111561134457fe5b600381111561134f57fe5b905250600090508251600381111561136357fe5b1461136a57fe5b61137b84662386f26fc10000612b08565b608084018190528382600381111561138f57fe5b600381111561139a57fe5b90525060009050825160038111156113ae57fe5b146113b557fe5b6000886001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156113f257600080fd5b505af1158015611406573d6000803e3d6000fd5b505050506040513d602081101561141c57600080fd5b50516040805160a08101825260808082018481528252825160208082018552606089810151835281850192835285518083018752938a01518452848601938452600181860181815260008b815260cd8552889020965151875593515190860155925151600285015590516003909301805460ff19169315159390931790925582518481529182018a9052818301899052915192935084927fa9bbfc8562a8e1e6b889a428f128c90ed60c6204c37e4fb4354a202b4db59204929181900390910190a2509998505050505050505050565b6114f7610b89612b6d565b6115325760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b61110781613daa565b611546610b89612b6d565b6115815760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16156115cc576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6099805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610c4a612b6d565b6000806000806000806000808860d2600082815260200190815260200160002060070160149054906101000a900460ff16611672576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b5050506000968752505060d26020525050604090922060068101546005820154825460078401546003850154600486015460028701546001909701546001600160a01b039687169a958716995093975091909416949092909190565b600082815260d26020526040812060070154819081908590600160a01b900460ff1661172f576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600086815260cd602052604090206003015460ff166117575760009350839250829150611e15565b61175f6141fd565b50600086815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526117f56142bf565b50600087815260cd6020908152604091829020825160a08101845281546080820190815281528351808401855260018301548152818401528351928301845260028201548352928301919091526003015460ff16151560608201526118586142f9565b611860614382565b60405180602001604052808560e001516001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b505050506040513d60208110156118d457600080fd5b505190528351518151919250106118f9575060009650869550859450611e1592505050565b611907818460000151613df2565b602084018190528382600381111561191b57fe5b600381111561192657fe5b905250600090508251600381111561193a57fe5b1461194157fe5b61194f82602001518a613e2c565b604084018190528382600381111561196357fe5b600381111561196e57fe5b905250600090508251600381111561198257fe5b146119d4576040805162461bcd60e51b815260206004820152601a60248201527f696e7465726573742063616c63756c6174696f6e206572726f72000000000000604482015290519081900360640190fd5b60d054670de0b6b3a76400001415611a86576119f4826040015182613e94565b610120840181905283826003811115611a0957fe5b6003811115611a1457fe5b9052506000905082516003811115611a2857fe5b14611a645760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b600080611a75846101200151613eb7565b91995097509550611e159350505050565b60d054611aad57604080516020810182526000815260c08401528201516060830152611b85565b60408083015181516020810190925260d0548252611aca91613ec6565b60c0840181905283826003811115611ade57fe5b6003811115611ae957fe5b9052506000905082516003811115611afd57fe5b14611b395760405162461bcd60e51b81526004018080602001828103825260228152602001806146196022913960400191505060405180910390fd5b611b4b82604001518360c00151613df2565b6060840181905283826003811115611b5f57fe5b6003811115611b6a57fe5b9052506000905082516003811115611b7e57fe5b14611b8557fe5b611b9782606001518460200151613ec6565b6080840181905283826003811115611bab57fe5b6003811115611bb657fe5b9052506000905082516003811115611bca57fe5b14611c065760405162461bcd60e51b81526004018080602001828103825260218152602001806145d76021913960400191505060405180910390fd5b611c1882606001518360800151613df2565b60a0840181905283826003811115611c2c57fe5b6003811115611c3757fe5b9052506000905082516003811115611c4b57fe5b14611c5257fe5b611c60826080015182613e94565b60e0840181905283826003811115611c7457fe5b6003811115611c7f57fe5b9052506000905082516003811115611c9357fe5b14611ce5576040805162461bcd60e51b815260206004820181905260248201527f73656e64657220696e74657265737420636f6e76657273696f6e206572726f72604482015290519081900360640190fd5b611cf38260a0015182613e94565b610100840181905283826003811115611d0857fe5b6003811115611d1357fe5b9052506000905082516003811115611d2757fe5b14611d635760405162461bcd60e51b815260040180806020018281038252602381526020018061468d6023913960400191505060405180910390fd5b611d718260c0015182613e94565b610120840181905283826003811115611d8657fe5b6003811115611d9157fe5b9052506000905082516003811115611da557fe5b14611de15760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b611dee8260e00151613eb7565b611dfc836101000151613eb7565b611e0a846101200151613eb7565b975097509750505050505b509250925092565b6033546001600160a01b031690565b6033546000906001600160a01b0316611e43612b6d565b6001600160a01b031614905090565b611e5a611e2c565b611e6357600080fd5b6064811115611eb9576040805162461bcd60e51b815260206004820152601f60248201527f6665652070657263656e7461676520686967686572207468616e203130302500604482015290519081900360640190fd5b611ec1614395565b611ed282662386f26fc10000612b08565b6020830181905282826003811115611ee657fe5b6003811115611ef157fe5b9052506000905081516003811115611f0557fe5b14611f0c57fe5b60408051602080820183528301519081905260d0555182907f38e229a7f3f9c329892d08eb37c4e91ccac6d12c798d394990ca4f56028ec26690600090a25050565b600090815260cd602052604090206003015460ff1690565b600081815260d260205260408120600701548290600160a01b900460ff16611fc3576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b611fcb6141fd565b50600083815260d26020908152604091829020825161012081018452815481526001820154928101929092526002810154928201929092526003820154606082018190526004830154608083015260058301546001600160a01b0390811660a08401526006840154811660c084015260079093015492831660e0830152600160a01b90920460ff16151561010082015290421161206c576000925050610db6565b8060800151421015612085576060015142039150610db6565b6060810151608090910151039392505050565b6120a0611e2c565b6120a957600080fd5b609a80546001019081905560ce5460408051632f52e59560e01b81526001600160a01b03868116600483015291519190921691632f52e595916024808301926020929190829003018186803b15801561210157600080fd5b505afa158015612115573d6000803e3d6000fd5b505050506040513d602081101561212b57600080fd5b505161217a576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b600082116121c0576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b6001600160a01b038316600090815260cf60205260409020548211156122175760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b61221f6143ac565b6001600160a01b038416600090815260cf60205260409020546122429084612b4a565b6001600160a01b038616600090815260cf602052604090208190558282600381111561226a57fe5b600381111561227557fe5b905250600090508151600381111561228957fe5b1461229057fe5b60405183906001600160a01b038616907f13e8af02ad3e36f8d82fc8b86dcd67b7ed11f718f0e52fb245d2038eb71856ba90600090a36040805163a9059cbb60e01b81523360048201526024810185905290516001600160a01b0386169163a9059cbb9160448083019260209291908290030181600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b505161238b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b50609a54811461239a57600080fd5b505050565b600054610100900460ff16806123b857506123b8613d7e565b806123c6575060005460ff16155b6124015760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561242c576000805460ff1961ff0019909116610100171660011790555b61243582613faf565b6099805460ff191690558015612451576000805461ff00191690555b5050565b60995460009060ff16156124a3576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0386166124fe576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b03861630141561255c576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b0386163314156125b1576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b600085116125f8576040805162461bcd60e51b815260206004820152600f60248201526e6465706f736974206973207a65726f60881b604482015290519081900360640190fd5b428310156126375760405162461bcd60e51b81526004018080602001828103825260218152602001806145f86021913960400191505060405180910390fd5b82821161268b576040805162461bcd60e51b815260206004820152601f60248201527f73746f702074696d65206265666f7265207468652073746172742074696d6500604482015290519081900360640190fd5b6126936143bf565b61269d8385612b4a565b60208301819052828260038111156126b157fe5b60038111156126bc57fe5b90525060009050815160038111156126d057fe5b146126d757fe5b8060200151861015612730576040805162461bcd60e51b815260206004820152601f60248201527f6465706f73697420736d616c6c6572207468616e2074696d652064656c746100604482015290519081900360640190fd5b8060200151868161273d57fe5b061561277a5760405162461bcd60e51b815260040180806020018281038252602281526020018061463b6022913960400191505060405180910390fd5b612788868260200151614067565b604083018190528282600381111561279c57fe5b60038111156127a757fe5b90525060009050815160038111156127bb57fe5b146127c257fe5b600060d154905060405180610120016040528088815260200183604001518152602001888152602001868152602001858152602001896001600160a01b03168152602001336001600160a01b03168152602001876001600160a01b031681526020016001151581525060d26000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160060160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160070160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160070160146101000a81548160ff02191690831515021790555090505061292860d1546001613d84565b60d18190558382600381111561293a57fe5b600381111561294557fe5b905250600090508251600381111561295957fe5b146129ab576040805162461bcd60e51b815260206004820181905260248201527f6e6578742073747265616d2069642063616c63756c6174696f6e206572726f72604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038816916323b872dd9160648083019260209291908290030181600087803b158015612a0057600080fd5b505af1158015612a14573d6000803e3d6000fd5b505050506040513d6020811015612a2a57600080fd5b5051612a76576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b604080518881526001600160a01b038881166020830152818301889052606082018790529151918a1691339184917f7b01d409597969366dc268d7f957a990d1ca3d3449baf8fb45db67351aecfe789181900360800190a4979650505050505050565b60ce546001600160a01b031681565b60d05481565b612af6611e2c565b612aff57600080fd5b61110781614092565b60008083612b1b57506000905080612b43565b83830283858281612b2857fe5b0414612b3c57506002915060009050612b43565b6000925090505b9250929050565b600080838311612b61575060009050818303612b43565b50600390506000612b43565b3390565b60006001600160a01b038216612b8657600080fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b612bae6141fd565b50600081815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a08401526006820154811660c0840181905260079092015490811660e0840152600160a01b900460ff161515610100830152909190612c4a9084906108a1565b90506000612c5c848460a001516108a1565b600085815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b031916905560e08401519091508115612daa57806001600160a01b031663a9059cbb8560a00151846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612d2d57600080fd5b505af1158015612d41573d6000803e3d6000fd5b505050506040513d6020811015612d5757600080fd5b5051612daa576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8215612e9157806001600160a01b031663a9059cbb8560c00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612e1457600080fd5b505af1158015612e28573d6000803e3d6000fd5b505050506040513d6020811015612e3e57600080fd5b5051612e91576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b8360a001516001600160a01b03168460c001516001600160a01b0316867fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98686604051808381526020018281526020019250505060405180910390a45050505050565b612efc6141fd565b50600081815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff161515610100820152612f92614266565b6000612fa2848460c001516108a1565b90506000612fb4858560a001516108a1565b90506000806000612fc588856116ce565b925092509250612fd58584613d84565b6020880181905287826003811115612fe957fe5b6003811115612ff457fe5b905250600090508651600381111561300857fe5b146130445760405162461bcd60e51b81526004018080602001828103825260248152602001806147406024913960400191505060405180910390fd5b61304e8484612b4a565b604088018190528782600381111561306257fe5b600381111561306d57fe5b905250600090508651600381111561308157fe5b146130bd5760405162461bcd60e51b815260040180806020018281038252603b8152602001806146b0603b913960400191505060405180910390fd5b6130cb866040015182612b4a565b60608801819052878260038111156130df57fe5b60038111156130ea57fe5b90525060009050865160038111156130fe57fe5b1461313a5760405162461bcd60e51b81526004018080602001828103825260278152602001806146eb6027913960400191505060405180910390fd5b60e08701516001600160a01b0316600090815260cf60205260409020546131619082613d84565b60e08901516001600160a01b0316600090815260cf602052604090208190558782600381111561318d57fe5b600381111561319857fe5b90525060009050865160038111156131ac57fe5b146131e85760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b600088815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd855292852085815590810185905591820193909355909101805460ff1916905560e0880151908701511561336357806001600160a01b031663a9059cbb8960c0015189602001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156132e657600080fd5b505af11580156132fa573d6000803e3d6000fd5b505050506040513d602081101561331057600080fd5b5051613363576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b60608701511561345257806001600160a01b031663a9059cbb8960a0015189606001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156133d557600080fd5b505af11580156133e9573d6000803e3d6000fd5b505050506040513d60208110156133ff57600080fd5b5051613452576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8760a001516001600160a01b03168860c001516001600160a01b03168a7fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98a602001518b60600151604051808381526020018281526020019250505060405180910390a4604080518581526020810185905280820184905290518a917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a2505050505050505050565b61350c6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526135a26143ac565b6135b0826040015184612b4a565b600086815260d260205260409020600201819055828260038111156135d157fe5b60038111156135dc57fe5b90525060009050815160038111156135f057fe5b146135f757fe5b600084815260d2602052604090206002015461366d57600084815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b03191690555b8160e001516001600160a01b031663a9059cbb8360a00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156136d557600080fd5b505af11580156136e9573d6000803e3d6000fd5b505050506040513d60208110156136ff57600080fd5b505161374b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b8160a001516001600160a01b0316847f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c856040518082815260200191505060405180910390a350505050565b61379f6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526138356143bf565b600080600061384487876116ce565b9250925092506138548684612b4a565b602086018190528582600381111561386857fe5b600381111561387357fe5b905250600090508451600381111561388757fe5b146138c35760405162461bcd60e51b815260040180806020018281038252603081526020018061465d6030913960400191505060405180910390fd5b6138d1846020015182612b4a565b60408601819052858260038111156138e557fe5b60038111156138f057fe5b905250600090508451600381111561390457fe5b146139405760405162461bcd60e51b81526004018080602001828103825260278152602001806145476027913960400191505060405180910390fd5b61394e856040015187612b4a565b600089815260d2602052604090206002018190558582600381111561396f57fe5b600381111561397a57fe5b905250600090508451600381111561398e57fe5b146139ca5760405162461bcd60e51b81526004018080602001828103825260258152602001806145b26025913960400191505060405180910390fd5b600087815260d26020526040902060020154613a6857600087815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd9094529184208481559182018490559181019290925501805460ff191690555b60e08501516001600160a01b0316600090815260cf6020526040902054613a8f9082613d84565b60e08701516001600160a01b0316600090815260cf6020526040902081905585826003811115613abb57fe5b6003811115613ac657fe5b9052506000905084516003811115613ada57fe5b14613b165760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b60e08501518315613c0257806001600160a01b031663a9059cbb8760c00151866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613b8557600080fd5b505af1158015613b99573d6000803e3d6000fd5b505050506040513d6020811015613baf57600080fd5b5051613c02576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b806001600160a01b031663a9059cbb8760a0015187604001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613c6a57600080fd5b505af1158015613c7e573d6000803e3d6000fd5b505050506040513d6020811015613c9457600080fd5b5051613ce7576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8560a001516001600160a01b0316887f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c87604001516040518082815260200191505060405180910390a36040805185815260208101859052808201849052905189917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a25050505050505050565b303b1590565b600080838301848110613d9c57600092509050612b43565b506002915060009050612b43565b613dbb60668263ffffffff61410116565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6000613dfc614382565b600080613e1186600001518660000151612b4a565b60408051602081019091529081529097909650945050505050565b6000613e36614382565b600080613e47866000015186612b08565b90925090506000826003811115613e5a57fe5b14613e7957506040805160208101909152600081529092509050612b43565b60408051602081019091529081526000969095509350505050565b6000613e9e614382565b83518351613eac919061414d565b915091509250929050565b51670de0b6b3a7640000900490565b6000613ed0614382565b600080613ee586600001518660000151612b08565b90925090506000826003811115613ef857fe5b14613f1757506040805160208101909152600081529092509050612b43565b600080613f2c6706f05b59d3b2000084613d84565b90925090506000826003811115613f3f57fe5b14613f6157506040805160208101909152600081529094509250612b43915050565b600080613f7683670de0b6b3a7640000614067565b90925090506000826003811115613f8957fe5b14613f9057fe5b604080516020810190915290815260009a909950975050505050505050565b600054610100900460ff1680613fc85750613fc8613d7e565b80613fd6575060005460ff16155b6140115760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561403c576000805460ff1961ff0019909116610100171660011790555b61404582610c67565b6140525761405282613daa565b8015612451576000805461ff00191690555050565b6000808261407b5750600190506000612b43565b600083858161408657fe5b04915091509250929050565b6001600160a01b0381166140a557600080fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811661411457600080fd5b61411e8282612b71565b1561412857600080fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6000614157614382565b60008061416c86670de0b6b3a7640000612b08565b9092509050600082600381111561417f57fe5b1461419e57506040805160208101909152600081529092509050612b43565b6000806141ab8388614067565b909250905060008260038111156141be57fe5b146141e057506040805160208101909152600081529094509250612b43915050565b604080516020810190915290815260009890975095505050505050565b604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000151581525090565b604080516080810190915280600081526020016000815260200160008152602001600081525090565b6040805160a081019091528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806142d2614382565b81526020016142df614382565b81526020016142ec614382565b8152600060209091015290565b6040805161014081019091528060008152602001614315614382565b8152602001614322614382565b815260200161432f614382565b815260200161433c614382565b8152602001614349614382565b8152602001614356614382565b8152602001614363614382565b8152602001614370614382565b815260200161437d614382565b905290565b6040518060200160405280600081525090565b604080518082019091526000808252602082015290565b604080516020810190915280600061437d565b6040805160608101909152806000815260200160008152602001600081525090565b600054610100900460ff16806143fa57506143fa613d7e565b80614408575060005460ff16155b6144435760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561446e576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015612451576000805461ff0019169055505056fe636f6d706f756e64696e672073747265616d20646f6573206e6f742065786973746561726e696e6773206164646974696f6e2063616c63756c6174696f6e206572726f72506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c656e6574207769746864726177616c20616d6f756e742063616c63756c6174696f6e206572726f7273747265616d20646f6573206e6f742065786973740000000000000000000000616d6f756e7420657863656564732074686520617661696c61626c652062616c616e636562616c616e6365207375627472616374696f6e2063616c63756c6174696f6e206572726f7273656e64657220696e7465726573742063616c63756c6174696f6e206572726f7273746172742074696d65206265666f726520626c6f636b2e74696d657374616d707361626c69657220696e7465726573742063616c63756c6174696f6e206572726f726465706f736974206e6f74206d756c7469706c65206f662074696d652064656c7461616d6f756e7420776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f72726563697069656e7420696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e636520776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f726e657420726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f72436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65646e65742073656e6465722062616c616e63652063616c63756c6174696f6e206572726f727361626c69657220696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f7263616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616da265627a7a72315820d5ad0c39f51a54f8b3b77f6b8f02e3d034b5fabbacccfa1751ca957d1cd14a2d64736f6c634300050b0032436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a656463546f6b656e4d616e6167657220636f6e747261637420697320746865207a65726f2061646472657373000000000000000000000000342a6596f50b4db7c3246c0f4efb1f06843d7405

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061018e5760003560e01c8063894e9a0d116100de578063a82ccd4d11610097578063cc1b4bf611610071578063cc1b4bf614610518578063d2cba55c14610558578063ddca3f4314610560578063f2fde38b146105685761018e565b8063a82ccd4d146104a9578063c1eb9ee0146104c6578063c4d66de8146104f25761018e565b8063894e9a0d146103925780638c9a3252146104025780638da5cb5b146104435780638f32d59b146104675780639012c4a81461046f578063a734d51b1461048c5761018e565b80635c975abb1161014b5780638129fc1c116101255780638129fc1c146103105780638195aeaa1461031857806382dc1ec4146103645780638456cb591461038a5761018e565b80635c975abb146102c85780636db9241b146102d05780637a9b2c6c146102ed5761018e565b8063131b9c04146101935780631e99d569146101cb5780632b8a119d146101d35780633656eec2146102585780633f4ba83a1461028457806346fbf68e1461028e575b600080fd5b6101b9600480360360208110156101a957600080fd5b50356001600160a01b031661058e565b60408051918252519081900360200190f35b6101b961066e565b6101f0600480360360208110156101e957600080fd5b5035610674565b604080516001600160a01b039c8d1681529a8c1660208c01528a810199909952969099166060890152608088019490945260a087019290925260c086015260e08501526101008401526101208301939093526101408201929092529051908190036101600190f35b6101b96004803603604081101561026e57600080fd5b50803590602001356001600160a01b03166108a1565b61028c610b7e565b005b6102b4600480360360208110156102a457600080fd5b50356001600160a01b0316610c67565b604080519115158252519081900360200190f35b6102b4610c80565b6102b4600480360360208110156102e657600080fd5b5035610c89565b6102b46004803603604081101561030357600080fd5b5080359060200135610dbc565b61028c611063565b6101b9600480360360e081101561032e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060808101359060a08101359060c0013561110a565b61028c6004803603602081101561037a57600080fd5b50356001600160a01b03166114ec565b61028c61153b565b6103af600480360360208110156103a857600080fd5b5035611602565b604080516001600160a01b03998a168152978916602089015287810196909652939096166060860152608085019190915260a084015260c083019390935260e08201929092529051908190036101000190f35b6104256004803603604081101561041857600080fd5b50803590602001356116ce565b60408051938452602084019290925282820152519081900360600190f35b61044b611e1d565b604080516001600160a01b039092168252519081900360200190f35b6102b4611e2c565b61028c6004803603602081101561048557600080fd5b5035611e52565b6102b4600480360360208110156104a257600080fd5b5035611f4e565b6101b9600480360360208110156104bf57600080fd5b5035611f66565b61028c600480360360408110156104dc57600080fd5b506001600160a01b038135169060200135612098565b61028c6004803603602081101561050857600080fd5b50356001600160a01b031661239f565b6101b9600480360360a081101561052e57600080fd5b506001600160a01b0381358116916020810135916040820135169060608101359060800135612455565b61044b612ad9565b6101b9612ae8565b61028c6004803603602081101561057e57600080fd5b50356001600160a01b0316612aee565b60ce5460408051632f52e59560e01b81526001600160a01b03848116600483015291516000939290921691632f52e59591602480820192602092909190829003018186803b1580156105df57600080fd5b505afa1580156105f3573d6000803e3d6000fd5b505050506040513d602081101561060957600080fd5b5051610652576040805162461bcd60e51b81526020600482015260136024820152723a37b5b2b71034b9903737ba1031aa37b5b2b760691b604482015290519081900360640190fd5b506001600160a01b0316600090815260cf602052604090205490565b60d15481565b60008060008060008060008060008060008b60d2600082815260200190815260200160002060070160149054906101000a900460ff166106e9576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b60008d815260cd60205260409020600301548d9060ff1661073b5760405162461bcd60e51b81526004018080602001828103825260218152602001806144d36021913960400191505060405180910390fd5b60d260008f815260200190815260200160002060060160009054906101000a90046001600160a01b03169c5060d260008f815260200190815260200160002060050160009054906101000a90046001600160a01b03169b5060d260008f8152602001908152602001600020600001549a5060d260008f815260200190815260200160002060070160009054906101000a90046001600160a01b0316995060d260008f815260200190815260200160002060030154985060d260008f815260200190815260200160002060040154975060d260008f815260200190815260200160002060020154965060d260008f815260200190815260200160002060010154955060cd60008f815260200190815260200160002060000160000154945060cd60008f815260200190815260200160002060010160000154935060cd60008f8152602001908152602001600020600201600001549250505091939597999b90929496989a50565b600082815260d260205260408120600701548390600160a01b900460ff166108fe576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b6109066141fd565b50600084815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff16151561010082015261099c614266565b60006109a787611f66565b90506109b7818460200151612b08565b60208401819052838260038111156109cb57fe5b60038111156109d657fe5b90525060009050825160038111156109ea57fe5b14610a265760405162461bcd60e51b81526004018080602001828103825260238152602001806147856023913960400191505060405180910390fd5b604083015183511115610acb57610a4583600001518460400151612b4a565b6040840181905283826003811115610a5957fe5b6003811115610a6457fe5b9052506000905082516003811115610a7857fe5b14610a7f57fe5b610a9182602001518360400151612b4a565b6020840181905283826003811115610aa557fe5b6003811115610ab057fe5b9052506000905082516003811115610ac457fe5b14610acb57fe5b8260a001516001600160a01b0316866001600160a01b03161415610af75750602001519250610b779050565b8260c001516001600160a01b0316866001600160a01b03161415610b6f57610b2783604001518360200151612b4a565b6060840181905283826003811115610b3b57fe5b6003811115610b4657fe5b9052506000905082516003811115610b5a57fe5b14610b6157fe5b50606001519250610b779050565b600094505050505b5092915050565b610b8e610b89612b6d565b610c67565b610bc95760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16610c17576040805162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015290519081900360640190fd5b6099805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa610c4a612b6d565b604080516001600160a01b039092168252519081900360200190a1565b6000610c7a60668363ffffffff612b7116565b92915050565b60995460ff1690565b609a805460010190819055600082815260d260205260408120600701549091908390600160a01b900460ff16610cf4576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600084815260d2602052604090206006015484906001600160a01b0316331480610d375750600081815260d260205260409020600501546001600160a01b031633145b610d725760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b600085815260cd602052604090206003015460ff16610d9957610d9485612ba6565b610da2565b610da285612ef4565b600193505050609a548114610db657600080fd5b50919050565b60995460009060ff1615610e0a576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b609a805460010190819055600084815260d260205260409020600701548490600160a01b900460ff16610e72576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600085815260d2602052604090206006015485906001600160a01b0316331480610eb55750600081815260d260205260409020600501546001600160a01b031633145b610ef05760405162461bcd60e51b81526004018080602001828103825260378152602001806147a86037913960400191505060405180910390fd5b60008511610f36576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b610f3e6141fd565b50600086815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a084018190526006830154821660c085015260079092015490811660e0840152600160a01b900460ff161515610100830152909190610fda9089906108a1565b90508681101561101b5760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b600088815260cd602052604090206003015460ff166110435761103e8888613504565b61104d565b61104d8888613797565b6001955050505050609a548114610b7757600080fd5b600054610100900460ff168061107c575061107c613d7e565b8061108a575060005460ff16155b6110c55760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff161580156110f0576000805460ff1961ff0019909116610100171660011790555b6001609a558015611107576000805461ff00191690555b50565b60995460009060ff1615611158576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b60ce5460408051632f52e59560e01b81526001600160a01b03898116600483015291519190921691632f52e595916024808301926020929190829003018186803b1580156111a557600080fd5b505afa1580156111b9573d6000803e3d6000fd5b505050506040513d60208110156111cf57600080fd5b505161121e576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b61122661428f565b6112308484613d84565b602083018190528282600381111561124457fe5b600381111561124f57fe5b905250600090508151600381111561126357fe5b146112b5576040805162461bcd60e51b815260206004820152601b60248201527f73686172652073756d2063616c63756c6174696f6e206572726f720000000000604482015290519081900360640190fd5b806020015160641461130e576040805162461bcd60e51b815260206004820152601b60248201527f73686172657320646f206e6f742073756d20757020746f203130300000000000604482015290519081900360640190fd5b600061131d8a8a8a8a8a612455565b905061133085662386f26fc10000612b08565b606084018190528382600381111561134457fe5b600381111561134f57fe5b905250600090508251600381111561136357fe5b1461136a57fe5b61137b84662386f26fc10000612b08565b608084018190528382600381111561138f57fe5b600381111561139a57fe5b90525060009050825160038111156113ae57fe5b146113b557fe5b6000886001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156113f257600080fd5b505af1158015611406573d6000803e3d6000fd5b505050506040513d602081101561141c57600080fd5b50516040805160a08101825260808082018481528252825160208082018552606089810151835281850192835285518083018752938a01518452848601938452600181860181815260008b815260cd8552889020965151875593515190860155925151600285015590516003909301805460ff19169315159390931790925582518481529182018a9052818301899052915192935084927fa9bbfc8562a8e1e6b889a428f128c90ed60c6204c37e4fb4354a202b4db59204929181900390910190a2509998505050505050505050565b6114f7610b89612b6d565b6115325760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b61110781613daa565b611546610b89612b6d565b6115815760405162461bcd60e51b81526004018080602001828103825260308152602001806145176030913960400191505060405180910390fd5b60995460ff16156115cc576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6099805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610c4a612b6d565b6000806000806000806000808860d2600082815260200190815260200160002060070160149054906101000a900460ff16611672576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b5050506000968752505060d26020525050604090922060068101546005820154825460078401546003850154600486015460028701546001909701546001600160a01b039687169a958716995093975091909416949092909190565b600082815260d26020526040812060070154819081908590600160a01b900460ff1661172f576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b600086815260cd602052604090206003015460ff166117575760009350839250829150611e15565b61175f6141fd565b50600086815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526117f56142bf565b50600087815260cd6020908152604091829020825160a08101845281546080820190815281528351808401855260018301548152818401528351928301845260028201548352928301919091526003015460ff16151560608201526118586142f9565b611860614382565b60405180602001604052808560e001516001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156118aa57600080fd5b505af11580156118be573d6000803e3d6000fd5b505050506040513d60208110156118d457600080fd5b505190528351518151919250106118f9575060009650869550859450611e1592505050565b611907818460000151613df2565b602084018190528382600381111561191b57fe5b600381111561192657fe5b905250600090508251600381111561193a57fe5b1461194157fe5b61194f82602001518a613e2c565b604084018190528382600381111561196357fe5b600381111561196e57fe5b905250600090508251600381111561198257fe5b146119d4576040805162461bcd60e51b815260206004820152601a60248201527f696e7465726573742063616c63756c6174696f6e206572726f72000000000000604482015290519081900360640190fd5b60d054670de0b6b3a76400001415611a86576119f4826040015182613e94565b610120840181905283826003811115611a0957fe5b6003811115611a1457fe5b9052506000905082516003811115611a2857fe5b14611a645760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b600080611a75846101200151613eb7565b91995097509550611e159350505050565b60d054611aad57604080516020810182526000815260c08401528201516060830152611b85565b60408083015181516020810190925260d0548252611aca91613ec6565b60c0840181905283826003811115611ade57fe5b6003811115611ae957fe5b9052506000905082516003811115611afd57fe5b14611b395760405162461bcd60e51b81526004018080602001828103825260228152602001806146196022913960400191505060405180910390fd5b611b4b82604001518360c00151613df2565b6060840181905283826003811115611b5f57fe5b6003811115611b6a57fe5b9052506000905082516003811115611b7e57fe5b14611b8557fe5b611b9782606001518460200151613ec6565b6080840181905283826003811115611bab57fe5b6003811115611bb657fe5b9052506000905082516003811115611bca57fe5b14611c065760405162461bcd60e51b81526004018080602001828103825260218152602001806145d76021913960400191505060405180910390fd5b611c1882606001518360800151613df2565b60a0840181905283826003811115611c2c57fe5b6003811115611c3757fe5b9052506000905082516003811115611c4b57fe5b14611c5257fe5b611c60826080015182613e94565b60e0840181905283826003811115611c7457fe5b6003811115611c7f57fe5b9052506000905082516003811115611c9357fe5b14611ce5576040805162461bcd60e51b815260206004820181905260248201527f73656e64657220696e74657265737420636f6e76657273696f6e206572726f72604482015290519081900360640190fd5b611cf38260a0015182613e94565b610100840181905283826003811115611d0857fe5b6003811115611d1357fe5b9052506000905082516003811115611d2757fe5b14611d635760405162461bcd60e51b815260040180806020018281038252602381526020018061468d6023913960400191505060405180910390fd5b611d718260c0015182613e94565b610120840181905283826003811115611d8657fe5b6003811115611d9157fe5b9052506000905082516003811115611da557fe5b14611de15760405162461bcd60e51b81526004018080602001828103825260218152602001806147646021913960400191505060405180910390fd5b611dee8260e00151613eb7565b611dfc836101000151613eb7565b611e0a846101200151613eb7565b975097509750505050505b509250925092565b6033546001600160a01b031690565b6033546000906001600160a01b0316611e43612b6d565b6001600160a01b031614905090565b611e5a611e2c565b611e6357600080fd5b6064811115611eb9576040805162461bcd60e51b815260206004820152601f60248201527f6665652070657263656e7461676520686967686572207468616e203130302500604482015290519081900360640190fd5b611ec1614395565b611ed282662386f26fc10000612b08565b6020830181905282826003811115611ee657fe5b6003811115611ef157fe5b9052506000905081516003811115611f0557fe5b14611f0c57fe5b60408051602080820183528301519081905260d0555182907f38e229a7f3f9c329892d08eb37c4e91ccac6d12c798d394990ca4f56028ec26690600090a25050565b600090815260cd602052604090206003015460ff1690565b600081815260d260205260408120600701548290600160a01b900460ff16611fc3576040805162461bcd60e51b8152602060048201526015602482015260008051602061456e833981519152604482015290519081900360640190fd5b611fcb6141fd565b50600083815260d26020908152604091829020825161012081018452815481526001820154928101929092526002810154928201929092526003820154606082018190526004830154608083015260058301546001600160a01b0390811660a08401526006840154811660c084015260079093015492831660e0830152600160a01b90920460ff16151561010082015290421161206c576000925050610db6565b8060800151421015612085576060015142039150610db6565b6060810151608090910151039392505050565b6120a0611e2c565b6120a957600080fd5b609a80546001019081905560ce5460408051632f52e59560e01b81526001600160a01b03868116600483015291519190921691632f52e595916024808301926020929190829003018186803b15801561210157600080fd5b505afa158015612115573d6000803e3d6000fd5b505050506040513d602081101561212b57600080fd5b505161217a576040805162461bcd60e51b815260206004820152601960248201527818d51bdad95b881a5cc81b9bdd081dda1a5d195b1a5cdd1959603a1b604482015290519081900360640190fd5b600082116121c0576040805162461bcd60e51b815260206004820152600e60248201526d616d6f756e74206973207a65726f60901b604482015290519081900360640190fd5b6001600160a01b038316600090815260cf60205260409020548211156122175760405162461bcd60e51b815260040180806020018281038252602481526020018061458e6024913960400191505060405180910390fd5b61221f6143ac565b6001600160a01b038416600090815260cf60205260409020546122429084612b4a565b6001600160a01b038616600090815260cf602052604090208190558282600381111561226a57fe5b600381111561227557fe5b905250600090508151600381111561228957fe5b1461229057fe5b60405183906001600160a01b038616907f13e8af02ad3e36f8d82fc8b86dcd67b7ed11f718f0e52fb245d2038eb71856ba90600090a36040805163a9059cbb60e01b81523360048201526024810185905290516001600160a01b0386169163a9059cbb9160448083019260209291908290030181600087803b15801561231557600080fd5b505af1158015612329573d6000803e3d6000fd5b505050506040513d602081101561233f57600080fd5b505161238b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b50609a54811461239a57600080fd5b505050565b600054610100900460ff16806123b857506123b8613d7e565b806123c6575060005460ff16155b6124015760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561242c576000805460ff1961ff0019909116610100171660011790555b61243582613faf565b6099805460ff191690558015612451576000805461ff00191690555b5050565b60995460009060ff16156124a3576040805162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015290519081900360640190fd5b6001600160a01b0386166124fe576040805162461bcd60e51b815260206004820152601a60248201527f73747265616d20746f20746865207a65726f2061646472657373000000000000604482015290519081900360640190fd5b6001600160a01b03861630141561255c576040805162461bcd60e51b815260206004820152601d60248201527f73747265616d20746f2074686520636f6e747261637420697473656c66000000604482015290519081900360640190fd5b6001600160a01b0386163314156125b1576040805162461bcd60e51b815260206004820152601460248201527339ba3932b0b6903a37903a34329031b0b63632b960611b604482015290519081900360640190fd5b600085116125f8576040805162461bcd60e51b815260206004820152600f60248201526e6465706f736974206973207a65726f60881b604482015290519081900360640190fd5b428310156126375760405162461bcd60e51b81526004018080602001828103825260218152602001806145f86021913960400191505060405180910390fd5b82821161268b576040805162461bcd60e51b815260206004820152601f60248201527f73746f702074696d65206265666f7265207468652073746172742074696d6500604482015290519081900360640190fd5b6126936143bf565b61269d8385612b4a565b60208301819052828260038111156126b157fe5b60038111156126bc57fe5b90525060009050815160038111156126d057fe5b146126d757fe5b8060200151861015612730576040805162461bcd60e51b815260206004820152601f60248201527f6465706f73697420736d616c6c6572207468616e2074696d652064656c746100604482015290519081900360640190fd5b8060200151868161273d57fe5b061561277a5760405162461bcd60e51b815260040180806020018281038252602281526020018061463b6022913960400191505060405180910390fd5b612788868260200151614067565b604083018190528282600381111561279c57fe5b60038111156127a757fe5b90525060009050815160038111156127bb57fe5b146127c257fe5b600060d154905060405180610120016040528088815260200183604001518152602001888152602001868152602001858152602001896001600160a01b03168152602001336001600160a01b03168152602001876001600160a01b031681526020016001151581525060d26000838152602001908152602001600020600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a08201518160050160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060c08201518160060160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060e08201518160070160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506101008201518160070160146101000a81548160ff02191690831515021790555090505061292860d1546001613d84565b60d18190558382600381111561293a57fe5b600381111561294557fe5b905250600090508251600381111561295957fe5b146129ab576040805162461bcd60e51b815260206004820181905260248201527f6e6578742073747265616d2069642063616c63756c6174696f6e206572726f72604482015290519081900360640190fd5b604080516323b872dd60e01b81523360048201523060248201526044810189905290516001600160a01b038816916323b872dd9160648083019260209291908290030181600087803b158015612a0057600080fd5b505af1158015612a14573d6000803e3d6000fd5b505050506040513d6020811015612a2a57600080fd5b5051612a76576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b604080518881526001600160a01b038881166020830152818301889052606082018790529151918a1691339184917f7b01d409597969366dc268d7f957a990d1ca3d3449baf8fb45db67351aecfe789181900360800190a4979650505050505050565b60ce546001600160a01b031681565b60d05481565b612af6611e2c565b612aff57600080fd5b61110781614092565b60008083612b1b57506000905080612b43565b83830283858281612b2857fe5b0414612b3c57506002915060009050612b43565b6000925090505b9250929050565b600080838311612b61575060009050818303612b43565b50600390506000612b43565b3390565b60006001600160a01b038216612b8657600080fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b612bae6141fd565b50600081815260d26020908152604080832081516101208101835281548152600182015493810193909352600281015491830191909152600381015460608301526004810154608083015260058101546001600160a01b0390811660a08401526006820154811660c0840181905260079092015490811660e0840152600160a01b900460ff161515610100830152909190612c4a9084906108a1565b90506000612c5c848460a001516108a1565b600085815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b031916905560e08401519091508115612daa57806001600160a01b031663a9059cbb8560a00151846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612d2d57600080fd5b505af1158015612d41573d6000803e3d6000fd5b505050506040513d6020811015612d5757600080fd5b5051612daa576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8215612e9157806001600160a01b031663a9059cbb8560c00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015612e1457600080fd5b505af1158015612e28573d6000803e3d6000fd5b505050506040513d6020811015612e3e57600080fd5b5051612e91576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b8360a001516001600160a01b03168460c001516001600160a01b0316867fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98686604051808381526020018281526020019250505060405180910390a45050505050565b612efc6141fd565b50600081815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff161515610100820152612f92614266565b6000612fa2848460c001516108a1565b90506000612fb4858560a001516108a1565b90506000806000612fc588856116ce565b925092509250612fd58584613d84565b6020880181905287826003811115612fe957fe5b6003811115612ff457fe5b905250600090508651600381111561300857fe5b146130445760405162461bcd60e51b81526004018080602001828103825260248152602001806147406024913960400191505060405180910390fd5b61304e8484612b4a565b604088018190528782600381111561306257fe5b600381111561306d57fe5b905250600090508651600381111561308157fe5b146130bd5760405162461bcd60e51b815260040180806020018281038252603b8152602001806146b0603b913960400191505060405180910390fd5b6130cb866040015182612b4a565b60608801819052878260038111156130df57fe5b60038111156130ea57fe5b90525060009050865160038111156130fe57fe5b1461313a5760405162461bcd60e51b81526004018080602001828103825260278152602001806146eb6027913960400191505060405180910390fd5b60e08701516001600160a01b0316600090815260cf60205260409020546131619082613d84565b60e08901516001600160a01b0316600090815260cf602052604090208190558782600381111561318d57fe5b600381111561319857fe5b90525060009050865160038111156131ac57fe5b146131e85760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b600088815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd855292852085815590810185905591820193909355909101805460ff1916905560e0880151908701511561336357806001600160a01b031663a9059cbb8960c0015189602001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156132e657600080fd5b505af11580156132fa573d6000803e3d6000fd5b505050506040513d602081101561331057600080fd5b5051613363576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b60608701511561345257806001600160a01b031663a9059cbb8960a0015189606001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156133d557600080fd5b505af11580156133e9573d6000803e3d6000fd5b505050506040513d60208110156133ff57600080fd5b5051613452576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8760a001516001600160a01b03168860c001516001600160a01b03168a7fca3e6079b726e7728802a0537949e2d1c7762304fa641fb06eb56daf2ba8c6b98a602001518b60600151604051808381526020018281526020019250505060405180910390a4604080518581526020810185905280820184905290518a917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a2505050505050505050565b61350c6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526135a26143ac565b6135b0826040015184612b4a565b600086815260d260205260409020600201819055828260038111156135d157fe5b60038111156135dc57fe5b90525060009050815160038111156135f057fe5b146135f757fe5b600084815260d2602052604090206002015461366d57600084815260d26020526040812081815560018101829055600281018290556003810182905560048101919091556005810180546001600160a01b0319908116909155600682018054909116905560070180546001600160a81b03191690555b8160e001516001600160a01b031663a9059cbb8360a00151856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156136d557600080fd5b505af11580156136e9573d6000803e3d6000fd5b505050506040513d60208110156136ff57600080fd5b505161374b576040805162461bcd60e51b8152602060048201526016602482015275746f6b656e207472616e73666572206661696c75726560501b604482015290519081900360640190fd5b8160a001516001600160a01b0316847f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c856040518082815260200191505060405180910390a350505050565b61379f6141fd565b50600082815260d2602090815260409182902082516101208101845281548152600182015492810192909252600281015492820192909252600382015460608201526004820154608082015260058201546001600160a01b0390811660a08301526006830154811660c083015260079092015491821660e0820152600160a01b90910460ff1615156101008201526138356143bf565b600080600061384487876116ce565b9250925092506138548684612b4a565b602086018190528582600381111561386857fe5b600381111561387357fe5b905250600090508451600381111561388757fe5b146138c35760405162461bcd60e51b815260040180806020018281038252603081526020018061465d6030913960400191505060405180910390fd5b6138d1846020015182612b4a565b60408601819052858260038111156138e557fe5b60038111156138f057fe5b905250600090508451600381111561390457fe5b146139405760405162461bcd60e51b81526004018080602001828103825260278152602001806145476027913960400191505060405180910390fd5b61394e856040015187612b4a565b600089815260d2602052604090206002018190558582600381111561396f57fe5b600381111561397a57fe5b905250600090508451600381111561398e57fe5b146139ca5760405162461bcd60e51b81526004018080602001828103825260258152602001806145b26025913960400191505060405180910390fd5b600087815260d26020526040902060020154613a6857600087815260d260209081526040808320838155600180820185905560028083018690556003808401879055600484018790556005840180546001600160a01b03199081169091556006850180549091169055600790930180546001600160a81b031916905560cd9094529184208481559182018490559181019290925501805460ff191690555b60e08501516001600160a01b0316600090815260cf6020526040902054613a8f9082613d84565b60e08701516001600160a01b0316600090815260cf6020526040902081905585826003811115613abb57fe5b6003811115613ac657fe5b9052506000905084516003811115613ada57fe5b14613b165760405162461bcd60e51b81526004018080602001828103825260238152602001806144f46023913960400191505060405180910390fd5b60e08501518315613c0257806001600160a01b031663a9059cbb8760c00151866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613b8557600080fd5b505af1158015613b99573d6000803e3d6000fd5b505050506040513d6020811015613baf57600080fd5b5051613c02576040805162461bcd60e51b815260206004820152601d60248201527f73656e64657220746f6b656e207472616e73666572206661696c757265000000604482015290519081900360640190fd5b806001600160a01b031663a9059cbb8760a0015187604001516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015613c6a57600080fd5b505af1158015613c7e573d6000803e3d6000fd5b505050506040513d6020811015613c9457600080fd5b5051613ce7576040805162461bcd60e51b815260206004820181905260248201527f726563697069656e7420746f6b656e207472616e73666572206661696c757265604482015290519081900360640190fd5b8560a001516001600160a01b0316887f36c3ab437e6a424ed25dc4bfdeb62706aa06558660fab2dab229d2555adaf89c87604001516040518082815260200191505060405180910390a36040805185815260208101859052808201849052905189917f5a8a03e48302e0bd2e011a3a2b54d1f849c55497f462f404bf52dce4290456b5919081900360600190a25050505050505050565b303b1590565b600080838301848110613d9c57600092509050612b43565b506002915060009050612b43565b613dbb60668263ffffffff61410116565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6000613dfc614382565b600080613e1186600001518660000151612b4a565b60408051602081019091529081529097909650945050505050565b6000613e36614382565b600080613e47866000015186612b08565b90925090506000826003811115613e5a57fe5b14613e7957506040805160208101909152600081529092509050612b43565b60408051602081019091529081526000969095509350505050565b6000613e9e614382565b83518351613eac919061414d565b915091509250929050565b51670de0b6b3a7640000900490565b6000613ed0614382565b600080613ee586600001518660000151612b08565b90925090506000826003811115613ef857fe5b14613f1757506040805160208101909152600081529092509050612b43565b600080613f2c6706f05b59d3b2000084613d84565b90925090506000826003811115613f3f57fe5b14613f6157506040805160208101909152600081529094509250612b43915050565b600080613f7683670de0b6b3a7640000614067565b90925090506000826003811115613f8957fe5b14613f9057fe5b604080516020810190915290815260009a909950975050505050505050565b600054610100900460ff1680613fc85750613fc8613d7e565b80613fd6575060005460ff16155b6140115760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561403c576000805460ff1961ff0019909116610100171660011790555b61404582610c67565b6140525761405282613daa565b8015612451576000805461ff00191690555050565b6000808261407b5750600190506000612b43565b600083858161408657fe5b04915091509250929050565b6001600160a01b0381166140a557600080fd5b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160a01b03811661411457600080fd5b61411e8282612b71565b1561412857600080fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6000614157614382565b60008061416c86670de0b6b3a7640000612b08565b9092509050600082600381111561417f57fe5b1461419e57506040805160208101909152600081529092509050612b43565b6000806141ab8388614067565b909250905060008260038111156141be57fe5b146141e057506040805160208101909152600081529094509250612b43915050565b604080516020810190915290815260009890975095505050505050565b604051806101200160405280600081526020016000815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000151581525090565b604080516080810190915280600081526020016000815260200160008152602001600081525090565b6040805160a081019091528060008152602001600081526020016000815260200160008152602001600081525090565b60405180608001604052806142d2614382565b81526020016142df614382565b81526020016142ec614382565b8152600060209091015290565b6040805161014081019091528060008152602001614315614382565b8152602001614322614382565b815260200161432f614382565b815260200161433c614382565b8152602001614349614382565b8152602001614356614382565b8152602001614363614382565b8152602001614370614382565b815260200161437d614382565b905290565b6040518060200160405280600081525090565b604080518082019091526000808252602082015290565b604080516020810190915280600061437d565b6040805160608101909152806000815260200160008152602001600081525090565b600054610100900460ff16806143fa57506143fa613d7e565b80614408575060005460ff16155b6144435760405162461bcd60e51b815260040180806020018281038252602e815260200180614712602e913960400191505060405180910390fd5b600054610100900460ff1615801561446e576000805460ff1961ff0019909116610100171660011790555b603380546001600160a01b0319166001600160a01b0384811691909117918290556040519116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a38015612451576000805461ff0019169055505056fe636f6d706f756e64696e672073747265616d20646f6573206e6f742065786973746561726e696e6773206164646974696f6e2063616c63756c6174696f6e206572726f72506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c656e6574207769746864726177616c20616d6f756e742063616c63756c6174696f6e206572726f7273747265616d20646f6573206e6f742065786973740000000000000000000000616d6f756e7420657863656564732074686520617661696c61626c652062616c616e636562616c616e6365207375627472616374696f6e2063616c63756c6174696f6e206572726f7273656e64657220696e7465726573742063616c63756c6174696f6e206572726f7273746172742074696d65206265666f726520626c6f636b2e74696d657374616d707361626c69657220696e7465726573742063616c63756c6174696f6e206572726f726465706f736974206e6f74206d756c7469706c65206f662074696d652064656c7461616d6f756e7420776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f72726563697069656e7420696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e636520776974686f75742073656e64657220696e7465726573742063616c63756c6174696f6e206572726f726e657420726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f72436f6e747261637420696e7374616e63652068617320616c7265616479206265656e20696e697469616c697a65646e65742073656e6465722062616c616e63652063616c63756c6174696f6e206572726f727361626c69657220696e74657265737420636f6e76657273696f6e206572726f72726563697069656e742062616c616e63652063616c63756c6174696f6e206572726f7263616c6c6572206973206e6f74207468652073656e646572206f722074686520726563697069656e74206f66207468652073747265616da265627a7a72315820d5ad0c39f51a54f8b3b77f6b8f02e3d034b5fabbacccfa1751ca957d1cd14a2d64736f6c634300050b0032

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000342a6596f50b4db7c3246c0f4efb1f06843d7405

-----Decoded View---------------
Arg [0] : cTokenManagerAddress (address): 0x342A6596F50b4Db7c3246C0F4eFb1f06843d7405

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000342a6596f50b4db7c3246c0f4efb1f06843d7405


Deployed Bytecode Sourcemap

28122:36493:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28122:36493:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45476:202;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45476:202:0;-1:-1:-1;;;;;45476:202:0;;:::i;:::-;;;;;;;;;;;;;;;;29189:27;;;:::i;38548:1286::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38548:1286:0;;:::i;:::-;;;;-1:-1:-1;;;;;38548:1286:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36255:1624;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;36255:1624:0;;;;;;-1:-1:-1;;;;;36255:1624:0;;:::i;24641:120::-;;;:::i;:::-;;21844:109;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21844:109:0;-1:-1:-1;;;;;21844:109:0;;:::i;:::-;;;;;;;;;;;;;;;;;;23848:78;;;:::i;54875:401::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54875:401:0;;:::i;53733:724::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;53733:724:0;;;;;;;:::i;3486:218::-;;;:::i;50839:2359::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;50839:2359:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;21961:92::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;21961:92:0;-1:-1:-1;;;;;21961:92:0;;:::i;24428:118::-;;;:::i;34089:823::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;34089:823:0;;:::i;:::-;;;;-1:-1:-1;;;;;34089:823:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40719:4504;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;40719:4504:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;18614:79;;;:::i;:::-;;;;-1:-1:-1;;;;;18614:79:0;;;;;;;;;;;;;;18949:94;;;:::i;31910:696::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;31910:696:0;;:::i;38112:141::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38112:141:0;;:::i;35349:362::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;35349:362:0;;:::i;32971:834::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;32971:834:0;;;;;;;;:::i;23604:144::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;23604:144:0;-1:-1:-1;;;;;23604:144:0;;:::i;47114:2386::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;;47114:2386:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;28812:35::-;;;:::i;29104:14::-;;;:::i;19220:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;19220:109:0;-1:-1:-1;;;;;19220:109:0;;:::i;45476:202::-;45570:13;;:36;;;-1:-1:-1;;;45570:36:0;;-1:-1:-1;;;;;45570:36:0;;;;;;;;;45542:7;;45570:13;;;;;:22;;:36;;;;;;;;;;;;;;;:13;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;45570:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;45570:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;45570:36:0;45562:68;;;;;-1:-1:-1;;;45562:68:0;;;;;;;;;;;;-1:-1:-1;;;45562:68:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;;45648:22:0;;;;;:8;:22;;;;;;;45476:202::o;29189:27::-;;;;:::o;38548:1286::-;38735:14;38764:17;38796:15;38826:20;38861:17;38893:16;38924:24;38963:21;38999:27;39041:29;39085:32;38650:8;30763:7;:17;30771:8;30763:17;;;;;;;;;;;:26;;;;;;;;;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;31007:32;;;;:22;:32;;;;;:41;;;38693:8;;31007:41;;30999:87;;;;-1:-1:-1;;;30999:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39154:7;:17;39162:8;39154:17;;;;;;;;;;;:24;;;;;;;;;;-1:-1:-1;;;;;39154:24:0;39145:33;;39201:7;:17;39209:8;39201:17;;;;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;;;;39201:27:0;39189:39;;39249:7;:17;39257:8;39249:17;;;;;;;;;;;:25;;;39239:35;;39300:7;:17;39308:8;39300:17;;;;;;;;;;;:30;;;;;;;;;;-1:-1:-1;;;;;39300:30:0;39285:45;;39353:7;:17;39361:8;39353:17;;;;;;;;;;;:27;;;39341:39;;39402:7;:17;39410:8;39402:17;;;;;;;;;;;:26;;;39391:37;;39458:7;:17;39466:8;39458:17;;;;;;;;;;;:34;;;39439:53;;39519:7;:17;39527:8;39519:17;;;;;;;;;;;:31;;;39503:47;;39583:22;:32;39606:8;39583:32;;;;;;;;;;;:52;;:61;;;39561:83;;39679:22;:32;39702:8;39679:32;;;;;;;;;;;:44;;:53;;;39655:77;;39770:22;:32;39793:8;39770:32;;;;;;;;;;;:47;;:56;;;39743:83;;30826:1;38548:1286;;;;;;;;;;;;;;:::o;36255:1624::-;36349:15;30763:17;;;:7;:17;;;;;:26;;;:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;36377:26;;:::i;:::-;-1:-1:-1;36406:17:0;;;;:7;:17;;;;;;;;;36377:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;36377:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;36377:46:0;;;;;;;;;;;36434:30;;:::i;:::-;36477:13;36493:17;36501:8;36493:7;:17::i;:::-;36477:33;;36561:36;36569:5;36576:6;:20;;;36561:7;:36::i;:::-;36536:21;;;36521:76;;;36522:4;36521:76;;;;;;;;;;;;;;;;;;;-1:-1:-1;36632:18:0;;-1:-1:-1;36616:12:0;;:34;;;;;;;;;36608:82;;;;-1:-1:-1;;;36608:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36979:23;;;;36962:14;;:40;36958:478;;;37059:48;37067:6;:14;;;37083:6;:23;;;37059:7;:48::i;:::-;37034:21;;;37019:88;;;37020:4;37019:88;;;;;;;;;;;;;;;;;;;-1:-1:-1;37145:18:0;;-1:-1:-1;37129:12:0;;:34;;;;;;;;;37122:42;;;;37219:53;37227:4;:21;;;37250:4;:21;;;37219:7;:53::i;:::-;37194:21;;;37179:93;;;37180:4;37179:93;;;;;;;;;;;;;;;;;;;-1:-1:-1;37405:18:0;;-1:-1:-1;37389:12:0;;:34;;;;;;;;;37382:42;;;;37459:6;:16;;;-1:-1:-1;;;;;37452:23:0;:3;-1:-1:-1;;;;;37452:23:0;;37448:57;;;-1:-1:-1;37484:21:0;;;;-1:-1:-1;37477:28:0;;-1:-1:-1;37477:28:0;37448:57;37527:6;:13;;;-1:-1:-1;;;;;37520:20:0;:3;-1:-1:-1;;;;;37520:20:0;;37516:337;;;37594:55;37602:6;:23;;;37627:4;:21;;;37594:7;:55::i;:::-;37572:18;;;37557:92;;;37558:4;37557:92;;;;;;;;;;;;;;;;;;;-1:-1:-1;37782:18:0;;-1:-1:-1;37766:12:0;;:34;;;;;;;;;37759:42;;;;-1:-1:-1;37823:18:0;;;;-1:-1:-1;37816:25:0;;-1:-1:-1;37816:25:0;37516:337;37870:1;37863:8;;;;;30826:1;36255:1624;;;;;:::o;24641:120::-;21741:22;21750:12;:10;:12::i;:::-;21741:8;:22::i;:::-;21733:83;;;;-1:-1:-1;;;21733:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24284:7;;;;24276:40;;;;;-1:-1:-1;;;24276:40:0;;;;;;;;;;;;-1:-1:-1;;;24276:40:0;;;;;;;;;;;;;;;24700:7;:15;;-1:-1:-1;;24700:15:0;;;24731:22;24740:12;:10;:12::i;:::-;24731:22;;;-1:-1:-1;;;;;24731:22:0;;;;;;;;;;;;;;24641:120::o;21844:109::-;21900:4;21924:21;:8;21937:7;21924:21;:12;:21;:::i;:::-;21917:28;21844:109;-1:-1:-1;;21844:109:0:o;23848:78::-;23911:7;;;;23848:78;:::o;54875:401::-;4123:13;:18;;4140:1;4123:18;;;;;-1:-1:-1;30763:17:0;;;:7;:17;;;;;:26;;;-1:-1:-1;;4123:18:0;30763:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;30442:17;;;;:7;:17;;;;;:24;;;:17;;-1:-1:-1;;;;;30442:24:0;30428:10;:38;;:83;;-1:-1:-1;30484:17:0;;;;:7;:17;;;;;:27;;;-1:-1:-1;;;;;30484:27:0;30470:10;:41;30428:83;30406:188;;;;-1:-1:-1;;;30406:188:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55073:32;;;;:22;:32;;;;;:41;;;;;55068:179;;55131:30;55152:8;55131:20;:30::i;:::-;55068:179;;;55194:41;55226:8;55194:31;:41::i;:::-;55264:4;55257:11;;30826:1;4199;4235:13;;4219:12;:29;4211:38;;;;;;54875:401;;;;:::o;53733:724::-;24085:7;;53949:4;;24085:7;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;4123:13;:18;;4140:1;4123:18;;;;;-1:-1:-1;30763:17:0;;;:7;:17;;;;;:26;;;:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;30442:17;;;;:7;:17;;;;;:24;;;:17;;-1:-1:-1;;;;;30442:24:0;30428:10;:38;;:83;;-1:-1:-1;30484:17:0;;;;:7;:17;;;;;:27;;;-1:-1:-1;;;;;30484:27:0;30470:10;:41;30428:83;30406:188;;;;-1:-1:-1;;;30406:188:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53988:1;53979:6;:10;53971:37;;;;;-1:-1:-1;;;53971:37:0;;;;;;;;;;;;-1:-1:-1;;;53971:37:0;;;;;;;;;;;;;;;54019:26;;:::i;:::-;-1:-1:-1;54048:17:0;;;;:7;:17;;;;;;;;54019:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54019:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;54019:46:0;;;;;;;;;;;;54048:17;54094:37;;54048:17;;54094:9;:37::i;:::-;54076:55;;54161:6;54150:7;:17;;54142:66;;;;-1:-1:-1;;;54142:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54226:32;;;;:22;:32;;;;;:41;;;;;54221:207;;54284:44;54311:8;54321:6;54284:26;:44::i;:::-;54221:207;;;54361:55;54399:8;54409:6;54361:37;:55::i;:::-;54445:4;54438:11;;;;30826:1;4199;4235:13;;4219:12;:29;4211:38;;;;;3486:218;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;3695:1;3679:13;:17;2237:57;;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;2237:57;3486:218;:::o;50839:2359::-;24085:7;;51134;;24085;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;51162:13;;:36;;;-1:-1:-1;;;51162:36:0;;-1:-1:-1;;;;;51162:36:0;;;;;;;;;:13;;;;;:22;;:36;;;;;;;;;;;;;;:13;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;51162:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;51162:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;51162:36:0;51154:74;;;;;-1:-1:-1;;;51154:74:0;;;;;;;;;;;;-1:-1:-1;;;51154:74:0;;;;;;;;;;;;;;;51239:44;;:::i;:::-;51391:56;51399:21;51422:24;51391:7;:56::i;:::-;51374:13;;;51359:88;;;51360:4;51359:88;;;;;;;;;;;;;;;;;;;-1:-1:-1;51482:18:0;;-1:-1:-1;51466:12:0;;:34;;;;;;;;;51458:74;;;;;-1:-1:-1;;;51458:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51551:4;:13;;;51568:3;51551:20;51543:60;;;;;-1:-1:-1;;;51543:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;51616:16;51635:67;51648:9;51659:7;51668:12;51682:9;51693:8;51635:12;:67::i;:::-;51616:86;;51940:42;51948:21;28485:4;51940:7;:42::i;:::-;51912:24;;;51897:85;;;51898:4;51897:85;;;;;;;;;;;;;;;;;;;-1:-1:-1;52198:18:0;;-1:-1:-1;52182:12:0;;:34;;;;;;;;;52175:42;;;;52276:45;52284:24;28485:4;52276:7;:45::i;:::-;52245:27;;;52230:91;;;52231:4;52230:91;;;;;;;;;;;;;;;;;;;-1:-1:-1;52540:18:0;;-1:-1:-1;52524:12:0;;:34;;;;;;;;;52517:42;;;;52633:27;52671:12;-1:-1:-1;;;;;52663:41:0;;:43;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52663:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52663:43:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;52663:43:0;52752:291;;;52816:38;;;;;52752:291;;;;52816:38;;;52752:291;;52988:43;;52663;52988;;;;;53004:24;;;;;52988:43;;52752:291;;;;;;52914:46;;;;;;;52930:27;;;;52914:46;;-1:-1:-1;;;52752:291:0;;;52879:4;52752:291;;;;;;-1:-1:-1;52717:32:0;;;:22;:32;;;;;:326;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;52717:326:0;;;;;;;;;;;53061:103;;;;;;;;;;;;;;;;;;;52663:43;;-1:-1:-1;52717:32:0;;53061:103;;;;;;;;;;;-1:-1:-1;53182:8:0;50839:2359;-1:-1:-1;;;;;;;;;50839:2359:0:o;21961:92::-;21741:22;21750:12;:10;:12::i;21741:22::-;21733:83;;;;-1:-1:-1;;;21733:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22026:19;22037:7;22026:10;:19::i;24428:118::-;21741:22;21750:12;:10;:12::i;21741:22::-;21733:83;;;;-1:-1:-1;;;21733:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24085:7;;;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;24488:7;:14;;-1:-1:-1;;24488:14:0;24498:4;24488:14;;;24518:20;24525:12;:10;:12::i;34089:823::-;34222:14;34251:17;34283:15;34313:20;34348:17;34380:16;34411:24;34450:21;34180:8;30763:7;:17;30771:8;30763:17;;;;;;;;;;;:26;;;;;;;;;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;-1:-1:-1;;;34508:17:0;;;;-1:-1:-1;;34508:7:0;:17;;-1:-1:-1;;34508:17:0;;;;:24;;;;34555:27;;;;34603:25;;34654:30;;;;34707:27;;;;34756:26;;;;34812:34;;;;34508:24;34873:31;;;;-1:-1:-1;;;;;34508:24:0;;;;34555:27;;;;-1:-1:-1;34603:25:0;;-1:-1:-1;34654:30:0;;;;;34756:26;;34812:34;;34873:31;34089:823::o;40719:4504::-;40839:22;30763:17;;;:7;:17;;;;;:26;;;40839:22;;;;30763:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;40936:32;;;;:22;:32;;;;;:41;;;;;40931:91;;41002:1;;-1:-1:-1;41002:1:0;;-1:-1:-1;41002:1:0;;-1:-1:-1;40994:16:0;;40931:91;41032:26;;:::i;:::-;-1:-1:-1;41061:17:0;;;;:7;:17;;;;;;;;;41032:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41032:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;41032:46:0;;;;;;;;;;;41089:56;;:::i;:::-;-1:-1:-1;41148:32:0;;;;:22;:32;;;;;;;;;41089:91;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;41089:91:0;;;;;;;;;;;;;;;41191:31;;:::i;:::-;41424:30;;:::i;:::-;41457:69;;;;;;;;41481:6;:19;;;-1:-1:-1;;;;;41473:48:0;;:50;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;41473:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;41473:50:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41473:50:0;41457:69;;41573:41;;:50;41541:28;;41424:102;;-1:-1:-1;;41537:131:0;;-1:-1:-1;41648:1:0;;-1:-1:-1;41648:1:0;;-1:-1:-1;41648:1:0;;-1:-1:-1;41640:16:0;;-1:-1:-1;;;41640:16:0;41537:131;41719:70;41726:19;41747:21;:41;;;41719:6;:70::i;:::-;41693:22;;;41678:111;;;41679:4;41678:111;;;;;;;;;;;;;;;;;;;-1:-1:-1;41823:18:0;;-1:-1:-1;41807:12:0;;:34;;;;;;;;;41800:42;;;;41999:41;42009:4;:22;;;42033:6;41999:9;:41::i;:::-;41972:23;;;41957:83;;;41958:4;41957:83;;;;;;;;;;;;;;;;;;;-1:-1:-1;42075:18:0;;-1:-1:-1;42059:12:0;;:34;;;;;;;;;42051:73;;;;;-1:-1:-1;;;42051:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;42196:3;:12;28374:4;42196:30;42192:1266;;;42282:52;42289:4;:23;;;42314:19;42282:6;:52::i;:::-;42258:20;;;42243:91;;;42244:4;42243:91;;;;;;;;;;;;;;;;;;;-1:-1:-1;42373:18:0;;-1:-1:-1;42357:12:0;;:34;;;;;;;;;42349:80;;;;-1:-1:-1;;;42349:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42452:1;42455;42458:30;42467:4;:20;;;42458:8;:30::i;:::-;42444:45;;-1:-1:-1;42444:45:0;-1:-1:-1;42444:45:0;-1:-1:-1;42444:45:0;;-1:-1:-1;;;;42444:45:0;42192:1266;42511:3;:12;42507:951;;42578:20;;;;;;;;-1:-1:-1;42578:20:0;;42545:30;;;:53;42642:23;;;42613:26;;;:52;42507:951;;;42754:23;;;;;42747:36;;;;;;;;42779:3;42747:36;;;;;:6;:36::i;:::-;42713:30;;;42698:85;;;42699:4;42698:85;;;;;;;;;;;;;;;;;;;-1:-1:-1;42822:18:0;;-1:-1:-1;42806:12:0;;:34;;;;;;;;;42798:81;;;;-1:-1:-1;;;42798:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43030:112;43055:4;:23;;;43097:4;:30;;;43030:6;:112::i;:::-;43000:26;;;42985:157;;;42986:4;42985:157;;;;;;;;;;;;;;;;;;;-1:-1:-1;43427:18:0;;-1:-1:-1;43411:12:0;;:34;;;;;;;;;43404:42;;;;43579:106;43600:4;:26;;;43641:21;:33;;;43579:6;:106::i;:::-;43546:29;;;43531:154;;;43532:4;43531:154;;;;;;;;;;;;;;;;;;;-1:-1:-1;43720:18:0;;-1:-1:-1;43704:12:0;;:34;;;;;;;;;43696:80;;;;-1:-1:-1;;;43696:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43904:102;43925:4;:26;;;43966:4;:29;;;43904:6;:102::i;:::-;43868:32;;;43853:153;;;43854:4;43853:153;;;;;;;;;;;;;;;;;;;-1:-1:-1;44290:18:0;;-1:-1:-1;44274:12:0;;:34;;;;;;;;;44267:42;;;;44435:58;44442:4;:29;;;44473:19;44435:6;:58::i;:::-;44412:19;;;44397:96;;;44398:4;44397:96;;;;;;;;;;;;;;;;;;;-1:-1:-1;44528:18:0;;-1:-1:-1;44512:12:0;;:34;;;;;;;;;44504:79;;;;;-1:-1:-1;;;44504:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44637:61;44644:4;:32;;;44678:19;44637:6;:61::i;:::-;44611:22;;;44596:102;;;44597:4;44596:102;;;;;;;;;;;;;;;;;;;-1:-1:-1;44733:18:0;;-1:-1:-1;44717:12:0;;:34;;;;;;;;;44709:82;;;;-1:-1:-1;;;44709:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44843:59;44850:4;:30;;;44882:19;44843:6;:59::i;:::-;44819:20;;;44804:98;;;44805:4;44804:98;;;;;;;;;;;;;;;;;;;-1:-1:-1;44937:18:0;;-1:-1:-1;44921:12:0;;:34;;;;;;;;;44913:80;;;;-1:-1:-1;;;44913:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45119:29;45128:4;:19;;;45119:8;:29::i;:::-;45150:32;45159:4;:22;;;45150:8;:32::i;:::-;45184:30;45193:4;:20;;;45184:8;:30::i;:::-;45111:104;;;;;;;;;;30826:1;40719:4504;;;;;;:::o;18614:79::-;18679:6;;-1:-1:-1;;;;;18679:6:0;18614:79;:::o;18949:94::-;19029:6;;18989:4;;-1:-1:-1;;;;;19029:6:0;19013:12;:10;:12::i;:::-;-1:-1:-1;;;;;19013:22:0;;19006:29;;18949:94;:::o;31910:696::-;18826:9;:7;:9::i;:::-;18818:18;;;;;;32007:3;31990:13;:20;;31982:64;;;;;-1:-1:-1;;;31982:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;32057:30;;:::i;:::-;32243:34;32251:13;28485:4;32243:7;:34::i;:::-;32223:16;;;32208:69;;;32209:4;32208:69;;;;;;;;;;;;;;;;;;;-1:-1:-1;32485:18:0;;-1:-1:-1;32469:12:0;;:34;;;;;;;;;32462:42;;;;32523:35;;;;;;;;;32539:16;;;32523:35;;;;32517:3;:41;32574:24;32584:13;;32574:24;;-1:-1:-1;;32574:24:0;18847:1;31910:696;:::o;38112:141::-;38180:4;38204:32;;;:22;:32;;;;;:41;;;;;;38112:141::o;35349:362::-;35428:13;30763:17;;;:7;:17;;;;;:26;;;:17;;-1:-1:-1;;;30763:26:0;;;;30755:60;;;;;-1:-1:-1;;;30755:60:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;30755:60:0;;;;;;;;;;;;;;;35454:26;;:::i;:::-;-1:-1:-1;35483:17:0;;;;:7;:17;;;;;;;;;35454:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;35454:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;35454:46:0;;;;;;;;;;;;35515:15;:35;35511:49;;35559:1;35552:8;;;;;35511:49;35593:6;:15;;;35575;:33;35571:80;;;35635:16;;;35617:15;:34;;-1:-1:-1;35610:41:0;;35571:80;35687:16;;;;35669:15;;;;;:34;;35349:362;-1:-1:-1;;;35349:362:0:o;32971:834::-;18826:9;:7;:9::i;:::-;18818:18;;;;;;4123:13;:18;;4140:1;4123:18;;;;;33082:13;;:36;;;-1:-1:-1;;;33082:36:0;;-1:-1:-1;;;;;33082:36:0;;;;;;;;;:13;;;;;:22;;:36;;;;;;;;;;;;;;:13;:36;;;5:2:-1;;;;30:1;27;20:12;5:2;33082:36:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33082:36:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33082:36:0;33074:74;;;;;-1:-1:-1;;;33074:74:0;;;;;;;;;;;;-1:-1:-1;;;33074:74:0;;;;;;;;;;;;;;;33176:1;33167:6;:10;33159:37;;;;;-1:-1:-1;;;33159:37:0;;;;;;;;;;;;-1:-1:-1;;;33159:37:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;33215:22:0;;;;;;:8;:22;;;;;;:32;-1:-1:-1;33215:32:0;33207:81;;;;-1:-1:-1;;;33207:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33301:33;;:::i;:::-;-1:-1:-1;;;;;33394:22:0;;;;;;:8;:22;;;;;;33386:39;;33418:6;33386:7;:39::i;:::-;-1:-1:-1;;;;;33360:22:0;;33346:12;33360:22;;;:8;:22;;;;;33345:80;;;33346:4;33345:80;;;;;;;;;;;;;;;;;;;-1:-1:-1;33631:18:0;;-1:-1:-1;33615:12:0;;:34;;;;;;;;;33608:42;;;;33668:34;;33695:6;;-1:-1:-1;;;;;33668:34:0;;;;;;;;33721:49;;;-1:-1:-1;;;33721:49:0;;33751:10;33721:49;;;;;;;;;;;;-1:-1:-1;;;;;33721:29:0;;;;;:49;;;;;;;;;;;;;;-1:-1:-1;33721:29:0;:49;;;5:2:-1;;;;30:1;27;20:12;5:2;33721:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;33721:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;33721:49:0;33713:84;;;;;-1:-1:-1;;;33713:84:0;;;;;;;;;;;;-1:-1:-1;;;33713:84:0;;;;;;;;;;;;;;;4199:1;4235:13;;4219:12;:29;4211:38;;;;;;18847:1;32971:834;;:::o;23604:144::-;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;23670:44;23707:6;23670:36;:44::i;:::-;23725:7;:15;;-1:-1:-1;;23725:15:0;;;2237:57;;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;2237:57;23604:144;;:::o;47114:2386::-;24085:7;;47288;;24085;;24084:8;24076:37;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;-1:-1:-1;;;24076:37:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;47321:26:0;;47313:65;;;;;-1:-1:-1;;;47313:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47397:26:0;;47418:4;47397:26;;47389:68;;;;;-1:-1:-1;;;47389:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;47476:23:0;;47489:10;47476:23;;47468:56;;;;;-1:-1:-1;;;47468:56:0;;;;;;;;;;;;-1:-1:-1;;;47468:56:0;;;;;;;;;;;;;;;47553:1;47543:7;:11;47535:39;;;;;-1:-1:-1;;;47535:39:0;;;;;;;;;;;;-1:-1:-1;;;47535:39:0;;;;;;;;;;;;;;;47606:15;47593:9;:28;;47585:74;;;;-1:-1:-1;;;47585:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47689:9;47678:8;:20;47670:64;;;;;-1:-1:-1;;;47670:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;47747:33;;:::i;:::-;47823:28;47831:8;47841:9;47823:7;:28::i;:::-;47806:13;;;47791:60;;;47792:4;47791:60;;;;;;;;;;;;;;;;;;;-1:-1:-1;48005:18:0;;-1:-1:-1;47989:12:0;;:34;;;;;;;;;47982:42;;;;48120:4;:13;;;48109:7;:24;;48101:68;;;;;-1:-1:-1;;;48101:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;48261:4;:13;;;48251:7;:23;;;;;;:28;48243:75;;;;-1:-1:-1;;;48243:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48368:31;48376:7;48385:4;:13;;;48368:7;:31::i;:::-;48346:18;;;48331:68;;;48332:4;48331:68;;;;;;;;;;;;;;;;;;;-1:-1:-1;48537:18:0;;-1:-1:-1;48521:12:0;;:34;;;;;;;;;48514:42;;;;48620:16;48639:12;;48620:31;;48682:350;;;;;;;;48759:7;48682:350;;;;48825:4;:18;;;48682:350;;;;48728:7;48682:350;;;;48937:9;48682:350;;;;48971:8;48682:350;;;;48869:9;-1:-1:-1;;;;;48682:350:0;;;;;48901:10;-1:-1:-1;;;;;48682:350:0;;;;;49008:12;-1:-1:-1;;;;;48682:350:0;;;;;48791:4;48682:350;;;;;48662:7;:17;48670:8;48662:17;;;;;;;;;;;:370;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48662:370:0;;;;;-1:-1:-1;;;;;48662:370:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48662:370:0;;;;;-1:-1:-1;;;;;48662:370:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48662:370:0;;;;;-1:-1:-1;;;;;48662:370:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49121:33;49129:12;;49151:1;49121:7;:33::i;:::-;49105:12;49090:64;;;49091:4;49090:64;;;;;;;;;;;;;;;;;;;-1:-1:-1;49189:18:0;;-1:-1:-1;49173:12:0;;:34;;;;;;;;;49165:79;;;;;-1:-1:-1;;;49165:79:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49265:69;;;-1:-1:-1;;;49265:69:0;;49299:10;49265:69;;;;49319:4;49265:69;;;;;;;;;;;;-1:-1:-1;;;;;49265:33:0;;;;;:69;;;;;;;;;;;;;;-1:-1:-1;49265:33:0;:69;;;5:2:-1;;;;30:1;27;20:12;5:2;49265:69:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;49265:69:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;49265:69:0;49257:104;;;;;-1:-1:-1;;;49257:104:0;;;;;;;;;;;;-1:-1:-1;;;49257:104:0;;;;;;;;;;;;;;;49377:89;;;;;;-1:-1:-1;;;;;49377:89:0;;;;;;;;;;;;;;;;;;;;;;;;;49400:10;;49390:8;;49377:89;;;;;;;;;49484:8;47114:2386;-1:-1:-1;;;;;;;47114:2386:0:o;28812:35::-;;;-1:-1:-1;;;;;28812:35:0;;:::o;29104:14::-;;;;:::o;19220:109::-;18826:9;:7;:9::i;:::-;18818:18;;;;;;19293:28;19312:8;19293:18;:28::i;4930:343::-;4986:9;;5018:6;5014:69;;-1:-1:-1;5049:18:0;;-1:-1:-1;5049:18:0;5041:30;;5014:69;5104:5;;;5108:1;5104;:5;:1;5126:5;;;;;:10;5122:144;;-1:-1:-1;5161:26:0;;-1:-1:-1;5189:1:0;;-1:-1:-1;5153:38:0;;5122:144;5232:18;;-1:-1:-1;5252:1:0;-1:-1:-1;4930:343:0;;;;;;:::o;5718:236::-;5774:9;5785:4;5811:1;5806;:6;5802:145;;-1:-1:-1;5837:18:0;;-1:-1:-1;5857:5:0;;;5829:34;;5802:145;-1:-1:-1;5904:27:0;;-1:-1:-1;5933:1:0;5896:39;;17012:90;17084:10;17012:90;:::o;20612:165::-;20684:4;-1:-1:-1;;;;;20709:21:0;;20701:30;;;;;;-1:-1:-1;;;;;;20749:20:0;:11;:20;;;;;;;;;;;;;;;20612:165::o;60027:729::-;60095:26;;:::i;:::-;-1:-1:-1;60124:17:0;;;;:7;:17;;;;;;;;60095:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;60095:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;60095:46:0;;;;;;;;;;;;60124:17;60176:34;;60124:17;;60176:9;:34::i;:::-;60152:58;;60221:24;60248:37;60258:8;60268:6;:16;;;60248:9;:37::i;:::-;60305:17;;;;:7;:17;;;;;60298:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60298:24:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60298:24:0;;;60357:19;;;;60221:64;;-1:-1:-1;60392:20:0;;60388:134;;60435:5;-1:-1:-1;;;;;60435:14:0;;60450:6;:16;;;60468;60435:50;;;;;;;;;;;;;-1:-1:-1;;;;;60435:50:0;-1:-1:-1;;;;;60435:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60435:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60435:50:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60435:50:0;60427:95;;;;;-1:-1:-1;;;60427:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60537:17;;60533:109;;60564:5;-1:-1:-1;;;;;60564:14:0;;60579:6;:13;;;60594;60564:44;;;;;;;;;;;;;-1:-1:-1;;;;;60564:44:0;-1:-1:-1;;;;;60564:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60564:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60564:44:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60564:44:0;60556:86;;;;;-1:-1:-1;;;60556:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;60698:6;:16;;;-1:-1:-1;;;;;60660:88:0;60683:6;:13;;;-1:-1:-1;;;;;60660:88:0;60673:8;60660:88;60716:13;60731:16;60660:88;;;;;;;;;;;;;;;;;;;;;;;;60027:729;;;;;:::o;61410:3202::-;61489:26;;:::i;:::-;-1:-1:-1;61518:17:0;;;;:7;:17;;;;;;;;;61489:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;61489:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;61489:46:0;;;;;;;;;;;61546:43;;:::i;:::-;61799:21;61823:34;61833:8;61843:6;:13;;;61823:9;:34::i;:::-;61799:58;;61868:24;61895:37;61905:8;61915:6;:16;;;61895:9;:37::i;:::-;61868:64;;62059:22;62083:25;62110:23;62137:75;62162:8;62185:16;62137:10;:75::i;:::-;62058:154;;;;;;62605:38;62613:13;62628:14;62605:7;:38::i;:::-;62580:21;;;62565:78;;;62566:4;62565:78;;;;;;;;;;;;;;;;;;;-1:-1:-1;62678:18:0;;-1:-1:-1;62662:12:0;;:34;;;;;;;;;62654:83;;;;-1:-1:-1;;;62654:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63156:41;63164:16;63182:14;63156:7;:41::i;:::-;63110:42;;;63095:102;;;63096:4;63095:102;;;;;;;;;;;;;;;;;;;-1:-1:-1;63232:18:0;;-1:-1:-1;63216:12:0;;:34;;;;;;;;;63208:106;;;;-1:-1:-1;;;63208:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63368:68;63376:4;:42;;;63420:15;63368:7;:68::i;:::-;63340:24;;;63325:111;;;63326:4;63325:111;;;;;;;;;;;;;;;;;;;-1:-1:-1;63471:18:0;;-1:-1:-1;63455:12:0;;:34;;;;;;;;;63447:86;;;;-1:-1:-1;;;63447:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63694:19;;;;-1:-1:-1;;;;;63685:29:0;;;;;:8;:29;;;;;;63677:55;;63716:15;63677:7;:55::i;:::-;63653:19;;;;-1:-1:-1;;;;;63644:29:0;63630:12;63644:29;;;:8;:29;;;;;63629:103;;;63630:4;63629:103;;;;;;;;;;;;;;;;;;;-1:-1:-1;63767:18:0;;-1:-1:-1;63751:12:0;;:34;;;;;;;;;63743:82;;;;-1:-1:-1;;;63743:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63893:17;;;;:7;:17;;;;;;;;63886:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;63886:24:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;63886:24:0;;;63928:22;:32;;;;;63921:39;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63921:39:0;;;64063:19;;;;64098:21;;;;:25;64094:138;;64146:5;-1:-1:-1;;;;;64146:14:0;;64161:6;:13;;;64176:4;:21;;;64146:52;;;;;;;;;;;;;-1:-1:-1;;;;;64146:52:0;-1:-1:-1;;;;;64146:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64146:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64146:52:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64146:52:0;64138:94;;;;;-1:-1:-1;;;64138:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;64247:24;;;;:28;64243:150;;64298:5;-1:-1:-1;;;;;64298:14:0;;64313:6;:16;;;64331:4;:24;;;64298:58;;;;;;;;;;;;;-1:-1:-1;;;;;64298:58:0;-1:-1:-1;;;;;64298:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64298:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64298:58:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64298:58:0;64290:103;;;;;-1:-1:-1;;;64290:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64449:6;:16;;;-1:-1:-1;;;;;64411:104:0;64434:6;:13;;;-1:-1:-1;;;;;64411:104:0;64424:8;64411:104;64467:4;:21;;;64490:4;:24;;;64411:104;;;;;;;;;;;;;;;;;;;;;;;;64531:73;;;;;;;;;;;;;;;;;;;;64543:8;;64531:73;;;;;;;;;;61410:3202;;;;;;;;;:::o;55779:844::-;55869:26;;:::i;:::-;-1:-1:-1;55898:17:0;;;;:7;:17;;;;;;;;;55869:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55869:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;55869:46:0;;;;;;;;;;;55926:47;;:::i;:::-;56037:40;56045:6;:23;;;56070:6;56037:7;:40::i;:::-;55985:12;55999:17;;;:7;:17;;;;;:34;;55984:93;;;55985:4;55984:93;;;;;;;;;;;;;;;;;;;-1:-1:-1;56334:18:0;;-1:-1:-1;56318:12:0;;:34;;;;;;;;;56311:42;;;;56370:17;;;;:7;:17;;;;;:34;;;56366:69;;56418:17;;;;:7;:17;;;;;56411:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56411:24:0;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;56411:24:0;;;56366:69;56463:6;:19;;;-1:-1:-1;;;;;56456:36:0;;56493:6;:16;;;56511:6;56456:62;;;;;;;;;;;;;-1:-1:-1;;;;;56456:62:0;-1:-1:-1;;;;;56456:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56456:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;56456:62:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56456:62:0;56448:97;;;;;-1:-1:-1;;;56448:97:0;;;;;;;;;;;;-1:-1:-1;;;56448:97:0;;;;;;;;;;;;;;;56590:6;:16;;;-1:-1:-1;;;;;56561:54:0;56580:8;56561:54;56608:6;56561:54;;;;;;;;;;;;;;;;;;55779:844;;;;:::o;57155:2582::-;57256:26;;:::i;:::-;-1:-1:-1;57285:17:0;;;;:7;:17;;;;;;;;;57256:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57256:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;57256:46:0;;;;;;;;;;;57313:58;;:::i;:::-;57496:22;57520:25;57547:23;57574:28;57585:8;57595:6;57574:10;:28::i;:::-;57495:107;;;;;;58011:31;58019:6;58027:14;58011:7;:31::i;:::-;57975:32;;;57960:82;;;57961:4;57960:82;;;;;;;;;;;;;;;;;;;-1:-1:-1;58077:18:0;;-1:-1:-1;58061:12:0;;:34;;;;;;;;;58053:95;;;;-1:-1:-1;;;58053:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58202:58;58210:4;:32;;;58244:15;58202:7;:58::i;:::-;58174:24;;;58159:101;;;58160:4;58159:101;;;;;;;;;;;;;;;;;;;-1:-1:-1;58295:18:0;;-1:-1:-1;58279:12:0;;:34;;;;;;;;;58271:86;;;;-1:-1:-1;;;58271:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58498:40;58506:6;:23;;;58531:6;58498:7;:40::i;:::-;58446:12;58460:17;;;:7;:17;;;;;:34;;58445:93;;;58446:4;58445:93;;;;;;;;;;;;;;;;;;;-1:-1:-1;58573:18:0;;-1:-1:-1;58557:12:0;;:34;;;;;;;;;58549:84;;;;-1:-1:-1;;;58549:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58746:17;;;;:7;:17;;;;;:34;;;58742:150;;58809:17;;;;:7;:17;;;;;;;;58802:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;58802:24:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;58802:24:0;;;58848:22;:32;;;;;;58841:39;;;;;;;;;;;;;;;;;;;-1:-1:-1;;58841:39:0;;;58742:150;59042:19;;;;-1:-1:-1;;;;;59033:29:0;;;;;:8;:29;;;;;;59025:55;;59064:15;59025:7;:55::i;:::-;59001:19;;;;-1:-1:-1;;;;;58992:29:0;58978:12;58992:29;;;:8;:29;;;;;58977:103;;;58978:4;58977:103;;;;;;;;;;;;;;;;;;;-1:-1:-1;59115:18:0;;-1:-1:-1;59099:12:0;;:34;;;;;;;;;59091:82;;;;-1:-1:-1;;;59091:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59279:19;;;;59314:18;;59310:125;;59355:6;-1:-1:-1;;;;;59355:15:0;;59371:6;:13;;;59386:14;59355:46;;;;;;;;;;;;;-1:-1:-1;;;;;59355:46:0;-1:-1:-1;;;;;59355:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59355:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59355:46:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59355:46:0;59347:88;;;;;-1:-1:-1;;;59347:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;59454:6;-1:-1:-1;;;;;59454:15:0;;59470:6;:16;;;59488:4;:24;;;59454:59;;;;;;;;;;;;;-1:-1:-1;;;;;59454:59:0;-1:-1:-1;;;;;59454:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59454:59:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59454:59:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59454:59:0;59446:104;;;;;-1:-1:-1;;;59446:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59597:6;:16;;;-1:-1:-1;;;;;59568:72:0;59587:8;59568:72;59615:4;:24;;;59568:72;;;;;;;;;;;;;;;;;;59656:73;;;;;;;;;;;;;;;;;;;;59668:8;;59656:73;;;;;;;;;;57155:2582;;;;;;;;:::o;2388:476::-;2828:7;2816:20;2851:7;2388:476;:::o;6039:258::-;6095:9;;6132:5;;;6154:6;;;6150:140;;6185:18;;-1:-1:-1;6205:1:0;-1:-1:-1;6177:30:0;;6150:140;-1:-1:-1;6248:26:0;;-1:-1:-1;6276:1:0;;-1:-1:-1;6240:38:0;;22061:122;22118:21;:8;22131:7;22118:21;:12;:21;:::i;:::-;22155:20;;-1:-1:-1;;;;;22155:20:0;;;;;;;;22061:122;:::o;8416:225::-;8483:9;8494:10;;:::i;:::-;8518:15;8535:11;8550:31;8558:1;:10;;;8570:1;:10;;;8550:7;:31::i;:::-;8609:23;;;;;;;;;;;;8517:64;;8609:23;;-1:-1:-1;8416:225:0;-1:-1:-1;;;;;8416:225:0:o;8730:353::-;8799:9;8810:10;;:::i;:::-;8834:14;8850:19;8873:27;8881:1;:10;;;8893:6;8873:7;:27::i;:::-;8833:67;;-1:-1:-1;8833:67:0;-1:-1:-1;8923:18:0;8915:4;:26;;;;;;;;;8911:92;;-1:-1:-1;8972:18:0;;;;;;;;;-1:-1:-1;8972:18:0;;8966:4;;-1:-1:-1;8972:18:0;-1:-1:-1;8958:33:0;;8911:92;9043:31;;;;;;;;;;;;-1:-1:-1;;9043:31:0;;-1:-1:-1;8730:353:0;-1:-1:-1;;;;8730:353:0:o;13705:146::-;13772:9;13783:10;;:::i;:::-;13820;;13832;;13813:30;;13820:10;13813:6;:30::i;:::-;13806:37;;;;13705:146;;;;;:::o;14009:213::-;14191:12;7135:4;14191:23;;;14009:213::o;11678:1136::-;11745:9;11756:10;;:::i;:::-;11782:14;11798:24;11826:31;11834:1;:10;;;11846:1;:10;;;11826:7;:31::i;:::-;11781:76;;-1:-1:-1;11781:76:0;-1:-1:-1;11880:18:0;11872:4;:26;;;;;;;;;11868:92;;-1:-1:-1;11929:18:0;;;;;;;;;-1:-1:-1;11929:18:0;;11923:4;;-1:-1:-1;11929:18:0;-1:-1:-1;11915:33:0;;11868:92;12277:14;;12334:42;7175:10;12356:19;12334:7;:42::i;:::-;12276:100;;-1:-1:-1;12276:100:0;-1:-1:-1;12399:18:0;12391:4;:26;;;;;;;;;12387:92;;-1:-1:-1;12448:18:0;;;;;;;;;-1:-1:-1;12448:18:0;;12442:4;;-1:-1:-1;12448:18:0;-1:-1:-1;12434:33:0;;-1:-1:-1;;12434:33:0;12387:92;12492:14;12508:12;12524:51;12532:32;7135:4;12524:7;:51::i;:::-;12491:84;;-1:-1:-1;12491:84:0;-1:-1:-1;12721:18:0;12713:4;:26;;;;;;;;;12706:34;;;;12781:24;;;;;;;;;;;;-1:-1:-1;;12781:24:0;;-1:-1:-1;11678:1136:0;-1:-1:-1;;;;;;;;11678:1136:0:o;21551:141::-;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;21622:16;21631:6;21622:8;:16::i;:::-;21617:68;;21655:18;21666:6;21655:10;:18::i;:::-;2241:14;2237:57;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;21551:141;;:::o;5368:215::-;5424:9;;5456:6;5452:77;;-1:-1:-1;5487:26:0;;-1:-1:-1;5515:1:0;5479:38;;5452:77;5549:18;5573:1;5569;:5;;;;;;5541:34;;;;5368:215;;;;;:::o;19479:187::-;-1:-1:-1;;;;;19553:22:0;;19545:31;;;;;;19613:6;;19592:38;;-1:-1:-1;;;;;19592:38:0;;;;19613:6;;19592:38;;19613:6;;19592:38;19641:6;:17;;-1:-1:-1;;;;;;19641:17:0;-1:-1:-1;;;;;19641:17:0;;;;;;;;;;19479:187::o;20064:186::-;-1:-1:-1;;;;;20141:21:0;;20133:30;;;;;;20183:18;20187:4;20193:7;20183:3;:18::i;:::-;20182:19;20174:28;;;;;;-1:-1:-1;;;;;20215:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;20215:27:0;20238:4;20215:27;;;20064:186::o;7489:515::-;7550:9;7561:10;;:::i;:::-;7585:14;7601:20;7625:22;7633:3;7135:4;7625:7;:22::i;:::-;7584:63;;-1:-1:-1;7584:63:0;-1:-1:-1;7670:18:0;7662:4;:26;;;;;;;;;7658:92;;-1:-1:-1;7719:18:0;;;;;;;;;-1:-1:-1;7719:18:0;;7713:4;;-1:-1:-1;7719:18:0;-1:-1:-1;7705:33:0;;7658:92;7763:14;7779:13;7796:31;7804:15;7821:5;7796:7;:31::i;:::-;7762:65;;-1:-1:-1;7762:65:0;-1:-1:-1;7850:18:0;7842:4;:26;;;;;;;;;7838:92;;-1:-1:-1;7899:18:0;;;;;;;;;-1:-1:-1;7899:18:0;;7893:4;;-1:-1:-1;7899:18:0;-1:-1:-1;7885:33:0;;-1:-1:-1;;7885:33:0;7838:92;7970:25;;;;;;;;;;;;-1:-1:-1;;7970:25:0;;-1:-1:-1;7489:515:0;-1:-1:-1;;;;;;7489:515:0:o;28122:36493::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;28122:36493:0;;;;;;-1:-1:-1;;;;;28122:36493:0;;;;;;-1:-1:-1;;;;;28122:36493:0;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;-1:-1:-1;28122:36493:0;;;;;;;;;;;;;;:::o;18401:145::-;1987:12;;;;;;;;:31;;;2003:15;:13;:15::i;:::-;1987:47;;;-1:-1:-1;2023:11:0;;;;2022:12;1987:47;1979:106;;;;-1:-1:-1;;;1979:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2094:19;2117:12;;;;;;2116:13;2136:83;;;;2165:12;:19;;-1:-1:-1;;;;2165:19:0;;;;;2193:18;2180:4;2193:18;;;2136:83;18467:6;:15;;-1:-1:-1;;;;;;18467:15:0;-1:-1:-1;;;;;18467:15:0;;;;;;;;;;;18498:40;;18531:6;;;-1:-1:-1;;18498:40:0;;-1:-1:-1;;18498:40:0;2241:14;2237:57;;;2281:5;2266:20;;-1:-1:-1;;2266:20:0;;;18401:145;;:::o

Swarm Source

bzzr://d5ad0c39f51a54f8b3b77f6b8f02e3d034b5fabbacccfa1751ca957d1cd14a2d
Loading...
Loading
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.