Contract 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00

Contract Overview

Balance:
0 BNB

Token:
Txn Hash
Block
From
To
Value [Txn Fee]
0xc05e5e9cd2d380fbd830cb252c653cd92e484c89a7b979f19d00d63e4b859c3385645302021-05-05 3:08:5642 days 7 hrs ago0x6da28bca661599285c3af9186a81e8c42b4db010 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.00100417
0xabcf4f685210abba83a6eccc1ef42ec7bafe91191747eb68e8b4aae6c7d87df785645112021-05-05 3:07:5942 days 7 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.00065165
0x917a4cbbd75e1ec582b5a0e1d36d2d1623ace27fa3117311e5d5465054f7628c85644982021-05-05 3:07:2042 days 7 hrs ago0x6da28bca661599285c3af9186a81e8c42b4db010 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.00023687
0x1fca084b7fa3a18921bd4fc177680e5f6524b92e3ef19896b584ef478f89abc785644642021-05-05 3:05:3842 days 7 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.00030501
0x7de964a76cfea78c47b2d975952d315d2360fd28487616de961d8ed67eb54e7185643692021-05-05 3:00:5342 days 7 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.00162432
0x30855ddc7434eaac26dc0163cba2ffb267083c87d7f30383b36d7da28daf00e685641882021-05-05 2:51:5042 days 8 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.00057865
0x17522549540c543c85f43704fa804392597c7aa655502880108c8ada07a5d2a085640352021-05-05 2:44:1142 days 8 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.00183897
0xf33f8da5f6e88703b6310861be58d8dee47f47b090067643a0663c7e2b53813985639972021-05-05 2:42:1742 days 8 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.0016773
0xd70225a3b652510373fb6445011d7cb6b462b8880b799a68b86bdf990f8945a085639662021-05-05 2:40:4442 days 8 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  0x0f21ab921bb1a554be0ea4ad2095b788dc749e000 BNB0.0011625
0xf8eef454ba700a6784fb45d65b1f828946835dbda4bde63106c89da02cc11cb685639132021-05-05 2:38:0542 days 8 hrs ago0x845d819431c6360ab5ad1f0a39b9591abbf5eba3 IN  Contract Creation0 BNB0.03239272
[ Download CSV Export 
Latest 16 internal transactions
Parent Txn Hash Block From To Value
0xc05e5e9cd2d380fbd830cb252c653cd92e484c89a7b979f19d00d63e4b859c3385645302021-05-05 3:08:5642 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0xc05e5e9cd2d380fbd830cb252c653cd92e484c89a7b979f19d00d63e4b859c3385645302021-05-05 3:08:5642 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0xc05e5e9cd2d380fbd830cb252c653cd92e484c89a7b979f19d00d63e4b859c3385645302021-05-05 3:08:5642 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0xc05e5e9cd2d380fbd830cb252c653cd92e484c89a7b979f19d00d63e4b859c3385645302021-05-05 3:08:5642 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0xc05e5e9cd2d380fbd830cb252c653cd92e484c89a7b979f19d00d63e4b859c3385645302021-05-05 3:08:5642 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0xc05e5e9cd2d380fbd830cb252c653cd92e484c89a7b979f19d00d63e4b859c3385645302021-05-05 3:08:5642 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x7de964a76cfea78c47b2d975952d315d2360fd28487616de961d8ed67eb54e7185643692021-05-05 3:00:5342 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x7de964a76cfea78c47b2d975952d315d2360fd28487616de961d8ed67eb54e7185643692021-05-05 3:00:5342 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x7de964a76cfea78c47b2d975952d315d2360fd28487616de961d8ed67eb54e7185643692021-05-05 3:00:5342 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x7de964a76cfea78c47b2d975952d315d2360fd28487616de961d8ed67eb54e7185643692021-05-05 3:00:5342 days 7 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x30855ddc7434eaac26dc0163cba2ffb267083c87d7f30383b36d7da28daf00e685641882021-05-05 2:51:5042 days 8 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x17522549540c543c85f43704fa804392597c7aa655502880108c8ada07a5d2a085640352021-05-05 2:44:1142 days 8 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x17522549540c543c85f43704fa804392597c7aa655502880108c8ada07a5d2a085640352021-05-05 2:44:1142 days 8 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x17522549540c543c85f43704fa804392597c7aa655502880108c8ada07a5d2a085640352021-05-05 2:44:1142 days 8 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0x17522549540c543c85f43704fa804392597c7aa655502880108c8ada07a5d2a085640352021-05-05 2:44:1142 days 8 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
0xd70225a3b652510373fb6445011d7cb6b462b8880b799a68b86bdf990f8945a085639662021-05-05 2:40:4442 days 8 hrs ago 0x0f21ab921bb1a554be0ea4ad2095b788dc749e00 0x879acd17663d6ae00a4ce19ceb77991483bb15bd0 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Bridge

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT
pragma solidity 0.6.12;

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

/**
 * @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, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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 (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @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) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @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) {
        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, reverting 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) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting 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) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * 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);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * 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) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * 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;
    }
}

/**
 * @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) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @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");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain`call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.staticcall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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

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

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

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        // solhint-disable-next-line max-line-length
        require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

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

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

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            // solhint-disable-next-line max-line-length
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

interface IValueLiquidPair {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

    function transfer(address to, uint256 value) external returns (bool);

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event PaidProtocolFee(uint112 collectedFee0, uint112 collectedFee1);
    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
    event Swap(address indexed sender, uint256 amount0In, uint256 amount1In, uint256 amount0Out, uint256 amount1Out, address indexed to);
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function getCollectedFees() external view returns (uint112 _collectedFee0, uint112 _collectedFee1);

    function getTokenWeights() external view returns (uint32 tokenWeight0, uint32 tokenWeight1);

    function getSwapFee() external view returns (uint32);

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to) external returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(
        address,
        address,
        uint32,
        uint32
    ) external;
}

/*
 * @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.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address payable) {
        return msg.sender;
    }

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

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

    mapping(address => uint256) private _balances;

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

    uint256 private _totalSupply;

    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 virtual returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual 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 virtual returns (uint8) {
        return _decimals;
    }

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(sender, recipient, amount);

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

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

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

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

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

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

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

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This 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 virtual {
        _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 {}
}

contract MidasGoldToken is ERC20 {
    using SafeERC20 for IERC20;
    using SafeMath for uint256;

    address public governance = address(0xD025628eEe504330f1282C96B28a731E3995ff66);
    mapping(address => bool) public minters;

    uint256 public cap;

    constructor(uint256 _cap) public ERC20("Midas Gold", "MDG") {
        cap = _cap;
        governance = msg.sender;
    }

    modifier onlyGovernance() {
        require(msg.sender == governance, "!governance");
        _;
    }

    modifier onlyMinter() {
        require(msg.sender == governance || minters[msg.sender], "!governance && !minter");
        _;
    }

    function mint(address _to, uint256 _amount) external onlyMinter {
        _mint(_to, _amount);
    }

    function burn(uint256 _amount) external {
        _burn(msg.sender, _amount);
    }

    function burnFrom(address _account, uint256 _amount) external {
        uint256 decreasedAllowance = allowance(_account, msg.sender).sub(_amount, "ERC20: burn amount exceeds allowance");
        _approve(_account, msg.sender, decreasedAllowance);
        _burn(_account, _amount);
    }

    function setGovernance(address _governance) external onlyGovernance {
        governance = _governance;
    }

    function addMinter(address _minter) external onlyGovernance {
        minters[_minter] = true;
    }

    function removeMinter(address _minter) external onlyGovernance {
        minters[_minter] = false;
    }

    function setCap(uint256 _cap) external onlyGovernance {
        require(_cap >= totalSupply(), "_cap is below current total supply");
        cap = _cap;
    }

    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - minted tokens must not cause the total supply to go over the cap.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

        if (from == address(0)) {
            // When minting tokens
            require(totalSupply().add(amount) <= cap, "ERC20Capped: cap exceeded");
        }
    }

    // This function allows governance to take unsupported tokens out of the contract. This is in an effort to make someone whole, should they seriously mess up.
    // There is no guarantee governance will vote to return these. It also allows for removal of airdropped tokens.
    function governanceRecoverUnsupported(
        IERC20 _token,
        address _to,
        uint256 _amount
    ) external onlyGovernance {
        _token.safeTransfer(_to, _amount);
    }
}

/*
.___  ___.  __   _______       ___           _______.     _______   ______    __       _______
|   \/   | |  | |       \     /   \         /       |    /  _____| /  __  \  |  |     |       \
|  \  /  | |  | |  .--.  |   /  ^  \       |   (----`   |  |  __  |  |  |  | |  |     |  .--.  |
|  |\/|  | |  | |  |  |  |  /  /_\  \       \   \       |  | |_ | |  |  |  | |  |     |  |  |  |
|  |  |  | |  | |  '--'  | /  _____  \  .----)   |      |  |__| | |  `--'  | |  `----.|  '--'  |
|__|  |__| |__| |_______/ /__/     \__\ |_______/        \______|  \______/  |_______||_______/
 */
contract Bridge {
    // 'mdg' represents layer token MDG[N], 'MDG' represent MidasGoldToken
    using SafeERC20 for IERC20;
    using SafeMath for uint256;

    uint256 public constant BLOCKS_PER_10_MINUTES = 200;
    uint256 public constant BLOCKS_PER_2_HOURs = 60;
    uint256 public constant BLOCKS_PER_6_HOURs = 2400 * 3;
    uint256 public constant BLOCKS_PER_12_HOURs = 2400 * 6;
    uint256 public constant BLOCKS_PER_DAY = 28800; // 86400 / 3;
    address public constant MDG = address(0x879ACD17663D6Ae00A4cE19ceB77991483bb15bD);
    address public constant BUSD = address(0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56);
    address public MDG_BUSD = address(0xB10C30f83eBb92F5BaEf377168C4bFc9740d903c);

    address public operator = address(0xD025628eEe504330f1282C96B28a731E3995ff66);
    bool public initialized = false;
    address public reserveFund = address(0x39d91fb1Cb86c836da6300C0e700717d5dFe289F);
    uint256 public halvingRate = 9500; // 9500/10000 = 0.95
    uint256 public burnRate = 2000; // 2000/10000 = 20%
    uint256 public reserveRate = 2000; // 20%
    uint256 public rewardRate = 3000; //30%
    uint256 public totalMDGBurned = 0;
    mapping(address => bool) private rewardDistributors;
    uint256 public activeDistributorAmount = 0;

    struct RateVector {
        // averageRate = (blockSum + prevBlockSum) / (blockCount + prevBlockCount)
        uint256 blockSum; // each block ~ 6 hours
        uint256 blockCount;
        uint256 startBlock;
        uint256 prevBlockSum;
        uint256 prevBlockCount;
        uint256 lastUpdated;
        uint256 lastRate;
    }

    struct LayerInfo {
        IERC20 mdg; // Mdg[N]
        address mdgBusd;
        uint256 lastRate;
        uint256 startBlock;
        uint256 endBlock;
        uint256 nextHalvingBlock;
        uint256 MDGRewards;
        uint256 MDGBurned;
        uint256 mdgConverted; // mdg[N]
    }

    LayerInfo[] public layerInfo;
    RateVector[] public layerRateVector;

    event Initialized(address indexed executor, uint256 at);
    event Convert(address indexed user, uint256 burnAmount, uint256 MDGOut);

    function initialize() public {
        require(!initialized, "initialized");
        require(MidasGoldToken(MDG).minters(address(this)), "not minter");
        operator = address(0x845d819431c6360AB5AD1F0A39B9591AbBf5eBA3);
        reserveFund = address(0x39d91fb1Cb86c836da6300C0e700717d5dFe289F);
        MDG_BUSD = address(0xB10C30f83eBb92F5BaEf377168C4bFc9740d903c);
        halvingRate = 9500; // 9500/10000 = 0.95
        burnRate = 2000; // 2000/10000 = 20%
        reserveRate = 2000; // 20%
        rewardRate = 3000; //30%
        layerInfo.push(LayerInfo(IERC20(0), address(0), 0, 0, 0, 0, 0, 0, 0)); // fake layer 0
        layerInfo.push(LayerInfo(IERC20(0), address(0), 0, 0, 0, 0, 0, 0, 0)); // fake layer 1
        layerRateVector.push(RateVector(0, 0, 0, 0, 0, 0, 0)); // fake layer 0
        layerRateVector.push(RateVector(0, 0, 0, 0, 0, 0, 0)); // fake layer 1

        initialized = true;
        emit Initialized(msg.sender, block.number);
    }

    modifier notInitialized() {
        require(!initialized, "initialized");
        _;
    }

    modifier onlyOperator() {
        require(operator == msg.sender, "not operator");
        _;
    }

    modifier onlyDistributor() {
        require(msg.sender == operator || rewardDistributors[msg.sender], "!distributor");
        _;
    }

    modifier checkHalving() {
        uint256 _length = layerInfo.length;
        for (uint256 _i = 0; _i < _length; _i++) {
            LayerInfo storage _layer = layerInfo[_i];
            if (_layer.endBlock > block.number) {
                while (_layer.lastRate > 1000 && block.number >= _layer.nextHalvingBlock) {
                    _layer.lastRate = _layer.lastRate.mul(halvingRate).div(10000);
                    _layer.nextHalvingBlock = _layer.nextHalvingBlock.add(BLOCKS_PER_2_HOURs);
                }
            }
        }
        _;
    }

    function setOperator(address _operator) external onlyOperator {
        require(operator != address(0), "zero");
        operator = _operator;
    }

    function setReserveFund(address _reserveFund) external onlyOperator {
        require(_reserveFund != address(0), "zero");
        reserveFund = _reserveFund;
    }

    function setMDGBUSD(address _MDGBUSD) external onlyOperator {
        require(IValueLiquidPair(_MDGBUSD).token0() == MDG, "wrong _MDGBUSD");
        require(IValueLiquidPair(_MDGBUSD).token1() == BUSD, "wrong _MDGBUSD");
        MDG_BUSD = _MDGBUSD;
    }

    function addRewardDistributor(address _distributor) external onlyOperator {
        if (!rewardDistributors[_distributor]) {
            activeDistributorAmount++;
            rewardDistributors[_distributor] = true;
        }
    }

    function removeRewardDistributor(address _distributor) external onlyOperator {
        if (rewardDistributors[_distributor]) {
            rewardDistributors[_distributor] = false;
            activeDistributorAmount--;
        }
    }

    function setRates(
        uint256 _halvingRate,
        uint256 _burnRate,
        uint256 _reserveRate,
        uint256 _rewardRate
    ) external onlyOperator {
        require(_halvingRate < 10000, "over 100%");
        require(_burnRate.add(_reserveRate).add(_rewardRate) <= 10000, "over 100%");
        halvingRate = _halvingRate;
        burnRate = _burnRate;
        reserveRate = _reserveRate;
        rewardRate = _rewardRate;
    }

    function setLayer(
        uint256 _layerId,
        address _mdg,
        address _mdgBusd,
        uint256 _lastRate,
        uint256 _startBlock,
        uint256 _endBlock
    ) external onlyOperator {
        require(_mdg != address(0), "wrong _mdg");
        require(_lastRate >= 1000, "rate < 0.1"); // 1000/10000 = 0.1
        require(_lastRate <= 10000, "rate > 1"); // 10000/10000 = 1.0
        require(_endBlock > _startBlock, "startBlock over endBlock");
        require(_layerId <= layerInfo.length, "wrong _layerId");
//        require(IValueLiquidPair(_mdgBusd).token0() == _mdg, "wrong _mdgBusd");
//        require(IValueLiquidPair(_mdgBusd).token1() == BUSD, "wrong _mdgBusd");

        if (_layerId == layerInfo.length) {
            uint256 _nextHalvingBlock = _startBlock.add(BLOCKS_PER_2_HOURs);
            layerInfo.push(LayerInfo(IERC20(_mdg), address(_mdgBusd), _lastRate, _startBlock, _endBlock, _nextHalvingBlock, 0, 0, 0));
            layerRateVector.push(RateVector(0, 0, 0, 0, 0, 0, 0));
        } else {
            require(_endBlock > block.number, "late");
            LayerInfo storage _layerInfo = layerInfo[_layerId];
            _layerInfo.mdg = IERC20(_mdg);
            _layerInfo.mdgBusd = _mdgBusd;
            _layerInfo.lastRate = _lastRate;
            _layerInfo.startBlock = _startBlock;
            _layerInfo.endBlock = _endBlock;
        }
    }

    function setLastRate(
        uint256 _layerId,
        uint256 _lastRate,
        uint256 _nextHalvingBlock
    ) external onlyOperator {
        require(_layerId < layerInfo.length, "layer not found");
        LayerInfo storage _layerInfo = layerInfo[_layerId];
        require(_lastRate >= 1000, "rate < 0.1"); // 1000/10000 = 0.1
        require(_lastRate <= 10000, "rate > 1"); // 10000/10000 = 1.0
        require(_nextHalvingBlock > block.number, "late");
        _layerInfo.lastRate = _lastRate;
        _layerInfo.nextHalvingBlock = _nextHalvingBlock;
    }

    function getInstantRate(LayerInfo storage _layer) internal view returns (uint256) {
        (uint112 _R0, uint112 _R1, ) = IValueLiquidPair(MDG_BUSD).getReserves(); // MDG
        (uint112 _r0, uint112 _r1, ) = IValueLiquidPair(_layer.mdgBusd).getReserves(); // mdg[N]
        uint256 rate = uint256(_R0).mul(_r1).div(_R1).mul(10).div(_r0);
        rate = rate < 1 ? 1 : rate >= 10 ? 10 : (rate.mul(_r0).mul(_R1) != uint256(_R0).mul(_r1).mul(10)) ? rate + 1 : rate;
        return rate * 1000;
    }

    function getInstantRate(uint256 _layerId) public view returns (uint256) {
        // returns in [1000, 10000]
        require(_layerId < layerInfo.length, "layer not found");
        return getInstantRate(layerInfo[_layerId]);
    }

    function getAverageRate(uint256 _layerId) public returns (uint256) {
        require(_layerId < layerInfo.length, "layer not found");
        LayerInfo storage _layer = layerInfo[_layerId];
        RateVector storage _vector = layerRateVector[_layerId];
        uint256 _rate = getInstantRate(_layer);

        if (_vector.blockCount == 0) {
            // first rate
            _vector.blockCount = 1;
            _vector.blockSum = _rate;
            _vector.startBlock = block.number;
            _vector.lastUpdated = block.number;
        } else if (block.number > BLOCKS_PER_12_HOURs + _vector.startBlock) {
            // refresh
            _vector.blockCount = 1;
            _vector.blockSum = _rate;
            _vector.startBlock = block.number;
            _vector.prevBlockCount = 0;
            _vector.prevBlockSum = 0;
            _vector.lastUpdated = block.number;
        } else if (block.number > BLOCKS_PER_6_HOURs + _vector.startBlock) {
            _vector.prevBlockCount = _vector.blockCount;
            _vector.prevBlockSum = _vector.blockSum;
            _vector.blockCount = 1;
            _vector.blockSum = _rate;
            _vector.startBlock = block.number;
            _vector.lastUpdated = block.number;
        } else {
            if (block.number > BLOCKS_PER_10_MINUTES + _vector.lastUpdated || _vector.blockCount + _vector.prevBlockCount == 1) {
                _vector.blockSum += _rate;
                _vector.blockCount++;
                _vector.lastUpdated = block.number;
            } else {
                uint256 _rateSum = _vector.blockSum.add(_vector.prevBlockSum).sub(_vector.lastRate);
                uint256 _rateCount = _vector.blockCount + _vector.prevBlockCount - 1;
                uint256 _averageRate = _rateSum.div(_rateCount);
                if (absDiff(_averageRate, _rate) < absDiff(_averageRate, _vector.lastRate)) {
                    _vector.blockSum = _vector.blockSum.sub(_vector.lastRate).add(_rate);
                }
            }
        }
        _vector.lastRate = _rate;

        return _vector.blockSum.add(_vector.prevBlockSum).div(_vector.blockCount + _vector.prevBlockCount);
    }

    function absDiff(uint256 a, uint256 b) internal pure returns (uint256 c) {
        c = a > b ? a - b : b - a;
    }

    function convert(uint256 _layerId, uint256 _mdgAmount) external checkHalving {
        require(_layerId < layerInfo.length, "layer not found");
        LayerInfo storage _layer = layerInfo[_layerId];
        require(_layer.endBlock > block.number, "closed");
        address _sender = msg.sender;
        _layer.mdg.safeTransferFrom(_sender, address(this), _mdgAmount); // deposit mdg[N]
        _layer.mdgConverted = _layer.mdgConverted.add(_mdgAmount);

        // mint MDG to user
        uint256 _MDGOut = _mdgAmount.mul(_layer.lastRate).div(10000);
        MidasGoldToken(MDG).mint(_sender, _MDGOut);

        // mint MDG rewards + reserve + burn
        uint256 _excessiveMDG = _mdgAmount.sub(_MDGOut);
        _mintMDG(_excessiveMDG, _layer);

        emit Convert(_sender, _mdgAmount, _MDGOut);
    }

    function _mintMDG(uint256 _excessiveMDG, LayerInfo storage _layer) internal {
        uint256 _toReserve = _excessiveMDG.mul(reserveRate).div(10000); //20%
        uint256 _rewardAmount = _excessiveMDG.mul(rewardRate).div(10000); //30%
        uint256 _burnAmount = _excessiveMDG.mul(burnRate).div(10000); //20%
        MidasGoldToken(MDG).mint(reserveFund, _toReserve);
        MidasGoldToken(MDG).mint(address(this), _rewardAmount.add(_burnAmount));
        _layer.MDGRewards = _layer.MDGRewards.add(_rewardAmount);
        _layer.MDGBurned = _layer.MDGBurned.add(_burnAmount);
    }

    function distributeRewards(address _to, uint256 _layerId) external onlyDistributor {
        require(_layerId < layerInfo.length, "layer not found");
        LayerInfo storage _layer = layerInfo[_layerId];
        require(_layer.endBlock <= block.number, "running");
        require(_layer.MDGRewards.add(_layer.MDGBurned) <= IERC20(MDG).balanceOf(address(this)), "over balance");

        // mint unconverted MDG
        uint256 _mdgSupply = _layer.mdg.totalSupply();
        if (_mdgSupply > _layer.mdgConverted) {
            uint256 unconvertedMDG = _mdgSupply.sub(_layer.mdgConverted);
            _mintMDG(unconvertedMDG, _layer);
        }

        // transfer
        uint256 _rewardAmount = _layer.MDGRewards;
        uint256 _burnAmount = _layer.MDGBurned;
        _layer.MDGRewards = 0;
        _layer.MDGBurned = 0;
        IERC20(MDG).safeTransfer(_to, _rewardAmount);
        MidasGoldToken(MDG).burn(_burnAmount);
        totalMDGBurned = totalMDGBurned.add(_burnAmount);
    }

    function governanceRecoverUnsupported(
        IERC20 _token,
        address _to,
        uint256 _amount
    ) external onlyOperator {
        _token.safeTransfer(_to, _amount);
    }
}

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"burnAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"MDGOut","type":"uint256"}],"name":"Convert","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"executor","type":"address"},{"indexed":false,"internalType":"uint256","name":"at","type":"uint256"}],"name":"Initialized","type":"event"},{"inputs":[],"name":"BLOCKS_PER_10_MINUTES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BLOCKS_PER_12_HOURs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BLOCKS_PER_2_HOURs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BLOCKS_PER_6_HOURs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BLOCKS_PER_DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BUSD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MDG","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MDG_BUSD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activeDistributorAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_distributor","type":"address"}],"name":"addRewardDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"burnRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_layerId","type":"uint256"},{"internalType":"uint256","name":"_mdgAmount","type":"uint256"}],"name":"convert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_layerId","type":"uint256"}],"name":"distributeRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_layerId","type":"uint256"}],"name":"getAverageRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_layerId","type":"uint256"}],"name":"getInstantRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_token","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"governanceRecoverUnsupported","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"halvingRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"layerInfo","outputs":[{"internalType":"contract IERC20","name":"mdg","type":"address"},{"internalType":"address","name":"mdgBusd","type":"address"},{"internalType":"uint256","name":"lastRate","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"endBlock","type":"uint256"},{"internalType":"uint256","name":"nextHalvingBlock","type":"uint256"},{"internalType":"uint256","name":"MDGRewards","type":"uint256"},{"internalType":"uint256","name":"MDGBurned","type":"uint256"},{"internalType":"uint256","name":"mdgConverted","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"layerRateVector","outputs":[{"internalType":"uint256","name":"blockSum","type":"uint256"},{"internalType":"uint256","name":"blockCount","type":"uint256"},{"internalType":"uint256","name":"startBlock","type":"uint256"},{"internalType":"uint256","name":"prevBlockSum","type":"uint256"},{"internalType":"uint256","name":"prevBlockCount","type":"uint256"},{"internalType":"uint256","name":"lastUpdated","type":"uint256"},{"internalType":"uint256","name":"lastRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_distributor","type":"address"}],"name":"removeRewardDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveFund","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserveRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_layerId","type":"uint256"},{"internalType":"uint256","name":"_lastRate","type":"uint256"},{"internalType":"uint256","name":"_nextHalvingBlock","type":"uint256"}],"name":"setLastRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_layerId","type":"uint256"},{"internalType":"address","name":"_mdg","type":"address"},{"internalType":"address","name":"_mdgBusd","type":"address"},{"internalType":"uint256","name":"_lastRate","type":"uint256"},{"internalType":"uint256","name":"_startBlock","type":"uint256"},{"internalType":"uint256","name":"_endBlock","type":"uint256"}],"name":"setLayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_MDGBUSD","type":"address"}],"name":"setMDGBUSD","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"}],"name":"setOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_halvingRate","type":"uint256"},{"internalType":"uint256","name":"_burnRate","type":"uint256"},{"internalType":"uint256","name":"_reserveRate","type":"uint256"},{"internalType":"uint256","name":"_rewardRate","type":"uint256"}],"name":"setRates","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_reserveFund","type":"address"}],"name":"setReserveFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalMDGBurned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

