Contract 0x02ee9AEbb75470D517BFf722D36762d2b231539C

Contract Overview

Balance:
0 Ether
Txn Hash
Method
Block
From
To
Value
0x9b6f0d86ee8de6edbf2fc80c5e91d98b6b8d354ec2058f2b2a2c6668e2fb5f05Enable Market60023942020-02-20 5:24:26820 days 5 hrs ago0x8d7f03fde1a626223364e592740a233b72395235 IN  0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether0.0000243771
0x2527759daa2de69f1a61e881c02272aeb7c37190c6d6c7c688f62b8219d6d2d3Enable Market60023912020-02-20 5:23:41820 days 5 hrs ago0x8d7f03fde1a626223364e592740a233b72395235 IN  0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether0.0000225871
0x1f93d18d63b98cba459559908b3413bb3e0334eb0f6bd1adf879b4a1b87a72e3Transfer Ownersh...59961392020-02-19 3:20:35821 days 7 hrs ago0x8d7f03fde1a626223364e592740a233b72395235 IN  0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether0.0004492168
0x4207103063a86ecb68d6efb381a18cac0524d879e8b9df9a137740fa8db61ab40x6080604059961222020-02-19 3:16:20821 days 7 hrs ago0x8d7f03fde1a626223364e592740a233b72395235 IN  Create: DmmController0 Ether0.0268117688
[ Download CSV Export 
Latest 20 internal transactions
Parent Txn Hash Block From To Value
0x7d39c56e85921a6e921c8893b5a55640a3f28a84241acf3d5bf97045f586ad1092054652021-08-30 11:48:38262 days 23 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0x7d39c56e85921a6e921c8893b5a55640a3f28a84241acf3d5bf97045f586ad1092054652021-08-30 11:48:38262 days 23 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0x7d39c56e85921a6e921c8893b5a55640a3f28a84241acf3d5bf97045f586ad1092054652021-08-30 11:48:38262 days 23 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x02ee9aebb75470d517bff722d36762d2b231539c 0x7a01313ed513f13acc35536cb66feb5362e6c3c30 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x02ee9aebb75470d517bff722d36762d2b231539c 0x1393a9496a526a95a59cf187f71a0dc077d97a0b0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x02ee9aebb75470d517bff722d36762d2b231539c 0x1393a9496a526a95a59cf187f71a0dc077d97a0b0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0xb656ba77a80d945ace973b5e13c7387323d222f497df05577d29895ce494e18160022882020-02-20 4:57:56820 days 6 hrs ago 0x1393a9496a526a95a59cf187f71a0dc077d97a0b 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0x64fc735bdf1a4154d2f18b62cdaaf9f842d85d3ff9d2b307d69f71217a04a5e160022262020-02-20 4:42:26820 days 6 hrs ago 0xcfd027019f9ff28ac3db417b630c7a21881090fb 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0x9fd82879c6ba1ffcbb3b60c3f1c024d306dba5ba41a464f3024521678f5c625559964142020-02-19 4:29:20821 days 6 hrs ago 0x02ee9aebb75470d517bff722d36762d2b231539c 0xbc5b9040fee0cca807a0d6e35f535a1b8e609c140 Ether
0x9fd82879c6ba1ffcbb3b60c3f1c024d306dba5ba41a464f3024521678f5c625559964142020-02-19 4:29:20821 days 6 hrs ago 0xcfd027019f9ff28ac3db417b630c7a21881090fb 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
0x1c16881b02168d3d14ee57ef8abf6bd8936c3741baaf29862e16c329779207fb59963952020-02-19 4:24:35821 days 6 hrs ago 0x02ee9aebb75470d517bff722d36762d2b231539c 0xbc5b9040fee0cca807a0d6e35f535a1b8e609c140 Ether
0x1c16881b02168d3d14ee57ef8abf6bd8936c3741baaf29862e16c329779207fb59963952020-02-19 4:24:35821 days 6 hrs ago 0xcfd027019f9ff28ac3db417b630c7a21881090fb 0x02ee9aebb75470d517bff722d36762d2b231539c0 Ether
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
DmmController

Compiler Version
v0.5.13+commit.5b0b510c

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-02-19
*/

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

pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
 * the optional functions; to access them see {ERC20Detailed}.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

// File: @openzeppelin/contracts/math/SafeMath.sol

pragma solidity ^0.5.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     *
     * _Available since v2.4.0._
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, errorMessage);
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return mod(a, b, "SafeMath: modulo by zero");
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts with custom message when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     *
     * _Available since v2.4.0._
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

// File: @openzeppelin/contracts/utils/Address.sol

