ETH Price: $3,997.61 (-0.01%)

Contract

0xA4fc358455Febe425536fd1878bE67FfDBDEC59a
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Transaction Hash
Method
Block
From
To
Withdraw From St...213188472024-12-03 1:58:474 days ago1733191127IN
Sablier v1.0
0 ETH0.0013860317.71805611
Withdraw From St...211883662024-11-14 20:37:4722 days ago1731616667IN
Sablier v1.0
0 ETH0.002111327.47092637
Withdraw From St...207864102024-09-19 18:24:1178 days ago1726770251IN
Sablier v1.0
0 ETH0.0014068317.98628811
Withdraw From St...194427772024-03-15 20:38:35266 days ago1710535115IN
Sablier v1.0
0 ETH0.0030105332.75988523
Withdraw From St...193212702024-02-27 20:27:47283 days ago1709065667IN
Sablier v1.0
0 ETH0.005288956.32062554
Withdraw From St...193212602024-02-27 20:25:35283 days ago1709065535IN
Sablier v1.0
0 ETH0.0042461455.28325544
Withdraw From St...193212522024-02-27 20:23:59283 days ago1709065439IN
Sablier v1.0
0 ETH0.0051957155.3424065
Withdraw From St...192663642024-02-20 3:53:35291 days ago1708401215IN
Sablier v1.0
0 ETH0.0023707425.24300653
Withdraw From St...190573282024-01-21 19:37:47320 days ago1705865867IN
Sablier v1.0
0 ETH0.0014967815.9373035
Withdraw From St...187009742023-12-02 20:01:35370 days ago1701547295IN
Sablier v1.0
0 ETH0.0035556743.52537176
Withdraw From St...187008722023-12-02 19:40:59370 days ago1701546059IN
Sablier v1.0
0 ETH0.0038633447.29736327
Withdraw From St...185525092023-11-12 1:18:11391 days ago1699751891IN
Sablier v1.0
0 ETH0.0019460420.72086607
Withdraw From St...184173212023-10-24 3:04:35410 days ago1698116675IN
Sablier v1.0
0 ETH0.0049046452.22321407
Withdraw From St...183283102023-10-11 16:11:47422 days ago1697040707IN
Sablier v1.0
0 ETH0.001648617.64719893
Withdraw From St...176980332023-07-15 9:53:59511 days ago1689414839IN
Sablier v1.0
0 ETH0.0011935413.05109658
Withdraw From St...176371532023-07-06 20:23:35519 days ago1688675015IN
Sablier v1.0
0 ETH0.0022117923.09265196
Withdraw From St...175707952023-06-27 12:50:11529 days ago1687870211IN
Sablier v1.0
0 ETH0.0016962618.45833435
Withdraw From St...174732402023-06-13 19:47:11542 days ago1686685631IN
Sablier v1.0
0 ETH0.0018573919.77947841
Withdraw From St...174732302023-06-13 19:45:11542 days ago1686685511IN
Sablier v1.0
0 ETH0.001733122.56503569
Withdraw From St...174732202023-06-13 19:43:11542 days ago1686685391IN
Sablier v1.0
0 ETH0.0018761719.98461511
Withdraw From St...173614022023-05-29 1:31:59558 days ago1685323919IN
Sablier v1.0
0 ETH0.0055169958.74332542
Withdraw From St...172269692023-05-10 2:14:11577 days ago1683684851IN
Sablier v1.0
0 ETH0.0069893574.42058541
Withdraw From St...171208442023-04-25 4:16:23592 days ago1682396183IN
Sablier v1.0
0 ETH0.0035305937.59266872
Withdraw From St...169699822023-04-03 17:30:35613 days ago1680543035IN
Sablier v1.0
0 ETH0.0026241127.94082662
Withdraw From St...168340762023-03-15 15:06:47632 days ago1678892807IN
Sablier v1.0
0 ETH0.0034432436.65796438
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

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

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

The core piece of technology powering Sablier, the protocol for real-time finance on Ethereum.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Chain Token Portfolio % Price Amount Value
ETH50.35%$0.09196651,791,197.8919$4,763,030.11
ETH12.23%$22.5751,257.614$1,156,884.35
ETH11.33%$0.03563930,061,571.7325$1,071,351.49
ETH9.02%$0.1201927,100,806.8404$853,460.18
ETH5.16%$0.1129754,318,951.8007$487,933.58
ETH2.30%$1.21179,876.5475$217,650.62
ETH2.25%$0.0814622,608,364.6219$212,483.19
ETH1.99%$0.630543299,173.483$188,641.75
ETH1.85%$0.0302775,778,383.5314$174,951.54
ETH1.61%$13.9510,887.1903$151,876.31
ETH0.64%$0.0140314,330,539.9264$60,762.89
ETH0.30%$0.177114157,866.2657$27,960.38
ETH0.21%$0.21517693,108.4453$20,034.7
ETH0.14%$0.2706649,431.6965$13,379.18
ETH0.11%$0.24980642,874.1866$10,710.23
ETH0.10%$0.9992589,019.6159$9,012.92
ETH0.08%$0.002662,968,570.2823$7,896.6
ETH0.08%$0.008294900,630.2838$7,469.63
ETH0.08%$17.52425.9$7,461.77
ETH0.05%$38.7112.3086$4,346.34
ETH0.03%$0.9993432,804.8658$2,803.02
ETH0.03%$0.023974110,078.977$2,639
ETH0.01%$3,997.610.3495$1,397.05
ETH0.01%$99,1170.0101$999.1
ETH0.01%$1.24784.0872$972.27
ETH<0.01%$0.002884297,084.9961$856.7
ETH<0.01%$25.0823.8215$597.44
ETH<0.01%$20.6925.63$530.28
ETH<0.01%$0.1371812,285.1908$313.48
ETH<0.01%$1.54179.5373$275.79
ETH<0.01%$0.834922312.5912$260.99
ETH<0.01%$0.345849520.5258$180.02
ETH<0.01%$0.455246238.1216$108.4
ETH<0.01%$0.509133100.4043$51.12
ETH<0.01%$0.070702492$34.79
ETH<0.01%$1.8815$28.2
ETH<0.01%$0.036538712.936$26.05
ETH<0.01%$0.87395518$15.73
ETH<0.01%$2,181.580.005$10.91
ETH<0.01%$1.0210$10.17
ETH<0.01%$1.595.2875$8.42
ETH<0.01%$0.001116,000$6.66
ETH<0.01%$22.210.25$5.55
ETH<0.01%$0.10509447.8009$5.02
ETH<0.01%$0.9997794.57$4.57
ETH<0.01%$117.310.0361$4.24
ETH<0.01%$3.980.9652$3.84
ETH<0.01%$1,090.820.00185$2.02
ETH<0.01%$0.04731435$1.66
ETH<0.01%$0.02432449.3954$1.2
ETH<0.01%$0.005966148.4999$0.8859
ETH<0.01%$0.00640540$0.2562
ETH<0.01%$2.750.09$0.2474
FTM<0.01%$2.125$10.6
FTM<0.01%$1.370.011$0.015117
AVAX<0.01%$0.02421850$1.21
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.