Contract 0x5069FA2330B8Ca3ba1838F05E2Fffe432A120141

Contract Overview

Balance:
0 BNB

Token:
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x8e6ab8608ea0f519d6358a4a3fb40b951ec1c660388e10867d30023de1855722Borrow Token158842802022-01-15 11:50:112 days 14 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0009095
0x255a1943f477830277ed0d826007e805c85c87b1dfb1cea6306729b00fa32c76Borrow Token158841712022-01-15 11:44:442 days 14 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0009095
0x663b703b023043524f108c45d72ba409ae46dfad1e45a075ea693613221e6c82Borrow Token158841422022-01-15 11:43:172 days 14 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0010595
0x2efac7a807a2bf1cb89935600c036377559fe67e8824d265e809417b371235adBorrow Token158836612022-01-15 11:19:142 days 15 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0009095
0xf444987460ca0151d51b6bd5bdb1d83aeb0f23631901fd019ab88ce310df7b7dBorrow Token158836332022-01-15 11:17:502 days 15 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00090962
0x6164aaa784a301cc6f6747bd6b4e07cebed17640b76ae854a0e54f5d853d0c0dDeposit Collater...158500292022-01-14 7:17:133 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0005616
0x146ec57b171f26ca45d3af9e5f58ff6ff27601d7da42005fd9aacee205744791Deposit Collater...158410782022-01-13 23:49:404 days 2 hrs ago0x6082bcb75b7ac5eab352f3941990e1a59308e958 IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0006
0x055c81cea4a3ac8af44f75502e964c9ea295848e64d43f20999718397aebeb3dDeposit Collater...158362232022-01-13 19:46:554 days 6 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0007116
0xc1c7e18739e102f5508b1d31b6b3818e0ae35bc1e9eafdf24ee2a007b4368b29Deposit Collater...158362022022-01-13 19:45:524 days 6 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0006
0xd7abe96008498fcb8a7d24392ea91d8119222d0d064fc3c39ceec1ed67156016Borrow Token158349502022-01-13 18:43:164 days 7 hrs ago0x7805fa0360110ea6deb508b00e3d19290c9fd0e5 IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0010595
0x9c736eb51e822964edd95a2f7f46fdd20576836cada3b9a6fcfe5a2d93fbddcfDeposit Collater...158348112022-01-13 18:36:194 days 7 hrs ago0x7805fa0360110ea6deb508b00e3d19290c9fd0e5 IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00071172
0x2a52ef2bee4035c090c5cbc1cd8b73986dda939a5d2b917bcdf0d25c35809769Create Vault158246712022-01-13 9:59:154 days 16 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00150445
0xa42a73f9d00bae805c52a754551f201146206b78defc72f50704321075012879Create Vault158243252022-01-13 9:41:574 days 16 hrs ago0x7805fa0360110ea6deb508b00e3d19290c9fd0e5 IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00150445
0x60fd9ce55cf6548300dd0f9bda0f571bae171451aa4779d26a81f719f4eb69caCreate Vault158236722022-01-13 9:09:184 days 17 hrs ago0x6082bcb75b7ac5eab352f3941990e1a59308e958 IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00150445
0x6ce3f1ebf31f78cf47317d3f2d41c69a133b7a0e548b3d7d82db38e4b3ad2acdCreate Vault158228392022-01-13 8:27:394 days 17 hrs ago0xd5d8217fad745f5275dffd2b749db1afc31301a7 IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00150445
0xacbb1e14a0a9ba5c0f42519a647dfb4998b25066a6016087bcde4e7c64b2fc0cCreate Vault158226832022-01-13 8:19:514 days 18 hrs ago0xd5d8217fad745f5275dffd2b749db1afc31301a7 IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00161245
0xbfad7ff5fefd158dccbda6fb7aeedd77e420ec794b06d551247ec00a0f825c4fCreate Vault158212372022-01-13 7:07:334 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00150445
0xeef0671b7f8a98e5dafb769a95d9897f5027bc3057d680347d3df6ca81c83c21Borrow Token158205872022-01-13 6:35:034 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0009095
0x787f1b8847a0054afe5c9c304dc73b95b191619ee116ea7b8d2d7f702b21c0bfDeposit Collater...158204002022-01-13 6:25:424 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0006
0x3e4b0a970b5b4f8e8ee4931a78b90c49a67b54cf585920e621610f995dbc3736Deposit Collater...158203802022-01-13 6:24:424 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0006
0x326ce381a8494f39a4c76e8a962f307ffd7158b1d41e93c68f758309cfa5f1c4Deposit Collater...158203372022-01-13 6:22:334 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0006
0xfb782e728936ee8cde65e2f613b6a901eb7d6a541015c2bdd934ba4653ee4a15Deposit Collater...158203242022-01-13 6:21:544 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00056196
0xbd569e8359d989052e88480c0c883779376d3f1250428928284b178b10c394faDeposit Collater...158203062022-01-13 6:21:004 days 19 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0012
0xe8e2278fa6b1f6777e9da60ceef1458c02713c1aeca96cbb3b4a29c11200e84fDeposit Collater...158202752022-01-13 6:19:274 days 20 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.0006
0xa93e263c80e491e262ec358ef54134c22184d94f043f9e1b1db61430d1ed90c6Create Vault158201662022-01-13 6:14:004 days 20 hrs ago0x9b6a04053f7374a18ed4ae6c2eeaf60666ee7e8b IN  0x5069fa2330b8ca3ba1838f05e2fffe432a1201410 BNB0.00150445
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x8e6ab8608ea0f519d6358a4a3fb40b951ec1c660388e10867d30023de1855722158842802022-01-15 11:50:112 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x8e6ab8608ea0f519d6358a4a3fb40b951ec1c660388e10867d30023de1855722158842802022-01-15 11:50:112 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x8e6ab8608ea0f519d6358a4a3fb40b951ec1c660388e10867d30023de1855722158842802022-01-15 11:50:112 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x8e6ab8608ea0f519d6358a4a3fb40b951ec1c660388e10867d30023de1855722158842802022-01-15 11:50:112 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xd66c6b4f0be8ce5b39d52e0fd1344c389929b3780 BNB
0x8e6ab8608ea0f519d6358a4a3fb40b951ec1c660388e10867d30023de1855722158842802022-01-15 11:50:112 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x8e6ab8608ea0f519d6358a4a3fb40b951ec1c660388e10867d30023de1855722158842802022-01-15 11:50:112 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x255a1943f477830277ed0d826007e805c85c87b1dfb1cea6306729b00fa32c76158841712022-01-15 11:44:442 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x255a1943f477830277ed0d826007e805c85c87b1dfb1cea6306729b00fa32c76158841712022-01-15 11:44:442 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x255a1943f477830277ed0d826007e805c85c87b1dfb1cea6306729b00fa32c76158841712022-01-15 11:44:442 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x255a1943f477830277ed0d826007e805c85c87b1dfb1cea6306729b00fa32c76158841712022-01-15 11:44:442 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xd66c6b4f0be8ce5b39d52e0fd1344c389929b3780 BNB
0x255a1943f477830277ed0d826007e805c85c87b1dfb1cea6306729b00fa32c76158841712022-01-15 11:44:442 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x255a1943f477830277ed0d826007e805c85c87b1dfb1cea6306729b00fa32c76158841712022-01-15 11:44:442 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x663b703b023043524f108c45d72ba409ae46dfad1e45a075ea693613221e6c82158841422022-01-15 11:43:172 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x663b703b023043524f108c45d72ba409ae46dfad1e45a075ea693613221e6c82158841422022-01-15 11:43:172 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x663b703b023043524f108c45d72ba409ae46dfad1e45a075ea693613221e6c82158841422022-01-15 11:43:172 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x663b703b023043524f108c45d72ba409ae46dfad1e45a075ea693613221e6c82158841422022-01-15 11:43:172 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xd66c6b4f0be8ce5b39d52e0fd1344c389929b3780 BNB
0x663b703b023043524f108c45d72ba409ae46dfad1e45a075ea693613221e6c82158841422022-01-15 11:43:172 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x663b703b023043524f108c45d72ba409ae46dfad1e45a075ea693613221e6c82158841422022-01-15 11:43:172 days 14 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x2efac7a807a2bf1cb89935600c036377559fe67e8824d265e809417b371235ad158836612022-01-15 11:19:142 days 15 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x2efac7a807a2bf1cb89935600c036377559fe67e8824d265e809417b371235ad158836612022-01-15 11:19:142 days 15 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x2efac7a807a2bf1cb89935600c036377559fe67e8824d265e809417b371235ad158836612022-01-15 11:19:142 days 15 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0x2efac7a807a2bf1cb89935600c036377559fe67e8824d265e809417b371235ad158836612022-01-15 11:19:142 days 15 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xd66c6b4f0be8ce5b39d52e0fd1344c389929b3780 BNB
0x2efac7a807a2bf1cb89935600c036377559fe67e8824d265e809417b371235ad158836612022-01-15 11:19:142 days 15 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0x143db3ceefbdfe5631add3e50f7614b6ba708ba70 BNB
0x2efac7a807a2bf1cb89935600c036377559fe67e8824d265e809417b371235ad158836612022-01-15 11:19:142 days 15 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
0xf444987460ca0151d51b6bd5bdb1d83aeb0f23631901fd019ab88ce310df7b7d158836332022-01-15 11:17:502 days 15 hrs ago 0x5069fa2330b8ca3ba1838f05e2fffe432a120141 0xc9f654d481e79d01448030b08516b7f9fcf71e130 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
erc20QiStablecoin

Compiler Version
v0.5.16+commit.9c3226ce

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at BscScan.com on 2021-11-03
*/

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 {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

    /**
     * @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: @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.
     *
     * [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.
     *
     * Among others, `isContract` will return false for the following 
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // 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 != accountHash && codehash != 0x0);
    }

    /**
     * @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/token/ERC20/ERC20.sol

pragma solidity ^0.5.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20Mintable}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20 {
    using SafeMath for uint256;

    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20};
     *
     * Requirements:
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for `sender`'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply = _totalSupply.add(amount);
        _balances[account] = _balances[account].add(amount);
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal {
        require(account != address(0), "ERC20: burn from the zero address");

        _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
        _totalSupply = _totalSupply.sub(amount);
        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens.
     *
     * This is internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`.`amount` is then deducted
     * from the caller's allowance.
     *
     * See {_burn} and {_approve}.
     */
    function _burnFrom(address account, uint256 amount) internal {
        _burn(account, amount);
        _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance"));
    }
}

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

pragma solidity ^0.5.0;


/**
 * @dev Optional functions from the ERC20 standard.
 */
contract ERC20Detailed is IERC20 {
    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of
     * these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol, uint8 decimals) public {
        _name = name;
        _symbol = symbol;
        _decimals = decimals;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view returns (string memory) {
        return _name;
    }

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

    /**
     * @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() public view returns (uint8) {
        return _decimals;
    }
}

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

pragma solidity ^0.5.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 *
 * _Since v2.5.0:_ this module is now much more gas efficient, given net gas
 * metering changes introduced in the Istanbul hardfork.
 */
contract ReentrancyGuard {
    bool private _notEntered;

    constructor () internal {
        // Storing an initial non-zero value makes deployment a bit more
        // expensive, but in exchange the refund on every call to nonReentrant
        // will be lower in amount. Since refunds are capped to a percetange of
        // the total transaction's gas, it is best to keep them low in cases
        // like this one, to increase the likelihood of the full refund coming
        // into effect.
        _notEntered = true;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_notEntered, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _notEntered = false;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _notEntered = true;
    }
}

// File: contracts/PriceSource.sol

pragma solidity ^0.5.0;

interface PriceSource {
    function latestRoundData() external view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}

// File: @openzeppelin/contracts/introspection/IERC165.sol

pragma solidity ^0.5.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol

pragma solidity ^0.5.0;


/**
 * @dev Required interface of an ERC721 compliant contract.
 */
contract IERC721 is IERC165 {
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of NFTs in `owner`'s account.
     */
    function balanceOf(address owner) public view returns (uint256 balance);

    /**
     * @dev Returns the owner of the NFT specified by `tokenId`.
     */
    function ownerOf(uint256 tokenId) public view returns (address owner);

    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     *
     *
     * Requirements:
     * - `from`, `to` cannot be zero.
     * - `tokenId` must be owned by `from`.
     * - If the caller is not `from`, it must be have been allowed to move this
     * NFT by either {approve} or {setApprovalForAll}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public;
    /**
     * @dev Transfers a specific NFT (`tokenId`) from one account (`from`) to
     * another (`to`).
     *
     * Requirements:
     * - If the caller is not `from`, it must be approved to move this NFT by
     * either {approve} or {setApprovalForAll}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public;
    function approve(address to, uint256 tokenId) public;
    function getApproved(uint256 tokenId) public view returns (address operator);

    function setApprovalForAll(address operator, bool _approved) public;
    function isApprovedForAll(address owner, address operator) public view returns (bool);


    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public;
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

pragma solidity ^0.5.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
    /**
     * @notice Handle the receipt of an NFT
     * @dev The ERC721 smart contract calls this function on the recipient
     * after a {IERC721-safeTransferFrom}. This function MUST return the function selector,
     * otherwise the caller will revert the transaction. The selector to be
     * returned can be obtained as `this.onERC721Received.selector`. This
     * function MAY throw to revert and reject the transfer.
     * Note: the ERC721 contract address is always the message sender.
     * @param operator The address which called `safeTransferFrom` function
     * @param from The address which previously owned the token
     * @param tokenId The NFT identifier which is being transferred
     * @param data Additional data with no specified format
     * @return bytes4 `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
     */
    function onERC721Received(address operator, address from, uint256 tokenId, bytes memory data)
    public returns (bytes4);
}

// File: @openzeppelin/contracts/drafts/Counters.sol

pragma solidity ^0.5.0;


/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 * Since it is not possible to overflow a 256 bit integer with increments of one, `increment` can skip the {SafeMath}
 * overflow check, thereby saving gas. This does assume however correct usage, in that the underlying `_value` is never
 * directly accessed.
 */
library Counters {
    using SafeMath for uint256;

    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        // The {SafeMath} overflow check can be skipped here, see the comment at the top
        counter._value += 1;
    }

    function decrement(Counter storage counter) internal {
        counter._value = counter._value.sub(1);
    }
}

// File: @openzeppelin/contracts/introspection/ERC165.sol

pragma solidity ^0.5.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol

pragma solidity ^0.5.0;