pragma solidity ^0.5.5;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * This test is non-exhaustive, and there may be false-negatives: during the
     * execution of a contract's constructor, its address will be reported as
     * not containing a contract.
     *
     * IMPORTANT: It is unsafe to assume that an address for which this
     * function returns false is an externally-owned account (EOA) and not a
     * contract.
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies in extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
        // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
        // for accounts without code, i.e. `keccak256('')`
        bytes32 codehash;
        bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
        // solhint-disable-next-line no-inline-assembly
        assembly { codehash := extcodehash(account) }
        return (codehash != 0x0 && codehash != accountHash);
    }

    /**
     * @dev Converts an `address` into `address payable`. Note that this is
     * simply a type cast: the actual underlying value is not changed.
     *
     * _Available since v2.4.0._
     */
    function toPayable(address account) internal pure returns (address payable) {
        return address(uint160(account));
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     *
     * _Available since v2.4.0._
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

// File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol

pragma solidity ^0.5.0;




/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using SafeMath for uint256;
    using Address for address;

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

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

    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

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

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
        callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves.

        // A Solidity high level call has three parts:
        //  1. The target address is checked to verify it contains contract code
        //  2. The call itself is made, and success asserted
        //  3. The return value is decoded, which in turn checks the size of the returned data.
        // solhint-disable-next-line max-line-length
        require(address(token).isContract(), "SafeERC20: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = address(token).call(data);
        require(success, "SafeERC20: low-level call failed");

        if (returndata.length > 0) { // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: @openzeppelin/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 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, which should be used via inheritance.
    constructor () internal { }
    // solhint-disable-previous-line no-empty-blocks

    function _msgSender() internal view returns (address payable) {
        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: @openzeppelin/contracts/ownership/Ownable.sol

pragma solidity ^0.5.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
contract Ownable is Context {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () internal {
        _owner = _msgSender();
        emit OwnershipTransferred(address(0), _owner);
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(isOwner(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Returns true if the caller is the current owner.
     */
    function isOwner() public view returns (bool) {
        return _msgSender() == _owner;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

// File: contracts/constants/CommonConstants.sol

pragma solidity ^0.5.0;

contract CommonConstants {

    uint public constant EXCHANGE_RATE_BASE_RATE = 1e18;

}

// File: contracts/utils/Blacklistable.sol

pragma solidity ^0.5.0;


/**
 * @dev Allows accounts to be blacklisted by the owner of the contract.
 *
 *  Taken from USDC's contract for blacklisting certain addresses from owning and interacting with the token.
 */
contract Blacklistable is Ownable {

    string public constant BLACKLISTED = "BLACKLISTED";

    mapping(address => bool) internal blacklisted;

    event Blacklisted(address indexed account);
    event UnBlacklisted(address indexed account);
    event BlacklisterChanged(address indexed newBlacklister);

    /**
     * @dev Throws if called by any account other than the creator of this contract
    */
    modifier onlyBlacklister() {
        require(msg.sender == owner(), "MUST_BE_BLACKLISTER");
        _;
    }

    /**
     * @dev Throws if `account` is blacklisted
     *
     * @param account The address to check
    */
    modifier notBlacklisted(address account) {
        require(blacklisted[account] == false, BLACKLISTED);
        _;
    }

    /**
     * @dev Checks if `account` is blacklisted. Reverts with `BLACKLISTED` if blacklisted.
    */
    function checkNotBlacklisted(address account) public view {
        require(!blacklisted[account], BLACKLISTED);
    }

    /**
     * @dev Checks if `account` is blacklisted
     *
     * @param account The address to check
    */
    function isBlacklisted(address account) public view returns (bool) {
        return blacklisted[account];
    }

    /**
     * @dev Adds `account` to blacklist
     *
     * @param account The address to blacklist
    */
    function blacklist(address account) public onlyBlacklister {
        blacklisted[account] = true;
        emit Blacklisted(account);
    }

    /**
     * @dev Removes account from blacklist
     *
     * @param account The address to remove from the blacklist
    */
    function unBlacklist(address account) public onlyBlacklister {
        blacklisted[account] = false;
        emit UnBlacklisted(account);
    }

}

// File: contracts/impl/DmmBlacklistable.sol

pragma solidity ^0.5.0;


contract DmmBlacklistable is Blacklistable {

    constructor() public {
    }

}

// File: contracts/interfaces/ICollateralValuator.sol

pragma solidity ^0.5.0;

interface ICollateralValuator {

    event CollateralValueUpdated(uint newCollateralValue);

    /**
     * @dev Gets the DMM ecosystem's collateral's value from Chainlink's on-chain data feed.
     *
     * @return The value of the ecosystem's collateral, as a number with 18 decimals
     */
    function getCollateralValue() external view returns (uint);

}

// File: contracts/interfaces/InterestRateInterface.sol

pragma solidity ^0.5.0;

interface InterestRateInterface {

    /**
      * @dev Returns the current interest rate for the given DMMA and corresponding total supply & active supply
      *
      * @param dmmTokenId The DMMA whose interest should be retrieved
      * @param totalSupply The total supply fot he DMM token
      * @param activeSupply The supply that's currently being lent by users
      * @return The interest rate in APY, which is a number with 18 decimals
      */
    function getInterestRate(uint dmmTokenId, uint totalSupply, uint activeSupply) external view returns (uint);

}

// File: @openzeppelin/contracts/access/Roles.sol

pragma solidity ^0.5.0;

/**
 * @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(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        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), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

// File: @openzeppelin/contracts/access/roles/PauserRole.sol

pragma solidity ^0.5.0;



contract PauserRole is Context {
    using Roles for Roles.Role;

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

    Roles.Role private _pausers;

    constructor () internal {
        _addPauser(_msgSender());
    }

    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 renouncePauser() public {
        _removePauser(_msgSender());
    }

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

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

// File: @openzeppelin/contracts/lifecycle/Pausable.sol

pragma solidity ^0.5.0;



/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
contract Pausable is Context, PauserRole {
    /**
     * @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.
     */
    constructor () internal {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function isPaused() 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/IDmmController.sol

pragma solidity ^0.5.0;




interface IDmmController {

    event TotalSupplyIncreased(uint oldTotalSupply, uint newTotalSupply);
    event TotalSupplyDecreased(uint oldTotalSupply, uint newTotalSupply);

    event AdminDeposit(address indexed admin, uint amount);
    event AdminWithdraw(address indexed admin, uint amount);

    function blacklistable() external view returns (Blacklistable);

    /**
     * @dev Disables the corresponding DMMA from minting new tokens. This allows the market to close over time, since
     *      users are only able to redeem tokens.
     *
     * @param underlyingToken   The token that should be wrapped to create a new DMMA
     * @param symbol            The symbol of the new DMMA, IE DAI or USDC
     * @param decimals          The number of decimals of the underlying token, and therefore the number for this DMMA.
     */
    function addMarket(
        address underlyingToken,
        string calldata symbol,
        string calldata name,
        uint8 decimals,
        uint minMintAmount,
        uint minRedeemAmount,
        uint totalSupply
    ) external;

    /**
     * @dev Enables the corresponding DMMA to allow minting new tokens.
     *
     * @param dmmTokenId  The DMMA that should be enabled.
     */
    function enableMarket(uint dmmTokenId) external;

    /**
     * @dev Disables the corresponding DMMA from minting new tokens. This allows the market to close over time, since
     *      users are only able to redeem tokens.
     *
     * @param dmmTokenId  The DMMA that should be disabled.
     */
    function disableMarket(uint dmmTokenId) external;

    /**
     * @dev Sets a new contract that implements the `InterestRateInterface` interface.
     *
     * @param newInterestRateInterface  The new contract that implements the `InterestRateInterface` interface.
     */
    function setInterestRateInterface(address newInterestRateInterface) external;

    /**
     * @dev Sets a new contract that implements the `ICollateralizationGetter` interface.
     *
     * @param newCollateralValuator The new contract that implements the `ICollateralValuator` interface.
     */
    function setCollateralValuator(address newCollateralValuator) external;

    /**
     * @dev Sets a new contract that implements the `UnderlyingTokenValuator` interface
     *
     * @param newUnderlyingTokenValuator The new contract that implements the `UnderlyingTokenValuator` interface
     */
    function setUnderlyingTokenValuator(address newUnderlyingTokenValuator) external;

    /**
     * @dev Allows the owners of the DMM Ecosystem to withdraw funds from a DMMA. These withdrawn funds are then
     *      allocated to real-world assets that will be used to pay interest into the DMMA.
     *
     * @param newMinCollateralization   The new min collateralization (with 18 decimals) at which the DMME must be in
     *                                  order to add to the total supply of DMM.
     */
    function setMinCollateralization(uint newMinCollateralization) external;

    /**
     * @dev Allows the owners of the DMM Ecosystem to withdraw funds from a DMMA. These withdrawn funds are then
     *      allocated to real-world assets that will be used to pay interest into the DMMA.
     *
     * @param newMinReserveRatio   The new ratio (with 18 decimals) that is used to enforce a certain percentage of assets
     *                          are kept in each DMMA.
     */
    function setMinReserveRatio(uint newMinReserveRatio) external;

    /**
     * @dev Increases the max supply for the provided `dmmTokenId` by `amount`. This call reverts with
     *      INSUFFICIENT_COLLATERAL if there isn't enough collateral in the Chainlink contract to cover the controller's
     *      requirements for minimum collateral.
     */
    function increaseTotalSupply(uint dmmTokenId, uint amount) external;

    /**
     * @dev Increases the max supply for the provided `dmmTokenId` by `amount`.
     */
    function decreaseTotalSupply(uint dmmTokenId, uint amount) external;

    /**
     * @dev Allows the owners of the DMM Ecosystem to withdraw funds from a DMMA. These withdrawn funds are then
     *      allocated to real-world assets that will be used to pay interest into the DMMA.
     *
     * @param dmmTokenId The ID of the DMM token whose underlying will be funded.
     * @param underlyingAmount  The amount underlying the DMM token that will be deposited into the DMMA.
     */
    function adminWithdrawFunds(uint dmmTokenId, uint underlyingAmount) external;

    /**
     * @dev Allows the owners of the DMM Ecosystem to deposit funds into a DMMA. These funds are used to disburse
     *      interest payments and add more liquidity to the specific market.
     *
     * @param dmmTokenId The ID of the DMM token whose underlying will be funded.
     * @param underlyingAmount  The amount underlying the DMM token that will be deposited into the DMMA.
     */
    function adminDepositFunds(uint dmmTokenId, uint underlyingAmount) external;

    /**
     * @dev Gets the collateralization of the system by dividing the total value of all the assets by the value of the
     *      total supplies of all the markets.
     *
     * @return  The total collateralization of the system, as a number with 18 decimals. For example
     *          `1010000000000000000` is 101% or 1.01.
     */
    function getTotalCollateralization() external view returns (uint);

    /**
     * @dev Gets the collateralization of the system by dividing the total value of all the assets by the value of the
     *      active supplies of the DMM tokens. In this case, active supply means the number of DMM tokens that are NOT
     *      in the contract, and therefore there is an obligation to pay interest to those token holders.
     *
     * @return  The active collateralization of the system, as a number with 18 decimals. For example
     *          `1010000000000000000` is 101% or 1.01.
     */
    function getActiveCollateralization() external view returns (uint);

    /**
     * @dev Gets the interest rate from the underlying token, IE DAI or USDC.
     *
     * @return  The current interest rate, represented using 18 decimals. Meaning `65000000000000000` is 6.5% APY or
     *          0.065.
     */
    function getInterestRateByUnderlyingTokenAddress(address underlyingToken) external view returns (uint);

    /**
     * @dev Gets the interest rate from the DMM token, IE DMM: DAI or DMM: USDC.
     *
     * @return  The current interest rate, represented using 18 decimals. Meaning, `65000000000000000` is 6.5% APY or
     *          0.065.
     */
    function getInterestRateByDmmTokenId(uint dmmTokenId) external view returns (uint);

    /**
     * @dev Gets the interest rate from the DMM token, IE DMM: DAI or DMM: USDC.
     *
     * @return  The current interest rate, represented using 18 decimals. Meaning, `65000000000000000` is 6.5% APY or
     *          0.065.
     */
    function getInterestRateByDmmTokenAddress(address dmmToken) external view returns (uint);

    /**
     * @dev Gets the exchange rate from the underlying to the DMM token, such that
     *      `DMM: Token = underlying / exchangeRate`
     *
     * @return  The current exchange rate, represented using 18 decimals. Meaning, `200000000000000000` is 0.2.
     */
    function getExchangeRateByUnderlying(address underlyingToken) external view returns (uint);

    /**
     * @dev Gets the exchange rate from the underlying to the DMM token, such that
     *      `DMM: Token = underlying / exchangeRate`
     *
     * @return  The current exchange rate, represented using 18 decimals. Meaning, `200000000000000000` is 0.2.
     */
    function getExchangeRate(address dmmToken) external view returns (uint);

    /**
     * @dev Gets the DMM token for the provided underlying token. For example, sending DAI returns DMM: DAI.
     */
    function getDmmTokenForUnderlying(address underlyingToken) external view returns (address);

    /**
     * @dev Gets the underlying token for the provided DMM token. For example, sending DMM: DAI returns DAI.
     */
    function getUnderlyingTokenForDmm(address dmmToken) external view returns (address);

    /**
     * @return True if the market is enabled for this DMMA or false if it is not enabled.
     */
    function isMarketEnabledByDmmTokenId(uint dmmTokenId) external view returns (bool);

    /**
     * @return True if the market is enabled for this DMM token (IE DMM: DAI) or false if it is not enabled.
     */
    function isMarketEnabledByDmmTokenAddress(address dmmToken) external view returns (bool);

    /**
     * @return True if the market is enabled for this underlying token (IE DAI) or false if it is not enabled.
     */
    function getTokenIdFromDmmTokenAddress(address dmmTokenAddress) external view returns (uint);

}

// File: contracts/interfaces/IDmmToken.sol

pragma solidity ^0.5.0;

/**
 * Basically an interface except, contains the implementation of the type-hashes for offline signature generation.
 *
 * This contract contains the signatures and documentation for all publicly-implemented functions in the DMM token.
 */
interface IDmmToken {

    /*****************
     * Events
     */

    event Mint(address indexed minter, address indexed recipient, uint amount);
    event Redeem(address indexed redeemer, address indexed recipient, uint amount);
    event FeeTransfer(address indexed owner, address indexed recipient, uint amount);

    event TotalSupplyIncreased(uint oldTotalSupply, uint newTotalSupply);
    event TotalSupplyDecreased(uint oldTotalSupply, uint newTotalSupply);

    event OffChainRequestValidated(address indexed owner, address indexed feeRecipient, uint nonce, uint expiry, uint feeAmount);

    /*****************
     * Functions
     */

    /**
     * @dev The controller that deployed this parent
     */
    function controller() external view returns (address);

    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei.
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() external view returns (uint8);

    /**
     * @return  The min amount that can be minted in a single transaction. This amount corresponds with the number of
     *          decimals that this token has.
     */
    function minMintAmount() external view returns (uint);

    /**
     * @return  The min amount that can be redeemed from DMM to underlying in a single transaction. This amount
     *          corresponds with the number of decimals that this token has.
     */
    function minRedeemAmount() external view returns (uint);

    /**
      * @dev The amount of DMM that is in circulation (outside of this contract)
      */
    function activeSupply() external view returns (uint);

    /**
     * @dev Attempts to add `amount` to the total supply by issuing the tokens to this contract. This call fires a
     *      Transfer event from the 0x0 address to this contract.
     */
    function increaseTotalSupply(uint amount) external;

    /**
     * @dev Attempts to remove `amount` from the total supply by destroying those tokens that are held in this
     *      contract. This call reverts with TOO_MUCH_ACTIVE_SUPPLY if `amount` is not held in this contract.
     */
    function decreaseTotalSupply(uint amount) external;

    /**
     * @dev An admin function that lets the ecosystem's organizers deposit the underlying token around which this DMMA
     *      wraps to this contract. This is used to replenish liquidity and after interest payouts are made from the
     *      real-world assets.
     */
    function depositUnderlying(uint underlyingAmount) external returns (bool);

    /**
     * @dev An admin function that lets the ecosystem's organizers withdraw the underlying token around which this DMMA
     *      wraps from this contract. This is used to withdraw deposited tokens, to be allocated to real-world assets
     *      that produce income streams and can cover interest payments.
     */
    function withdrawUnderlying(uint underlyingAmount) external returns (bool);

    /**
      * @dev The timestamp at which the exchange rate was last updated.
      */
    function exchangeRateLastUpdatedTimestamp() external view returns (uint);

    /**
      * @dev The timestamp at which the exchange rate was last updated.
      */
    function exchangeRateLastUpdatedBlockNumber() external view returns (uint);

    /**
     * @dev The exchange rate from underlying to DMM. Invert this number to go from DMM to underlying. This number
     *      has 18 decimals.
     */
    function getCurrentExchangeRate() external view returns (uint);

    /**
     * @dev The current nonce of the provided `owner`. This `owner` should be the signer for any gasless transactions.
     */
    function nonceOf(address owner) external view returns (uint);

    /**
     * @dev Transfers the token around which this DMMA wraps from msg.sender to the DMMA contract. Then, sends the
     *      corresponding amount of DMM to the msg.sender. Note, this call reverts with INSUFFICIENT_DMM_LIQUIDITY if
     *      there is not enough DMM available to be minted.
     *
     * @param amount The amount of underlying to send to this DMMA for conversion to DMM.
     * @return The amount of DMM minted.
     */
    function mint(uint amount) external returns (uint);

    /**
     * @dev Transfers the token around which this DMMA wraps from sender to the DMMA contract. Then, sends the
     *      corresponding amount of DMM to recipient. Note, an allowance must be set for sender for the underlying
     *      token that is at least of size `amount` / `exchangeRate`. This call reverts with INSUFFICIENT_DMM_LIQUIDITY if
     *      there is not enough DMM available to be minted.
     *
     * @param owner         The address that is sending the `underlyingAmount` underlying token.
     * @param recipient     The address the will receive the newly minted DMM.
     * @param amount        The amount of underlying to send to this DMMA for conversion to DMM.
     * @return The amount of DMM minted.
     */
    function mintFrom(address owner, address recipient, uint amount) external returns (uint);

    /**
     * @dev Transfers the token around which this DMMA wraps from sender to the DMMA contract. Then, sends the
     *      corresponding amount of DMM to recipient. Note, an allowance must be set for sender for the underlying
     *      token that is at least of size `amount` / `exchangeRate`. This call reverts with INSUFFICIENT_DMM_LIQUIDITY
     *      if there is not enough DMM available to be minted. See #MINT_TYPE_HASH. This function gives the `owner` the
     *      illusion of committing a gasless transaction, allowing a relayer to broadcast the transaction and
     *      potentially collect a fee for doing so.
     *
     * @param owner         The user that signed the off-chain message.
     * @param recipient     The address that will receive the newly-minted DMM tokens.
     * @param nonce         An auto-incrementing integer that prevents replay attacks. See #nonceOf(address) to get the
     *                      owner's current nonce.
     * @param expiry        The timestamp, in unix seconds, at which the signed off-chain message expires. A value of 0
     *                      means there is no expiration.
     * @param amount        The amount of underlying that should be minted by `owner` and sent to `recipient`.
     * @param feeAmount     The amount of DMM to be sent to feeRecipient for sending this transaction on behalf of
     *                      owner. Can be 0, which means the user won't be charged a fee. Must be <= `amount`.
     * @param feeRecipient  The address that should receive the fee. A value of 0x0 will send the fees to `msg.sender`.
     *                      Note, no fees are sent if the feeAmount is 0, regardless of what feeRecipient is.
     * @param v             The ECDSA V parameter.
     * @param r             The ECDSA R parameter.
     * @param s             The ECDSA S parameter.
     * @return  The amount of DMM minted.
     */
    function mintFromGaslessRequest(
        address owner,
        address recipient,
        uint nonce,
        uint expiry,
        uint amount,
        uint feeAmount,
        address feeRecipient,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint);

    /**
     * @dev Transfers DMM from msg.sender to this DMMA contract. Then, sends the corresponding amount of token around
     *      which this DMMA wraps to the msg.sender. Note, this call reverts with INSUFFICIENT_UNDERLYING_LIQUIDITY if
     *      there is not enough DMM available to be redeemed.
     *
     * @param amount    The amount of DMM to be transferred from msg.sender to this DMMA.
     * @return          The amount of underlying redeemed.
     */
    function redeem(uint amount) external returns (uint);

    /**
     * @dev Transfers DMM from `sender` to this DMMA contract. Then, sends the corresponding amount of token around
     *      which this DMMA wraps to `recipient`. Note, an allowance must be set for sender for DMM that is at least of
     *      size `amount`. This call reverts with INSUFFICIENT_UNDERLYING_LIQUIDITY if there is not enough underlying
     *      available to be redeemed.
     *
     * @param owner         The address that is sending the `underlyingAmount` underlying token.
     * @param recipient     The address the will receive the newly redeemed DMM.
     * @param amount        The amount of DMM token to be redeemed for the recipient.
     * @return The amount of underlying redeemed.
     */
    function redeemFrom(address owner, address recipient, uint amount) external returns (uint);

    /**
     * @dev Transfers DMM from `owner` to the DMMA contract. Then, sends the corresponding amount of token around which
     *      this DMMA wraps to `recipient`. Note, an allowance must be set for sender for the underlying
     *      token that is at least of size `amount`. This call reverts with INSUFFICIENT_UNDERLYING_LIQUIDITY
     *      if there is not enough underlying available to be redeemed. See #REDEEM_TYPE_HASH. This function gives the
     *      `owner` the illusion of committing a gasless transaction, allowing a relayer to broadcast the transaction
     *      and potentially collect a fee for doing so.
     *
     * @param owner         The user that signed the off-chain message.
     * @param recipient     The address that will receive the newly-redeemed DMM tokens.
     * @param nonce         An auto-incrementing integer that prevents replay attacks. See #nonceOf(address) to get the
     *                      owner's current nonce.
     * @param expiry        The timestamp, in unix seconds, at which the signed off-chain message expires. A value of 0
     *                      means there is no expiration.
     * @param amount        The amount of DMM that should be redeemed for `owner` and sent to `recipient`.
     * @param feeAmount     The amount of DMM to be sent to feeRecipient for sending this transaction on behalf of
     *                      owner. Can be 0, which means the user won't be charged a fee. Must be <= `amount`
     * @param feeRecipient  The address that should receive the fee. A value of 0x0 will send the fees to `msg.sender`.
     *                      Note, no fees are sent if the feeAmount is 0, regardless of what feeRecipient is.
     * @param v             The ECDSA V parameter.
     * @param r             The ECDSA R parameter.
     * @param s             The ECDSA S parameter.
     * @return  The amount of underlying redeemed.
     */
    function redeemFromGaslessRequest(
        address owner,
        address recipient,
        uint nonce,
        uint expiry,
        uint amount,
        uint feeAmount,
        address feeRecipient,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint);

    /**
     * @dev Sets an allowance for owner with spender using an offline-generated signature. This function allows a
     *      relayer to send the transaction, giving the owner the illusion of committing a gasless transaction. See
     *      #PERMIT_TYPEHASH.
     *
     * @param owner         The user that signed the off-chain message.
     * @param spender       The contract/wallet that can spend DMM tokens on behalf of owner.
     * @param nonce         An auto-incrementing integer that prevents replay attacks. See #nonceOf(address) to get the
     *                      owner's current nonce.
     * @param expiry        The timestamp, in unix seconds, at which the signed off-chain message expires. A value of 0
     *                      means there is no expiration.
     * @param allowed       True if the spender can spend funds on behalf of owner or false to revoke this privilege.
     * @param feeAmount     The amount of DMM to be sent to feeRecipient for sending this transaction on behalf of
     *                      owner. Can be 0, which means the user won't be charged a fee.
     * @param feeRecipient  The address that should receive the fee. A value of 0x0 will send the fees to `msg.sender`.
     *                      Note, no fees are sent if the feeAmount is 0, regardless of what feeRecipient is.
     * @param v             The ECDSA V parameter.
     * @param r             The ECDSA R parameter.
     * @param s             The ECDSA S parameter.
     */
    function permit(
        address owner,
        address spender,
        uint nonce,
        uint expiry,
        bool allowed,
        uint feeAmount,
        address feeRecipient,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Transfers DMM from the `owner` to `recipient` using an offline-generated signature. This function allows a
     *      relayer to send the transaction, giving the owner the illusion of committing a gasless transaction. See
     *      #TRANSFER_TYPEHASH. This function gives the `owner` the illusion of committing a gasless transaction,
     *      allowing a relayer to broadcast the transaction and potentially collect a fee for doing so.
     *
     * @param owner         The user that signed the off-chain message and originator of the transfer.
     * @param recipient     The address that will receive the transferred DMM tokens.
     * @param nonce         An auto-incrementing integer that prevents replay attacks. See #nonceOf(address) to get the
     *                      owner's current nonce.
     * @param expiry        The timestamp, in unix seconds, at which the signed off-chain message expires. A value of 0
     *                      means there is no expiration.
     * @param amount        The amount of DMM that should be transferred from `owner` and sent to `recipient`.
     * @param feeAmount     The amount of DMM to be sent to feeRecipient for sending this transaction on behalf of
     *                      owner. Can be 0, which means the user won't be charged a fee.
     * @param feeRecipient  The address that should receive the fee. A value of 0x0 will send the fees to `msg.sender`.
     *                      Note, no fees are sent if the feeAmount is 0, regardless of what feeRecipient is.
     * @param v             The ECDSA V parameter.
     * @param r             The ECDSA R parameter.
     * @param s             The ECDSA S parameter.
     * @return              True if the transfer was successful or false if it failed.
     */
    function transferFromGaslessRequest(
        address owner,
        address recipient,
        uint nonce,
        uint expiry,
        uint amount,
        uint feeAmount,
        address feeRecipient,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

}

// File: contracts/interfaces/IUnderlyingTokenValuator.sol

pragma solidity ^0.5.0;

interface IUnderlyingTokenValuator {

    /**
      * @dev Gets the tokens value in terms of USD.
      *
      * @return The value of the `amount` of `token`, as a number with 18 decimals
      */
    function getTokenValue(address token, uint amount) external view returns (uint);

}

// File: contracts/interfaces/IDmmTokenFactory.sol

pragma solidity ^0.5.0;


interface IDmmTokenFactory {

    function deployToken(
        string calldata symbol,
        string calldata name,
        uint8 decimals,
        uint minMintAmount,
        uint minRedeemAmount,
        uint totalSupply,
        address controller
    ) external returns (IDmmToken);

}

// File: contracts/impl/DmmController.sol

pragma solidity ^0.5.0;













contract DmmController is Pausable, CommonConstants, IDmmController, Ownable {

    using SafeMath for uint256;
    using SafeERC20 for IERC20;

    /********************************
     * Events
     */

    event InterestRateInterfaceChanged(address previousInterestRateInterface, address newInterestRateInterface);
    event CollateralValuatorChanged(address previousCollateralValuator, address newCollateralValuator);
    event UnderlyingTokenValuatorChanged(address previousUnderlyingTokenValuator, address newUnderlyingTokenValuator);

    event MarketAdded(uint indexed dmmTokenId, address indexed dmmToken, address indexed underlyingToken);

    event DisableMarket(uint indexed dmmTokenId);
    event EnableMarket(uint indexed dmmTokenId);

    event MinCollateralizationChanged(uint previousMinCollateralization, uint newMinCollateralization);
    event MinReserveRatioChanged(uint previousMinReserveRatio, uint newMinReserveRatio);

    /********************************
     * Controller Fields
     */

    DmmBlacklistable public dmmBlacklistable;
    InterestRateInterface public interestRateInterface;
    ICollateralValuator public collateralValuator;
    IUnderlyingTokenValuator public underlyingTokenValuator;
    IDmmTokenFactory public dmmTokenFactory;
    IDmmTokenFactory public dmmEtherFactory;
    uint public minCollateralization;
    uint public minReserveRatio;
    address public wethToken;

    /********************************
     * DMM Account Management
     */

    mapping(uint => address) public dmmTokenIdToDmmTokenAddressMap;
    mapping(address => uint) public dmmTokenAddressToDmmTokenIdMap;

    mapping(address => uint) public underlyingTokenAddressToDmmTokenIdMap;
    mapping(uint => address) public dmmTokenIdToUnderlyingTokenAddressMap;

    mapping(uint => bool) public dmmTokenIdToIsDisabledMap;
    uint[] public dmmTokenIds;

    /********************************
     * Constants
     */

    uint public constant COLLATERALIZATION_BASE_RATE = 1e18;
    uint public constant MIN_RESERVE_RATIO_BASE_RATE = 1e18;

    constructor(
        address _interestRateInterface,
        address _collateralValuator,
        address _underlyingTokenValuator,
        address _dmmEtherFactory,
        address _dmmTokenFactory,
        address _dmmBlacklistable,
        uint256 _minCollateralization,
        uint256 _minReserveRatio,
        address _wethToken
    ) public {
        interestRateInterface = InterestRateInterface(_interestRateInterface);
        collateralValuator = ICollateralValuator(_collateralValuator);
        underlyingTokenValuator = IUnderlyingTokenValuator(_underlyingTokenValuator);
        dmmTokenFactory = IDmmTokenFactory(_dmmTokenFactory);
        dmmEtherFactory = IDmmTokenFactory(_dmmEtherFactory);
        dmmBlacklistable = DmmBlacklistable(_dmmBlacklistable);
        minCollateralization = _minCollateralization;
        minReserveRatio = _minReserveRatio;
        wethToken = _wethToken;
    }

    /*****************
     * Modifiers
     */

    modifier whenNotPaused() {
        require(!isPaused(), "ECOSYSTEM_PAUSED");
        _;
    }

    modifier whenPaused() {
        require(isPaused(), "ECOSYSTEM_NOT_PAUSED");
        _;
    }

    modifier checkTokenExists(uint dmmTokenId) {
        require(dmmTokenIdToDmmTokenAddressMap[dmmTokenId] != address(0x0), "TOKEN_DOES_NOT_EXIST");
        _;
    }

    /**********************
     * Public Functions
     */

    function transferOwnership(address newOwner) public onlyOwner {
        super.transferOwnership(newOwner);
        addPauser(newOwner);
    }

    function blacklistable() public view returns (Blacklistable) {
        return dmmBlacklistable;
    }

    function addMarket(
        address underlyingToken,
        string memory symbol,
        string memory name,
        uint8 decimals,
        uint minMintAmount,
        uint minRedeemAmount,
        uint totalSupply
    ) public onlyOwner {
        require(underlyingTokenAddressToDmmTokenIdMap[underlyingToken] == 0, "TOKEN_ALREADY_EXISTS");

        // Start the IDs at 1. Zero is reserved for the empty case when it doesn't exist.
        uint dmmTokenId = dmmTokenIds.length + 1;
        address controller = address(this);
        IDmmToken dmmToken;

        if (underlyingToken == wethToken) {
            dmmToken = dmmEtherFactory.deployToken(
                symbol,
                name,
                decimals,
                minMintAmount,
                minRedeemAmount,
                totalSupply,
                controller
            );
        } else {
            dmmToken = dmmTokenFactory.deployToken(
                symbol,
                name,
                decimals,
                minMintAmount,
                minRedeemAmount,
                totalSupply,
                controller
            );
        }

        address dmmTokenAddress = address(dmmToken);

        // Update the maps
        dmmTokenIdToDmmTokenAddressMap[dmmTokenId] = dmmTokenAddress;
        dmmTokenAddressToDmmTokenIdMap[dmmTokenAddress] = dmmTokenId;
        underlyingTokenAddressToDmmTokenIdMap[underlyingToken] = dmmTokenId;
        dmmTokenIdToUnderlyingTokenAddressMap[dmmTokenId] = underlyingToken;

        // Misc. Structures
        dmmTokenIdToIsDisabledMap[dmmTokenId] = false;
        dmmTokenIds.push(dmmTokenId);

        emit MarketAdded(dmmTokenId, dmmTokenAddress, underlyingToken);
    }

    function enableMarket(uint dmmTokenId) public checkTokenExists(dmmTokenId) whenNotPaused onlyOwner {
        require(dmmTokenIdToIsDisabledMap[dmmTokenId], "MARKET_ALREADY_ENABLED");
        dmmTokenIdToIsDisabledMap[dmmTokenId] = false;
        emit EnableMarket(dmmTokenId);
    }

    function disableMarket(uint dmmTokenId) public checkTokenExists(dmmTokenId) whenNotPaused onlyOwner {
        require(!dmmTokenIdToIsDisabledMap[dmmTokenId], "MARKET_ALREADY_DISABLED");
        dmmTokenIdToIsDisabledMap[dmmTokenId] = true;
        emit DisableMarket(dmmTokenId);
    }

    function setInterestRateInterface(address newInterestRateInterface) public whenNotPaused onlyOwner {
        address oldInterestRateInterface = address(interestRateInterface);
        interestRateInterface = InterestRateInterface(newInterestRateInterface);
        emit InterestRateInterfaceChanged(oldInterestRateInterface, address(interestRateInterface));
    }

    function setCollateralValuator(address newCollateralValuator) public whenNotPaused onlyOwner {
        address oldCollateralValuator = address(collateralValuator);
        collateralValuator = ICollateralValuator(newCollateralValuator);
        emit CollateralValuatorChanged(oldCollateralValuator, address(collateralValuator));
    }

    function setUnderlyingTokenValuator(address newUnderlyingTokenValuator) public whenNotPaused onlyOwner {
        address oldUnderlyingTokenValuator = address(underlyingTokenValuator);
        underlyingTokenValuator = IUnderlyingTokenValuator(newUnderlyingTokenValuator);
        emit UnderlyingTokenValuatorChanged(oldUnderlyingTokenValuator, address(underlyingTokenValuator));
    }

    function setMinCollateralization(uint newMinCollateralization) public whenNotPaused onlyOwner {
        uint oldMinCollateralization = minCollateralization;
        minCollateralization = newMinCollateralization;
        emit MinCollateralizationChanged(oldMinCollateralization, minCollateralization);
    }

    function setMinReserveRatio(uint newMinReserveRatio) public whenNotPaused onlyOwner {
        uint oldMinReserveRatio = minReserveRatio;
        minReserveRatio = newMinReserveRatio;
        emit MinReserveRatioChanged(oldMinReserveRatio, minReserveRatio);
    }

    function increaseTotalSupply(
        uint dmmTokenId,
        uint amount
    ) public checkTokenExists(dmmTokenId) whenNotPaused onlyOwner {
        IDmmToken(dmmTokenIdToDmmTokenAddressMap[dmmTokenId]).increaseTotalSupply(amount);
        require(getTotalCollateralization() >= minCollateralization, "INSUFFICIENT_COLLATERAL");
    }

    function decreaseTotalSupply(
        uint dmmTokenId,
        uint amount
    ) public checkTokenExists(dmmTokenId) whenNotPaused onlyOwner {
        IDmmToken(dmmTokenIdToDmmTokenAddressMap[dmmTokenId]).decreaseTotalSupply(amount);
    }

    function adminWithdrawFunds(
        uint dmmTokenId,
        uint256 underlyingAmount
    ) public checkTokenExists(dmmTokenId) whenNotPaused onlyOwner {
        // Attempt to pull from the DMM contract into this contract, then send from this contract to sender.
        IDmmToken token = IDmmToken(dmmTokenIdToDmmTokenAddressMap[dmmTokenId]);
        token.withdrawUnderlying(underlyingAmount);
        IERC20 underlyingToken = IERC20(dmmTokenIdToUnderlyingTokenAddressMap[dmmTokenId]);
        underlyingToken.safeTransfer(_msgSender(), underlyingAmount);

        // This is the amount owed by the system in terms of underlying
        uint totalOwedAmount = token.activeSupply().mul(token.getCurrentExchangeRate()).div(EXCHANGE_RATE_BASE_RATE);
        uint underlyingBalance = IERC20(dmmTokenIdToUnderlyingTokenAddressMap[dmmTokenId]).balanceOf(address(token));

        // IE if we owe 100 and have an underlying balance of 10 --> reserve ratio is 0.1
        uint actualReserveRatio = underlyingBalance.mul(MIN_RESERVE_RATIO_BASE_RATE).div(totalOwedAmount);

        require(actualReserveRatio >= minReserveRatio, "INSUFFICIENT_LEFTOVER_RESERVES");

        emit AdminWithdraw(_msgSender(), underlyingAmount);
    }

    function adminDepositFunds(
        uint dmmTokenId,
        uint256 underlyingAmount
    ) public checkTokenExists(dmmTokenId) whenNotPaused onlyOwner {
        // Attempt to pull from the sender into this contract, then have the DMM token pull from here.
        IERC20 underlyingToken = IERC20(dmmTokenIdToUnderlyingTokenAddressMap[dmmTokenId]);
        underlyingToken.safeTransferFrom(_msgSender(), address(this), underlyingAmount);

        address dmmTokenAddress = dmmTokenIdToDmmTokenAddressMap[dmmTokenId];
        underlyingToken.approve(dmmTokenAddress, underlyingAmount);
        IDmmToken(dmmTokenAddress).depositUnderlying(underlyingAmount);
        emit AdminDeposit(_msgSender(), underlyingAmount);
    }

    function getTotalCollateralization() public view returns (uint) {
        uint totalLiabilities = 0;
        for (uint i = 0; i < dmmTokenIds.length; i++) {
            // IDs start at 1
            IDmmToken token = IDmmToken(dmmTokenIdToDmmTokenAddressMap[dmmTokenIds[i]]);
            uint underlyingValue = getSupplyValue(token, IERC20(address(token)).totalSupply());
            totalLiabilities = totalLiabilities.add(underlyingValue);
        }
        uint collateralValue = collateralValuator.getCollateralValue();
        return collateralValue.mul(COLLATERALIZATION_BASE_RATE).div(totalLiabilities);
    }

    function getActiveCollateralization() public view returns (uint) {
        uint totalLiabilities = 0;
        for (uint i = 0; i < dmmTokenIds.length; i++) {
            // IDs start at 1
            IDmmToken token = IDmmToken(dmmTokenIdToDmmTokenAddressMap[dmmTokenIds[i + 1]]);
            uint underlyingValue = getSupplyValue(token, token.activeSupply());
            totalLiabilities = totalLiabilities.add(underlyingValue);
        }
        uint collateralValue = collateralValuator.getCollateralValue();
        return collateralValue.mul(COLLATERALIZATION_BASE_RATE).div(totalLiabilities);
    }

    function getInterestRateByUnderlyingTokenAddress(address underlyingToken) public view returns (uint) {
        uint dmmTokenId = underlyingTokenAddressToDmmTokenIdMap[underlyingToken];
        return getInterestRateByDmmTokenId(dmmTokenId);
    }

    function getInterestRateByDmmTokenId(uint dmmTokenId) checkTokenExists(dmmTokenId) public view returns (uint) {
        address dmmToken = dmmTokenIdToDmmTokenAddressMap[dmmTokenId];
        uint totalSupply = IERC20(dmmToken).totalSupply();
        uint activeSupply = IDmmToken(dmmToken).activeSupply();
        return interestRateInterface.getInterestRate(dmmTokenId, totalSupply, activeSupply);
    }

    function getInterestRateByDmmTokenAddress(address dmmToken) public view returns (uint) {
        uint dmmTokenId = dmmTokenAddressToDmmTokenIdMap[dmmToken];
        require(dmmTokenId != 0, "TOKEN_DOES_NOT_EXIST");

        uint totalSupply = IERC20(dmmToken).totalSupply();
        uint activeSupply = IDmmToken(dmmToken).activeSupply();
        return interestRateInterface.getInterestRate(dmmTokenId, totalSupply, activeSupply);
    }

    function getExchangeRateByUnderlying(address underlyingToken) public view returns (uint) {
        address dmmToken = getDmmTokenForUnderlying(underlyingToken);
        return IDmmToken(dmmToken).getCurrentExchangeRate();
    }

    function getExchangeRate(address dmmToken) public view returns (uint) {
        uint dmmTokenId = dmmTokenAddressToDmmTokenIdMap[dmmToken];
        require(dmmTokenId != 0, "TOKEN_DOES_NOT_EXIST");

        return IDmmToken(dmmToken).getCurrentExchangeRate();
    }

    function getDmmTokenForUnderlying(address underlyingToken) public view returns (address) {
        uint dmmTokenId = underlyingTokenAddressToDmmTokenIdMap[underlyingToken];
        require(dmmTokenId != 0, "TOKEN_DOES_NOT_EXIST");

        return dmmTokenIdToDmmTokenAddressMap[dmmTokenId];
    }

    function getUnderlyingTokenForDmm(address dmmToken) public view returns (address) {
        uint dmmTokenId = dmmTokenAddressToDmmTokenIdMap[dmmToken];
        require(dmmTokenId != 0, "TOKEN_DOES_NOT_EXIST");

        return dmmTokenIdToUnderlyingTokenAddressMap[dmmTokenId];
    }

    function isMarketEnabledByDmmTokenId(uint dmmTokenId) checkTokenExists(dmmTokenId) public view returns (bool) {
        return !dmmTokenIdToIsDisabledMap[dmmTokenId];
    }

    function isMarketEnabledByDmmTokenAddress(address dmmToken) public view returns (bool) {
        uint dmmTokenId = dmmTokenAddressToDmmTokenIdMap[dmmToken];
        require(dmmTokenId != 0, "TOKEN_DOES_NOT_EXIST");

        return !dmmTokenIdToIsDisabledMap[dmmTokenId];
    }

    function getTokenIdFromDmmTokenAddress(address dmmToken) public view returns (uint) {
        uint dmmTokenId = dmmTokenAddressToDmmTokenIdMap[dmmToken];
        require(dmmTokenId != 0, "TOKEN_DOES_NOT_EXIST");

        return dmmTokenId;
    }

    function getDmmTokenIds() public view returns (uint[] memory) {
        return dmmTokenIds;
    }

    /**********************
     * Private Functions
     */

    function getSupplyValue(IDmmToken token, uint supply) private view returns (uint) {
        uint underlyingTokenAmount = supply.mul(token.getCurrentExchangeRate()).div(EXCHANGE_RATE_BASE_RATE);
        address underlyingToken = getUnderlyingTokenForDmm(address(token));
        return underlyingTokenValuator.getTokenValue(underlyingToken, underlyingTokenAmount);
    }

}

Contract ABI

[{"inputs":[{"internalType":"address","name":"_interestRateInterface","type":"address"},{"internalType":"address","name":"_collateralValuator","type":"address"},{"internalType":"address","name":"_underlyingTokenValuator","type":"address"},{"internalType":"address","name":"_dmmEtherFactory","type":"address"},{"internalType":"address","name":"_dmmTokenFactory","type":"address"},{"internalType":"address","name":"_dmmBlacklistable","type":"address"},{"internalType":"uint256","name":"_minCollateralization","type":"uint256"},{"internalType":"uint256","name":"_minReserveRatio","type":"uint256"},{"internalType":"address","name":"_wethToken","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousCollateralValuator","type":"address"},{"indexed":false,"internalType":"address","name":"newCollateralValuator","type":"address"}],"name":"CollateralValuatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"dmmTokenId","type":"uint256"}],"name":"DisableMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"dmmTokenId","type":"uint256"}],"name":"EnableMarket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousInterestRateInterface","type":"address"},{"indexed":false,"internalType":"address","name":"newInterestRateInterface","type":"address"}],"name":"InterestRateInterfaceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"dmmTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"dmmToken","type":"address"},{"indexed":true,"internalType":"address","name":"underlyingToken","type":"address"}],"name":"MarketAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousMinCollateralization","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinCollateralization","type":"uint256"}],"name":"MinCollateralizationChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"previousMinReserveRatio","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinReserveRatio","type":"uint256"}],"name":"MinReserveRatioChanged","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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":false,"internalType":"uint256","name":"oldTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"TotalSupplyDecreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newTotalSupply","type":"uint256"}],"name":"TotalSupplyIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousUnderlyingTokenValuator","type":"address"},{"indexed":false,"internalType":"address","name":"newUnderlyingTokenValuator","type":"address"}],"name":"UnderlyingTokenValuatorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"constant":true,"inputs":[],"name":"COLLATERALIZATION_BASE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"EXCHANGE_RATE_BASE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MIN_RESERVE_RATIO_BASE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"underlyingToken","type":"address"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"decimals","type":"uint8"},{"internalType":"uint256","name":"minMintAmount","type":"uint256"},{"internalType":"uint256","name":"minRedeemAmount","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"name":"addMarket","outputs":[],"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":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"},{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"adminDepositFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"},{"internalType":"uint256","name":"underlyingAmount","type":"uint256"}],"name":"adminWithdrawFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"blacklistable","outputs":[{"internalType":"contract Blacklistable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"collateralValuator","outputs":[{"internalType":"contract ICollateralValuator","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decreaseTotalSupply","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"}],"name":"disableMarket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"dmmBlacklistable","outputs":[{"internalType":"contract DmmBlacklistable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dmmEtherFactory","outputs":[{"internalType":"contract IDmmTokenFactory","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"dmmTokenAddressToDmmTokenIdMap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"dmmTokenFactory","outputs":[{"internalType":"contract IDmmTokenFactory","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dmmTokenIdToDmmTokenAddressMap","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dmmTokenIdToIsDisabledMap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dmmTokenIdToUnderlyingTokenAddressMap","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dmmTokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"}],"name":"enableMarket","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getActiveCollateralization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"underlyingToken","type":"address"}],"name":"getDmmTokenForUnderlying","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDmmTokenIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"dmmToken","type":"address"}],"name":"getExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"underlyingToken","type":"address"}],"name":"getExchangeRateByUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"dmmToken","type":"address"}],"name":"getInterestRateByDmmTokenAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"}],"name":"getInterestRateByDmmTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"underlyingToken","type":"address"}],"name":"getInterestRateByUnderlyingTokenAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"dmmToken","type":"address"}],"name":"getTokenIdFromDmmTokenAddress","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getTotalCollateralization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"dmmToken","type":"address"}],"name":"getUnderlyingTokenForDmm","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseTotalSupply","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"interestRateInterface","outputs":[{"internalType":"contract InterestRateInterface","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"dmmToken","type":"address"}],"name":"isMarketEnabledByDmmTokenAddress","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"dmmTokenId","type":"uint256"}],"name":"isMarketEnabledByDmmTokenId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","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":"minCollateralization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minReserveRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renouncePauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newCollateralValuator","type":"address"}],"name":"setCollateralValuator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newInterestRateInterface","type":"address"}],"name":"setInterestRateInterface","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newMinCollateralization","type":"uint256"}],"name":"setMinCollateralization","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newMinReserveRatio","type":"uint256"}],"name":"setMinReserveRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newUnderlyingTokenValuator","type":"address"}],"name":"setUnderlyingTokenValuator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"underlyingTokenAddressToDmmTokenIdMap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"underlyingTokenValuator","outputs":[{"internalType":"contract IUnderlyingTokenValuator","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"wethToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162003a7938038062003a7983398181016040526101208110156200003857600080fd5b508051602082015160408301516060840151608085015160a086015160c087015160e0880151610100909801519697959694959394929391929091906200009a6200008b6001600160e01b036200019b16565b6001600160e01b036200019f16565b6001805460ff19169055620000b76001600160e01b036200019b16565b60018054610100600160a81b0319166101006001600160a01b03938416810291909117918290556040519104909116906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3600380546001600160a01b03199081166001600160a01b039b8c1617909155600480548216998b1699909917909855600580548916978a16979097179096556006805488169489169490941790935560078054871694881694909417909355600280548616918716919091179055600891909155600955600a805490921692169190911790556200031b565b3390565b620001ba816000620001f160201b6200346a1790919060201c565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b6200020682826001600160e01b036200029816565b156200027357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b60006001600160a01b038216620002fb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602281526020018062003a576022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b61372c806200032b6000396000f3fe608060405234801561001057600080fd5b50600436106103425760003560e01c806382dc1ec4116101b8578063ba5d006711610104578063e09286de116100a2578063efb7601d1161007c578063efb7601d1461094a578063f2fde38b14610970578063f9322c7414610996578063ffd2bab6146109bc57610342565b8063e09286de1461091d578063e123bf271461093a578063eb65b7791461094257610342565b8063cd147c41116100de578063cd147c4114610891578063cd4aa182146108ae578063d9d3c53e146108d4578063e0471613146108f757610342565b8063ba5d006714610863578063c37c4d7c1461086b578063c3c6de911461069157610342565b806398c3729811610171578063af4b4cc51161014b578063af4b4cc5146107f2578063b187bd2614610818578063b2a24d9f14610820578063ba082cde1461083d57610342565b806398c372981461079e578063a0acbce0146107c4578063a694de28146107ea57610342565b806382dc1ec414610726578063836851351461074c5780638456cb59146107695780638da5cb5b146107715780638f32d59b1461077957806396a442251461078157610342565b8063533f3ba8116102925780636ef8d66d1161023057806379db8e231161020a57806379db8e23146106c65780637e7bb8a1146106e357806380d9fde61461069157806380de4cf91461070057610342565b80636ef8d66d14610699578063715018a6146106a15780637990e8fa146106a957610342565b8063565c17141161026c578063565c1714146106645780635a596d1c146106815780635b10a00e1461068957806369ce6b771461069157610342565b8063533f3ba8146104ee5780635550425a1461063f578063561778ea1461064757610342565b8063375cea96116102ff5780634b57b0be116102d95780634b57b0be146104775780634b826d811461047f5780634d38f747146104a25780634d79af57146104c857610342565b8063375cea961461042d5780633f4ba83a1461043557806346fbf68e1461043d57610342565b80630107f15b146103475780631b581b481461036b5780631deef941146103855780631fbfc5ff146103dd57806327c3a770146103e5578063339b37761461040a575b600080fd5b61034f6109e2565b604080516001600160a01b039092168252519081900360200190f35b6103736109f1565b60408051918252519081900360200190f35b61038d610b81565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103c95781810151838201526020016103b1565b505050509050019250505060405180910390f35b61034f610bd9565b610408600480360360408110156103fb57600080fd5b5080359060200135610be8565b005b6104086004803603604081101561042057600080fd5b5080359060200135610e67565b61034f611022565b610408611031565b6104636004803603602081101561045357600080fd5b50356001600160a01b031661111c565b604080519115158252519081900360200190f35b61034f611134565b6104086004803603604081101561049557600080fd5b5080359060200135611143565b610463600480360360208110156104b857600080fd5b50356001600160a01b03166112a0565b610408600480360360208110156104de57600080fd5b50356001600160a01b0316611312565b610408600480360360e081101561050457600080fd5b6001600160a01b03823516919081019060408101602082013564010000000081111561052f57600080fd5b82018360208201111561054157600080fd5b8035906020019184600183028401116401000000008311171561056357600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156105b657600080fd5b8201836020820111156105c857600080fd5b803590602001918460018302840111640100000000831117156105ea57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295505060ff8335169350505060208101359060408101359060600135611408565b61034f6118a5565b6104636004803603602081101561065d57600080fd5b50356118b4565b6104086004803603602081101561067a57600080fd5b50356118c9565b610373611a5e565b61034f611a64565b610373611a73565b610408611a7f565b610408611a91565b610463600480360360208110156106bf57600080fd5b5035611b28565b61034f600480360360208110156106dc57600080fd5b5035611b99565b610408600480360360208110156106f957600080fd5b5035611bb4565b6103736004803603602081101561071657600080fd5b50356001600160a01b0316611c8f565b6104086004803603602081101561073c57600080fd5b50356001600160a01b0316611ce8565b6104086004803603602081101561076257600080fd5b5035611d3a565b610408611e15565b61034f611edd565b610463611ef1565b6104086004803603602081101561079757600080fd5b5035611f1c565b61034f600480360360208110156107b457600080fd5b50356001600160a01b03166120a6565b610373600480360360208110156107da57600080fd5b50356001600160a01b031661211d565b61037361212f565b6103736004803603602081101561080857600080fd5b50356001600160a01b03166121dd565b6104636123a1565b6103736004803603602081101561083657600080fd5b50356123aa565b6104086004803603602081101561085357600080fd5b50356001600160a01b03166123c8565b6103736124be565b61034f6004803603602081101561088157600080fd5b50356001600160a01b03166124c4565b61034f600480360360208110156108a757600080fd5b503561253b565b610373600480360360208110156108c457600080fd5b50356001600160a01b0316612556565b610408600480360360408110156108ea57600080fd5b508035906020013561257f565b6104086004803603602081101561090d57600080fd5b50356001600160a01b031661296b565b6103736004803603602081101561093357600080fd5b5035612a61565b61034f612c3b565b61034f612c4a565b6103736004803603602081101561096057600080fd5b50356001600160a01b0316612c59565b6104086004803603602081101561098657600080fd5b50356001600160a01b0316612d1e565b610373600480360360208110156109ac57600080fd5b50356001600160a01b0316612d77565b610373600480360360208110156109d257600080fd5b50356001600160a01b0316612dbe565b6002546001600160a01b031690565b600080805b601054811015610ad3576000600b600060108460010181548110610a1657fe5b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b031690506000610ab582836001600160a01b031663babd70126040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8457600080fd5b505afa158015610a98573d6000803e3d6000fd5b505050506040513d6020811015610aae57600080fd5b5051612dd0565b9050610ac7848263ffffffff612eb716565b935050506001016109f6565b506000600460009054906101000a90046001600160a01b03166001600160a01b031663c047e5636040518163ffffffff1660e01b815260040160206040518083038186803b158015610b2457600080fd5b505afa158015610b38573d6000803e3d6000fd5b505050506040513d6020811015610b4e57600080fd5b50519050610b7a82610b6e83670de0b6b3a764000063ffffffff612f1116565b9063ffffffff612f6a16565b9250505090565b60606010805480602002602001604051908101604052809291908181526020018280548015610bcf57602002820191906000526020600020905b815481526020019060010190808311610bbb575b5050505050905090565b6006546001600160a01b031681565b6000828152600b602052604090205482906001600160a01b0316610c41576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b610c496123a1565b15610c8e576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b610c96611ef1565b610cd5576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6000838152600e60205260409020546001600160a01b0316610d10610cf8612fac565b6001600160a01b03831690308663ffffffff612fb016565b6000848152600b6020908152604080832054815163095ea7b360e01b81526001600160a01b039182166004820181905260248201899052925192949186169363095ea7b39360448084019492939192918390030190829087803b158015610d7657600080fd5b505af1158015610d8a573d6000803e3d6000fd5b505050506040513d6020811015610da057600080fd5b50506040805163b9f5be4160e01b81526004810186905290516001600160a01b0383169163b9f5be419160248083019260209291908290030181600087803b158015610deb57600080fd5b505af1158015610dff573d6000803e3d6000fd5b505050506040513d6020811015610e1557600080fd5b50610e209050612fac565b6001600160a01b03167fce8f50bef0c9b984189b343b8bf9264667774780224a0b53de9005bb2d384a9f856040518082815260200191505060405180910390a25050505050565b6000828152600b602052604090205482906001600160a01b0316610ec0576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b610ec86123a1565b15610f0d576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b610f15611ef1565b610f54576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6000838152600b60205260408082205481516303a8799360e31b81526004810186905291516001600160a01b0390911692631d43cc98926024808201939182900301818387803b158015610fa757600080fd5b505af1158015610fbb573d6000803e3d6000fd5b50505050600854610fca61212f565b101561101d576040805162461bcd60e51b815260206004820152601760248201527f494e53554646494349454e545f434f4c4c41544552414c000000000000000000604482015290519081900360640190fd5b505050565b6007546001600160a01b031681565b61104161103c612fac565b61111c565b61107c5760405162461bcd60e51b81526004018080602001828103825260308152602001806135d46030913960400191505060405180910390fd5b6110846123a1565b6110cc576040805162461bcd60e51b81526020600482015260146024820152731150d3d4d654d5115357d393d517d4105554d15160621b604482015290519081900360640190fd5b6001805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6110ff612fac565b604080516001600160a01b039092168252519081900360200190a1565b600061112e818363ffffffff61301016565b92915050565b600a546001600160a01b031681565b6000828152600b602052604090205482906001600160a01b031661119c576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b6111a46123a1565b156111e9576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b6111f1611ef1565b611230576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6000838152600b6020526040808220548151636e11451160e01b81526004810186905291516001600160a01b0390911692636e114511926024808201939182900301818387803b15801561128357600080fd5b505af1158015611297573d6000803e3d6000fd5b50505050505050565b6001600160a01b0381166000908152600c6020526040812054806112f9576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b6000908152600f602052604090205460ff161592915050565b61131a6123a1565b1561135f576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b611367611ef1565b6113a6576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b600380546001600160a01b038381166001600160a01b0319831617928390556040805192821680845293909116602083015280517f8d7f6129d57ccb02dbf423991fc05188ee19ee305d4cc6eaa0e9eaf27bdbc8099281900390910190a15050565b611410611ef1565b61144f576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6001600160a01b0387166000908152600d6020526040902054156114b1576040805162461bcd60e51b8152602060048201526014602482015273544f4b454e5f414c52454144595f45584953545360601b604482015290519081900360640190fd5b601054600a5460019091019030906000906001600160a01b038b811691161415611653576007546040516208144560e11b815260ff89166044820152606481018890526084810187905260a481018690526001600160a01b0384811660c483015260e0600483019081528c5160e48401528c5191909316926210288a928d928d928d928d928d928d928c92829160248101916101049091019060208c019080838360005b8381101561156d578181015183820152602001611555565b50505050905090810190601f16801561159a5780820380516001836020036101000a031916815260200191505b5083810382528951815289516020918201918b019080838360005b838110156115cd5781810151838201526020016115b5565b50505050905090810190601f1680156115fa5780820380516001836020036101000a031916815260200191505b509950505050505050505050602060405180830381600087803b15801561162057600080fd5b505af1158015611634573d6000803e3d6000fd5b505050506040513d602081101561164a57600080fd5b505190506117cd565b6006546040516208144560e11b815260ff89166044820152606481018890526084810187905260a481018690526001600160a01b0384811660c483015260e0600483019081528c5160e48401528c5191909316926210288a928d928d928d928d928d928d928c92829160248101916101049091019060208c019080838360005b838110156116eb5781810151838201526020016116d3565b50505050905090810190601f1680156117185780820380516001836020036101000a031916815260200191505b5083810382528951815289516020918201918b019080838360005b8381101561174b578181015183820152602001611733565b50505050905090810190601f1680156117785780820380516001836020036101000a031916815260200191505b509950505050505050505050602060405180830381600087803b15801561179e57600080fd5b505af11580156117b2573d6000803e3d6000fd5b505050506040513d60208110156117c857600080fd5b505190505b6000838152600b6020908152604080832080546001600160a01b038087166001600160a01b03199283168117909355828652600c85528386208990558f16808652600d8552838620899055888652600e855283862080549092168117909155600f909352818420805460ff19169055601080546001810182559085527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672018790559051849387917f54736d25075919df72a1cdd3bab83287f25b1bf8bf9deac0f043b6cf6eea334a9190a45050505050505050505050565b6002546001600160a01b031681565b600f6020526000908152604090205460ff1681565b6000818152600b602052604090205481906001600160a01b0316611922576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b61192a6123a1565b1561196f576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b611977611ef1565b6119b6576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6000828152600f602052604090205460ff1615611a1a576040805162461bcd60e51b815260206004820152601760248201527f4d41524b45545f414c52454144595f44495341424c4544000000000000000000604482015290519081900360640190fd5b6000828152600f6020526040808220805460ff191660011790555183917f88062db56f0bada5b549bac4f4637f70288a1bfbd50c0578cf1b217a5d94e9b491a25050565b60095481565b6004546001600160a01b031681565b670de0b6b3a764000081565b611a8f611a8a612fac565b613077565b565b611a99611ef1565b611ad8576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b60015460405160009161010090046001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a360018054610100600160a81b0319169055565b6000818152600b602052604081205482906001600160a01b0316611b81576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b50506000908152600f602052604090205460ff161590565b600b602052600090815260409020546001600160a01b031681565b611bbc6123a1565b15611c01576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b611c09611ef1565b611c48576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6008805490829055604080518281526020810184905281517f41c21d7a9652c6a2e6c22641602770b2d9d04f367adb18eabbf076d74521b721929181900390910190a15050565b6001600160a01b0381166000908152600c60205260408120548061112e576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b611cf361103c612fac565b611d2e5760405162461bcd60e51b81526004018080602001828103825260308152602001806135d46030913960400191505060405180910390fd5b611d37816130bf565b50565b611d426123a1565b15611d87576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b611d8f611ef1565b611dce576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6009805490829055604080518281526020810184905281517fb8a37dfe71ffcc47f17a11cabec0d2d41cd370c7f7f2c4a7fca4cef6282ad568929181900390910190a15050565b611e2061103c612fac565b611e5b5760405162461bcd60e51b81526004018080602001828103825260308152602001806135d46030913960400191505060405180910390fd5b611e636123a1565b15611ea8576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b6001805460ff1916811790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110ff612fac565b60015461010090046001600160a01b031690565b60015460009061010090046001600160a01b0316611f0d612fac565b6001600160a01b031614905090565b6000818152600b602052604090205481906001600160a01b0316611f75576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b611f7d6123a1565b15611fc2576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b611fca611ef1565b612009576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6000828152600f602052604090205460ff16612065576040805162461bcd60e51b815260206004820152601660248201527513505492d15517d053149150511657d153905093115160521b604482015290519081900360640190fd5b6000828152600f6020526040808220805460ff191690555183917f8227fbc28a4e896face737e0ecdd927a187a4ef9013b8dbcce2f5fb88cc7a81791a25050565b6001600160a01b0381166000908152600d6020526040812054806120ff576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b6000908152600b60205260409020546001600160a01b031692915050565b600d6020526000908152604090205481565b600080805b601054811015610ad3576000600b60006010848154811061215157fe5b9060005260206000200154815260200190815260200160002060009054906101000a90046001600160a01b0316905060006121bf82836001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610a8457600080fd5b90506121d1848263ffffffff612eb716565b93505050600101612134565b6001600160a01b0381166000908152600c602052604081205480612236576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b6000836001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561227157600080fd5b505afa158015612285573d6000803e3d6000fd5b505050506040513d602081101561229b57600080fd5b505160408051635d5eb80960e11b815290519192506000916001600160a01b0387169163babd7012916004808301926020929190829003018186803b1580156122e357600080fd5b505afa1580156122f7573d6000803e3d6000fd5b505050506040513d602081101561230d57600080fd5b5051600354604080516364bfe61f60e11b815260048101879052602481018690526044810184905290519293506001600160a01b039091169163c97fcc3e91606480820192602092909190829003018186803b15801561236c57600080fd5b505afa158015612380573d6000803e3d6000fd5b505050506040513d602081101561239657600080fd5b505195945050505050565b60015460ff1690565b601081815481106123b757fe5b600091825260209091200154905081565b6123d06123a1565b15612415576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b61241d611ef1565b61245c576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b600580546001600160a01b038381166001600160a01b0319831617928390556040805192821680845293909116602083015280517f059ad1c0c51ecc25729ab67ccc037eb0729e4b7773c472de55817dc441b188179281900390910190a15050565b60085481565b6001600160a01b0381166000908152600c60205260408120548061251d576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b6000908152600e60205260409020546001600160a01b031692915050565b600e602052600090815260409020546001600160a01b031681565b6001600160a01b0381166000908152600d602052604081205461257881612a61565b9392505050565b6000828152600b602052604090205482906001600160a01b03166125d8576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b6125e06123a1565b15612625576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b61262d611ef1565b61266c576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b6000838152600b602090815260408083205481516301071a2960e41b81526004810187905291516001600160a01b03909116938493631071a290936024808201949293918390030190829087803b1580156126c657600080fd5b505af11580156126da573d6000803e3d6000fd5b505050506040513d60208110156126f057600080fd5b50506000848152600e60205260409020546001600160a01b031661272c612715612fac565b6001600160a01b038316908663ffffffff61310716565b600061281a670de0b6b3a7640000610b6e856001600160a01b0316633ca967f36040518163ffffffff1660e01b815260040160206040518083038186803b15801561277657600080fd5b505afa15801561278a573d6000803e3d6000fd5b505050506040513d60208110156127a057600080fd5b505160408051635d5eb80960e11b815290516001600160a01b0389169163babd7012916004808301926020929190829003018186803b1580156127e257600080fd5b505afa1580156127f6573d6000803e3d6000fd5b505050506040513d602081101561280c57600080fd5b50519063ffffffff612f1116565b6000878152600e602090815260408083205481516370a0823160e01b81526001600160a01b038981166004830152925195965093949116926370a08231926024808301939192829003018186803b15801561287457600080fd5b505afa158015612888573d6000803e3d6000fd5b505050506040513d602081101561289e57600080fd5b5051905060006128c083610b6e84670de0b6b3a764000063ffffffff612f1116565b9050600954811015612919576040805162461bcd60e51b815260206004820152601e60248201527f494e53554646494349454e545f4c4546544f5645525f52455345525645530000604482015290519081900360640190fd5b612921612fac565b6001600160a01b03167fba443e8671971c36cdeb74f87321041daff421230cbc5e36cb835269ed1d8b7e886040518082815260200191505060405180910390a25050505050505050565b6129736123a1565b156129b8576040805162461bcd60e51b815260206004820152601060248201526f1150d3d4d654d5115357d4105554d15160821b604482015290519081900360640190fd5b6129c0611ef1565b6129ff576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b600480546001600160a01b038381166001600160a01b0319831617928390556040805192821680845293909116602083015280517f314ae709118555c5bd2ada9391c31a42ad9ce83324312476b6cbb384bbc1f2729281900390910190a15050565b6000818152600b602052604081205482906001600160a01b0316612aba576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b6000838152600b602090815260408083205481516318160ddd60e01b815291516001600160a01b03909116939284926318160ddd9260048083019392829003018186803b158015612b0a57600080fd5b505afa158015612b1e573d6000803e3d6000fd5b505050506040513d6020811015612b3457600080fd5b505160408051635d5eb80960e11b815290519192506000916001600160a01b0385169163babd7012916004808301926020929190829003018186803b158015612b7c57600080fd5b505afa158015612b90573d6000803e3d6000fd5b505050506040513d6020811015612ba657600080fd5b5051600354604080516364bfe61f60e11b8152600481018a9052602481018690526044810184905290519293506001600160a01b039091169163c97fcc3e91606480820192602092909190829003018186803b158015612c0557600080fd5b505afa158015612c19573d6000803e3d6000fd5b505050506040513d6020811015612c2f57600080fd5b50519695505050505050565b6005546001600160a01b031681565b6003546001600160a01b031681565b6001600160a01b0381166000908152600c602052604081205480612cb2576040805162461bcd60e51b815260206004820152601460248201526000805160206136ae833981519152604482015290519081900360640190fd5b826001600160a01b0316633ca967f36040518163ffffffff1660e01b815260040160206040518083038186803b158015612ceb57600080fd5b505afa158015612cff573d6000803e3d6000fd5b505050506040513d6020811015612d1557600080fd5b50519392505050565b612d26611ef1565b612d65576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b612d6e81613159565b611d3781611ce8565b600080612d83836120a6565b9050806001600160a01b0316633ca967f36040518163ffffffff1660e01b815260040160206040518083038186803b158015612ceb57600080fd5b600c6020526000908152604090205481565b600080612e54670de0b6b3a7640000610b6e866001600160a01b0316633ca967f36040518163ffffffff1660e01b815260040160206040518083038186803b158015612e1b57600080fd5b505afa158015612e2f573d6000803e3d6000fd5b505050506040513d6020811015612e4557600080fd5b5051869063ffffffff612f1116565b90506000612e61856124c4565b60055460408051636d34cd1760e01b81526001600160a01b038085166004830152602482018790529151939450911691636d34cd1791604480820192602092909190829003018186803b15801561236c57600080fd5b600082820183811015612578576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612f205750600061112e565b82820282848281612f2d57fe5b04146125785760405162461bcd60e51b815260040180806020018281038252602181526020018061364b6021913960400191505060405180910390fd5b600061257883836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506131a9565b3390565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261300a90859061324b565b50505050565b60006001600160a01b0382166130575760405162461bcd60e51b815260040180806020018281038252602281526020018061368c6022913960400191505060405180910390fd5b506001600160a01b03166000908152602091909152604090205460ff1690565b61308860008263ffffffff61340316565b6040516001600160a01b038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b6130d060008263ffffffff61346a16565b6040516001600160a01b038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b17905261101d90849061324b565b613161611ef1565b6131a0576040805162461bcd60e51b8152602060048201819052602482015260008051602061366c833981519152604482015290519081900360640190fd5b611d37816134eb565b600081836132355760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156131fa5781810151838201526020016131e2565b50505050905090810190601f1680156132275780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161324157fe5b0495945050505050565b61325d826001600160a01b0316613597565b6132ae576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106132ec5780518252601f1990920191602091820191016132cd565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461334e576040519150601f19603f3d011682016040523d82523d6000602084013e613353565b606091505b5091509150816133aa576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561300a578080602001905160208110156133c657600080fd5b505161300a5760405162461bcd60e51b815260040180806020018281038252602a8152602001806136ce602a913960400191505060405180910390fd5b61340d8282613010565b6134485760405162461bcd60e51b815260040180806020018281038252602181526020018061362a6021913960400191505060405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6134748282613010565b156134c6576040805162461bcd60e51b815260206004820152601f60248201527f526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500604482015290519081900360640190fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b0381166135305760405162461bcd60e51b81526004018080602001828103825260268152602001806136046026913960400191505060405180910390fd5b6001546040516001600160a01b0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0390921661010002610100600160a81b0319909216919091179055565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47081158015906135cb5750808214155b94935050505056fe506175736572526f6c653a2063616c6c657220646f6573206e6f742068617665207468652050617573657220726f6c654f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c65536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572526f6c65733a206163636f756e7420697320746865207a65726f2061646472657373544f4b454e5f444f45535f4e4f545f45584953540000000000000000000000005361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a265627a7a7231582040b308e2af01060f2b41df0eed8e708021e549089b20ccd53ce7ef3c0cacd13b64736f6c634300050d0032526f6c65733a206163636f756e7420697320746865207a65726f20616464726573730000000000000000000000007a01313ed513f13acc35536cb66feb5362e6c3c300000000000000000000000028a655d5221c866fb3790dbe75fd657219cd3324000000000000000000000000cca971a0d728f138c96a0e14b20040832ea55053000000000000000000000000dd34269490a4095f445da6c683dd2f010bbc9282000000000000000000000000bc5b9040fee0cca807a0d6e35f535a1b8e609c14000000000000000000000000bb2706d18b5def6f66b1f97ee47b42ea6a45f73a0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000005ae1948b45d61917452af4208e3b2fef1bc70e12

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

0000000000000000000000007a01313ed513f13acc35536cb66feb5362e6c3c300000000000000000000000028a655d5221c866fb3790dbe75fd657219cd3324000000000000000000000000cca971a0d728f138c96a0e14b20040832ea55053000000000000000000000000dd34269490a4095f445da6c683dd2f010bbc9282000000000000000000000000bc5b9040fee0cca807a0d6e35f535a1b8e609c14000000000000000000000000bb2706d18b5def6f66b1f97ee47b42ea6a45f73a0000000000000000000000000000000000000000000000000de0b6b3a764000000000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000005ae1948b45d61917452af4208e3b2fef1bc70e12

-----Decoded View---------------
Arg [0] : _interestRateInterface (address): 0x7a01313ed513f13acc35536cb66feb5362e6c3c3
Arg [1] : _collateralValuator (address): 0x28a655d5221c866fb3790dbe75fd657219cd3324
Arg [2] : _underlyingTokenValuator (address): 0xcca971a0d728f138c96a0e14b20040832ea55053
Arg [3] : _dmmEtherFactory (address): 0xdd34269490a4095f445da6c683dd2f010bbc9282
Arg [4] : _dmmTokenFactory (address): 0xbc5b9040fee0cca807a0d6e35f535a1b8e609c14
Arg [5] : _dmmBlacklistable (address): 0xbb2706d18b5def6f66b1f97ee47b42ea6a45f73a
Arg [6] : _minCollateralization (uint256): 1000000000000000000
Arg [7] : _minReserveRatio (uint256): 500000000000000000
Arg [8] : _wethToken (address): 0x5ae1948b45d61917452af4208e3b2fef1bc70e12

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 0000000000000000000000007a01313ed513f13acc35536cb66feb5362e6c3c3
Arg [1] : 00000000000000000000000028a655d5221c866fb3790dbe75fd657219cd3324
Arg [2] : 000000000000000000000000cca971a0d728f138c96a0e14b20040832ea55053
Arg [3] : 000000000000000000000000dd34269490a4095f445da6c683dd2f010bbc9282
Arg [4] : 000000000000000000000000bc5b9040fee0cca807a0d6e35f535a1b8e609c14
Arg [5] : 000000000000000000000000bb2706d18b5def6f66b1f97ee47b42ea6a45f73a
Arg [6] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [7] : 00000000000000000000000000000000000000000000000006f05b59d3b20000
Arg [8] : 0000000000000000000000005ae1948b45d61917452af4208e3b2fef1bc70e12


Deployed ByteCode Sourcemap

52826:15286:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52826:15286:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56540:103;;;:::i;:::-;;;;-1:-1:-1;;;;;56540:103:0;;;;;;;;;;;;;;63963:615;;;:::i;:::-;;;;;;;;;;;;;;;;67561:99;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;67561:99:0;;;;;;;;;;;;;;;;;54090:39;;;:::i;62588:733::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62588:733:0;;;;;;;:::i;:::-;;60735:342;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60735:342:0;;;;;;;:::i;54136:39::-;;;:::i;26690:120::-;;;:::i;24167:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24167:109:0;-1:-1:-1;;;;;24167:109:0;;:::i;:::-;;;;;;;;;;;;;;;;;;54255:24;;;:::i;61085:244::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61085:244:0;;;;;;;:::i;67014:281::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67014:281:0;-1:-1:-1;;;;;67014:281:0;;:::i;59025:367::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59025:367:0;-1:-1:-1;;;;;59025:367:0;;:::i;56651:1775::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;56651:1775:0;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;56651:1775:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;56651:1775:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;56651:1775:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;56651:1775:0;;;;;;;;-1:-1:-1;56651:1775:0;;-1:-1:-1;;21:11;5:28;;2:2;;;46:1;43;36:12;2:2;56651:1775:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;56651:1775:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;56651:1775:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;56651:1775:0;;-1:-1:-1;;56651:1775:0;;;;;-1:-1:-1;;;56651:1775:0;;;;;;;;;;;;;;:::i;53872:40::-;;;:::i;54663:54::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54663:54:0;;:::i;58728:289::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58728:289:0;;:::i;54221:27::-;;;:::i;53976:45::-;;;:::i;54888:55::-;;;:::i;24384:79::-;;;:::i;18260:140::-;;;:::i;66832:174::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66832:174:0;;:::i;54369:62::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54369:62:0;;:::i;60142:311::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60142:311:0;;:::i;67303:250::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67303:250:0;-1:-1:-1;;;;;67303:250:0;;:::i;24284:92::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;24284:92:0;-1:-1:-1;;;;;24284:92:0;;:::i;60461:266::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;60461:266:0;;:::i;26477:118::-;;;:::i;17449:79::-;;;:::i;17815:94::-;;;:::i;58434:286::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58434:286:0;;:::i;66228:301::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66228:301:0;-1:-1:-1;;;;;66228:301:0;;:::i;54509:69::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54509:69:0;-1:-1:-1;;;;;54509:69:0;;:::i;63329:626::-;;;:::i;65260:444::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65260:444:0;-1:-1:-1;;;;;65260:444:0;;:::i;25895:80::-;;;:::i;54724:25::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54724:25:0;;:::i;59746:388::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59746:388:0;-1:-1:-1;;;;;59746:388:0;;:::i;54182:32::-;;;:::i;66537:287::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66537:287:0;-1:-1:-1;;;;;66537:287:0;;:::i;54585:69::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54585:69:0;;:::i;64586:249::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64586:249:0;-1:-1:-1;;;;;64586:249:0;;:::i;61337:1243::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61337:1243:0;;;;;;;:::i;59400:338::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;59400:338:0;-1:-1:-1;;;;;59400:338:0;;:::i;64843:409::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64843:409:0;;:::i;54028:55::-;;;:::i;53919:50::-;;;:::i;65950:270::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65950:270:0;-1:-1:-1;;;;;65950:270:0;;:::i;56388:144::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;56388:144:0;-1:-1:-1;;;;;56388:144:0;;:::i;65712:230::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65712:230:0;-1:-1:-1;;;;;65712:230:0;;:::i;54438:62::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54438:62:0;-1:-1:-1;;;;;54438:62:0;;:::i;56540:103::-;56619:16;;-1:-1:-1;;;;;56619:16:0;56540:103;:::o;63963:615::-;64022:4;;;64075:335;64096:11;:18;64092:22;;64075:335;;;64167:15;64195:30;:50;64226:11;64238:1;64242;64238:5;64226:18;;;;;;;;;;;;;;;;64195:50;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64195:50:0;64167:79;;64261:20;64284:43;64299:5;64306;-1:-1:-1;;;;;64306:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64306:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64306:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64306:20:0;64284:14;:43::i;:::-;64261:66;-1:-1:-1;64361:37:0;:16;64261:66;64361:37;:20;:37;:::i;:::-;64342:56;-1:-1:-1;;;64116:3:0;;64075:335;;;;64420:20;64443:18;;;;;;;;;-1:-1:-1;;;;;64443:18:0;-1:-1:-1;;;;;64443:37:0;;:39;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64443:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64443:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;64443:39:0;;-1:-1:-1;64500:70:0;64553:16;64500:48;64443:39;54877:4;64500:48;:19;:48;:::i;:::-;:52;:70;:52;:70;:::i;:::-;64493:77;;;;63963:615;:::o;67561:99::-;67608:13;67641:11;67634:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67561:99;:::o;54090:39::-;;;-1:-1:-1;;;;;54090:39:0;;:::o;62588:733::-;56266:3;56212:42;;;:30;:42;;;;;;62707:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;62858:22;62890:49;;;:37;:49;;;;;;-1:-1:-1;;;;;62890:49:0;62951:79;62984:12;:10;:12::i;:::-;-1:-1:-1;;;;;62951:32:0;;;63006:4;63013:16;62951:79;:32;:79;:::i;:::-;63043:23;63069:42;;;:30;:42;;;;;;;;;63122:58;;-1:-1:-1;;;63122:58:0;;-1:-1:-1;;;;;63069:42:0;;;63122:58;;;;;;;;;;;;;;63069:42;;63122:23;;;;;;:58;;;;;63069:42;;63122:58;;;;;;;;;;:23;:58;;;5:2:-1;;;;30:1;27;20:12;5:2;63122:58:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63122:58:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;63191:62:0;;;-1:-1:-1;;;63191:62:0;;;;;;;;;;-1:-1:-1;;;;;63191:44:0;;;;;:62;;;;;63122:58;;63191:62;;;;;;;-1:-1:-1;63191:44:0;:62;;;5:2:-1;;;;30:1;27;20:12;5:2;63191:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63191:62:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63282:12:0;;-1:-1:-1;63282:10:0;:12::i;:::-;-1:-1:-1;;;;;63269:44:0;;63296:16;63269:44;;;;;;;;;;;;;;;;;;17718:1;;62588:733;;;:::o;60735:342::-;56266:3;56212:42;;;:30;:42;;;;;;60843:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;60900:42;;;;:30;:42;;;;;;;60890:81;;-1:-1:-1;;;60890:81:0;;;;;;;;;;-1:-1:-1;;;;;60900:42:0;;;;60890:73;;:81;;;;;;;;;;;60900:42;;60890:81;;;5:2:-1;;;;30:1;27;20:12;5:2;60890:81:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60890:81:0;;;;61021:20;;60990:27;:25;:27::i;:::-;:51;;60982:87;;;;;-1:-1:-1;;;60982:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;60735:342;;;:::o;54136:39::-;;;-1:-1:-1;;;;;54136:39:0;;:::o;26690:120::-;24064:22;24073:12;:10;:12::i;:::-;24064:8;:22::i;:::-;24056:83;;;;-1:-1:-1;;;24056:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56087:10;:8;:10::i;:::-;56079:43;;;;;-1:-1:-1;;;56079:43:0;;;;;;;;;;;;-1:-1:-1;;;56079:43:0;;;;;;;;;;;;;;;26749:7;:15;;-1:-1:-1;;26749:15:0;;;26780:22;26789:12;:10;:12::i;:::-;26780:22;;;-1:-1:-1;;;;;26780:22:0;;;;;;;;;;;;;;26690:120::o;24167:109::-;24223:4;24247:21;24223:4;24260:7;24247:21;:12;:21;:::i;:::-;24240:28;24167:109;-1:-1:-1;;24167:109:0:o;54255:24::-;;;-1:-1:-1;;;;;54255:24:0;;:::o;61085:244::-;56266:3;56212:42;;;:30;:42;;;;;;61193:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;61250:42;;;;:30;:42;;;;;;;61240:81;;-1:-1:-1;;;61240:81:0;;;;;;;;;;-1:-1:-1;;;;;61250:42:0;;;;61240:73;;:81;;;;;;;;;;;61250:42;;61240:81;;;5:2:-1;;;;30:1;27;20:12;5:2;61240:81:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61240:81:0;;;;61085:244;;;:::o;67014:281::-;-1:-1:-1;;;;;67130:40:0;;67095:4;67130:40;;;:30;:40;;;;;;67189:15;67181:48;;;;;-1:-1:-1;;;67181:48:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;67181:48:0;;;;;;;;;;;;;;;67250:37;;;;:25;:37;;;;;;;;67249:38;;67014:281;-1:-1:-1;;67014:281:0:o;59025:367::-;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;59178:21;;;-1:-1:-1;;;;;59211:71:0;;;-1:-1:-1;;;;;;59211:71:0;;;;;;;59298:86;;;59178:21;;;59298:86;;;59361:21;;;;59298:86;;;;;;;;;;;;;;;;17718:1;59025:367;:::o;56651:1775::-;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;56919:54:0;;;;;;:37;:54;;;;;;:59;56911:92;;;;;-1:-1:-1;;;56911:92:0;;;;;;;;;;;;-1:-1:-1;;;56911:92:0;;;;;;;;;;;;;;;57125:11;:18;57257:9;;57146:1;57125:22;;;;57187:4;;57107:15;;-1:-1:-1;;;;;57238:28:0;;;57257:9;;57238:28;57234:600;;;57294:15;;:242;;-1:-1:-1;;;57294:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57294:242:0;;;;;;;;;;;;;;;;;;;;;;:15;;;;;:27;;57340:6;;57365:4;;57388:8;;57415:13;;57447:15;;57481:11;;57511:10;;57294:242;;;;;;;;;;;;;;;;;;:15;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57294:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57294:242:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57294:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57294:242:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57294:242:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57294:242:0;;-1:-1:-1;57234:600:0;;;57580:15;;:242;;-1:-1:-1;;;57580:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57580:242:0;;;;;;;;;;;;;;;;;;;;;;:15;;;;;:27;;57626:6;;57651:4;;57674:8;;57701:13;;57733:15;;57767:11;;57797:10;;57580:242;;;;;;;;;;;;;;;;;;:15;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57580:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57580:242:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;57580:242:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57580:242:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;57580:242:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;57580:242:0;;-1:-1:-1;57234:600:0;57846:23;57930:42;;;:30;:42;;;;;;;;:60;;-1:-1:-1;;;;;57930:60:0;;;-1:-1:-1;;;;;;57930:60:0;;;;;;;;58001:47;;;:30;:47;;;;;:60;;;58072:54;;;;;:37;:54;;;;;:67;;;58150:49;;;:37;:49;;;;;:67;;;;;;;;;;58259:25;:37;;;;;;:45;;-1:-1:-1;;58259:45:0;;;58315:11;27:10:-1;;57930:60:0;23:18:-1;;45:23;;58315:28:0;;;;;;;;58361:57;;57880:8;;57961:10;;58361:57;;57846:23;58361:57;17718:1;;;;56651:1775;;;;;;;:::o;53872:40::-;;;-1:-1:-1;;;;;53872:40:0;;:::o;54663:54::-;;;;;;;;;;;;;;;:::o;58728:289::-;56266:3;56212:42;;;:30;:42;;;;;;58792:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;58848:37;;;;:25;:37;;;;;;;;58847:38;58839:74;;;;;-1:-1:-1;;;58839:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;58924:37;;;;:25;:37;;;;;;:44;;-1:-1:-1;;58924:44:0;58964:4;58924:44;;;58984:25;58950:10;;58984:25;;;58728:289;;:::o;54221:27::-;;;;:::o;53976:45::-;;;-1:-1:-1;;;;;53976:45:0;;:::o;54888:55::-;54939:4;54888:55;:::o;24384:79::-;24428:27;24442:12;:10;:12::i;:::-;24428:13;:27::i;:::-;24384:79::o;18260:140::-;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;18343:6;;18322:40;;18359:1;;18343:6;;;-1:-1:-1;;;;;18343:6:0;;18322:40;;18359:1;;18322:40;18373:6;:19;;-1:-1:-1;;;;;;18373:19:0;;;18260:140::o;66832:174::-;66936:4;56212:42;;;:30;:42;;;;;;66903:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;-1:-1:-1;;66961:37:0;;;;:25;:37;;;;;;;;66960:38;;66832:174::o;54369:62::-;;;;;;;;;;;;-1:-1:-1;;;;;54369:62:0;;:::o;60142:311::-;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;60278:20;;;60309:46;;;;60371:74;;;;;;;;;;;;;;;;;;;;;;;;;17718:1;60142:311;:::o;67303:250::-;-1:-1:-1;;;;;67416:40:0;;67381:4;67416:40;;;:30;:40;;;;;;67475:15;67467:48;;;;;-1:-1:-1;;;67467:48:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;67467:48:0;;;;;;;;;;;;;;24284:92;24064:22;24073:12;:10;:12::i;24064:22::-;24056:83;;;;-1:-1:-1;;;24056:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24349:19;24360:7;24349:10;:19::i;:::-;24284:92;:::o;60461:266::-;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;60582:15;;;60608:36;;;;60660:59;;;;;;;;;;;;;;;;;;;;;;;;;17718:1;60461:266;:::o;26477:118::-;24064:22;24073:12;:10;:12::i;24064:22::-;24056:83;;;;-1:-1:-1;;;24056:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;26547:4;26537:14;;-1:-1:-1;;26537:14:0;;;;;26567:20;26574:12;:10;:12::i;17449:79::-;17514:6;;;;;-1:-1:-1;;;;;17514:6:0;;17449:79::o;17815:94::-;17895:6;;17855:4;;17895:6;;;-1:-1:-1;;;;;17895:6:0;17879:12;:10;:12::i;:::-;-1:-1:-1;;;;;17879:22:0;;17872:29;;17815:94;:::o;58434:286::-;56266:3;56212:42;;;:30;:42;;;;;;58497:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;58552:37;;;;:25;:37;;;;;;;;58544:72;;;;;-1:-1:-1;;;58544:72:0;;;;;;;;;;;;-1:-1:-1;;;58544:72:0;;;;;;;;;;;;;;;58667:5;58627:37;;;:25;:37;;;;;;:45;;-1:-1:-1;;58627:45:0;;;58688:24;58653:10;;58688:24;;;58434:286;;:::o;66228:301::-;-1:-1:-1;;;;;66346:54:0;;66308:7;66346:54;;;:37;:54;;;;;;66419:15;66411:48;;;;;-1:-1:-1;;;66411:48:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;66411:48:0;;;;;;;;;;;;;;;66479:42;;;;:30;:42;;;;;;-1:-1:-1;;;;;66479:42:0;;66228:301;-1:-1:-1;;66228:301:0:o;54509:69::-;;;;;;;;;;;;;:::o;63329:626::-;63387:4;;;63440:347;63461:11;:18;63457:22;;63440:347;;;63532:15;63560:30;:46;63591:11;63603:1;63591:14;;;;;;;;;;;;;;;;63560:46;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63560:46:0;63532:75;;63622:20;63645:59;63660:5;63682;-1:-1:-1;;;;;63667:34:0;;:36;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;63645:59:0;63622:82;-1:-1:-1;63738:37:0;:16;63622:82;63738:37;:20;:37;:::i;:::-;63719:56;-1:-1:-1;;;63481:3:0;;63440:347;;65260:444;-1:-1:-1;;;;;65376:40:0;;65341:4;65376:40;;;:30;:40;;;;;;65435:15;65427:48;;;;;-1:-1:-1;;;65427:48:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;65427:48:0;;;;;;;;;;;;;;;65488:16;65514:8;-1:-1:-1;;;;;65507:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65507:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65507:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65507:30:0;65568:34;;;-1:-1:-1;;;65568:34:0;;;;65507:30;;-1:-1:-1;65548:17:0;;-1:-1:-1;;;;;65568:32:0;;;;;:34;;;;;65507:30;;65568:34;;;;;;;:32;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;65568:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65568:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65568:34:0;65620:21;;:76;;;-1:-1:-1;;;65620:76:0;;;;;;;;;;;;;;;;;;;;;;65568:34;;-1:-1:-1;;;;;;65620:21:0;;;;:37;;:76;;;;;65568:34;;65620:76;;;;;;;;:21;:76;;;5:2:-1;;;;30:1;27;20:12;5:2;65620:76:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65620:76:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65620:76:0;;65260:444;-1:-1:-1;;;;;65260:444:0:o;25895:80::-;25960:7;;;;25895:80;:::o;54724:25::-;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54724:25:0;:::o;59746:388::-;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;59905:23;;;-1:-1:-1;;;;;59940:78:0;;;-1:-1:-1;;;;;;59940:78:0;;;;;;;60034:92;;;59905:23;;;60034:92;;;60101:23;;;;60034:92;;;;;;;;;;;;;;;;17718:1;59746:388;:::o;54182:32::-;;;;:::o;66537:287::-;-1:-1:-1;;;;;66648:40:0;;66610:7;66648:40;;;:30;:40;;;;;;66707:15;66699:48;;;;;-1:-1:-1;;;66699:48:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;66699:48:0;;;;;;;;;;;;;;;66767:49;;;;:37;:49;;;;;;-1:-1:-1;;;;;66767:49:0;;66537:287;-1:-1:-1;;66537:287:0:o;54585:69::-;;;;;;;;;;;;-1:-1:-1;;;;;54585:69:0;;:::o;64586:249::-;-1:-1:-1;;;;;64716:54:0;;64681:4;64716:54;;;:37;:54;;;;;;64788:39;64716:54;64788:27;:39::i;:::-;64781:46;64586:249;-1:-1:-1;;;64586:249:0:o;61337:1243::-;56266:3;56212:42;;;:30;:42;;;;;;61457:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;61614:15;61642:42;;;:30;:42;;;;;;;;;61696;;-1:-1:-1;;;61696:42:0;;;;;;;;;;-1:-1:-1;;;;;61642:42:0;;;;;;61696:24;;:42;;;;;61642;;61696;;;;;;;;61642;61696;;;5:2:-1;;;;30:1;27;20:12;5:2;61696:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61696:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;61749:22:0;61781:49;;;:37;61696:42;61781:49;;;;;-1:-1:-1;;;;;61781:49:0;61842:60;61871:12;:10;:12::i;:::-;-1:-1:-1;;;;;61842:28:0;;;61885:16;61842:60;:28;:60;:::i;:::-;61988:20;62011:85;19166:4;62011:56;62036:5;-1:-1:-1;;;;;62036:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62036:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62036:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62036:30:0;62011:20;;;-1:-1:-1;;;62011:20:0;;;;-1:-1:-1;;;;;62011:18:0;;;;;:20;;;;;62036:30;;62011:20;;;;;;;:18;:20;;;5:2:-1;;;;30:1;27;20:12;5:2;62011:20:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62011:20:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62011:20:0;;:56;:24;:56;:::i;:85::-;62107:22;62139:49;;;:37;:49;;;;;;;;;62132:83;;-1:-1:-1;;;62132:83:0;;-1:-1:-1;;;;;62132:83:0;;;;;;;;;61988:108;;-1:-1:-1;62107:22:0;;62139:49;;;62132:67;;:83;;;;;62139:49;;62132:83;;;;;62139:49;62132:83;;;5:2:-1;;;;30:1;27;20:12;5:2;62132:83:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62132:83:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62132:83:0;;-1:-1:-1;62319:23:0;62345:71;62400:15;62345:50;62132:83;54939:4;62345:50;:21;:50;:::i;:71::-;62319:97;;62459:15;;62437:18;:37;;62429:80;;;;;-1:-1:-1;;;62429:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;62541:12;:10;:12::i;:::-;-1:-1:-1;;;;;62527:45:0;;62555:16;62527:45;;;;;;;;;;;;;;;;;;17718:1;;;;;61337:1243;;;:::o;59400:338::-;55987:10;:8;:10::i;:::-;55986:11;55978:40;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;-1:-1:-1;;;55978:40:0;;;;;;;;;;;;;;;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;59544:18;;;-1:-1:-1;;;;;59574:63:0;;;-1:-1:-1;;;;;;59574:63:0;;;;;;;59653:77;;;59544:18;;;59653:77;;;59710:18;;;;59653:77;;;;;;;;;;;;;;;;17718:1;59400:338;:::o;64843:409::-;64947:4;56212:42;;;:30;:42;;;;;;64914:10;;-1:-1:-1;;;;;56212:42:0;56204:91;;;;;-1:-1:-1;;;56204:91:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;56204:91:0;;;;;;;;;;;;;;;64964:16;64983:42;;;:30;:42;;;;;;;;;65055:30;;-1:-1:-1;;;65055:30:0;;;;-1:-1:-1;;;;;64983:42:0;;;;64964:16;64983:42;;65055:28;;:30;;;;;64983:42;65055:30;;;;;64983:42;65055:30;;;5:2:-1;;;;30:1;27;20:12;5:2;65055:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65055:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65055:30:0;65116:34;;;-1:-1:-1;;;65116:34:0;;;;65055:30;;-1:-1:-1;65096:17:0;;-1:-1:-1;;;;;65116:32:0;;;;;:34;;;;;65055:30;;65116:34;;;;;;;:32;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;65116:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65116:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65116:34:0;65168:21;;:76;;;-1:-1:-1;;;65168:76:0;;;;;;;;;;;;;;;;;;;;;;65116:34;;-1:-1:-1;;;;;;65168:21:0;;;;:37;;:76;;;;;65116:34;;65168:76;;;;;;;;:21;:76;;;5:2:-1;;;;30:1;27;20:12;5:2;65168:76:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;65168:76:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;65168:76:0;;64843:409;-1:-1:-1;;;;;;64843:409:0:o;54028:55::-;;;-1:-1:-1;;;;;54028:55:0;;:::o;53919:50::-;;;-1:-1:-1;;;;;53919:50:0;;:::o;65950:270::-;-1:-1:-1;;;;;66049:40:0;;66014:4;66049:40;;;:30;:40;;;;;;66108:15;66100:48;;;;;-1:-1:-1;;;66100:48:0;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;66100:48:0;;;;;;;;;;;;;;;66178:8;-1:-1:-1;;;;;66168:42:0;;:44;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66168:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66168:44:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66168:44:0;;65950:270;-1:-1:-1;;;65950:270:0:o;56388:144::-;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;56461:33;56485:8;56461:23;:33::i;:::-;56505:19;56515:8;56505:9;:19::i;65712:230::-;65795:4;65812:16;65831:41;65856:15;65831:24;:41::i;:::-;65812:60;;65900:8;-1:-1:-1;;;;;65890:42:0;;:44;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;54438:62:0;;;;;;;;;;;;;:::o;67734:373::-;67810:4;67827:26;67856:71;19166:4;67856:42;67867:5;-1:-1:-1;;;;;67867:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67867:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67867:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67867:30:0;67856:6;;:42;:10;:42;:::i;:71::-;67827:100;;67938:23;67964:40;67997:5;67964:24;:40::i;:::-;68022:23;;:77;;;-1:-1:-1;;;68022:77:0;;-1:-1:-1;;;;;68022:77:0;;;;;;;;;;;;;;;67938:66;;-1:-1:-1;68022:23:0;;;:37;;:77;;;;;;;;;;;;;;;:23;:77;;;5:2:-1;;;;30:1;27;20:12;3793:181:0;3851:7;3883:5;;;3907:6;;;;3899:46;;;;;-1:-1:-1;;;3899:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;5165:471;5223:7;5468:6;5464:47;;-1:-1:-1;5498:1:0;5491:8;;5464:47;5535:5;;;5539:1;5535;:5;:1;5559:5;;;;;:10;5551:56;;;;-1:-1:-1;;;5551:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6104:132;6162:7;6189:39;6193:1;6196;6189:39;;;;;;;;;;;;;;;;;:3;:39::i;16198:98::-;16278:10;16198:98;:::o;12364:204::-;12491:68;;;-1:-1:-1;;;;;12491:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12491:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;12465:95:0;;12484:5;;12465:18;:95::i;:::-;12364:204;;;;:::o;23432:203::-;23504:4;-1:-1:-1;;;;;23529:21:0;;23521:68;;;;-1:-1:-1;;;23521:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;23607:20:0;:11;:20;;;;;;;;;;;;;;;23432:203::o;24601:130::-;24661:24;:8;24677:7;24661:24;:15;:24;:::i;:::-;24701:22;;-1:-1:-1;;;;;24701:22:0;;;;;;;;24601:130;:::o;24471:122::-;24528:21;:8;24541:7;24528:21;:12;:21;:::i;:::-;24565:20;;-1:-1:-1;;;;;24565:20:0;;;;;;;;24471:122;:::o;12180:176::-;12289:58;;;-1:-1:-1;;;;;12289:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;12289:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;12263:85:0;;12282:5;;12263:18;:85::i;18555:109::-;17661:9;:7;:9::i;:::-;17653:54;;;;;-1:-1:-1;;;17653:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;17653:54:0;;;;;;;;;;;;;;;18628:28;18647:8;18628:18;:28::i;6766:345::-;6852:7;6954:12;6947:5;6939:28;;;;-1:-1:-1;;;6939:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;6939:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6978:9;6994:1;6990;:5;;;;;;;6766:345;-1:-1:-1;;;;;6766:345:0:o;14219:1114::-;14823:27;14831:5;-1:-1:-1;;;;;14823:25:0;;:27::i;:::-;14815:71;;;;;-1:-1:-1;;;14815:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;14960:12;14974:23;15009:5;-1:-1:-1;;;;;15001:19:0;15021:4;15001:25;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;176:10;;164:23;;-1:-1;;139:12;;;;98:2;89:12;;;;114;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;15001:25:0;;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;14959:67:0;;;;15045:7;15037:52;;;;;-1:-1:-1;;;15037:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15106:17;;:21;15102:224;;15248:10;15237:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;15237:30:0;15229:85;;;;-1:-1:-1;;;15229:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23154:183;23234:18;23238:4;23244:7;23234:3;:18::i;:::-;23226:64;;;;-1:-1:-1;;;23226:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23301:20:0;23324:5;23301:20;;;;;;;;;;;:28;;-1:-1:-1;;23301:28:0;;;23154:183::o;22896:178::-;22974:18;22978:4;22984:7;22974:3;:18::i;:::-;22973:19;22965:63;;;;;-1:-1:-1;;;22965:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;23039:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;23039:27:0;23062:4;23039:27;;;22896:178::o;18770:229::-;-1:-1:-1;;;;;18844:22:0;;18836:73;;;;-1:-1:-1;;;18836:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18946:6;;18925:38;;-1:-1:-1;;;;;18925:38:0;;;;18946:6;;;;;18925:38;;;;;18974:6;:17;;-1:-1:-1;;;;;18974:17:0;;;;;-1:-1:-1;;;;;;18974:17:0;;;;;;;;;18770:229::o;9018:810::-;9078:4;9737:20;;9580:66;9777:15;;;;;:42;;;9808:11;9796:8;:23;;9777:42;9769:51;9018:810;-1:-1:-1;;;;9018:810:0:o

Swarm Source

bzzr://40b308e2af01060f2b41df0eed8e708021e549089b20ccd53ce7ef3c0cacd13b
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading

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.