ETH Price: $3,118.18 (+0.58%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

TokenTracker

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Approve241451872026-01-02 6:34:3510 days ago1767335675IN
0xDb4f5Bc7...F366aD782
0 ETH0.000001370.0294769
Return Locked Po...106597522020-08-14 18:21:181976 days ago1597429278IN
0xDb4f5Bc7...F366aD782
0 ETH0.00619914184
Return Locked Po...106597262020-08-14 18:13:461976 days ago1597428826IN
0xDb4f5Bc7...F366aD782
0 ETH0.00656765182
Start Auction On...106587192020-08-14 14:43:111976 days ago1597416191IN
0xDb4f5Bc7...F366aD782
0 ETH0.0183504200
Unlock SBT106586862020-08-14 14:34:071976 days ago1597415647IN
0xDb4f5Bc7...F366aD782
0 ETH0.01353022220
Mint106586472020-08-14 14:25:061976 days ago1597415106IN
0xDb4f5Bc7...F366aD782
0 ETH0.05758116105
Approve106536612020-08-13 20:00:341977 days ago1597348834IN
0xDb4f5Bc7...F366aD782
0 ETH0.00515595117
Mint106534272020-08-13 19:09:031977 days ago1597345743IN
0xDb4f5Bc7...F366aD782
0 ETH0.03867324120
Mint106530742020-08-13 17:52:071977 days ago1597341127IN
0xDb4f5Bc7...F366aD782
0 ETH0.10038303165
Approve106266882020-08-09 16:01:561981 days ago1596988916IN
0xDb4f5Bc7...F366aD782
0 ETH0.00484748110
Approve106266832020-08-09 16:00:241981 days ago1596988824IN
0xDb4f5Bc7...F366aD782
0 ETH0.00484616110
Mint106259542020-08-09 13:17:261981 days ago1596979046IN
0xDb4f5Bc7...F366aD782
0 ETH0.0643983390
Set Auction Cont...106210692020-08-08 19:24:341982 days ago1596914674IN
0xDb4f5Bc7...F366aD782
0 ETH0.0043458100

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FlattenStableCoin

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
Yes with 20000 runs

Other Settings:
constantinople EvmVersion, None license
/**
 *Submitted for verification at Etherscan.io on 2020-08-12
*/

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

pragma solidity ^0.6.0;


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

pragma solidity 0.6.6;


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
    );

    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 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

pragma solidity 0.6.6;


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

pragma solidity ^0.6.0;


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

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

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

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

pragma solidity ^0.6.0;


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

        return c;
    }

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

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    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/utils/Address.sol

pragma solidity ^0.6.2;


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

pragma solidity ^0.6.0;


/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {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 override view returns (uint256) {
        return _totalSupply;
    }

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

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

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

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount)
        public
        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

pragma solidity ^0.6.0;


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

pragma solidity 0.6.6;


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

pragma solidity 0.6.6;


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

    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 auctionID2BondID(bytes32 auctionID)
        external
        view
        returns (bytes32);

    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/util/DeployerRole.sol

pragma solidity 0.6.6;


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

pragma solidity 0.6.6;


abstract contract UseAuctionLater is DeployerRole {
    AuctionInterface 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 = AuctionInterface(payable(contractAddress));
    }
}

// File: contracts/util/TransferETHInterface.sol

pragma solidity 0.6.6;


interface TransferETHInterface {
    receive() external payable;

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

// File: contracts/bondToken/BondTokenInterface.sol

pragma solidity 0.6.6;


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: @openzeppelin/contracts/math/SignedSafeMath.sol

pragma solidity ^0.6.0;


/**
 * @title SignedSafeMath
 * @dev Signed math operations with safety checks that revert on error.
 */
library SignedSafeMath {
    int256 private constant _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

pragma solidity ^0.6.0;


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

pragma solidity ^0.6.0;


/**
 * @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: contracts/solidBondSafety/SolidBondSafety.sol

pragma solidity 0.6.6;


// 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/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

pragma solidity 0.6.6;


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/BondMakerInterface.sol

pragma solidity 0.6.6;


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/StableCoin.sol

contract FlattenStableCoin 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;

    /**
     * @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
    ) public UseOracle(oracleAddress) UseBondMaker(bondMakerAddress) {
        _setupDecimals(8);
        AUCTION_SPAN = auctionSpan;
        EMERGENCY_AUCTION_SPAN = emergencyAuctionSpan;
    }

    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;
        }
        _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
        returns (bool)
    {
        (, uint256 maturity, uint64 solidStrikePriceE4, ) = _bondMakerContract
            .getBond(bondID);
        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);

        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 {
        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(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 {
        bytes32 poolID = getCurrentPoolID(bondID);
        (address bondTokenAddress, uint256 maturity, , ) = _bondMakerContract
            .getBond(bondID);
        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 {
        bytes32 poolID = getCurrentPoolID(bondID);
        (
            address bondTokenAddress,
            uint256 maturity,
            uint64 solidBondStrikePriceUSD,

        ) = _bondMakerContract.getBond(bondID);
        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 {
        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)
        internal
        returns (uint64)
    {
        AuctionAmountInfo memory auctionInfo = _auctionAmountInfo[poolID];
        if (!auctionInfo.isAllAmountSoldInAuction) {
            return 0;
        }

        uint256 pool = lockedPoolE8[msg.sender][poolID].IDOLAmount;
        uint256 amountE8 = lockedPoolE8[msg.sender][poolID].baseSBTAmount;
        delete lockedPoolE8[msg.sender][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 returnLockedPool(bytes32[] memory poolIDs)
        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]);
            totalBackIDOLAmount = totalBackIDOLAmount.add(backIDOLAmount);
            emit LogReturnLockedPool(poolIDs[i], msg.sender, backIDOLAmount);
        }

        this.transfer(msg.sender, totalBackIDOLAmount);

        return totalBackIDOLAmount.toUint64();
    }
}

Contract Security Audit

Contract ABI

API
[{"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"}],"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":"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":"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"}]

6101006040523480156200001257600080fd5b50604051620048a3380380620048a3833981810160405260808110156200003857600080fd5b5080516020808301516040808501516060909501518151808301835260048082527f69444f4c0000000000000000000000000000000000000000000000000000000082870181815285518087019096529185529584019590955280519596939593949193869388939091620000b09160039162000206565b508051620000c690600490602084019062000206565b50506005805460ff19166012179055506001600160a01b03811662000137576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180620048806023913960400191505060405180910390fd5b60058054610100600160a81b0319166101006001600160a01b03938416021790558116620001b1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180620048806023913960400191505060405180910390fd5b6001600160601b0319606091821b1660805233901b60a052620001de60086001600160e01b03620001f016565b60c09190915260e05250620002ab9050565b6005805460ff191660ff92909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200024957805160ff191683800117855562000279565b8280016001018555821562000279579182015b82811115620002795782518255916020019190600101906200025c565b50620002879291506200028b565b5090565b620002a891905b8082111562000287576000815560010162000292565b90565b60805160601c60a05160601c60c05160e0516145766200030a60003980612b52525080611d0252806129f6525080612db3525080610cda52806112e052806117345280611c105280611fe2528061294d52806137f552506145766000f3fe608060405234801561001057600080fd5b50600436106101e55760003560e01c806379cc67901161010f578063b67f0935116100a2578063dbb2348311610071578063dbb2348314610817578063dd62ed3e14610850578063dfef99f61461088b578063e2fbacdd146108c1576101e5565b8063b67f0935146106de578063bc27f2ec14610728578063c4fb3c3e14610745578063d528d8aa146107e8576101e5565b80639ed7ac70116100de5780639ed7ac7014610622578063a457c2d71461064f578063a9059cbb14610688578063b515f740146106c1576101e5565b806379cc6790146105aa5780637b7e31b1146105e357806393bb8a01146105eb57806395d89b411461061a576101e5565b80632fe82fe611610187578063616d272f11610156578063616d272f146104bb57806367fd88d0146104fa5780636881df131461055a57806370a0823114610577576101e5565b80632fe82fe6146103d5578063313ce56714610447578063395093511461046557806350fef38c1461049e576101e5565b806309f2c019116101c357806309f2c019146102e9578063134b0fca1461035b57806318160ddd1461038a57806323b872dd14610392576101e5565b8063023924c7146101ea57806306fdde031461021f578063095ea7b31461029c575b600080fd5b61021d6004803603602081101561020057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166108de565b005b6102276109d5565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610261578181015183820152602001610249565b50505050905090810190601f16801561028e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102d5600480360360408110156102b257600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610a89565b604080519115158252519081900360200190f35b610306600480360360208110156102ff57600080fd5b5035610aa7565b6040805167ffffffffffffffff998a16815297891660208901529588168787015293871660608701529186166080860152851660a085015290931660c083015291151560e08201529051908190036101000190f35b6103786004803603602081101561037157600080fd5b5035610bec565b60408051918252519081900360200190f35b610378610c18565b6102d5600480360360608110156103a857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610c1e565b61041e600480360360608110156103eb57600080fd5b50803590602081013573ffffffffffffffffffffffffffffffffffffffff16906040013567ffffffffffffffff16610cc5565b6040805193845267ffffffffffffffff9283166020850152911682820152519081900360600190f35b61044f611262565b6040805160ff9092168252519081900360200190f35b6102d56004803603604081101561047b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561126b565b61021d600480360360208110156104b457600080fd5b50356112cc565b61021d600480360360808110156104d157600080fd5b5080359067ffffffffffffffff60208201358116916040810135909116906060013515156116da565b6105336004803603604081101561051057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611843565b6040805167ffffffffffffffff938416815291909216602082015281519081900390910190f35b6103786004803603602081101561057057600080fd5b5035611893565b6103786004803603602081101561058d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118e3565b61021d600480360360408110156105c057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561190b565b61037861196f565b6102d56004803603608081101561060157600080fd5b5080359060208101359060408101359060600135611975565b610227611a83565b6103786004803603604081101561063857600080fd5b508035906020013567ffffffffffffffff16611b02565b6102d56004803603604081101561066557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611b7a565b6102d56004803603604081101561069e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611bf5565b6102d5600480360360208110156106d757600080fd5b5035611c09565b61070b600480360360408110156106f457600080fd5b508035906020013567ffffffffffffffff16611fcf565b6040805167ffffffffffffffff9092168252519081900360200190f35b61070b6004803603602081101561073e57600080fd5b50356124bd565b61070b6004803603602081101561075b57600080fd5b81019060208101813564010000000081111561077657600080fd5b82018360208201111561078857600080fd5b803590602001918460208302840111640100000000831117156107aa57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506124d9945050505050565b6102d5600480360360808110156107fe57600080fd5b5080359060208101359060408101359060600135612638565b6105336004803603604081101561082d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612766565b6103786004803603604081101561086657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661279d565b6108a8600480360360208110156108a157600080fd5b50356127d5565b6040805192835260208301919091528051918290030190f35b61021d600480360360208110156108d757600080fd5b503561293b565b6108e733612db1565b6109225760405162461bcd60e51b815260040180806020018281038252602e8152602001806142cd602e913960400191505060405180910390fd5b60065473ffffffffffffffffffffffffffffffffffffffff16156109775760405162461bcd60e51b815260040180806020018281038252602a8152602001806144ac602a913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166109c95760405162461bcd60e51b81526004018080602001828103825260238152602001806143916023913960400191505060405180910390fd5b6109d281612df0565b50565b60038054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a7f5780601f10610a5457610100808354040283529160200191610a7f565b820191906000526020600020905b815481529060010190602001808311610a6257829003601f168201915b5050505050905090565b6000610a9d610a96612e37565b8484612e3b565b5060015b92915050565b600080600080600080600080610abb6140f7565b506000898152600a60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484018590527001000000000000000000000000000000008304821695840186905278010000000000000000000000000000000000000000000000009092041660608301819052909b509199509197509550610b4f6140f7565b50505060009788525050600b60209081526040968790208751608081018952905467ffffffffffffffff808216808452680100000000000000008304821694840185905270010000000000000000000000000000000083049091169983018a9052780100000000000000000000000000000000000000000000000090910460ff161515606090920182905296989597949693959394919391925090565b60008181526008602052604081205467ffffffffffffffff16610c0f8382611b02565b9150505b919050565b60025490565b6000610c2b848484612f4e565b610cbb84610c37612e37565b610cb6856040518060600160405280602881526020016143426028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020526040812090610c82612e37565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff6130f616565b612e3b565b5060019392505050565b6000806000610cd386610bec565b92506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b896040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015610d4957600080fd5b505afa158015610d5d573d6000803e3d6000fd5b505050506040513d6080811015610d7357600080fd5b50805160409091015190925067ffffffffffffffff169050610d9488611c09565b610dcf5760405162461bcd60e51b815260040180806020018281038252602f81526020018061423e602f913960400191505060405180910390fd5b610dd76140f7565b506000858152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481169483019490945270010000000000000000000000000000000081048416928201929092527801000000000000000000000000000000000000000000000000909104821660608201529190610e6b9089168463ffffffff61318d16565b90506000610e7882611893565b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015230602482015267ffffffffffffffff8c1660448201529051919250869173ffffffffffffffffffffffffffffffffffffffff8316916323b872dd9160648083019260209291908290030181600087803b158015610f0157600080fd5b505af1158015610f15573d6000803e3d6000fd5b505050506040513d6020811015610f2b57600080fd5b5060009050610f4183600a63ffffffff6131ed16565b73ffffffffffffffffffffffffffffffffffffffff8d1660009081526009602090815260408083208e84529091529020805491925090610f9a90610f959067ffffffffffffffff168463ffffffff61322f16565b613289565b81547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff91821617808355610fec91610f95916801000000000000000090048116908f1661322f565b815467ffffffffffffffff9190911668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781556110468d611041868563ffffffff6132d616565b613318565b6110503083613318565b600754611063908663ffffffff61322f16565b600755855161108a90610f959067ffffffffffffffff908116908f1663ffffffff61322f16565b67ffffffffffffffff908116875260408701516110b291610f9591168463ffffffff61322f16565b67ffffffffffffffff908116604080890191825260008e8152600a60209081529181208a518154938c0151945160608d0151871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff918816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff97891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff949099167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009097169690961792909216969096179490941692909217939093169190911790556111d6858463ffffffff6132d616565b90508d73ffffffffffffffffffffffffffffffffffffffff168f7f5a0def86b68ea53595ef32019b93a42eedf7c609407f51834703faa48bd592d08e848760405180848152602001838152602001828152602001935050505060405180910390a38b61124182613289565b61124a85613289565b9b509b509b5050505050505050505093509350939050565b60055460ff1690565b6000610a9d611278612e37565b84610cb68560016000611289612e37565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61322f16565b60006112d782610bec565b905060008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561134f57600080fd5b505afa158015611363573d6000803e3d6000fd5b505050506040513d608081101561137957600080fd5b5080516020820151604090920151909450909250905067ffffffffffffffff81166113eb576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b6000806113f661343b565b91509150600061141b838567ffffffffffffffff168461141461357a565b8903611975565b90508061146f576040805162461bcd60e51b815260206004820152601b60248201527f74686520534254206973206e6f7420696e20656d657267656e63790000000000604482015290519081900360640190fd5b60006114796140f7565b50506000878152600a60209081526040918290208251608081018452905467ffffffffffffffff8082168084526801000000000000000083048216948401949094527001000000000000000000000000000000008204811694830194909452780100000000000000000000000000000000000000000000000090049092166060830152908161153257604081015167ffffffffffffffff1615611524576115248a600080600161357e565b5050505050505050506109d2565b506000888152600a6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560065481517f9da326ef000000000000000000000000000000000000000000000000000000008152600481018e905267ffffffffffffffff8616602482015260016044820152915173ffffffffffffffffffffffffffffffffffffffff90911693639da326ef93606480850194919392918390030190829087803b1580156115f157600080fd5b505af1158015611605573d6000803e3d6000fd5b505050506040513d602081101561161b57600080fd5b5050600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051899283169163a9059cbb9160448083019260209291908290030181600087803b1580156116a257600080fd5b505af11580156116b6573d6000803e3d6000fd5b505050506040513d60208110156116cc57600080fd5b505050505050505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146117305760405162461bcd60e51b81526004018080602001828103825260238152602001806142aa6023913960400191505060405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b1580156117a357600080fd5b505afa1580156117b7573d6000803e3d6000fd5b505050506040513d60808110156117cd57600080fd5b506040015167ffffffffffffffff16905080611830576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b61183c8585858561357e565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600960209081526040808320938352929052205467ffffffffffffffff80821692680100000000000000009092041690565b6000600754600014156118b9576118b28261271063ffffffff6131ed16565b9050610c13565b610aa16007546118d76118ca610c18565b859063ffffffff61318d16565b9063ffffffff6131ed16565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff1633146119615760405162461bcd60e51b81526004018080602001828103825260238152602001806142aa6023913960400191505060405180910390fd5b61196b8282613c00565b5050565b60075490565b600082630bebc20081111561198b5750630bebc2005b626ebe00831061199f576001915050611a7b565b60006119c1846119b5848063ffffffff61318d16565b9063ffffffff61318d16565b905066072ba304f8000081046000806119d9836127d5565b9150915060006119e88b613d3c565b905060006119f58b613d3c565b90506000611a19611a0c858463ffffffff613d9c16565b849063ffffffff613e7f16565b90506000611a3f83611a3381818c8b63ffffffff613d9c16565b9063ffffffff613d9c16565b905060008083131580611a6e575081611a6b680118188ff217800000611a33868063ffffffff613d9c16565b13155b9a50505050505050505050505b949350505050565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a7f5780601f10610a5457610100808354040283529160200191610a7f565b6040805160208082019490945260c09290921b7fffffffffffffffff00000000000000000000000000000000000000000000000016828201527f6c69656e0000000000000000000000000000000000000000000000000000000060488301528051808303602c018152604c9092019052805191012090565b6000610a9d611b87612e37565b84610cb68560405180606001604052806025815260200161451c6025913960016000611bb1612e37565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff6130f616565b6000610a9d611c02612e37565b8484612f4e565b60008060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b856040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015611c7f57600080fd5b505afa158015611c93573d6000803e3d6000fd5b505050506040513d6080811015611ca957600080fd5b506020810151604090910151909250905067ffffffffffffffff8116611d005760405162461bcd60e51b815260040180806020018281038252602a815260200180614142602a913960400191505060405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000611d2961357a565b018211611d675760405162461bcd60e51b815260040180806020018281038252603c81526020018061418e603c913960400191505060405180910390fd5b620186a067ffffffffffffffff82160667ffffffffffffffff16600014611dbf5760405162461bcd60e51b81526004018080602001828103825260228152602001806144fa6022913960400191505060405180910390fd5b600654604080517fecfb314d00000000000000000000000000000000000000000000000000000000815260048101879052905160009273ffffffffffffffffffffffffffffffffffffffff169163ecfb314d916024808301926020929190829003018186803b158015611e3157600080fd5b505afa158015611e45573d6000803e3d6000fd5b505050506040513d6020811015611e5b57600080fd5b5051600654604080517f9737d6fd00000000000000000000000000000000000000000000000000000000815260048101849052905192935073ffffffffffffffffffffffffffffffffffffffff90911691639737d6fd91602480820192602092909190829003018186803b158015611ed257600080fd5b505afa158015611ee6573d6000803e3d6000fd5b505050506040513d6020811015611efc57600080fd5b505167ffffffffffffffff1615611f5a576040805162461bcd60e51b815260206004820152601860248201527f7468697320534254206973206f6e20612061756369746f6e0000000000000000604482015290519081900360640190fd5b600080611f6561343b565b915091506000611f8a838667ffffffffffffffff1684611f8361357a565b8a03612638565b6040805182158152905191925089917fea0241146eaea8e64956684a8df42cc134671b71fcc2b474bcbd63f30b32984f9181900360200190a215979650505050505050565b600080611fdb84610bec565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b876040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d608081101561207b57600080fd5b50805160409091015190925067ffffffffffffffff169050806120e5576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b6120ed6140f7565b506000838152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481168386015270010000000000000000000000000000000082048116838501527801000000000000000000000000000000000000000000000000909104166060808301919091528251908101909252603d8083529093926121db92610f9592879261426d908301396121ce612196610c18565b6040518060600160405280602c8152602001614212602c91396121ce6007548f67ffffffffffffffff1661318d90919063ffffffff16565b919063ffffffff613ee416565b905061220b610f958867ffffffffffffffff16846060015167ffffffffffffffff1661322f90919063ffffffff16565b67ffffffffffffffff90811660608401526122299033908916613c00565b604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015267ffffffffffffffff831660248201529051859173ffffffffffffffffffffffffffffffffffffffff83169163a9059cbb916044808201926020929091908290030181600087803b1580156122aa57600080fd5b505af11580156122be573d6000803e3d6000fd5b505050506040513d60208110156122d457600080fd5b50506040805167ffffffffffffffff808b16825284166020820152815133928c927f87efbe374e86e4f26b4593306372ef7f3c1fa4ed256c9d4f7400d00b3f729114929081900390910190a361234c61233d67ffffffffffffffff84168663ffffffff61318d16565b6007549063ffffffff6132d616565b600755825161237390610f959067ffffffffffffffff90811690851663ffffffff6132d616565b67ffffffffffffffff9081168452602084015161239e91610f9591811690851663ffffffff61322f16565b67ffffffffffffffff90811660208086019182526000988952600a905260409788902085518154925199870151606090970151841678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff978516700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9b861668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff939096167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009095169490941791909116939093179890981617939093169290921790945550919250505092915050565b60086020526000908152604090205467ffffffffffffffff1681565b600080805b83518110156125a25760006125058583815181106124f857fe5b6020026020010151613f49565b90506125218367ffffffffffffffff831663ffffffff61322f16565b92503373ffffffffffffffffffffffffffffffffffffffff1685838151811061254657fe5b60200260200101517fb931a8416f2f16d5400a0cce933872df77c3cfcadae032ff6b1646e8cdc12a3c83604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390a3506001016124de565b50604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018390529051309163a9059cbb9160448083019260209291908290030181600087803b15801561260257600080fd5b505af1158015612616573d6000803e3d6000fd5b505050506040513d602081101561262c57600080fd5b50610c0f905081613289565b60006002850261c350850210801561265257506212750082105b1561265f57506000611a7b565b630bebc20083111561267357506001611a7b565b626ebe00821061268557506001611a7b565b600061269b836119b5868063ffffffff61318d16565b905066072ba304f8000081046000806126b3836127d5565b9150915060006126c28a613d3c565b905060006126cf8a613d3c565b905060006127086126eb6003611a33878663ffffffff613d9c16565b6126fc85600263ffffffff613d9c16565b9063ffffffff613e7f16565b905060006127256009611a33858181818e8d63ffffffff613d9c16565b905060008083131580612754575081612751680118188ff217800000611a33868063ffffffff613d9c16565b13155b9e9d5050505050505050505050505050565b600960209081526000928352604080842090915290825290205467ffffffffffffffff808216916801000000000000000090041682565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60008062c3204083116127ef575060009050612af8612936565b630394b7b183116128085750615a4090506115bc612936565b6307f7cae4831161284057506206400090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81fc612936565b630bf3790083116128785750621f126990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1e88612936565b630fc0bf0183116128b0575062817ac190507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffae894612936565b63134fd90083116128e957506301af0c8990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f33b612936565b6040805162461bcd60e51b815260206004820152600e60248201527f6e6f742061636365707461626c65000000000000000000000000000000000000604482015290519081900360640190fd5b915091565b600061294682610bec565b90506000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b856040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b1580156129bc57600080fd5b505afa1580156129d0573d6000803e3d6000fd5b505050506040513d60808110156129e657600080fd5b50805160209091015190925090507f0000000000000000000000000000000000000000000000000000000000000000612a1d61357a565b01811115612a5c5760405162461bcd60e51b815260040180806020018281038252602e81526020018061447e602e913960400191505060405180910390fd5b6000612a666140f7565b50506000838152600a60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484019490945270010000000000000000000000000000000082048116948301949094527801000000000000000000000000000000000000000000000000900490921660608301529081612b1b57604081015167ffffffffffffffff1615612b1157612b1186600080600161357e565b50505050506109d2565b506000848152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690557f0000000000000000000000000000000000000000000000000000000000000000612b7961357a565b018211612c3d57600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810188905267ffffffffffffffff8416602482015260016044820152905173ffffffffffffffffffffffffffffffffffffffff90921691639da326ef916064808201926020929091908290030181600087803b158015612c0b57600080fd5b505af1158015612c1f573d6000803e3d6000fd5b505050506040513d6020811015612c3557600080fd5b50612cf89050565b600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810188905267ffffffffffffffff84166024820152600060448201819052915173ffffffffffffffffffffffffffffffffffffffff90931692639da326ef92606480840193602093929083900390910190829087803b158015612ccb57600080fd5b505af1158015612cdf573d6000803e3d6000fd5b505050506040513d6020811015612cf557600080fd5b50505b600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051859283169163a9059cbb9160448083019260209291908290030181600087803b158015612d7d57600080fd5b505af1158015612d91573d6000803e3d6000fd5b505050506040513d6020811015612da757600080fd5b5050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff90811691161490565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3390565b73ffffffffffffffffffffffffffffffffffffffff8316612e8d5760405162461bcd60e51b81526004018080602001828103825260248152602001806144326024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612edf5760405162461bcd60e51b81526004018080602001828103825260228152602001806141ca6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316612fa05760405162461bcd60e51b815260040180806020018281038252602581526020018061440d6025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612ff25760405162461bcd60e51b815260040180806020018281038252602381526020018061411f6023913960400191505060405180910390fd5b612ffd8383836140c3565b61304d816040518060600160405280602681526020016141ec6026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054919063ffffffff6130f616565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461308f908263ffffffff61322f16565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156131855760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561314a578181015183820152602001613132565b50505050905090810190601f1680156131775780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008261319c57506000610aa1565b828202828482816131a957fe5b04146131e65760405162461bcd60e51b81526004018080602001828103825260218152602001806142fb6021913960400191505060405180910390fd5b9392505050565b60006131e683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613ee4565b6000828201838110156131e6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006801000000000000000082106132d25760405162461bcd60e51b815260040180806020018281038252602681526020018061431c6026913960400191505060405180910390fd5b5090565b60006131e683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130f6565b73ffffffffffffffffffffffffffffffffffffffff8216613380576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61338c600083836140c3565b60025461339f908263ffffffff61322f16565b60025573ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020546133d8908263ffffffff61322f16565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600080600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3e6ba946040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156134a857600080fd5b505af11580156134bc573d6000803e3d6000fd5b505050506040513d60208110156134d257600080fd5b5051600554604080517f3af2888b000000000000000000000000000000000000000000000000000000008152905192945061010090910473ffffffffffffffffffffffffffffffffffffffff1691633af2888b916004808201926020929091908290030181600087803b15801561354857600080fd5b505af115801561355c573d6000803e3d6000fd5b505050506040513d602081101561357257600080fd5b505190509091565b4290565b600061358985610bec565b90506135936140f7565b506000818152600b60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484019490945270010000000000000000000000000000000082048116948301949094527801000000000000000000000000000000000000000000000000900460ff16151560608201529161362791610f9591871661322f565b67ffffffffffffffff9081168252602082015161365291610f9591811690881663ffffffff61322f16565b67ffffffffffffffff1660208201528215613ae85761366f6140f7565b506000828152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481169483019490945270010000000000000000000000000000000081048416928201839052780100000000000000000000000000000000000000000000000090049092166060830152909190819061370490600963ffffffff61318d16565b9050600061372982856040015167ffffffffffffffff1661322f90919063ffffffff16565b9050600061375c866020015167ffffffffffffffff16866060015167ffffffffffffffff1661322f90919063ffffffff16565b9050828111156137bc5780821061379457606085015161378d90839067ffffffffffffffff1663ffffffff6132d616565b93506137b7565b60608501516137b490829067ffffffffffffffff1663ffffffff6132d616565b93505b6137ee565b6137eb866020015167ffffffffffffffff16866040015167ffffffffffffffff1661322f90919063ffffffff16565b93505b50505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166326d6c97b8a6040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561386457600080fd5b505afa158015613878573d6000803e3d6000fd5b505050506040513d608081101561388e57600080fd5b5060400151905061389f3083613c00565b6138d1610f95856020015167ffffffffffffffff16856060015167ffffffffffffffff1661322f90919063ffffffff16565b67ffffffffffffffff90811660608501528451613901916138fc91811690841663ffffffff61318d16565b6140c8565b8351602084015161392991610f959167ffffffffffffffff908116911663ffffffff61322f16565b67ffffffffffffffff1660208085018290526040805160608101909152603880825261398193610f9593909291906143b49083013960608701516121ce9067ffffffffffffffff166305f5e10063ffffffff61318d16565b67ffffffffffffffff90811660408087019190915260016060870181905260008c8152600860205291909120546139c492610f959291169063ffffffff61322f16565b60008a8152600860209081526040808320805467ffffffffffffffff9586167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000091821617909155898452600a835292819020875181549389015192890151606090990151861678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff998716700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff94881668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff93909816959096169490941716949094171691909117949094169390931790925550505b6000918252600b60209081526040928390208251815492840151948401516060909401517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090931667ffffffffffffffff918216177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000095821695909502949094177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000009490931693909302919091177fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009115159190910217905550505050565b73ffffffffffffffffffffffffffffffffffffffff8216613c525760405162461bcd60e51b81526004018080602001828103825260218152602001806143ec6021913960400191505060405180910390fd5b613c5e826000836140c3565b613cae8160405180606001604052806022815260200161416c6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040902054919063ffffffff6130f616565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902055600254613ce7908263ffffffff6132d616565b60025560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60007f800000000000000000000000000000000000000000000000000000000000000082106132d25760405162461bcd60e51b81526004018080602001828103825260288152602001806144566028913960400191505060405180910390fd5b600082613dab57506000610aa1565b827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015613df957507f800000000000000000000000000000000000000000000000000000000000000082145b15613e355760405162461bcd60e51b815260040180806020018281038252602781526020018061436a6027913960400191505060405180910390fd5b82820282848281613e4257fe5b05146131e65760405162461bcd60e51b815260040180806020018281038252602781526020018061436a6027913960400191505060405180910390fd5b6000818303818312801590613e945750838113155b80613ea95750600083128015613ea957508381135b6131e65760405162461bcd60e51b81526004018080602001828103825260248152602001806144d66024913960400191505060405180910390fd5b60008183613f335760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561314a578181015183820152602001613132565b506000838581613f3f57fe5b0495945050505050565b6000613f536140f7565b506000828152600b60209081526040918290208251608081018452905467ffffffffffffffff80821683526801000000000000000082048116938301939093527001000000000000000000000000000000008104909216928101929092527801000000000000000000000000000000000000000000000000900460ff16151560608201819052613fe7576000915050610c13565b33600090815260096020818152604080842087855290915280832080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081169091559084015167ffffffffffffffff80831694680100000000000000009093048116939116919061405a90859061318d565b6140726305f5e1006118d7858763ffffffff61318d16565b11156140a55761408984600963ffffffff61318d16565b6140a16305f5e1006118d7858763ffffffff61318d16565b0390505b6140b8610f95828663ffffffff6140e116565b979650505050505050565b505050565b6007546140db908263ffffffff6132d616565b60075550565b60008183106140f057816131e6565b5090919050565b6040805160808101825260008082526020820181905291810182905260608101919091529056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737374686520626f6e6420646f6573206e6f74206d6174636820746f2074686520666f726d206f662053425445524332303a206275726e20616d6f756e7420657863656564732062616c616e636561207265717565737420746f20686f6c6420616e2061756374696f6e206f662074686520626f6e642068617320616c7265616479206578706972656445524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636573797374656d206572726f723a20746f74616c537570706c79206e65766572206265636f6d6573207a65726f53425420776974682074686520626f6e644944206973206e6f742063757272656e746c792061636365707461626c6573797374656d206572726f723a20736f6c6964537472696b655072696365206e65766572206265636f6d6573207a65726f205b756e6c6f636b5342545d6d73672e73656e646572206d7573742062652061756374696f6e20636f6e74726163746f6e6c79206465706c6f79657220697320616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e203634206269747345524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77636f6e74726163742073686f756c64206265206e6f6e2d7a65726f206164647265737373797374656d3a2074686520746f74616c20756e6c6f636b20616d6f756e742073686f756c64206265206e6f6e2d7a65726f2076616c756545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737353616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235366d61747572697479206973206c61746572207468616e2074686520726567756c61722061756374696f6e5370616e7468652061756374696f6e20636f6e747261637420697320616c726561647920726567697374657265645369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f7774686520737472696b65207072696365206e65656420746f20626520242031302a5845524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220ec31e73691d5223cd49ce0de66f4abd57af73830d3eba761318d911fb47bb1dc64736f6c63430006060033636f6e74726163742073686f756c64206265206e6f6e2d7a65726f2061646472657373000000000000000000000000120a078fdc516a1a98bbecb9e961f8741ac7ac82000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a3000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000000000000000000000000000000000000015f90

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101e55760003560e01c806379cc67901161010f578063b67f0935116100a2578063dbb2348311610071578063dbb2348314610817578063dd62ed3e14610850578063dfef99f61461088b578063e2fbacdd146108c1576101e5565b8063b67f0935146106de578063bc27f2ec14610728578063c4fb3c3e14610745578063d528d8aa146107e8576101e5565b80639ed7ac70116100de5780639ed7ac7014610622578063a457c2d71461064f578063a9059cbb14610688578063b515f740146106c1576101e5565b806379cc6790146105aa5780637b7e31b1146105e357806393bb8a01146105eb57806395d89b411461061a576101e5565b80632fe82fe611610187578063616d272f11610156578063616d272f146104bb57806367fd88d0146104fa5780636881df131461055a57806370a0823114610577576101e5565b80632fe82fe6146103d5578063313ce56714610447578063395093511461046557806350fef38c1461049e576101e5565b806309f2c019116101c357806309f2c019146102e9578063134b0fca1461035b57806318160ddd1461038a57806323b872dd14610392576101e5565b8063023924c7146101ea57806306fdde031461021f578063095ea7b31461029c575b600080fd5b61021d6004803603602081101561020057600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166108de565b005b6102276109d5565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610261578181015183820152602001610249565b50505050905090810190601f16801561028e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102d5600480360360408110156102b257600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610a89565b604080519115158252519081900360200190f35b610306600480360360208110156102ff57600080fd5b5035610aa7565b6040805167ffffffffffffffff998a16815297891660208901529588168787015293871660608701529186166080860152851660a085015290931660c083015291151560e08201529051908190036101000190f35b6103786004803603602081101561037157600080fd5b5035610bec565b60408051918252519081900360200190f35b610378610c18565b6102d5600480360360608110156103a857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135610c1e565b61041e600480360360608110156103eb57600080fd5b50803590602081013573ffffffffffffffffffffffffffffffffffffffff16906040013567ffffffffffffffff16610cc5565b6040805193845267ffffffffffffffff9283166020850152911682820152519081900360600190f35b61044f611262565b6040805160ff9092168252519081900360200190f35b6102d56004803603604081101561047b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561126b565b61021d600480360360208110156104b457600080fd5b50356112cc565b61021d600480360360808110156104d157600080fd5b5080359067ffffffffffffffff60208201358116916040810135909116906060013515156116da565b6105336004803603604081101561051057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611843565b6040805167ffffffffffffffff938416815291909216602082015281519081900390910190f35b6103786004803603602081101561057057600080fd5b5035611893565b6103786004803603602081101561058d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166118e3565b61021d600480360360408110156105c057600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561190b565b61037861196f565b6102d56004803603608081101561060157600080fd5b5080359060208101359060408101359060600135611975565b610227611a83565b6103786004803603604081101561063857600080fd5b508035906020013567ffffffffffffffff16611b02565b6102d56004803603604081101561066557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611b7a565b6102d56004803603604081101561069e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611bf5565b6102d5600480360360208110156106d757600080fd5b5035611c09565b61070b600480360360408110156106f457600080fd5b508035906020013567ffffffffffffffff16611fcf565b6040805167ffffffffffffffff9092168252519081900360200190f35b61070b6004803603602081101561073e57600080fd5b50356124bd565b61070b6004803603602081101561075b57600080fd5b81019060208101813564010000000081111561077657600080fd5b82018360208201111561078857600080fd5b803590602001918460208302840111640100000000831117156107aa57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506124d9945050505050565b6102d5600480360360808110156107fe57600080fd5b5080359060208101359060408101359060600135612638565b6105336004803603604081101561082d57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135612766565b6103786004803603604081101561086657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602001351661279d565b6108a8600480360360208110156108a157600080fd5b50356127d5565b6040805192835260208301919091528051918290030190f35b61021d600480360360208110156108d757600080fd5b503561293b565b6108e733612db1565b6109225760405162461bcd60e51b815260040180806020018281038252602e8152602001806142cd602e913960400191505060405180910390fd5b60065473ffffffffffffffffffffffffffffffffffffffff16156109775760405162461bcd60e51b815260040180806020018281038252602a8152602001806144ac602a913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166109c95760405162461bcd60e51b81526004018080602001828103825260238152602001806143916023913960400191505060405180910390fd5b6109d281612df0565b50565b60038054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a7f5780601f10610a5457610100808354040283529160200191610a7f565b820191906000526020600020905b815481529060010190602001808311610a6257829003601f168201915b5050505050905090565b6000610a9d610a96612e37565b8484612e3b565b5060015b92915050565b600080600080600080600080610abb6140f7565b506000898152600a60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484018590527001000000000000000000000000000000008304821695840186905278010000000000000000000000000000000000000000000000009092041660608301819052909b509199509197509550610b4f6140f7565b50505060009788525050600b60209081526040968790208751608081018952905467ffffffffffffffff808216808452680100000000000000008304821694840185905270010000000000000000000000000000000083049091169983018a9052780100000000000000000000000000000000000000000000000090910460ff161515606090920182905296989597949693959394919391925090565b60008181526008602052604081205467ffffffffffffffff16610c0f8382611b02565b9150505b919050565b60025490565b6000610c2b848484612f4e565b610cbb84610c37612e37565b610cb6856040518060600160405280602881526020016143426028913973ffffffffffffffffffffffffffffffffffffffff8a16600090815260016020526040812090610c82612e37565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002054919063ffffffff6130f616565b612e3b565b5060019392505050565b6000806000610cd386610bec565b92506000807f000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a373ffffffffffffffffffffffffffffffffffffffff166326d6c97b896040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015610d4957600080fd5b505afa158015610d5d573d6000803e3d6000fd5b505050506040513d6080811015610d7357600080fd5b50805160409091015190925067ffffffffffffffff169050610d9488611c09565b610dcf5760405162461bcd60e51b815260040180806020018281038252602f81526020018061423e602f913960400191505060405180910390fd5b610dd76140f7565b506000858152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481169483019490945270010000000000000000000000000000000081048416928201929092527801000000000000000000000000000000000000000000000000909104821660608201529190610e6b9089168463ffffffff61318d16565b90506000610e7882611893565b604080517f23b872dd00000000000000000000000000000000000000000000000000000000815233600482015230602482015267ffffffffffffffff8c1660448201529051919250869173ffffffffffffffffffffffffffffffffffffffff8316916323b872dd9160648083019260209291908290030181600087803b158015610f0157600080fd5b505af1158015610f15573d6000803e3d6000fd5b505050506040513d6020811015610f2b57600080fd5b5060009050610f4183600a63ffffffff6131ed16565b73ffffffffffffffffffffffffffffffffffffffff8d1660009081526009602090815260408083208e84529091529020805491925090610f9a90610f959067ffffffffffffffff168463ffffffff61322f16565b613289565b81547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001667ffffffffffffffff91821617808355610fec91610f95916801000000000000000090048116908f1661322f565b815467ffffffffffffffff9190911668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161781556110468d611041868563ffffffff6132d616565b613318565b6110503083613318565b600754611063908663ffffffff61322f16565b600755855161108a90610f959067ffffffffffffffff908116908f1663ffffffff61322f16565b67ffffffffffffffff908116875260408701516110b291610f9591168463ffffffff61322f16565b67ffffffffffffffff908116604080890191825260008e8152600a60209081529181208a518154938c0151945160608d0151871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff918816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff97891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff949099167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009097169690961792909216969096179490941692909217939093169190911790556111d6858463ffffffff6132d616565b90508d73ffffffffffffffffffffffffffffffffffffffff168f7f5a0def86b68ea53595ef32019b93a42eedf7c609407f51834703faa48bd592d08e848760405180848152602001838152602001828152602001935050505060405180910390a38b61124182613289565b61124a85613289565b9b509b509b5050505050505050505093509350939050565b60055460ff1690565b6000610a9d611278612e37565b84610cb68560016000611289612e37565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918c16815292529020549063ffffffff61322f16565b60006112d782610bec565b905060008060007f000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a373ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561134f57600080fd5b505afa158015611363573d6000803e3d6000fd5b505050506040513d608081101561137957600080fd5b5080516020820151604090920151909450909250905067ffffffffffffffff81166113eb576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b6000806113f661343b565b91509150600061141b838567ffffffffffffffff168461141461357a565b8903611975565b90508061146f576040805162461bcd60e51b815260206004820152601b60248201527f74686520534254206973206e6f7420696e20656d657267656e63790000000000604482015290519081900360640190fd5b60006114796140f7565b50506000878152600a60209081526040918290208251608081018452905467ffffffffffffffff8082168084526801000000000000000083048216948401949094527001000000000000000000000000000000008204811694830194909452780100000000000000000000000000000000000000000000000090049092166060830152908161153257604081015167ffffffffffffffff1615611524576115248a600080600161357e565b5050505050505050506109d2565b506000888152600a6020908152604080832080547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016905560065481517f9da326ef000000000000000000000000000000000000000000000000000000008152600481018e905267ffffffffffffffff8616602482015260016044820152915173ffffffffffffffffffffffffffffffffffffffff90911693639da326ef93606480850194919392918390030190829087803b1580156115f157600080fd5b505af1158015611605573d6000803e3d6000fd5b505050506040513d602081101561161b57600080fd5b5050600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051899283169163a9059cbb9160448083019260209291908290030181600087803b1580156116a257600080fd5b505af11580156116b6573d6000803e3d6000fd5b505050506040513d60208110156116cc57600080fd5b505050505050505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146117305760405162461bcd60e51b81526004018080602001828103825260238152602001806142aa6023913960400191505060405180910390fd5b60007f000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a373ffffffffffffffffffffffffffffffffffffffff166326d6c97b866040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b1580156117a357600080fd5b505afa1580156117b7573d6000803e3d6000fd5b505050506040513d60808110156117cd57600080fd5b506040015167ffffffffffffffff16905080611830576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b61183c8585858561357e565b5050505050565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600960209081526040808320938352929052205467ffffffffffffffff80821692680100000000000000009092041690565b6000600754600014156118b9576118b28261271063ffffffff6131ed16565b9050610c13565b610aa16007546118d76118ca610c18565b859063ffffffff61318d16565b9063ffffffff6131ed16565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b60065473ffffffffffffffffffffffffffffffffffffffff1633146119615760405162461bcd60e51b81526004018080602001828103825260238152602001806142aa6023913960400191505060405180910390fd5b61196b8282613c00565b5050565b60075490565b600082630bebc20081111561198b5750630bebc2005b626ebe00831061199f576001915050611a7b565b60006119c1846119b5848063ffffffff61318d16565b9063ffffffff61318d16565b905066072ba304f8000081046000806119d9836127d5565b9150915060006119e88b613d3c565b905060006119f58b613d3c565b90506000611a19611a0c858463ffffffff613d9c16565b849063ffffffff613e7f16565b90506000611a3f83611a3381818c8b63ffffffff613d9c16565b9063ffffffff613d9c16565b905060008083131580611a6e575081611a6b680118188ff217800000611a33868063ffffffff613d9c16565b13155b9a50505050505050505050505b949350505050565b60048054604080516020601f60027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015610a7f5780601f10610a5457610100808354040283529160200191610a7f565b6040805160208082019490945260c09290921b7fffffffffffffffff00000000000000000000000000000000000000000000000016828201527f6c69656e0000000000000000000000000000000000000000000000000000000060488301528051808303602c018152604c9092019052805191012090565b6000610a9d611b87612e37565b84610cb68560405180606001604052806025815260200161451c6025913960016000611bb1612e37565b73ffffffffffffffffffffffffffffffffffffffff908116825260208083019390935260409182016000908120918d1681529252902054919063ffffffff6130f616565b6000610a9d611c02612e37565b8484612f4e565b60008060007f000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a373ffffffffffffffffffffffffffffffffffffffff166326d6c97b856040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b158015611c7f57600080fd5b505afa158015611c93573d6000803e3d6000fd5b505050506040513d6080811015611ca957600080fd5b506020810151604090910151909250905067ffffffffffffffff8116611d005760405162461bcd60e51b815260040180806020018281038252602a815260200180614142602a913960400191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000003f480611d2961357a565b018211611d675760405162461bcd60e51b815260040180806020018281038252603c81526020018061418e603c913960400191505060405180910390fd5b620186a067ffffffffffffffff82160667ffffffffffffffff16600014611dbf5760405162461bcd60e51b81526004018080602001828103825260228152602001806144fa6022913960400191505060405180910390fd5b600654604080517fecfb314d00000000000000000000000000000000000000000000000000000000815260048101879052905160009273ffffffffffffffffffffffffffffffffffffffff169163ecfb314d916024808301926020929190829003018186803b158015611e3157600080fd5b505afa158015611e45573d6000803e3d6000fd5b505050506040513d6020811015611e5b57600080fd5b5051600654604080517f9737d6fd00000000000000000000000000000000000000000000000000000000815260048101849052905192935073ffffffffffffffffffffffffffffffffffffffff90911691639737d6fd91602480820192602092909190829003018186803b158015611ed257600080fd5b505afa158015611ee6573d6000803e3d6000fd5b505050506040513d6020811015611efc57600080fd5b505167ffffffffffffffff1615611f5a576040805162461bcd60e51b815260206004820152601860248201527f7468697320534254206973206f6e20612061756369746f6e0000000000000000604482015290519081900360640190fd5b600080611f6561343b565b915091506000611f8a838667ffffffffffffffff1684611f8361357a565b8a03612638565b6040805182158152905191925089917fea0241146eaea8e64956684a8df42cc134671b71fcc2b474bcbd63f30b32984f9181900360200190a215979650505050505050565b600080611fdb84610bec565b90506000807f000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a373ffffffffffffffffffffffffffffffffffffffff166326d6c97b876040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561205157600080fd5b505afa158015612065573d6000803e3d6000fd5b505050506040513d608081101561207b57600080fd5b50805160409091015190925067ffffffffffffffff169050806120e5576040805162461bcd60e51b815260206004820152601f60248201527f74686520626f6e64206973206e6f742074686520666f726d206f662053425400604482015290519081900360640190fd5b6120ed6140f7565b506000838152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481168386015270010000000000000000000000000000000082048116838501527801000000000000000000000000000000000000000000000000909104166060808301919091528251908101909252603d8083529093926121db92610f9592879261426d908301396121ce612196610c18565b6040518060600160405280602c8152602001614212602c91396121ce6007548f67ffffffffffffffff1661318d90919063ffffffff16565b919063ffffffff613ee416565b905061220b610f958867ffffffffffffffff16846060015167ffffffffffffffff1661322f90919063ffffffff16565b67ffffffffffffffff90811660608401526122299033908916613c00565b604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015267ffffffffffffffff831660248201529051859173ffffffffffffffffffffffffffffffffffffffff83169163a9059cbb916044808201926020929091908290030181600087803b1580156122aa57600080fd5b505af11580156122be573d6000803e3d6000fd5b505050506040513d60208110156122d457600080fd5b50506040805167ffffffffffffffff808b16825284166020820152815133928c927f87efbe374e86e4f26b4593306372ef7f3c1fa4ed256c9d4f7400d00b3f729114929081900390910190a361234c61233d67ffffffffffffffff84168663ffffffff61318d16565b6007549063ffffffff6132d616565b600755825161237390610f959067ffffffffffffffff90811690851663ffffffff6132d616565b67ffffffffffffffff9081168452602084015161239e91610f9591811690851663ffffffff61322f16565b67ffffffffffffffff90811660208086019182526000988952600a905260409788902085518154925199870151606090970151841678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff978516700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff9b861668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff939096167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009095169490941791909116939093179890981617939093169290921790945550919250505092915050565b60086020526000908152604090205467ffffffffffffffff1681565b600080805b83518110156125a25760006125058583815181106124f857fe5b6020026020010151613f49565b90506125218367ffffffffffffffff831663ffffffff61322f16565b92503373ffffffffffffffffffffffffffffffffffffffff1685838151811061254657fe5b60200260200101517fb931a8416f2f16d5400a0cce933872df77c3cfcadae032ff6b1646e8cdc12a3c83604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390a3506001016124de565b50604080517fa9059cbb000000000000000000000000000000000000000000000000000000008152336004820152602481018390529051309163a9059cbb9160448083019260209291908290030181600087803b15801561260257600080fd5b505af1158015612616573d6000803e3d6000fd5b505050506040513d602081101561262c57600080fd5b50610c0f905081613289565b60006002850261c350850210801561265257506212750082105b1561265f57506000611a7b565b630bebc20083111561267357506001611a7b565b626ebe00821061268557506001611a7b565b600061269b836119b5868063ffffffff61318d16565b905066072ba304f8000081046000806126b3836127d5565b9150915060006126c28a613d3c565b905060006126cf8a613d3c565b905060006127086126eb6003611a33878663ffffffff613d9c16565b6126fc85600263ffffffff613d9c16565b9063ffffffff613e7f16565b905060006127256009611a33858181818e8d63ffffffff613d9c16565b905060008083131580612754575081612751680118188ff217800000611a33868063ffffffff613d9c16565b13155b9e9d5050505050505050505050505050565b600960209081526000928352604080842090915290825290205467ffffffffffffffff808216916801000000000000000090041682565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60008062c3204083116127ef575060009050612af8612936565b630394b7b183116128085750615a4090506115bc612936565b6307f7cae4831161284057506206400090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81fc612936565b630bf3790083116128785750621f126990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1e88612936565b630fc0bf0183116128b0575062817ac190507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffae894612936565b63134fd90083116128e957506301af0c8990507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4f33b612936565b6040805162461bcd60e51b815260206004820152600e60248201527f6e6f742061636365707461626c65000000000000000000000000000000000000604482015290519081900360640190fd5b915091565b600061294682610bec565b90506000807f000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a373ffffffffffffffffffffffffffffffffffffffff166326d6c97b856040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b1580156129bc57600080fd5b505afa1580156129d0573d6000803e3d6000fd5b505050506040513d60808110156129e657600080fd5b50805160209091015190925090507f000000000000000000000000000000000000000000000000000000000003f480612a1d61357a565b01811115612a5c5760405162461bcd60e51b815260040180806020018281038252602e81526020018061447e602e913960400191505060405180910390fd5b6000612a666140f7565b50506000838152600a60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484019490945270010000000000000000000000000000000082048116948301949094527801000000000000000000000000000000000000000000000000900490921660608301529081612b1b57604081015167ffffffffffffffff1615612b1157612b1186600080600161357e565b50505050506109d2565b506000848152600a6020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001690557f0000000000000000000000000000000000000000000000000000000000015f90612b7961357a565b018211612c3d57600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810188905267ffffffffffffffff8416602482015260016044820152905173ffffffffffffffffffffffffffffffffffffffff90921691639da326ef916064808201926020929091908290030181600087803b158015612c0b57600080fd5b505af1158015612c1f573d6000803e3d6000fd5b505050506040513d6020811015612c3557600080fd5b50612cf89050565b600654604080517f9da326ef0000000000000000000000000000000000000000000000000000000081526004810188905267ffffffffffffffff84166024820152600060448201819052915173ffffffffffffffffffffffffffffffffffffffff90931692639da326ef92606480840193602093929083900390910190829087803b158015612ccb57600080fd5b505af1158015612cdf573d6000803e3d6000fd5b505050506040513d6020811015612cf557600080fd5b50505b600654604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff928316600482015267ffffffffffffffff841660248201529051859283169163a9059cbb9160448083019260209291908290030181600087803b158015612d7d57600080fd5b505af1158015612d91573d6000803e3d6000fd5b505050506040513d6020811015612da757600080fd5b5050505050505050565b7f0000000000000000000000008cb13a8271efa096b407ec8a20aa14c01e74c42773ffffffffffffffffffffffffffffffffffffffff90811691161490565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b3390565b73ffffffffffffffffffffffffffffffffffffffff8316612e8d5760405162461bcd60e51b81526004018080602001828103825260248152602001806144326024913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612edf5760405162461bcd60e51b81526004018080602001828103825260228152602001806141ca6022913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316612fa05760405162461bcd60e51b815260040180806020018281038252602581526020018061440d6025913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216612ff25760405162461bcd60e51b815260040180806020018281038252602381526020018061411f6023913960400191505060405180910390fd5b612ffd8383836140c3565b61304d816040518060600160405280602681526020016141ec6026913973ffffffffffffffffffffffffffffffffffffffff8616600090815260208190526040902054919063ffffffff6130f616565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220939093559084168152205461308f908263ffffffff61322f16565b73ffffffffffffffffffffffffffffffffffffffff8084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b600081848411156131855760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561314a578181015183820152602001613132565b50505050905090810190601f1680156131775780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008261319c57506000610aa1565b828202828482816131a957fe5b04146131e65760405162461bcd60e51b81526004018080602001828103825260218152602001806142fb6021913960400191505060405180910390fd5b9392505050565b60006131e683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250613ee4565b6000828201838110156131e6576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006801000000000000000082106132d25760405162461bcd60e51b815260040180806020018281038252602681526020018061431c6026913960400191505060405180910390fd5b5090565b60006131e683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506130f6565b73ffffffffffffffffffffffffffffffffffffffff8216613380576040805162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015290519081900360640190fd5b61338c600083836140c3565b60025461339f908263ffffffff61322f16565b60025573ffffffffffffffffffffffffffffffffffffffff82166000908152602081905260409020546133d8908263ffffffff61322f16565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b600080600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3e6ba946040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156134a857600080fd5b505af11580156134bc573d6000803e3d6000fd5b505050506040513d60208110156134d257600080fd5b5051600554604080517f3af2888b000000000000000000000000000000000000000000000000000000008152905192945061010090910473ffffffffffffffffffffffffffffffffffffffff1691633af2888b916004808201926020929091908290030181600087803b15801561354857600080fd5b505af115801561355c573d6000803e3d6000fd5b505050506040513d602081101561357257600080fd5b505190509091565b4290565b600061358985610bec565b90506135936140f7565b506000818152600b60209081526040918290208251608081018452905467ffffffffffffffff80821680845268010000000000000000830482169484019490945270010000000000000000000000000000000082048116948301949094527801000000000000000000000000000000000000000000000000900460ff16151560608201529161362791610f9591871661322f565b67ffffffffffffffff9081168252602082015161365291610f9591811690881663ffffffff61322f16565b67ffffffffffffffff1660208201528215613ae85761366f6140f7565b506000828152600a602090815260408083208151608081018352905467ffffffffffffffff808216835268010000000000000000820481169483019490945270010000000000000000000000000000000081048416928201839052780100000000000000000000000000000000000000000000000090049092166060830152909190819061370490600963ffffffff61318d16565b9050600061372982856040015167ffffffffffffffff1661322f90919063ffffffff16565b9050600061375c866020015167ffffffffffffffff16866060015167ffffffffffffffff1661322f90919063ffffffff16565b9050828111156137bc5780821061379457606085015161378d90839067ffffffffffffffff1663ffffffff6132d616565b93506137b7565b60608501516137b490829067ffffffffffffffff1663ffffffff6132d616565b93505b6137ee565b6137eb866020015167ffffffffffffffff16866040015167ffffffffffffffff1661322f90919063ffffffff16565b93505b50505060007f000000000000000000000000acdc94b9f187fa7ee3c5cf0969c2faccab4e37a373ffffffffffffffffffffffffffffffffffffffff166326d6c97b8a6040518263ffffffff1660e01b81526004018082815260200191505060806040518083038186803b15801561386457600080fd5b505afa158015613878573d6000803e3d6000fd5b505050506040513d608081101561388e57600080fd5b5060400151905061389f3083613c00565b6138d1610f95856020015167ffffffffffffffff16856060015167ffffffffffffffff1661322f90919063ffffffff16565b67ffffffffffffffff90811660608501528451613901916138fc91811690841663ffffffff61318d16565b6140c8565b8351602084015161392991610f959167ffffffffffffffff908116911663ffffffff61322f16565b67ffffffffffffffff1660208085018290526040805160608101909152603880825261398193610f9593909291906143b49083013960608701516121ce9067ffffffffffffffff166305f5e10063ffffffff61318d16565b67ffffffffffffffff90811660408087019190915260016060870181905260008c8152600860205291909120546139c492610f959291169063ffffffff61322f16565b60008a8152600860209081526040808320805467ffffffffffffffff9586167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000091821617909155898452600a835292819020875181549389015192890151606090990151861678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff998716700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff94881668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff93909816959096169490941716949094171691909117949094169390931790925550505b6000918252600b60209081526040928390208251815492840151948401516060909401517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090931667ffffffffffffffff918216177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000095821695909502949094177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff167001000000000000000000000000000000009490931693909302919091177fffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009115159190910217905550505050565b73ffffffffffffffffffffffffffffffffffffffff8216613c525760405162461bcd60e51b81526004018080602001828103825260218152602001806143ec6021913960400191505060405180910390fd5b613c5e826000836140c3565b613cae8160405180606001604052806022815260200161416c6022913973ffffffffffffffffffffffffffffffffffffffff8516600090815260208190526040902054919063ffffffff6130f616565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260208190526040902055600254613ce7908263ffffffff6132d616565b60025560408051828152905160009173ffffffffffffffffffffffffffffffffffffffff8516917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35050565b60007f800000000000000000000000000000000000000000000000000000000000000082106132d25760405162461bcd60e51b81526004018080602001828103825260288152602001806144566028913960400191505060405180910390fd5b600082613dab57506000610aa1565b827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff148015613df957507f800000000000000000000000000000000000000000000000000000000000000082145b15613e355760405162461bcd60e51b815260040180806020018281038252602781526020018061436a6027913960400191505060405180910390fd5b82820282848281613e4257fe5b05146131e65760405162461bcd60e51b815260040180806020018281038252602781526020018061436a6027913960400191505060405180910390fd5b6000818303818312801590613e945750838113155b80613ea95750600083128015613ea957508381135b6131e65760405162461bcd60e51b81526004018080602001828103825260248152602001806144d66024913960400191505060405180910390fd5b60008183613f335760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561314a578181015183820152602001613132565b506000838581613f3f57fe5b0495945050505050565b6000613f536140f7565b506000828152600b60209081526040918290208251608081018452905467ffffffffffffffff80821683526801000000000000000082048116938301939093527001000000000000000000000000000000008104909216928101929092527801000000000000000000000000000000000000000000000000900460ff16151560608201819052613fe7576000915050610c13565b33600090815260096020818152604080842087855290915280832080547fffffffffffffffffffffffffffffffff0000000000000000000000000000000081169091559084015167ffffffffffffffff80831694680100000000000000009093048116939116919061405a90859061318d565b6140726305f5e1006118d7858763ffffffff61318d16565b11156140a55761408984600963ffffffff61318d16565b6140a16305f5e1006118d7858763ffffffff61318d16565b0390505b6140b8610f95828663ffffffff6140e116565b979650505050505050565b505050565b6007546140db908263ffffffff6132d616565b60075550565b60008183106140f057816131e6565b5090919050565b6040805160808101825260008082526020820181905291810182905260608101919091529056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737374686520626f6e6420646f6573206e6f74206d6174636820746f2074686520666f726d206f662053425445524332303a206275726e20616d6f756e7420657863656564732062616c616e636561207265717565737420746f20686f6c6420616e2061756374696f6e206f662074686520626f6e642068617320616c7265616479206578706972656445524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e636573797374656d206572726f723a20746f74616c537570706c79206e65766572206265636f6d6573207a65726f53425420776974682074686520626f6e644944206973206e6f742063757272656e746c792061636365707461626c6573797374656d206572726f723a20736f6c6964537472696b655072696365206e65766572206265636f6d6573207a65726f205b756e6c6f636b5342545d6d73672e73656e646572206d7573742062652061756374696f6e20636f6e74726163746f6e6c79206465706c6f79657220697320616c6c6f77656420746f2063616c6c20746869732066756e6374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e203634206269747345524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e63655369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77636f6e74726163742073686f756c64206265206e6f6e2d7a65726f206164647265737373797374656d3a2074686520746f74616c20756e6c6f636b20616d6f756e742073686f756c64206265206e6f6e2d7a65726f2076616c756545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737353616665436173743a2076616c756520646f65736e27742066697420696e20616e20696e743235366d61747572697479206973206c61746572207468616e2074686520726567756c61722061756374696f6e5370616e7468652061756374696f6e20636f6e747261637420697320616c726561647920726567697374657265645369676e6564536166654d6174683a207375627472616374696f6e206f766572666c6f7774686520737472696b65207072696365206e65656420746f20626520242031302a5845524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220ec31e73691d5223cd49ce0de66f4abd57af73830d3eba761318d911fb47bb1dc64736f6c63430006060033

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

000000000000000000000000120a078fdc516a1a98bbecb9e961f8741ac7ac82000000000000000000000000acDC94b9f187fA7ee3C5cf0969c2fAcCaB4E37A3000000000000000000000000000000000000000000000000000000000003f4800000000000000000000000000000000000000000000000000000000000015f90

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

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000120a078fdc516a1a98bbecb9e961f8741ac7ac82
Arg [1] : 000000000000000000000000acDC94b9f187fA7ee3C5cf0969c2fAcCaB4E37A3
Arg [2] : 000000000000000000000000000000000000000000000000000000000003f480
Arg [3] : 0000000000000000000000000000000000000000000000000000000000015f90


Deployed Bytecode Sourcemap

54721:26275:0:-:0;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;54721:26275:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;32946:395:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;32946:395:0;;;;:::i;:::-;;17348: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;17348:83:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19545:210;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;19545:210:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;64308:1293;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;64308:1293:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65948:262;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;65948:262:0;;:::i;:::-;;;;;;;;;;;;;;;;18423:100;;;:::i;20229:454::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;20229:454:0;;;;;;;;;;;;;;;;;;:::i;68306:2415::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;68306:2415:0;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18275:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;21092:300;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;21092:300:0;;;;;;;;;:::i;75997:1679::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;75997:1679:0;;:::i;77840:614::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;77840:614:0;;;;;;;;;;;;;;;;;;;;;;;;;:::i;66218:284::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;66218:284:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78652:333;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;78652:333:0;;:::i;18586:119::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;18586:119:0;;;;:::i;70865:243::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;70865:243:0;;;;;;;;;:::i;65609:113::-;;;:::i;45386:1063::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;45386:1063:0;;;;;;;;;;;;;;;;;:::i;17550:87::-;;;:::i;65730:210::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;65730:210:0;;;;;;;;;:::i;21895:400::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;21895:400:0;;;;;;;;;:::i;18918:216::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;18918:216:0;;;;;;;;;:::i;66889:1234::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;66889:1234:0;;:::i;72060:1973::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;72060:1973:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;55392:53;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;55392:53:0;;:::i;80331:662::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;80331:662:0;;;;;;;;27:11:-1;11:28;;8:2;;;52:1;49;42:12;8:2;80331:662:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;80331:662: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;80331:662:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;80331:662:0;;-1:-1:-1;80331:662:0;;-1:-1:-1;;;;;80331:662:0:i;46952:1780::-;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;46952:1780:0;;;;;;;;;;;;;;;;;:::i;55767:70::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;55767:70:0;;;;;;;;;:::i;19197:201::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;19197:201:0;;;;;;;;;;;:::i;44316:703::-;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;44316:703:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;74127:1589;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;74127:1589:0;;:::i;32946:395::-;32155:23;32167:10;32155:11;:23::i;:::-;32133:119;;;;-1:-1:-1;;;32133:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33060:16:::1;::::0;33052:39:::1;33060:16;33052:39:::0;33030:131:::1;;;;-1:-1:-1::0;;;33030:131:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33194:29;::::0;::::1;33172:114;;;;-1:-1:-1::0;;;33172:114:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33297:36;33317:15;33297:19;:36::i;:::-;32946:395:::0;:::o;17348:83::-;17418:5;17411:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17385:13;;17411:12;;17418:5;;17411:12;;17418:5;17411:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17348:83;:::o;19545:210::-;19664:4;19686:39;19695:12;:10;:12::i;:::-;19709:7;19718:6;19686:8;:39::i;:::-;-1:-1:-1;19743:4:0;19545:210;;;;;:::o;64308:1293::-;64427:21;64463:23;64501:26;64542:22;64579:28;64622:29;64666:33;64714:29;64777:41;;:::i;:::-;-1:-1:-1;64831:28:0;;;;:20;:28;;;;;;;;;64777:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64777:82:0;;-1:-1:-1;64777:82:0;;-1:-1:-1;64777:82:0;-1:-1:-1;65146:46:0;;:::i;:::-;-1:-1:-1;;;65205:26:0;;;;-1:-1:-1;;65205:18:0;:26;;;;;;;;;65146:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64308:1293;;;;;;;;65146:85;;;;;;-1:-1:-1;65146:85:0;64308:1293::o;65948:262::-;66056:7;66112:27;;;:19;:27;;;;;;;;66157:45;66132:6;66112:27;66157:14;:45::i;:::-;66150:52;;;65948:262;;;;:::o;18423:100::-;18503:12;;18423:100;:::o;20229:454::-;20369:4;20386:36;20396:6;20404:9;20415:6;20386:9;:36::i;:::-;20433:220;20456:6;20477:12;:10;:12::i;:::-;20504:138;20560:6;20504:138;;;;;;;;;;;;;;;;;:19;;;;;;;:11;:19;;;;;;20524:12;:10;:12::i;:::-;20504:33;;;;;;;;;;;;;-1:-1:-1;20504:33:0;;;:138;;:37;:138;:::i;:::-;20433:8;:220::i;:::-;-1:-1:-1;20671:4:0;20229:454;;;;;:::o;68306:2415::-;68476:14;68505:25;68545:23;68605:24;68622:6;68605:16;:24::i;:::-;68596:33;;68738:24;68792:26;68835:18;:26;;;68862:6;68835:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;68835:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;68835:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;68835:34:0;;;;;;;;;-1:-1:-1;68723:146:0;;;-1:-1:-1;68902:23:0;68918:6;68902:15;:23::i;:::-;68880:120;;;;-1:-1:-1;;;68880:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69019:41;;:::i;:::-;-1:-1:-1;69073:28:0;;;;:20;:28;;;;;;;;69019:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69073:28;69209:36;;:16;;69226:18;69209:36;:16;:36;:::i;:::-;69181:64;;69256:20;69279:31;69292:17;69279:12;:31::i;:::-;69383:71;;;;;;69414:10;69383:71;;;;69434:4;69383:71;;;;;;;;;;;;;69256:54;;-1:-1:-1;69355:16:0;;69383:30;;;;;;:71;;;;;;;;;;;;;;69323:23;69383:30;:71;;;2:2:-1;;;;27:1;24;17:12;2:2;69383:71:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;69383:71:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;69555:18:0;;-1:-1:-1;69576:20:0;:12;69593:2;69576:20;:16;:20;:::i;:::-;69643:23;;;69607:33;69643:23;;;:12;:23;;;;;;;;:31;;;;;;;;69713:39;;69555:41;;-1:-1:-1;69643:31:0;69713:94;;:69;;:39;;69555:41;69713:69;:57;:69;:::i;:::-;:92;:94::i;:::-;69685:122;;;;;;;;;;;;69849:99;;:74;;:42;;;;;;:74;;:60;:74::i;:99::-;69818:130;;;;;;;;;;;;;;;;69961:46;69967:9;69978:28;:12;69995:10;69978:28;:16;:28;:::i;:::-;69961:5;:46::i;:::-;70018:32;70032:4;70039:10;70018:5;:32::i;:::-;70083:19;;:42;;70107:17;70083:42;:23;:42;:::i;:::-;70061:19;:64;70176:51;;:108;;:83;;;:69;;;;:83;;;:69;:83;:::i;:108::-;70136:148;;;;;;70334:50;;;;:105;;:80;;:68;70403:10;70334:80;:68;:80;:::i;:105::-;70295:144;;;;:36;;;;:144;;;70450:28;;;;:20;:28;;;;;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70531:28;:12;70548:10;70531:28;:16;:28;:::i;:::-;70508:51;;70595:9;70575:64;;70587:6;70575:64;70606:6;70614:12;70628:10;70575:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70658:6;70666:23;:12;:21;:23::i;:::-;70691:21;:10;:19;:21::i;:::-;70650:63;;;;;;;;;;;;;;;68306:2415;;;;;;;:::o;18275:83::-;18341:9;;;;18275:83;:::o;21092:300::-;21207:4;21229:133;21252:12;:10;:12::i;:::-;21279:7;21301:50;21340:10;21301:11;:25;21313:12;:10;:12::i;:::-;21301:25;;;;;;;;;;;;;;;;;;-1:-1:-1;21301:25:0;;;:34;;;;;;;;;;;:50;:38;:50;:::i;75997:1679::-;76070:14;76087:24;76104:6;76087:16;:24::i;:::-;76070:41;;76137:24;76176:16;76207:30;76254:18;:26;;;76281:6;76254:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;76254:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;76254:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;76254:34:0;;;;;;;;;;;;;-1:-1:-1;76254:34:0;;-1:-1:-1;76254:34:0;-1:-1:-1;76321:28:0;;;76299:109;;;;;-1:-1:-1;;;76299:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;76422:19;76443:18;76465:16;:14;:16::i;:::-;76421:60;;;;76492:13;76508:162;76536:11;76562:23;76508:162;;76600:10;76636:23;:21;:23::i;:::-;76625:8;:34;76508:13;:162::i;:::-;76492:178;;76689:8;76681:48;;;;;-1:-1:-1;;;76681:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;76742:29;76803:41;;:::i;:::-;-1:-1:-1;;76861:28:0;;;;:20;:28;;;;;;;;;76803:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76985:27;76981:232;;77037:36;;;;:41;;;77033:140;;77103:50;77134:6;77142:1;77145;77148:4;77103:30;:50::i;:::-;77191:7;;;;;;;;;;;76981:232;-1:-1:-1;77234:28:0;;;;:20;:28;;;;;;;;77227:58;;;;;;77309:16;;:67;;;;;;;;;;;77227:58;77309:67;;;;;;77227:58;77309:67;;;;;;:16;;;;;:29;;:67;;;;;77234:28;;77309:67;;;;;;;;;:16;:67;;;2:2:-1;;;;27:1;24;17:12;2:2;77309:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77309:67:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;77603:16:0;;77554:114;;;;;;:26;77603:16;;;77554:114;;;;;;;;;;;;;77515:16;;77554:26;;;;;:114;;;;;77309:67;;77554:114;;;;;;;77435:36;77554:26;:114;;;2:2:-1;;;;27:1;24;17:12;2:2;77554:114:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77554:114:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;;;;;;;75997:1679:0;:::o;77840:614::-;78062:16;;;;78040:10;:39;78018:124;;;;-1:-1:-1;;;78018:124:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78160:24;78190:18;:26;;;78217:6;78190:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;78190:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;78190:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;78190:34:0;;;78155:69;;;-1:-1:-1;78243:21:0;78235:65;;;;;-1:-1:-1;;;78235:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;78311:135;78356:6;78377:13;78405:9;78429:6;78311:30;:135::i;:::-;77840:614;;;;;:::o;66218:284::-;66391:18;;;;;66337:6;66391:18;;;:12;:18;;;;;;;;:26;;;;;;;:37;;;;;;66443:40;;;;;;66218:284::o;78652:333::-;78767:20;78809:19;;78832:1;78809:24;78805:92;;;78857:28;:17;78879:5;78857:28;:21;:28;:::i;:::-;78850:35;;;;78805:92;78916:61;78957:19;;78916:36;78938:13;:11;:13::i;:::-;78916:17;;:36;:21;:36;:::i;:::-;:40;:61;:40;:61;:::i;18586:119::-;18679:18;;18652:7;18679:18;;;;;;;;;;;;18586:119::o;70865:243::-;70987:16;;;;70965:10;:39;70943:124;;;;-1:-1:-1;;;70943:124:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71078:22;71084:7;71093:6;71078:5;:22::i;:::-;70865:243;;:::o;65609:113::-;65695:19;;65609:113;:::o;45386:1063::-;45567:4;45598:10;45629:9;45623:15;;45619:94;;;-1:-1:-1;45661:9:0;45619:94;45744:8;45727:13;:25;45723:111;;45776:4;45769:11;;;;;45723:111;45844:14;45861:31;45878:13;45861:12;45869:3;;45861:12;:7;:12;:::i;:::-;:16;:31;:16;:31;:::i;:::-;45844:48;-1:-1:-1;45930:24:0;45920:35;;45905:12;;46029:28;45920:35;46029:22;:28::i;:::-;46001:56;;;;46068:10;46081:22;:11;:20;:22::i;:::-;46068:35;;46114:10;46127:31;:20;:29;:31::i;:::-;46114:44;-1:-1:-1;46169:10:0;46182:21;46190:12;:3;46114:44;46190:12;:7;:12;:::i;:::-;46182:3;;:21;:7;:21;:::i;:::-;46169:34;-1:-1:-1;46277:11:0;46291:42;46329:3;46291:33;46329:3;46291:33;46298:6;46310:4;46291:24;:18;:24;:::i;:::-;:28;:33;:28;:33;:::i;:42::-;46277:56;;46344:13;46367:1;46360:3;:8;;:55;;;-1:-1:-1;46411:4:0;46372:35;46389:17;46372:12;46380:3;;46372:12;:7;:12;:::i;:35::-;:43;;46360:55;46344:71;-1:-1:-1;;;;;;;;;;;45386:1063:0;;;;;;;:::o;17550:87::-;17622:7;17615:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17589:13;;17615:14;;17622:7;;17615:14;;17622:7;17615:14;;;;;;;;;;;;;;;;;;;;;;;;65730:210;65892:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26:21:-1;;;22:32;;6:49;;65892:39:0;;;;;;65882:50;;;;;;65730:210::o;21895:400::-;22015:4;22037:228;22060:12;:10;:12::i;:::-;22087:7;22109:145;22166:15;22109:145;;;;;;;;;;;;;;;;;:11;:25;22121:12;:10;:12::i;:::-;22109:25;;;;;;;;;;;;;;;;;;-1:-1:-1;22109:25:0;;;:34;;;;;;;;;;;:145;;:38;:145;:::i;18918:216::-;19040:4;19062:42;19072:12;:10;:12::i;:::-;19086:9;19097:6;19062:9;:42::i;66889:1234::-;66999:4;67024:16;67042:25;67073:18;:40;;;67114:6;67073:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67073:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67073:48:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;67073:48:0;;;;;;;;;;;-1:-1:-1;67073:48:0;-1:-1:-1;67154:23:0;;;67132:115;;;;-1:-1:-1;;;67132:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67317:12;67291:23;:21;:23::i;:::-;:38;67280:8;:49;67258:159;;;;-1:-1:-1;;;67258:159:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67472:5;67450:28;;;;:33;;67482:1;67450:33;67428:117;;;;-1:-1:-1;;;67428:117:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67578:16;;:44;;;;;;;;;;;;;;67558:17;;67578:16;;;:36;;:44;;;;;;;;;;;;;;:16;:44;;;2:2:-1;;;;27:1;24;17:12;2:2;67578:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67578:44:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;67578:44:0;67655:16;;:50;;;;;;;;;;;;;;67578:44;;-1:-1:-1;67655:16:0;;;;;:39;;:50;;;;;67578:44;;67655:50;;;;;;;;:16;:50;;;2:2:-1;;;;27:1;24;17:12;2:2;67655:50:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;67655:50:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;67655:50:0;:55;;;67633:129;;;;;-1:-1:-1;;;67633:129:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;67776:21;67799:20;67823:16;:14;:16::i;:::-;67775:64;;;;67850:13;67866:165;67898:13;67926:18;67866:165;;67959:12;67997:23;:21;:23::i;:::-;67986:8;:34;67866:17;:165::i;:::-;68049:37;;;68076:9;;68049:37;;;;67850:181;;-1:-1:-1;68068:6:0;;68049:37;;;;;;;;;68106:9;;66889:1234;-1:-1:-1;;;;;;;66889:1234:0:o;72060:1973::-;72168:6;72192:14;72209:24;72226:6;72209:16;:24::i;:::-;72192:41;;72259:24;72313:26;72356:18;:26;;;72383:6;72356:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;72356:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72356:34:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;72356:34:0;;;;;;;;;-1:-1:-1;72244:146:0;;;-1:-1:-1;72409:23:0;72401:67;;;;;-1:-1:-1;;;72401:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;72487:41;;:::i;:::-;-1:-1:-1;72541:28:0;;;;:20;:28;;;;;;;;72487:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72603:272;;;;;;;;;;;;72487:82;;72541:28;72603:297;;:272;;72768:18;;72603:272;;;;;:132;72673:13;:11;:13::i;:::-;72603:132;;;;;;;;;;;;;;;;;:51;72634:19;;72603:12;:30;;;;:51;;;;:::i;:::-;:69;:132;;:69;:132;:::i;:297::-;72582:318;;72975:107;:82;73044:12;72975:82;;:14;:50;;;:68;;;;:82;;;;:::i;:107::-;72936:146;;;;:36;;;:146;73095:31;;73101:10;;73095:31;;:5;:31::i;:::-;73282:51;;;;;;73309:10;73282:51;;;;;;;;;;;;;73243:16;;73282:26;;;;;;:51;;;;;;;;;;;;;;;73163:36;73282:26;:51;;;2:2:-1;;;;27:1;24;17:12;2:2;73282:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73282:51:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;73351:58:0;;;;;;;;;;;73282:51;73351:58;;;;;73371:10;;73363:6;;73351:58;;;;;;;;;;;73532:84;73570:35;:15;;;73586:18;73570:35;:15;:35;:::i;:::-;73532:19;;;:84;:23;:84;:::i;:::-;73510:19;:106;73667:51;;:107;;:82;;;:69;;;;:82;;;:69;:82;:::i;:107::-;73627:147;;;;;;73827:53;;;;:109;;:84;;:71;;;:84;;;:71;:84;:::i;:109::-;73785:151;;;;:39;;;;:151;;;73949:28;;;;:20;:28;;;;;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;74014:11:0;;-1:-1:-1;;;72060:1973:0;;;;:::o;55392:53::-;;;;;;;;;;;;;;;:::o;80331:662::-;80435:6;;;80501:376;80525:7;:14;80521:1;:18;80501:376;;;80649:21;80673:37;80699:7;80707:1;80699:10;;;;;;;;;;;;;;80673:25;:37::i;:::-;80649:61;-1:-1:-1;80747:39:0;:19;:39;;;;:23;:39;:::i;:::-;80725:61;;80838:10;80806:59;;80826:7;80834:1;80826:10;;;;;;;;;;;;;;80806:59;80850:14;80806:59;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80541:3:0;;80501:376;;;-1:-1:-1;80889:46:0;;;;;;80903:10;80889:46;;;;;;;;;;;;:4;;:13;;:46;;;;;;;;;;;;;;-1:-1:-1;80889:4:0;:46;;;2:2:-1;;;;27:1;24;17:12;2:2;80889:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;80889:46:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;80955:30:0;;-1:-1:-1;80955:19:0;:28;:30::i;46952:1780::-;47137:4;47221:1;47207:15;;47172:32;;;:50;:90;;;;;47255:7;47239:13;:23;47172:90;47154:262;;;-1:-1:-1;47296:5:0;47289:12;;47154:262;47336:9;47323:10;:22;47319:97;;;-1:-1:-1;47369:4:0;47362:11;;47319:97;47447:8;47430:13;:25;47426:111;;-1:-1:-1;47479:4:0;47472:11;;47426:111;47547:14;47564:45;47595:13;47564:26;47579:10;;47564:26;:14;:26;:::i;:45::-;47547:62;-1:-1:-1;47647:24:0;47637:35;;47622:12;;47746:28;47637:35;47746:22;:28::i;:::-;47718:56;;;;48330:10;48343:22;:11;:20;:22::i;:::-;48330:35;;48376:10;48389:31;:20;:29;:31::i;:::-;48376:44;-1:-1:-1;48431:10:0;48444:35;48459:19;48476:1;48459:12;:3;48376:44;48459:12;:7;:12;:::i;:19::-;48444:10;:3;48452:1;48444:10;:7;:10;:::i;:::-;:14;:35;:14;:35;:::i;:::-;48431:48;-1:-1:-1;48553:11:0;48567:49;48614:1;48567:42;48605:3;48567:42;48605:3;48567:42;48574:6;48586:4;48567:24;:18;:24;:::i;:49::-;48553:63;;48627:13;48650:1;48643:3;:8;;:55;;;-1:-1:-1;48694:4:0;48655:35;48672:17;48655:12;48663:3;;48655:12;:7;:12;:::i;:35::-;:43;;48643:55;48627:71;46952:1780;-1:-1:-1;;;;;;;;;;;;;;46952:1780:0:o;55767:70::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;19197:201::-;19363:18;;;;19331:7;19363:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;19197:201::o;44316:703::-;44410:11;44423:10;44463:11;44455:4;:19;44451:561;;-1:-1:-1;44499:1:0;;-1:-1:-1;44502:5:0;44491:17;;44451:561;44538:11;44530:4;:19;44526:486;;-1:-1:-1;44574:9:0;;-1:-1:-1;44585:4:0;44566:24;;44526:486;44620:13;44612:4;:21;44608:404;;-1:-1:-1;44658:9:0;;-1:-1:-1;44669:6:0;44650:26;;44608:404;44706:13;44698:4;:21;44694:318;;-1:-1:-1;44744:11:0;;-1:-1:-1;44757:7:0;44736:29;;44694:318;44795:13;44787:4;:21;44783:229;;-1:-1:-1;44833:11:0;;-1:-1:-1;44846:7:0;44825:29;;44783:229;44884:13;44876:4;:21;44872:140;;-1:-1:-1;44922:11:0;;-1:-1:-1;44935:7:0;44914:29;;44872:140;44976:24;;;-1:-1:-1;;;44976:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;44872:140;44316:703;;;:::o;74127:1589::-;74202:14;74219:24;74236:6;74219:16;:24::i;:::-;74202:41;;74255:24;74281:16;74305:18;:40;;;74346:6;74305:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;74305:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;74305:48:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;74305:48:0;;;;;;;;;-1:-1:-1;74305:48:0;-1:-1:-1;74424:12:0;74398:23;:21;:23::i;:::-;:38;74386:8;:50;;74364:146;;;;-1:-1:-1;;;74364:146:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74523:29;74584:41;;:::i;:::-;-1:-1:-1;;74642:28:0;;;;:20;:28;;;;;;;;;74584:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74766:27;74762:232;;74818:36;;;;:41;;;74814:140;;74884:50;74915:6;74923:1;74926;74929:4;74884:30;:50::i;:::-;74972:7;;;;;;;74762:232;-1:-1:-1;75015:28:0;;;;:20;:28;;;;;75008:58;;;;;;75132:22;75106:23;:21;:23::i;:::-;:48;75094:8;:60;75090:327;;75171:16;;:67;;;;;;;;;;;;;;;;;;;:16;:67;;;;;;:16;;;;;:29;;:67;;;;;;;;;;;;;;;:16;;:67;;;2:2:-1;;;;27:1;24;17:12;2:2;75171:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75171:67:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;75090:327:0;;-1:-1:-1;75090:327:0;;75271:16;;:134;;;;;;;;;;;;;;;;;;;:16;:134;;;;;;;;:16;;;;;:29;;:134;;;;;;;;;;;;;;;;;;:16;:134;;;2:2:-1;;;;27:1;24;17:12;2:2;75271:134:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75271:134:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;75090:327:0;75643:16;;75594:114;;;;;;:26;75643:16;;;75594:114;;;;;;;;;;;;;75555:16;;75594:26;;;;;:114;;;;;;;;;;;;;;75475:36;75594:26;:114;;;2:2:-1;;;;27:1;24;17:12;2:2;75594:114:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;75594:114:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;;;;;;;74127:1589:0;:::o;32350:113::-;32446:9;32435:20;;;;;;;;32350:113::o;33349:143::-;33423:16;:61;;;;;;;;;;;;;;;33349:143::o;6502:106::-;6590:10;6502:106;:::o;25281:380::-;25417:19;;;25409:68;;;;-1:-1:-1;;;25409:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25496:21;;;25488:68;;;;-1:-1:-1;;;25488:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25569:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;25621:32;;;;;;;;;;;;;;;;;25281:380;;;:::o;22785:610::-;22925:20;;;22917:70;;;;-1:-1:-1;;;22917:70:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23006:23;;;22998:71;;;;-1:-1:-1;;;22998:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23082:47;23103:6;23111:9;23122:6;23082:20;:47::i;:::-;23162:108;23198:6;23162:108;;;;;;;;;;;;;;;;;:17;;;:9;:17;;;;;;;;;;;;:108;;:21;:108;:::i;:::-;23142:17;;;;:9;:17;;;;;;;;;;;:128;;;;23304:20;;;;;;;:32;;23329:6;23304:32;:24;:32;:::i;:::-;23281:20;;;;:9;:20;;;;;;;;;;;;:55;;;;23352:35;;;;;;;23281:20;;23352:35;;;;;;;;;;;;;22785:610;;;:::o;8658:226::-;8778:7;8814:12;8806:6;;;;8798:29;;;;-1:-1:-1;;;8798: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;8798:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;8850:5:0;;;8658:226::o;9135:471::-;9193:7;9438:6;9434:47;;-1:-1:-1;9468:1:0;9461:8;;9434:47;9505:5;;;9509:1;9505;:5;:1;9529:5;;;;;:10;9521:56;;;;-1:-1:-1;;;9521:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9597:1;9135:471;-1:-1:-1;;;9135:471:0:o;10074:132::-;10132:7;10159:39;10163:1;10166;10159:39;;;;;;;;;;;;;;;;;:3;:39::i;7771:181::-;7829:7;7861:5;;;7885:6;;;;7877:46;;;;;-1:-1:-1;;;7877:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;38273:178;38329:6;38364:5;38356;:13;38348:64;;;;-1:-1:-1;;;38348:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38437:5:0;38273:178::o;8227:136::-;8285:7;8312:43;8316:1;8319;8312:43;;;;;;;;;;;;;;;;;:3;:43::i;23676:378::-;23760:21;;;23752:65;;;;;-1:-1:-1;;;23752:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;23830:49;23859:1;23863:7;23872:6;23830:20;:49::i;:::-;23907:12;;:24;;23924:6;23907:24;:16;:24;:::i;:::-;23892:12;:39;23963:18;;;:9;:18;;;;;;;;;;;:30;;23986:6;23963:30;:22;:30;:::i;:::-;23942:18;;;:9;:18;;;;;;;;;;;:51;;;;24009:37;;;;;;;23942:18;;:9;;24009:37;;;;;;;;;;23676:378;;:::o;50285:282::-;50347:21;50370:20;50424:15;;;;;;;;;;;:27;;;:29;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;50424:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50424:29:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;50424:29:0;50479:15;;:31;;;;;;;;50424:29;;-1:-1:-1;50479:15:0;;;;;;;:29;;:31;;;;;50424:29;;50479:31;;;;;;;;;:15;:31;;;2:2:-1;;;;27:1;24;17:12;2:2;50479:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;50479:31:0;;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;-1:-1;50479:31:0;;-1:-1:-1;50285:282:0;;:::o;5653:194::-;5787:3;;5653:194::o;58647:4793::-;58833:14;58850:24;58867:6;58850:16;:24::i;:::-;58833:41;;58885:36;;:::i;:::-;-1:-1:-1;58924:26:0;;;;:18;:26;;;;;;;;;58885:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59003:113;;:88;;;;:69;:88::i;:113::-;58963:153;;;;;;59164:48;;;;:108;;:83;;:66;;;:83;;;:66;:83;:::i;:108::-;59127:145;;:34;;;:145;59285:4097;;;;59377:41;;:::i;:::-;-1:-1:-1;59435:28:0;;;;:20;:28;;;;;;;;59377:86;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59435:28;;;60396:98;;55096:21;60396:98;:40;:98;:::i;:::-;60375:119;;60513:18;60534:92;60597:10;60534:14;:36;;;:40;;;;:92;;;;:::i;:::-;60513:113;;60645:15;60663:116;60726:11;:34;;;60663:116;;:14;:36;;;:40;;;;:116;;;;:::i;:::-;60645:134;;60812:10;60802:7;:20;60798:1198;;;60865:7;60851:10;:21;60847:817;;61172:36;;;;61127:108;;:10;;:108;;;:14;:108;:::i;:::-;61110:125;;60847:817;;;61577:36;;;;61535:105;;:7;;:105;;;:11;:105;:::i;:::-;61518:122;;60847:817;60798:1198;;;61852:124;61919:11;:34;;;61852:124;;:14;:36;;;:40;;;;:124;;;;:::i;:::-;61835:141;;60798:1198;59285:4097;;;62032:30;62068:18;:26;;;62113:6;62068:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;62068:66:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62068:66:0;;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;-1:-1;62068:66:0;;;;-1:-1:-1;62151:36:0;62165:4;62172:14;62151:5;:36::i;:::-;62241:141;:112;62318:11;:34;;;62241:112;;:14;:54;;;:76;;;;:112;;;;:::i;:141::-;62202:180;;;;:36;;;:180;62433:37;;62399:155;;62433:106;;:41;;;:106;;;:41;:106;:::i;:::-;62399:15;:155::i;:::-;62691:37;;62611:57;;;;:147;;:118;;;:79;;;;:118;;:79;:118;:::i;:147::-;62569:189;;:39;;;;:189;;;62816:277;;;;;;;;;;;;;:306;;:277;;62569:189;;62816:277;;;;;;;:54;;;;:83;;:76;;62893:5;62816:83;:76;:83;:::i;:306::-;62775:347;;;;:38;;;;:347;;;;63178:4;63139:36;;;:43;;;;63227:27;;;:19;:27;;;;;;;:81;;:52;;:27;;;:52;:49;:52;:::i;:81::-;63197:27;;;;:19;:27;;;;;;;;:111;;;;;;;;;;;;;;63325:28;;;:20;:28;;;;;;:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;59285:4097:0;63392:26;;;;:18;:26;;;;;;;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;58647:4793:0:o;24386:455::-;24470:21;;;24462:67;;;;-1:-1:-1;;;24462:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24542:49;24563:7;24580:1;24584:6;24542:20;:49::i;:::-;24625:105;24662:6;24625:105;;;;;;;;;;;;;;;;;:18;;;:9;:18;;;;;;;;;;;;:105;;:22;:105;:::i;:::-;24604:18;;;:9;:18;;;;;;;;;;:126;24756:12;;:24;;24773:6;24756:24;:16;:24;:::i;:::-;24741:12;:39;24796:37;;;;;;;;24822:1;;24796:37;;;;;;;;;;;;;24386:455;;:::o;40410:181::-;40466:6;40501;40493:5;:14;40485:67;;;;-1:-1:-1;;;40485:67:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34973:605;35029:6;35273;35269:47;;-1:-1:-1;35303:1:0;35296:8;;35269:47;35352:1;35357:2;35352:7;:27;;;;;34873:7;35363:1;:16;35352:27;35350:30;35328:119;;;;-1:-1:-1;;;35328:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35471:5;;;35475:1;35471;:5;:1;35495:5;;;;;:10;35487:62;;;;-1:-1:-1;;;35487:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36110:255;36166:6;36196:5;;;36235:6;;;;;;:16;;;36250:1;36245;:6;;36235:16;36234:38;;;;36261:1;36257;:5;:14;;;;;36270:1;36266;:5;36257:14;36212:124;;;;-1:-1:-1;;;36212:124:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10694:379;10814:7;10916:12;10909:5;10901:28;;;;-1:-1:-1;;;10901:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:10:-1;;8:100;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;10901:28:0;;10940:9;10956:1;10952;:5;;;;;;;10694:379;-1:-1:-1;;;;;10694:379:0:o;78993:1160::-;79080:6;79104:36;;:::i;:::-;-1:-1:-1;79143:26:0;;;;:18;:26;;;;;;;;;79104:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79180:78;;79245:1;79238:8;;;;;79180:78;79298:10;79270:12;79285:24;;;:12;:24;;;;;;;;:32;;;;;;;;;:43;;79415:39;;;;;;79496:38;;;;79285:43;;;;;79358:46;;;;;;;79467:67;;;79270:12;79919:26;;79285:43;;79919:8;:26::i;:::-;79860:43;79897:5;79860:32;:18;79883:8;79860:32;:22;:32;:::i;:43::-;:85;79842:257;;;80061:26;:4;55096:21;80061:26;:8;:26;:::i;:::-;79998:43;80035:5;79998:32;:18;80021:8;79998:32;:22;:32;:::i;:43::-;:89;79972:115;;79842:257;80118:27;:16;:6;80129:4;80118:16;:10;:16;:::i;:27::-;80111:34;78993:1160;-1:-1:-1;;;;;;;78993:1160:0:o;26686:125::-;;;;:::o;57962:132::-;58050:19;;:36;;58074:11;58050:36;:23;:36;:::i;:::-;58028:19;:58;-1:-1:-1;57962:132:0:o;27244:106::-;27302:7;27333:1;27329;:5;:13;;27341:1;27329:13;;;-1:-1:-1;27337:1:0;;27244:106;-1:-1:-1;27244:106:0:o;54721:26275::-;;;;;;;;;-1:-1:-1;54721:26275:0;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://ec31e73691d5223cd49ce0de66f4abd57af73830d3eba761318d911fb47bb1dc

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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