6080604052600080546001600160a01b031990811673b10c30f83ebb92f5baef377168c4bfc9740d903c1782556001805460ff60a01b1990831673d025628eee504330f1282c96b28a731e3995ff6617169055600280549091167339d91fb1cb86c836da6300c0e700717d5dfe289f17905561251c6003556107d06004819055600555610bb8600655600781905560095534801561009c57600080fd5b50613775806100ac6000396000f3fe608060405234801561001057600080fd5b506004361061020b5760003560e01c806378987da21161012a578063b3ab15fb116100bd578063c077d42d1161008c578063e793937211610071578063e7939372146105ca578063f498d8a6146105d2578063f6383b2c146106055761020b565b8063c077d42d1461058f578063c974da62146105c25761020b565b8063b3ab15fb14610519578063b7f92b711461054c578063bb6d890f14610554578063bed99850146105875761020b565b80638129fc1c116100f95780638129fc1c1461046057806396e4ee3d14610468578063a8031a1d1461048b578063ac945cf1146104c45761020b565b806378987da2146103cb5780637a10f136146103d35780637b0a47ee146104505780637e6335f4146104585761020b565b8063484f4ea9116101a25780635d7e1c9a116101715780635d7e1c9a1461036f57806363c136f71461039e5780636a33590d146103a65780636bb987fe146103c35761020b565b8063484f4ea91461032e578063570ca7351461033657806358cc316c1461033e57806358d7bf80146103675761020b565b8063159d3352116101de578063159d3352146102ce578063187bb037146102d65780631c96e950146102f35780633468003c146103265761020b565b806303ed19b31461021057806309b5328d146102415780631551ab9a14610298578063158ef93e146102b2575b600080fd5b610218610648565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b610296600480360360c081101561025757600080fd5b5080359073ffffffffffffffffffffffffffffffffffffffff602082013581169160408101359091169060608101359060808101359060a00135610660565b005b6102a0610c64565b60408051918252519081900360200190f35b6102ba610c6a565b604080519115158252519081900360200190f35b6102a0610c8b565b6102a0600480360360208110156102ec57600080fd5b5035610c90565b6102966004803603602081101561030957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610d2c565b6102a0610e3d565b610218610e42565b610218610e5a565b6102966004803603606081101561035457600080fd5b5080359060208101359060400135610e76565b6102a06110ee565b6102966004803603608081101561038557600080fd5b50803590602081013590604081013590606001356110f4565b610218611282565b6102a0600480360360208110156103bc57600080fd5b503561129e565b6102a0611514565b6102a061151a565b6103f0600480360360208110156103e957600080fd5b5035611520565b6040805173ffffffffffffffffffffffffffffffffffffffff9a8b168152989099166020890152878901969096526060870194909452608086019290925260a085015260c084015260e08301526101008201529051908190036101200190f35b6102a0611592565b6102a0611598565b61029661159e565b6102966004803603604081101561047e57600080fd5b5080359060200135611cfd565b610296600480360360408110156104a157600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561200c565b6104e1600480360360208110156104da57600080fd5b503561245d565b604080519788526020880196909652868601949094526060860192909252608085015260a084015260c0830152519081900360e00190f35b6102966004803603602081101561052f57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166124ac565b6102186125ff565b6102966004803603602081101561056a57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661261b565b6102a0612743565b610296600480360360208110156105a557600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612749565b6102a0612a54565b6102a0612a5a565b610296600480360360208110156105e857600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16612a60565b6102966004803603606081101561061b57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135612bb1565b73879acd17663d6ae00a4ce19ceb77991483bb15bd81565b60015473ffffffffffffffffffffffffffffffffffffffff1633146106e657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff851661076857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f77726f6e67205f6d646700000000000000000000000000000000000000000000604482015290519081900360640190fd5b6103e88310156107d957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f72617465203c20302e3100000000000000000000000000000000000000000000604482015290519081900360640190fd5b61271083111561084a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f72617465203e2031000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b8181116108b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f7374617274426c6f636b206f76657220656e64426c6f636b0000000000000000604482015290519081900360640190fd5b600a5486111561092957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f77726f6e67205f6c617965724964000000000000000000000000000000000000604482015290519081900360640190fd5b600a54861415610b6657600061094083603c612c5d565b9050600a6040518061012001604052808873ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200160008152602001600081526020016000815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801555050600b6040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060155505050610c5c565b438111610bd657604080517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048083019190915260248201527f6c61746500000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b6000600a8781548110610be557fe5b60009182526020909120600990910201805473ffffffffffffffffffffffffffffffffffffffff8089167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316178355600183018054918916919092161790556002810185905560038101849055600401829055505b505050505050565b60075481565b60015474010000000000000000000000000000000000000000900460ff1681565b603c81565b600a546000908210610d0357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6c61796572206e6f7420666f756e640000000000000000000000000000000000604482015290519081900360640190fd5b610d26600a8381548110610d1357fe5b9060005260206000209060090201612cd8565b92915050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610db257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526008602052604090205460ff16610e3a5760098054600190810190915573ffffffffffffffffffffffffffffffffffffffff8216600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690911790555b50565b60c881565b73e9e7cea3dedca5984780bafc599bd69add087d5681565b60015473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff163314610efc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b600a548310610f6c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6c61796572206e6f7420666f756e640000000000000000000000000000000000604482015290519081900360640190fd5b6000600a8481548110610f7b57fe5b906000526020600020906009020190506103e8831015610ffc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f72617465203c20302e3100000000000000000000000000000000000000000000604482015290519081900360640190fd5b61271083111561106d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600860248201527f72617465203e2031000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b4382116110dd57604080517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048083019190915260248201527f6c61746500000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600281019290925560059091015550565b60055481565b60015473ffffffffffffffffffffffffffffffffffffffff16331461117a57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b61271084106111ea57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6f76657220313030250000000000000000000000000000000000000000000000604482015290519081900360640190fd5b612710611201826111fb8686612c5d565b90612c5d565b111561126e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600960248201527f6f76657220313030250000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600393909355600491909155600555600655565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b600a54600090821061131157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6c61796572206e6f7420666f756e640000000000000000000000000000000000604482015290519081900360640190fd5b6000600a838154811061132057fe5b906000526020600020906009020190506000600b848154811061133f57fe5b90600052602060002090600702019050600061135a83612cd8565b905081600101546000141561138457600182810155808255436002830181905560058301556114db565b8160020154613840014311156113bd576001828101558082554360028301819055600060048401819055600384015560058301556114db565b8160020154611c20014311156113f6576001808301805460048501558354600385015555808255436002830181905560058301556114db565b816005015460c801431180611415575081600401548260010154016001145b15611437578154810182556001808301805490910190554360058301556114db565b6000611462836006015461145c85600301548660000154612c5d90919063ffffffff16565b90612efc565b60048401546001850154919250017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01600061149e8383612f73565b90506114ae818660060154612ff4565b6114b88286612ff4565b10156114d757600685015485546114d49186916111fb91612efc565b85555b5050505b60068201819055600482015460018301546003840154845461150b93929092019161150591612c5d565b90612f73565b95945050505050565b61708081565b611c2081565b600a818154811061152d57fe5b600091825260209091206009909102018054600182015460028301546003840154600485015460058601546006870154600788015460089098015473ffffffffffffffffffffffffffffffffffffffff97881699509690951696939592949193909289565b60065481565b60035481565b60015474010000000000000000000000000000000000000000900460ff161561162857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600b60248201527f696e697469616c697a6564000000000000000000000000000000000000000000604482015290519081900360640190fd5b604080517ff46eccc4000000000000000000000000000000000000000000000000000000008152306004820152905173879acd17663d6ae00a4ce19ceb77991483bb15bd9163f46eccc4916024808301926020929190829003018186803b15801561169257600080fd5b505afa1580156116a6573d6000803e3d6000fd5b505050506040513d60208110156116bc57600080fd5b505161172957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f6e6f74206d696e74657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b73845d819431c6360ab5ad1f0a39b9591abbf5eba3600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507339d91fb1cb86c836da6300c0e700717d5dfe289f600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555073b10c30f83ebb92f5baef377168c4bfc9740d903c6000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061251c6003819055506107d06004819055506107d0600581905550610bb8600681905550600a604051806101200160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801555050600a604051806101200160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815250908060018154018082558091505060019003906000526020600020906009020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801555050600b6040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c082015181600601555050600b6040518060e0016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509080600181540180825580915050600190039060005260206000209060070201600090919091909150600082015181600001556020820151816001015560408201518160020155606082015181600301556080820151816004015560a0820151816005015560c08201518160060155505060018060146101000a81548160ff0219169083151502179055503373ffffffffffffffffffffffffffffffffffffffff167f25ff68dd81b34665b5ba7e553ee5511bf6812e12adb4a7e2c0d9e26b3099ce79436040518082815260200191505060405180910390a2565b600a5460005b81811015611d9c576000600a8281548110611d1a57fe5b906000526020600020906009020190504381600401541115611d93575b6103e88160020154118015611d50575080600501544310155b15611d9357611d74612710611505600354846002015461300290919063ffffffff16565b60028201556005810154611d8990603c612c5d565b6005820155611d37565b50600101611d03565b50600a548310611e0d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6c61796572206e6f7420666f756e640000000000000000000000000000000000604482015290519081900360640190fd5b6000600a8481548110611e1c57fe5b9060005260206000209060090201905043816004015411611e9e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600660248201527f636c6f7365640000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b80543390611ec49073ffffffffffffffffffffffffffffffffffffffff16823087613075565b6008820154611ed39085612c5d565b60088301556002820154600090611ef39061271090611505908890613002565b905073879acd17663d6ae00a4ce19ceb77991483bb15bd73ffffffffffffffffffffffffffffffffffffffff166340c10f1983836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b158015611f7a57600080fd5b505af1158015611f8e573d6000803e3d6000fd5b505050506000611fa78287612efc90919063ffffffff16565b9050611fb38185613110565b6040805187815260208101849052815173ffffffffffffffffffffffffffffffffffffffff8616927f9018eade4aec2a696b34b0f5459a1a7dc058389bab8e2380d880817a9e22b213928290030190a250505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633148061204157503360009081526008602052604090205460ff165b6120ac57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f216469737472696275746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b600a54811061211c57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f6c61796572206e6f7420666f756e640000000000000000000000000000000000604482015290519081900360640190fd5b6000600a828154811061212b57fe5b9060005260206000209060090201905043816004015411156121ae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f72756e6e696e6700000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905173879acd17663d6ae00a4ce19ceb77991483bb15bd916370a08231916024808301926020929190829003018186803b15801561221857600080fd5b505afa15801561222c573d6000803e3d6000fd5b505050506040513d602081101561224257600080fd5b50516007820154600683015461225791612c5d565b11156122c457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6f7665722062616c616e63650000000000000000000000000000000000000000604482015290519081900360640190fd5b8054604080517f18160ddd000000000000000000000000000000000000000000000000000000008152905160009273ffffffffffffffffffffffffffffffffffffffff16916318160ddd916004808301926020929190829003018186803b15801561232e57600080fd5b505afa158015612342573d6000803e3d6000fd5b505050506040513d602081101561235857600080fd5b50516008830154909150811115612390576000612382836008015483612efc90919063ffffffff16565b905061238e8184613110565b505b600682018054600784018054600093849055929055906123c573879acd17663d6ae00a4ce19ceb77991483bb15bd87846132d7565b73879acd17663d6ae00a4ce19ceb77991483bb15bd73ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561242c57600080fd5b505af1158015612440573d6000803e3d6000fd5b50506007546124529250905082612c5d565b600755505050505050565b600b818154811061246a57fe5b90600052602060002090600702016000915090508060000154908060010154908060020154908060030154908060040154908060050154908060060154905087565b60015473ffffffffffffffffffffffffffffffffffffffff16331461253257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b60015473ffffffffffffffffffffffffffffffffffffffff166125b857604080517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048083019190915260248201527f7a65726f00000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60025473ffffffffffffffffffffffffffffffffffffffff1681565b60015473ffffffffffffffffffffffffffffffffffffffff1633146126a157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526008602052604090205460ff1615610e3a5773ffffffffffffffffffffffffffffffffffffffff16600090815260086020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055600980547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019055565b60045481565b60015473ffffffffffffffffffffffffffffffffffffffff1633146127cf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b73879acd17663d6ae00a4ce19ceb77991483bb15bd73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d602081101561286a57600080fd5b505173ffffffffffffffffffffffffffffffffffffffff16146128ee57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f77726f6e67205f4d444742555344000000000000000000000000000000000000604482015290519081900360640190fd5b73e9e7cea3dedca5984780bafc599bd69add087d5673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b15801561295f57600080fd5b505afa158015612973573d6000803e3d6000fd5b505050506040513d602081101561298957600080fd5b505173ffffffffffffffffffffffffffffffffffffffff1614612a0d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f77726f6e67205f4d444742555344000000000000000000000000000000000000604482015290519081900360640190fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60095481565b61384081565b60015473ffffffffffffffffffffffffffffffffffffffff163314612ae657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8116612b6a57604080517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048083019190915260248201527f7a65726f00000000000000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60015473ffffffffffffffffffffffffffffffffffffffff163314612c3757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f6e6f74206f70657261746f720000000000000000000000000000000000000000604482015290519081900360640190fd5b612c5873ffffffffffffffffffffffffffffffffffffffff841683836132d7565b505050565b600082820183811015612cd157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612d4457600080fd5b505afa158015612d58573d6000803e3d6000fd5b505050506040513d6060811015612d6e57600080fd5b5080516020909101516001860154604080517f0902f1ac0000000000000000000000000000000000000000000000000000000081529051939550919350600092839273ffffffffffffffffffffffffffffffffffffffff90921691630902f1ac916004808301926060929190829003018186803b158015612dee57600080fd5b505afa158015612e02573d6000803e3d6000fd5b505050506040513d6060811015612e1857600080fd5b50805160209091015190925090506000612e606dffffffffffffffffffffffffffff8085169061150590600a90612e5a908981169084908c8116908a16613002565b90613002565b905060018110612eea57600a811015612ee257612e95600a612e5a6dffffffffffffffffffffffffffff888116908616613002565b612ecc856dffffffffffffffffffffffffffff16612e5a866dffffffffffffffffffffffffffff168561300290919063ffffffff16565b1415612ed85780612edd565b806001015b612ee5565b600a5b612eed565b60015b6103e802979650505050505050565b600082821115612f6d57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6000808211612fe357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381612fec57fe5b049392505050565b6000818311612f6d57500390565b60008261301157506000610d26565b8282028284828161301e57fe5b0414612cd1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806136f56021913960400191505060405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905261310a908590613360565b50505050565b600061312d6127106115056005548661300290919063ffffffff16565b9050600061314c6127106115056006548761300290919063ffffffff16565b9050600061316b6127106115056004548861300290919063ffffffff16565b600254604080517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9092166004830152602482018690525191925073879acd17663d6ae00a4ce19ceb77991483bb15bd916340c10f199160448082019260009290919082900301818387803b1580156131fa57600080fd5b505af115801561320e573d6000803e3d6000fd5b5073879acd17663d6ae00a4ce19ceb77991483bb15bd92506340c10f19915030905061323a8585612c5d565b6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050600060405180830381600087803b15801561328d57600080fd5b505af11580156132a1573d6000803e3d6000fd5b50505060068501546132b4915083612c5d565b600685015560078401546132c89082612c5d565b84600701819055505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052612c589084905b60606133c2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166134389092919063ffffffff16565b805190915015612c58578080602001905160208110156133e157600080fd5b5051612c58576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613716602a913960400191505060405180910390fd5b6060613447848460008561344f565b949350505050565b6060824710156134aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806136cf6026913960400191505060405180910390fd5b6134b38561360a565b61351e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061358857805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161354b565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146135ea576040519150601f19603f3d011682016040523d82523d6000602084013e6135ef565b606091505b50915091506135ff828286613610565b979650505050505050565b3b151590565b6060831561361f575081612cd1565b82511561362f5782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561369357818101518382015260200161367b565b50505050905090810190601f1680156136c05780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a26469706673582212205d0c9af607be0affbcae9059abc227d59a11c88ba958d9a12491f7dc6fed2c1164736f6c634300060c0033