/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is Context, ERC165, IERC721 {
    using SafeMath for uint256;
    using Address for address;
    using Counters for Counters.Counter;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from token ID to owner
    mapping (uint256 => address) private _tokenOwner;

    // Mapping from token ID to approved address
    mapping (uint256 => address) private _tokenApprovals;

    // Mapping from owner to number of owned token
    mapping (address => Counters.Counter) private _ownedTokensCount;

    // Mapping from owner to operator approvals
    mapping (address => mapping (address => bool)) private _operatorApprovals;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    constructor () public {
        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner address to query the balance of
     * @return uint256 representing the amount owned by the passed address
     */
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }

    /**
     * @dev Gets the owner of the specified token ID.
     * @param tokenId uint256 ID of the token to query the owner of
     * @return address currently marked as the owner of the given token ID
     */
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");

        return owner;
    }

    /**
     * @dev Approves another address to transfer the given token ID
     * The zero address indicates there is no approved address.
     * There can only be one approved address per token at a given time.
     * Can only be called by the token owner or an approved operator.
     * @param to address to be approved for the given token ID
     * @param tokenId uint256 ID of the token to be approved
     */
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Gets the approved address for a token ID, or zero if no address set
     * Reverts if the token ID does not exist.
     * @param tokenId uint256 ID of the token to query the approval of
     * @return address currently approved for the given token ID
     */
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Sets or unsets the approval of a given operator
     * An operator is allowed to transfer all tokens of the sender on their behalf.
     * @param to operator address to set the approval
     * @param approved representing the status of the approval to be set
     */
    function setApprovalForAll(address to, bool approved) public {
        require(to != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][to] = approved;
        emit ApprovalForAll(_msgSender(), to, approved);
    }

    /**
     * @dev Tells whether an operator is approved by a given owner.
     * @param owner owner address which you want to query the approval of
     * @param operator operator address which you want to query the approval of
     * @return bool whether the given operator is approved by the given owner
     */
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev Transfers the ownership of a given token ID to another address.
     * Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     * Requires the msg.sender to be the owner, approved, or operator.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement {IERC721Receiver-onERC721Received},
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the _msgSender() to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransferFrom(from, to, tokenId, _data);
    }

    /**
     * @dev Safely transfers the ownership of a given token ID to another address
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * Requires the msg.sender to be the owner, approved, or operator
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) internal {
        _transferFrom(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether the specified token exists.
     * @param tokenId uint256 ID of the token to query the existence of
     * @return bool whether the token exists
     */
    function _exists(uint256 tokenId) internal view returns (bool) {
        address owner = _tokenOwner[tokenId];
        return owner != address(0);
    }

    /**
     * @dev Returns whether the given spender can transfer a given token ID.
     * @param spender address of the spender to query
     * @param tokenId uint256 ID of the token to be transferred
     * @return bool whether the msg.sender is approved for the given token ID,
     * is an operator of the owner, or is the owner of the token
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _safeMint(address to, uint256 tokenId) internal {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Internal function to safely mint a new token.
     * Reverts if the given token ID already exists.
     * If the target address is a contract, it must implement `onERC721Received`,
     * which is called upon a safe transfer, and return the magic value
     * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
     * the transfer is reverted.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     * @param _data bytes data to send along with a safe transfer check
     */
    function _safeMint(address to, uint256 tokenId, bytes memory _data) internal {
        _mint(to, tokenId);
        require(_checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to The address that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _tokenOwner[tokenId] = to;
        _ownedTokensCount[to].increment();

        emit Transfer(address(0), to, tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {_burn} instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        require(ownerOf(tokenId) == owner, "ERC721: burn of token that is not own");

        _clearApproval(tokenId);

        _ownedTokensCount[owner].decrement();
        _tokenOwner[tokenId] = address(0);

        emit Transfer(owner, address(0), tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(uint256 tokenId) internal {
        _burn(ownerOf(tokenId), tokenId);
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        require(ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _clearApproval(tokenId);

        _ownedTokensCount[from].decrement();
        _ownedTokensCount[to].increment();

        _tokenOwner[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * This is an internal detail of the `ERC721` contract and its use is deprecated.
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param _data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory _data)
        internal returns (bool)
    {
        if (!to.isContract()) {
            return true;
        }
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = to.call(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ));
        if (!success) {
            if (returndata.length > 0) {
                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert("ERC721: transfer to non ERC721Receiver implementer");
            }
        } else {
            bytes4 retval = abi.decode(returndata, (bytes4));
            return (retval == _ERC721_RECEIVED);
        }
    }

    /**
     * @dev Private function to clear current approval of a given token ID.
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _clearApproval(uint256 tokenId) private {
        if (_tokenApprovals[tokenId] != address(0)) {
            _tokenApprovals[tokenId] = address(0);
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Enumerable.sol

pragma solidity ^0.5.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Enumerable is IERC721 {
    function totalSupply() public view returns (uint256);
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256 tokenId);

    function tokenByIndex(uint256 index) public view returns (uint256);
}

// File: @openzeppelin/contracts/token/ERC721/ERC721Enumerable.sol

pragma solidity ^0.5.0;





/**
 * @title ERC-721 Non-Fungible Token with optional enumeration extension logic
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Enumerable is Context, ERC165, ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => uint256[]) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

    /**
     * @dev Constructor function.
     */
    constructor () public {
        // register the supported interface to conform to ERC721Enumerable via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

    /**
     * @dev Gets the token ID at a given index of the tokens list of the requested owner.
     * @param owner address owning the tokens list to be accessed
     * @param index uint256 representing the index to be accessed of the requested tokens list
     * @return uint256 token ID at the given index of the tokens list owned by the requested address
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev Gets the total amount of tokens stored by the contract.
     * @return uint256 representing the total amount of tokens
     */
    function totalSupply() public view returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev Gets the token ID at a given index of all the tokens in this contract
     * Reverts if the index is greater or equal to the total number of tokens.
     * @param index uint256 representing the index to be accessed of the tokens list
     * @return uint256 token ID at the given index of the tokens list
     */
    function tokenByIndex(uint256 index) public view returns (uint256) {
        require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Internal function to transfer ownership of a given token ID to another address.
     * As opposed to transferFrom, this imposes no restrictions on msg.sender.
     * @param from current owner of the token
     * @param to address to receive the ownership of the given token ID
     * @param tokenId uint256 ID of the token to be transferred
     */
    function _transferFrom(address from, address to, uint256 tokenId) internal {
        super._transferFrom(from, to, tokenId);

        _removeTokenFromOwnerEnumeration(from, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);
    }

    /**
     * @dev Internal function to mint a new token.
     * Reverts if the given token ID already exists.
     * @param to address the beneficiary that will own the minted token
     * @param tokenId uint256 ID of the token to be minted
     */
    function _mint(address to, uint256 tokenId) internal {
        super._mint(to, tokenId);

        _addTokenToOwnerEnumeration(to, tokenId);

        _addTokenToAllTokensEnumeration(tokenId);
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use {ERC721-_burn} instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        _removeTokenFromOwnerEnumeration(owner, tokenId);
        // Since tokenId will be deleted, we can clear its slot in _ownedTokensIndex to trigger a gas refund
        _ownedTokensIndex[tokenId] = 0;

        _removeTokenFromAllTokensEnumeration(tokenId);
    }

    /**
     * @dev Gets the list of token IDs of the requested owner.
     * @param owner address owning the tokens
     * @return uint256[] List of token IDs owned by the requested address
     */
    function _tokensOfOwner(address owner) internal view returns (uint256[] storage) {
        return _ownedTokens[owner];
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        _ownedTokensIndex[tokenId] = _ownedTokens[to].length;
        _ownedTokens[to].push(tokenId);
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        _ownedTokens[from].length--;

        // Note that _ownedTokensIndex[tokenId] hasn't been cleared: it still points to the old slot (now occupied by
        // lastTokenId, or just over the end of the array if the token was the last one).
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length.sub(1);
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        _allTokens.length--;
        _allTokensIndex[tokenId] = 0;
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Metadata.sol

pragma solidity ^0.5.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
contract IERC721Metadata is IERC721 {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

// File: @openzeppelin/contracts/token/ERC721/ERC721Metadata.sol

pragma solidity ^0.5.0;





contract ERC721Metadata is Context, ERC165, ERC721, IERC721Metadata {
    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Base URI
    string private _baseURI;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /**
     * @dev Constructor function
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
    }

    /**
     * @dev Gets the token name.
     * @return string representing the token name
     */
    function name() external view returns (string memory) {
        return _name;
    }

    /**
     * @dev Gets the token symbol.
     * @return string representing the token symbol
     */
    function symbol() external view returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the URI for a given token ID. May return an empty string.
     *
     * If the token's URI is non-empty and a base URI was set (via
     * {_setBaseURI}), it will be added to the token ID's URI as a prefix.
     *
     * Reverts if the token ID does not exist.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];

        // Even if there is a base URI, it is only appended to non-empty token-specific URIs
        if (bytes(_tokenURI).length == 0) {
            return "";
        } else {
            // abi.encodePacked is being used to concatenate strings
            return string(abi.encodePacked(_baseURI, _tokenURI));
        }
    }

    /**
     * @dev Internal function to set the token URI for a given token.
     *
     * Reverts if the token ID does not exist.
     *
     * TIP: if all token IDs share a prefix (e.g. if your URIs look like
     * `http://api.myproject.com/token/<id>`), use {_setBaseURI} to store
     * it and save gas.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI}.
     *
     * _Available since v2.5.0._
     */
    function _setBaseURI(string memory baseURI) internal {
        _baseURI = baseURI;
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a preffix in {tokenURI} to each token's URI, when
    * they are non-empty.
    *
    * _Available since v2.5.0._
    */
    function baseURI() external view returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev Internal function to burn a specific token.
     * Reverts if the token does not exist.
     * Deprecated, use _burn(uint256) instead.
     * @param owner owner of the token to burn
     * @param tokenId uint256 ID of the token being burned by the msg.sender
     */
    function _burn(address owner, uint256 tokenId) internal {
        super._burn(owner, tokenId);

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/ERC721Full.sol

pragma solidity ^0.5.0;




/**
 * @title Full ERC721 Token
 * @dev This implementation includes all the required and some optional functionality of the ERC721 standard
 * Moreover, it includes approve all functionality using operator terminology.
 *
 * See https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata {
    constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) {
        // solhint-disable-previous-line no-empty-blocks
    }
}

// File: contracts/interfaces/IVaultMetaProvider.sol

pragma solidity 0.5.16;

interface IVaultMetaProvider {
    function getTokenURI(address vault_address, uint256 tokenId) external view returns (string memory);
    function getBaseURI() external view returns (string memory);
}

// File: contracts/interfaces/IVaultMetaRegistry.sol

pragma solidity 0.5.16;

interface IVaultMetaRegistry {
    function getMetaProvider(address vault_address) external view returns (address);
}

// File: contracts/MyVaultV3.sol

// contracts/MyVaultNFT.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.5.16;





contract VaultNFTv3 is ERC721Full {

    address public _meta;
    string public base;

    constructor(string memory name, string memory symbol, address meta, string memory baseURI)
        public
        ERC721Full(name, symbol)
    {
        _meta = meta;
        base=baseURI;
    }

    function tokenURI(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId));

        IVaultMetaRegistry registry = IVaultMetaRegistry(_meta);
        IVaultMetaProvider provider = IVaultMetaProvider(registry.getMetaProvider(address(this)));

        return bytes(base).length > 0 ? string(abi.encodePacked(base, provider.getTokenURI(address(this), tokenId))) : "";
    }
}

// File: contracts/erc20Stablecoin/erc20Stablecoin.sol

pragma solidity 0.5.16;








contract erc20Stablecoin is ReentrancyGuard, VaultNFTv3 {
    PriceSource public ethPriceSource;
    
    using SafeMath for uint256;
    using SafeERC20 for ERC20Detailed;

    uint256 public _minimumCollateralPercentage;

    uint256 public vaultCount;
    uint256 public closingFee;
    uint256 public openingFee;

    uint256 public treasury;
    uint256 public tokenPeg;

    mapping(uint256 => uint256) public vaultCollateral;
    mapping(uint256 => uint256) public vaultDebt;

    uint256 public debtRatio;
    uint256 public gainRatio;

    address public stabilityPool;

    ERC20Detailed public collateral;

    ERC20Detailed public ghostDai;

    uint8 public priceSourceDecimals;

    event CreateVault(uint256 vaultID, address creator);
    event DestroyVault(uint256 vaultID);
    event TransferVault(uint256 vaultID, address from, address to);
    event DepositCollateral(uint256 vaultID, uint256 amount);
    event WithdrawCollateral(uint256 vaultID, uint256 amount);
    event BorrowToken(uint256 vaultID, uint256 amount);
    event PayBackToken(uint256 vaultID, uint256 amount, uint256 closingFee);
    event LiquidateVault(uint256 vaultID, address owner, address buyer, uint256 debtRepaid, uint256 collateralLiquidated, uint256 closingFee);

    mapping(address => uint256) public ethDebt;

    constructor(
        address ethPriceSourceAddress,
        uint256 minimumCollateralPercentage,
        string memory name,
        string memory symbol,
        address _ghostDai,
        address _collateral,
        address meta,
        string memory baseURI
    ) VaultNFTv3(name, symbol, meta, baseURI) public {
        assert(ethPriceSourceAddress != address(0));
        assert(minimumCollateralPercentage != 0);
                        //  | decimals start here
        closingFee=50; // 0.5%
        openingFee=0; // 0.0%
        ethPriceSource = PriceSource(ethPriceSourceAddress);
        stabilityPool = address(0);
        tokenPeg = 100000000; // $1

        debtRatio = 2; // 1/2, pay back 50%
        gainRatio = 1100;// /10 so 1.1

        _minimumCollateralPercentage = minimumCollateralPercentage;

        collateral = ERC20Detailed(_collateral);
        ghostDai = ERC20Detailed(_ghostDai);
    }

    modifier onlyVaultOwner(uint256 vaultID) {
        require(_exists(vaultID), "Vault does not exist");
        require(ownerOf(vaultID) == msg.sender, "Vault is not owned by you");
        _;
    }

    function getDebtCeiling() public view returns (uint256){
        return ghostDai.balanceOf(address(this));
    }

    function exists(uint256 vaultID) external view returns (bool){
        return _exists(vaultID);
    }

    function getClosingFee() external view returns (uint256){
        return closingFee;
    }

    function getOpeningFee() external view returns (uint256){
        return openingFee;
    }

    function getTokenPriceSource() public view returns (uint256){
        return tokenPeg;
    }

    function getEthPriceSource() public view returns (uint256){
        (,int256 price,,,) = ethPriceSource.latestRoundData();
        return uint256(price);
    }

    function calculateCollateralProperties(uint256 _collateral, uint256 _debt) private view returns (uint256, uint256) {

        assert(getEthPriceSource() != 0);
        assert(getTokenPriceSource() != 0);

        uint256 collateralValue = _collateral.mul(getEthPriceSource()).mul(10**(uint256(ghostDai.decimals()).sub(uint256(collateral.decimals()))));

        assert(collateralValue >= _collateral);

        uint256 debtValue = _debt.mul(getTokenPriceSource());

        assert(debtValue >= _debt);

        uint256 collateralValueTimes100 = collateralValue.mul(100);

        assert(collateralValueTimes100 > collateralValue);

        return (collateralValueTimes100, debtValue);
    }

    function isValidCollateral(uint256 collateral, uint256 debt) private view returns (bool) {
        (uint256 collateralValueTimes100, uint256 debtValue) = calculateCollateralProperties(collateral, debt);

        uint256 collateralPercentage = collateralValueTimes100.div(debtValue);

        return collateralPercentage >= _minimumCollateralPercentage;
    }

    function createVault() external returns (uint256) {
        uint256 id = vaultCount;
        vaultCount = vaultCount.add(1);

        assert(vaultCount >= id);

        _mint(msg.sender,id);

        emit CreateVault(id, msg.sender);

        return id;
    }

    function destroyVault(uint256 vaultID) external onlyVaultOwner(vaultID) nonReentrant {
        require(vaultDebt[vaultID] == 0, "Vault has outstanding debt");

        if(vaultCollateral[vaultID]!=0) {
            // withdraw leftover collateral
            collateral.safeTransfer(ownerOf(vaultID), vaultCollateral[vaultID]);
        }

        _burn(vaultID);

        delete vaultCollateral[vaultID];
        delete vaultDebt[vaultID];

        emit DestroyVault(vaultID);
    }

    function depositCollateral(uint256 vaultID, uint256 amount) external {

        collateral.safeTransferFrom(msg.sender, address(this), amount);

        uint256 newCollateral = vaultCollateral[vaultID].add(amount);

        assert(newCollateral >= vaultCollateral[vaultID]);

        vaultCollateral[vaultID] = newCollateral;

        emit DepositCollateral(vaultID, amount);
    }

    function withdrawCollateral(uint256 vaultID, uint256 amount) external onlyVaultOwner(vaultID) nonReentrant {
        require(vaultCollateral[vaultID] >= amount, "Vault does not have enough collateral");

        uint256 newCollateral = vaultCollateral[vaultID].sub(amount);

        if(vaultDebt[vaultID] != 0) {
            require(isValidCollateral(newCollateral, vaultDebt[vaultID]), "Withdrawal would put vault below minimum collateral percentage");
        }

        vaultCollateral[vaultID] = newCollateral;
        collateral.safeTransfer(msg.sender, amount);

        emit WithdrawCollateral(vaultID, amount);
    }

    function borrowToken(uint256 vaultID, uint256 amount) external onlyVaultOwner(vaultID) {
        require(amount > 0, "Must borrow non-zero amount");
        require(amount <= getDebtCeiling(), "borrowToken: Cannot mint over available supply.");

        uint256 newDebt = vaultDebt[vaultID].add(amount);

        assert(newDebt > vaultDebt[vaultID]);

        require(isValidCollateral(vaultCollateral[vaultID], newDebt), "Borrow would put vault below minimum collateral percentage");

        vaultDebt[vaultID] = newDebt;

        // ghostDai
        ghostDai.safeTransfer(msg.sender, amount);

        emit BorrowToken(vaultID, amount);
    }

    function payBackToken(uint256 vaultID, uint256 amount) external {
        require(ghostDai.balanceOf(msg.sender) >= amount, "Token balance too low");
        require(vaultDebt[vaultID] >= amount, "Vault debt less than amount to pay back");

        uint256 _closingFee = (amount.mul(closingFee).mul(getTokenPriceSource())).div(getEthPriceSource().mul(10000));

        //ghostDai
        ghostDai.safeTransferFrom(msg.sender, address(this), amount);

        vaultDebt[vaultID] = vaultDebt[vaultID].sub(amount);
        vaultCollateral[vaultID]=vaultCollateral[vaultID].sub(_closingFee);
        vaultCollateral[treasury]=vaultCollateral[treasury].add(_closingFee);

        emit PayBackToken(vaultID, amount, _closingFee);
    }

    function getPaid() public nonReentrant {
        require(ethDebt[msg.sender]!=0, "Don't have anything for you.");
        uint256 amount = ethDebt[msg.sender];
        ethDebt[msg.sender]=0;
        collateral.safeTransfer(msg.sender, amount);
    }

    function checkCost(uint256 vaultID) public view returns (uint256) {

        if(vaultCollateral[vaultID] == 0 || vaultDebt[vaultID]==0 || !checkLiquidation(vaultID) ){
            return 0;
        }

        (uint256 collateralValueTimes100, uint256 debtValue) = calculateCollateralProperties(vaultCollateral[vaultID], vaultDebt[vaultID]);

        if(debtValue==0){
            return 0;
        }
        
        uint256 collateralPercentage = collateralValueTimes100.div(debtValue);

        debtValue = debtValue.div(10 ** priceSourceDecimals);

        uint256 halfDebt = debtValue.div(debtRatio); //debtRatio (2)

        return(halfDebt);
    }

    function checkExtract(uint256 vaultID) public view returns (uint256) {

        if(vaultCollateral[vaultID] == 0|| !checkLiquidation(vaultID) ) {
            return 0;
        }

        (uint256 collateralValueTimes100, uint256 debtValue) = calculateCollateralProperties(vaultCollateral[vaultID], vaultDebt[vaultID]);

        uint256 halfDebt = debtValue.div(debtRatio); //debtRatio (2)

        if(halfDebt==0){
            return 0;
        }
        return halfDebt.mul(gainRatio).div(1000).div(getEthPriceSource());
    }

    function checkCollateralPercentage(uint256 vaultID) public view returns(uint256){
        require(_exists(vaultID), "Vault does not exist");

        if(vaultCollateral[vaultID] == 0 || vaultDebt[vaultID]==0){
            return 0;
        }
        (uint256 collateralValueTimes100, uint256 debtValue) = calculateCollateralProperties(vaultCollateral[vaultID], vaultDebt[vaultID]);

        return collateralValueTimes100.div(debtValue);
    }

    function checkLiquidation(uint256 vaultID) public view returns (bool) {
        require(_exists(vaultID), "Vault does not exist");
        
        if(vaultCollateral[vaultID] == 0 || vaultDebt[vaultID]==0){
            return false;
        }

        (uint256 collateralValueTimes100, uint256 debtValue) = calculateCollateralProperties(vaultCollateral[vaultID], vaultDebt[vaultID]);

        uint256 collateralPercentage = collateralValueTimes100.div(debtValue);

        if(collateralPercentage < _minimumCollateralPercentage){
            return true;
        } else{
            return false;
        }
    }

    function liquidateVault(uint256 vaultID) external {
        require(_exists(vaultID), "Vault does not exist");
        require(stabilityPool==address(0) || msg.sender ==  stabilityPool, "liquidation is disabled for public");

        (uint256 collateralValueTimes100, uint256 debtValue) = calculateCollateralProperties(vaultCollateral[vaultID], vaultDebt[vaultID]);

        uint256 collateralPercentage = collateralValueTimes100.div(debtValue);

        require(collateralPercentage < _minimumCollateralPercentage, "Vault is not below minimum collateral percentage");

        debtValue = debtValue.div(10 ** priceSourceDecimals);

        uint256 halfDebt = debtValue.div(debtRatio); //debtRatio (2)

        require(ghostDai.balanceOf(msg.sender) >= halfDebt, "Token balance too low to pay off outstanding debt");

        //ghostDai
        ghostDai.safeTransferFrom(msg.sender, address(this), halfDebt);

        uint256 ethExtract = checkExtract(vaultID);

        vaultDebt[vaultID] = vaultDebt[vaultID].sub(halfDebt); // we paid back half of its debt.

        uint256 _closingFee = (halfDebt.mul(closingFee).mul(getTokenPriceSource()) ).div(getEthPriceSource().mul(10000));
     
        vaultCollateral[vaultID]=vaultCollateral[vaultID].sub(_closingFee);
        vaultCollateral[treasury]=vaultCollateral[treasury].add(_closingFee);

        // deduct the amount from the vault's collateral
        vaultCollateral[vaultID] = vaultCollateral[vaultID].sub(ethExtract);

        // let liquidator take the collateral
        ethDebt[msg.sender] = ethDebt[msg.sender].add(ethExtract);

        emit LiquidateVault(vaultID, ownerOf(vaultID), msg.sender, halfDebt, ethExtract, _closingFee);
    }
}

// File: contracts/erc20Stablecoin/erc20QiStablecoin.sol

pragma solidity 0.5.16;



contract erc20QiStablecoin is erc20Stablecoin, Ownable {

    constructor(
        address ethPriceSourceAddress,
        uint256 minimumCollateralPercentage,
        string memory name,
        string memory symbol,
        address _ghostDai,
        address _collateral,
        address meta,
        string memory baseURI
    ) erc20Stablecoin(
        ethPriceSourceAddress,
        minimumCollateralPercentage,
        name,
        symbol,
        _ghostDai,
        _collateral,
        meta,
        baseURI
    ) public {
        treasury=0;
    }

    function setGainRatio(uint256 _gainRatio) external onlyOwner() {
        gainRatio=_gainRatio;
    }

    function setDebtRatio(uint256 _debtRatio) external onlyOwner() {
        debtRatio=_debtRatio;
    }

    // management function
    function transferToken(address to, address token, uint256 amountToken) external onlyOwner() {
        ERC20(token).transfer(to, amountToken);
    }

    function changeEthPriceSource(address ethPriceSourceAddress) external onlyOwner() {
        ethPriceSource = PriceSource(ethPriceSourceAddress);
    }

    function setTokenPeg(uint256 _tokenPeg) external onlyOwner() {
        tokenPeg = _tokenPeg;
    }

    function setStabilityPool(address _pool) external onlyOwner() {
        stabilityPool = _pool;
    }

    function setMinCollateralRatio(uint256 minimumCollateralPercentage) external onlyOwner() {
        _minimumCollateralPercentage = minimumCollateralPercentage;
    }

    function setClosingFee(uint256 amount) external onlyOwner() {
        closingFee = amount;
    }

    function setOpeningFee(uint256 amount) external onlyOwner() {
        openingFee = amount;
    }

    function setTreasury(uint256 _treasury) external onlyOwner() {
        require(_exists(_treasury), "Vault does not exist");
        treasury = _treasury;
    }

    function transferToken(uint256 amountToken) public onlyOwner() {
        // Transfer reserve tokens back to main ghostDai contract
        ghostDai.transfer(address(ghostDai), amountToken);
    }

    function setBaseURI(string memory baseURI) public onlyOwner() {
        _setBaseURI(baseURI);
    }
}

Contract ABI

[{"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"},{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"_ghostDai","type":"address"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"address","name":"meta","type":"address"},{"internalType":"string","name":"baseURI","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BorrowToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"CreateVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"DestroyVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRepaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralLiquidated","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"LiquidateVault","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":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"PayBackToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"TransferVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawCollateral","type":"event"},{"constant":true,"inputs":[],"name":"_meta","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_minimumCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"base","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"borrowToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"}],"name":"changeEthPriceSource","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkExtract","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkLiquidation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"closingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"collateral","outputs":[{"internalType":"contract ERC20Detailed","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"createVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"destroyVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ethPriceSource","outputs":[{"internalType":"contract PriceSource","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"gainRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getClosingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getDebtCeiling","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getEthPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getOpeningFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"getPaid","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getTokenPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ghostDai","outputs":[{"internalType":"contract ERC20Detailed","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","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":false,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"liquidateVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"openingFee","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":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"payBackToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"priceSourceDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setClosingFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"setDebtRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_gainRatio","type":"uint256"}],"name":"setGainRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"}],"name":"setMinCollateralRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setOpeningFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"setStabilityPool","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenPeg","type":"uint256"}],"name":"setTokenPeg","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_treasury","type":"uint256"}],"name":"setTreasury","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"stabilityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenPeg","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","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":false,"inputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"}],"name":"transferToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountToken","type":"uint256"}],"name":"transferToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"treasury","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vaultCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vaultCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162004cdc38038062004cdc83398181016040526101008110156200003857600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006457600080fd5b9083019060208201858111156200007a57600080fd5b82516401000000008111828201881017156200009557600080fd5b82525081516020918201929091019080838360005b83811015620000c4578181015183820152602001620000aa565b50505050905090810190601f168015620000f25780820380516001836020036101000a031916815260200191505b50604052602001805160405193929190846401000000008211156200011657600080fd5b9083019060208201858111156200012c57600080fd5b82516401000000008111828201881017156200014757600080fd5b82525081516020918201929091019080838360005b83811015620001765781810151838201526020016200015c565b50505050905090810190601f168015620001a45780820380516001836020036101000a031916815260200191505b50604081815260208301519083015160608401516080909401805192969195919284640100000000821115620001d957600080fd5b908301906020820185811115620001ef57600080fd5b82516401000000008111828201881017156200020a57600080fd5b82525081516020918201929091019080838360005b83811015620002395781810151838201526020016200021f565b50505050905090810190601f168015620002675780820380516001836020036101000a031916815260200191505b5060405250506000805460ff191660011790555087878787878787878585838383838181620002a66301ffc9a760e01b6001600160e01b036200045116565b620002c16380ac58cd60e01b6001600160e01b036200045116565b620002dc63780e9d6360e01b6001600160e01b036200045116565b8151620002f190600a906020850190620004de565b5080516200030790600b906020840190620004de565b5062000323635b5e139f60e01b6001600160e01b036200045116565b5050600e80546001600160a01b0319166001600160a01b038616179055505080516200035790600f906020840190620004de565b50505050506001600160a01b0388166200036d57fe5b866200037557fe5b5050603260135560006014819055601080546001600160a01b03199081166001600160a01b03998a1617909155601b8054821690556305f5e100601655600260195561044c601a55601196909655601c8054871692881692909217909155601d8054909516919095161790925550620003ef9050620004d9565b601f80546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350506000601555506200058095505050505050565b6001600160e01b03198082161415620004b1576040805162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015290519081900360640190fd5b6001600160e01b0319166000908152600160208190526040909120805460ff19169091179055565b335b90565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200052157805160ff191683800117855562000551565b8280016001018555821562000551579182015b828111156200055157825182559160200191906001019062000534565b506200055f92915062000563565b5090565b620004db91905b808211156200055f57600081556001016200056a565b61474c80620005906000396000f3fe608060405234801561001057600080fd5b50600436106104075760003560e01c8063767a7b0511610220578063b88d4fde11610130578063d8dfeb45116100b8578063eb6a887d11610087578063eb6a887d14610b9e578063ece1373214610bbb578063f2fde38b14610bde578063f5537ede14610c04578063ffc73da714610c3a57610407565b8063d8dfeb4514610b43578063df98784614610b4b578063e5f4dc9214610b68578063e985e9c514610b7057610407565b8063cdfedd63116100ff578063cdfedd6314610af1578063cea55f5714610af9578063cf41d6f814610b01578063d310f49b14610b09578063d4a9b2c514610b2657610407565b8063b88d4fde146109e8578063c71abb3214610aae578063c87b56dd14610acc578063cd44db1b14610ae957610407565b806395d89b41116101b3578063a22cb46511610182578063a22cb46514610985578063a5e98837146109b3578063a7c6a100146109bb578063ab806f15146109c3578063b86f6aef146109cb57610407565b806395d89b411461093257806398c3f2db1461093a57806398d721e0146109425780639fc71b311461096857610407565b80638da5cb5b116101ef5780638da5cb5b146108fd5780638f32d59b1461090557806390cf0bba1461090d57806394cd4ba71461092a57610407565b8063767a7b051461087d57806385af3c16146108a057806385e290a3146108c357806386375994146108e057610407565b806342842e0e1161031b57806356572ac0116102ae5780636c0360eb1161027d5780636c0360eb1461082257806370a082311461082a5780637139c92914610850578063715018a61461086d578063728bbbb51461087557610407565b806356572ac0146107d85780635d12928b146107f557806361d027b3146107fd5780636352211e1461080557610407565b80634f558e79116102ea5780634f558e79146106f05780634f6ccce71461070d5780635001f3b51461072a57806355f804b31461073257610407565b806342842e0e1461068457806342f371c6146106ba578063470ffb33146106c257806348e6e392146106ca57610407565b806311b4a8321161039e5780632f745c591161036d5780632f745c591461060e578063311f392a1461063a5780633853627514610642578063387cadf51461065f5780633db991771461066757610407565b806311b4a8321461059957806318160ddd146105c85780631c883e7b146105d057806323b872dd146105d857610407565b806307960532116103da5780630796053214610507578063081812fc1461052d57806308ec59271461054a578063095ea7b31461056d57610407565b806301e49d0a1461040c57806301ffc9a71461042b578063048c661d1461046657806306fdde031461048a575b600080fd5b6104296004803603602081101561042257600080fd5b5035610c57565b005b6104526004803603602081101561044157600080fd5b50356001600160e01b031916610ca3565b604080519115158252519081900360200190f35b61046e610cc6565b604080516001600160a01b039092168252519081900360200190f35b610492610cd5565b6040805160208082528351818301528351919283929083019185019080838360005b838110156104cc5781810151838201526020016104b4565b50505050905090810190601f1680156104f95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6104296004803603602081101561051d57600080fd5b50356001600160a01b0316610d6c565b61046e6004803603602081101561054357600080fd5b5035610dd5565b6104296004803603604081101561056057600080fd5b5080359060200135610e37565b6104296004803603604081101561058357600080fd5b506001600160a01b038135169060200135611081565b6105b6600480360360208110156105af57600080fd5b50356111a9565b60408051918252519081900360200190f35b6105b6611287565b6105b661128d565b610429600480360360608110156105ee57600080fd5b506001600160a01b03813581169160208101359091169060400135611293565b6105b66004803603604081101561062457600080fd5b506001600160a01b0381351690602001356112ef565b6105b661136f565b6104296004803603602081101561065857600080fd5b5035611375565b61046e6113c1565b6104296004803603602081101561067d57600080fd5b50356113d0565b6104296004803603606081101561069a57600080fd5b506001600160a01b0381358116916020810135909116906040013561141c565b61046e611437565b61046e611446565b6105b6600480360360208110156106e057600080fd5b50356001600160a01b0316611455565b6104526004803603602081101561070657600080fd5b5035611467565b6105b66004803603602081101561072357600080fd5b5035611472565b6104926114d8565b6104296004803603602081101561074857600080fd5b81019060208101813564010000000081111561076357600080fd5b82018360208201111561077557600080fd5b8035906020019184600183028401116401000000008311171561079757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611566945050505050565b6105b6600480360360208110156107ee57600080fd5b50356115b9565b6105b6611675565b6105b66116e3565b61046e6004803603602081101561081b57600080fd5b50356116e9565b61049261173d565b6105b66004803603602081101561084057600080fd5b50356001600160a01b031661179e565b6104296004803603602081101561086657600080fd5b5035611806565b6104296118a3565b6105b6611934565b6104296004803603604081101561089357600080fd5b508035906020013561193a565b610429600480360360408110156108b657600080fd5b5080359060200135611ba0565b610429600480360360208110156108d957600080fd5b5035611ddb565b610429600480360360208110156108f657600080fd5b5035612000565b61046e61204c565b61045261205b565b6104296004803603602081101561092357600080fd5b5035612081565b6105b6612454565b6104926124d0565b6105b6612531565b6104296004803603602081101561095857600080fd5b50356001600160a01b03166125b7565b6104296004803603602081101561097e57600080fd5b5035612620565b6104296004803603604081101561099b57600080fd5b506001600160a01b03813516906020013515156126e6565b6105b66127eb565b6105b66127f1565b6105b66127f7565b610452600480360360208110156109e157600080fd5b50356127fd565b610429600480360360808110156109fe57600080fd5b6001600160a01b03823581169260208101359091169160408201359190810190608081016060820135640100000000811115610a3957600080fd5b820183602082011115610a4b57600080fd5b80359060200191846001830284011164010000000083111715610a6d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506128e4945050505050565b610ab6612942565b6040805160ff9092168252519081900360200190f35b61049260048036036020811015610ae257600080fd5b5035612952565b6105b6612c1a565b6105b6612c20565b6105b6612c26565b610429612c2c565b6105b660048036036020811015610b1f57600080fd5b5035612d2e565b6105b660048036036020811015610b3c57600080fd5b5035612d40565b61046e612d52565b6105b660048036036020811015610b6157600080fd5b5035612d61565b6105b6612e22565b61045260048036036040811015610b8657600080fd5b506001600160a01b0381358116916020013516612e28565b61042960048036036020811015610bb457600080fd5b5035612e56565b61042960048036036040811015610bd157600080fd5b5080359060200135612ea2565b61042960048036036020811015610bf457600080fd5b50356001600160a01b0316612f4c565b61042960048036036060811015610c1a57600080fd5b506001600160a01b03813581169160208101359091169060400135612f9c565b61042960048036036020811015610c5057600080fd5b5035613074565b610c5f61205b565b610c9e576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601655565b6001600160e01b0319811660009081526001602052604090205460ff165b919050565b601b546001600160a01b031681565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610d615780601f10610d3657610100808354040283529160200191610d61565b820191906000526020600020905b815481529060010190602001808311610d4457829003601f168201915b505050505090505b90565b610d7461205b565b610db3576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6000610de0826130c0565b610e1b5760405162461bcd60e51b815260040180806020018281038252602c81526020018061454a602c913960400191505060405180910390fd5b506000908152600360205260409020546001600160a01b031690565b81610e41816130c0565b610e89576040805162461bcd60e51b815260206004820152601460248201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b33610e93826116e9565b6001600160a01b031614610eea576040805162461bcd60e51b81526020600482015260196024820152785661756c74206973206e6f74206f776e656420627920796f7560381b604482015290519081900360640190fd5b60008211610f3f576040805162461bcd60e51b815260206004820152601b60248201527f4d75737420626f72726f77206e6f6e2d7a65726f20616d6f756e740000000000604482015290519081900360640190fd5b610f47612454565b821115610f855760405162461bcd60e51b815260040180806020018281038252602f8152602001806143d9602f913960400191505060405180910390fd5b600083815260186020526040812054610fa4908463ffffffff6130dd16565b6000858152601860205260409020549091508111610fbe57fe5b600084815260176020526040902054610fd7908261313e565b6110125760405162461bcd60e51b815260040180806020018281038252603a8152602001806145bf603a913960400191505060405180910390fd5b6000848152601860205260409020819055601d54611040906001600160a01b0316338563ffffffff61317316565b604080518581526020810185905281517f3e08df88d8e28f37df9bf227d3142ac506a364403445661a60891a49ed6792ca929181900390910190a150505050565b600061108c826116e9565b9050806001600160a01b0316836001600160a01b031614156110df5760405162461bcd60e51b81526004018080602001828103825260218152602001806145f96021913960400191505060405180910390fd5b806001600160a01b03166110f16131c5565b6001600160a01b0316148061111257506111128161110d6131c5565b612e28565b61114d5760405162461bcd60e51b81526004018080602001828103825260388152602001806144396038913960400191505060405180910390fd5b60008281526003602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60008181526017602052604081205415806111d05750600082815260186020526040902054155b806111e157506111df826127fd565b155b156111ee57506000610cc1565b60008281526017602090815260408083205460189092528220548291611213916131c9565b91509150806000141561122b57600092505050610cc1565b600061123d838363ffffffff61336616565b601d5490915061126490839060ff600160a01b9091048116600a0a1663ffffffff61336616565b9150600061127d6019548461336690919063ffffffff16565b9695505050505050565b60085490565b60135481565b6112a461129e6131c5565b826133a8565b6112df5760405162461bcd60e51b815260040180806020018281038252603181526020018061464a6031913960400191505060405180910390fd5b6112ea838383613444565b505050565b60006112fa8361179e565b82106113375760405162461bcd60e51b815260040180806020018281038252602b8152602001806142e1602b913960400191505060405180910390fd5b6001600160a01b038316600090815260066020526040902080548390811061135b57fe5b906000526020600020015490505b92915050565b601a5481565b61137d61205b565b6113bc576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601155565b601d546001600160a01b031681565b6113d861205b565b611417576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601355565b6112ea838383604051806020016040528060008152506128e4565b6010546001600160a01b031681565b600e546001600160a01b031681565b601e6020526000908152604090205481565b6000611369826130c0565b600061147c611287565b82106114b95760405162461bcd60e51b815260040180806020018281038252602c81526020018061467b602c913960400191505060405180910390fd5b600882815481106114c657fe5b90600052602060002001549050919050565b600f805460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152929183018282801561155e5780601f106115335761010080835404028352916020019161155e565b820191906000526020600020905b81548152906001019060200180831161154157829003601f168201915b505050505081565b61156e61205b565b6115ad576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b6115b681613463565b50565b60008181526017602052604081205415806115da57506115d8826127fd565b155b156115e757506000610cc1565b6000828152601760209081526040808320546018909252822054829161160c916131c9565b9150915060006116276019548361336690919063ffffffff16565b90508061163a5760009350505050610cc1565b61166c611645612531565b6116606103e8611660601a548661347a90919063ffffffff16565b9063ffffffff61336616565b95945050505050565b60125460009061168c81600163ffffffff6130dd16565b601281905581111561169a57fe5b6116a433826134d3565b6040805182815233602082015281517f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804929181900390910190a1905090565b60155481565b6000818152600260205260408120546001600160a01b0316806113695760405162461bcd60e51b81526004018080602001828103825260298152602001806144c26029913960400191505060405180910390fd5b600c8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610d615780601f10610d3657610100808354040283529160200191610d61565b60006001600160a01b0382166117e55760405162461bcd60e51b815260040180806020018281038252602a815260200180614498602a913960400191505060405180910390fd5b6001600160a01b0382166000908152600460205260409020611369906134f0565b61180e61205b565b61184d576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b611856816130c0565b61189e576040805162461bcd60e51b815260206004820152601460248201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b601555565b6118ab61205b565b6118ea576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601f546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3601f80546001600160a01b0319169055565b60145481565b81611944816130c0565b61198c576040805162461bcd60e51b815260206004820152601460248201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b33611996826116e9565b6001600160a01b0316146119ed576040805162461bcd60e51b81526020600482015260196024820152785661756c74206973206e6f74206f776e656420627920796f7560381b604482015290519081900360640190fd5b60005460ff16611a44576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000805460ff1916815583815260176020526040902054821115611a995760405162461bcd60e51b81526004018080602001828103825260258152602001806143886025913960400191505060405180910390fd5b600083815260176020526040812054611ab8908463ffffffff6134f416565b60008581526018602052604090205490915015611b2457600084815260186020526040902054611ae990829061313e565b611b245760405162461bcd60e51b815260040180806020018281038252603e8152602001806144eb603e913960400191505060405180910390fd5b6000848152601760205260409020819055601c54611b52906001600160a01b0316338563ffffffff61317316565b604080518581526020810185905281517f6c0ea3bea9dd66afa8f9d39d6eb93d833466190330813b42835efc650dca4cb9929181900390910190a150506000805460ff191660011790555050565b601d54604080516370a0823160e01b8152336004820152905183926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611bea57600080fd5b505afa158015611bfe573d6000803e3d6000fd5b505050506040513d6020811015611c1457600080fd5b50511015611c61576040805162461bcd60e51b8152602060048201526015602482015274546f6b656e2062616c616e636520746f6f206c6f7760581b604482015290519081900360640190fd5b600082815260186020526040902054811115611cae5760405162461bcd60e51b81526004018080602001828103825260278152602001806144716027913960400191505060405180910390fd5b6000611cec611ccd612710611cc1612531565b9063ffffffff61347a16565b611660611cd8612c1a565b601354611cc190879063ffffffff61347a16565b601d54909150611d0d906001600160a01b031633308563ffffffff61353616565b600083815260186020526040902054611d2c908363ffffffff6134f416565b600084815260186020908152604080832093909355601790522054611d57908263ffffffff6134f416565b6000848152601760205260408082209290925560155481522054611d81908263ffffffff6130dd16565b601554600090815260176020908152604091829020929092558051858152918201849052818101839052517f31f96762af4051f367185773cc2f55bfb112a6c114b3407ded1f321a9eb199ac9181900360600190a1505050565b80611de5816130c0565b611e2d576040805162461bcd60e51b815260206004820152601460248201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b33611e37826116e9565b6001600160a01b031614611e8e576040805162461bcd60e51b81526020600482015260196024820152785661756c74206973206e6f74206f776e656420627920796f7560381b604482015290519081900360640190fd5b60005460ff16611ee5576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000805460ff191681558281526018602052604090205415611f4e576040805162461bcd60e51b815260206004820152601a60248201527f5661756c7420686173206f75747374616e64696e672064656274000000000000604482015290519081900360640190fd5b60008281526017602052604090205415611f9657611f96611f6e836116e9565b600084815260176020526040902054601c546001600160a01b0316919063ffffffff61317316565b611f9f82613590565b60008281526017602090815260408083208390556018825280832092909255815184815291517f4fe08624ee65b341c38ab9693d216b909d4ddee1bc8d3fe0fea14026c361b4659281900390910190a150506000805460ff19166001179055565b61200861205b565b612047576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601455565b601f546001600160a01b031690565b601f546000906001600160a01b03166120726131c5565b6001600160a01b031614905090565b61208a816130c0565b6120d2576040805162461bcd60e51b815260206004820152601460248201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b601b546001600160a01b031615806120f45750601b546001600160a01b031633145b61212f5760405162461bcd60e51b81526004018080602001828103825260228152602001806146f66022913960400191505060405180910390fd5b60008181526017602090815260408083205460189092528220548291612154916131c9565b9092509050600061216b838363ffffffff61336616565b905060115481106121ad5760405162461bcd60e51b815260040180806020018281038252603081526020018061461a6030913960400191505060405180910390fd5b601d546121d190839060ff600160a01b9091048116600a0a1663ffffffff61336616565b915060006121ea6019548461336690919063ffffffff16565b601d54604080516370a0823160e01b8152336004820152905192935083926001600160a01b03909216916370a0823191602480820192602092909190829003018186803b15801561223a57600080fd5b505afa15801561224e573d6000803e3d6000fd5b505050506040513d602081101561226457600080fd5b505110156122a35760405162461bcd60e51b81526004018080602001828103825260318152602001806144086031913960400191505060405180910390fd5b601d546122c1906001600160a01b031633308463ffffffff61353616565b60006122cc866115b9565b6000878152601860205260409020549091506122ee908363ffffffff6134f416565b600087815260186020526040812091909155612330612311612710611cc1612531565b61166061231c612c1a565b601354611cc190889063ffffffff61347a16565b600088815260176020526040902054909150612352908263ffffffff6134f416565b600088815260176020526040808220929092556015548152205461237c908263ffffffff6130dd16565b6015546000908152601760205260408082209290925588815220546123a7908363ffffffff6134f416565b600088815260176020908152604080832093909355338252601e905220546123d5908363ffffffff6130dd16565b336000908152601e60205260409020557f4d151d3a98b83151d51917640c221f8c8e3c054422ea1b48dcbbd57e3f4210d587612410816116e9565b604080519283526001600160a01b0390911660208301523382820152606082018690526080820185905260a08201849052519081900360c00190a150505050505050565b601d54604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561249f57600080fd5b505afa1580156124b3573d6000803e3d6000fd5b505050506040513d60208110156124c957600080fd5b5051905090565b600b8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610d615780601f10610d3657610100808354040283529160200191610d61565b600080601060009054906101000a90046001600160a01b03166001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a06040518083038186803b15801561258257600080fd5b505afa158015612596573d6000803e3d6000fd5b505050506040513d60a08110156125ac57600080fd5b506020015191505090565b6125bf61205b565b6125fe576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601b80546001600160a01b0319166001600160a01b0392909216919091179055565b61262861205b565b612667576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601d546040805163a9059cbb60e01b81526001600160a01b0390921660048301819052602483018490529051909163a9059cbb9160448083019260209291908290030181600087803b1580156126bc57600080fd5b505af11580156126d0573d6000803e3d6000fd5b505050506040513d60208110156112ea57600080fd5b6126ee6131c5565b6001600160a01b0316826001600160a01b03161415612754576040805162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604482015290519081900360640190fd5b80600560006127616131c5565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff1916921515929092179091556127a56131c5565b60408051841515815290516001600160a01b0392909216917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319181900360200190a35050565b60135490565b60125481565b60145490565b6000612808826130c0565b612850576040805162461bcd60e51b815260206004820152601460248201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b60008281526017602052604090205415806128775750600082815260186020526040902054155b1561288457506000610cc1565b600082815260176020908152604080832054601890925282205482916128a9916131c9565b909250905060006128c0838363ffffffff61336616565b90506011548110156128d85760019350505050610cc1565b60009350505050610cc1565b6128f56128ef6131c5565b836133a8565b6129305760405162461bcd60e51b815260040180806020018281038252603181526020018061464a6031913960400191505060405180910390fd5b61293c848484846135a2565b50505050565b601d54600160a01b900460ff1681565b606061295d826130c0565b61296657600080fd5b600e5460408051636411ba2160e11b815230600482015290516001600160a01b0390921691600091839163c823744291602480820192602092909190829003018186803b1580156129b657600080fd5b505afa1580156129ca573d6000803e3d6000fd5b505050506040513d60208110156129e057600080fd5b5051600f5490915060026000196101006001841615020190911604612a145760405180602001604052806000815250612c12565b604080516305b1feb160e11b8152306004820152602481018690529051600f916001600160a01b03841691630b63fd6291604480820192600092909190829003018186803b158015612a6557600080fd5b505afa158015612a79573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015612aa257600080fd5b8101908080516040519392919084640100000000821115612ac257600080fd5b908301906020820185811115612ad757600080fd5b8251640100000000811182820188101715612af157600080fd5b82525081516020918201929091019080838360005b83811015612b1e578181015183820152602001612b06565b50505050905090810190601f168015612b4b5780820380516001836020036101000a031916815260200191505b506040525050506040516020018083805460018160011615610100020316600290048015612bb05780601f10612b8e576101008083540402835291820191612bb0565b820191906000526020600020905b815481529060010190602001808311612b9c575b5050825160208401908083835b60208310612bdc5780518252601f199092019160209182019101612bbd565b6001836020036101000a038019825116818451168082178552505050505050905001925050506040516020818303038152906040525b949350505050565b60165490565b60165481565b60195481565b60005460ff16612c83576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6000805460ff19168155338152601e6020526040902054612ceb576040805162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e00000000604482015290519081900360640190fd5b336000818152601e602052604081208054919055601c549091612d1e916001600160a01b0316908363ffffffff61317316565b506000805460ff19166001179055565b60186020526000908152604090205481565b60176020526000908152604090205481565b601c546001600160a01b031681565b6000612d6c826130c0565b612db4576040805162461bcd60e51b815260206004820152601460248201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604482015290519081900360640190fd5b6000828152601760205260409020541580612ddb5750600082815260186020526040902054155b15612de857506000610cc1565b60008281526017602090815260408083205460189092528220548291612e0d916131c9565b9092509050612c12828263ffffffff61336616565b60115481565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b612e5e61205b565b612e9d576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601955565b601c54612ec0906001600160a01b031633308463ffffffff61353616565b600082815260176020526040812054612edf908363ffffffff6130dd16565b600084815260176020526040902054909150811015612efa57fe5b600083815260176020908152604091829020839055815185815290810184905281517f52c4e7127ec34e8fc95f09ce2d06b4f00acca12ccbcdfb246ef67ee6aefe068d929181900390910190a1505050565b612f5461205b565b612f93576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b6115b6816135f4565b612fa461205b565b612fe3576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b816001600160a01b031663a9059cbb84836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561304357600080fd5b505af1158015613057573d6000803e3d6000fd5b505050506040513d602081101561306d57600080fd5b5050505050565b61307c61205b565b6130bb576040805162461bcd60e51b81526020600482018190526024820152600080516020614576833981519152604482015290519081900360640190fd5b601a55565b6000908152600260205260409020546001600160a01b0316151590565b600082820183811015613137576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b600080600061314d85856131c9565b90925090506000613164838363ffffffff61336616565b60115411159695505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b1790526112ea908490613695565b3390565b6000806131d4612531565b6131da57fe5b6131e2612c1a565b6131e857fe5b600061330b6132f0601c60009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561323e57600080fd5b505afa158015613252573d6000803e3d6000fd5b505050506040513d602081101561326857600080fd5b5051601d546040805163313ce56760e01b8152905160ff909316926001600160a01b039092169163313ce56791600480820192602092909190829003018186803b1580156132b557600080fd5b505afa1580156132c9573d6000803e3d6000fd5b505050506040513d60208110156132df57600080fd5b505160ff169063ffffffff6134f416565b600a0a611cc16132fe612531565b889063ffffffff61347a16565b90508481101561331757fe5b6000613331613324612c1a565b869063ffffffff61347a16565b90508481101561333d57fe5b600061335083606463ffffffff61347a16565b905082811161335b57fe5b969095509350505050565b600061313783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061384d565b60006133b3826130c0565b6133ee5760405162461bcd60e51b815260040180806020018281038252602c8152602001806143ad602c913960400191505060405180910390fd5b60006133f9836116e9565b9050806001600160a01b0316846001600160a01b031614806134345750836001600160a01b031661342984610dd5565b6001600160a01b0316145b80612c125750612c128185612e28565b61344f8383836138ef565b6134598382613a33565b6112ea8282613b21565b805161347690600c9060208401906141e4565b5050565b60008261348957506000611369565b8282028284828161349657fe5b04146131375760405162461bcd60e51b81526004018080602001828103825260218152602001806145296021913960400191505060405180910390fd5b6134dd8282613b5f565b6134e78282613b21565b61347681613c90565b5490565b600061313783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613cd4565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b17905261293c908590613695565b6115b661359c826116e9565b82613d2e565b6135ad848484613444565b6135b984848484613d76565b61293c5760405162461bcd60e51b815260040180806020018281038252603281526020018061430c6032913960400191505060405180910390fd5b6001600160a01b0381166136395760405162461bcd60e51b815260040180806020018281038252602681526020018061433e6026913960400191505060405180910390fd5b601f546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3601f80546001600160a01b0319166001600160a01b0392909216919091179055565b6136a7826001600160a01b0316613fb1565b6136f8576040805162461bcd60e51b815260206004820152601f60248201527f5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400604482015290519081900360640190fd5b60006060836001600160a01b0316836040518082805190602001908083835b602083106137365780518252601f199092019160209182019101613717565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613798576040519150601f19603f3d011682016040523d82523d6000602084013e61379d565b606091505b5091509150816137f4576040805162461bcd60e51b815260206004820181905260248201527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564604482015290519081900360640190fd5b80511561293c5780806020019051602081101561381057600080fd5b505161293c5760405162461bcd60e51b815260040180806020018281038252602a8152602001806146cc602a913960400191505060405180910390fd5b600081836138d95760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561389e578181015183820152602001613886565b50505050905090810190601f1680156138cb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816138e557fe5b0495945050505050565b826001600160a01b0316613902826116e9565b6001600160a01b0316146139475760405162461bcd60e51b81526004018080602001828103825260298152602001806145966029913960400191505060405180910390fd5b6001600160a01b03821661398c5760405162461bcd60e51b81526004018080602001828103825260248152602001806143646024913960400191505060405180910390fd5b61399581613fea565b6001600160a01b03831660009081526004602052604090206139b690614025565b6001600160a01b03821660009081526004602052604090206139d79061403c565b60008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6001600160a01b038216600090815260066020526040812054613a5d90600163ffffffff6134f416565b600083815260076020526040902054909150808214613af8576001600160a01b0384166000908152600660205260408120805484908110613a9a57fe5b906000526020600020015490508060066000876001600160a01b03166001600160a01b031681526020019081526020016000208381548110613ad857fe5b600091825260208083209091019290925591825260079052604090208190555b6001600160a01b038416600090815260066020526040902080549061306d906000198301614262565b6001600160a01b0390911660009081526006602081815260408084208054868652600784529185208290559282526001810183559183529091200155565b6001600160a01b038216613bba576040805162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604482015290519081900360640190fd5b613bc3816130c0565b15613c15576040805162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604482015290519081900360640190fd5b600081815260026020908152604080832080546001600160a01b0319166001600160a01b038716908117909155835260049091529020613c549061403c565b60405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b60008184841115613d265760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561389e578181015183820152602001613886565b505050900390565b613d388282614045565b6000818152600d60205260409020546002600019610100600184161502019091160415613476576000818152600d6020526040812061347691614286565b6000613d8a846001600160a01b0316613fb1565b613d9657506001612c12565b600060606001600160a01b038616630a85bd0160e11b613db46131c5565b89888860405160240180856001600160a01b03166001600160a01b03168152602001846001600160a01b03166001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613e2d578181015183820152602001613e15565b50505050905090810190601f168015613e5a5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b0319909a16999099178952518151919890975087965094509250829150849050835b60208310613ec25780518252601f199092019160209182019101613ea3565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613f24576040519150601f19603f3d011682016040523d82523d6000602084013e613f29565b606091505b509150915081613f7a57805115613f435780518082602001fd5b60405162461bcd60e51b815260040180806020018281038252603281526020018061430c6032913960400191505060405180910390fd5b6000818060200190516020811015613f9157600080fd5b50516001600160e01b031916630a85bd0160e11b149350612c1292505050565b6000813f7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470818114801590612c12575050151592915050565b6000818152600360205260409020546001600160a01b0316156115b657600090815260036020526040902080546001600160a01b0319169055565b805461403890600163ffffffff6134f416565b9055565b80546001019055565b61404f8282614071565b6140598282613a33565b60008181526007602052604081205561347681614148565b816001600160a01b0316614084826116e9565b6001600160a01b0316146140c95760405162461bcd60e51b81526004018080602001828103825260258152602001806146a76025913960400191505060405180910390fd5b6140d281613fea565b6001600160a01b03821660009081526004602052604090206140f390614025565b60008181526002602052604080822080546001600160a01b0319169055518291906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60085460009061415f90600163ffffffff6134f416565b6000838152600960205260408120546008805493945090928490811061418157fe5b90600052602060002001549050806008838154811061419c57fe5b600091825260208083209091019290925582815260099091526040902082905560088054906141cf906000198301614262565b50505060009182525060096020526040812055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061422557805160ff1916838001178555614252565b82800160010185558215614252579182015b82811115614252578251825591602001919060010190614237565b5061425e9291506142c6565b5090565b8154818355818111156112ea576000838152602090206112ea9181019083016142c6565b50805460018160011615610100020316600290046000825580601f106142ac57506115b6565b601f0160209004906000526020600020908101906115b691905b610d6991905b8082111561425e57600081556001016142cc56fe455243373231456e756d657261626c653a206f776e657220696e646578206f7574206f6620626f756e64734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f20616464726573735661756c7420646f6573206e6f74206861766520656e6f75676820636f6c6c61746572616c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e626f72726f77546f6b656e3a2043616e6e6f74206d696e74206f76657220617661696c61626c6520737570706c792e546f6b656e2062616c616e636520746f6f206c6f7720746f20706179206f6666206f75747374616e64696e6720646562744552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c5661756c742064656274206c657373207468616e20616d6f756e7420746f20706179206261636b4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e5769746864726177616c20776f756c6420707574207661756c742062656c6f77206d696e696d756d20636f6c6c61746572616c2070657263656e74616765536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65724552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e426f72726f7720776f756c6420707574207661756c742062656c6f77206d696e696d756d20636f6c6c61746572616c2070657263656e746167654552433732313a20617070726f76616c20746f2063757272656e74206f776e65725661756c74206973206e6f742062656c6f77206d696e696d756d20636f6c6c61746572616c2070657263656e746167654552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f766564455243373231456e756d657261626c653a20676c6f62616c20696e646578206f7574206f6620626f756e64734552433732313a206275726e206f6620746f6b656e2074686174206973206e6f74206f776e5361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565646c69717569646174696f6e2069732064697361626c656420666f72207075626c6963a265627a7a72315820d13e7b06f902d0075de260422a7b04b5a1dcf7816a51d1ad8157dddf1abbc0fa64736f6c63430005100032000000000000000000000000143db3ceefbdfe5631add3e50f7614b6ba708ba7000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000c9f654d481e79d01448030b08516b7f9fcf71e13000000000000000000000000d66c6b4f0be8ce5b39d52e0fd1344c389929b37800000000000000000000000074e3751f8c7928697ae42461ba07f3cbe127aea00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000e4554482067444149205661756c7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056547445654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001568747470733a2f2f697066732e696f2f697066732f0000000000000000000000

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

000000000000000000000000143db3ceefbdfe5631add3e50f7614b6ba708ba7000000000000000000000000000000000000000000000000000000000000009600000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000c9f654d481e79d01448030b08516b7f9fcf71e13000000000000000000000000d66c6b4f0be8ce5b39d52e0fd1344c389929b37800000000000000000000000074e3751f8c7928697ae42461ba07f3cbe127aea00000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000e4554482067444149205661756c7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000056547445654000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001568747470733a2f2f697066732e696f2f697066732f0000000000000000000000

-----Decoded View---------------
Arg [0] : ethPriceSourceAddress (address): 0x143db3ceefbdfe5631add3e50f7614b6ba708ba7
Arg [1] : minimumCollateralPercentage (uint256): 150
Arg [2] : name (string): ETH gDAI Vault
Arg [3] : symbol (string): eGDVT
Arg [4] : _ghostDai (address): 0xc9f654d481e79d01448030b08516b7f9fcf71e13
Arg [5] : _collateral (address): 0xd66c6b4f0be8ce5b39d52e0fd1344c389929b378
Arg [6] : meta (address): 0x74e3751f8c7928697ae42461ba07f3cbe127aea0
Arg [7] : baseURI (string): https://ipfs.io/ipfs/

-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 000000000000000000000000143db3ceefbdfe5631add3e50f7614b6ba708ba7
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000096
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [4] : 000000000000000000000000c9f654d481e79d01448030b08516b7f9fcf71e13
Arg [5] : 000000000000000000000000d66c6b4f0be8ce5b39d52e0fd1344c389929b378
Arg [6] : 00000000000000000000000074e3751f8c7928697ae42461ba07f3cbe127aea0
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [8] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [9] : 4554482067444149205661756c74000000000000000000000000000000000000
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [11] : 6547445654000000000000000000000000000000000000000000000000000000
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000015
Arg [13] : 68747470733a2f2f697066732e696f2f697066732f0000000000000000000000


Deployed ByteCode Sourcemap

82945:2235:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;82945:2235:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84096:100;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84096:100:0;;:::i;:::-;;38211:135;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;38211:135:0;-1:-1:-1;;;;;;38211:135:0;;:::i;:::-;;;;;;;;;;;;;;;;;;71540:28;;;:::i;:::-;;;;-1:-1:-1;;;;;71540:28:0;;;;;;;;;;;;;;66008:85;;;:::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;66008:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83936:152;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83936:152:0;-1:-1:-1;;;;;83936:152:0;;:::i;43173:204::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;43173:204:0;;:::i;77103:661::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;77103:661:0;;;;;;;:::i;42455:425::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;42455:425:0;;;;;;;;:::i;78785:672::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;78785:672:0;;:::i;:::-;;;;;;;;;;;;;;;;57600:96;;;:::i;71238:25::-;;;:::i;44856:292::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;44856:292:0;;;;;;;;;;;;;;;;;:::i;57209:232::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;57209:232:0;;;;;;;;:::i;71507:24::-;;;:::i;84314:166::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84314:166:0;;:::i;71617:29::-;;;:::i;84488:98::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84488:98:0;;:::i;45810:134::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;45810:134:0;;;;;;;;;;;;;;;;;:::i;71033:33::-;;;:::i;70193:20::-;;;:::i;72273:42::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72273:42:0;-1:-1:-1;;;;;72273:42:0;;:::i;73606:103::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73606:103:0;;:::i;58042:199::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;58042:199:0;;:::i;70220:18::-;;;:::i;85076:101::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;85076:101:0;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;85076:101:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;85076:101: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;85076:101:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;85076:101:0;;-1:-1:-1;85076:101:0;;-1:-1:-1;;;;;85076:101:0:i;79465:541::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;79465:541:0;;:::i;75277:270::-;;;:::i;71304:23::-;;;:::i;41796:228::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41796:228:0;;:::i;68261:91::-;;;:::i;41359:211::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;41359:211:0;-1:-1:-1;;;;;41359:211:0;;:::i;84700:162::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84700:162:0;;:::i;2911:140::-;;;:::i;71270:25::-;;;:::i;76458:637::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;76458:637:0;;;;;;;:::i;77772:743::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;77772:743:0;;;;;;;:::i;75555:495::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;75555:495:0;;:::i;84594:98::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84594:98:0;;:::i;2100:79::-;;;:::i;2466:94::-;;;:::i;81111:1736::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;81111:1736:0;;:::i;73484:114::-;;;:::i;66208:89::-;;;:::i;74019:162::-;;;:::i;84204:102::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84204:102:0;-1:-1:-1;;;;;84204:102:0;;:::i;84870:198::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84870:198:0;;:::i;43678:254::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;43678:254:0;;;;;;;;;;:::i;73717:92::-;;;:::i;71206:25::-;;;:::i;73817:92::-;;;:::i;80474:629::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;80474:629:0;;:::i;46681:272::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;;;;;46681:272:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;5:28;;2:2;;;46:1;43;36:12;2:2;46681:272:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;46681:272: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;46681:272:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;46681:272:0;;-1:-1:-1;46681:272:0;;-1:-1:-1;;;;;46681:272:0:i;71655:32::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;70455:409;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70455:409:0;;:::i;73917:94::-;;;:::i;71334:23::-;;;:::i;71476:24::-;;;:::i;78523:254::-;;;:::i;71423:44::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71423:44:0;;:::i;71366:50::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71366:50:0;;:::i;71577:31::-;;;:::i;80014:452::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;80014:452:0;;:::i;71154:43::-;;;:::i;44262:147::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;44262:147:0;;;;;;;;;;:::i;83641:102::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83641:102:0;;:::i;76058:392::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;76058:392:0;;;;;;;:::i;3206:109::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;3206:109:0;-1:-1:-1;;;;;3206:109:0;;:::i;83779:149::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;83779:149:0;;;;;;;;;;;;;;;;;:::i;83531:102::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83531:102:0;;:::i;84096:100::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;84168:8;:20;84096:100::o;38211:135::-;-1:-1:-1;;;;;;38305:33:0;;38281:4;38305:33;;;:20;:33;;;;;;;;38211:135;;;;:::o;71540:28::-;;;-1:-1:-1;;;;;71540:28:0;;:::o;66008:85::-;66080:5;66073:12;;;;;;;;-1:-1:-1;;66073:12:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66047:13;;66073:12;;66080:5;;66073:12;;66080:5;66073:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66008:85;;:::o;83936:152::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;84029:14;:51;;-1:-1:-1;;;;;;84029:51:0;-1:-1:-1;;;;;84029:51:0;;;;;;;;;;83936:152::o;43173:204::-;43232:7;43260:16;43268:7;43260;:16::i;:::-;43252:73;;;;-1:-1:-1;;;43252:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43345:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;43345:24:0;;43173:204::o;77103:661::-;77181:7;73336:16;73344:7;73336;:16::i;:::-;73328:49;;;;;-1:-1:-1;;;73328:49:0;;;;;;;;;;;;-1:-1:-1;;;73328:49:0;;;;;;;;;;;;;;;73416:10;73396:16;73404:7;73396;:16::i;:::-;-1:-1:-1;;;;;73396:30:0;;73388:68;;;;;-1:-1:-1;;;73388:68:0;;;;;;;;;;;;-1:-1:-1;;;73388:68:0;;;;;;;;;;;;;;;77218:1;77209:6;:10;77201:50;;;;;-1:-1:-1;;;77201:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;77280:16;:14;:16::i;:::-;77270:6;:26;;77262:86;;;;-1:-1:-1;;;77262:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77361:15;77379:18;;;:9;:18;;;;;;:30;;77402:6;77379:30;:22;:30;:::i;:::-;77439:18;;;;:9;:18;;;;;;77361:48;;-1:-1:-1;77429:28:0;;77422:36;;;;77497:24;;;;:15;:24;;;;;;77479:52;;77523:7;77479:17;:52::i;:::-;77471:123;;;;-1:-1:-1;;;77471:123:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77607:18;;;;:9;:18;;;;;:28;;;77669:8;;:41;;-1:-1:-1;;;;;77669:8:0;77691:10;77703:6;77669:41;:21;:41;:::i;:::-;77728:28;;;;;;;;;;;;;;;;;;;;;;;;;73467:1;77103:661;;;:::o;42455:425::-;42519:13;42535:16;42543:7;42535;:16::i;:::-;42519:32;;42576:5;-1:-1:-1;;;;;42570:11:0;:2;-1:-1:-1;;;;;42570:11:0;;;42562:57;;;;-1:-1:-1;;;42562:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42656:5;-1:-1:-1;;;;;42640:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;42640:21:0;;:62;;;;42665:37;42682:5;42689:12;:10;:12::i;:::-;42665:16;:37::i;:::-;42632:154;;;;-1:-1:-1;;;42632:154:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42799:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;42799:29:0;-1:-1:-1;;;;;42799:29:0;;;;;;;;;42844:28;;42799:24;;42844:28;;;;;;;42455:425;;;:::o;78785:672::-;78842:7;78867:24;;;:15;:24;;;;;;:29;;:54;;-1:-1:-1;78900:18:0;;;;:9;:18;;;;;;:21;78867:54;:84;;;;78926:25;78943:7;78926:16;:25::i;:::-;78925:26;78867:84;78864:124;;;-1:-1:-1;78975:1:0;78968:8;;78864:124;79001:31;79085:24;;;:15;:24;;;;;;;;;79111:9;:18;;;;;;79001:31;;79055:75;;:29;:75::i;:::-;79000:130;;;;79146:9;79157:1;79146:12;79143:51;;;79181:1;79174:8;;;;;;79143:51;79214:28;79245:38;:23;79273:9;79245:38;:27;:38;:::i;:::-;79328:19;;79214:69;;-1:-1:-1;79308:40:0;;:9;;79328:19;-1:-1:-1;;;79328:19:0;;;;;79322:2;:25;79308:40;;:13;:40;:::i;:::-;79296:52;;79361:16;79380:24;79394:9;;79380;:13;;:24;;;;:::i;:::-;79361:43;78785:672;-1:-1:-1;;;;;;78785:672:0:o;57600:96::-;57671:10;:17;57600:96;:::o;71238:25::-;;;;:::o;44856:292::-;45000:41;45019:12;:10;:12::i;:::-;45033:7;45000:18;:41::i;:::-;44992:103;;;;-1:-1:-1;;;44992:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45108:32;45122:4;45128:2;45132:7;45108:13;:32::i;:::-;44856:292;;;:::o;57209:232::-;57289:7;57325:16;57335:5;57325:9;:16::i;:::-;57317:5;:24;57309:80;;;;-1:-1:-1;;;57309:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57407:19:0;;;;;;:12;:19;;;;;:26;;57427:5;;57407:26;;;;;;;;;;;;;;57400:33;;57209:232;;;;;:::o;71507:24::-;;;;:::o;84314:166::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;84414:28;:58;84314:166::o;71617:29::-;;;-1:-1:-1;;;;;71617:29:0;;:::o;84488:98::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;84559:10;:19;84488:98::o;45810:134::-;45897:39;45914:4;45920:2;45924:7;45897:39;;;;;;;;;;;;:16;:39::i;71033:33::-;;;-1:-1:-1;;;;;71033:33:0;;:::o;70193:20::-;;;-1:-1:-1;;;;;70193:20:0;;:::o;72273:42::-;;;;;;;;;;;;;:::o;73606:103::-;73662:4;73685:16;73693:7;73685;:16::i;58042:199::-;58100:7;58136:13;:11;:13::i;:::-;58128:5;:21;58120:78;;;;-1:-1:-1;;;58120:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58216:10;58227:5;58216:17;;;;;;;;;;;;;;;;58209:24;;58042:199;;;:::o;70220:18::-;;;;;;;;;;;;;;;-1:-1:-1;;70220:18:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;85076:101::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;85149:20;85161:7;85149:11;:20::i;:::-;85076:101;:::o;79465:541::-;79525:7;79550:24;;;:15;:24;;;;;;:29;;:58;;;79583:25;79600:7;79583:16;:25::i;:::-;79582:26;79550:58;79547:99;;;-1:-1:-1;79633:1:0;79626:8;;79547:99;79659:31;79743:24;;;:15;:24;;;;;;;;;79769:9;:18;;;;;;79659:31;;79713:75;;:29;:75::i;:::-;79658:130;;;;79801:16;79820:24;79834:9;;79820;:13;;:24;;;;:::i;:::-;79801:43;-1:-1:-1;79876:11:0;79873:50;;79910:1;79903:8;;;;;;;79873:50;79940:58;79978:19;:17;:19::i;:::-;79940:33;79968:4;79940:23;79953:9;;79940:8;:12;;:23;;;;:::i;:::-;:27;:33;:27;:33;:::i;:58::-;79933:65;79465:541;-1:-1:-1;;;;;79465:541:0:o;75277:270::-;75351:10;;75318:7;;75385:17;75351:10;75400:1;75385:17;:14;:17;:::i;:::-;75372:10;:30;;;75422:16;-1:-1:-1;75422:16:0;75415:24;;;;75452:20;75458:10;75469:2;75452:5;:20::i;:::-;75490:27;;;;;;75506:10;75490:27;;;;;;;;;;;;;;;;;75537:2;-1:-1:-1;75277:270:0;:::o;71304:23::-;;;;:::o;41796:228::-;41851:7;41887:20;;;:11;:20;;;;;;-1:-1:-1;;;;;41887:20:0;41926:19;41918:73;;;;-1:-1:-1;;;41918:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68261:91;68336:8;68329:15;;;;;;;;-1:-1:-1;;68329:15:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68303:13;;68329:15;;68336:8;;68329:15;;68336:8;68329:15;;;;;;;;;;;;;;;;;;;;;;;;41359:211;41414:7;-1:-1:-1;;;;;41442:19:0;;41434:74;;;;-1:-1:-1;;;41434:74:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;41528:24:0;;;;;;:17;:24;;;;;:34;;:32;:34::i;84700:162::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;84780:18;84788:9;84780:7;:18::i;:::-;84772:51;;;;;-1:-1:-1;;;84772:51:0;;;;;;;;;;;;-1:-1:-1;;;84772:51:0;;;;;;;;;;;;;;;84834:8;:20;84700:162::o;2911:140::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;2994:6;;2973:40;;3010:1;;-1:-1:-1;;;;;2994:6:0;;2973:40;;3010:1;;2973:40;3024:6;:19;;-1:-1:-1;;;;;;3024:19:0;;;2911:140::o;71270:25::-;;;;:::o;76458:637::-;76543:7;73336:16;73344:7;73336;:16::i;:::-;73328:49;;;;;-1:-1:-1;;;73328:49:0;;;;;;;;;;;;-1:-1:-1;;;73328:49:0;;;;;;;;;;;;;;;73416:10;73396:16;73404:7;73396;:16::i;:::-;-1:-1:-1;;;;;73396:30:0;;73388:68;;;;;-1:-1:-1;;;73388:68:0;;;;;;;;;;;;-1:-1:-1;;;73388:68:0;;;;;;;;;;;;;;;30928:11;;;;30920:55;;;;;-1:-1:-1;;;30920:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;31067:5;31053:19;;-1:-1:-1;;31053:19:0;;;76584:24;;;:15;:24;;;;;;:34;-1:-1:-1;76584:34:0;76576:84;;;;-1:-1:-1;;;76576:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76673:21;76697:24;;;:15;:24;;;;;;:36;;76726:6;76697:36;:28;:36;:::i;:::-;76749:18;;;;:9;:18;;;;;;76673:60;;-1:-1:-1;76749:23:0;76746:182;;76830:18;;;;:9;:18;;;;;;76797:52;;76815:13;;76797:17;:52::i;:::-;76789:127;;;;-1:-1:-1;;;76789:127:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76940:24;;;;:15;:24;;;;;:40;;;76991:10;;:43;;-1:-1:-1;;;;;76991:10:0;77015;77027:6;76991:43;:23;:43;:::i;:::-;77052:35;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;31233:11:0;:18;;-1:-1:-1;;31233:18:0;31247:4;31233:18;;;-1:-1:-1;;76458:637:0:o;77772:743::-;77855:8;;:30;;;-1:-1:-1;;;77855:30:0;;77874:10;77855:30;;;;;;77889:6;;-1:-1:-1;;;;;77855:8:0;;:18;;:30;;;;;;;;;;;;;;:8;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;77855:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77855:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;77855:30:0;:40;;77847:74;;;;;-1:-1:-1;;;77847:74:0;;;;;;;;;;;;-1:-1:-1;;;77847:74:0;;;;;;;;;;;;;;;77940:18;;;;:9;:18;;;;;;:28;-1:-1:-1;77940:28:0;77932:80;;;;-1:-1:-1;;;77932:80:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78025:19;78047:87;78103:30;78127:5;78103:19;:17;:19::i;:::-;:23;:30;:23;:30;:::i;:::-;78048:49;78075:21;:19;:21::i;:::-;78059:10;;78048:22;;:6;;:22;:10;:22;:::i;78047:87::-;78167:8;;78025:109;;-1:-1:-1;78167:60:0;;-1:-1:-1;;;;;78167:8:0;78193:10;78213:4;78220:6;78167:60;:25;:60;:::i;:::-;78261:18;;;;:9;:18;;;;;;:30;;78284:6;78261:30;:22;:30;:::i;:::-;78240:18;;;;:9;:18;;;;;;;;:51;;;;78327:15;:24;;;;:41;;78356:11;78327:41;:28;:41;:::i;:::-;78302:24;;;;:15;:24;;;;;;:66;;;;78421:8;;78405:25;;;;:42;;78435:11;78405:42;:29;:42;:::i;:::-;78395:8;;78379:25;;;;:15;:25;;;;;;;;;:68;;;;78465:42;;;;;;;;;;;;;;;;;;;;;;;;;;;77772:743;;;:::o;75555:495::-;75618:7;73336:16;73344:7;73336;:16::i;:::-;73328:49;;;;;-1:-1:-1;;;73328:49:0;;;;;;;;;;;;-1:-1:-1;;;73328:49:0;;;;;;;;;;;;;;;73416:10;73396:16;73404:7;73396;:16::i;:::-;-1:-1:-1;;;;;73396:30:0;;73388:68;;;;;-1:-1:-1;;;73388:68:0;;;;;;;;;;;;-1:-1:-1;;;73388:68:0;;;;;;;;;;;;;;;30928:11;;;;30920:55;;;;;-1:-1:-1;;;30920:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;31067:5;31053:19;;-1:-1:-1;;31053:19:0;;;75659:18;;;:9;:18;;;;;;:23;75651:62;;;;;-1:-1:-1;;;75651:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;75729:24;;;;:15;:24;;;;;;:27;75726:171;;75818:67;75842:16;75850:7;75842;:16::i;:::-;75860:24;;;;:15;:24;;;;;;75818:10;;-1:-1:-1;;;;;75818:10:0;;:67;;:23;:67;:::i;:::-;75909:14;75915:7;75909:5;:14::i;:::-;75943:24;;;;:15;:24;;;;;;;;75936:31;;;75985:9;:18;;;;;75978:25;;;;76021:21;;;;;;;;;;;;;;;;;-1:-1:-1;;31233:11:0;:18;;-1:-1:-1;;31233:18:0;31247:4;31233:18;;;75555:495::o;84594:98::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;84665:10;:19;84594:98::o;2100:79::-;2165:6;;-1:-1:-1;;;;;2165:6:0;2100:79;:::o;2466:94::-;2546:6;;2506:4;;-1:-1:-1;;;;;2546:6:0;2530:12;:10;:12::i;:::-;-1:-1:-1;;;;;2530:22:0;;2523:29;;2466:94;:::o;81111:1736::-;81180:16;81188:7;81180;:16::i;:::-;81172:49;;;;;-1:-1:-1;;;81172:49:0;;;;;;;;;;;;-1:-1:-1;;;81172:49:0;;;;;;;;;;;;;;;81240:13;;-1:-1:-1;;;;;81240:13:0;:25;;:57;;-1:-1:-1;81284:13:0;;-1:-1:-1;;;;;81284:13:0;81269:10;:28;81240:57;81232:104;;;;-1:-1:-1;;;81232:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81350:31;81434:24;;;:15;:24;;;;;;;;;81460:9;:18;;;;;;81350:31;;81404:75;;:29;:75::i;:::-;81349:130;;-1:-1:-1;81349:130:0;-1:-1:-1;81492:28:0;81523:38;81349:130;;81523:38;:27;:38;:::i;:::-;81492:69;;81605:28;;81582:20;:51;81574:112;;;;-1:-1:-1;;;81574:112:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81731:19;;81711:40;;:9;;81731:19;-1:-1:-1;;;81731:19:0;;;;;81725:2;:25;81711:40;;:13;:40;:::i;:::-;81699:52;;81764:16;81783:24;81797:9;;81783;:13;;:24;;;;:::i;:::-;81844:8;;:30;;;-1:-1:-1;;;81844:30:0;;81863:10;81844:30;;;;;;81764:43;;-1:-1:-1;81764:43:0;;-1:-1:-1;;;;;81844:8:0;;;;:18;;:30;;;;;;;;;;;;;;;:8;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;81844:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;81844:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;81844:30:0;:42;;81836:104;;;;-1:-1:-1;;;81836:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81973:8;;:62;;-1:-1:-1;;;;;81973:8:0;81999:10;82019:4;82026:8;81973:62;:25;:62;:::i;:::-;82048:18;82069:21;82082:7;82069:12;:21::i;:::-;82124:18;;;;:9;:18;;;;;;82048:42;;-1:-1:-1;82124:32:0;;82147:8;82124:32;:22;:32;:::i;:::-;82103:18;;;;:9;:18;;;;;:53;;;;82225:90;82284:30;82308:5;82284:19;:17;:19::i;:30::-;82226:51;82255:21;:19;:21::i;:::-;82239:10;;82226:24;;:8;;:24;:12;:24;:::i;82225:90::-;82358:24;;;;:15;:24;;;;;;82203:112;;-1:-1:-1;82358:41:0;;82203:112;82358:41;:28;:41;:::i;:::-;82333:24;;;;:15;:24;;;;;;:66;;;;82452:8;;82436:25;;;;:42;;82466:11;82436:42;:29;:42;:::i;:::-;82426:8;;82410:25;;;;:15;:25;;;;;;:68;;;;82576:24;;;;;:40;;82605:10;82576:40;:28;:40;:::i;:::-;82549:24;;;;:15;:24;;;;;;;;:67;;;;82706:10;82698:19;;:7;:19;;;;:35;;82722:10;82698:35;:23;:35;:::i;:::-;82684:10;82676:19;;;;:7;:19;;;;;:57;82751:88;82766:7;82775:16;82766:7;82775;:16::i;:::-;82751:88;;;;;;-1:-1:-1;;;;;82751:88:0;;;;;;;82793:10;82751:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81111:1736;;;;;;;:::o;73484:114::-;73557:8;;:33;;;-1:-1:-1;;;73557:33:0;;73584:4;73557:33;;;;;;73531:7;;-1:-1:-1;;;;;73557:8:0;;:18;;:33;;;;;;;;;;;;;;:8;:33;;;5:2:-1;;;;30:1;27;20:12;5:2;73557:33:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73557:33:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73557:33:0;;-1:-1:-1;73484:114:0;:::o;66208:89::-;66282:7;66275:14;;;;;;;;-1:-1:-1;;66275:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66249:13;;66275:14;;66282:7;;66275:14;;66282:7;66275:14;;;;;;;;;;;;;;;;;;;;;;;;74019:162;74069:7;74090:12;74109:14;;;;;;;;;-1:-1:-1;;;;;74109:14:0;-1:-1:-1;;;;;74109:30:0;;:32;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74109:32:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74109:32:0;;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;74109:32:0;;;;-1:-1:-1;;74019:162:0;:::o;84204:102::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;84277:13;:21;;-1:-1:-1;;;;;;84277:21:0;-1:-1:-1;;;;;84277:21:0;;;;;;;;;;84204:102::o;84870:198::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;85011:8;;:49;;;-1:-1:-1;;;85011:49:0;;-1:-1:-1;;;;;85011:8:0;;;:49;;;;;;;;;;;;;;:8;;:17;;:49;;;;;;;;;;;;;;:8;;:49;;;5:2:-1;;;;30:1;27;20:12;5:2;85011:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;85011:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;43678:254:0;43764:12;:10;:12::i;:::-;-1:-1:-1;;;;;43758:18:0;:2;-1:-1:-1;;;;;43758:18:0;;;43750:56;;;;;-1:-1:-1;;;43750:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;43858:8;43819:18;:32;43838:12;:10;:12::i;:::-;-1:-1:-1;;;;;43819:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;43819:32:0;;;:36;;;;;;;;;;;;:47;;-1:-1:-1;;43819:47:0;;;;;;;;;;;43897:12;:10;:12::i;:::-;43882:42;;;;;;;;;;-1:-1:-1;;;;;43882:42:0;;;;;;;;;;;;;;43678:254;;:::o;73717:92::-;73791:10;;73717:92;:::o;71206:25::-;;;;:::o;73817:92::-;73891:10;;73817:92;:::o;80474:629::-;80538:4;80563:16;80571:7;80563;:16::i;:::-;80555:49;;;;;-1:-1:-1;;;80555:49:0;;;;;;;;;;;;-1:-1:-1;;;80555:49:0;;;;;;;;;;;;;;;80628:24;;;;:15;:24;;;;;;:29;;:54;;-1:-1:-1;80661:18:0;;;;:9;:18;;;;;;:21;80628:54;80625:97;;;-1:-1:-1;80705:5:0;80698:12;;80625:97;80735:31;80819:24;;;:15;:24;;;;;;;;;80845:9;:18;;;;;;80735:31;;80789:75;;:29;:75::i;:::-;80734:130;;-1:-1:-1;80734:130:0;-1:-1:-1;80877:28:0;80908:38;80734:130;;80908:38;:27;:38;:::i;:::-;80877:69;;80985:28;;80962:20;:51;80959:137;;;81036:4;81029:11;;;;;;;80959:137;81079:5;81072:12;;;;;;;46681:272;46796:41;46815:12;:10;:12::i;:::-;46829:7;46796:18;:41::i;:::-;46788:103;;;;-1:-1:-1;;;46788:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46902:43;46920:4;46926:2;46930:7;46939:5;46902:17;:43::i;:::-;46681:272;;;;:::o;71655:32::-;;;-1:-1:-1;;;71655:32:0;;;;;:::o;70455:409::-;70511:13;70545:16;70553:7;70545;:16::i;:::-;70537:25;;;;;;70624:5;;70690:39;;;-1:-1:-1;;;70690:39:0;;70723:4;70690:39;;;;;;-1:-1:-1;;;;;70624:5:0;;;;70575:27;;70624:5;;70690:24;;:39;;;;;;;;;;;;;;;70624:5;70690:39;;;5:2:-1;;;;30:1;27;20:12;5:2;70690:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70690:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70690:39:0;70756:4;70750:18;70690:39;;-1:-1:-1;70750:18:0;-1:-1:-1;;70750:18:0;;;;;;;;;;;:106;;;;;;;;;;;;;;;;;70805:44;;;-1:-1:-1;;;70805:44:0;;70834:4;70805:44;;;;;;;;;;;;70799:4;;-1:-1:-1;;;;;70805:20:0;;;;;:44;;;;;-1:-1:-1;;70805:44:0;;;;;;;;:20;:44;;;5:2:-1;;;;30:1;27;20:12;5:2;70805:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;70805:44:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;70805:44:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;70805:44:0;;;;;;;;;;;;;19:11:-1;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;213:10;;261:11;244:29;;285:43;;;282:58;-1:-1;233:115;230:2;;;361:1;358;351:12;230:2;372:25;;-1:-1;70805:44:0;;420:4:-1;411:14;;;;70805:44:0;;;;;411:14:-1;70805:44: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;70805:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70782:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70782:68:0;;;;;;;;;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;;;70782:68:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;70782:68:0;;;70750:106;70743:113;70455:409;-1:-1:-1;;;;70455:409:0:o;73917:94::-;73995:8;;73917:94;:::o;71334:23::-;;;;:::o;71476:24::-;;;;:::o;78523:254::-;30928:11;;;;30920:55;;;;;-1:-1:-1;;;30920:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;31067:5;31053:19;;-1:-1:-1;;31053:19:0;;;78589:10;78581:19;;:7;:19;;;;;;78573:63;;;;;-1:-1:-1;;;78573:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;78672:10;78647:14;78664:19;;;:7;:19;;;;;;;78694:21;;;78726:10;;78664:19;;78726:43;;-1:-1:-1;;;;;78726:10:0;;78664:19;78726:43;:23;:43;:::i;:::-;-1:-1:-1;31233:11:0;:18;;-1:-1:-1;;31233:18:0;31247:4;31233:18;;;78523:254::o;71423:44::-;;;;;;;;;;;;;:::o;71366:50::-;;;;;;;;;;;;;:::o;71577:31::-;;;-1:-1:-1;;;;;71577:31:0;;:::o;80014:452::-;80086:7;80113:16;80121:7;80113;:16::i;:::-;80105:49;;;;;-1:-1:-1;;;80105:49:0;;;;;;;;;;;;-1:-1:-1;;;80105:49:0;;;;;;;;;;;;;;;80170:24;;;;:15;:24;;;;;;:29;;:54;;-1:-1:-1;80203:18:0;;;;:9;:18;;;;;;:21;80170:54;80167:93;;;-1:-1:-1;80247:1:0;80240:8;;80167:93;80271:31;80355:24;;;:15;:24;;;;;;;;;80381:9;:18;;;;;;80271:31;;80325:75;;:29;:75::i;:::-;80270:130;;-1:-1:-1;80270:130:0;-1:-1:-1;80420:38:0;80270:130;;80420:38;:27;:38;:::i;71154:43::-;;;;:::o;44262:147::-;-1:-1:-1;;;;;44366:25:0;;;44342:4;44366:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;44262:147::o;83641:102::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;83715:9;:20;83641:102::o;76058:392::-;76140:10;;:62;;-1:-1:-1;;;;;76140:10:0;76168;76188:4;76195:6;76140:62;:27;:62;:::i;:::-;76215:21;76239:24;;;:15;:24;;;;;;:36;;76268:6;76239:36;:28;:36;:::i;:::-;76312:24;;;;:15;:24;;;;;;76215:60;;-1:-1:-1;76295:41:0;;;76288:49;;;;76350:24;;;;:15;:24;;;;;;;;;:40;;;76408:34;;;;;;;;;;;;;;;;;;;;;;;;76058:392;;;:::o;3206:109::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;3279:28;3298:8;3279:18;:28::i;83779:149::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;83888:5;-1:-1:-1;;;;;83882:21:0;;83904:2;83908:11;83882:38;;;;;;;;;;;;;-1:-1:-1;;;;;83882:38:0;-1:-1:-1;;;;;83882:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;83882:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;83882:38:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;83779:149:0:o;83531:102::-;2312:9;:7;:9::i;:::-;2304:54;;;;;-1:-1:-1;;;2304:54:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;2304:54:0;;;;;;;;;;;;;;;83605:9;:20;83531:102::o;48146:155::-;48203:4;48236:20;;;:11;:20;;;;;;-1:-1:-1;;;;;48236:20:0;48274:19;;;48146:155::o;7450:181::-;7508:7;7540:5;;;7564:6;;;;7556:46;;;;;-1:-1:-1;;;7556:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;7622:1;7450:181;-1:-1:-1;;;7450:181:0:o;74905:364::-;74988:4;75006:31;75039:17;75060:47;75090:10;75102:4;75060:29;:47::i;:::-;75005:102;;-1:-1:-1;75005:102:0;-1:-1:-1;75120:28:0;75151:38;75005:102;;75151:38;:27;:38;:::i;:::-;75233:28;;-1:-1:-1;75209:52:0;;74905:364;-1:-1:-1;;;;;;74905:364:0:o;15781:176::-;15890:58;;;-1:-1:-1;;;;;15890:58:0;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;15890:58:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;15864:85:0;;15883:5;;15864:18;:85::i;806:98::-;886:10;806:98;:::o;74189:708::-;74286:7;74295;74324:19;:17;:19::i;:::-;74317:32;;;;74367:21;:19;:21::i;:::-;74360:34;;;;74407:23;74433:112;74479:64;74520:10;;;;;;;;;-1:-1:-1;;;;;74520:10:0;-1:-1:-1;;;;;74520:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;74520:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74520:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;74520:21:0;74487:8;;:19;;;-1:-1:-1;;;74487:19:0;;;;74512:30;;;;;-1:-1:-1;;;;;74487:8:0;;;;:17;;:19;;;;;74520:21;;74487:19;;;;;;;;:8;:19;;;5:2:-1;;;;30:1;27;20:12;5:2;74487:19:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74487:19:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;74487:19:0;74479:28;;;:64;:32;:64;:::i;:::-;74474:2;:70;74433:36;74449:19;:17;:19::i;:::-;74433:11;;:36;:15;:36;:::i;:112::-;74407:138;;74584:11;74565:15;:30;;74558:38;;;;74609:17;74629:32;74639:21;:19;:21::i;:::-;74629:5;;:32;:9;:32;:::i;:::-;74609:52;;74694:5;74681:9;:18;;74674:26;;;;74713:31;74747:24;:15;74767:3;74747:24;:19;:24;:::i;:::-;74713:58;;74817:15;74791:23;:41;74784:49;;;;74854:23;74879:9;;-1:-1:-1;74189:708:0;-1:-1:-1;;;;74189:708:0:o;9761:132::-;9819:7;9846:39;9850:1;9853;9846:39;;;;;;;;;;;;;;;;;:3;:39::i;48671:333::-;48756:4;48781:16;48789:7;48781;:16::i;:::-;48773:73;;;;-1:-1:-1;;;48773:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48857:13;48873:16;48881:7;48873;:16::i;:::-;48857:32;;48919:5;-1:-1:-1;;;;;48908:16:0;:7;-1:-1:-1;;;;;48908:16:0;;:51;;;;48952:7;-1:-1:-1;;;;;48928:31:0;:20;48940:7;48928:11;:20::i;:::-;-1:-1:-1;;;;;48928:31:0;;48908:51;:87;;;;48963:32;48980:5;48987:7;48963:16;:32::i;58625:245::-;58711:38;58731:4;58737:2;58741:7;58711:19;:38::i;:::-;58762:47;58795:4;58801:7;58762:32;:47::i;:::-;58822:40;58850:2;58854:7;58822:27;:40::i;67930:90::-;67994:18;;;;:8;;:18;;;;;:::i;:::-;;67930:90;:::o;8822:471::-;8880:7;9125:6;9121:47;;-1:-1:-1;9155:1:0;9148:8;;9121:47;9192:5;;;9196:1;9192;:5;:1;9216:5;;;;;:10;9208:56;;;;-1:-1:-1;;;9208:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59135:202;59199:24;59211:2;59215:7;59199:11;:24::i;:::-;59236:40;59264:2;59268:7;59236:27;:40::i;:::-;59289;59321:7;59289:31;:40::i;36800:114::-;36892:14;;36800:114::o;7906:136::-;7964:7;7991:43;7995:1;7998;7991:43;;;;;;;;;;;;;;;;;:3;:43::i;15965:204::-;16092:68;;;-1:-1:-1;;;;;16092:68:0;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;;6:49;;16092:68:0;;;;;;;;25:18:-1;;61:17;;-1:-1;;;;;182:15;-1:-1;;;179:29;160:49;;16066:95:0;;16085:5;;16066:18;:95::i;51889:92::-;51941:32;51947:16;51955:7;51947;:16::i;:::-;51965:7;51941:5;:32::i;47672:272::-;47782:32;47796:4;47802:2;47806:7;47782:13;:32::i;:::-;47833:48;47856:4;47862:2;47866:7;47875:5;47833:22;:48::i;:::-;47825:111;;;;-1:-1:-1;;;47825:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3421:229;-1:-1:-1;;;;;3495:22:0;;3487:73;;;;-1:-1:-1;;;3487:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3597:6;;3576:38;;-1:-1:-1;;;;;3576:38:0;;;;3597:6;;3576:38;;3597:6;;3576:38;3625:6;:17;;-1:-1:-1;;;;;;3625:17:0;-1:-1:-1;;;;;3625:17:0;;;;;;;;;;3421:229::o;17820:1114::-;18424:27;18432:5;-1:-1:-1;;;;;18424:25:0;;:27::i;:::-;18416:71;;;;;-1:-1:-1;;;18416:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;18561:12;18575:23;18610:5;-1:-1:-1;;;;;18602:19:0;18622:4;18602: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;;;18602: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;;18560:67:0;;;;18646:7;18638:52;;;;;-1:-1:-1;;;18638:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18707:17;;:21;18703:224;;18849:10;18838:30;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;18838:30:0;18830:85;;;;-1:-1:-1;;;18830:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10423:345;10509:7;10611:12;10604:5;10596:28;;;;-1:-1:-1;;;10596: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;10596:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10635:9;10651:1;10647;:5;;;;;;;10423:345;-1:-1:-1;;;;;10423:345:0:o;52367:459::-;52481:4;-1:-1:-1;;;;;52461:24:0;:16;52469:7;52461;:16::i;:::-;-1:-1:-1;;;;;52461:24:0;;52453:78;;;;-1:-1:-1;;;52453:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;52550:16:0;;52542:65;;;;-1:-1:-1;;;52542:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52620:23;52635:7;52620:14;:23::i;:::-;-1:-1:-1;;;;;52656:23:0;;;;;;:17;:23;;;;;:35;;:33;:35::i;:::-;-1:-1:-1;;;;;52702:21:0;;;;;;:17;:21;;;;;:33;;:31;:33::i;:::-;52748:20;;;;:11;:20;;;;;;:25;;-1:-1:-1;;;;;;52748:25:0;-1:-1:-1;;;;;52748:25:0;;;;;;;;;52791:27;;52748:20;;52791:27;;;;;;;52367:459;;;:::o;61810:1148::-;-1:-1:-1;;;;;62101:18:0;;62076:22;62101:18;;;:12;:18;;;;;:25;:32;;62131:1;62101:32;:29;:32;:::i;:::-;62144:18;62165:26;;;:17;:26;;;;;;62076:57;;-1:-1:-1;62298:28:0;;;62294:328;;-1:-1:-1;;;;;62365:18:0;;62343:19;62365:18;;;:12;:18;;;;;:34;;62384:14;;62365:34;;;;;;;;;;;;;;62343:56;;62449:11;62416:12;:18;62429:4;-1:-1:-1;;;;;62416:18:0;-1:-1:-1;;;;;62416:18:0;;;;;;;;;;;;62435:10;62416:30;;;;;;;;;;;;;;;;;;;:44;;;;62533:30;;;:17;:30;;;;;:43;;;62294:328;-1:-1:-1;;;;;62711:18:0;;;;;;:12;:18;;;;;:27;;;;;-1:-1:-1;;62711:27:0;;;:::i;60632:186::-;-1:-1:-1;;;;;60746:16:0;;;;;;;:12;:16;;;;;;;;:23;;60717:26;;;:17;:26;;;;;:52;;;60780:16;;;39:1:-1;23:18;;45:23;;60780:30:0;;;;;;;;60632:186::o;50756:335::-;-1:-1:-1;;;;;50828:16:0;;50820:61;;;;;-1:-1:-1;;;50820:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50901:16;50909:7;50901;:16::i;:::-;50900:17;50892:58;;;;;-1:-1:-1;;;50892:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;50963:20;;;;:11;:20;;;;;;;;:25;;-1:-1:-1;;;;;;50963:25:0;-1:-1:-1;;;;;50963:25:0;;;;;;;;50999:21;;:17;:21;;;;;:33;;:31;:33::i;:::-;51050;;51075:7;;-1:-1:-1;;;;;51050:33:0;;;51067:1;;51050:33;;51067:1;;51050:33;50756:335;;:::o;61019:164::-;61123:10;:17;;61096:24;;;;:15;:24;;;;;:44;;;39:1:-1;23:18;;45:23;;61151:24:0;;;;;;;61019:164::o;8379:192::-;8465:7;8501:12;8493:6;;;;8485:29;;;;-1:-1:-1;;;8485:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;8485:29:0;-1:-1:-1;;;8537:5:0;;;8379:192::o;68654:247::-;68721:27;68733:5;68740:7;68721:11;:27::i;:::-;68807:19;;;;:10;:19;;;;;68801:33;;-1:-1:-1;;68801:33:0;;;;;;;;;;;:38;68797:97;;68863:19;;;;:10;:19;;;;;68856:26;;;:::i;53478:1079::-;53600:4;53627:15;:2;-1:-1:-1;;;;;53627:13:0;;:15::i;:::-;53622:60;;-1:-1:-1;53666:4:0;53659:11;;53622:60;53753:12;53767:23;-1:-1:-1;;;;;53794:7:0;;-1:-1:-1;;;53899:12:0;:10;:12::i;:::-;53926:4;53945:7;53967:5;53802:181;;;;;;-1:-1:-1;;;;;53802:181:0;-1:-1:-1;;;;;53802:181:0;;;;;;-1:-1:-1;;;;;53802:181:0;-1:-1:-1;;;;;53802:181: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;53802:181:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53802:181:0;;;-1:-1:-1;;26:21;;;22:32;6:49;;53802:181:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;53802:181:0;;;179:29:-1;;;;160:49;;53794:190:0;;;53802:181;;53794:190;;-1:-1:-1;53794:190:0;;-1:-1:-1;25:18;-1:-1;53794:190:0;-1:-1:-1;53794:190:0;;-1:-1:-1;53794:190:0;;-1:-1:-1;25:18;36:153;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;;;53794:190: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;;53752:232:0;;;;54000:7;53995:555;;54028:17;;:21;54024:384;;54196:10;54190:17;54257:15;54244:10;54240:2;54236:19;54229:44;54144:148;54332:60;;-1:-1:-1;;;54332:60:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53995:555;54440:13;54467:10;54456:32;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;54456:32:0;-1:-1:-1;;;;;;54511:26:0;-1:-1:-1;;;54511:26:0;;-1:-1:-1;54503:35:0;;-1:-1:-1;;;54503:35:0;12810:619;12870:4;13338:20;;13181:66;13378:23;;;;;;:42;;-1:-1:-1;;13405:15:0;;;12810:619;-1:-1:-1;;12810:619:0:o;54725:175::-;54825:1;54789:24;;;:15;:24;;;;;;-1:-1:-1;;;;;54789:24:0;:38;54785:108;;54879:1;54844:24;;;:15;:24;;;;;:37;;-1:-1:-1;;;;;;54844:37:0;;;54725:175::o;37111:110::-;37192:14;;:21;;37211:1;37192:21;:18;:21;:::i;:::-;37175:38;;37111:110::o;36922:181::-;37076:19;;37094:1;37076:19;;;36922:181::o;59621:372::-;59688:27;59700:5;59707:7;59688:11;:27::i;:::-;59728:48;59761:5;59768:7;59728:32;:48::i;:::-;59926:1;59897:26;;;:17;:26;;;;;:30;59940:45;59915:7;59940:36;:45::i;51368:333::-;51463:5;-1:-1:-1;;;;;51443:25:0;:16;51451:7;51443;:16::i;:::-;-1:-1:-1;;;;;51443:25:0;;51435:75;;;;-1:-1:-1;;;51435:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51523:23;51538:7;51523:14;:23::i;:::-;-1:-1:-1;;;;;51559:24:0;;;;;;:17;:24;;;;;:36;;:34;:36::i;:::-;51637:1;51606:20;;;:11;:20;;;;;;:33;;-1:-1:-1;;;;;;51606:33:0;;;51657:36;51618:7;;51637:1;-1:-1:-1;;;;;51657:36:0;;;;;51637:1;;51657:36;51368:333;;:::o;63253:1082::-;63531:10;:17;63506:22;;63531:24;;63553:1;63531:24;:21;:24;:::i;:::-;63566:18;63587:24;;;:15;:24;;;;;;63960:10;:26;;63506:49;;-1:-1:-1;63587:24:0;;63506:49;;63960:26;;;;;;;;;;;;;;63938:48;;64024:11;63999:10;64010;63999:22;;;;;;;;;;;;;;;;;;;:36;;;;64104:28;;;:15;:28;;;;;;:41;;;64269:10;:19;;;;;-1:-1:-1;;64269:19:0;;;:::i;:::-;-1:-1:-1;;;64326:1:0;64299:24;;;-1:-1:-1;64299:15:0;:24;;;;;:28;63253:1082::o;82945:2235::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82945:2235:0;;;-1:-1:-1;82945:2235:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

bzzr://d13e7b06f902d0075de260422a7b04b5a1dcf7816a51d1ad8157dddf1abbc0fa
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading