ETH Price: $3,390.21 (+1.52%)

Token

iDOL (iDOL)
 

Overview

Max Total Supply

314,914,121.87679886 iDOL

Holders

342

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 8 Decimals)

Filtered by Token Holder
thetaylor.eth
Balance
7.70971494 iDOL

Value
$0.00
0x72eb41ae7f943445da9932662d31a06d56a3cfaa
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
StableCoin

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
Yes with 20000 runs

Other Settings:
constantinople EvmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-08-31
*/

pragma solidity 0.6.6;

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


/**
 * @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.
     */
    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.
     */
    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.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b != 0, errorMessage);
        return a % b;
    }
}

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



/**
 * @title SignedSafeMath
 * @dev Signed math operations with safety checks that revert on error.
 */
library SignedSafeMath {
    int256 constant private _INT256_MIN = -2**255;

    /**
     * @dev Multiplies two signed integers, reverts on overflow.
     */
    function mul(int256 a, int256 b) internal pure returns (int256) {
        // 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;
        }

        require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow");

        int256 c = a * b;
        require(c / a == b, "SignedSafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0, "SignedSafeMath: division by zero");
        require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");

        int256 c = a / b;

        return c;
    }

    /**
     * @dev Subtracts two signed integers, reverts on overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");

        return c;
    }

    /**
     * @dev Adds two signed integers, reverts on overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");

        return c;
    }
}

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




/**
 * @dev Wrappers over Solidity's uintXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such 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.
 *
 * Can be combined with {SafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and then downcasting.
 */
library SafeCast {

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        require(value < 2**255, "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

// File: contracts/math/UseSafeMath.sol







/**
 * @notice ((a - 1) / b) + 1 = (a + b -1) / b
 * for example a.add(10**18 -1).div(10**18) = a.sub(1).div(10**18) + 1
 */

library SafeMathDivRoundUp {
    using SafeMath for uint256;

    function divRoundUp(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }
        require(b > 0, errorMessage);
        return ((a - 1) / b) + 1;
    }

    function divRoundUp(uint256 a, uint256 b) internal pure returns (uint256) {
        return divRoundUp(a, b, "SafeMathDivRoundUp: modulo by zero");
    }
}


/**
 * @title UseSafeMath
 * @dev One can use SafeMath for not only uint256 but also uin64 or uint16,
 * and also can use SafeCast for uint256.
 * For example:
 *   uint64 a = 1;
 *   uint64 b = 2;
 *   a = a.add(b).toUint64() // `a` become 3 as uint64
 * In additionally, one can use SignedSafeMath and SafeCast.toUint256(int256) for int256.
 * In the case of the operation to the uint64 value, one need to cast the value into int256 in
 * advance to use `sub` as SignedSafeMath.sub not SafeMath.sub.
 * For example:
 *   int256 a = 1;
 *   uint64 b = 2;
 *   int256 c = 3;
 *   a = a.add(int256(b).sub(c)); // `a` become 0 as int256
 *   b = a.toUint256().toUint64(); // `b` become 0 as uint64
 */
abstract contract UseSafeMath {
    using SafeMath for uint256;
    using SafeMathDivRoundUp for uint256;
    using SafeMath for uint64;
    using SafeMathDivRoundUp for uint64;
    using SafeMath for uint16;
    using SignedSafeMath for int256;
    using SafeCast for uint256;
    using SafeCast for int256;
}

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



/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
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: contracts/StableCoinInterface.sol





interface StableCoinInterface is IERC20 {
    event LogIsAcceptableSBT(bytes32 indexed bondID, bool isAcceptable);

    event LogMintIDOL(
        bytes32 indexed bondID,
        address indexed owner,
        bytes32 poolID,
        uint256 obtainIDOLAmount,
        uint256 poolIDOLAmount
    );

    event LogBurnIDOL(
        bytes32 indexed bondID, // poolID?
        address indexed owner,
        uint256 burnIDOLAmount,
        uint256 unlockSBTAmount
    );

    event LogReturnLockedPool(
        bytes32 indexed poolID,
        address indexed owner,
        uint64 backIDOLAmount
    );

    event LogLambda(
        bytes32 indexed poolID,
        uint64 settledAverageAuctionPrice,
        uint256 totalSupply,
        uint256 lockedSBTValue
    );

    function getPoolInfo(bytes32 poolID)
        external
        view
        returns (
            uint64 lockedSBTTotal,
            uint64 unlockedSBTTotal,
            uint64 lockedPoolIDOLTotal,
            uint64 burnedIDOLTotal,
            uint64 soldSBTTotalInAuction,
            uint64 paidIDOLTotalInAuction,
            uint64 settledAverageAuctionPrice,
            bool isAllAmountSoldInAuction
        );

    function solidValueTotal() external view returns (uint256 solidValue);

    function isAcceptableSBT(bytes32 bondID) external returns (bool ok);

    function mint(
        bytes32 bondID,
        address recipient,
        uint64 lockAmount
    )
        external
        returns (
            bytes32 poolID,
            uint64 obtainIDOLAmount,
            uint64 poolIDOLAmount
        );

    function burnFrom(address account, uint256 amount) external;

    function unlockSBT(bytes32 bondID, uint64 burnAmount)
        external
        returns (uint64 rewardSBT);

    function startAuctionOnMaturity(bytes32 bondID) external;

    function startAuctionByMarket(bytes32 bondID) external;

    function setSettledAverageAuctionPrice(
        bytes32 bondID,
        uint64 totalPaidIDOL,
        uint64 SBTAmount,
        bool isLast
    ) external;

    function calcSBT2IDOL(uint256 solidBondAmount)
        external
        view
        returns (uint256 IDOLAmount);

    function returnLockedPool(bytes32[] calldata poolIDs)
        external
        returns (uint64 IDOLAmount);

    function returnLockedPoolTo(bytes32[] calldata poolIDs, address account)
        external
        returns (uint64 IDOLAmount);

    function generatePoolID(bytes32 bondID, uint64 count)
        external
        pure
        returns (bytes32 poolID);

    function getCurrentPoolID(bytes32 bondID)
        external
        view
        returns (bytes32 poolID);

    function getLockedPool(address user, bytes32 poolID)
        external
        view
        returns (uint64, uint64);
}

// File: contracts/util/Time.sol




abstract contract Time {
    function _getBlockTimestampSec()
        internal
        view
        returns (uint256 unixtimesec)
    {
        unixtimesec = now; // solium-disable-line security/no-block-members
    }
}

// File: @openzeppelin/contracts/GSN/Context.sol



/*
 * @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 { }

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

    function _msgData() internal view virtual 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/utils/Address.sol



/**
 * @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 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].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

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

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







/**
 * @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 {ERC20MinterPauser}.
 *
 * 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;
    using Address for address;

    mapping (address => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;
    uint8 private _decimals;

    /**
     * @dev Sets the values for {name} and {symbol}, initializes {decimals} with
     * a default value of 18.
     *
     * To select a different value for {decimals}, use {_setupDecimals}.
     *
     * All three of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name, string memory symbol) public {
        _name = name;
        _symbol = symbol;
        _decimals = 18;
    }

    /**
     * @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. This is the value {ERC20} uses, unless {_setupDecimals} is
     * called.
     *
     * 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;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view override 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 virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

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

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override 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 virtual override 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 virtual 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 virtual 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 virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        _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 virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _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 virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        _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 virtual {
        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 Sets {decimals} to a value other than the default one of 18.
     *
     * WARNING: This function should only be called from the constructor. Most
     * applications that interact with token contracts will not expect
     * {decimals} to ever change, and may work incorrectly if it does.
     */
    function _setupDecimals(uint8 decimals_) internal {
        _decimals = decimals_;
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

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



/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}

// File: contracts/solidBondSafety/SolidBondSafety.sol






// This contract is used for calculating minimum threshold acceptable strike price (relative to the current oracle price)
// for the SBT with the time to maturity and the volatility from oracle.
// It is derived from the risk appetite of this protocol.
// For volatile SBT due to the long time to maturity or the underlying ETH volatility,
// the minimum threshold acceptable strike price needs to increase in order to mitigate the risk of emergency auction.
// The policy in this protocol is to equalize the risk of acceptable SBT over the different time to maturity or the underlying ETH volatility.
// The threshold is thus derived from solving the black-scholes formula with a linear approximation technique.
// Even in the approximation of the formula, there remains square root of time, which is tricky to handle in solidity.
// Hence, we deal with the value in the squared form of the value.
// In the following notations, for example, vvtE16 represents v^2 * t * 10^16.
abstract contract SolidBondSafety is UseSafeMath, Time {
    /// @notice The return values of getEmergencyBorderInfo are intermediate values
    /// used for checking if the SBT is acceptable to the IDOL contract.
    /// Let f(x) = a*x + b be the function defined below:
    /// f(x) =            1.1    for 0      <= x <= 0.3576
    /// f(x) =  1.52 x +  0.5564 for 0.3576 < x <= 0.7751
    /// f(x) =  6.4  x -  3.226  for 0.7751 < x <= 1.1562
    /// f(x) = 14.27 x - 12.3256 for 1.1562 < x <= 1.416
    /// f(x) = 29.13 x - 33.3676 for 1.416  < x <= 1.6257
    /// f(x) = 53.15 x - 72.4165 for 1.6257 < x <= 1.8
    /// Then, we define getEmergencyBorderInfo(x^2 * 10^8) = (a^2 * 10^4, b * 10^4).
    /// @param  xxE8 is multiply 10^8 with the square of x
    /// @return aaE4 is multiply 10000 with the square of a
    /// @return bE4  is multiply 10000 with b
    function getEmergencyBorderInfo(uint256 xxE8)
        public
        pure
        returns (int256 aaE4, int256 bE4)
    {
        if (xxE8 <= 3576 * 3576) {
            return (0, 11000);
        } else if (xxE8 <= 7751 * 7751) {
            return (152 * 152, 5564);
        } else if (xxE8 <= 11562 * 11562) {
            return (640 * 640, -32260);
        } else if (xxE8 <= 14160 * 14160) {
            return (1427 * 1427, -123256);
        } else if (xxE8 <= 16257 * 16257) {
            return (2913 * 2913, -333676);
        } else if (xxE8 <= 18000 * 18000) {
            return (5315 * 5315, -724165);
        } else {
            revert("not acceptable");
        }
    }

    /// @param rateETH2USD S * 10^8 (USD/ETH)
    /// @param solidBondStrikePrice K * 10^4 (USD/SBT)
    /// @param volatility v * 10^8
    /// @param untilMaturity t (= T * 365 * 86400)
    // isInEmergency checks if the SBT should be put into emergency auction.
    // The condition is verified by utilizing approximate form of black-scholes formula.
    function isInEmergency(
        uint256 rateETH2USD,
        uint256 solidBondStrikePrice,
        uint256 volatility,
        uint256 untilMaturity
    ) public pure returns (bool) {
        uint256 vE8 = volatility;
        if (vE8 > 2 * 10**8) {
            vE8 = 2 * 10**8; // The volatility is too high.
        }
        if (untilMaturity >= 12 weeks) {
            return true; // The period until maturity is too long.
        }
        uint256 vvtE16 = vE8.mul(vE8).mul(untilMaturity);

        uint256 xxE8 = vvtE16 / (64 * 10**6 * 86400 * 365); // 1.25^2 / 10^8 = 1 / (64 * 10^6)
        (int256 aaE4, int256 bE4) = getEmergencyBorderInfo(xxE8);
        int256 sE8 = rateETH2USD.toInt256();
        int256 kE4 = solidBondStrikePrice.toInt256();
        int256 cE8 = sE8.sub(bE4.mul(kE4));
        // int256 lE28 = cE8.mul(cE8).mul(20183040 * 10**12);
        int256 rE28 = int256(vvtE16).mul(aaE4).mul(kE4).mul(kE4);
        bool isDanger = cE8 <= 0 || cE8.mul(cE8).mul(20183040 * 10**12) <= rE28;
        return isDanger;
    }

    /// @param rateETH2USD S * 10^8 (USD/ETH)
    /// @param solidBondStrikePrice K * 10^4  (USD/SBT)
    /// @param volatility v * 10^8
    /// @param untilMaturity t (= T * 365 * 86400)
    // isDangerSolidBond checks if the SBT is acceptable to be a part of IDOL.
    // The condition is verified by utilizing approximate form of black-scholes formula.
    // This condition is more strict than the condition for triggering emergency auction described in isInEmergency function above.
    function isDangerSolidBond(
        uint256 rateETH2USD,
        uint256 solidBondStrikePrice,
        uint256 volatility,
        uint256 untilMaturity
    ) public pure returns (bool) {
        if (
            solidBondStrikePrice * 5 * 10**4 < rateETH2USD * 2 &&
            untilMaturity < 2 weeks
        ) {
            return false;
        } else if (volatility > 2 * 10**8) {
            return true; // The volatility is too high.
        }
        if (untilMaturity >= 12 weeks) {
            return true; // The period until maturity is too long.
        }
        uint256 vvtE16 = volatility.mul(volatility).mul(untilMaturity);

        uint256 xxE8 = vvtE16 / (64 * 10**6 * 86400 * 365); // 1.25^2 / 10^8 = 1 / (64 * 10^6)
        (int256 aaE4, int256 bE4) = getEmergencyBorderInfo(xxE8);
        //                                            S/K <= 1.5f(1.25*v*sqrt(T))
        // <=>                                        S/K <= 1.5(1.25a*v*sqrt(T) + b)
        // <=>                                 (2S - 3bK) <= (3.75aKv) * sqrt(T)
        // if 2S > 3bK,
        //                                   (2S - 3bK)^2 <= (3.75aKv)^2 * t / 365 / 86400
        // <=>                       20183040(2S - 3bK)^2 <= 9t(aKv)^2
        // <=> 20183040 * 10^12(10^8 * 2S - 10^8 * 3bK)^2 <= 9 * 10000a^2 * (10000K)^2 * t(10^8 * v)^2
        int256 sE8 = rateETH2USD.toInt256();
        int256 kE4 = solidBondStrikePrice.toInt256();
        int256 cE8 = sE8.mul(2).sub(bE4.mul(kE4).mul(3));
        // int256 lE28 = cE8.mul(cE8).mul(20183040 * 10**12);
        int256 rE28 = int256(vvtE16).mul(aaE4).mul(kE4).mul(kE4).mul(9);
        bool isDanger = cE8 <= 0 || cE8.mul(cE8).mul(20183040 * 10**12) <= rE28;
        return isDanger;
    }
}

// File: contracts/AuctionTimeControlInterface.sol




interface AuctionTimeControlInterface {
    enum TimeControlFlag {
        BEFORE_AUCTION_FLAG,
        ACCEPTING_BIDS_PERIOD_FLAG,
        REVEALING_BIDS_PERIOD_FLAG,
        RECEIVING_SBT_PERIOD_FLAG,
        AFTER_AUCTION_FLAG
    }

    function listAuction(uint256 timestamp)
        external
        view
        returns (bytes32[] memory);

    function getTimeControlFlag(bytes32 auctionID)
        external
        view
        returns (TimeControlFlag);

    function isInPeriod(bytes32 auctionID, TimeControlFlag flag)
        external
        view
        returns (bool);

    function isAfterPeriod(bytes32 auctionID, TimeControlFlag flag)
        external
        view
        returns (bool);
}

// File: contracts/AuctionInterface.sol





interface AuctionInterface is AuctionTimeControlInterface {
    event LogStartAuction(
        bytes32 indexed auctionID,
        bytes32 bondID,
        uint256 auctionedAmount
    );

    event LogCancelBid(
        bytes32 indexed auctionID,
        address indexed bidder,
        bytes32 secret,
        uint256 returnedIDOLAmount
    );

    event LogAuctionResult(
        bytes32 indexed auctionID,
        address indexed bidder,
        uint256 SBTAmountOfReward,
        uint256 IDOLAmountOfPayment,
        uint256 IDOLAmountOfChange
    );

    event LogCloseAuction(
        bytes32 indexed auctionID,
        bool isLast,
        bytes32 nextAuctionID
    );

    function ongoingAuctionSBTTotal(bytes32 auctionID)
        external
        view
        returns (uint64 ongoingSBTAmountE8);

    function startAuction(
        bytes32 bondID,
        uint64 auctionAmount,
        bool isEmergency
    ) external returns (bytes32 auctonID);

    function cancelBid(bytes32 auctionID, bytes32 secret)
        external
        returns (uint64 returnedIDOLAmount);

    function makeAuctionResult(
        bytes32 auctionID,
        uint64 myLowestPrice,
        uint64[] calldata winnerBids,
        uint64[] calldata loserBids
    )
        external
        returns (
            uint64 winnerAmount,
            uint64 toPay,
            uint64 IDOLAmountOfChange
        );

    function closeAuction(bytes32 auctionID)
        external
        returns (bool isLast, bytes32 nextAuctionID);

    function receiveUnrevealedBidDistribution(bytes32 auctionID, bytes32 secret)
        external
        returns (bool success);

    function getCurrentAuctionID(bytes32 bondID)
        external
        view
        returns (bytes32 auctionID);

    function generateAuctionID(bytes32 bondID, uint256 auctionCount)
        external
        pure
        returns (bytes32 auctionID);

    function listBondIDFromAuctionID(bytes32[] calldata auctionIDs)
        external
        view
        returns (bytes32[] memory bondIDs);

    function getAuctionStatus(bytes32 auctionID)
        external
        view
        returns (
            uint256 closingTime,
            uint64 auctionAmount,
            uint64 rewardedAmount,
            uint64 totalSBTAmountBid,
            bool isEmergency,
            bool doneFinalizeWinnerAmount,
            bool doneSortPrice,
            uint64 lowestBidPriceDeadLine,
            uint64 highestBidPriceDeadLine,
            uint64 totalSBTAmountPaidForUnrevealed
        );

    function getWeeklyAuctionStatus(uint256 weekNumber)
        external
        view
        returns (uint256[] memory weeklyAuctionStatus);

    function calcWinnerAmount(
        bytes32 auctionID,
        address sender,
        uint64[] calldata winnerBids
    ) external view returns (uint64 winnerAmount);

    function calcBillAndCheckLoserBids(
        bytes32 auctionID,
        address sender,
        uint64 winnerAmountInput,
        uint64 myLowestPrice,
        uint64[] calldata myLoseBids
    ) external view returns (uint64 paymentAmount);

    function getAuctionCount(bytes32 bondID)
        external
        view
        returns (uint256 auctionCount);
}

// File: contracts/AuctionTimeControl.sol






contract AuctionTimeControl is Time, AuctionTimeControlInterface {
    uint256 internal immutable MIN_NORMAL_AUCTION_PERIOD;
    uint256 internal immutable MIN_EMERGENCY_AUCTION_PERIOD;
    uint256 internal immutable NORMAL_AUCTION_REVEAL_SPAN;
    uint256 internal immutable EMERGENCY_AUCTION_REVEAL_SPAN;
    uint256 internal immutable AUCTION_WITHDRAW_SPAN;
    uint256 internal immutable EMERGENCY_AUCTION_WITHDRAW_SPAN;

    TimeControlFlag internal constant BEFORE_AUCTION_FLAG = TimeControlFlag
        .BEFORE_AUCTION_FLAG;
    TimeControlFlag internal constant ACCEPTING_BIDS_PERIOD_FLAG = TimeControlFlag
        .ACCEPTING_BIDS_PERIOD_FLAG;
    TimeControlFlag internal constant REVEALING_BIDS_PERIOD_FLAG = TimeControlFlag
        .REVEALING_BIDS_PERIOD_FLAG;
    TimeControlFlag internal constant RECEIVING_SBT_PERIOD_FLAG = TimeControlFlag
        .RECEIVING_SBT_PERIOD_FLAG;
    TimeControlFlag internal constant AFTER_AUCTION_FLAG = TimeControlFlag
        .AFTER_AUCTION_FLAG;

    /**
     * @dev Get whether the auction is in emergency or not.
     */
    mapping(bytes32 => bool) public isAuctionEmergency;

    /**
     * @dev The end time that the auction accepts bids.
     * The zero value indicates the auction is not held.
     */
    mapping(bytes32 => uint256) public auctionClosingTime;

    /**
     * @dev The contents in this internal storage variable can be seen by listAuction function.
     */
    mapping(uint256 => bytes32[]) internal _weeklyAuctionList;

    constructor(
        uint256 minNormalAuctionPeriod,
        uint256 minEmergencyAuctionPeriod,
        uint256 normalAuctionRevealSpan,
        uint256 emergencyAuctionRevealSpan,
        uint256 auctionWithdrawSpan,
        uint256 emergencyAuctionWithdrawSpan
    ) public {
        MIN_NORMAL_AUCTION_PERIOD = minNormalAuctionPeriod;
        MIN_EMERGENCY_AUCTION_PERIOD = minEmergencyAuctionPeriod;
        NORMAL_AUCTION_REVEAL_SPAN = normalAuctionRevealSpan;
        EMERGENCY_AUCTION_REVEAL_SPAN = emergencyAuctionRevealSpan;
        AUCTION_WITHDRAW_SPAN = auctionWithdrawSpan;
        EMERGENCY_AUCTION_WITHDRAW_SPAN = emergencyAuctionWithdrawSpan;
    }

    /**
     * @dev Get auctions which will close within the week.
     */
    function listAuction(uint256 weekNumber)
        public
        override
        view
        returns (bytes32[] memory)
    {
        return _weeklyAuctionList[weekNumber];
    }

    /**
     * @notice Gets the period the auction is currently in.
     * This function returns 0-4 corresponding to its period.
     */
    function getTimeControlFlag(bytes32 auctionID)
        public
        override
        view
        returns (TimeControlFlag)
    {
        uint256 closingTime = auctionClosingTime[auctionID];

        // Note that the auction span differs based on whether the auction is in emergency or not.
        bool isEmergency = isAuctionEmergency[auctionID];
        uint256 revealSpan = NORMAL_AUCTION_REVEAL_SPAN;
        uint256 withdrawSpan = AUCTION_WITHDRAW_SPAN;
        if (isEmergency) {
            revealSpan = EMERGENCY_AUCTION_REVEAL_SPAN;
            withdrawSpan = EMERGENCY_AUCTION_WITHDRAW_SPAN;
        }

        uint256 nowTime = _getBlockTimestampSec();
        if (closingTime == 0) {
            return BEFORE_AUCTION_FLAG;
        } else if (nowTime <= closingTime) {
            return ACCEPTING_BIDS_PERIOD_FLAG;
        } else if (nowTime < closingTime + revealSpan) {
            return REVEALING_BIDS_PERIOD_FLAG;
        } else if (nowTime < closingTime + revealSpan + withdrawSpan) {
            return RECEIVING_SBT_PERIOD_FLAG;
        } else {
            return AFTER_AUCTION_FLAG;
        }
    }

    /**
     * @notice This function returns whether or not the auction is in the period indicated
     * by the flag.
     */
    function isInPeriod(bytes32 auctionID, TimeControlFlag flag)
        public
        override
        view
        returns (bool)
    {
        return getTimeControlFlag(auctionID) == flag;
    }

    /**
     * @notice Returns whether or not the auction is in or after the period indicated
     * by the flag.
     */
    function isAfterPeriod(bytes32 auctionID, TimeControlFlag flag)
        public
        override
        view
        returns (bool)
    {
        return getTimeControlFlag(auctionID) >= flag;
    }

    /**
     * @dev Calculates and registers the end time of the period in which the auction accepts bids
     * (= closingTime). The period in which bids are revealed follows after this time.
     */
    function _setAuctionClosingTime(bytes32 auctionID, bool isEmergency)
        internal
    {
        uint256 closingTime;

        if (isEmergency) {
            closingTime =
                ((_getBlockTimestampSec() +
                    MIN_EMERGENCY_AUCTION_PERIOD +
                    5 minutes -
                    1) / 5 minutes) *
                (5 minutes);
        } else {
            closingTime =
                ((_getBlockTimestampSec() +
                    MIN_NORMAL_AUCTION_PERIOD +
                    1 hours -
                    1) / 1 hours) *
                (1 hours);
        }
        _setAuctionClosingTime(auctionID, isEmergency, closingTime);
    }

    /**
     * @dev Registers the end time of the period in which the auction accepts bids (= closingTime).
     * The period in which bids are revealed follows after this time.
     */
    function _setAuctionClosingTime(
        bytes32 auctionID,
        bool isEmergency,
        uint256 closingTime
    ) internal {
        isAuctionEmergency[auctionID] = isEmergency;
        auctionClosingTime[auctionID] = closingTime;
        uint256 weekNumber = closingTime / (1 weeks);
        _weeklyAuctionList[weekNumber].push(auctionID);
    }
}

// File: contracts/BondMakerInterface.sol




interface BondMakerInterface {
    event LogNewBond(
        bytes32 indexed bondID,
        address bondTokenAddress,
        uint64 stableStrikePrice,
        bytes32 fnMapID
    );

    event LogNewBondGroup(uint256 indexed bondGroupID);

    event LogIssueNewBonds(
        uint256 indexed bondGroupID,
        address indexed issuer,
        uint256 amount
    );

    event LogReverseBondToETH(
        uint256 indexed bondGroupID,
        address indexed owner,
        uint256 amount
    );

    event LogExchangeEquivalentBonds(
        address indexed owner,
        uint256 indexed inputBondGroupID,
        uint256 indexed outputBondGroupID,
        uint256 amount
    );

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

    function registerNewBond(uint256 maturity, bytes calldata fnMap)
        external
        returns (
            bytes32 bondID,
            address bondTokenAddress,
            uint64 solidStrikePrice,
            bytes32 fnMapID
        );

    function registerNewBondGroup(
        bytes32[] calldata bondIDList,
        uint256 maturity
    ) external returns (uint256 bondGroupID);

    function issueNewBonds(uint256 bondGroupID)
        external
        payable
        returns (uint256 amount);

    function reverseBondToETH(uint256 bondGroupID, uint256 amount)
        external
        returns (bool success);

    function exchangeEquivalentBonds(
        uint256 inputBondGroupID,
        uint256 outputBondGroupID,
        uint256 amount,
        bytes32[] calldata exceptionBonds
    ) external returns (bool);

    function liquidateBond(uint256 bondGroupID, uint256 oracleHintID) external;

    function getBond(bytes32 bondID)
        external
        view
        returns (
            address bondAddress,
            uint256 maturity,
            uint64 solidStrikePrice,
            bytes32 fnMapID
        );

    function getFnMap(bytes32 fnMapID)
        external
        view
        returns (bytes memory fnMap);

    function getBondGroup(uint256 bondGroupID)
        external
        view
        returns (bytes32[] memory bondIDs, uint256 maturity);

    function generateBondID(uint256 maturity, bytes calldata functionHash)
        external
        pure
        returns (bytes32 bondID);
}

// File: contracts/UseBondMaker.sol





abstract contract UseBondMaker {
    BondMakerInterface internal immutable _bondMakerContract;

    constructor(address contractAddress) public {
        require(
            contractAddress != address(0),
            "contract should be non-zero address"
        );
        _bondMakerContract = BondMakerInterface(payable(contractAddress));
    }
}

// File: contracts/UseStableCoin.sol





abstract contract UseStableCoin {
    StableCoinInterface internal immutable _IDOLContract;

    constructor(address contractAddress) public {
        require(
            contractAddress != address(0),
            "contract should be non-zero address"
        );
        _IDOLContract = StableCoinInterface(contractAddress);
    }

    function _transferIDOLFrom(
        address from,
        address to,
        uint256 amount
    ) internal {
        _IDOLContract.transferFrom(from, to, amount);
    }

    function _transferIDOL(address to, uint256 amount) internal {
        _IDOLContract.transfer(to, amount);
    }

    function _transferIDOL(
        address to,
        uint256 amount,
        string memory errorMessage
    ) internal {
        require(_IDOLContract.balanceOf(address(this)) >= amount, errorMessage);
        _IDOLContract.transfer(to, amount);
    }
}

// File: contracts/auction/AuctionSecret.sol





interface AuctionSecretInterface {
        function auctionSecret(
        bytes32 auctionID,
        bytes32 secret
    ) external view returns (
        address sender,
        uint64 amount,
        uint64 IDOLamount
    );
}

abstract contract AuctionSecret is AuctionSecretInterface {
    /**
     * @param sender is the account who set this secret bid.
     * @param amount is target SBT amount.
     * @param IDOLamount is deposited iDOL amount attached to this secret bid.
     */
    struct Secret {
        address sender;
        uint64 amount;
        uint64 IDOLamount;
    }
    mapping(bytes32 => mapping(bytes32 => Secret)) public override auctionSecret;

    function _setSecret(
        bytes32 auctionID,
        bytes32 secret,
        address sender,
        uint64 amount,
        uint64 IDOLamount
    ) internal returns (bool) {
        require(
            auctionSecret[auctionID][secret].sender == address(0),
            "Secret already exists"
        );
        require(sender != address(0), "the zero address cannot set secret");
        auctionSecret[auctionID][secret] = Secret({
            sender: sender,
            amount: amount,
            IDOLamount: IDOLamount
        });
        return true;
    }

    function _removeSecret(bytes32 auctionID, bytes32 secret)
        internal
        returns (bool)
    {
        delete auctionSecret[auctionID][secret];
        return true;
    }
}

// File: contracts/AuctionBoardInterface.sol




interface AuctionBoardInterface is AuctionSecretInterface {
    event LogBidMemo(
        bytes32 indexed auctionID,
        address indexed bidder,
        bytes memo
    );

    event LogInsertBoard(
        bytes32 indexed auctionID,
        address indexed bidder,
        uint64 bidPrice,
        uint64 boardIndex,
        uint64 targetSBTAmount
    );

    event LogAuctionInfoDiff(
        bytes32 indexed auctionID,
        uint64 settledAmount,
        uint64 paidIDOL,
        uint64 rewardedSBT
    );

    function bidWithMemo(
        bytes32 auctionID,
        bytes32 secret,
        uint64 totalSBTAmountBid,
        bytes calldata memo
    ) external returns (uint256 depositedIDOLAmount);

    function revealBids(
        bytes32 auctionID,
        uint64[] calldata bids,
        uint64 random
    ) external;

    function sortBidPrice(bytes32 auctionID, uint64[] calldata sortedPrice)
        external;

    function makeEndInfo(bytes32 auctionID) external;

    function calcBill(
        bytes32 auctionID,
        uint64 winnerAmount,
        uint64 myLowestPrice
    ) external view returns (uint64 paymentAmount);

    function getUnsortedBidPrice(bytes32 auctionID)
        external
        view
        returns (uint64[] memory bidPriceList);

    function getSortedBidPrice(bytes32 auctionID)
        external
        view
        returns (uint64[] memory bidPriceList);

    function getEndInfo(bytes32 auctionID)
        external
        view
        returns (
            uint64 price,
            uint64 boardIndex,
            uint64 loseSBTAmount,
            uint64 auctionEndPriceWinnerSBTAmount
        );

    function getBidderStatus(bytes32 auctionID, address bidder)
        external
        view
        returns (uint64 toBack, bool isIDOLReturned);

    function getBoard(
        bytes32 auctionID,
        uint64 price,
        uint64 boardIndex
    ) external view returns (address bidder, uint64 amount);

    function getBoardStatus(bytes32 auctionID)
        external
        view
        returns (uint64[] memory boardStatus);

    function generateMultiSecret(
        bytes32 auctionID,
        uint64[] calldata bids,
        uint64 random
    ) external pure returns (bytes32 secret);

    function discretizeBidPrice(uint64 price)
        external
        pure
        returns (uint64 discretizedPrice);

    function auctionDisposalInfo(bytes32 auctionID) external view returns (
        uint64 solidStrikePriceIDOLForUnrevealedE8,
        uint64 solidStrikePriceIDOLForRestWinnersE8,
        bool isEndInfoCreated,
        bool isForceToFinalizeWinnerAmountTriggered,
        bool isPriceSorted
    );

    function removeSecret(
        bytes32 auctionID,
        bytes32 secret,
        uint64 subtractAmount
    ) external;

    function auctionRevealInfo(bytes32 auctionID) external view returns (
        uint64 totalSBTAmountBid,
        uint64 totalIDOLSecret,
        uint64 totalIDOLRevealed,
        uint16 auctionPriceCount
    );

    function auctionBoard(
        bytes32 auctionID,
        uint64 bidPrice,
        uint256 boardIndex
    ) external view returns (
        uint64 bidAmount,
        address bidder
    );

    function auctionParticipantInfo(
        bytes32 auctionID,
        address participant
    ) external view returns (
        uint64 auctionLockedIDOLAmountE8,
        uint16 bidCount
    );

    function auctionInfo(
        bytes32 auctionID
    ) external view returns (
        uint64 auctionSettledTotalE8,
        uint64 auctionRewardedTotalE8,
        uint64 auctionPaidTotalE8
    );

    function updateAuctionInfo(
        bytes32 auctionID,
        uint64 settledAmountE8,
        uint64 paidIDOLE8,
        uint64 rewardedSBTE8
    ) external;

    function deleteParticipantInfo(
        bytes32 auctionID,
        address participant
    ) external;
}

// File: contracts/UseAuctionBoard.sol





abstract contract UseAuctionBoard {
    AuctionBoardInterface internal immutable _auctionBoardContract;

    constructor(address contractAddress) public {
        require(
            contractAddress != address(0),
            "contract should be non-zero address"
        );
        _auctionBoardContract = AuctionBoardInterface(contractAddress);
    }
}

// File: contracts/oracle/OracleInterface.sol




// Oracle referenced by OracleProxy must implement this interface.
interface OracleInterface {
    // Returns if oracle is running.
    function alive() external view returns (bool);

    // Returns latest id.
    // The first id is 1 and 0 value is invalid as id.
    // Each price values and theirs timestamps are identified by id.
    // Ids are assigned incrementally to values.
    function latestId() external returns (uint256);

    // Returns latest price value.
    // decimal 8
    function latestPrice() external returns (uint256);

    // Returns timestamp of latest price.
    function latestTimestamp() external returns (uint256);

    // Returns price of id.
    function getPrice(uint256 id) external returns (uint256);

    // Returns timestamp of id.
    function getTimestamp(uint256 id) external returns (uint256);

    function getVolatility() external returns (uint256);
}

// File: contracts/oracle/UseOracle.sol





abstract contract UseOracle {
    OracleInterface internal _oracleContract;

    constructor(address contractAddress) public {
        require(
            contractAddress != address(0),
            "contract should be non-zero address"
        );
        _oracleContract = OracleInterface(contractAddress);
    }

    /// @notice Get the latest USD/ETH price and historical volatility using oracle.
    /// @return rateETH2USDE8 (10^-8 USD/ETH)
    /// @return volatilityE8 (10^-8)
    function _getOracleData()
        internal
        returns (uint256 rateETH2USDE8, uint256 volatilityE8)
    {
        rateETH2USDE8 = _oracleContract.latestPrice();
        volatilityE8 = _oracleContract.getVolatility();

        return (rateETH2USDE8, volatilityE8);
    }

    /// @notice Get the price of the oracle data with a minimum timestamp that does more than input value
    /// when you know the ID you are looking for.
    /// @param timestamp is the timestamp that you want to get price.
    /// @param hintID is the ID of the oracle data you are looking for.
    /// @return rateETH2USDE8 (10^-8 USD/ETH)
    function _getPriceOn(uint256 timestamp, uint256 hintID)
        internal
        returns (uint256 rateETH2USDE8)
    {
        uint256 latestID = _oracleContract.latestId();
        require(
            latestID != 0,
            "system error: the ID of oracle data should not be zero"
        );

        require(hintID != 0, "the hint ID must not be zero");
        uint256 id = hintID;
        if (hintID > latestID) {
            id = latestID;
        }

        require(
            _oracleContract.getTimestamp(id) > timestamp,
            "there is no price data after maturity"
        );

        id--;
        while (id != 0) {
            if (_oracleContract.getTimestamp(id) <= timestamp) {
                break;
            }
            id--;
        }

        return _oracleContract.getPrice(id + 1);
    }
}

// File: contracts/util/TransferETHInterface.sol




interface TransferETHInterface {
    receive() external payable;

    event LogTransferETH(
        address indexed from,
        address indexed to,
        uint256 value
    );
}

// File: contracts/bondToken/BondTokenInterface.sol






interface BondTokenInterface is TransferETHInterface, IERC20 {
    event LogExpire(
        uint128 rateNumerator,
        uint128 rateDenominator,
        bool firstTime
    );

    function mint(address account, uint256 amount)
        external
        returns (bool success);

    function expire(uint128 rateNumerator, uint128 rateDenominator)
        external
        returns (bool firstTime);

    function burn(uint256 amount) external returns (bool success);

    function burnAll() external returns (uint256 amount);

    function isMinter(address account) external view returns (bool minter);

    function getRate()
        external
        view
        returns (uint128 rateNumerator, uint128 rateDenominator);
}

// File: contracts/Auction.sol













contract Auction is
    UseSafeMath,
    AuctionInterface,
    AuctionTimeControl,
    UseStableCoin,
    UseBondMaker,
    UseAuctionBoard
{
    using Math for uint256;

    uint64 internal constant NO_SKIP_BID = uint64(-1);
    uint64 internal constant SKIP_RECEIVING_WIN_BIDS = uint64(-2);
    uint256 internal constant POOL_AUCTION_COUNT_PADDING = 10**8;

    /**
     * @notice The times of auctions held for the auction ID.
     * @dev The contents in this internal storage variable can be seen by getAuctionCount function.
     */
    mapping(bytes32 => uint256) internal _bondIDAuctionCount;

    /**
     * @notice Get the bond ID from the auction ID.
     */
    mapping(bytes32 => bytes32) public auctionID2BondID;

    /**
     * @dev The contents in this internal storage variable can be seen by getAuctionStatus function.
     * @param ongoingAuctionSBTTotalE8 is the SBT amount put up in the auction.
     * @param lowestBidPriceDeadLineE8 is the minimum bid price in the auction.
     * @param highestBidPriceDeadLineE8 is the maximum bid price in the auction.
     * @param totalSBTAmountPaidForUnrevealedE8 is the SBT Amount allocated for those who had not revealed their own bid.
     */
    struct AuctionConfig {
        uint64 ongoingAuctionSBTTotalE8;
        uint64 lowestBidPriceDeadLineE8;
        uint64 highestBidPriceDeadLineE8;
        uint64 totalSBTAmountPaidForUnrevealedE8;
    }
    mapping(bytes32 => AuctionConfig) internal _auctionConfigList;

    constructor(
        address bondMakerAddress,
        address IDOLAddress,
        address auctionBoardAddress,
        uint256 minNormalAuctionPeriod,
        uint256 minEmergencyAuctionPeriod,
        uint256 normalAuctionRevealSpan,
        uint256 emergencyAuctionRevealSpan,
        uint256 auctionWithdrawSpan,
        uint256 emergencyAuctionWithdrawSpan
    )
        public
        AuctionTimeControl(
            minNormalAuctionPeriod,
            minEmergencyAuctionPeriod,
            normalAuctionRevealSpan,
            emergencyAuctionRevealSpan,
            auctionWithdrawSpan,
            emergencyAuctionWithdrawSpan
        )
        UseBondMaker(bondMakerAddress)
        UseStableCoin(IDOLAddress)
        UseAuctionBoard(auctionBoardAddress)
    {}

    /**
     * @dev This function starts the auction for the auctionID. Can be called only by the IDOL contract.
     */
    function startAuction(
        bytes32 bondID,
        uint64 auctionAmount,
        bool isEmergency
    ) external override returns (bytes32) {
        require(
            msg.sender == address(_IDOLContract),
            "caller must be IDOL contract"
        );
        return _startAuction(bondID, auctionAmount, isEmergency);
    }

    /**
     * @notice This function is called when the auction (re)starts.
     * @param bondID is SBT ID whose auction will be held.
     * @param auctionAmount is SBT amount put up in the auction.
     * @param isEmergency is the flag that indicates the auction schedule is for emergency mode.
     */
    function _startAuction(
        bytes32 bondID,
        uint64 auctionAmount,
        bool isEmergency
    ) internal returns (bytes32) {
        (, , uint256 solidStrikePriceE4, ) = _bondMakerContract.getBond(bondID);
        uint256 strikePriceIDOL = _IDOLContract.calcSBT2IDOL(
            solidStrikePriceE4.mul(10**8)
        );

        uint256 auctionCount = _bondIDAuctionCount[bondID].add(1);
        _bondIDAuctionCount[bondID] = auctionCount;
        bytes32 auctionID = getCurrentAuctionID(bondID);
        require(
            isInPeriod(auctionID, BEFORE_AUCTION_FLAG),
            "the auction has been held"
        );

        uint256 betaCount = auctionCount.mod(POOL_AUCTION_COUNT_PADDING).min(9);

        auctionID2BondID[auctionID] = bondID;

        _setAuctionClosingTime(auctionID, isEmergency);

        {
            AuctionConfig memory auctionConfig = _auctionConfigList[auctionID];
            auctionConfig.ongoingAuctionSBTTotalE8 = auctionAmount;
            auctionConfig.lowestBidPriceDeadLineE8 = _auctionBoardContract
                .discretizeBidPrice(
                strikePriceIDOL
                    .mul(10 - betaCount)
                    .divRoundUp(10**(1 + 8))
                    .mul(10**8)
                    .toUint64()
            );
            auctionConfig.highestBidPriceDeadLineE8 = _auctionBoardContract
                .discretizeBidPrice(
                strikePriceIDOL.divRoundUp(10**8).mul(10**8).toUint64()
            );
            _auctionConfigList[auctionID] = auctionConfig;
        }

        emit LogStartAuction(auctionID, bondID, auctionAmount);

        return auctionID;
    }

    /**
     * @notice submit only your own winning bids and get SBT amount which you'll aquire.
     */
    function calcWinnerAmount(
        bytes32 auctionID,
        address sender,
        uint64[] memory winnerBids
    ) public override view returns (uint64) {
        uint256 totalBidAmount;

        (
            uint64 endPrice,
            uint64 endBoardIndex,
            uint64 loseSBTAmount,

        ) = _auctionBoardContract.getEndInfo(auctionID);

        uint64 bidPrice;
        uint64 boardIndex;
        // can calculate winner amount after making the end info.
        {
            (, , bool isEndInfoCreated, , ) = _auctionBoardContract
                .auctionDisposalInfo(auctionID);
            require(isEndInfoCreated, "the end info has not been made yet");
        }

        for (uint256 i = 0; i < winnerBids.length; i += 2) {
            if (i != 0) {
                require(
                    bidPrice > winnerBids[i] ||
                        (bidPrice == winnerBids[i] &&
                            boardIndex < winnerBids[i + 1]),
                    "winner bids are not sorted"
                );
            }
            bidPrice = winnerBids[i];
            boardIndex = winnerBids[i + 1];
            (uint64 bidAmount, address bidder) = _auctionBoardContract
                .auctionBoard(auctionID, bidPrice, boardIndex);
            require(bidder == sender, "this bid is not yours");

            totalBidAmount = totalBidAmount.add(bidAmount);
            if (endPrice == bidPrice) {
                if (boardIndex == endBoardIndex) {
                    // Guarantee loseSBTAmount <= bidAmount in this case.
                    totalBidAmount = totalBidAmount.sub(loseSBTAmount);
                } else {
                    require(
                        boardIndex < endBoardIndex,
                        "this bid does not win"
                    );
                }
            } else {
                require(endPrice < bidPrice, "this bid does not win");
            }
        }

        return totalBidAmount.toUint64();
    }

    /**
     * @notice all loser bids must be reported to this function. These are checked and counted for calculations of bill.
     * @param auctionID aunctionID
     * @param sender owner of the bids
     * @param winnerAmountInput SBT amount to aquire. this is needed because this effect the price of SBT in Vickly Auction's protocol.
     * @param myLowestPrice myLowestPrice is the lowest price of skip bids.
     * @param myLoseBids is the all bids which is after the endInfo
     */
    function calcBillAndCheckLoserBids(
        bytes32 auctionID,
        address sender,
        uint64 winnerAmountInput,
        uint64 myLowestPrice,
        uint64[] memory myLoseBids
    ) public override view returns (uint64) {
        uint256 winnerAmount = winnerAmountInput;
        uint256 toPaySkip = 0;

        if (
            myLowestPrice != NO_SKIP_BID &&
            myLowestPrice != SKIP_RECEIVING_WIN_BIDS
        ) {
            bool myLowestVerify = false;
            for (uint256 i = 0; i < myLoseBids.length; i += 2) {
                uint64 price = myLoseBids[i];
                if (price == myLowestPrice) {
                    myLowestVerify = true;
                    break;
                }
            }

            require(
                myLowestVerify,
                "myLowestPrice must be included in myLoseBids"
            );
        }

        // The amount of sender's lose bids will be skipped. In order to optimize the calculation,
        // components in myLoseBids with a higher price than myLowestPrice are added to winnerAmount and
        // to be subtracted at the end of this function.
        for (uint256 i = 0; i < myLoseBids.length; i += 2) {
            uint64 price = myLoseBids[i];
            uint64 boardIndex = myLoseBids[i + 1];

            if (i != 0) {
                require(
                    price < myLoseBids[i - 2] ||
                        (price == myLoseBids[i - 2] &&
                            boardIndex > myLoseBids[i - 1]),
                    "myLoseBids is not sorted"
                );
            }
            {
                (
                    uint64 endPrice,
                    uint64 endBoardIndex,
                    uint64 loseSBTAmount,

                ) = _auctionBoardContract.getEndInfo(auctionID);

                if (price == endPrice) {
                    if (boardIndex == endBoardIndex) {
                        require(
                            loseSBTAmount != 0,
                            "myLoseBids includes the bid which is same as endInfo with no lose SBT amount"
                        );

                        // This function does not guarantee to return the correct result if an invalid input is given,
                        // because this function can be used just for getting information.
                        // This function is used in the procecss of makeAuctionResult(), and in such a case,
                        // all the verification for bidder==sender and some necessary conditions are processed
                        // in different functions.

                        if (myLowestPrice <= price) {
                            winnerAmount = winnerAmount.add(loseSBTAmount);
                            toPaySkip = toPaySkip.add(
                                price.mul(loseSBTAmount).div(10**8)
                            );
                            continue;
                        }
                    } else {
                        require(
                            boardIndex > endBoardIndex,
                            "myLoseBids includes the bid whose bid index is less than that of endInfo"
                        );
                    }
                } else {
                    require(
                        price < endPrice,
                        "myLoseBids includes the bid whose price is more than that of endInfo"
                    );
                }
            }

            (uint64 bidAmount, address bidder) = _auctionBoardContract
                .auctionBoard(auctionID, price, boardIndex);
            require(
                bidder == sender,
                "myLoseBids includes the bid whose owner is not the sender"
            );

            if (myLowestPrice <= price) {
                winnerAmount = winnerAmount.add(bidAmount);
                toPaySkip = toPaySkip.add(price.mul(bidAmount).div(10**8));
            }
        }

        if (myLowestPrice == SKIP_RECEIVING_WIN_BIDS) {
            // Reduce calculation costs instead by receiving obtained SBT at the highest losing price.
            (uint64 endPrice, , , ) = _auctionBoardContract.getEndInfo(
                auctionID
            );
            //while toPaySkip is expected to be zero in the loop above,
            //only the exception is when the the price acctually hit uint64(-1) at an extremely unexpected case.
            return
                endPrice
                    .mul(winnerAmount)
                    .divRoundUp(10**8)
                    .sub(toPaySkip)
                    .toUint64();
        }

        return
            _auctionBoardContract
                .calcBill(auctionID, winnerAmount.toUint64(), myLowestPrice)
                .sub(toPaySkip)
                .toUint64();
    }

    /**
     * @notice Submit all my win and lose bids, verify them, and transfer the auction reward.
     * @param winnerBids is an array of alternating price and board index.
     * For example, if the end info is { price: 96, boardIndex: 0, loseSBTAmount: 100000000 } and you have 3 bids:
     * { price: 99, boardIndex: 0 }, { price: 97, boardIndex: 2 }, and { price: 96, boardIndex: 1 },
     * you should submit [9900000000, 0, 9700000000, 2] as winnerBids and [9600000000, 1] as loserBids.
     * If the end info is { price: 96, boardIndex: 0, loseSBTAmount: 100000000 } and you have 1 bid:
     * { price: 96, boardIndex: 0 }, you should submit [9600000000, 0] as winnerBids and [9600000000, 0]
     * as loserBids.
     */
    function makeAuctionResult(
        bytes32 auctionID,
        uint64 myLowestPrice,
        uint64[] memory winnerBids,
        uint64[] memory loserBids
    )
        public
        override
        returns (
            uint64,
            uint64,
            uint64
        )
    {
        (
            uint64 auctionLockedIDOLAmountE8,
            uint16 bidCount
        ) = _auctionBoardContract.auctionParticipantInfo(auctionID, msg.sender);

        require(auctionLockedIDOLAmountE8 != 0, "This process is already done");

        {
            (
                uint64 endPrice,
                uint64 endBoardIndex,
                uint64 loseSBTAmount,
                uint64 auctionEndPriceWinnerSBTAmount
            ) = _auctionBoardContract.getEndInfo(auctionID);
            (address endBidder, ) = _auctionBoardContract.getBoard(
                auctionID,
                endPrice,
                endBoardIndex
            );
            // If dupicated bid count is included (loseSBTAmount != 0), bidCount is increased by 1.
            // When both auctionEndPriceWinnerSBTAmount and loseSBTAmount are no-zero value,
            // the end info bid has two components(a winner bid side & a loser bid side).
            // If endInfo bid is frauded in calcBillAndCheckLoserBids L269, revert here. So there needs not check sender==bidder.
            require(
                winnerBids.length.div(2) + loserBids.length.div(2) ==
                    bidCount +
                        (
                            (msg.sender == endBidder &&
                                loseSBTAmount != 0 &&
                                auctionEndPriceWinnerSBTAmount != 0)
                                ? 1
                                : 0
                        ),
                "must submit all of your bids"
            );
        }

        uint64 winnerAmount = calcWinnerAmount(
            auctionID,
            msg.sender,
            winnerBids
        );

        uint64 toPay;
        TimeControlFlag timeFlag = getTimeControlFlag(auctionID);

        if (timeFlag == RECEIVING_SBT_PERIOD_FLAG) {
            toPay = calcBillAndCheckLoserBids(
                auctionID,
                msg.sender,
                winnerAmount,
                myLowestPrice,
                loserBids
            );
        } else {
            require(
                timeFlag > RECEIVING_SBT_PERIOD_FLAG,
                "has not been the receiving period yet"
            );
            toPay = calcBillAndCheckLoserBids(
                auctionID,
                msg.sender,
                winnerAmount,
                SKIP_RECEIVING_WIN_BIDS,
                loserBids
            );
        }

        // IDOLAmountOfChange = max(auctionLockedIDOLAmountE8 - toPay, 0)
        if (toPay > auctionLockedIDOLAmountE8) {
            // assertion to prevent from the worst case that accumulate to certain amount by rounding up of toPay.
            require(
                toPay.sub(auctionLockedIDOLAmountE8) < 10**8,
                "system error: does not ignore too big error for spam protection"
            );
            toPay = auctionLockedIDOLAmountE8;
        }
        uint64 IDOLAmountOfChange = auctionLockedIDOLAmountE8 - toPay;

        _auctionBoardContract.deleteParticipantInfo(auctionID, msg.sender);
        _transferIDOL(msg.sender, IDOLAmountOfChange);

        _auctionBoardContract.updateAuctionInfo(
            auctionID,
            0,
            toPay,
            winnerAmount
        );
        _distributeToWinners(auctionID, winnerAmount);

        emit LogAuctionResult(
            auctionID,
            msg.sender,
            winnerAmount,
            toPay,
            IDOLAmountOfChange
        );

        return (winnerAmount, toPay, IDOLAmountOfChange);
    }

    /**
     * @notice Close the auction when it is done. If some part of SBTs remain unsold, the auction is held again.
     */
    function closeAuction(bytes32 auctionID)
        public
        override
        returns (bool, bytes32)
    {
        (uint64 auctionSettledTotalE8, , ) = _auctionBoardContract.auctionInfo(
            auctionID
        );
        require(
            isInPeriod(auctionID, AFTER_AUCTION_FLAG),
            "This function is not allowed to execute in this period"
        );

        uint64 ongoingAuctionSBTTotal = _auctionConfigList[auctionID]
            .ongoingAuctionSBTTotalE8;
        require(ongoingAuctionSBTTotal != 0, "already closed");
        bytes32 bondID = auctionID2BondID[auctionID];

        {
            (, , bool isEndInfoCreated, , ) = _auctionBoardContract
                .auctionDisposalInfo(auctionID);
            require(isEndInfoCreated, "has not set end info");
        }

        _forceToFinalizeWinnerAmount(auctionID);

        uint256 nextAuctionAmount = ongoingAuctionSBTTotal.sub(
            auctionSettledTotalE8,
            "allocated SBT amount for auction never becomes lower than reward total"
        );

        bool isLast = nextAuctionAmount == 0;
        _publishSettledAverageAuctionPrice(auctionID, isLast);

        bytes32 nextAuctionID = bytes32(0);
        if (isLast) {
            // closeAuction adds 10**8 to _bondIDAuctionCount[bondID] and resets beta count
            // when all SBT of the auction is sold out.
            _bondIDAuctionCount[bondID] = _bondIDAuctionCount[bondID]
                .div(POOL_AUCTION_COUNT_PADDING)
                .add(1)
                .mul(POOL_AUCTION_COUNT_PADDING);
        } else {
            // When the SBT is not sold out in the auction, restart a new one until all the SBT is successfully sold.
            nextAuctionID = _startAuction(
                bondID,
                nextAuctionAmount.toUint64(),
                true
            );
        }
        delete _auctionConfigList[auctionID].ongoingAuctionSBTTotalE8;

        emit LogCloseAuction(auctionID, isLast, nextAuctionID);

        return (isLast, nextAuctionID);
    }

    /**
     * @notice This function returns SBT amount and iDOL amount (as its change) settled for those who didn't reveal bids.
     */
    function _calcUnrevealedBidDistribution(
        uint64 ongoingAmount,
        uint64 totalIDOLAmountUnrevealed,
        uint64 totalSBTAmountPaidForUnrevealed,
        uint64 solidStrikePriceIDOL,
        uint64 IDOLAmountDeposited
    )
        internal
        pure
        returns (uint64 receivingSBTAmount, uint64 returnedIDOLAmount)
    {
        // (total target) - (total revealed) = (total unrevealed)
        uint64 totalSBTAmountUnrevealed = totalIDOLAmountUnrevealed
            .mul(10**8)
            .div(solidStrikePriceIDOL, "system error: Oracle has a problem")
            .toUint64();

        // min((total unrevealed), ongoing) - (total paid already) = (total deposit for punishment)
        uint64 totalLeftSBTAmountForUnrevealed = uint256(
            totalSBTAmountUnrevealed
        )
            .min(ongoingAmount)
            .sub(totalSBTAmountPaidForUnrevealed)
            .toUint64();

        // (receiving SBT amount) = min((bid amount), (total deposited))
        uint256 expectedReceivingSBTAmount = IDOLAmountDeposited.mul(10**8).div(
            solidStrikePriceIDOL,
            "system error: Oracle has a problem"
        );

        // (returned iDOL amount) = (deposit amount) - (iDOL value of receiving SBT amount)
        if (expectedReceivingSBTAmount <= totalLeftSBTAmountForUnrevealed) {
            receivingSBTAmount = expectedReceivingSBTAmount.toUint64();
            returnedIDOLAmount = 0;
        } else if (totalLeftSBTAmountForUnrevealed == 0) {
            receivingSBTAmount = 0;
            returnedIDOLAmount = IDOLAmountDeposited;
        } else {
            receivingSBTAmount = totalLeftSBTAmountForUnrevealed;
            returnedIDOLAmount = IDOLAmountDeposited
                .sub(
                totalLeftSBTAmountForUnrevealed
                    .mul(solidStrikePriceIDOL)
                    .divRoundUp(10**8)
            )
                .toUint64();
        }

        return (receivingSBTAmount, returnedIDOLAmount);
    }

    /**
     * @notice Transfer SBT for those who forget to reveal.
     */
    function receiveUnrevealedBidDistribution(bytes32 auctionID, bytes32 secret)
        public
        override
        returns (bool)
    {
        (
            uint64 solidStrikePriceIDOL,
            ,
            bool isEndInfoCreated,
            ,

        ) = _auctionBoardContract.auctionDisposalInfo(auctionID);
        require(
            isEndInfoCreated,
            "EndInfo hasn't been made. This Function has not been allowed yet."
        );

        (address secOwner, , uint64 IDOLAmountDeposited) = _auctionBoardContract
            .auctionSecret(auctionID, secret);
        require(secOwner == msg.sender, "ownership of the bid is required");

        (
            ,
            uint64 totalIDOLSecret,
            uint64 totalIDOLAmountRevealed,

        ) = _auctionBoardContract.auctionRevealInfo(auctionID);
        uint64 totalIDOLAmountUnrevealed = totalIDOLSecret
            .sub(totalIDOLAmountRevealed)
            .toUint64();

        uint64 receivingSBTAmount;
        uint64 returnedIDOLAmount;
        uint64 totalSBTAmountPaidForUnrevealed;
        {
            AuctionConfig memory auctionConfig = _auctionConfigList[auctionID];
            totalSBTAmountPaidForUnrevealed = auctionConfig
                .totalSBTAmountPaidForUnrevealedE8;

            (
                receivingSBTAmount,
                returnedIDOLAmount
            ) = _calcUnrevealedBidDistribution(
                auctionConfig.ongoingAuctionSBTTotalE8,
                totalIDOLAmountUnrevealed,
                totalSBTAmountPaidForUnrevealed,
                solidStrikePriceIDOL,
                IDOLAmountDeposited
            );
        }

        _auctionConfigList[auctionID]
            .totalSBTAmountPaidForUnrevealedE8 = totalSBTAmountPaidForUnrevealed
            .add(receivingSBTAmount)
            .toUint64();
        _auctionBoardContract.removeSecret(auctionID, secret, 0);

        // Transfer the winning SBT and (if necessary) return the rest of deposited iDOL.
        _distributeToWinners(auctionID, receivingSBTAmount);
        _IDOLContract.transfer(secOwner, returnedIDOLAmount);

        return true;
    }

    /**
     * @notice Cancel the bid of your own within the bid acceptance period.
     */
    function cancelBid(bytes32 auctionID, bytes32 secret)
        public
        override
        returns (uint64)
    {
        require(
            isInPeriod(auctionID, ACCEPTING_BIDS_PERIOD_FLAG),
            "it is not the time to accept bids"
        );
        (address owner, , uint64 IDOLamount) = _auctionBoardContract
            .auctionSecret(auctionID, secret);
        require(owner == msg.sender, "you are not the bidder for the secret");
        _auctionBoardContract.removeSecret(auctionID, secret, IDOLamount);
        _transferIDOL(
            owner,
            IDOLamount,
            "system error: try to cancel bid, but cannot return iDOL"
        );

        emit LogCancelBid(auctionID, owner, secret, IDOLamount);

        return IDOLamount;
    }

    /**
     * @notice Returns the current auction ID.
     */
    function getCurrentAuctionID(bytes32 bondID)
        public
        override
        view
        returns (bytes32)
    {
        uint256 count = _bondIDAuctionCount[bondID];
        return generateAuctionID(bondID, count);
    }

    /**
     * @notice Generates auction ID from bond ID and the count of auctions for the bond.
     */
    function generateAuctionID(bytes32 bondID, uint256 count)
        public
        override
        pure
        returns (bytes32)
    {
        return keccak256(abi.encode(bondID, count));
    }

    /**
     * @dev The bidder succeeds in winning the SBT for the auctionID with receivingBondAmount, and pays IDOL with billingIDOLAmount.
     */
    function _distributeToWinners(bytes32 auctionID, uint64 receivingBondAmount)
        internal
        returns (uint64)
    {
        // Get the address of SBT contract.
        (address solidBondAddress, , , ) = _getBondFromAuctionID(auctionID);
        require(solidBondAddress != address(0), "the bond is not registered");

        // Transfer the winning SBT.
        BondTokenInterface solidBondContract = BondTokenInterface(
            payable(solidBondAddress)
        );
        solidBondContract.transfer(msg.sender, receivingBondAmount);
    }

    /**
     * @dev When isLast is true, the SBTs put up in the auction are sold entirely.
     * The average auction price is used for deciding the amount of IDOL to return from the lock pool.
     */
    function _publishSettledAverageAuctionPrice(bytes32 auctionID, bool isLast)
        internal
    {
        bytes32 bondID = auctionID2BondID[auctionID];
        (
            ,
            uint64 auctionRewardedTotalE8,
            uint64 auctionPaidTotalE8
        ) = _auctionBoardContract.auctionInfo(auctionID);

        // The auction contract actually do not burn iDOL. Paid iDOL will be transferred and burned in the stable coin contract.
        _transferIDOL(
            address(_IDOLContract),
            auctionPaidTotalE8,
            "system error: cannot transfer iDOL from auction contract to iDOL contract"
        );

        _IDOLContract.setSettledAverageAuctionPrice(
            bondID,
            auctionPaidTotalE8,
            auctionRewardedTotalE8,
            isLast
        );
    }

    /**
     * @dev How much IDOL to burn is decided by the settlement price.
     * Hence, this contract needs to decide the price within some specified period.
     */
    function _forceToFinalizeWinnerAmount(bytes32 auctionID) internal {
        (
            uint64 auctionSettledTotalE8,
            uint64 auctionRewardedTotalE8,

        ) = _auctionBoardContract.auctionInfo(auctionID);

        if (_auctionBoardContract.getSortedBidPrice(auctionID).length == 0) {
            return;
        }

        (uint256 burnIDOLRate, , , ) = _auctionBoardContract.getEndInfo(
            auctionID
        );

        uint256 _totalSBTForRestWinners = auctionSettledTotalE8.sub(
            auctionRewardedTotalE8,
            "system error: allocated SBT amount for auction never becomes lower than reward total at any point"
        );

        uint256 burnIDOL = _totalSBTForRestWinners.mul(burnIDOLRate).div(10**8);

        _auctionBoardContract.updateAuctionInfo(
            auctionID,
            _totalSBTForRestWinners.toUint64(),
            burnIDOL.toUint64(),
            _totalSBTForRestWinners.toUint64()
        );
    }

    /**
     * @notice Returns the bond information corresponding to the auction ID.
     */
    function _getBondFromAuctionID(bytes32 auctionID)
        internal
        view
        returns (
            address erc20Address,
            uint256 maturity,
            uint64 solidStrikePrice,
            bytes32 fnMapID
        )
    {
        bytes32 bondID = auctionID2BondID[auctionID];
        return _bondMakerContract.getBond(bondID);
    }

    /**
     * @notice Returns the bond IDs corresponding to the auction IDs respectively.
     */
    function listBondIDFromAuctionID(bytes32[] memory auctionIDs)
        public
        override
        view
        returns (bytes32[] memory bondIDs)
    {
        bondIDs = new bytes32[](auctionIDs.length);
        for (uint256 i = 0; i < auctionIDs.length; i++) {
            bondIDs[i] = auctionID2BondID[auctionIDs[i]];
        }
    }

    /**
     * @notice Returns the auction status.
     * @param auctionID is a auction ID.
     * @return closingTime is .
     * @return auctionAmount is the SBT amount put up in the auction.
     * @return rewardedAmount is .
     * @return totalSBTAmountBid is .
     * @return isEmergency is .
     * @return doneFinalizeWinnerAmount is .
     * @return doneSortPrice is .
     * @return lowestBidPriceDeadLine is the minimum bid price in the auction.
     * @return highestBidPriceDeadLine is the maximum bid price in the auction.
     * @return totalSBTAmountPaidForUnrevealed is the SBT Amount allocated for those who had not revealed their own bid.
     */
    function getAuctionStatus(bytes32 auctionID)
        public
        override
        view
        returns (
            uint256 closingTime,
            uint64 auctionAmount,
            uint64 rewardedAmount,
            uint64 totalSBTAmountBid,
            bool isEmergency,
            bool doneFinalizeWinnerAmount,
            bool doneSortPrice,
            uint64 lowestBidPriceDeadLine,
            uint64 highestBidPriceDeadLine,
            uint64 totalSBTAmountPaidForUnrevealed
        )
    {
        closingTime = auctionClosingTime[auctionID].toUint64();
        AuctionConfig memory auctionConfig = _auctionConfigList[auctionID];
        auctionAmount = auctionConfig.ongoingAuctionSBTTotalE8;
        lowestBidPriceDeadLine = auctionConfig.lowestBidPriceDeadLineE8;
        highestBidPriceDeadLine = auctionConfig.highestBidPriceDeadLineE8;
        totalSBTAmountPaidForUnrevealed = auctionConfig
            .totalSBTAmountPaidForUnrevealedE8;
        (, rewardedAmount, ) = _auctionBoardContract.auctionInfo(auctionID);
        (totalSBTAmountBid, , , ) = _auctionBoardContract.auctionRevealInfo(
            auctionID
        );
        isEmergency = isAuctionEmergency[auctionID];
        (, , , doneFinalizeWinnerAmount, doneSortPrice) = _auctionBoardContract
            .auctionDisposalInfo(auctionID);
    }

    /**
     * @notice Returns the status of auctions which is held in the week.
     * @param weekNumber is the quotient obtained by dividing the timestamp by 7 * 24 * 60 * 60 (= 7 days).
     */
    function getWeeklyAuctionStatus(uint256 weekNumber)
        external
        override
        view
        returns (uint256[] memory weeklyAuctionStatus)
    {
        bytes32[] memory auctions = listAuction(weekNumber);
        weeklyAuctionStatus = new uint256[](auctions.length.mul(6));
        for (uint256 i = 0; i < auctions.length; i++) {
            (
                uint256 closingTime,
                uint64 auctionAmount,
                uint64 rewardedAmount,
                uint64 totalSBTAmountBid,
                bool isEmergency,
                bool doneFinalizeWinnerAmount,
                bool doneSortPrice,
                ,
                ,

            ) = getAuctionStatus(auctions[i]);
            uint8 auctionStatusCode = (isEmergency ? 1 : 0) << 2;
            auctionStatusCode += (doneFinalizeWinnerAmount ? 1 : 0) << 1;
            auctionStatusCode += doneSortPrice ? 1 : 0;
            weeklyAuctionStatus[i * 6] = closingTime;
            weeklyAuctionStatus[i * 6 + 1] = auctionAmount;
            weeklyAuctionStatus[i * 6 + 2] = rewardedAmount;
            weeklyAuctionStatus[i * 6 + 3] = totalSBTAmountBid;
            weeklyAuctionStatus[i * 6 + 4] = auctionStatusCode;
            weeklyAuctionStatus[i * 6 + 5] = uint256(auctions[i]);
        }
    }

    /**
     * @notice Returns total SBT amount put up in the auction.
     */
    function ongoingAuctionSBTTotal(bytes32 auctionID)
        external
        override
        view
        returns (uint64 ongoingSBTAmountE8)
    {
        AuctionConfig memory auctionConfig = _auctionConfigList[auctionID];
        return auctionConfig.ongoingAuctionSBTTotalE8;
    }

    function getAuctionCount(bytes32 bondID)
        external
        override
        view
        returns (uint256 auctionCount)
    {
        return _bondIDAuctionCount[bondID];
    }
}

// File: contracts/util/DeployerRole.sol




abstract contract DeployerRole {
    address internal immutable _deployer;

    modifier onlyDeployer() {
        require(
            _isDeployer(msg.sender),
            "only deployer is allowed to call this function"
        );
        _;
    }

    constructor() public {
        _deployer = msg.sender;
    }

    function _isDeployer(address account) internal view returns (bool) {
        return account == _deployer;
    }
}

// File: contracts/UseAuctionLater.sol






abstract contract UseAuctionLater is DeployerRole {
    Auction internal _auctionContract;

    modifier isNotEmptyAuctionInstance() {
        require(
            address(_auctionContract) != address(0),
            "the auction contract is not set"
        );
        _;
    }

    /**
     * @dev This function is called only once when the code is initially deployed.
     */
    function setAuctionContract(address contractAddress) public onlyDeployer {
        require(
            address(_auctionContract) == address(0),
            "the auction contract is already registered"
        );
        require(
            contractAddress != address(0),
            "contract should be non-zero address"
        );
        _setAuctionContract(contractAddress);
    }

    function _setAuctionContract(address contractAddress) internal {
        _auctionContract = Auction(payable(contractAddress));
    }
}

// File: contracts/StableCoin.sol














contract StableCoin is
    UseSafeMath,
    StableCoinInterface,
    Time,
    ERC20("iDOL", "iDOL"),
    SolidBondSafety,
    UseOracle,
    UseBondMaker,
    UseAuctionLater
{
    using Math for uint256;

    /**
     * @dev pool:mint = 1:9
     */
    uint256 internal constant LOCK_POOL_BORDER = 1;
    uint256 internal constant MINT_IDOL_BORDER = 10 - LOCK_POOL_BORDER;
    uint256 internal immutable AUCTION_SPAN;
    uint256 internal immutable EMERGENCY_AUCTION_SPAN;
    uint256 internal immutable MINT_IDOL_AMOUNT_BORDER;

    /**
     * @dev The contents of this internal storage variable can be seen by solidValueTotal function.
     */
    uint256 internal _solidValueTotalE12;

    mapping(bytes32 => uint64) public auctionTriggerCount;

    /**
     * @dev Record the pooled IDOL for each person(= beta * minted amount).
     * The pooled IDOL is going to be refunded partially to the person when the deposited SBT is
     * sold in the auction.
     */
    struct LockedPool {
        uint64 IDOLAmount;
        uint64 baseSBTAmount;
    }
    mapping(address => mapping(bytes32 => LockedPool)) public lockedPoolE8;

    /**
     * @dev The contents in this internal storage variable can be seen by getPoolInfo function.
     * @param lockedSolidBondTotalE8 is the current locked SBT amount.
     * @param unlockedSolidBondTotalE8 is the SBT amount unlocked by unlockSBT().
     * @param lockedPoolIDOLTotalE8 is the iDOL amount locked to the pool for the SBT.
     * @param SBT2BurnedIDOLTotalE8 is the iDOL amount burned by unlockSBT() or setSettledAverageAuctionPrice().
     */
    struct AccountingTotalInfo {
        uint64 lockedSolidBondTotalE8;
        uint64 unlockedSolidBondTotalE8;
        uint64 lockedPoolIDOLTotalE8;
        uint64 SBT2BurnedIDOLTotalE8;
    }
    mapping(bytes32 => AccountingTotalInfo) internal _accountingTotalInfo;

    /**
     * @notice Record the average settlement price for each SBT bondID.
     * @dev The average settlement price is used for calculating the amount to return partially from
     * the pooled IDOL.
     * The contents in this internal storage variable can be seen by getPoolInfo function.
     * @param auctionSoldSolidBondTotal is the SBT total amount already sold in the auction.
     * @param auctionPaidIDOLTotalE8 is the iDOL amount already paid for the SBT in the auction.
     * @param settledAverageAuctionPrice is the average price for the SBT in the auction and unlockSBT().
     * @param isAllAmountSoldInAuction indicates whether auctionSoldSolidBondTotal equals to the auction amount or not.
     */
    struct AuctionAmountInfo {
        uint64 auctionSoldSolidBondTotal;
        uint64 auctionPaidIDOLTotalE8;
        uint64 settledAverageAuctionPrice;
        bool isAllAmountSoldInAuction;
    }
    mapping(bytes32 => AuctionAmountInfo) internal _auctionAmountInfo;

    constructor(
        address oracleAddress,
        address bondMakerAddress,
        uint256 auctionSpan,
        uint256 emergencyAuctionSpan,
        uint256 mintIDOLAmountBorder
    ) public UseOracle(oracleAddress) UseBondMaker(bondMakerAddress) {
        _setupDecimals(8);
        AUCTION_SPAN = auctionSpan;
        EMERGENCY_AUCTION_SPAN = emergencyAuctionSpan;
        MINT_IDOL_AMOUNT_BORDER = mintIDOLAmountBorder;
    }

    function _reduceSBTValue(uint256 SBTValueE12) internal {
        _solidValueTotalE12 = _solidValueTotalE12.sub(SBTValueE12);
    }

    /**
     * @notice In order to calculate the amount to burn from the pooled IDOL, need to aggregate
     * IDOLs both in the auction and in the unlockSBT function. Calculate settled-average-auction-
     * price (every time an auction ends, the auction contract trigger this)
     * @param bondID ID for auctioned SBT
     * @param auctionPaidIDOL IDOL amount burned in this auction
     * @param auctionSoldAmount SBT amount sold in this auction
     * @param isLastTime True when the auction successfully sold all the SBT
     */
    function _setSettledAverageAuctionPrice(
        bytes32 bondID,
        uint64 auctionPaidIDOL,
        uint64 auctionSoldAmount,
        bool isLastTime
    ) internal {
        bytes32 poolID = getCurrentPoolID(bondID);
        AuctionAmountInfo memory auctionInfo = _auctionAmountInfo[poolID];

        auctionInfo.auctionSoldSolidBondTotal = auctionInfo
            .auctionSoldSolidBondTotal
            .add(auctionSoldAmount)
            .toUint64();
        auctionInfo.auctionPaidIDOLTotalE8 = auctionInfo
            .auctionPaidIDOLTotalE8
            .add(auctionPaidIDOL)
            .toUint64();

        if (isLastTime) {
            // Calculate the amount of IDOL to burn

                AccountingTotalInfo memory accountingInfo
             = _accountingTotalInfo[poolID];
            uint256 burnIDOLAmount = 0;

            /**
             * @dev In the case of beta=0.1, total distributed IDOL for the bondID
             * can be calculated by the pooled IDOL amount for the bondID multiplied by 9
             * (= MINT_IDOL_BORDER).
             * In the case that someone has withdrawn SBT by unlockSBT(), the pooled IDOL is also
             * circulated.
             * When 3 SBT (strike = $100) are withdrawn by unlockSBT() and 8 SBT are sold in the
             * auction, circulated = (3+8)*100*0.9 and everminted = (3+8)*100.
             * Those 3 and 8 can be captured by looking at the amount of IDOL in the pool.
             */
            {
                // (circulated amount) = (locked pool iDOL total) * MINT_IDOL_BORDER / LOCK_POOL_BORDER
                //                     = (locked pool iDOL total) * MINT_IDOL_BORDER
                uint256 circulated = accountingInfo.lockedPoolIDOLTotalE8.mul(
                    MINT_IDOL_BORDER
                );
                uint256 everMinted = accountingInfo.lockedPoolIDOLTotalE8.add(
                    circulated
                );
                uint256 allBurn = accountingInfo.SBT2BurnedIDOLTotalE8.add(
                    auctionInfo.auctionPaidIDOLTotalE8
                );
                if (allBurn > circulated) {
                    if (everMinted >= allBurn) {
                        // burn all the IDOL issued for the SBT put up in the auction
                        //SAME MEANING of: burnIDOLAmount = everMinted.sub(allBurn).add(auctionPaidIDOLTotalE8[bondID]);
                        burnIDOLAmount = everMinted.sub(
                            accountingInfo.SBT2BurnedIDOLTotalE8
                        );
                    } else {
                        // burn all the IDOL issued for the SBT put up in the auction, and excess amount.
                        //SAME MEANING of: burnIDOLAmount = allBurn.sub(allBurn).add(auctionPaidIDOLTotalE8[bondID]);
                        burnIDOLAmount = allBurn.sub(
                            accountingInfo.SBT2BurnedIDOLTotalE8
                        );
                    }
                } else {
                    // burn as much as we can.
                    //In this case, burn rate(price) is lower than 1-beta
                    burnIDOLAmount = accountingInfo.lockedPoolIDOLTotalE8.add(
                        auctionInfo.auctionPaidIDOLTotalE8
                    );
                }
            }

            (, , uint64 solidBondStrikePriceUSD, ) = _bondMakerContract.getBond(
                bondID
            );

            _burn(address(this), burnIDOLAmount);
            accountingInfo.SBT2BurnedIDOLTotalE8 = accountingInfo
                .SBT2BurnedIDOLTotalE8
                .add(auctionInfo.auctionPaidIDOLTotalE8)
                .toUint64();

            _reduceSBTValue(
                auctionInfo.auctionSoldSolidBondTotal.mul(
                    solidBondStrikePriceUSD
                )
            );
            accountingInfo.unlockedSolidBondTotalE8 = accountingInfo
                .unlockedSolidBondTotalE8
                .add(auctionInfo.auctionSoldSolidBondTotal)
                .toUint64();

            auctionInfo.settledAverageAuctionPrice = accountingInfo
                .SBT2BurnedIDOLTotalE8
                .mul(10**8)
                .div(
                accountingInfo
                    .unlockedSolidBondTotalE8,
                "system: the total unlock amount should be non-zero value"
            )
                .toUint64();

            auctionInfo.isAllAmountSoldInAuction = true;
            auctionTriggerCount[bondID] = auctionTriggerCount[bondID]
                .add(1)
                .toUint64();

            _accountingTotalInfo[poolID] = accountingInfo;

            uint256 totalIDOLSupply = totalSupply();
            emit LogLambda(
                poolID,
                auctionInfo.settledAverageAuctionPrice,
                totalIDOLSupply,
                _solidValueTotalE12
            );
        }
        _auctionAmountInfo[poolID] = auctionInfo;
    }

    /**
     * @param poolID is a pool ID.
     * @return lockedSBTTotal is the current locked SBT amount. (e8)
     * @return unlockedSBTTotal is the SBT amount unlocked with unlockSBT(). (e8)
     * @return lockedPoolIDOLTotal is the iDOL amount locked to the pool when this was minted. (e8)
     * @return burnedIDOLTotal is the iDOL amount burned with unlockSBT() and setSettledAverageAuctionPrice(). (e8)
     * @return soldSBTTotalInAuction is the SBT total amount already sold in the auction. (e8)
     * @return paidIDOLTotalInAuction is the iDOL amount already paid for SBT in the auction. (e8)
     * @return settledAverageAuctionPrice is the average price with iDOL of the SBT in the auction and unlockSBT(). (e8)
     * @return isAllAmountSoldInAuction is whether auctionSoldSolidBondTotal is equal to the auction amount or not.
     */
    function getPoolInfo(bytes32 poolID)
        external
        override
        view
        returns (
            uint64 lockedSBTTotal,
            uint64 unlockedSBTTotal,
            uint64 lockedPoolIDOLTotal,
            uint64 burnedIDOLTotal,
            uint64 soldSBTTotalInAuction,
            uint64 paidIDOLTotalInAuction,
            uint64 settledAverageAuctionPrice,
            bool isAllAmountSoldInAuction
        )
    {

            AccountingTotalInfo memory accountingInfo
         = _accountingTotalInfo[poolID];
        lockedSBTTotal = accountingInfo.lockedSolidBondTotalE8;
        unlockedSBTTotal = accountingInfo.unlockedSolidBondTotalE8;
        lockedPoolIDOLTotal = accountingInfo.lockedPoolIDOLTotalE8;
        burnedIDOLTotal = accountingInfo.SBT2BurnedIDOLTotalE8;


            AuctionAmountInfo memory auctionSettlementInfo
         = _auctionAmountInfo[poolID];
        soldSBTTotalInAuction = auctionSettlementInfo.auctionSoldSolidBondTotal;
        paidIDOLTotalInAuction = auctionSettlementInfo.auctionPaidIDOLTotalE8;
        settledAverageAuctionPrice = auctionSettlementInfo
            .settledAverageAuctionPrice;
        isAllAmountSoldInAuction = auctionSettlementInfo
            .isAllAmountSoldInAuction;
    }

    function solidValueTotal() external override view returns (uint256) {
        return _solidValueTotalE12;
    }

    function generatePoolID(bytes32 bondID, uint64 count)
        public
        override
        pure
        returns (bytes32)
    {
        return keccak256(abi.encodePacked(bondID, count, "lien"));
    }

    function getCurrentPoolID(bytes32 bondID)
        public
        override
        view
        returns (bytes32)
    {
        uint64 currentTriggeredCount = auctionTriggerCount[bondID];
        return generatePoolID(bondID, currentTriggeredCount);
    }

    function getLockedPool(address user, bytes32 poolID)
        public
        override
        view
        returns (uint64, uint64)
    {
        return (
            lockedPoolE8[user][poolID].IDOLAmount,
            lockedPoolE8[user][poolID].baseSBTAmount
        );
    }

    /**
     * @dev poolID is counted up and used when the SBT once released from IDOL in the emergency
     * auction becomes qualified again before its maturity.
     */

    /**
     * @dev Check if the SBT is qualified in terms of the length of the time until maturity,
     * the volatility, and the distance between the current price and the strike price.
     */
    function isAcceptableSBT(bytes32 bondID)
        public
        virtual
        override
        isNotEmptyAuctionInstance
        returns (bool)
    {
        (
            address bondTokenAddress,
            uint256 maturity,
            uint64 solidStrikePriceE4,

        ) = _bondMakerContract.getBond(bondID);
        require(bondTokenAddress != address(0), "the bond is not registered");
        require(
            solidStrikePriceE4 != 0,
            "the bond does not match to the form of SBT"
        );
        require(
            maturity > _getBlockTimestampSec() + AUCTION_SPAN,
            "a request to hold an auction of the bond has already expired"
        );
        require(
            solidStrikePriceE4 % (10**5) == 0,
            "the strike price need to be $ 10*X"
        );

        bytes32 auctionID = _auctionContract.getCurrentAuctionID(bondID);
        require(
            _auctionContract.ongoingAuctionSBTTotal(auctionID) == 0,
            "this SBT is on a auciton"
        );

        (uint256 rateETH2USDE8, uint256 volatilityE8) = _getOracleData();
        bool isDanger = isDangerSolidBond(
            rateETH2USDE8,
            solidStrikePriceE4,
            volatilityE8,
            maturity - _getBlockTimestampSec()
        );

        emit LogIsAcceptableSBT(bondID, !isDanger);

        return !isDanger;
    }

    /**
     * @notice Lock SBT and mint IDOL
     * @param bondID the ID for the SBT locked for minting IDOL
     * @param lockAmountE8 the amount of locked SBT
     */
    function mint(
        bytes32 bondID,
        address recipient,
        uint64 lockAmountE8
    )
        public
        override
        returns (
            bytes32 poolID,
            uint64 obtainIDOLAmountE8,
            uint64 poolIDOLAmountE8
        )
    {
        poolID = getCurrentPoolID(bondID);

        // Check if the maturity is sufficiently distant from the current time.
        (
            address bondTokenAddress,
            ,
            uint256 solidStrikePriceE4,

        ) = _bondMakerContract.getBond(bondID);
        require(
            isAcceptableSBT(bondID),
            "SBT with the bondID is not currently acceptable"
        );


            AccountingTotalInfo memory accountingInfo
         = _accountingTotalInfo[poolID];

        // Calculate the mint amount based on the dilution ratio.
        uint256 solidBondValueE12 = lockAmountE8.mul(solidStrikePriceE4);
        uint256 mintAmountE8 = calcSBT2IDOL(solidBondValueE12);
        require(
            accountingInfo.lockedPoolIDOLTotalE8 != 0 ||
                mintAmountE8 >= MINT_IDOL_AMOUNT_BORDER,
            "mint amount need to be greater than 500 idol for this bond"
        );

        ERC20 bondTokenContract = ERC20(bondTokenAddress);
        bondTokenContract.transferFrom(msg.sender, address(this), lockAmountE8);

        // (pooling amount) = mintAmountE8 * LOCK_POOL_BORDER / 10 = mintAmountE8 / 10
        uint256 poolAmount = mintAmountE8.div(10);
        LockedPool storage lockedPoolInfo = lockedPoolE8[recipient][poolID];
        lockedPoolInfo.IDOLAmount = lockedPoolInfo
            .IDOLAmount
            .add(poolAmount)
            .toUint64();
        lockedPoolInfo.baseSBTAmount = lockedPoolInfo
            .baseSBTAmount
            .add(lockAmountE8)
            .toUint64();

        _mint(recipient, mintAmountE8.sub(poolAmount));
        _mint(address(this), poolAmount);
        _solidValueTotalE12 = _solidValueTotalE12.add(solidBondValueE12);
        accountingInfo.lockedSolidBondTotalE8 = accountingInfo
            .lockedSolidBondTotalE8
            .add(lockAmountE8)
            .toUint64();
        accountingInfo.lockedPoolIDOLTotalE8 = accountingInfo
            .lockedPoolIDOLTotalE8
            .add(poolAmount)
            .toUint64();
        _accountingTotalInfo[poolID] = accountingInfo;

        uint256 obtainAmount = mintAmountE8.sub(poolAmount);
        emit LogMintIDOL(bondID, recipient, poolID, obtainAmount, poolAmount);
        return (poolID, obtainAmount.toUint64(), poolAmount.toUint64());
    }

    /**
     * @dev Only the auction contract address can burn some specified amount of the IDOL held by
     * an account.
     */
    function burnFrom(address account, uint256 amount)
        public
        override
        isNotEmptyAuctionInstance
    {
        require(
            msg.sender == address(_auctionContract),
            "msg.sender must be auction contract"
        );
        _burn(account, amount);
    }

    /**
     * @notice This function provides the opportunity to redeem any type of SBT with a correct
     * amount by burning iDOL. iDOL is pegged to totalLockedValue/totalSupply dollar
     * (initially 1 dollar), so we can always allow anyone to redeem at most 1 dollar worth SBT
     * by burning 1 dollar worth iDOL.
     * This is based on the mathematical fact that the theoretical value of 1 unit SBT with
     * strike price 100 dollar is always strictly less than 100 dollar (e.g. 99.99 dollar).
     * @dev IDOL contract needs to know the value of iDOL per unit by calculating
     * totalLockedValue/totalSupply the value of iDOL per unit may change when the auction
     * settlement price is not within the certain price range.
     * rewardSBT = burnAmountE8/solidStrikePriceE4 * totalSupply/totalLockedValue
     * @param bondID is the bond to unlock
     * @param burnAmountE8 is the iDOL amount to burn
     */
    function unlockSBT(bytes32 bondID, uint64 burnAmountE8)
        public
        override
        returns (uint64)
    {
        bytes32 poolID = getCurrentPoolID(bondID);
        (
            address bondTokenAddress,
            ,
            uint256 solidStrikePriceE4,

        ) = _bondMakerContract.getBond(bondID);
        require(bondTokenAddress != address(0), "the bond is not registered");
        require(solidStrikePriceE4 != 0, "the bond is not the form of SBT");

            AccountingTotalInfo memory accountingInfo
         = _accountingTotalInfo[poolID];

        uint64 rewardSBTE8 = burnAmountE8
            .mul(_solidValueTotalE12)
            .div(totalSupply(), "system error: totalSupply never becomes zero")
            .div(
            solidStrikePriceE4,
            "system error: solidStrikePrice never becomes zero [unlockSBT]"
        )
            .toUint64();

        // Burn iDOL.
        accountingInfo.SBT2BurnedIDOLTotalE8 = accountingInfo
            .SBT2BurnedIDOLTotalE8
            .add(burnAmountE8)
            .toUint64();

        _burn(msg.sender, burnAmountE8);

        // Return SBT.
        BondTokenInterface bondTokenContract = BondTokenInterface(
            payable(bondTokenAddress)
        );
        bondTokenContract.transfer(msg.sender, rewardSBTE8);

        emit LogBurnIDOL(bondID, msg.sender, burnAmountE8, rewardSBTE8);

        // Update solidValueTotal, lockedSolidBondTotalE18 and unlockedSolidBondTotal.
        _solidValueTotalE12 = _solidValueTotalE12.sub(
            rewardSBTE8.mul(solidStrikePriceE4)
        );
        accountingInfo.lockedSolidBondTotalE8 = accountingInfo
            .lockedSolidBondTotalE8
            .sub(rewardSBTE8)
            .toUint64();
        accountingInfo.unlockedSolidBondTotalE8 = accountingInfo
            .unlockedSolidBondTotalE8
            .add(rewardSBTE8)
            .toUint64();

        _accountingTotalInfo[poolID] = accountingInfo;

        return rewardSBTE8;
    }

    /**
     * @notice Starts regular auction for SBT with short maturity.
     */
    function startAuctionOnMaturity(bytes32 bondID)
        public
        override
        isNotEmptyAuctionInstance
    {
        bytes32 poolID = getCurrentPoolID(bondID);
        (
            address bondTokenAddress,
            uint256 maturity,
            uint64 solidBondStrikePriceUSD,

        ) = _bondMakerContract.getBond(bondID);
        require(bondTokenAddress != address(0), "the bond is not registered");
        require(
            solidBondStrikePriceUSD != 0,
            "the bond is not the form of SBT"
        );
        require(
            maturity <= _getBlockTimestampSec() + AUCTION_SPAN,
            "maturity is later than the regular auctionSpan"
        );

        uint64 lockedSolidBondTotalE8;
        {

                AccountingTotalInfo memory accountingInfo
             = _accountingTotalInfo[poolID];
            lockedSolidBondTotalE8 = accountingInfo.lockedSolidBondTotalE8;
            if (lockedSolidBondTotalE8 == 0) {
                if (accountingInfo.lockedPoolIDOLTotalE8 != 0) {
                    _setSettledAverageAuctionPrice(bondID, 0, 0, true);
                }
                return;
            }
            delete _accountingTotalInfo[poolID].lockedSolidBondTotalE8;
        }

        if (maturity <= _getBlockTimestampSec() + EMERGENCY_AUCTION_SPAN) {
            _auctionContract.startAuction(bondID, lockedSolidBondTotalE8, true);
        } else {
            _auctionContract.startAuction(
                bondID,
                lockedSolidBondTotalE8,
                false
            );
        }

        // Send SBT to the auction contract.
        BondTokenInterface bondTokenContract = BondTokenInterface(
            payable(bondTokenAddress)
        );
        bondTokenContract.transfer(
            address(_auctionContract),
            lockedSolidBondTotalE8
        );
    }

    /**
     * @notice Starts emergency auction
     * @dev Check if the SBT needs to trigger the emergency auction based on the length of the
     * time until maturity, the volatility, and the distance between the current price and the
     * strike price.
     */
    function startAuctionByMarket(bytes32 bondID)
        public
        override
        isNotEmptyAuctionInstance
    {
        bytes32 poolID = getCurrentPoolID(bondID);
        (
            address bondTokenAddress,
            uint256 maturity,
            uint64 solidBondStrikePriceUSD,

        ) = _bondMakerContract.getBond(bondID);
        require(bondTokenAddress != address(0), "the bond is not registered");
        require(
            solidBondStrikePriceUSD != 0,
            "the bond is not the form of SBT"
        );

        (uint256 rateETH2USD, uint256 volatility) = _getOracleData();
        bool isDanger = isInEmergency(
            rateETH2USD,
            solidBondStrikePriceUSD,
            volatility,
            maturity - _getBlockTimestampSec()
        );
        require(isDanger, "the SBT is not in emergency");

        uint64 lockedSolidBondTotalE8;
        {

                AccountingTotalInfo memory accountingInfo
             = _accountingTotalInfo[poolID];
            lockedSolidBondTotalE8 = accountingInfo.lockedSolidBondTotalE8;
            if (lockedSolidBondTotalE8 == 0) {
                if (accountingInfo.lockedPoolIDOLTotalE8 != 0) {
                    _setSettledAverageAuctionPrice(bondID, 0, 0, true);
                }
                return;
            }
            delete _accountingTotalInfo[poolID].lockedSolidBondTotalE8;
        }

        _auctionContract.startAuction(bondID, lockedSolidBondTotalE8, true);

        // Send SBT to the auction contract.
        BondTokenInterface bondTokenContract = BondTokenInterface(
            payable(bondTokenAddress)
        );
        bondTokenContract.transfer(
            address(_auctionContract),
            lockedSolidBondTotalE8
        );
    }

    /**
     * @notice Sets SettledAverageAuctionPrice and burns a portion of pooled IDOL.
     * @dev Only callable from the auction contract.
     */
    function setSettledAverageAuctionPrice(
        bytes32 bondID,
        uint64 totalPaidIDOL,
        uint64 SBTAmount,
        bool isLast
    ) public override isNotEmptyAuctionInstance {
        require(
            msg.sender == address(_auctionContract),
            "msg.sender must be auction contract"
        );

        (, , uint256 solidStrikePrice, ) = _bondMakerContract.getBond(bondID);
        require(solidStrikePrice != 0, "the bond is not the form of SBT");
        _setSettledAverageAuctionPrice(
            bondID,
            totalPaidIDOL,
            SBTAmount,
            isLast
        );
    }

    /**
     * @dev Returns the IDOL amount equivalent to the strike price value of SBT.
     * @param solidBondValueE12 solidBondValueE12(USD) = SBT(SBT) * strikePrice(USD/SBT)
     */
    function calcSBT2IDOL(uint256 solidBondValueE12)
        public
        override
        view
        returns (uint256 IDOLAmountE8)
    {
        if (_solidValueTotalE12 == 0) {
            return solidBondValueE12.div(10**4);
        }

        return solidBondValueE12.mul(totalSupply()).div(_solidValueTotalE12);
    }

    function _calcUnlockablePoolAmount(bytes32 poolID, address account)
        internal
        returns (uint64)
    {
        AuctionAmountInfo memory auctionInfo = _auctionAmountInfo[poolID];
        if (!auctionInfo.isAllAmountSoldInAuction) {
            return 0;
        }

        uint256 pool = lockedPoolE8[account][poolID].IDOLAmount;
        uint256 amountE8 = lockedPoolE8[account][poolID].baseSBTAmount;
        delete lockedPoolE8[account][poolID];

        uint256 auctionIDOLPriceE8 = auctionInfo.settledAverageAuctionPrice;
        uint256 toBack = 0;

        // The return value can be calculated by
        // (average sold price) * (total sold amount) - (total distributed amount) for the bondID.
        // Here, (total distributed amount) = pool * MINT_IDOL_BORDER / LOCK_POOL_BORDER = pool * MINT_IDOL_BORDER
        if (
            auctionIDOLPriceE8.mul(amountE8).div(10**8) >
            pool.mul(MINT_IDOL_BORDER)
        ) {
            toBack =
                auctionIDOLPriceE8.mul(amountE8).div(10**8) -
                pool.mul(MINT_IDOL_BORDER);
        }

        return toBack.min(pool).toUint64();
    }

    /**
     * @notice Receives all the redeemable IDOL in one action.
     * @dev Receive corresponding pooled IDOL based on the SettledAverageAuctionPrice.
     */
    function returnLockedPoolTo(bytes32[] memory poolIDs, address account)
        public
        override
        returns (uint64)
    {
        uint256 totalBackIDOLAmount = 0;
        for (uint256 i = 0; i < poolIDs.length; i++) {
            // For each bondID, the return amount should not exceed the pooled amount.
            uint64 backIDOLAmount = _calcUnlockablePoolAmount(
                poolIDs[i],
                account
            );
            totalBackIDOLAmount = totalBackIDOLAmount.add(backIDOLAmount);
            if (backIDOLAmount != 0) {
                emit LogReturnLockedPool(poolIDs[i], account, backIDOLAmount);
            }
        }

        this.transfer(account, totalBackIDOLAmount);

        return totalBackIDOLAmount.toUint64();
    }

    function returnLockedPool(bytes32[] memory poolIDs)
        public
        override
        returns (uint64)
    {
        return returnLockedPoolTo(poolIDs, msg.sender);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"oracleAddress","type":"address"},{"internalType":"address","name":"bondMakerAddress","type":"address"},{"internalType":"uint256","name":"auctionSpan","type":"uint256"},{"internalType":"uint256","name":"emergencyAuctionSpan","type":"uint256"},{"internalType":"uint256","name":"mintIDOLAmountBorder","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"bondID","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"burnIDOLAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlockSBTAmount","type":"uint256"}],"name":"LogBurnIDOL","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"bondID","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"isAcceptable","type":"bool"}],"name":"LogIsAcceptableSBT","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolID","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"settledAverageAuctionPrice","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"totalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lockedSBTValue","type":"uint256"}],"name":"LogLambda","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"bondID","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"bytes32","name":"poolID","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"obtainIDOLAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"poolIDOLAmount","type":"uint256"}],"name":"LogMintIDOL","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolID","type":"bytes32"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint64","name":"backIDOLAmount","type":"uint64"}],"name":"LogReturnLockedPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"auctionTriggerCount","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"solidBondValueE12","type":"uint256"}],"name":"calcSBT2IDOL","outputs":[{"internalType":"uint256","name":"IDOLAmountE8","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"},{"internalType":"uint64","name":"count","type":"uint64"}],"name":"generatePoolID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"}],"name":"getCurrentPoolID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"xxE8","type":"uint256"}],"name":"getEmergencyBorderInfo","outputs":[{"internalType":"int256","name":"aaE4","type":"int256"},{"internalType":"int256","name":"bE4","type":"int256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"bytes32","name":"poolID","type":"bytes32"}],"name":"getLockedPool","outputs":[{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"poolID","type":"bytes32"}],"name":"getPoolInfo","outputs":[{"internalType":"uint64","name":"lockedSBTTotal","type":"uint64"},{"internalType":"uint64","name":"unlockedSBTTotal","type":"uint64"},{"internalType":"uint64","name":"lockedPoolIDOLTotal","type":"uint64"},{"internalType":"uint64","name":"burnedIDOLTotal","type":"uint64"},{"internalType":"uint64","name":"soldSBTTotalInAuction","type":"uint64"},{"internalType":"uint64","name":"paidIDOLTotalInAuction","type":"uint64"},{"internalType":"uint64","name":"settledAverageAuctionPrice","type":"uint64"},{"internalType":"bool","name":"isAllAmountSoldInAuction","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"}],"name":"isAcceptableSBT","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rateETH2USD","type":"uint256"},{"internalType":"uint256","name":"solidBondStrikePrice","type":"uint256"},{"internalType":"uint256","name":"volatility","type":"uint256"},{"internalType":"uint256","name":"untilMaturity","type":"uint256"}],"name":"isDangerSolidBond","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"rateETH2USD","type":"uint256"},{"internalType":"uint256","name":"solidBondStrikePrice","type":"uint256"},{"internalType":"uint256","name":"volatility","type":"uint256"},{"internalType":"uint256","name":"untilMaturity","type":"uint256"}],"name":"isInEmergency","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"lockedPoolE8","outputs":[{"internalType":"uint64","name":"IDOLAmount","type":"uint64"},{"internalType":"uint64","name":"baseSBTAmount","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint64","name":"lockAmountE8","type":"uint64"}],"name":"mint","outputs":[{"internalType":"bytes32","name":"poolID","type":"bytes32"},{"internalType":"uint64","name":"obtainIDOLAmountE8","type":"uint64"},{"internalType":"uint64","name":"poolIDOLAmountE8","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"poolIDs","type":"bytes32[]"}],"name":"returnLockedPool","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"poolIDs","type":"bytes32[]"},{"internalType":"address","name":"account","type":"address"}],"name":"returnLockedPoolTo","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"name":"setAuctionContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"},{"internalType":"uint64","name":"totalPaidIDOL","type":"uint64"},{"internalType":"uint64","name":"SBTAmount","type":"uint64"},{"internalType":"bool","name":"isLast","type":"bool"}],"name":"setSettledAverageAuctionPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"solidValueTotal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"}],"name":"startAuctionByMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"}],"name":"startAuctionOnMaturity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"bondID","type":"bytes32"},{"internalType":"uint64","name":"burnAmountE8","type":"uint64"}],"name":"unlockSBT","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"nonpayable","type":"function"}]

6101206040523480156200001257600080fd5b5060405162004eff38038062004eff833981810160405260a08110156200003857600080fd5b50805160208083015160408085015160608601516080909601518251808401845260048082527f69444f4c000000000000000000000000000000000000000000000000000000008288018181528651808801909752918652968501969096528051969794969295919387938993620000b491600391906200020e565b508051620000ca9060049060208401906200020e565b50506005805460ff19166012179055506001600160a01b0381166200013b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018062004edc6023913960400191505060405180910390fd5b60058054610100600160a81b0319166101006001600160a01b03938416021790558116620001b5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602381526020018062004edc6023913960400191505060405180910390fd5b6001600160601b0319606091821b1660805233901b60a052620001e260086001600160e01b03620001f816565b60c09290925260e0526101005250620002b39050565b6005805460ff191660ff92909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200025157805160ff191683800117855562000281565b8280016001018555821562000281579182015b828111156200028157825182559160200191906001019062000264565b506200028f92915062000293565b5090565b620002b091905b808211156200028f57600081556001016200029a565b90565b60805160601c60a05160601c60c05160e05161010051614bc06200031c60003980610f5b5250806130ed52508061224e5280612f9052508061334f525080610da052806116185280611b3e52806120ef528061252f5280612e1b5280613f225250614bc06000f3fe608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063b67f0935116100a2578063dbb2348311610071578063dbb23483146108dd578063dd62ed3e14610916578063dfef99f614610951578063e2fbacdd14610987576101f0565b8063b67f0935146107c1578063bc27f2ec146107ee578063c4fb3c3e1461080b578063d528d8aa146108ae576101f0565b80639ed7ac70116100de5780639ed7ac7014610705578063a457c2d714610732578063a9059cbb1461076b578063b515f740146107a4576101f0565b806379cc67901461068d5780637b7e31b1146106c657806393bb8a01146106ce57806395d89b41146106fd576101f0565b8063313ce56711610187578063616d272f11610156578063616d272f1461059e57806367fd88d0146105dd5780636881df131461063d57806370a082311461065a576101f0565b8063313ce5671461045257806339509351146104705780634e167ed9146104a957806350fef38c14610581576101f0565b8063134b0fca116101c3578063134b0fca1461036657806318160ddd1461039557806323b872dd1461039d5780632fe82fe6146103e0576101f0565b8063023924c7146101f557806306fdde031461022a578063095ea7b3146102a757806309f2c019146102f4575b600080fd5b6102286004803603602081101561020b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166109a4565b005b610232610a9b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561026c578181015183820152602001610254565b50505050905090810190601f1680156102995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102e0600480360360408110156102bd57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610b4f565b604080519115158252519081900360200190f35b6103116004803603602081101561030a57600080fd5b5035610b6d565b6040805167ffffffffffffffff998a16815297891660208901529588168787015293871660608701529186166080860152851660a085015290931660c083015291151560e08201529051908190036101000190f35b6103836004803603602081101561037c57600080fd5b5035610cb2565b60408051918252519081900360200190f35b610383610cde565b6102e0600480360360608110156103b357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610ce4565b610429600480360360608110156103f657600080fd5b50803590602081013573ffffffffffffffffffffffffffffffffffffffff16906040013567ffffffffffffffff16610d8b565b6040805193845267ffffffffffffffff9283166020850152911682820152519081900360600190f35b61045a6113a1565b6040805160ff9092168252519081900360200190f35b6102e06004803603604081101561048657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356113aa565b610564600480360360408110156104bf57600080fd5b8101906020810181356401000000008111156104da57600080fd5b8201836020820111156104ec57600080fd5b8035906020019184602083028401116401000000008311171561050e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505050903573ffffffffffffffffffffffffffffffffffffffff16915061140b9050565b6040805167ffffffffffffffff9092168252519081900360200190f35b6102286004803603602081101561059757600080fd5b503561159a565b610228600480360360808110156105b457600080fd5b5080359067ffffffffffffffff6020820135811691604081013590911690606001351515611a7a565b610616600480360360408110156105f357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611c4d565b6040805167ffffffffffffffff938416815291909216602082015281519081900390910190f35b6103836004803603602081101561065357600080fd5b5035611c9d565b6103836004803603602081101561067057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611ced565b610228600480360360408110156106a357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611d15565b610383611de3565b6102e0600480360360808110156106e457600080fd5b5080359060208101359060408101359060600135611de9565b610232611ef5565b6103836004803603604081101561071b57600080fd5b508035906020013567ffffffffffffffff16611f74565b6102e06004803603604081101561074857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611fec565b6102e06004803603604081101561078157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612067565b6102e0600480360360208110156107ba57600080fd5b503561207b565b610564600480360360408110156107d757600080fd5b508035906020013567ffffffffffffffff1661251c565b6105646004803603602081101561080457600080fd5b5035612a72565b6105646004803603602081101561082157600080fd5b81019060208101813564010000000081111561083c57600080fd5b82018360208201111561084e57600080fd5b8035906020019184602083028401116401000000008311171561087057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612a8e945050505050565b6102e0600480360360808110156108c457600080fd5b5080359060208101359060408101359060600135612a9a565b610616600480360360408110156108f357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612bc8565b6103836004803603604081101561092c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516612bff565b61096e6004803603602081101561096757600080fd5b5035612c37565b6040805192835260208301919091528051918290030190f35b6102286004803603602081101561099d57600080fd5b5035612d9d565b6109ad3361334d565b6109e85760405162461bcd60e51b815260040180806020018281038252602e8152602001806148dd602e913960400191505060405180910390fd5b60065473ffffffffffffffffffffffffffffffffffffffff1615610a3d5760405162461bcd60e51b815260040180806020018281038252602a815260200180614af6602a913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610a8f5760405162461bcd60e51b81526004018080602001828103825260238152602001806149a16023913960400191505060405180910390fd5b610a988161338c565b50565b60038054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610b455780601f10610b1a57610100808354040283529160200191610b45565b820191906000526020600020905b815481529060010190602001808311610b2857829003601f168201915b5050505050905090565b6000610b63610b5c6133d3565b84846133d7565b5060015b92915050565b600080600080600080600080610b81614707565b506000898152600a60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484018590527001000000000000000000000000000000008304821695840186905278010000000000000000000000000000000000000000000000009092041660608301819052909b509199509197509550610c15614707565b50505060009788525050600b60209081526040968790208751608081018952905467ffffffffffffffff808216808452680100000000000000008304821694840185905270010000000000000000000000000000000083049091169983018a9052780100000000000000000000000000000000000000000000000090910460ff161515606090920182905296989597949693959394919391925090565b60008181526008602052604081205467ffffffffffffffff16610cd58382611f74565b9150505b919050565b60025490565b6000610cf18484846134ea565b610d8184610cfd6133d3565b610d7c856040518060600160405280602881526020016149526028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020526040812090610d486133d3565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff61369216565b6133d7565b5060019392505050565b6000806000610d9986610cb2565b92506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b896040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015610e0f57600080fd5b505afa158015610e23573d6000803e3d6000fd5b505050506040513d6080811015610e3957600080fd5b50805160409091015190925067ffffffffffffffff169050610e5a8861207b565b610e955760405162461bcd60e51b815260040180806020018281038252602f81526020018061484e602f913960400191505060405180910390fd5b610e9d614707565b506000858152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481169483019490945270010000000000000000000000000000000081048416928201929092527801000000000000000000000000000000000000000000000000909104821660608201529190610f319089168463ffffffff61372916565b90506000610f3e82611c9d565b9050826040015167ffffffffffffffff166000141580610f7e57507f00000000000000000000000000000000000000000000000000000000000000008110155b610fb95760405162461bcd60e51b815260040180806020018281038252603a815260200180614a1d603a913960400191505060405180910390fd5b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015230602482015267ffffffffffffffff8b1660448201529051869173ffffffffffffffffffffffffffffffffffffffff8316916323b872dd916064808201926020929091908290030181600087803b15801561104057600080fd5b505af1158015611054573d6000803e3d6000fd5b505050506040513d602081101561106a57600080fd5b506000905061108083600a63ffffffff61378916565b73ffffffffffffffffffffffffffffffffffffffff8d1660009081526009602090815260408083208e845290915290208054919250906110d9906110d49067ffffffffffffffff168463ffffffff6137cb16565b613825565b81547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9182161780835561112b916110d4916801000000000000000090048116908f166137cb565b815467ffffffffffffffff9190911668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781556111858d611180868563ffffffff61387216565b6138b4565b61118f30836138b4565b6007546111a2908663ffffffff6137cb16565b60075585516111c9906110d49067ffffffffffffffff908116908f1663ffffffff6137cb16565b67ffffffffffffffff908116875260408701516111f1916110d491168463ffffffff6137cb16565b67ffffffffffffffff908116604080890191825260008e8152600a60209081529181208a518154938c0151945160608d0151871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff918816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff97891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff949099167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096179290921696909617949094169290921793909316919091179055611315858463ffffffff61387216565b90508d73ffffffffffffffffffffffffffffffffffffffff168f7f5a0def86b68ea53595ef32019b93a42eedf7c609407f51834703faa48bd592d08e848760405180848152602001838152602001828152602001935050505060405180910390a38b61138082613825565b61138985613825565b9b509b509b5050505050505050505093509350939050565b60055460ff1690565b6000610b636113b76133d3565b84610d7c85600160006113c86133d3565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff6137cb16565b600080805b84518110156114e657600061143886838151811061142a57fe5b6020026020010151866139d7565b90506114548367ffffffffffffffff831663ffffffff6137cb16565b925067ffffffffffffffff8116156114dd578473ffffffffffffffffffffffffffffffffffffffff1686838151811061148957fe5b60200260200101517fb931a8416f2f16d5400a0cce933872df77c3cfcadae032ff6b1646e8cdc12a3c83604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390a35b50600101611410565b50604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602481018390529051309163a9059cbb9160448083019260209291908290030181600087803b15801561155c57600080fd5b505af1158015611570573d6000803e3d6000fd5b505050506040513d602081101561158657600080fd5b50611592905081613825565b949350505050565b60065473ffffffffffffffffffffffffffffffffffffffff16611604576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b600061160f82610cb2565b905060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561168757600080fd5b505afa15801561169b573d6000803e3d6000fd5b505050506040513d60808110156116b157600080fd5b5080516020820151604090920151909450909250905073ffffffffffffffffffffffffffffffffffffffff831661172f576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b67ffffffffffffffff811661178b576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b600080611796613b68565b9150915060006117bb838567ffffffffffffffff16846117b4613ca7565b8903611de9565b90508061180f576040805162461bcd60e51b815260206004820152601b60248201527f74686520534254206973206e6f7420696e20656d657267656e63790000000000604482015290519081900360640190fd5b6000611819614707565b50506000878152600a60209081526040918290208251608081018452905467ffffffffffffffff808216808452680100000000000000008304821694840194909452700100000000000000000000000000000000820481169483019490945278010000000000000000000000000000000000000000000000009004909216606083015290816118d257604081015167ffffffffffffffff16156118c4576118c48a6000806001613cab565b505050505050505050610a98565b506000888152600a6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560065481517f9da326ef000000000000000000000000000000000000000000000000000000008152600481018e905267ffffffffffffffff8616602482015260016044820152915173ffffffffffffffffffffffffffffffffffffffff90911693639da326ef93606480850194919392918390030190829087803b15801561199157600080fd5b505af11580156119a5573d6000803e3d6000fd5b505050506040513d60208110156119bb57600080fd5b5050600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051899283169163a9059cbb9160448083019260209291908290030181600087803b158015611a4257600080fd5b505af1158015611a56573d6000803e3d6000fd5b505050506040513d6020811015611a6c57600080fd5b505050505050505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff16611ae4576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff163314611b3a5760405162461bcd60e51b81526004018080602001828103825260238152602001806148ba6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015611bad57600080fd5b505afa158015611bc1573d6000803e3d6000fd5b505050506040513d6080811015611bd757600080fd5b506040015167ffffffffffffffff16905080611c3a576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b611c4685858585613cab565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600960209081526040808320938352929052205467ffffffffffffffff80821692680100000000000000009092041690565b600060075460001415611cc357611cbc8261271063ffffffff61378916565b9050610cd9565b610b67600754611ce1611cd4610cde565b859063ffffffff61372916565b9063ffffffff61378916565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff16611d7f576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff163314611dd55760405162461bcd60e51b81526004018080602001828103825260238152602001806148ba6023913960400191505060405180910390fd5b611ddf828261438a565b5050565b60075490565b600082630bebc200811115611dff5750630bebc2005b626ebe008310611e13576001915050611592565b6000611e3584611e29848063ffffffff61372916565b9063ffffffff61372916565b905066072ba304f800008104600080611e4d83612c37565b915091506000611e5c8b6144c6565b90506000611e698b6144c6565b90506000611e8d611e80858463ffffffff61452616565b849063ffffffff61460916565b90506000611eb383611ea781818c8b63ffffffff61452616565b9063ffffffff61452616565b905060008083131580611ee2575081611edf680118188ff217800000611ea7868063ffffffff61452616565b13155b9f9e505050505050505050505050505050565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610b455780601f10610b1a57610100808354040283529160200191610b45565b6040805160208082019490945260c09290921b7fffffffffffffffff00000000000000000000000000000000000000000000000016828201527f6c69656e0000000000000000000000000000000000000000000000000000000060488301528051808303602c018152604c9092019052805191012090565b6000610b63611ff96133d3565b84610d7c85604051806060016040528060258152602001614b6660259139600160006120236133d3565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61369216565b6000610b636120746133d3565b84846134ea565b60065460009073ffffffffffffffffffffffffffffffffffffffff166120e8576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561215e57600080fd5b505afa158015612172573d6000803e3d6000fd5b505050506040513d608081101561218857600080fd5b5080516020820151604090920151909450909250905073ffffffffffffffffffffffffffffffffffffffff8316612206576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b67ffffffffffffffff811661224c5760405162461bcd60e51b815260040180806020018281038252602a815260200180614752602a913960400191505060405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000612275613ca7565b0182116122b35760405162461bcd60e51b815260040180806020018281038252603c81526020018061479e603c913960400191505060405180910390fd5b620186a067ffffffffffffffff82160667ffffffffffffffff1660001461230b5760405162461bcd60e51b8152600401808060200182810382526022815260200180614b446022913960400191505060405180910390fd5b600654604080517fecfb314d00000000000000000000000000000000000000000000000000000000815260048101889052905160009273ffffffffffffffffffffffffffffffffffffffff169163ecfb314d916024808301926020929190829003018186803b15801561237d57600080fd5b505afa158015612391573d6000803e3d6000fd5b505050506040513d60208110156123a757600080fd5b5051600654604080517f9737d6fd00000000000000000000000000000000000000000000000000000000815260048101849052905192935073ffffffffffffffffffffffffffffffffffffffff90911691639737d6fd91602480820192602092909190829003018186803b15801561241e57600080fd5b505afa158015612432573d6000803e3d6000fd5b505050506040513d602081101561244857600080fd5b505167ffffffffffffffff16156124a6576040805162461bcd60e51b815260206004820152601860248201527f7468697320534254206973206f6e20612061756369746f6e0000000000000000604482015290519081900360640190fd5b6000806124b1613b68565b9150915060006124d6838667ffffffffffffffff16846124cf613ca7565b8a03612a9a565b604080518215815290519192508a917fea0241146eaea8e64956684a8df42cc134671b71fcc2b474bcbd63f30b32984f9181900360200190a21598975050505050505050565b60008061252884610cb2565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b876040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561259e57600080fd5b505afa1580156125b2573d6000803e3d6000fd5b505050506040513d60808110156125c857600080fd5b50805160409091015190925067ffffffffffffffff16905073ffffffffffffffffffffffffffffffffffffffff8216612648576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b8061269a576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b6126a2614707565b506000838152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481168386015270010000000000000000000000000000000082048116838501527801000000000000000000000000000000000000000000000000909104166060808301919091528251908101909252603d808352909392612790926110d492879261487d9083013961278361274b610cde565b6040518060600160405280602c8152602001614822602c91396127836007548f67ffffffffffffffff1661372990919063ffffffff16565b919063ffffffff61466e16565b90506127c06110d48867ffffffffffffffff16846060015167ffffffffffffffff166137cb90919063ffffffff16565b67ffffffffffffffff90811660608401526127de903390891661438a565b604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015267ffffffffffffffff831660248201529051859173ffffffffffffffffffffffffffffffffffffffff83169163a9059cbb916044808201926020929091908290030181600087803b15801561285f57600080fd5b505af1158015612873573d6000803e3d6000fd5b505050506040513d602081101561288957600080fd5b50506040805167ffffffffffffffff808b16825284166020820152815133928c927f87efbe374e86e4f26b4593306372ef7f3c1fa4ed256c9d4f7400d00b3f729114929081900390910190a36129016128f267ffffffffffffffff84168663ffffffff61372916565b6007549063ffffffff61387216565b6007558251612928906110d49067ffffffffffffffff90811690851663ffffffff61387216565b67ffffffffffffffff90811684526020840151612953916110d491811690851663ffffffff6137cb16565b67ffffffffffffffff90811660208086019182526000988952600a905260409788902085518154925199870151606090970151841678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff978516700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9b861668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff939096167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009095169490941791909116939093179890981617939093169290921790945550919250505092915050565b60086020526000908152604090205467ffffffffffffffff1681565b6000610b67823361140b565b60006002850261c3508502108015612ab457506212750082105b15612ac157506000611592565b630bebc200831115612ad557506001611592565b626ebe008210612ae757506001611592565b6000612afd83611e29868063ffffffff61372916565b905066072ba304f800008104600080612b1583612c37565b915091506000612b248a6144c6565b90506000612b318a6144c6565b90506000612b6a612b4d6003611ea7878663ffffffff61452616565b612b5e85600263ffffffff61452616565b9063ffffffff61460916565b90506000612b876009611ea7858181818e8d63ffffffff61452616565b905060008083131580612bb6575081612bb3680118188ff217800000611ea7868063ffffffff61452616565b13155b9e9d5050505050505050505050505050565b600960209081526000928352604080842090915290825290205467ffffffffffffffff808216916801000000000000000090041682565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60008062c320408311612c51575060009050612af8612d98565b630394b7b18311612c6a5750615a4090506115bc612d98565b6307f7cae48311612ca257506206400090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81fc612d98565b630bf379008311612cda5750621f126990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1e88612d98565b630fc0bf018311612d12575062817ac190507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffae894612d98565b63134fd9008311612d4b57506301af0c8990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f33b612d98565b6040805162461bcd60e51b815260206004820152600e60248201527f6e6f742061636365707461626c65000000000000000000000000000000000000604482015290519081900360640190fd5b915091565b60065473ffffffffffffffffffffffffffffffffffffffff16612e07576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b6000612e1282610cb2565b905060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015612e8a57600080fd5b505afa158015612e9e573d6000803e3d6000fd5b505050506040513d6080811015612eb457600080fd5b5080516020820151604090920151909450909250905073ffffffffffffffffffffffffffffffffffffffff8316612f32576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b67ffffffffffffffff8116612f8e576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b7f0000000000000000000000000000000000000000000000000000000000000000612fb7613ca7565b01821115612ff65760405162461bcd60e51b815260040180806020018281038252602e815260200180614ac8602e913960400191505060405180910390fd5b6000613000614707565b50506000848152600a60209081526040918290208251608081018452905467ffffffffffffffff808216808452680100000000000000008304821694840194909452700100000000000000000000000000000000820481169483019490945278010000000000000000000000000000000000000000000000009004909216606083015290816130b657604081015167ffffffffffffffff16156130ab576130ab876000806001613cab565b505050505050610a98565b506000858152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690557f0000000000000000000000000000000000000000000000000000000000000000613114613ca7565b0183116131d857600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810189905267ffffffffffffffff8416602482015260016044820152905173ffffffffffffffffffffffffffffffffffffffff90921691639da326ef916064808201926020929091908290030181600087803b1580156131a657600080fd5b505af11580156131ba573d6000803e3d6000fd5b505050506040513d60208110156131d057600080fd5b506132939050565b600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810189905267ffffffffffffffff84166024820152600060448201819052915173ffffffffffffffffffffffffffffffffffffffff90931692639da326ef92606480840193602093929083900390910190829087803b15801561326657600080fd5b505af115801561327a573d6000803e3d6000fd5b505050506040513d602081101561329057600080fd5b50505b600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051869283169163a9059cbb9160448083019260209291908290030181600087803b15801561331857600080fd5b505af115801561332c573d6000803e3d6000fd5b505050506040513d602081101561334257600080fd5b505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3390565b73ffffffffffffffffffffffffffffffffffffffff83166134295760405162461bcd60e51b8152600401808060200182810382526024815260200180614a7c6024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661347b5760405162461bcd60e51b81526004018080602001828103825260228152602001806147da6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661353c5760405162461bcd60e51b8152600401808060200182810382526025815260200180614a576025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661358e5760405162461bcd60e51b815260040180806020018281038252602381526020018061472f6023913960400191505060405180910390fd5b6135998383836146d3565b6135e9816040518060600160405280602681526020016147fc6026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054919063ffffffff61369216565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461362b908263ffffffff6137cb16565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156137215760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156136e65781810151838201526020016136ce565b50505050905090810190601f1680156137135780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008261373857506000610b67565b8282028284828161374557fe5b04146137825760405162461bcd60e51b815260040180806020018281038252602181526020018061490b6021913960400191505060405180910390fd5b9392505050565b600061378283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061466e565b600082820183811015613782576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600068010000000000000000821061386e5760405162461bcd60e51b815260040180806020018281038252602681526020018061492c6026913960400191505060405180910390fd5b5090565b600061378283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613692565b73ffffffffffffffffffffffffffffffffffffffff821661391c576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b613928600083836146d3565b60025461393b908263ffffffff6137cb16565b60025573ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054613974908263ffffffff6137cb16565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60006139e1614707565b506000838152600b60209081526040918290208251608081018452905467ffffffffffffffff80821683526801000000000000000082048116938301939093527001000000000000000000000000000000008104909216928101929092527801000000000000000000000000000000000000000000000000900460ff16151560608201819052613a75576000915050610b67565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020818152604080842088855290915280832080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081169091559084015167ffffffffffffffff808316946801000000000000000090930481169391169190613afe908590613729565b613b166305f5e100611ce1858763ffffffff61372916565b1115613b4957613b2d84600963ffffffff61372916565b613b456305f5e100611ce1858763ffffffff61372916565b0390505b613b5c6110d4828663ffffffff6146d816565b98975050505050505050565b600080600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3e6ba946040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613bd557600080fd5b505af1158015613be9573d6000803e3d6000fd5b505050506040513d6020811015613bff57600080fd5b5051600554604080517f3af2888b000000000000000000000000000000000000000000000000000000008152905192945061010090910473ffffffffffffffffffffffffffffffffffffffff1691633af2888b916004808201926020929091908290030181600087803b158015613c7557600080fd5b505af1158015613c89573d6000803e3d6000fd5b505050506040513d6020811015613c9f57600080fd5b505190509091565b4290565b6000613cb685610cb2565b9050613cc0614707565b506000818152600b60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484019490945270010000000000000000000000000000000082048116948301949094527801000000000000000000000000000000000000000000000000900460ff161515606082015291613d54916110d49187166137cb565b67ffffffffffffffff90811682526020820151613d7f916110d491811690881663ffffffff6137cb16565b67ffffffffffffffff166020820152821561427257613d9c614707565b506000828152600a602090815260408083208151608081018352905467ffffffffffffffff8082168352680100000000000000008204811694830194909452700100000000000000000000000000000000810484169282018390527801000000000000000000000000000000000000000000000000900490921660608301529091908190613e3190600963ffffffff61372916565b90506000613e5682856040015167ffffffffffffffff166137cb90919063ffffffff16565b90506000613e89866020015167ffffffffffffffff16866060015167ffffffffffffffff166137cb90919063ffffffff16565b905082811115613ee957808210613ec1576060850151613eba90839067ffffffffffffffff1663ffffffff61387216565b9350613ee4565b6060850151613ee190829067ffffffffffffffff1663ffffffff61387216565b93505b613f1b565b613f18866020015167ffffffffffffffff16866040015167ffffffffffffffff166137cb90919063ffffffff16565b93505b50505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b8a6040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015613f9157600080fd5b505afa158015613fa5573d6000803e3d6000fd5b505050506040513d6080811015613fbb57600080fd5b50604001519050613fcc308361438a565b613ffe6110d4856020015167ffffffffffffffff16856060015167ffffffffffffffff166137cb90919063ffffffff16565b67ffffffffffffffff9081166060850152845161402e9161402991811690841663ffffffff61372916565b6146ee565b83516020840151614056916110d49167ffffffffffffffff908116911663ffffffff6137cb16565b67ffffffffffffffff166020808501829052604080516060810190915260388082526140ae936110d493909291906149c49083013960608701516127839067ffffffffffffffff166305f5e10063ffffffff61372916565b67ffffffffffffffff90811660408087019190915260016060870181905260008c8152600860205291909120546140f1926110d49291169063ffffffff6137cb16565b60008a8152600860209081526040808320805467ffffffffffffffff9586167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000091821617909155898452600a835281842088518154948a0151938a015160608b0151881678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff918916700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff968a1668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff94909a169790951696909617919091169690961792909216179390931617909155614218610cde565b604080870151600754825167ffffffffffffffff90921682526020820184905281830152905191925087917fc96942e0138bef71dbf15b3512ad2970a8a07aeea02f0c50a94d373906dbf4cb9181900360600190a2505050505b6000918252600b60209081526040928390208251815492840151948401516060909401517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090931667ffffffffffffffff918216177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000095821695909502949094177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000009490931693909302919091177fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009115159190910217905550505050565b73ffffffffffffffffffffffffffffffffffffffff82166143dc5760405162461bcd60e51b81526004018080602001828103825260218152602001806149fc6021913960400191505060405180910390fd5b6143e8826000836146d3565b6144388160405180606001604052806022815260200161477c6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040902054919063ffffffff61369216565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902055600254614471908263ffffffff61387216565b60025560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60007f8000000000000000000000000000000000000000000000000000000000000000821061386e5760405162461bcd60e51b8152600401808060200182810382526028815260200180614aa06028913960400191505060405180910390fd5b60008261453557506000610b67565b827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14801561458357507f800000000000000000000000000000000000000000000000000000000000000082145b156145bf5760405162461bcd60e51b815260040180806020018281038252602781526020018061497a6027913960400191505060405180910390fd5b828202828482816145cc57fe5b05146137825760405162461bcd60e51b815260040180806020018281038252602781526020018061497a6027913960400191505060405180910390fd5b600081830381831280159061461e5750838113155b80614633575060008312801561463357508381135b6137825760405162461bcd60e51b8152600401808060200182810382526024815260200180614b206024913960400191505060405180910390fd5b600081836146bd5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156136e65781810151838201526020016136ce565b5060008385816146c957fe5b0495945050505050565b505050565b60008183106146e75781613782565b5090919050565b600754614701908263ffffffff61387216565b60075550565b6040805160808101825260008082526020820181905291810182905260608101919091529056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737374686520626f6e6420646f6573206e6f74206d6174636820746f2074686520666f726d206f662053425445524332303a206275726e20616d6f756e7420657863656564732062616c616e636561207265717565737420746f20686f6c6420616e2061756374696f6e206f662074686520626f6e642068617320616c7265616479206578706972656445524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636573797374656d206572726f723a20746f74616c537570706c79206e65766572206265636f6d6573207a65726f53425420776974682074686520626f6e644944206973206e6f742063757272656e746c792061636365707461626c6573797374656d206572726f723a20736f6c6964537472696b655072696365206e65766572206265636f6d6573207a65726f205b756e6c6f636b5342545d6d73672e73656e646572206d7573742062652061756374696f6e20636f6e74726163746f6e6c79206465706c6f79657220697320616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e203634206269747345524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77636f6e74726163742073686f756c64206265206e6f6e2d7a65726f206164647265737373797374656d3a2074686520746f74616c20756e6c6f636b20616d6f756e742073686f756c64206265206e6f6e2d7a65726f2076616c756545524332303a206275726e2066726f6d20746865207a65726f20616464726573736d696e7420616d6f756e74206e65656420746f2062652067726561746572207468616e203530302069646f6c20666f72207468697320626f6e6445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737353616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235366d61747572697479206973206c61746572207468616e2074686520726567756c61722061756374696f6e5370616e7468652061756374696f6e20636f6e747261637420697320616c726561647920726567697374657265645369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f7774686520737472696b65207072696365206e65656420746f20626520242031302a5845524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220d085672f8467497f59973194f9b1d4d97c7592939b63afb78bc9add4e0e727e664736f6c63430006060033636f6e74726163742073686f756c64206265206e6f6e2d7a65726f2061646472657373000000000000000000000000120a078fdc516a1a98bbecb9e961f8741ac7ac820000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df010000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000000000000000000000000000000000000015f900000000000000000000000000000000000000000000000000000000ba43b7400

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101f05760003560e01c806379cc67901161010f578063b67f0935116100a2578063dbb2348311610071578063dbb23483146108dd578063dd62ed3e14610916578063dfef99f614610951578063e2fbacdd14610987576101f0565b8063b67f0935146107c1578063bc27f2ec146107ee578063c4fb3c3e1461080b578063d528d8aa146108ae576101f0565b80639ed7ac70116100de5780639ed7ac7014610705578063a457c2d714610732578063a9059cbb1461076b578063b515f740146107a4576101f0565b806379cc67901461068d5780637b7e31b1146106c657806393bb8a01146106ce57806395d89b41146106fd576101f0565b8063313ce56711610187578063616d272f11610156578063616d272f1461059e57806367fd88d0146105dd5780636881df131461063d57806370a082311461065a576101f0565b8063313ce5671461045257806339509351146104705780634e167ed9146104a957806350fef38c14610581576101f0565b8063134b0fca116101c3578063134b0fca1461036657806318160ddd1461039557806323b872dd1461039d5780632fe82fe6146103e0576101f0565b8063023924c7146101f557806306fdde031461022a578063095ea7b3146102a757806309f2c019146102f4575b600080fd5b6102286004803603602081101561020b57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166109a4565b005b610232610a9b565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561026c578181015183820152602001610254565b50505050905090810190601f1680156102995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102e0600480360360408110156102bd57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610b4f565b604080519115158252519081900360200190f35b6103116004803603602081101561030a57600080fd5b5035610b6d565b6040805167ffffffffffffffff998a16815297891660208901529588168787015293871660608701529186166080860152851660a085015290931660c083015291151560e08201529051908190036101000190f35b6103836004803603602081101561037c57600080fd5b5035610cb2565b60408051918252519081900360200190f35b610383610cde565b6102e0600480360360608110156103b357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610ce4565b610429600480360360608110156103f657600080fd5b50803590602081013573ffffffffffffffffffffffffffffffffffffffff16906040013567ffffffffffffffff16610d8b565b6040805193845267ffffffffffffffff9283166020850152911682820152519081900360600190f35b61045a6113a1565b6040805160ff9092168252519081900360200190f35b6102e06004803603604081101561048657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356113aa565b610564600480360360408110156104bf57600080fd5b8101906020810181356401000000008111156104da57600080fd5b8201836020820111156104ec57600080fd5b8035906020019184602083028401116401000000008311171561050e57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505050903573ffffffffffffffffffffffffffffffffffffffff16915061140b9050565b6040805167ffffffffffffffff9092168252519081900360200190f35b6102286004803603602081101561059757600080fd5b503561159a565b610228600480360360808110156105b457600080fd5b5080359067ffffffffffffffff6020820135811691604081013590911690606001351515611a7a565b610616600480360360408110156105f357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611c4d565b6040805167ffffffffffffffff938416815291909216602082015281519081900390910190f35b6103836004803603602081101561065357600080fd5b5035611c9d565b6103836004803603602081101561067057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16611ced565b610228600480360360408110156106a357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611d15565b610383611de3565b6102e0600480360360808110156106e457600080fd5b5080359060208101359060408101359060600135611de9565b610232611ef5565b6103836004803603604081101561071b57600080fd5b508035906020013567ffffffffffffffff16611f74565b6102e06004803603604081101561074857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611fec565b6102e06004803603604081101561078157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612067565b6102e0600480360360208110156107ba57600080fd5b503561207b565b610564600480360360408110156107d757600080fd5b508035906020013567ffffffffffffffff1661251c565b6105646004803603602081101561080457600080fd5b5035612a72565b6105646004803603602081101561082157600080fd5b81019060208101813564010000000081111561083c57600080fd5b82018360208201111561084e57600080fd5b8035906020019184602083028401116401000000008311171561087057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612a8e945050505050565b6102e0600480360360808110156108c457600080fd5b5080359060208101359060408101359060600135612a9a565b610616600480360360408110156108f357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612bc8565b6103836004803603604081101561092c57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516612bff565b61096e6004803603602081101561096757600080fd5b5035612c37565b6040805192835260208301919091528051918290030190f35b6102286004803603602081101561099d57600080fd5b5035612d9d565b6109ad3361334d565b6109e85760405162461bcd60e51b815260040180806020018281038252602e8152602001806148dd602e913960400191505060405180910390fd5b60065473ffffffffffffffffffffffffffffffffffffffff1615610a3d5760405162461bcd60e51b815260040180806020018281038252602a815260200180614af6602a913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116610a8f5760405162461bcd60e51b81526004018080602001828103825260238152602001806149a16023913960400191505060405180910390fd5b610a988161338c565b50565b60038054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610b455780601f10610b1a57610100808354040283529160200191610b45565b820191906000526020600020905b815481529060010190602001808311610b2857829003601f168201915b5050505050905090565b6000610b63610b5c6133d3565b84846133d7565b5060015b92915050565b600080600080600080600080610b81614707565b506000898152600a60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484018590527001000000000000000000000000000000008304821695840186905278010000000000000000000000000000000000000000000000009092041660608301819052909b509199509197509550610c15614707565b50505060009788525050600b60209081526040968790208751608081018952905467ffffffffffffffff808216808452680100000000000000008304821694840185905270010000000000000000000000000000000083049091169983018a9052780100000000000000000000000000000000000000000000000090910460ff161515606090920182905296989597949693959394919391925090565b60008181526008602052604081205467ffffffffffffffff16610cd58382611f74565b9150505b919050565b60025490565b6000610cf18484846134ea565b610d8184610cfd6133d3565b610d7c856040518060600160405280602881526020016149526028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020526040812090610d486133d3565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff61369216565b6133d7565b5060019392505050565b6000806000610d9986610cb2565b92506000807f0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df01073ffffffffffffffffffffffffffffffffffffffff166326d6c97b896040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015610e0f57600080fd5b505afa158015610e23573d6000803e3d6000fd5b505050506040513d6080811015610e3957600080fd5b50805160409091015190925067ffffffffffffffff169050610e5a8861207b565b610e955760405162461bcd60e51b815260040180806020018281038252602f81526020018061484e602f913960400191505060405180910390fd5b610e9d614707565b506000858152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481169483019490945270010000000000000000000000000000000081048416928201929092527801000000000000000000000000000000000000000000000000909104821660608201529190610f319089168463ffffffff61372916565b90506000610f3e82611c9d565b9050826040015167ffffffffffffffff166000141580610f7e57507f0000000000000000000000000000000000000000000000000000000ba43b74008110155b610fb95760405162461bcd60e51b815260040180806020018281038252603a815260200180614a1d603a913960400191505060405180910390fd5b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015230602482015267ffffffffffffffff8b1660448201529051869173ffffffffffffffffffffffffffffffffffffffff8316916323b872dd916064808201926020929091908290030181600087803b15801561104057600080fd5b505af1158015611054573d6000803e3d6000fd5b505050506040513d602081101561106a57600080fd5b506000905061108083600a63ffffffff61378916565b73ffffffffffffffffffffffffffffffffffffffff8d1660009081526009602090815260408083208e845290915290208054919250906110d9906110d49067ffffffffffffffff168463ffffffff6137cb16565b613825565b81547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff9182161780835561112b916110d4916801000000000000000090048116908f166137cb565b815467ffffffffffffffff9190911668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781556111858d611180868563ffffffff61387216565b6138b4565b61118f30836138b4565b6007546111a2908663ffffffff6137cb16565b60075585516111c9906110d49067ffffffffffffffff908116908f1663ffffffff6137cb16565b67ffffffffffffffff908116875260408701516111f1916110d491168463ffffffff6137cb16565b67ffffffffffffffff908116604080890191825260008e8152600a60209081529181208a518154938c0151945160608d0151871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff918816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff97891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff949099167fffffffffffffffffffffffffffffffffffffffffffffffff0000000000000000909716969096179290921696909617949094169290921793909316919091179055611315858463ffffffff61387216565b90508d73ffffffffffffffffffffffffffffffffffffffff168f7f5a0def86b68ea53595ef32019b93a42eedf7c609407f51834703faa48bd592d08e848760405180848152602001838152602001828152602001935050505060405180910390a38b61138082613825565b61138985613825565b9b509b509b5050505050505050505093509350939050565b60055460ff1690565b6000610b636113b76133d3565b84610d7c85600160006113c86133d3565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff6137cb16565b600080805b84518110156114e657600061143886838151811061142a57fe5b6020026020010151866139d7565b90506114548367ffffffffffffffff831663ffffffff6137cb16565b925067ffffffffffffffff8116156114dd578473ffffffffffffffffffffffffffffffffffffffff1686838151811061148957fe5b60200260200101517fb931a8416f2f16d5400a0cce933872df77c3cfcadae032ff6b1646e8cdc12a3c83604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390a35b50600101611410565b50604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602481018390529051309163a9059cbb9160448083019260209291908290030181600087803b15801561155c57600080fd5b505af1158015611570573d6000803e3d6000fd5b505050506040513d602081101561158657600080fd5b50611592905081613825565b949350505050565b60065473ffffffffffffffffffffffffffffffffffffffff16611604576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b600061160f82610cb2565b905060008060007f0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df01073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561168757600080fd5b505afa15801561169b573d6000803e3d6000fd5b505050506040513d60808110156116b157600080fd5b5080516020820151604090920151909450909250905073ffffffffffffffffffffffffffffffffffffffff831661172f576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b67ffffffffffffffff811661178b576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b600080611796613b68565b9150915060006117bb838567ffffffffffffffff16846117b4613ca7565b8903611de9565b90508061180f576040805162461bcd60e51b815260206004820152601b60248201527f74686520534254206973206e6f7420696e20656d657267656e63790000000000604482015290519081900360640190fd5b6000611819614707565b50506000878152600a60209081526040918290208251608081018452905467ffffffffffffffff808216808452680100000000000000008304821694840194909452700100000000000000000000000000000000820481169483019490945278010000000000000000000000000000000000000000000000009004909216606083015290816118d257604081015167ffffffffffffffff16156118c4576118c48a6000806001613cab565b505050505050505050610a98565b506000888152600a6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560065481517f9da326ef000000000000000000000000000000000000000000000000000000008152600481018e905267ffffffffffffffff8616602482015260016044820152915173ffffffffffffffffffffffffffffffffffffffff90911693639da326ef93606480850194919392918390030190829087803b15801561199157600080fd5b505af11580156119a5573d6000803e3d6000fd5b505050506040513d60208110156119bb57600080fd5b5050600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051899283169163a9059cbb9160448083019260209291908290030181600087803b158015611a4257600080fd5b505af1158015611a56573d6000803e3d6000fd5b505050506040513d6020811015611a6c57600080fd5b505050505050505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff16611ae4576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff163314611b3a5760405162461bcd60e51b81526004018080602001828103825260238152602001806148ba6023913960400191505060405180910390fd5b60007f0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df01073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015611bad57600080fd5b505afa158015611bc1573d6000803e3d6000fd5b505050506040513d6080811015611bd757600080fd5b506040015167ffffffffffffffff16905080611c3a576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b611c4685858585613cab565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600960209081526040808320938352929052205467ffffffffffffffff80821692680100000000000000009092041690565b600060075460001415611cc357611cbc8261271063ffffffff61378916565b9050610cd9565b610b67600754611ce1611cd4610cde565b859063ffffffff61372916565b9063ffffffff61378916565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff16611d7f576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b60065473ffffffffffffffffffffffffffffffffffffffff163314611dd55760405162461bcd60e51b81526004018080602001828103825260238152602001806148ba6023913960400191505060405180910390fd5b611ddf828261438a565b5050565b60075490565b600082630bebc200811115611dff5750630bebc2005b626ebe008310611e13576001915050611592565b6000611e3584611e29848063ffffffff61372916565b9063ffffffff61372916565b905066072ba304f800008104600080611e4d83612c37565b915091506000611e5c8b6144c6565b90506000611e698b6144c6565b90506000611e8d611e80858463ffffffff61452616565b849063ffffffff61460916565b90506000611eb383611ea781818c8b63ffffffff61452616565b9063ffffffff61452616565b905060008083131580611ee2575081611edf680118188ff217800000611ea7868063ffffffff61452616565b13155b9f9e505050505050505050505050505050565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610b455780601f10610b1a57610100808354040283529160200191610b45565b6040805160208082019490945260c09290921b7fffffffffffffffff00000000000000000000000000000000000000000000000016828201527f6c69656e0000000000000000000000000000000000000000000000000000000060488301528051808303602c018152604c9092019052805191012090565b6000610b63611ff96133d3565b84610d7c85604051806060016040528060258152602001614b6660259139600160006120236133d3565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff61369216565b6000610b636120746133d3565b84846134ea565b60065460009073ffffffffffffffffffffffffffffffffffffffff166120e8576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b60008060007f0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df01073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561215e57600080fd5b505afa158015612172573d6000803e3d6000fd5b505050506040513d608081101561218857600080fd5b5080516020820151604090920151909450909250905073ffffffffffffffffffffffffffffffffffffffff8316612206576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b67ffffffffffffffff811661224c5760405162461bcd60e51b815260040180806020018281038252602a815260200180614752602a913960400191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000003f480612275613ca7565b0182116122b35760405162461bcd60e51b815260040180806020018281038252603c81526020018061479e603c913960400191505060405180910390fd5b620186a067ffffffffffffffff82160667ffffffffffffffff1660001461230b5760405162461bcd60e51b8152600401808060200182810382526022815260200180614b446022913960400191505060405180910390fd5b600654604080517fecfb314d00000000000000000000000000000000000000000000000000000000815260048101889052905160009273ffffffffffffffffffffffffffffffffffffffff169163ecfb314d916024808301926020929190829003018186803b15801561237d57600080fd5b505afa158015612391573d6000803e3d6000fd5b505050506040513d60208110156123a757600080fd5b5051600654604080517f9737d6fd00000000000000000000000000000000000000000000000000000000815260048101849052905192935073ffffffffffffffffffffffffffffffffffffffff90911691639737d6fd91602480820192602092909190829003018186803b15801561241e57600080fd5b505afa158015612432573d6000803e3d6000fd5b505050506040513d602081101561244857600080fd5b505167ffffffffffffffff16156124a6576040805162461bcd60e51b815260206004820152601860248201527f7468697320534254206973206f6e20612061756369746f6e0000000000000000604482015290519081900360640190fd5b6000806124b1613b68565b9150915060006124d6838667ffffffffffffffff16846124cf613ca7565b8a03612a9a565b604080518215815290519192508a917fea0241146eaea8e64956684a8df42cc134671b71fcc2b474bcbd63f30b32984f9181900360200190a21598975050505050505050565b60008061252884610cb2565b90506000807f0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df01073ffffffffffffffffffffffffffffffffffffffff166326d6c97b876040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561259e57600080fd5b505afa1580156125b2573d6000803e3d6000fd5b505050506040513d60808110156125c857600080fd5b50805160409091015190925067ffffffffffffffff16905073ffffffffffffffffffffffffffffffffffffffff8216612648576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b8061269a576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b6126a2614707565b506000838152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481168386015270010000000000000000000000000000000082048116838501527801000000000000000000000000000000000000000000000000909104166060808301919091528251908101909252603d808352909392612790926110d492879261487d9083013961278361274b610cde565b6040518060600160405280602c8152602001614822602c91396127836007548f67ffffffffffffffff1661372990919063ffffffff16565b919063ffffffff61466e16565b90506127c06110d48867ffffffffffffffff16846060015167ffffffffffffffff166137cb90919063ffffffff16565b67ffffffffffffffff90811660608401526127de903390891661438a565b604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015267ffffffffffffffff831660248201529051859173ffffffffffffffffffffffffffffffffffffffff83169163a9059cbb916044808201926020929091908290030181600087803b15801561285f57600080fd5b505af1158015612873573d6000803e3d6000fd5b505050506040513d602081101561288957600080fd5b50506040805167ffffffffffffffff808b16825284166020820152815133928c927f87efbe374e86e4f26b4593306372ef7f3c1fa4ed256c9d4f7400d00b3f729114929081900390910190a36129016128f267ffffffffffffffff84168663ffffffff61372916565b6007549063ffffffff61387216565b6007558251612928906110d49067ffffffffffffffff90811690851663ffffffff61387216565b67ffffffffffffffff90811684526020840151612953916110d491811690851663ffffffff6137cb16565b67ffffffffffffffff90811660208086019182526000988952600a905260409788902085518154925199870151606090970151841678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff978516700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9b861668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff939096167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009095169490941791909116939093179890981617939093169290921790945550919250505092915050565b60086020526000908152604090205467ffffffffffffffff1681565b6000610b67823361140b565b60006002850261c3508502108015612ab457506212750082105b15612ac157506000611592565b630bebc200831115612ad557506001611592565b626ebe008210612ae757506001611592565b6000612afd83611e29868063ffffffff61372916565b905066072ba304f800008104600080612b1583612c37565b915091506000612b248a6144c6565b90506000612b318a6144c6565b90506000612b6a612b4d6003611ea7878663ffffffff61452616565b612b5e85600263ffffffff61452616565b9063ffffffff61460916565b90506000612b876009611ea7858181818e8d63ffffffff61452616565b905060008083131580612bb6575081612bb3680118188ff217800000611ea7868063ffffffff61452616565b13155b9e9d5050505050505050505050505050565b600960209081526000928352604080842090915290825290205467ffffffffffffffff808216916801000000000000000090041682565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60008062c320408311612c51575060009050612af8612d98565b630394b7b18311612c6a5750615a4090506115bc612d98565b6307f7cae48311612ca257506206400090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81fc612d98565b630bf379008311612cda5750621f126990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1e88612d98565b630fc0bf018311612d12575062817ac190507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffae894612d98565b63134fd9008311612d4b57506301af0c8990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f33b612d98565b6040805162461bcd60e51b815260206004820152600e60248201527f6e6f742061636365707461626c65000000000000000000000000000000000000604482015290519081900360640190fd5b915091565b60065473ffffffffffffffffffffffffffffffffffffffff16612e07576040805162461bcd60e51b815260206004820152601f60248201527f7468652061756374696f6e20636f6e7472616374206973206e6f742073657400604482015290519081900360640190fd5b6000612e1282610cb2565b905060008060007f0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df01073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015612e8a57600080fd5b505afa158015612e9e573d6000803e3d6000fd5b505050506040513d6080811015612eb457600080fd5b5080516020820151604090920151909450909250905073ffffffffffffffffffffffffffffffffffffffff8316612f32576040805162461bcd60e51b815260206004820152601a60248201527f74686520626f6e64206973206e6f742072656769737465726564000000000000604482015290519081900360640190fd5b67ffffffffffffffff8116612f8e576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b7f000000000000000000000000000000000000000000000000000000000003f480612fb7613ca7565b01821115612ff65760405162461bcd60e51b815260040180806020018281038252602e815260200180614ac8602e913960400191505060405180910390fd5b6000613000614707565b50506000848152600a60209081526040918290208251608081018452905467ffffffffffffffff808216808452680100000000000000008304821694840194909452700100000000000000000000000000000000820481169483019490945278010000000000000000000000000000000000000000000000009004909216606083015290816130b657604081015167ffffffffffffffff16156130ab576130ab876000806001613cab565b505050505050610a98565b506000858152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690557f0000000000000000000000000000000000000000000000000000000000015f90613114613ca7565b0183116131d857600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810189905267ffffffffffffffff8416602482015260016044820152905173ffffffffffffffffffffffffffffffffffffffff90921691639da326ef916064808201926020929091908290030181600087803b1580156131a657600080fd5b505af11580156131ba573d6000803e3d6000fd5b505050506040513d60208110156131d057600080fd5b506132939050565b600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810189905267ffffffffffffffff84166024820152600060448201819052915173ffffffffffffffffffffffffffffffffffffffff90931692639da326ef92606480840193602093929083900390910190829087803b15801561326657600080fd5b505af115801561327a573d6000803e3d6000fd5b505050506040513d602081101561329057600080fd5b50505b600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051869283169163a9059cbb9160448083019260209291908290030181600087803b15801561331857600080fd5b505af115801561332c573d6000803e3d6000fd5b505050506040513d602081101561334257600080fd5b505050505050505050565b7f00000000000000000000000039a5bbc3f5536d7a9f40acfcb34738ff29540f4973ffffffffffffffffffffffffffffffffffffffff90811691161490565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3390565b73ffffffffffffffffffffffffffffffffffffffff83166134295760405162461bcd60e51b8152600401808060200182810382526024815260200180614a7c6024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661347b5760405162461bcd60e51b81526004018080602001828103825260228152602001806147da6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff831661353c5760405162461bcd60e51b8152600401808060200182810382526025815260200180614a576025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821661358e5760405162461bcd60e51b815260040180806020018281038252602381526020018061472f6023913960400191505060405180910390fd5b6135998383836146d3565b6135e9816040518060600160405280602681526020016147fc6026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054919063ffffffff61369216565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461362b908263ffffffff6137cb16565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156137215760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156136e65781810151838201526020016136ce565b50505050905090810190601f1680156137135780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008261373857506000610b67565b8282028284828161374557fe5b04146137825760405162461bcd60e51b815260040180806020018281038252602181526020018061490b6021913960400191505060405180910390fd5b9392505050565b600061378283836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061466e565b600082820183811015613782576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600068010000000000000000821061386e5760405162461bcd60e51b815260040180806020018281038252602681526020018061492c6026913960400191505060405180910390fd5b5090565b600061378283836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613692565b73ffffffffffffffffffffffffffffffffffffffff821661391c576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b613928600083836146d3565b60025461393b908263ffffffff6137cb16565b60025573ffffffffffffffffffffffffffffffffffffffff8216600090815260208190526040902054613974908263ffffffff6137cb16565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b60006139e1614707565b506000838152600b60209081526040918290208251608081018452905467ffffffffffffffff80821683526801000000000000000082048116938301939093527001000000000000000000000000000000008104909216928101929092527801000000000000000000000000000000000000000000000000900460ff16151560608201819052613a75576000915050610b67565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260096020818152604080842088855290915280832080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081169091559084015167ffffffffffffffff808316946801000000000000000090930481169391169190613afe908590613729565b613b166305f5e100611ce1858763ffffffff61372916565b1115613b4957613b2d84600963ffffffff61372916565b613b456305f5e100611ce1858763ffffffff61372916565b0390505b613b5c6110d4828663ffffffff6146d816565b98975050505050505050565b600080600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3e6ba946040518163ffffffff1660e01b8152600401602060405180830381600087803b158015613bd557600080fd5b505af1158015613be9573d6000803e3d6000fd5b505050506040513d6020811015613bff57600080fd5b5051600554604080517f3af2888b000000000000000000000000000000000000000000000000000000008152905192945061010090910473ffffffffffffffffffffffffffffffffffffffff1691633af2888b916004808201926020929091908290030181600087803b158015613c7557600080fd5b505af1158015613c89573d6000803e3d6000fd5b505050506040513d6020811015613c9f57600080fd5b505190509091565b4290565b6000613cb685610cb2565b9050613cc0614707565b506000818152600b60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484019490945270010000000000000000000000000000000082048116948301949094527801000000000000000000000000000000000000000000000000900460ff161515606082015291613d54916110d49187166137cb565b67ffffffffffffffff90811682526020820151613d7f916110d491811690881663ffffffff6137cb16565b67ffffffffffffffff166020820152821561427257613d9c614707565b506000828152600a602090815260408083208151608081018352905467ffffffffffffffff8082168352680100000000000000008204811694830194909452700100000000000000000000000000000000810484169282018390527801000000000000000000000000000000000000000000000000900490921660608301529091908190613e3190600963ffffffff61372916565b90506000613e5682856040015167ffffffffffffffff166137cb90919063ffffffff16565b90506000613e89866020015167ffffffffffffffff16866060015167ffffffffffffffff166137cb90919063ffffffff16565b905082811115613ee957808210613ec1576060850151613eba90839067ffffffffffffffff1663ffffffff61387216565b9350613ee4565b6060850151613ee190829067ffffffffffffffff1663ffffffff61387216565b93505b613f1b565b613f18866020015167ffffffffffffffff16866040015167ffffffffffffffff166137cb90919063ffffffff16565b93505b50505060007f0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df01073ffffffffffffffffffffffffffffffffffffffff166326d6c97b8a6040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015613f9157600080fd5b505afa158015613fa5573d6000803e3d6000fd5b505050506040513d6080811015613fbb57600080fd5b50604001519050613fcc308361438a565b613ffe6110d4856020015167ffffffffffffffff16856060015167ffffffffffffffff166137cb90919063ffffffff16565b67ffffffffffffffff9081166060850152845161402e9161402991811690841663ffffffff61372916565b6146ee565b83516020840151614056916110d49167ffffffffffffffff908116911663ffffffff6137cb16565b67ffffffffffffffff166020808501829052604080516060810190915260388082526140ae936110d493909291906149c49083013960608701516127839067ffffffffffffffff166305f5e10063ffffffff61372916565b67ffffffffffffffff90811660408087019190915260016060870181905260008c8152600860205291909120546140f1926110d49291169063ffffffff6137cb16565b60008a8152600860209081526040808320805467ffffffffffffffff9586167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000091821617909155898452600a835281842088518154948a0151938a015160608b0151881678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff918916700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff968a1668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff94909a169790951696909617919091169690961792909216179390931617909155614218610cde565b604080870151600754825167ffffffffffffffff90921682526020820184905281830152905191925087917fc96942e0138bef71dbf15b3512ad2970a8a07aeea02f0c50a94d373906dbf4cb9181900360600190a2505050505b6000918252600b60209081526040928390208251815492840151948401516060909401517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090931667ffffffffffffffff918216177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000095821695909502949094177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000009490931693909302919091177fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009115159190910217905550505050565b73ffffffffffffffffffffffffffffffffffffffff82166143dc5760405162461bcd60e51b81526004018080602001828103825260218152602001806149fc6021913960400191505060405180910390fd5b6143e8826000836146d3565b6144388160405180606001604052806022815260200161477c6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040902054919063ffffffff61369216565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902055600254614471908263ffffffff61387216565b60025560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60007f8000000000000000000000000000000000000000000000000000000000000000821061386e5760405162461bcd60e51b8152600401808060200182810382526028815260200180614aa06028913960400191505060405180910390fd5b60008261453557506000610b67565b827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14801561458357507f800000000000000000000000000000000000000000000000000000000000000082145b156145bf5760405162461bcd60e51b815260040180806020018281038252602781526020018061497a6027913960400191505060405180910390fd5b828202828482816145cc57fe5b05146137825760405162461bcd60e51b815260040180806020018281038252602781526020018061497a6027913960400191505060405180910390fd5b600081830381831280159061461e5750838113155b80614633575060008312801561463357508381135b6137825760405162461bcd60e51b8152600401808060200182810382526024815260200180614b206024913960400191505060405180910390fd5b600081836146bd5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156136e65781810151838201526020016136ce565b5060008385816146c957fe5b0495945050505050565b505050565b60008183106146e75781613782565b5090919050565b600754614701908263ffffffff61387216565b60075550565b6040805160808101825260008082526020820181905291810182905260608101919091529056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737374686520626f6e6420646f6573206e6f74206d6174636820746f2074686520666f726d206f662053425445524332303a206275726e20616d6f756e7420657863656564732062616c616e636561207265717565737420746f20686f6c6420616e2061756374696f6e206f662074686520626f6e642068617320616c7265616479206578706972656445524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636573797374656d206572726f723a20746f74616c537570706c79206e65766572206265636f6d6573207a65726f53425420776974682074686520626f6e644944206973206e6f742063757272656e746c792061636365707461626c6573797374656d206572726f723a20736f6c6964537472696b655072696365206e65766572206265636f6d6573207a65726f205b756e6c6f636b5342545d6d73672e73656e646572206d7573742062652061756374696f6e20636f6e74726163746f6e6c79206465706c6f79657220697320616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e203634206269747345524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77636f6e74726163742073686f756c64206265206e6f6e2d7a65726f206164647265737373797374656d3a2074686520746f74616c20756e6c6f636b20616d6f756e742073686f756c64206265206e6f6e2d7a65726f2076616c756545524332303a206275726e2066726f6d20746865207a65726f20616464726573736d696e7420616d6f756e74206e65656420746f2062652067726561746572207468616e203530302069646f6c20666f72207468697320626f6e6445524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737353616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235366d61747572697479206973206c61746572207468616e2074686520726567756c61722061756374696f6e5370616e7468652061756374696f6e20636f6e747261637420697320616c726561647920726567697374657265645369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f7774686520737472696b65207072696365206e65656420746f20626520242031302a5845524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220d085672f8467497f59973194f9b1d4d97c7592939b63afb78bc9add4e0e727e664736f6c63430006060033

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

000000000000000000000000120a078fdc516a1a98bbecb9e961f8741ac7ac820000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df010000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000000000000000000000000000000000000015f900000000000000000000000000000000000000000000000000000000ba43b7400

-----Decoded View---------------
Arg [0] : oracleAddress (address): 0x120a078FdC516A1A98bbecb9e961F8741AC7ac82
Arg [1] : bondMakerAddress (address): 0x8B24F5C764AB741Bc8a2426505BDa458C30dF010
Arg [2] : auctionSpan (uint256): 259200
Arg [3] : emergencyAuctionSpan (uint256): 90000
Arg [4] : mintIDOLAmountBorder (uint256): 50000000000

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000120a078fdc516a1a98bbecb9e961f8741ac7ac82
Arg [1] : 0000000000000000000000008b24f5c764ab741bc8a2426505bda458c30df010
Arg [2] : 000000000000000000000000000000000000000000000000000000000003f480
Arg [3] : 0000000000000000000000000000000000000000000000000000000000015f90
Arg [4] : 0000000000000000000000000000000000000000000000000000000ba43b7400


Deployed Bytecode Sourcemap

100095:28022:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;100095:28022:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;99488:395:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;99488:395:0;;;;:::i;:::-;;24899:83;;;:::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;24899:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27005:169;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;27005:169:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;110080:1293;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;110080:1293:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;111720:262;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;111720:262:0;;:::i;:::-;;;;;;;;;;;;;;;;25974:100;;;:::i;27648:321::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;27648:321:0;;;;;;;;;;;;;;;;;;:::i;114254:2635::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;114254:2635:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25826:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;28378:218;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;28378:218:0;;;;;;;;;:::i;127132:792::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;127132:792:0;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;127132:792:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;127132:792:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;127132:792:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;127132:792:0;;-1:-1:-1;;;127132:792:0;;;;;-1:-1:-1;127132:792:0;;-1:-1:-1;127132:792:0:i;:::-;;;;;;;;;;;;;;;;;;;122626:1817;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;122626:1817:0;;:::i;124607:640::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;124607:640:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;111990:284::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;111990:284:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;125445:333;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;125445:333:0;;:::i;26137:119::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;26137:119:0;;;;:::i;117033:301::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;117033:301:0;;;;;;;;;:::i;111381:113::-;;;:::i;37553:1063::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;37553:1063:0;;;;;;;;;;;;;;;;;:::i;25101:87::-;;;:::i;111502:210::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;111502:210:0;;;;;;;;;:::i;29099:269::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;29099:269:0;;;;;;;;;:::i;26469:175::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;26469:175:0;;;;;;;;;:::i;112661:1410::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;112661:1410:0;;:::i;118286:2051::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;118286:2051:0;;;;;;;;;:::i;100816:53::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;100816:53:0;;:::i;127932:182::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;127932:182:0;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;127932:182:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;127932:182:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;127932:182:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;127932:182:0;;-1:-1:-1;127932:182:0;;-1:-1:-1;;;;;127932:182:0:i;39119:1780::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;39119:1780:0;;;;;;;;;;;;;;;;;:::i;101191:70::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;101191:70:0;;;;;;;;;:::i;26707:151::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;26707:151:0;;;;;;;;;;;:::i;36483:703::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;36483:703:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;120431:1914;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;120431:1914:0;;:::i;99488:395::-;98724:23;98736:10;98724:11;:23::i;:::-;98702:119;;;;-1:-1:-1;;;98702:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99602:16:::1;::::0;99594:39:::1;99602:16;99594:39:::0;99572:131:::1;;;;-1:-1:-1::0;;;99572:131:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99736:29;::::0;::::1;99714:114;;;;-1:-1:-1::0;;;99714:114:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99839:36;99859:15;99839:19;:36::i;:::-;99488:395:::0;:::o;24899:83::-;24969:5;24962:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24936:13;;24962:12;;24969:5;;24962:12;;24969:5;24962:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24899:83;:::o;27005:169::-;27088:4;27105:39;27114:12;:10;:12::i;:::-;27128:7;27137:6;27105:8;:39::i;:::-;-1:-1:-1;27162:4:0;27005:169;;;;;:::o;110080:1293::-;110199:21;110235:23;110273:26;110314:22;110351:28;110394:29;110438:33;110486:29;110549:41;;:::i;:::-;-1:-1:-1;110603:28:0;;;;:20;:28;;;;;;;;;110549:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;110549:82:0;;-1:-1:-1;110549:82:0;;-1:-1:-1;110549:82:0;-1:-1:-1;110918:46:0;;:::i;:::-;-1:-1:-1;;;110977:26:0;;;;-1:-1:-1;;110977:18:0;:26;;;;;;;;;110918:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110080:1293;;;;;;;;110918:85;;;;;;-1:-1:-1;110918:85:0;110080:1293::o;111720:262::-;111828:7;111884:27;;;:19;:27;;;;;;;;111929:45;111904:6;111884:27;111929:14;:45::i;:::-;111922:52;;;111720:262;;;;:::o;25974:100::-;26054:12;;25974:100;:::o;27648:321::-;27754:4;27771:36;27781:6;27789:9;27800:6;27771:9;:36::i;:::-;27818:121;27827:6;27835:12;:10;:12::i;:::-;27849:89;27887:6;27849:89;;;;;;;;;;;;;;;;;:19;;;;;;;:11;:19;;;;;;27869:12;:10;:12::i;:::-;27849:33;;;;;;;;;;;;;-1:-1:-1;27849:33:0;;;:89;;:37;:89;:::i;:::-;27818:8;:121::i;:::-;-1:-1:-1;27957:4:0;27648:321;;;;;:::o;114254:2635::-;114424:14;114453:25;114493:23;114553:24;114570:6;114553:16;:24::i;:::-;114544:33;;114686:24;114740:26;114783:18;:26;;;114810:6;114783:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;114783:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;114783:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;114783:34:0;;;;;;;;;-1:-1:-1;114671:146:0;;;-1:-1:-1;114850:23:0;114866:6;114850:15;:23::i;:::-;114828:120;;;;-1:-1:-1;;;114828:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;114967:41;;:::i;:::-;-1:-1:-1;115021:28:0;;;;:20;:28;;;;;;;;114967:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;115021:28;115157:36;;:16;;115174:18;115157:36;:16;:36;:::i;:::-;115129:64;;115204:20;115227:31;115240:17;115227:12;:31::i;:::-;115204:54;;115291:14;:36;;;:41;;115331:1;115291:41;;:101;;;;115369:23;115353:12;:39;;115291:101;115269:209;;;;-1:-1:-1;;;115269:209:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;115551:71;;;;;;115582:10;115551:71;;;;115602:4;115551:71;;;;;;;;;;;;;115523:16;;115551:30;;;;;;:71;;;;;;;;;;;;;;;115491:23;115551:30;:71;;;2:2:-1;;;;27:1;24;17:12;2:2;115551:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;115551:71:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;115723:18:0;;-1:-1:-1;115744:20:0;:12;115761:2;115744:20;:16;:20;:::i;:::-;115811:23;;;115775:33;115811:23;;;:12;:23;;;;;;;;:31;;;;;;;;115881:39;;115723:41;;-1:-1:-1;115811:31:0;115881:94;;:69;;:39;;115723:41;115881:69;:57;:69;:::i;:::-;:92;:94::i;:::-;115853:122;;;;;;;;;;;;116017:99;;:74;;:42;;;;;;:74;;:60;:74::i;:99::-;115986:130;;;;;;;;;;;;;;;;116129:46;116135:9;116146:28;:12;116163:10;116146:28;:16;:28;:::i;:::-;116129:5;:46::i;:::-;116186:32;116200:4;116207:10;116186:5;:32::i;:::-;116251:19;;:42;;116275:17;116251:42;:23;:42;:::i;:::-;116229:19;:64;116344:51;;:108;;:83;;;:69;;;;:83;;;:69;:83;:::i;:108::-;116304:148;;;;;;116502:50;;;;:105;;:80;;:68;116571:10;116502:80;:68;:80;:::i;:105::-;116463:144;;;;:36;;;;:144;;;116618:28;;;;:20;:28;;;;;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116699:28;:12;116716:10;116699:28;:16;:28;:::i;:::-;116676:51;;116763:9;116743:64;;116755:6;116743:64;116774:6;116782:12;116796:10;116743:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;116826:6;116834:23;:12;:21;:23::i;:::-;116859:21;:10;:19;:21::i;:::-;116818:63;;;;;;;;;;;;;;;114254:2635;;;;;;;:::o;25826:83::-;25892:9;;;;25826:83;:::o;28378:218::-;28466:4;28483:83;28492:12;:10;:12::i;:::-;28506:7;28515:50;28554:10;28515:11;:25;28527:12;:10;:12::i;:::-;28515:25;;;;;;;;;;;;;;;;;;-1:-1:-1;28515:25:0;;;:34;;;;;;;;;;;:50;:38;:50;:::i;127132:792::-;127255:6;;;127321:490;127345:7;:14;127341:1;:18;127321:490;;;127469:21;127493:95;127537:7;127545:1;127537:10;;;;;;;;;;;;;;127566:7;127493:25;:95::i;:::-;127469:119;-1:-1:-1;127625:39:0;:19;:39;;;;:23;:39;:::i;:::-;127603:61;-1:-1:-1;127683:19:0;;;;127679:121;;127760:7;127728:56;;127748:7;127756:1;127748:10;;;;;;;;;;;;;;127728:56;127769:14;127728:56;;;;;;;;;;;;;;;;;;;;;;127679:121;-1:-1:-1;127361:3:0;;127321:490;;;-1:-1:-1;127823:43:0;;;;;;:13;:43;;;;;;;;;;;;;;:4;;:13;;:43;;;;;;;;;;;;;;-1:-1:-1;127823:4:0;:43;;;2:2:-1;;;;27:1;24;17:12;2:2;127823:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;127823:43:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;127886:30:0;;-1:-1:-1;127886:19:0;:28;:30::i;:::-;127879:37;127132:792;-1:-1:-1;;;;127132:792:0:o;122626:1817::-;99268:16;;99260:39;99268:16;99238:120;;;;;-1:-1:-1;;;99238:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;122757:14:::1;122774:24;122791:6;122774:16;:24::i;:::-;122757:41;;122824:24;122863:16:::0;122894:30:::1;122941:18;:26;;;122968:6;122941:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;122941:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;122941:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29::::0;22:12:::1;4:2;-1:-1:::0;122941:34:0;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;122941:34:0;;-1:-1:-1;122941:34:0;-1:-1:-1;122994:30:0::1;::::0;::::1;122986:69;;;::::0;;-1:-1:-1;;;122986:69:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;123088:28;::::0;::::1;123066:109;;;::::0;;-1:-1:-1;;;123066:109:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;123189:19;123210:18:::0;123232:16:::1;:14;:16::i;:::-;123188:60;;;;123259:13;123275:162;123303:11;123329:23;123275:162;;123367:10;123403:23;:21;:23::i;:::-;123392:8;:34;123275:13;:162::i;:::-;123259:178;;123456:8;123448:48;;;::::0;;-1:-1:-1;;;123448:48:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;123509:29;123570:41;;:::i;:::-;-1:-1:-1::0;;123628:28:0::1;::::0;;;:20:::1;:28;::::0;;;;;;;;123570:86;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;;::::1;::::0;;;;;123752:27;123748:232:::1;;123804:36;::::0;::::1;::::0;:41:::1;;::::0;123800:140:::1;;123870:50;123901:6;123909:1;123912::::0;123915:4:::1;123870:30;:50::i;:::-;123958:7;;;;;;;;;;;123748:232;-1:-1:-1::0;124001:28:0::1;::::0;;;:20:::1;:28;::::0;;;;;;;123994:58;;;::::1;::::0;;124076:16:::1;::::0;:67;;;;;::::1;::::0;::::1;::::0;;;123994:58:::1;124076:67:::0;::::1;::::0;;;;123994:58;124076:67;;;;;;:16:::1;::::0;;::::1;::::0;:29:::1;::::0;:67;;;;;124001:28;;124076:67;;;;;;;;;:16;:67;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;124076:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;124076:67:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;;124370:16:0::1;::::0;124321:114:::1;::::0;;;;;:26:::1;124370:16:::0;;::::1;124321:114;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;;124282:16;;124321:26;::::1;::::0;::::1;::::0;:114;;;;;124076:67:::1;::::0;124321:114;;;;;;;124202:36:::1;124321:26:::0;:114;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;124321:114:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;124321:114:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;;;;;;;;;;;122626:1817:0;:::o;124607:640::-;99268:16;;99260:39;99268:16;99238:120;;;;;-1:-1:-1;;;99238:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;124855:16:::1;::::0;::::1;;124833:10;:39;124811:124;;;;-1:-1:-1::0;;;124811:124:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124953:24;124983:18;:26;;;125010:6;124983:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;124983:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;124983:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29::::0;22:12:::1;4:2;-1:-1:::0;124983:34:0;;;124948:69:::1;;::::0;-1:-1:-1;125036:21:0;125028:65:::1;;;::::0;;-1:-1:-1;;;125028:65:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;125104:135;125149:6;125170:13;125198:9;125222:6;125104:30;:135::i;:::-;99369:1;124607:640:::0;;;;:::o;111990:284::-;112163:18;;;;;112109:6;112163:18;;;:12;:18;;;;;;;;:26;;;;;;;:37;;;;;;112215:40;;;;;;111990:284::o;125445:333::-;125560:20;125602:19;;125625:1;125602:24;125598:92;;;125650:28;:17;125672:5;125650:28;:21;:28;:::i;:::-;125643:35;;;;125598:92;125709:61;125750:19;;125709:36;125731:13;:11;:13::i;:::-;125709:17;;:36;:21;:36;:::i;:::-;:40;:61;:40;:61;:::i;26137:119::-;26230:18;;26203:7;26230:18;;;;;;;;;;;;26137:119::o;117033:301::-;99268:16;;99260:39;99268:16;99238:120;;;;;-1:-1:-1;;;99238:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;117213:16:::1;::::0;::::1;;117191:10;:39;117169:124;;;;-1:-1:-1::0;;;117169:124:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;117304:22;117310:7;117319:6;117304:5;:22::i;:::-;117033:301:::0;;:::o;111381:113::-;111467:19;;111381:113;:::o;37553:1063::-;37734:4;37765:10;37796:9;37790:15;;37786:94;;;-1:-1:-1;37828:9:0;37786:94;37911:8;37894:13;:25;37890:111;;37943:4;37936:11;;;;;37890:111;38011:14;38028:31;38045:13;38028:12;38036:3;;38028:12;:7;:12;:::i;:::-;:16;:31;:16;:31;:::i;:::-;38011:48;-1:-1:-1;38097:24:0;38087:35;;38072:12;;38196:28;38087:35;38196:22;:28::i;:::-;38168:56;;;;38235:10;38248:22;:11;:20;:22::i;:::-;38235:35;;38281:10;38294:31;:20;:29;:31::i;:::-;38281:44;-1:-1:-1;38336:10:0;38349:21;38357:12;:3;38281:44;38357:12;:7;:12;:::i;:::-;38349:3;;:21;:7;:21;:::i;:::-;38336:34;-1:-1:-1;38444:11:0;38458:42;38496:3;38458:33;38496:3;38458:33;38465:6;38477:4;38458:24;:18;:24;:::i;:::-;:28;:33;:28;:33;:::i;:42::-;38444:56;;38511:13;38534:1;38527:3;:8;;:55;;;-1:-1:-1;38578:4:0;38539:35;38556:17;38539:12;38547:3;;38539:12;:7;:12;:::i;:35::-;:43;;38527:55;38511:71;37553:1063;-1:-1:-1;;;;;;;;;;;;;;;37553:1063:0:o;25101:87::-;25173:7;25166:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25140:13;;25166:14;;25173:7;;25166:14;;25173:7;25166:14;;;;;;;;;;;;;;;;;;;;;;;;111502:210;111664:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;111664:39:0;;;;;;111654:50;;;;;;111502:210::o;29099:269::-;29192:4;29209:129;29218:12;:10;:12::i;:::-;29232:7;29241:96;29280:15;29241:96;;;;;;;;;;;;;;;;;:11;:25;29253:12;:10;:12::i;:::-;29241:25;;;;;;;;;;;;;;;;;;-1:-1:-1;29241:25:0;;;:34;;;;;;;;;;;:96;;:38;:96;:::i;26469:175::-;26555:4;26572:42;26582:12;:10;:12::i;:::-;26596:9;26607:6;26572:9;:42::i;112661:1410::-;99268:16;;112806:4;;99260:39;99268:16;99238:120;;;;;-1:-1:-1;;;99238:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;112843:24:::1;112882:16:::0;112913:25:::1;112955:18;:26;;;112982:6;112955:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;112955:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;112955:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29::::0;22:12:::1;4:2;-1:-1:::0;112955:34:0;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;112955:34:0;;-1:-1:-1;112955:34:0;-1:-1:-1;113008:30:0::1;::::0;::::1;113000:69;;;::::0;;-1:-1:-1;;;113000:69:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;113102:23;::::0;::::1;113080:115;;;;-1:-1:-1::0;;;113080:115:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113265:12;113239:23;:21;:23::i;:::-;:38;113228:8;:49;113206:159;;;;-1:-1:-1::0;;;113206:159:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113420:5;113398:28;::::0;::::1;;:33;;113430:1;113398:33;113376:117;;;;-1:-1:-1::0;;;113376:117:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113526:16;::::0;:44:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;113506:17:::1;::::0;113526:16:::1;;::::0;:36:::1;::::0;:44;;;;;::::1;::::0;;;;;;;;:16;:44;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;113526:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;113526:44:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;113526:44:0;113603:16:::1;::::0;:50:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;113526:44;;-1:-1:-1;113603:16:0::1;::::0;;::::1;::::0;:39:::1;::::0;:50;;;;;113526:44:::1;::::0;113603:50;;;;;;;;:16;:50;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;113603:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;113603:50:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;113603:50:0;:55:::1;;::::0;113581:129:::1;;;::::0;;-1:-1:-1;;;113581:129:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;113724:21;113747:20:::0;113771:16:::1;:14;:16::i;:::-;113723:64;;;;113798:13;113814:165;113846:13;113874:18;113814:165;;113907:12;113945:23;:21;:23::i;:::-;113934:8;:34;113814:17;:165::i;:::-;113997:37;::::0;;114024:9;::::1;113997:37:::0;;;;113798:181;;-1:-1:-1;114016:6:0;;113997:37:::1;::::0;;;;::::1;::::0;;::::1;114054:9;::::0;112661:1410;-1:-1:-1;;;;;;;;112661:1410:0:o;118286:2051::-;118394:6;118418:14;118435:24;118452:6;118435:16;:24::i;:::-;118418:41;;118485:24;118539:26;118582:18;:26;;;118609:6;118582:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;118582:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;118582:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;118582:34:0;;;;;;;;;-1:-1:-1;118470:146:0;;;-1:-1:-1;118635:30:0;;;118627:69;;;;;-1:-1:-1;;;118627:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;118715:23;118707:67;;;;;-1:-1:-1;;;118707:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;118791:41;;:::i;:::-;-1:-1:-1;118845:28:0;;;;:20;:28;;;;;;;;118791:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;118907:272;;;;;;;;;;;;118791:82;;118845:28;118907:297;;:272;;119072:18;;118907:272;;;;;:132;118977:13;:11;:13::i;:::-;118907:132;;;;;;;;;;;;;;;;;:51;118938:19;;118907:12;:30;;;;:51;;;;:::i;:::-;:69;:132;;:69;:132;:::i;:297::-;118886:318;;119279:107;:82;119348:12;119279:82;;:14;:50;;;:68;;;;:82;;;;:::i;:107::-;119240:146;;;;:36;;;:146;119399:31;;119405:10;;119399:31;;:5;:31::i;:::-;119586:51;;;;;;119613:10;119586:51;;;;;;;;;;;;;119547:16;;119586:26;;;;;;:51;;;;;;;;;;;;;;;119467:36;119586:26;:51;;;2:2:-1;;;;27:1;24;17:12;2:2;119586:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;119586:51:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;119655:58:0;;;;;;;;;;;119586:51;119655:58;;;;;119675:10;;119667:6;;119655:58;;;;;;;;;;;119836:84;119874:35;:15;;;119890:18;119874:35;:15;:35;:::i;:::-;119836:19;;;:84;:23;:84;:::i;:::-;119814:19;:106;119971:51;;:107;;:82;;;:69;;;;:82;;;:69;:82;:::i;:107::-;119931:147;;;;;;120131:53;;;;:109;;:84;;:71;;;:84;;;:71;:84;:::i;:109::-;120089:151;;;;:39;;;;:151;;;120253:28;;;;:20;:28;;;;;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;120318:11:0;;-1:-1:-1;;;118286:2051:0;;;;:::o;100816:53::-;;;;;;;;;;;;;;;:::o;127932:182::-;128036:6;128067:39;128086:7;128095:10;128067:18;:39::i;39119:1780::-;39304:4;39388:1;39374:15;;39339:32;;;:50;:90;;;;;39422:7;39406:13;:23;39339:90;39321:262;;;-1:-1:-1;39463:5:0;39456:12;;39321:262;39503:9;39490:10;:22;39486:97;;;-1:-1:-1;39536:4:0;39529:11;;39486:97;39614:8;39597:13;:25;39593:111;;-1:-1:-1;39646:4:0;39639:11;;39593:111;39714:14;39731:45;39762:13;39731:26;39746:10;;39731:26;:14;:26;:::i;:45::-;39714:62;-1:-1:-1;39814:24:0;39804:35;;39789:12;;39913:28;39804:35;39913:22;:28::i;:::-;39885:56;;;;40497:10;40510:22;:11;:20;:22::i;:::-;40497:35;;40543:10;40556:31;:20;:29;:31::i;:::-;40543:44;-1:-1:-1;40598:10:0;40611:35;40626:19;40643:1;40626:12;:3;40543:44;40626:12;:7;:12;:::i;:19::-;40611:10;:3;40619:1;40611:10;:7;:10;:::i;:::-;:14;:35;:14;:35;:::i;:::-;40598:48;-1:-1:-1;40720:11:0;40734:49;40781:1;40734:42;40772:3;40734:42;40772:3;40734:42;40741:6;40753:4;40734:24;:18;:24;:::i;:49::-;40720:63;;40794:13;40817:1;40810:3;:8;;:55;;;-1:-1:-1;40861:4:0;40822:35;40839:17;40822:12;40830:3;;40822:12;:7;:12;:::i;:35::-;:43;;40810:55;40794:71;39119:1780;-1:-1:-1;;;;;;;;;;;;;;39119:1780:0:o;101191:70::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;26707:151::-;26823:18;;;;26796:7;26823:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;26707:151::o;36483:703::-;36577:11;36590:10;36630:11;36622:4;:19;36618:561;;-1:-1:-1;36666:1:0;;-1:-1:-1;36669:5:0;36658:17;;36618:561;36705:11;36697:4;:19;36693:486;;-1:-1:-1;36741:9:0;;-1:-1:-1;36752:4:0;36733:24;;36693:486;36787:13;36779:4;:21;36775:404;;-1:-1:-1;36825:9:0;;-1:-1:-1;36836:6:0;36817:26;;36775:404;36873:13;36865:4;:21;36861:318;;-1:-1:-1;36911:11:0;;-1:-1:-1;36924:7:0;36903:29;;36861:318;36962:13;36954:4;:21;36950:229;;-1:-1:-1;37000:11:0;;-1:-1:-1;37013:7:0;36992:29;;36950:229;37051:13;37043:4;:21;37039:140;;-1:-1:-1;37089:11:0;;-1:-1:-1;37102:7:0;37081:29;;37039:140;37143:24;;;-1:-1:-1;;;37143:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;37039:140;36483:703;;;:::o;120431:1914::-;99268:16;;99260:39;99268:16;99238:120;;;;;-1:-1:-1;;;99238:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;120564:14:::1;120581:24;120598:6;120581:16;:24::i;:::-;120564:41;;120631:24;120670:16:::0;120701:30:::1;120748:18;:26;;;120775:6;120748:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24::::0;17:12:::1;2:2;120748:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;120748:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29::::0;22:12:::1;4:2;-1:-1:::0;120748:34:0;;::::1;::::0;::::1;::::0;;;;;;;;-1:-1:-1;120748:34:0;;-1:-1:-1;120748:34:0;-1:-1:-1;120801:30:0::1;::::0;::::1;120793:69;;;::::0;;-1:-1:-1;;;120793:69:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;120895:28;::::0;::::1;120873:109;;;::::0;;-1:-1:-1;;;120873:109:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;121053:12;121027:23;:21;:23::i;:::-;:38;121015:8;:50;;120993:146;;;;-1:-1:-1::0;;;120993:146:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;121152:29;121213:41;;:::i;:::-;-1:-1:-1::0;;121271:28:0::1;::::0;;;:20:::1;:28;::::0;;;;;;;;121213:86;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;;::::1;::::0;;;;;121395:27;121391:232:::1;;121447:36;::::0;::::1;::::0;:41:::1;;::::0;121443:140:::1;;121513:50;121544:6;121552:1;121555::::0;121558:4:::1;121513:30;:50::i;:::-;121601:7;;;;;;;;121391:232;-1:-1:-1::0;121644:28:0::1;::::0;;;:20:::1;:28;::::0;;;;121637:58;;;::::1;::::0;;121761:22:::1;121735:23;:21;:23::i;:::-;:48;121723:8;:60;121719:327;;121800:16;::::0;:67:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;:16;:67;;;;;;:16:::1;::::0;;::::1;::::0;:29:::1;::::0;:67;;;;;::::1;::::0;;;;;;;;;:16:::1;::::0;:67;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;121800:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;121800:67:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;121719:327:0::1;::::0;-1:-1:-1;121719:327:0::1;;121900:16;::::0;:134:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;:16:::1;:134:::0;;;;;;;;:16:::1;::::0;;::::1;::::0;:29:::1;::::0;:134;;;;;::::1;::::0;;;;;;;;;;;;:16;:134;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;121900:134:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;121900:134:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;;121719:327:0::1;122272:16;::::0;122223:114:::1;::::0;;;;;:26:::1;122272:16:::0;;::::1;122223:114;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;;;;;122184:16;;122223:26;::::1;::::0;::::1;::::0;:114;;;;;::::1;::::0;;;;;;;;122104:36:::1;122223:26:::0;:114;::::1;;2:2:-1::0;::::1;;;27:1;24::::0;17:12:::1;2:2;122223:114:0;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;122223:114:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28::::0;21:12:::1;4:2;-1:-1:::0;;;;;;;;120431:1914:0;:::o;98919:113::-;99015:9;99004:20;;;;;;;;98919:113::o;99891:134::-;99965:16;:52;;;;;;;;;;;;;;;99891:134::o;19691:106::-;19779:10;19691:106;:::o;32246:346::-;32348:19;;;32340:68;;;;-1:-1:-1;;;32340:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32427:21;;;32419:68;;;;-1:-1:-1;;;32419:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32500:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;32552:32;;;;;;;;;;;;;;;;;32246:346;;;:::o;29858:539::-;29964:20;;;29956:70;;;;-1:-1:-1;;;29956:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30045:23;;;30037:71;;;;-1:-1:-1;;;30037:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30121:47;30142:6;30150:9;30161:6;30121:20;:47::i;:::-;30201:71;30223:6;30201:71;;;;;;;;;;;;;;;;;:17;;;:9;:17;;;;;;;;;;;;:71;;:21;:71;:::i;:::-;30181:17;;;;:9;:17;;;;;;;;;;;:91;;;;30306:20;;;;;;;:32;;30331:6;30306:32;:24;:32;:::i;:::-;30283:20;;;;:9;:20;;;;;;;;;;;;:55;;;;30354:35;;;;;;;30283:20;;30354:35;;;;;;;;;;;;;29858:539;;;:::o;1801:192::-;1887:7;1923:12;1915:6;;;;1907:29;;;;-1:-1:-1;;;1907:29: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;1907:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1959:5:0;;;1801:192::o;2244:471::-;2302:7;2547:6;2543:47;;-1:-1:-1;2577:1:0;2570:8;;2543:47;2614:5;;;2618:1;2614;:5;:1;2638:5;;;;;:10;2630:56;;;;-1:-1:-1;;;2630:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2706:1;2244:471;-1:-1:-1;;;2244:471:0:o;3183:132::-;3241:7;3268:39;3272:1;3275;3268:39;;;;;;;;;;;;;;;;;:3;:39::i;914:181::-;972:7;1004:5;;;1028:6;;;;1020:46;;;;;-1:-1:-1;;;1020:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;8858:179;8914:6;8949:5;8941;:13;8933:65;;;;-1:-1:-1;;;8933:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9023:5:0;8858:179::o;1370:136::-;1428:7;1455:43;1459:1;1462;1455:43;;;;;;;;;;;;;;;;;:3;:43::i;30678:378::-;30762:21;;;30754:65;;;;;-1:-1:-1;;;30754:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;30832:49;30861:1;30865:7;30874:6;30832:20;:49::i;:::-;30909:12;;:24;;30926:6;30909:24;:16;:24;:::i;:::-;30894:12;:39;30965:18;;;:9;:18;;;;;;;;;;;:30;;30988:6;30965:30;:22;:30;:::i;:::-;30944:18;;;:9;:18;;;;;;;;;;;:51;;;;31011:37;;;;;;;30944:18;;:9;;31011:37;;;;;;;;;;30678:378;;:::o;125786:1168::-;125890:6;125914:36;;:::i;:::-;-1:-1:-1;125953:26:0;;;;:18;:26;;;;;;;;;125914:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;125990:78;;126055:1;126048:8;;;;;125990:78;126095:21;;;126080:12;126095:21;;;:12;:21;;;;;;;;:29;;;;;;;;;:40;;126219:36;;;;;;126297:38;;;;126095:40;;;;;126165:43;;;;;;;126268:67;;;126080:12;126720:26;;126095:40;;126720:8;:26::i;:::-;126661:43;126698:5;126661:32;:18;126684:8;126661:32;:22;:32;:::i;:43::-;:85;126643:257;;;126862:26;:4;100463:21;126862:26;:8;:26;:::i;:::-;126799:43;126836:5;126799:32;:18;126822:8;126799:32;:22;:32;:::i;:43::-;:89;126773:115;;126643:257;126919:27;:16;:6;126930:4;126919:16;:10;:16;:::i;:27::-;126912:34;125786:1168;-1:-1:-1;;;;;;;;125786:1168:0:o;62486:282::-;62548:21;62571:20;62625:15;;;;;;;;;;;:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62625:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62625:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62625:29:0;62680:15;;:31;;;;;;;;62625:29;;-1:-1:-1;62680:15:0;;;;;;;:29;;:31;;;;;62625:29;;62680:31;;;;;;;;;:15;:31;;;2:2:-1;;;;27:1;24;17:12;2:2;62680:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62680:31:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;62680:31:0;;-1:-1:-1;62486:282:0;;:::o;18709:194::-;18843:3;;18709:194::o;104167:5045::-;104353:14;104370:24;104387:6;104370:16;:24::i;:::-;104353:41;;104405:36;;:::i;:::-;-1:-1:-1;104444:26:0;;;;:18;:26;;;;;;;;;104405:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104523:113;;:88;;;;:69;:88::i;:113::-;104483:153;;;;;;104684:48;;;;:108;;:83;;:66;;;:83;;;:66;:83;:::i;:108::-;104647:145;;:34;;;:145;104805:4349;;;;104895:41;;:::i;:::-;-1:-1:-1;104953:28:0;;;;:20;:28;;;;;;;;104895:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104953:28;;;105914:98;;100463:21;105914:98;:40;:98;:::i;:::-;105893:119;;106031:18;106052:92;106115:10;106052:14;:36;;;:40;;;;:92;;;;:::i;:::-;106031:113;;106163:15;106181:116;106244:11;:34;;;106181:116;;:14;:36;;;:40;;;;:116;;;;:::i;:::-;106163:134;;106330:10;106320:7;:20;106316:1198;;;106383:7;106369:10;:21;106365:817;;106690:36;;;;106645:108;;:10;;:108;;;:14;:108;:::i;:::-;106628:125;;106365:817;;;107095:36;;;;107053:105;;:7;;:105;;;:11;:105;:::i;:::-;107036:122;;106365:817;106316:1198;;;107370:124;107437:11;:34;;;107370:124;;:14;:36;;;:40;;;;:124;;;;:::i;:::-;107353:141;;106316:1198;104805:4349;;;107550:30;107586:18;:26;;;107631:6;107586:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;107586:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;107586:66:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;107586:66:0;;;;-1:-1:-1;107669:36:0;107683:4;107690:14;107669:5;:36::i;:::-;107759:141;:112;107836:11;:34;;;107759:112;;:14;:54;;;:76;;;;:112;;;;:::i;:141::-;107720:180;;;;:36;;;:180;107951:37;;107917:155;;107951:106;;:41;;;:106;;;:41;:106;:::i;:::-;107917:15;:155::i;:::-;108209:37;;108129:57;;;;:147;;:118;;;:79;;;;:118;;:79;:118;:::i;:147::-;108087:189;;:39;;;;:189;;;108334:277;;;;;;;;;;;;;:306;;:277;;108087:189;;108334:277;;;;;;;:54;;;;:83;;:76;;108411:5;108334:83;:76;:83;:::i;:306::-;108293:347;;;;:38;;;;:347;;;;108696:4;108657:36;;;:43;;;;108745:27;;;:19;:27;;;;;;;:81;;:52;;:27;;;:52;:49;:52;:::i;:81::-;108715:27;;;;:19;:27;;;;;;;;:111;;;;;;;;;;;;;;108843:28;;;:20;:28;;;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;108931:13;:11;:13::i;:::-;109017:38;;;;;109108:19;;108964:178;;;;;;;;;;;;;;;;;;;;108905:39;;-1:-1:-1;108992:6:0;;108964:178;;;;;;;;;104805:4349;;;;;109164:26;;;;:18;:26;;;;;;;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;104167:5045:0:o;31388:418::-;31472:21;;;31464:67;;;;-1:-1:-1;;;31464:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31544:49;31565:7;31582:1;31586:6;31544:20;:49::i;:::-;31627:68;31650:6;31627:68;;;;;;;;;;;;;;;;;:18;;;:9;:18;;;;;;;;;;;;:68;;:22;:68;:::i;:::-;31606:18;;;:9;:18;;;;;;;;;;:89;31721:12;;:24;;31738:6;31721:24;:16;:24;:::i;:::-;31706:12;:39;31761:37;;;;;;;;31787:1;;31761:37;;;;;;;;;;;;;31388:418;;:::o;10999:181::-;11055:6;11090;11082:5;:14;11074:67;;;;-1:-1:-1;;;11074:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5726:568;5782:6;6026;6022:47;;-1:-1:-1;6056:1:0;6049:8;;6022:47;6091:1;6096:2;6091:7;:27;;;;;5626:7;6102:1;:16;6091:27;6089:30;6081:82;;;;-1:-1:-1;;;6081:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6187:5;;;6191:1;6187;:5;:1;6211:5;;;;;:10;6203:62;;;;-1:-1:-1;;;6203:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6789:218;6845:6;6875:5;;;6900:6;;;;;;:16;;;6915:1;6910;:6;;6900:16;6899:38;;;;6926:1;6922;:5;:14;;;;;6935:1;6931;:5;6922:14;6891:87;;;;-1:-1:-1;;;6891:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3803:345;3889:7;3991:12;3984:5;3976:28;;;;-1:-1:-1;;;3976:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;3976:28:0;;4015:9;4031:1;4027;:5;;;;;;;3803:345;-1:-1:-1;;;;;3803:345:0:o;33617:92::-;;;;:::o;34117:106::-;34175:7;34206:1;34202;:5;:13;;34214:1;34202:13;;;-1:-1:-1;34210:1:0;;34117:106;-1:-1:-1;34117:106:0:o;103482:132::-;103570:19;;:36;;103594:11;103570:36;:23;:36;:::i;:::-;103548:19;:58;-1:-1:-1;103482:132:0:o;100095:28022::-;;;;;;;;;-1:-1:-1;100095:28022:0;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://d085672f8467497f59973194f9b1d4d97c7592939b63afb78bc9add4e0e727e6
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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