Deployed ByteCode Sourcemap

40598:13421:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41065:81;;;:::i;:::-;;;;;;;;;;;;;;;;;;;46250:1424;;;;;;;;;;;;;;;;-1:-1:-1;46250:1424:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;41747:33;;;:::i;:::-;;;;;;;;;;;;;;;;41412:31;;;:::i;:::-;;;;;;;;;;;;;;;;;;40823:47;;;:::i;48781:236::-;;;;;;;;;;;;;;;;-1:-1:-1;48781:236:0;;:::i;45295:237::-;;;;;;;;;;;;;;;;-1:-1:-1;45295:237:0;;;;:::i;40765:51::-;;;:::i;41153:82::-;;;:::i;41328:77::-;;;:::i;47682:578::-;;;;;;;;;;;;;;;;-1:-1:-1;47682:578:0;;;;;;;;;;;;:::i;41655:33::-;;;:::i;45788:454::-;;;;;;;;;;;;;;;;-1:-1:-1;45788:454:0;;;;;;;;;;;;;;;;;:::i;41242:77::-;;;:::i;49025:2212::-;;;;;;;;;;;;;;;;-1:-1:-1;49025:2212:0;;:::i;40998:46::-;;;:::i;40877:53::-;;;:::i;42550:28::-;;;;;;;;;;;;;;;;-1:-1:-1;42550:28:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41702:32;;;:::i;41537:33::-;;;:::i;42771:984::-;;;:::i;51370:825::-;;;;;;;;;;;;;;;;-1:-1:-1;51370:825:0;;;;;;;:::i;52804:1013::-;;;;;;;;;;;;;;;;-1:-1:-1;52804:1013:0;;;;;;;;;:::i;42585:35::-;;;;;;;;;;;;;;;;-1:-1:-1;42585:35:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44694:151;;;;;;;;;;;;;;;;-1:-1:-1;44694:151:0;;;;:::i;41450:80::-;;;:::i;45540:240::-;;;;;;;;;;;;;;;;-1:-1:-1;45540:240:0;;;;:::i;41598:30::-;;;:::i;45028:259::-;;;;;;;;;;;;;;;;-1:-1:-1;45028:259:0;;;;:::i;41845:42::-;;;:::i;40937:54::-;;;:::i;44853:167::-;;;;;;;;;;;;;;;;-1:-1:-1;44853:167:0;;;;:::i;53825:191::-;;;;;;;;;;;;;;;;-1:-1:-1;53825:191:0;;;;;;;;;;;;;;;;;;:::i;41065:81::-;41103:42;41065:81;:::o;46250:1424::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46479:18:::1;::::0;::::1;46471:41;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46544:4;46531:9;:17;;46523:40;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46615:5;46602:9;:18;;46594:39;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46685:11;46673:9;:23;46665:60;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46756:9;:16:::0;46744:28;::::1;;46736:55;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46986:9;:16:::0;46974:28;::::1;46970:697;;;47019:25;47047:35;:11:::0;40868:2:::1;47047:15;:35::i;:::-;47019:63;;47097:9;47112:105;;;;;;;;47129:4;47112:105;;;;;;47144:8;47112:105;;;;;;47155:9;47112:105;;;;47166:11;47112:105;;;;47179:9;47112:105;;;;47190:17;47112:105;;;;47209:1;47112:105;;;;47212:1;47112:105;;;;47215:1;47112:105;;::::0;47097:121:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47233:15;47254:31;;;;;;;;47265:1;47254:31;;;;47268:1;47254:31;;;;47271:1;47254:31;;;;47274:1;47254:31;;;;47277:1;47254:31;;;;47280:1;47254:31;;;;47283:1;47254:31;;::::0;47233:53:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46970:697;;;;47339:12;47327:9;:24;47319:41;;;::::0;;::::1;::::0;;::::1;;::::0;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;47375:28;47406:9;47416:8;47406:19;;;;;;;;;::::0;;;::::1;::::0;;;::::1;::::0;;::::1;;47440:29:::0;;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;;47484:18;::::1;:29:::0;;;;::::1;::::0;;;::::1;;::::0;;47528:19:::1;::::0;::::1;:31:::0;;;47574:21:::1;::::0;::::1;:35:::0;;;47624:19:::1;;:31:::0;;;-1:-1:-1;46970:697:0::1;46250:1424:::0;;;;;;:::o;41747:33::-;;;;:::o;41412:31::-;;;;;;;;;:::o;40823:47::-;40868:2;40823:47;:::o;48781:236::-;48920:9;:16;48844:7;;48909:27;;48901:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48974:35;48989:9;48999:8;48989:19;;;;;;;;;;;;;;;;;;48974:14;:35::i;:::-;48967:42;48781:236;-1:-1:-1;;48781:236:0:o;45295:237::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45385:32:::1;::::0;::::1;;::::0;;;:18:::1;:32;::::0;;;;;::::1;;45380:145;;45434:23;:25:::0;;::::1;::::0;;::::1;::::0;;;45474:32:::1;::::0;::::1;45434:23;45474:32:::0;;;:18:::1;:32;::::0;;;;:39;;;::::1;::::0;;::::1;::::0;;45380:145:::1;45295:237:::0;:::o;40765:51::-;40813:3;40765:51;:::o;41153:82::-;41192:42;41153:82;:::o;41328:77::-;;;;;;:::o;47682:578::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47853:9:::1;:16:::0;47842:27;::::1;47834:55;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;47900:28;47931:9;47941:8;47931:19;;;;;;;;;;;;;;;;;;47900:50;;47982:4;47969:9;:17;;47961:40;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;48053:5;48040:9;:18;;48032:39;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;48131:12;48111:17;:32;48103:49;;;::::0;;::::1;::::0;;::::1;;::::0;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;48163:19;::::0;::::1;:31:::0;;;;48205:27:::1;::::0;;::::1;:47:::0;-1:-1:-1;47682:578:0:o;41655:33::-;;;;:::o;45788:454::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45989:5:::1;45974:12;:20;45966:42;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46075:5;46027:44;46059:11:::0;46027:27:::1;:9:::0;46041:12;46027:13:::1;:27::i;:::-;:31:::0;::::1;:44::i;:::-;:53;;46019:75;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;46105:11;:26:::0;;;;46142:8:::1;:20:::0;;;;46173:11:::1;:26:::0;46210:10:::1;:24:::0;45788:454::o;41242:77::-;;;;;;:::o;49025:2212::-;49122:9;:16;49083:7;;49111:27;;49103:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49169:24;49196:9;49206:8;49196:19;;;;;;;;;;;;;;;;;;49169:46;;49226:26;49255:15;49271:8;49255:25;;;;;;;;;;;;;;;;;;49226:54;;49291:13;49307:22;49322:6;49307:14;:22::i;:::-;49291:38;;49346:7;:18;;;49368:1;49346:23;49342:1742;;;49434:1;49413:18;;;:22;49450:24;;;49510:12;49489:18;;;:33;;;49537:19;;;:34;49342:1742;;;49630:7;:18;;;40983:8;49608:40;49593:12;:55;49589:1495;;;49710:1;49689:18;;;:22;49726:24;;;49786:12;49765:18;;;:33;;;49726:16;49813:22;;;:26;;;49854:20;;;:24;49893:19;;;:34;49589:1495;;;49985:7;:18;;;40922:8;49964:39;49949:12;:54;49945:1139;;;50045:18;;;;;;50020:22;;;:43;50101:16;;50078:20;;;:39;50132:22;50169:24;;;50229:12;-1:-1:-1;50208:18:0;;:33;;;50256:19;;;:34;49945:1139;;;50366:7;:19;;;40813:3;50342:43;50327:12;:58;:110;;;;50410:7;:22;;;50389:7;:18;;;:43;50436:1;50389:48;50327:110;50323:750;;;50458:25;;;;;;-1:-1:-1;50502:18:0;;;:20;;;;;;;50563:12;50541:19;;;:34;50323:750;;;50616:16;50635:64;50682:7;:16;;;50635:42;50656:7;:20;;;50635:7;:16;;;:20;;:42;;;;:::i;:::-;:46;;:64::i;:::-;50760:22;;;;50785:1;50739:18;;;50616:83;;-1:-1:-1;50739:43:0;:47;;50718:18;50828:24;50616:83;50739:47;50828:12;:24::i;:::-;50805:47;;50906:39;50914:12;50928:7;:16;;;50906:7;:39::i;:::-;50875:28;50883:12;50897:5;50875:7;:28::i;:::-;:70;50871:187;;;51010:16;;;;50989;;:49;;51032:5;;50989:38;;:20;:38::i;:49::-;50970:68;;50871:187;50323:750;;;;51094:16;;;:24;;;51206:22;;;;51185:18;;;;51159:20;;;;51138:16;;:91;;51185:43;;;;;51138:42;;:20;:42::i;:::-;:46;;:91::i;:::-;51131:98;49025:2212;-1:-1:-1;;;;;49025:2212:0:o;40998:46::-;41039:5;40998:46;:::o;40877:53::-;40922:8;40877:53;:::o;42550:28::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42550:28:0;;;;;;;;;;;;;;:::o;41702:32::-;;;;:::o;41537:33::-;;;;:::o;42771:984::-;42820:11;;;;;;;42819:12;42811:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42866:42;;;;;;42902:4;42866:42;;;;;;41103;;42866:27;;:42;;;;;;;;;;;;;;41103;42866;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42866:42:0;42858:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42953:42;42934:8;;:62;;;;;;;;;;;;;;;;;;43029:42;43007:11;;:65;;;;;;;;;;;;;;;;;;43102:42;43083:8;;:62;;;;;;;;;;;;;;;;;;43170:4;43156:11;:18;;;;43217:4;43206:8;:15;;;;43266:4;43252:11;:18;;;;43301:4;43288:10;:17;;;;43322:9;43337:53;;;;;;;;43354:1;43337:53;;;;;;43366:1;43337:53;;;;;;43370:1;43337:53;;;;43373:1;43337:53;;;;43376:1;43337:53;;;;43379:1;43337:53;;;;43382:1;43337:53;;;;43385:1;43337:53;;;;43388:1;43337:53;;;43322:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43418:9;43433:53;;;;;;;;43450:1;43433:53;;;;;;43462:1;43433:53;;;;;;43466:1;43433:53;;;;43469:1;43433:53;;;;43472:1;43433:53;;;;43475:1;43433:53;;;;43478:1;43433:53;;;;43481:1;43433:53;;;;43484:1;43433:53;;;43418:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43514:15;43535:31;;;;;;;;43546:1;43535:31;;;;43549:1;43535:31;;;;43552:1;43535:31;;;;43555:1;43535:31;;;;43558:1;43535:31;;;;43561:1;43535:31;;;;43564:1;43535:31;;;43514:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43594:15;43615:31;;;;;;;;43626:1;43615:31;;;;43629:1;43615:31;;;;43632:1;43615:31;;;;43635:1;43615:31;;;;43638:1;43615:31;;;;43641:1;43615:31;;;;43644:1;43615:31;;;43594:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43690:4;43676:11;;:18;;;;;;;;;;;;;;;;;;43722:10;43710:37;;;43734:12;43710:37;;;;;;;;;;;;;;;;;;42771:984::o;51370:825::-;44174:9;:16;44156:15;44201:466;44227:7;44222:2;:12;44201:466;;;44257:24;44284:9;44294:2;44284:13;;;;;;;;;;;;;;;;;;44257:40;;44334:12;44316:6;:15;;;:30;44312:344;;;44367:274;44392:4;44374:6;:15;;;:22;:65;;;;;44416:6;:23;;;44400:12;:39;;44374:65;44367:274;;;44482:43;44519:5;44482:32;44502:11;;44482:6;:15;;;:19;;:32;;;;:::i;:43::-;44464:15;;;:61;44574:23;;;;:47;;40868:2;44574:27;:47::i;:::-;44548:23;;;:73;44367:274;;;-1:-1:-1;44236:4:0;;44201:466;;;-1:-1:-1;51477:9:0::1;:16:::0;51466:27;::::1;51458:55;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;51524:24;51551:9;51561:8;51551:19;;;;;;;;;;;;;;;;;;51524:46;;51607:12;51589:6;:15;;;:30;51581:49;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;51680:10:::0;;51659::::1;::::0;51680:63:::1;::::0;:10:::1;;51659::::0;51725:4:::1;51732:10:::0;51680:27:::1;:63::i;:::-;51794:19;::::0;::::1;::::0;:35:::1;::::0;51818:10;51794:23:::1;:35::i;:::-;51772:19;::::0;::::1;:57:::0;51904:15:::1;::::0;::::1;::::0;51871::::1;::::0;51889:42:::1;::::0;51925:5:::1;::::0;51889:31:::1;::::0;:10;;:14:::1;:31::i;:42::-;51871:60;;41103:42;51942:24;;;51967:7;51976;51942:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;52043:21;52067:23;52082:7;52067:10;:14;;:23;;;;:::i;:::-;52043:47;;52101:31;52110:13;52125:6;52101:8;:31::i;:::-;52150:37;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;::::1;::::0;;;;;;::::1;44677:1;;;;51370:825:::0;;;:::o;52804:1013::-;44034:8;;;;44020:10;:22;;:56;;-1:-1:-1;44065:10:0;44046:30;;;;:18;:30;;;;;;;;44020:56;44012:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52917:9:::1;:16:::0;52906:27;::::1;52898:55;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;52964:24;52991:9;53001:8;52991:19;;;;;;;;;;;;;;;;;;52964:46;;53048:12;53029:6;:15;;;:31;;53021:51;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;53134:36;::::0;;;;;53164:4:::1;53134:36;::::0;::::1;::::0;;;41103:42:::1;::::0;53134:21:::1;::::0;:36;;;;;::::1;::::0;;;;;;;;41103:42;53134:36;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;53134:36:0;53113:16:::1;::::0;::::1;::::0;53091:17:::1;::::0;::::1;::::0;:39:::1;::::0;:21:::1;:39::i;:::-;:79;;53083:104;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;53254:10:::0;;:24:::1;::::0;;;;;;;53233:18:::1;::::0;53254:10:::1;;::::0;:22:::1;::::0;:24:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;:10;:24;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;53254:24:0;53306:19:::1;::::0;::::1;::::0;53254:24;;-1:-1:-1;53293:32:0;::::1;53289:172;;;53342:22;53367:35;53382:6;:19;;;53367:10;:14;;:35;;;;:::i;:::-;53342:60;;53417:32;53426:14;53442:6;53417:8;:32::i;:::-;53289:172;;53518:17;::::0;::::1;::::0;;53568:16:::1;::::0;::::1;::::0;;53494:21:::1;53595::::0;;;;53627:20;;;53518:17;53658:44:::1;41103:42;53683:3:::0;53518:17;53658:24:::1;:44::i;:::-;41103:42;53713:24;;;53738:11;53713:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;53778:14:0::1;::::0;:31:::1;::::0;-1:-1:-1;53778:14:0;-1:-1:-1;53797:11:0;53778:18:::1;:31::i;:::-;53761:14;:48:::0;-1:-1:-1;;;;;;52804:1013:0:o;42585:35::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;44694:151::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44775:8:::1;::::0;:22:::1;:8;44767:39;;;::::0;;::::1;::::0;;::::1;;::::0;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;44817:8;:20:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;44694:151::o;41450:80::-;;;;;;:::o;45540:240::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45632:32:::1;::::0;::::1;;::::0;;;:18:::1;:32;::::0;;;;;::::1;;45628:145;;;45681:32;;45716:5;45681:32:::0;;;:18:::1;:32;::::0;;;;:40;;;::::1;::::0;;45736:23:::1;:25:::0;;;;;;45540:240::o;41598:30::-;;;;:::o;45028:259::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41103:42:::1;45107;;45124:8;45107:33;;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;45107:35:0;:42:::1;;;45099:69;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;41192:42;45187:43;;45204:8;45187:33;;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;45187:35:0;:43:::1;;;45179:70;;;::::0;;::::1;::::0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;45260:8;:19:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;45028:259::o;41845:42::-;;;;:::o;40937:54::-;40983:8;40937:54;:::o;44853:167::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44940:26:::1;::::0;::::1;44932:43;;;::::0;;::::1;::::0;;::::1;;::::0;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;;;;;;;;::::1;;44986:11;:26:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;44853:167::o;53825:191::-;43907:8;;:22;:8;43919:10;43907:22;43899:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53975:33:::1;:19;::::0;::::1;53995:3:::0;54000:7;53975:19:::1;:33::i;:::-;53825:191:::0;;;:::o;5511:179::-;5569:7;5601:5;;;5625:6;;;;5617:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5681:1;5511:179;-1:-1:-1;;;5511:179:0:o;48268:505::-;48341:7;48362:11;48375;48409:8;;;;;;;;;;;48392:38;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48392:40:0;;;;;;;48498:14;;;;48392:40;48481:46;;;;;;;48392:40;;-1:-1:-1;48392:40:0;;-1:-1:-1;48451:11:0;;;;48498:14;;;;;48481:44;;:46;;;;;48392:40;;48481:46;;;;;;;48498:14;48481:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48481:46:0;;;;;;;;;-1:-1:-1;48481:46:0;-1:-1:-1;48548:12:0;48563:47;;;;;;:38;;48598:2;;48563:30;;;;;;:38;;:12;;;;:21;;:16;:21::i;:30::-;:34;;:38::i;:47::-;48548:62;;48635:1;48628:4;:8;:108;;48651:2;48643:4;:10;;:93;;48688:29;48714:2;48688:21;;:12;;;;:21;;:16;:21::i;:29::-;48662:22;48680:3;48662:22;;:13;48671:3;48662:13;;:4;:8;;:13;;;;:::i;:22::-;:55;;48661:75;;48732:4;48661:75;;;48721:4;48728:1;48721:8;48661:75;48643:93;;;48656:2;48643:93;48628:108;;;48639:1;48628:108;48761:4;48754:11;;48268:505;-1:-1:-1;;;;;;;48268:505:0:o;5973:158::-;6031:7;6064:1;6059;:6;;6051:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;6118:5:0;;;5973:158::o;7088:153::-;7146:7;7178:1;7174;:5;7166:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7232:1;7228;:5;;;;;;;7088:153;-1:-1:-1;;;7088:153:0:o;51245:117::-;51307:9;51337:1;51333;:5;:21;;-1:-1:-1;51349:5:0;;51245:117::o;6390:220::-;6448:7;6472:6;6468:20;;-1:-1:-1;6487:1:0;6480:8;;6468:20;6511:5;;;6515:1;6511;:5;:1;6535:5;;;;;:10;6527:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19232:248;19403:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19426:27;19403:68;;;19376:96;;19396:5;;19376:19;:96::i;:::-;19232:248;;;;:::o;52203:593::-;52290:18;52311:41;52346:5;52311:30;52329:11;;52311:13;:17;;:30;;;;:::i;:41::-;52290:62;;52369:21;52393:40;52427:5;52393:29;52411:10;;52393:13;:17;;:29;;;;:::i;:40::-;52369:64;;52450:19;52472:38;52504:5;52472:27;52490:8;;52472:13;:17;;:27;;;;:::i;:38::-;52552:11;;52527:49;;;;;;:24;52552:11;;;52527:49;;;;;;;;;;;52450:60;;-1:-1:-1;41103:42:0;;52527:24;;:49;;;;;-1:-1:-1;;52527:49:0;;;;;;;;-1:-1:-1;41103:42:0;52527:49;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41103:42:0;;-1:-1:-1;52587:24:0;;-1:-1:-1;52620:4:0;;-1:-1:-1;52627:30:0;:13;52645:11;52627:17;:30::i;:::-;52587:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;52689:17:0;;;;:36;;-1:-1:-1;52711:13:0;52689:21;:36::i;:::-;52669:17;;;:56;52755:16;;;;:33;;52776:11;52755:20;:33::i;:::-;52736:6;:16;;:52;;;;52203:593;;;;;:::o;19013:211::-;19157:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19180:23;19157:58;;;19130:86;;19150:5;;21474:774;21898:23;21924:69;21952:4;21924:69;;;;;;;;;;;;;;;;;21932:5;21924:27;;;;:69;;;;;:::i;:::-;22008:17;;21898:95;;-1:-1:-1;22008:21:0;22004:237;;22163:10;22152:30;;;;;;;;;;;;;;;-1:-1:-1;22152:30:0;22144:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13901:229;14038:12;14070:52;14092:6;14100:4;14106:1;14109:12;14070:21;:52::i;:::-;14063:59;13901:229;-1:-1:-1;;;;13901:229:0:o;15021:571::-;15191:12;15249:5;15224:21;:30;;15216:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15316:18;15327:6;15316:10;:18::i;:::-;15308:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15442:12;15456:23;15483:6;:11;;15502:5;15509:4;15483:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15441:73;;;;15532:52;15550:7;15559:10;15571:12;15532:17;:52::i;:::-;15525:59;15021:571;-1:-1:-1;;;;;;;15021:571:0:o;10961:444::-;11341:20;11389:8;;;10961:444::o;17670:777::-;17820:12;17849:7;17845:595;;;-1:-1:-1;17880:10:0;17873:17;;17845:595;17994:17;;:21;17990:439;;18257:10;18251:17;18318:15;18305:10;18301:2;18297:19;18290:44;18205:148;18400:12;18393:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Swarm Source

ipfs://5d0c9af607be0affbcae9059abc227d59a11c88ba958d9a12491f7dc6fed2c11
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading