Contract 0x3e719b796d4e3640f850291dc019f8e0080ddd31

Contract Overview

Balance:
0 BNB
Txn Hash
Block
From
To
Value [Txn Fee]
0xf891045b8ea008f10130e7c2c39bb0c2050d0aca174911f338f8b3d3c42a727783978372021-04-29 8:08:2244 days 4 hrs ago0x20000b9b01e93a39db9d286e9264eff7f2af16e9 IN  Contract Creation0 BNB0.02188771
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x2e241822f9c2319d9c16f41bbe9995cefc6384da058492e8e149f9054c26b38888320882021-05-14 10:36:0529 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x2e241822f9c2319d9c16f41bbe9995cefc6384da058492e8e149f9054c26b38888320882021-05-14 10:36:0529 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x2e241822f9c2319d9c16f41bbe9995cefc6384da058492e8e149f9054c26b38888320882021-05-14 10:36:0529 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x2e241822f9c2319d9c16f41bbe9995cefc6384da058492e8e149f9054c26b38888320882021-05-14 10:36:0529 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x91ae51e37f9ffddbefb47ddc904de917c5d6e1945dd9613fde0908e18896069e88319952021-05-14 10:31:2629 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x91ae51e37f9ffddbefb47ddc904de917c5d6e1945dd9613fde0908e18896069e88319952021-05-14 10:31:2629 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x91ae51e37f9ffddbefb47ddc904de917c5d6e1945dd9613fde0908e18896069e88319952021-05-14 10:31:2629 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x91ae51e37f9ffddbefb47ddc904de917c5d6e1945dd9613fde0908e18896069e88319952021-05-14 10:31:2629 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x91ae51e37f9ffddbefb47ddc904de917c5d6e1945dd9613fde0908e18896069e88319952021-05-14 10:31:2629 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x91ae51e37f9ffddbefb47ddc904de917c5d6e1945dd9613fde0908e18896069e88319952021-05-14 10:31:2629 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x91ae51e37f9ffddbefb47ddc904de917c5d6e1945dd9613fde0908e18896069e88319952021-05-14 10:31:2629 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0x6625d14dcdaae17da87e119307e5bd5b10b27f46eb3a79a7a20deee50385cbe588319542021-05-14 10:29:2329 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0xb132b2004fedcc2ce441af99c74e4b1b898533ecaf574667e91328369f3158c888319102021-05-14 10:27:1129 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0xb132b2004fedcc2ce441af99c74e4b1b898533ecaf574667e91328369f3158c888319102021-05-14 10:27:1129 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0xb132b2004fedcc2ce441af99c74e4b1b898533ecaf574667e91328369f3158c888319102021-05-14 10:27:1129 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0xb132b2004fedcc2ce441af99c74e4b1b898533ecaf574667e91328369f3158c888319102021-05-14 10:27:1129 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0xb132b2004fedcc2ce441af99c74e4b1b898533ecaf574667e91328369f3158c888319102021-05-14 10:27:1129 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
0xb132b2004fedcc2ce441af99c74e4b1b898533ecaf574667e91328369f3158c888319102021-05-14 10:27:1129 days 1 hr ago 0xebc8c5c6a046183913496181b001f1d0f8c9b7ff 0x3e719b796d4e3640f850291dc019f8e0080ddd310 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SakePerpState

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

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

// File: @openzeppelin\contracts-upgradeable\math\SafeMathUpgradeable.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

        return c;
    }

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

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

// File: node_modules\@openzeppelin\contracts-upgradeable\proxy\Initializable.sol


// solhint-disable-next-line compiler-version
pragma solidity >=0.4.24 <0.8.0;


/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 * 
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
 * 
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 */
abstract contract Initializable {

    /**
     * @dev Indicates that the contract has been initialized.
     */
    bool private _initialized;

    /**
     * @dev Indicates that the contract is in the process of being initialized.
     */
    bool private _initializing;

    /**
     * @dev Modifier to protect an initializer function from being invoked twice.
     */
    modifier initializer() {
        require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized");

        bool isTopLevelCall = !_initializing;
        if (isTopLevelCall) {
            _initializing = true;
            _initialized = true;
        }

        _;

        if (isTopLevelCall) {
            _initializing = false;
        }
    }

    /// @dev Returns true if and only if the function is running in the constructor
    function _isConstructor() private view returns (bool) {
        // extcodesize checks the size of the code stored in an address, and
        // address returns the current address. Since the code is still not
        // deployed when running a constructor, any checks on its code size will
        // yield zero, making it an effective way to detect if a contract is
        // under construction or not.
        address self = address(this);
        uint256 cs;
        // solhint-disable-next-line no-inline-assembly
        assembly { cs := extcodesize(self) }
        return cs == 0;
    }
}

// File: node_modules\@openzeppelin\contracts-upgradeable\GSN\ContextUpgradeable.sol


pragma solidity >=0.6.0 <0.8.0;


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

    function __Context_init_unchained() internal initializer {
    }
    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;
    }
    uint256[50] private __gap;
}

// File: @openzeppelin\contracts-upgradeable\access\OwnableUpgradeable.sol


pragma solidity >=0.6.0 <0.8.0;


/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
    address private _owner;

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    function __Ownable_init() internal initializer {
        __Context_init_unchained();
        __Ownable_init_unchained();
    }

    function __Ownable_init_unchained() internal initializer {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

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

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
    uint256[49] private __gap;
}

// File: contracts\utils\DecimalMath.sol

pragma solidity ^0.6.12;


/// @dev Implements simple fixed point math add, sub, mul and div operations.
/// @author Alberto Cuesta Cañada
library DecimalMath {
    using SafeMathUpgradeable for uint256;

    /// @dev Returns 1 in the fixed point representation, with `decimals` decimals.
    function unit(uint8 decimals) internal pure returns (uint256) {
        return 10**uint256(decimals);
    }

    /// @dev Adds x and y, assuming they are both fixed point with 18 decimals.
    function addd(uint256 x, uint256 y) internal pure returns (uint256) {
        return x.add(y);
    }

    /// @dev Subtracts y from x, assuming they are both fixed point with 18 decimals.
    function subd(uint256 x, uint256 y) internal pure returns (uint256) {
        return x.sub(y);
    }

    /// @dev Multiplies x and y, assuming they are both fixed point with 18 digits.
    function muld(uint256 x, uint256 y) internal pure returns (uint256) {
        return muld(x, y, 18);
    }

    /// @dev Multiplies x and y, assuming they are both fixed point with `decimals` digits.
    function muld(
        uint256 x,
        uint256 y,
        uint8 decimals
    ) internal pure returns (uint256) {
        return x.mul(y).div(unit(decimals));
    }

    /// @dev Divides x between y, assuming they are both fixed point with 18 digits.
    function divd(uint256 x, uint256 y) internal pure returns (uint256) {
        return divd(x, y, 18);
    }

    /// @dev Divides x between y, assuming they are both fixed point with `decimals` digits.
    function divd(
        uint256 x,
        uint256 y,
        uint8 decimals
    ) internal pure returns (uint256) {
        return x.mul(unit(decimals)).div(y);
    }
}

// File: contracts\utils\Decimal.sol


pragma solidity ^0.6.12;



library Decimal {
    using DecimalMath for uint256;
    using SafeMathUpgradeable for uint256;

    struct decimal {
        uint256 d;
    }

    function zero() internal pure returns (decimal memory) {
        return decimal(0);
    }

    function one() internal pure returns (decimal memory) {
        return decimal(DecimalMath.unit(18));
    }

    function toUint(decimal memory x) internal pure returns (uint256) {
        return x.d;
    }

    function modD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        return decimal(x.d.mul(DecimalMath.unit(18)) % y.d);
    }

    function cmp(decimal memory x, decimal memory y) internal pure returns (int8) {
        if (x.d > y.d) {
            return 1;
        } else if (x.d < y.d) {
            return -1;
        }
        return 0;
    }

    /// @dev add two decimals
    function addD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.add(y.d);
        return t;
    }

    /// @dev subtract two decimals
    function subD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.sub(y.d);
        return t;
    }

    /// @dev multiple two decimals
    function mulD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.muld(y.d);
        return t;
    }

    /// @dev multiple a decimal by a uint256
    function mulScalar(decimal memory x, uint256 y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.mul(y);
        return t;
    }

    /// @dev divide two decimals
    function divD(decimal memory x, decimal memory y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.divd(y.d);
        return t;
    }

    /// @dev divide a decimal by a uint256
    function divScalar(decimal memory x, uint256 y) internal pure returns (decimal memory) {
        decimal memory t;
        t.d = x.d.div(y);
        return t;
    }
}

// File: @openzeppelin\contracts-upgradeable\math\SignedSafeMathUpgradeable.sol


pragma solidity >=0.6.0 <0.8.0;

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

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

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

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

        return c;
    }

    /**
     * @dev Returns the integer division of two signed integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(int256 a, int256 b) internal pure returns (int256) {
        require(b != 0, "SignedSafeMath: division by zero");
        require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow");

        int256 c = a / b;

        return c;
    }

    /**
     * @dev Returns the subtraction of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a - b;
        require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow");

        return c;
    }

    /**
     * @dev Returns the addition of two signed integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(int256 a, int256 b) internal pure returns (int256) {
        int256 c = a + b;
        require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow");

        return c;
    }
}

// File: contracts\utils\SignedDecimalMath.sol

pragma solidity ^0.6.12;


/// @dev Implements simple signed fixed point math add, sub, mul and div operations.
library SignedDecimalMath {
    using SignedSafeMathUpgradeable for int256;

    /// @dev Returns 1 in the fixed point representation, with `decimals` decimals.
    function unit(uint8 decimals) internal pure returns (int256) {
        return int256(10**uint256(decimals));
    }

    /// @dev Adds x and y, assuming they are both fixed point with 18 decimals.
    function addd(int256 x, int256 y) internal pure returns (int256) {
        return x.add(y);
    }

    /// @dev Subtracts y from x, assuming they are both fixed point with 18 decimals.
    function subd(int256 x, int256 y) internal pure returns (int256) {
        return x.sub(y);
    }

    /// @dev Multiplies x and y, assuming they are both fixed point with 18 digits.
    function muld(int256 x, int256 y) internal pure returns (int256) {
        return muld(x, y, 18);
    }

    /// @dev Multiplies x and y, assuming they are both fixed point with `decimals` digits.
    function muld(
        int256 x,
        int256 y,
        uint8 decimals
    ) internal pure returns (int256) {
        return x.mul(y).div(unit(decimals));
    }

    /// @dev Divides x between y, assuming they are both fixed point with 18 digits.
    function divd(int256 x, int256 y) internal pure returns (int256) {
        return divd(x, y, 18);
    }

    /// @dev Divides x between y, assuming they are both fixed point with `decimals` digits.
    function divd(
        int256 x,
        int256 y,
        uint8 decimals
    ) internal pure returns (int256) {
        return x.mul(unit(decimals)).div(y);
    }
}

// File: contracts\utils\SignedDecimal.sol

pragma solidity ^0.6.12;




library SignedDecimal {
    using SignedDecimalMath for int256;
    using SignedSafeMathUpgradeable for int256;

    struct signedDecimal {
        int256 d;
    }

    function zero() internal pure returns (signedDecimal memory) {
        return signedDecimal(0);
    }

    function toInt(signedDecimal memory x) internal pure returns (int256) {
        return x.d;
    }

    function isNegative(signedDecimal memory x) internal pure returns (bool) {
        if (x.d < 0) {
            return true;
        }
        return false;
    }

    function abs(signedDecimal memory x) internal pure returns (Decimal.decimal memory) {
        Decimal.decimal memory t;
        if (x.d < 0) {
            t.d = uint256(0 - x.d);
        } else {
            t.d = uint256(x.d);
        }
        return t;
    }

    /// @dev add two decimals
    function addD(signedDecimal memory x, signedDecimal memory y) internal pure returns (signedDecimal memory) {
        signedDecimal memory t;
        t.d = x.d.add(y.d);
        return t;
    }

    /// @dev subtract two decimals
    function subD(signedDecimal memory x, signedDecimal memory y) internal pure returns (signedDecimal memory) {
        signedDecimal memory t;
        t.d = x.d.sub(y.d);
        return t;
    }

    /// @dev multiple two decimals
    function mulD(signedDecimal memory x, signedDecimal memory y) internal pure returns (signedDecimal memory) {
        signedDecimal memory t;
        t.d = x.d.muld(y.d);
        return t;
    }

    /// @dev multiple a signedDecimal by a int256
    function mulScalar(signedDecimal memory x, int256 y) internal pure returns (signedDecimal memory) {
        signedDecimal memory t;
        t.d = x.d.mul(y);
        return t;
    }

    /// @dev divide two decimals
    function divD(signedDecimal memory x, signedDecimal memory y) internal pure returns (signedDecimal memory) {
        signedDecimal memory t;
        t.d = x.d.divd(y.d);
        return t;
    }

    /// @dev divide a signedDecimal by a int256
    function divScalar(signedDecimal memory x, int256 y) internal pure returns (signedDecimal memory) {
        signedDecimal memory t;
        t.d = x.d.div(y);
        return t;
    }
}

// File: contracts\types\ISakePerpTypes.sol

pragma solidity ^0.6.12;
pragma experimental ABIEncoderV2;



interface ISakePerpTypes {
    //
    // Struct and Enum
    //
    enum Side {BUY, SELL}
    enum PnlCalcOption { SPOT_PRICE, TWAP, ORACLE }

    /// @notice This struct records personal position information
    /// @param size denominated in amm.baseAsset
    /// @param margin isolated margin
    /// @param openNotional the quoteAsset value of position when opening position. the cost of the position
    /// @param lastUpdatedCumulativePremiumFraction for calculating funding payment, record at the moment every time when trader open/reduce/close position
    /// @param lastUpdatedCumulativeOvernightFeeRate for calculating holding fee, record at the moment every time when trader open/reduce/close position
    /// @param liquidityHistoryIndex
    /// @param blockNumber the block number of the last position
    struct Position {
        SignedDecimal.signedDecimal size;
        Decimal.decimal margin;
        Decimal.decimal openNotional;
        SignedDecimal.signedDecimal lastUpdatedCumulativePremiumFraction;
        Decimal.decimal lastUpdatedCumulativeOvernightFeeRate;
        uint256 liquidityHistoryIndex;
        uint256 blockNumber;
    }
}

// File: @openzeppelin\contracts-upgradeable\token\ERC20\IERC20Upgradeable.sol


pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20Upgradeable {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

// File: contracts\types\ISakePerpVaultTypes.sol

pragma solidity ^0.6.12;

interface ISakePerpVaultTypes {
    /**
     * @notice pool types
     * @param HIGH high risk pool
     * @param LOW low risk pool
     */
    enum Risk {HIGH, LOW}
}

// File: contracts\types\IExchangeTypes.sol


pragma solidity ^0.6.12;



interface IExchangeTypes {
    /**
     * @notice asset direction, used in getInputPrice, getOutputPrice, swapInput and swapOutput
     * @param ADD_TO_AMM add asset to Amm
     * @param REMOVE_FROM_AMM remove asset from Amm
     */
    enum Dir {ADD_TO_AMM, REMOVE_FROM_AMM}

    struct LiquidityChangedSnapshot {
        SignedDecimal.signedDecimal cumulativeNotional;
        // the base/quote reserve of amm right before liquidity changed
        Decimal.decimal quoteAssetReserve;
        Decimal.decimal baseAssetReserve;
        // total position size owned by amm after last snapshot taken
        // `totalPositionSize` = currentBaseAssetReserve - lastLiquidityChangedHistoryItem.baseAssetReserve + prevTotalPositionSize
        SignedDecimal.signedDecimal totalPositionSize;
    }
}





// File: @openzeppelin\contracts-upgradeable\token\ERC20\ERC20Upgradeable.sol


pragma solidity >=0.6.0 <0.8.0;





/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {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 ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable {
    using SafeMathUpgradeable 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.
     */
    function __ERC20_init(string memory name_, string memory symbol_) internal initializer {
        __Context_init_unchained();
        __ERC20_init_unchained(name_, symbol_);
    }

    function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {
        _name = name_;
        _symbol = symbol_;
        _decimals = 18;
    }

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(sender, recipient, amount);

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

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

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

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

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

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

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

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

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

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

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

// File: contracts\MMLPToken.sol

pragma solidity ^0.6.12;



contract MMLPToken is ERC20Upgradeable, OwnableUpgradeable {
    constructor(string memory _name, string memory _symbol) public {
        __ERC20_init(_name, _symbol);
        __Ownable_init();
    }

    function mint(address _account, uint256 _amount) external onlyOwner {
        _mint(_account, _amount);
    }

    function burn(address _account, uint256 _amount) external onlyOwner {
        _burn(_account, _amount);
    }
}

// File: contracts\interface\IExchangeState.sol


pragma solidity ^0.6.12;



interface IExchangeState {
    function getMaxHoldingBaseAsset() external view returns (Decimal.decimal memory);

    function getOpenInterestNotionalCap() external view returns (Decimal.decimal memory);

    function initMarginRatio() external view returns (Decimal.decimal memory);

    function maintenanceMarginRatio() external view returns (Decimal.decimal memory);

    function liquidationFeeRatio() external view returns (Decimal.decimal memory);

    function maxLiquidationFee() external view returns (Decimal.decimal memory);

    function spreadRatio() external view returns (Decimal.decimal memory);

    function maxOracleSpreadRatio() external view returns (Decimal.decimal memory);

    function getInputPriceWithReserves(
        IExchangeTypes.Dir _dir,
        Decimal.decimal memory _quoteAssetAmount,
        Decimal.decimal memory _quoteAssetPoolAmount,
        Decimal.decimal memory _baseAssetPoolAmount
    ) external pure returns (Decimal.decimal memory);

    function getOutputPriceWithReserves(
        IExchangeTypes.Dir _dir,
        Decimal.decimal memory _baseAssetAmount,
        Decimal.decimal memory _quoteAssetPoolAmount,
        Decimal.decimal memory _baseAssetPoolAmount
    ) external pure returns (Decimal.decimal memory);

    function calcFee(Decimal.decimal calldata _quoteAssetAmount) external view returns (Decimal.decimal memory);

    function mint(
        ISakePerpVaultTypes.Risk _level,
        address account,
        uint256 amount
    ) external;

    function burn(
        ISakePerpVaultTypes.Risk _level,
        address account,
        uint256 amount
    ) external;

    function getLPToken(ISakePerpVaultTypes.Risk _level) external view returns (MMLPToken);
}

// File: contracts\interface\IExchange.sol

pragma solidity ^0.6.12;


interface IExchange is IExchangeTypes {
    function swapInput(
        Dir _dir,
        Decimal.decimal calldata _quoteAssetAmount,
        Decimal.decimal calldata _baseAssetAmountLimit
    ) external returns (Decimal.decimal memory);

    function swapOutput(
        Dir _dir,
        Decimal.decimal calldata _baseAssetAmount,
        Decimal.decimal calldata _quoteAssetAmountLimit,
        bool _skipFluctuationCheck
    ) external returns (Decimal.decimal memory);

    function migrateLiquidity(Decimal.decimal calldata _liquidityMultiplier, Decimal.decimal calldata _priceLimitRatio)
        external;

    function shutdown() external;

    function settleFunding() external returns (SignedDecimal.signedDecimal memory);

    function calcFee(Decimal.decimal calldata _quoteAssetAmount) external view returns (Decimal.decimal memory);

    function calcBaseAssetAfterLiquidityMigration(
        SignedDecimal.signedDecimal memory _baseAssetAmount,
        Decimal.decimal memory _fromQuoteReserve,
        Decimal.decimal memory _fromBaseReserve
    ) external view returns (SignedDecimal.signedDecimal memory);

    function getInputTwap(Dir _dir, Decimal.decimal calldata _quoteAssetAmount)
        external
        view
        returns (Decimal.decimal memory);

    function getOutputTwap(Dir _dir, Decimal.decimal calldata _baseAssetAmount)
        external
        view
        returns (Decimal.decimal memory);

    function getInputPrice(Dir _dir, Decimal.decimal calldata _quoteAssetAmount)
        external
        view
        returns (Decimal.decimal memory);

    function getOutputPrice(Dir _dir, Decimal.decimal calldata _baseAssetAmount)
        external
        view
        returns (Decimal.decimal memory);

    function getInputPriceWithReserves(
        Dir _dir,
        Decimal.decimal memory _quoteAssetAmount,
        Decimal.decimal memory _quoteAssetPoolAmount,
        Decimal.decimal memory _baseAssetPoolAmount
    ) external view returns (Decimal.decimal memory);

    function getOutputPriceWithReserves(
        Dir _dir,
        Decimal.decimal memory _baseAssetAmount,
        Decimal.decimal memory _quoteAssetPoolAmount,
        Decimal.decimal memory _baseAssetPoolAmount
    ) external view returns (Decimal.decimal memory);

    function getSpotPrice() external view returns (Decimal.decimal memory);

    function getLiquidityHistoryLength() external view returns (uint256);

    // overridden by state variable
    function quoteAsset() external view returns (IERC20Upgradeable);

    function open() external view returns (bool);

    // can not be overridden by state variable due to type `Deciaml.decimal`
    function getSettlementPrice() external view returns (Decimal.decimal memory);

    function getCumulativeNotional() external view returns (SignedDecimal.signedDecimal memory);

    function getMaxHoldingBaseAsset() external view returns (Decimal.decimal memory);

    function getOpenInterestNotionalCap() external view returns (Decimal.decimal memory);

    function getLiquidityChangedSnapshots(uint256 i) external view returns (LiquidityChangedSnapshot memory);

    function mint(
        ISakePerpVaultTypes.Risk _level,
        address account,
        uint256 amount
    ) external;

    function burn(
        ISakePerpVaultTypes.Risk _level,
        address account,
        uint256 amount
    ) external;

    function getMMUnrealizedPNL(Decimal.decimal memory _baseAssetReserve, Decimal.decimal memory _quoteAssetReserve)
        external
        view
        returns (SignedDecimal.signedDecimal memory);

    function moveAMMPriceToOracle(uint256 _oraclePrice, bytes32 _priceFeedKey) external;

    function setPriceFeed(address _priceFeed) external;

    function getReserve() external view returns (Decimal.decimal memory, Decimal.decimal memory);

    function initMarginRatio() external view returns (Decimal.decimal memory);

    function maintenanceMarginRatio() external view returns (Decimal.decimal memory);

    function liquidationFeeRatio() external view returns (Decimal.decimal memory);

    function maxLiquidationFee() external view returns (Decimal.decimal memory);

    function spreadRatio() external view returns (Decimal.decimal memory);

    function priceFeedKey() external view returns (bytes32);

    function tradeLimitRatio() external view returns (uint256);

    function priceAdjustRatio() external view returns (uint256);

    function fluctuationLimitRatio() external view returns (uint256);

    function fundingPeriod() external view returns (uint256);

    function adjustTotalPosition(
        SignedDecimal.signedDecimal memory adjustedPosition,
        SignedDecimal.signedDecimal memory oldAdjustedPosition
    ) external;

    function getTotalPositionSize() external view returns (SignedDecimal.signedDecimal memory);

    function exchangeState() external view returns (IExchangeState);

    function getUnderlyingPrice() external view returns (Decimal.decimal memory);

    function isOverSpreadLimit() external view returns (bool);
}

// File: contracts\interface\ISakePerpState.sol


pragma solidity ^0.6.12;


interface ISakePerpState {
    struct TradingState {
        uint256 lastestLongTime;
        uint256 lastestShortTime;
    }

    struct RemainMarginInfo {
        Decimal.decimal remainMargin;
        Decimal.decimal badDebt;
        SignedDecimal.signedDecimal fundingPayment;
        Decimal.decimal overnightFee;
    }

    function checkWaitingPeriod(
        address _exchange,
        address _trader,
        ISakePerpTypes.Side _side
    ) external returns (bool);

    function updateOpenInterestNotional(IExchange _exchange, SignedDecimal.signedDecimal memory _amount) external;

    function getWhiteList() external view returns (address);

    function getPositionNotionalAndUnrealizedPnl(
        IExchange _exchange,
        ISakePerpTypes.Position memory _position,
        ISakePerpTypes.PnlCalcOption _pnlCalcOption
    ) external view returns (Decimal.decimal memory positionNotional, SignedDecimal.signedDecimal memory unrealizedPnl);

    function calcPositionAfterLiquidityMigration(
        IExchange _exchange,
        ISakePerpTypes.Position memory _position,
        uint256 _latestLiquidityIndex
    ) external view returns (ISakePerpTypes.Position memory);

    function calcPositionAfterLiquidityMigrationWithoutNew(
        IExchange _exchange,
        ISakePerpTypes.Position memory _position,
        uint256 _latestLiquidityIndex
    ) external returns (SignedDecimal.signedDecimal memory);

    function calcRemainMarginWithFundingPaymentAndOvernightFee(
        IExchange _exchange,
        ISakePerpTypes.Position memory _oldPosition,
        SignedDecimal.signedDecimal memory _marginDelta
    ) external view returns (RemainMarginInfo memory remainMarginInfo);
}

// File: contracts\interface\ISakePerp.sol


pragma solidity ^0.6.12;

interface ISakePerp is ISakePerpTypes {
    function getMMLiquidity(address _exchange) external view returns (SignedDecimal.signedDecimal memory);

    function getLatestCumulativePremiumFraction(IExchange _exchange)
        external
        view
        returns (SignedDecimal.signedDecimal memory);

    function getLatestCumulativeOvernightFeeRate(IExchange _exchange) external view returns (Decimal.decimal memory);

    function getPositionNotionalAndUnrealizedPnl(
        IExchange _exchange,
        address _trader,
        PnlCalcOption _pnlCalcOption
    ) external view returns (Decimal.decimal memory positionNotional, SignedDecimal.signedDecimal memory unrealizedPnl);

    function getPosition(IExchange _exchange, address _trader) external view returns (Position memory);

    function getUnadjustedPosition(IExchange _exchange, address _trader)
        external
        view
        returns (Position memory position);

    function getMarginRatio(IExchange _exchange, address _trader)
        external
        view
        returns (SignedDecimal.signedDecimal memory);
}

// File: contracts\utils\BlockContext.sol


pragma solidity ^0.6.12;

// wrap block.xxx functions for testing
// only support timestamp and number so far
abstract contract BlockContext {
    //◥◤◥◤◥◤◥◤◥◤◥◤◥◤◥◤ add state variables below ◥◤◥◤◥◤◥◤◥◤◥◤◥◤◥◤//

    //◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣ add state variables above ◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣//
    uint256[50] private __gap;

    function _blockTimestamp() internal view virtual returns (uint256) {
        return block.timestamp;
    }

    function _blockNumber() internal view virtual returns (uint256) {
        return block.number;
    }
}

// File: contracts\utils\MixedDecimal.sol

pragma solidity ^0.6.12;




/// @dev To handle a signedDecimal add/sub/mul/div a decimal and provide convert decimal to signedDecimal helper
library MixedDecimal {
    using SignedDecimal for SignedDecimal.signedDecimal;
    using SignedSafeMathUpgradeable for int256;

    uint256 private constant _INT256_MAX = 2**255 - 1;
    string private constant ERROR_NON_CONVERTIBLE = "MixedDecimal: uint value is bigger than _INT256_MAX";

    modifier convertible(Decimal.decimal memory x) {
        require(_INT256_MAX >= x.d, ERROR_NON_CONVERTIBLE);
        _;
    }

    function fromDecimal(Decimal.decimal memory x)
        internal
        pure
        convertible(x)
        returns (SignedDecimal.signedDecimal memory)
    {
        return SignedDecimal.signedDecimal(int256(x.d));
    }

    function toUint(SignedDecimal.signedDecimal memory x) internal pure returns (uint256) {
        return x.abs().d;
    }

    /// @dev add SignedDecimal.signedDecimal and Decimal.decimal, using SignedSafeMath directly
    function addD(SignedDecimal.signedDecimal memory x, Decimal.decimal memory y)
        internal
        pure
        convertible(y)
        returns (SignedDecimal.signedDecimal memory)
    {
        SignedDecimal.signedDecimal memory t;
        t.d = x.d.add(int256(y.d));
        return t;
    }

    /// @dev subtract SignedDecimal.signedDecimal by Decimal.decimal, using SignedSafeMath directly
    function subD(SignedDecimal.signedDecimal memory x, Decimal.decimal memory y)
        internal
        pure
        convertible(y)
        returns (SignedDecimal.signedDecimal memory)
    {
        SignedDecimal.signedDecimal memory t;
        t.d = x.d.sub(int256(y.d));
        return t;
    }

    /// @dev multiple a SignedDecimal.signedDecimal by Decimal.decimal
    function mulD(SignedDecimal.signedDecimal memory x, Decimal.decimal memory y)
        internal
        pure
        convertible(y)
        returns (SignedDecimal.signedDecimal memory)
    {
        SignedDecimal.signedDecimal memory t;
        t = x.mulD(fromDecimal(y));
        return t;
    }

    /// @dev multiple a SignedDecimal.signedDecimal by a uint256
    function mulScalar(SignedDecimal.signedDecimal memory x, uint256 y)
        internal
        pure
        returns (SignedDecimal.signedDecimal memory)
    {
        require(_INT256_MAX >= y, ERROR_NON_CONVERTIBLE);
        SignedDecimal.signedDecimal memory t;
        t = x.mulScalar(int256(y));
        return t;
    }

    /// @dev divide a SignedDecimal.signedDecimal by a Decimal.decimal
    function divD(SignedDecimal.signedDecimal memory x, Decimal.decimal memory y)
        internal
        pure
        convertible(y)
        returns (SignedDecimal.signedDecimal memory)
    {
        SignedDecimal.signedDecimal memory t;
        t = x.divD(fromDecimal(y));
        return t;
    }

    /// @dev divide a SignedDecimal.signedDecimal by a uint256
    function divScalar(SignedDecimal.signedDecimal memory x, uint256 y)
        internal
        pure
        returns (SignedDecimal.signedDecimal memory)
    {
        require(_INT256_MAX >= y, ERROR_NON_CONVERTIBLE);
        SignedDecimal.signedDecimal memory t;
        t = x.divScalar(int256(y));
        return t;
    }
}

// File: contracts\SakePerpState.sol


pragma solidity 0.6.12;


contract SakePerpState is ISakePerpState, OwnableUpgradeable, BlockContext {
    using SafeMathUpgradeable for uint256;
    using Decimal for Decimal.decimal;
    using SignedDecimal for SignedDecimal.signedDecimal;
    using MixedDecimal for SignedDecimal.signedDecimal;

    mapping(address => mapping(address => TradingState)) public tradingState;
    address public SakePerp;
    uint256 public waitingPeriodSecs;

    // key by amm address. will be deprecated or replaced after guarded period.
    // it's not an accurate open interest, just a rough way to control the unexpected loss at the beginning
    mapping(address => Decimal.decimal) public openInterestNotionalMap;
    mapping(uint256 => SignedDecimal.signedDecimal) public snapshotDeltaPosNotional;

    // designed for arbitragers who can hold unlimited positions. will be removed after guarded period
    address internal whitelist;

    //**********************************************************//
    //    Can not change the order of above state variables     //
    //**********************************************************//

    //◥◤◥◤◥◤◥◤◥◤◥◤◥◤◥◤ add state variables below ◥◤◥◤◥◤◥◤◥◤◥◤◥◤◥◤//

    //◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣ add state variables above ◢◣◢◣◢◣◢◣◢◣◢◣◢◣◢◣//
    uint256[50] private __gap;

    modifier onlySakePerp() {
        require(SakePerp == _msgSender(), "caller is not SakePerp");
        _;
    }

    function initialize(address _SakePerp, uint256 _waitingPeriodSecs) public initializer {
        __Ownable_init();

        SakePerp = _SakePerp;
        waitingPeriodSecs = _waitingPeriodSecs;
    }

    /**
     * @notice trader can't do the reverse operation during waiting period
     */
    function checkWaitingPeriod(
        address _exchange,
        address _trader,
        ISakePerpTypes.Side _side
    ) public override onlySakePerp returns (bool) {
        if (_side == ISakePerpTypes.Side.BUY) {
            uint256 lastestShortTime = tradingState[_exchange][_trader].lastestShortTime;
            if (lastestShortTime.add(waitingPeriodSecs) > _blockTimestamp()) {
                return false;
            }
            tradingState[_exchange][_trader].lastestLongTime = _blockTimestamp();
        } else {
            uint256 lastestLongTime = tradingState[_exchange][_trader].lastestLongTime;
            if (lastestLongTime.add(waitingPeriodSecs) > _blockTimestamp()) {
                return false;
            }
            tradingState[_exchange][_trader].lastestShortTime = _blockTimestamp();
        }
        return true;
    }

    /**
     * @notice set max waiting period
     * @dev only owner can call
     * @param _waitingPeriodSecs new max waiting period in seconds
     */
    function setWaitingPeriodSecs(uint256 _waitingPeriodSecs) public onlyOwner {
        waitingPeriodSecs = _waitingPeriodSecs;
    }

    /**
     * @notice add an address in the whitelist. People in the whitelist can hold unlimited positions.
     * @dev only owner can call
     * @param _whitelist an address
     */
    function setWhitelist(address _whitelist) public onlyOwner {
        whitelist = _whitelist;
    }

    function getWhiteList() public view override returns (address) {
        return whitelist;
    }

    /**
     * @dev assume this will be removes soon once the guarded period has ended. caller need to ensure amm exist
     */
    function updateOpenInterestNotional(IExchange _exchange, SignedDecimal.signedDecimal memory _amount)
        public
        override
        onlySakePerp
    {
        // when cap = 0 means no cap
        uint256 cap = _exchange.getOpenInterestNotionalCap().toUint();
        address ammAddr = address(_exchange);
        if (cap > 0) {
            SignedDecimal.signedDecimal memory updatedOpenInterestNotional =
                _amount.addD(openInterestNotionalMap[ammAddr]);
            // the reduced open interest can be larger than total when profit is too high and other position are bankrupt
            if (updatedOpenInterestNotional.toInt() < 0) {
                updatedOpenInterestNotional = SignedDecimal.zero();
            }
            if (_amount.toInt() > 0) {
                // whitelist won't be restrict by open interest cap
                require(updatedOpenInterestNotional.toUint() <= cap || msg.sender == whitelist, "over limit");
            }
            openInterestNotionalMap[ammAddr] = updatedOpenInterestNotional.abs();
        }
    }

    /**
     * @notice get position notional and unrealized Pnl without fee expense and funding payment
     * @param _exchange IExchange address
     * @param _position trader position
     * @param _pnlCalcOption enum PnlCalcOption, SPOT_PRICE for spot price and TWAP for twap price
     * @return positionNotional position notional
     * @return unrealizedPnl unrealized Pnl
     */
    function getPositionNotionalAndUnrealizedPnl(
        IExchange _exchange,
        ISakePerpTypes.Position memory _position,
        ISakePerpTypes.PnlCalcOption _pnlCalcOption
    )
        public
        view
        override
        onlySakePerp
        returns (Decimal.decimal memory positionNotional, SignedDecimal.signedDecimal memory unrealizedPnl)
    {
        Decimal.decimal memory positionSizeAbs = _position.size.abs();
        if (positionSizeAbs.toUint() != 0) {
            bool isShortPosition = _position.size.toInt() < 0;
            IExchangeTypes.Dir dir =
                isShortPosition ? IExchangeTypes.Dir.REMOVE_FROM_AMM : IExchangeTypes.Dir.ADD_TO_AMM;
            if (_pnlCalcOption == ISakePerpTypes.PnlCalcOption.TWAP) {
                positionNotional = _exchange.getOutputTwap(dir, positionSizeAbs);
            }  else if (_pnlCalcOption == ISakePerpTypes.PnlCalcOption.SPOT_PRICE) {
                positionNotional = _exchange.getOutputPrice(dir, positionSizeAbs);
            } else {
                Decimal.decimal memory oraclePrice = _exchange.getUnderlyingPrice();
                positionNotional = positionSizeAbs.mulD(oraclePrice);
            }
            // unrealizedPnlForLongPosition = positionNotional - openNotional
            // unrealizedPnlForShortPosition = positionNotionalWhenBorrowed - positionNotionalWhenReturned =
            // openNotional - positionNotional = unrealizedPnlForLongPosition * -1
            unrealizedPnl = isShortPosition
                ? MixedDecimal.fromDecimal(_position.openNotional).subD(positionNotional)
                : MixedDecimal.fromDecimal(positionNotional).subD(_position.openNotional);
        }
    }

    function calcPositionAfterLiquidityMigration(
        IExchange _exchange,
        ISakePerpTypes.Position memory _position,
        uint256 _latestLiquidityIndex
    ) public view override onlySakePerp returns (ISakePerpTypes.Position memory) {
        if (_position.size.toInt() == 0) {
            _position.liquidityHistoryIndex = _latestLiquidityIndex;
            return _position;
        }

        // get the change in exchange notional value
        // notionalDelta = current cumulative notional - cumulative notional of last snapshot
        IExchange.LiquidityChangedSnapshot memory lastSnapshot =
            _exchange.getLiquidityChangedSnapshots(_position.liquidityHistoryIndex);
        SignedDecimal.signedDecimal memory notionalDelta =
            _exchange.getCumulativeNotional().subD(lastSnapshot.cumulativeNotional);

        // update the old curve's reserve
        // by applying notionalDelta to the old curve
        Decimal.decimal memory updatedOldBaseReserve;
        Decimal.decimal memory updatedOldQuoteReserve;
        if (notionalDelta.toInt() != 0) {
            Decimal.decimal memory baseAssetWorth =
                _exchange.getInputPriceWithReserves(
                    notionalDelta.toInt() > 0 ? IExchangeTypes.Dir.ADD_TO_AMM : IExchangeTypes.Dir.REMOVE_FROM_AMM,
                    notionalDelta.abs(),
                    lastSnapshot.quoteAssetReserve,
                    lastSnapshot.baseAssetReserve
                );
            updatedOldQuoteReserve = notionalDelta.addD(lastSnapshot.quoteAssetReserve).abs();
            if (notionalDelta.toInt() > 0) {
                updatedOldBaseReserve = lastSnapshot.baseAssetReserve.subD(baseAssetWorth);
            } else {
                updatedOldBaseReserve = lastSnapshot.baseAssetReserve.addD(baseAssetWorth);
            }
        } else {
            updatedOldQuoteReserve = lastSnapshot.quoteAssetReserve;
            updatedOldBaseReserve = lastSnapshot.baseAssetReserve;
        }

        // calculate the new position size
        _position.size = _exchange.calcBaseAssetAfterLiquidityMigration(
            _position.size,
            updatedOldQuoteReserve,
            updatedOldBaseReserve
        );
        _position.liquidityHistoryIndex = _latestLiquidityIndex;
        return _position;
    }

    function calcPositionAfterLiquidityMigrationWithoutNew(
        IExchange _exchange,
        ISakePerpTypes.Position memory _position,
        uint256 _latestLiquidityIndex
    ) public override onlySakePerp returns (SignedDecimal.signedDecimal memory) {
        IExchange.LiquidityChangedSnapshot memory latestSnapshot =
            _exchange.getLiquidityChangedSnapshots(_latestLiquidityIndex);
        SignedDecimal.signedDecimal memory notionalDelta = snapshotDeltaPosNotional[_position.liquidityHistoryIndex];
        bool isPositiveValue = _position.size.toInt() > 0 ? true : false;
        Decimal.decimal memory posNotional;

        {
            IExchange.LiquidityChangedSnapshot memory lastSnapshot =
                _exchange.getLiquidityChangedSnapshots(_position.liquidityHistoryIndex);
            SignedDecimal.signedDecimal memory totalDelta =
                latestSnapshot.cumulativeNotional.subD(lastSnapshot.cumulativeNotional).addD(notionalDelta);

            // update the old curve's reserve
            // by applying totalDelta to the old curve
            Decimal.decimal memory updatedOldBaseReserve;
            Decimal.decimal memory updatedOldQuoteReserve;
            if (totalDelta.toInt() != 0) {
                Decimal.decimal memory baseAssetWorth =
                    _exchange.getInputPriceWithReserves(
                        totalDelta.toInt() > 0 ? IExchangeTypes.Dir.ADD_TO_AMM : IExchangeTypes.Dir.REMOVE_FROM_AMM,
                        totalDelta.abs(),
                        lastSnapshot.quoteAssetReserve,
                        lastSnapshot.baseAssetReserve
                    );
                updatedOldQuoteReserve = totalDelta.addD(lastSnapshot.quoteAssetReserve).abs();
                if (totalDelta.toInt() > 0) {
                    updatedOldBaseReserve = lastSnapshot.baseAssetReserve.subD(baseAssetWorth);
                } else {
                    updatedOldBaseReserve = lastSnapshot.baseAssetReserve.addD(baseAssetWorth);
                }
            } else {
                updatedOldQuoteReserve = lastSnapshot.quoteAssetReserve;
                updatedOldBaseReserve = lastSnapshot.baseAssetReserve;
            }

            // measure the trader position's notional value on the old curve
            // (by simulating closing the position)
            posNotional = _exchange.getOutputPriceWithReserves(
                isPositiveValue ? IExchangeTypes.Dir.ADD_TO_AMM : IExchangeTypes.Dir.REMOVE_FROM_AMM,
                _position.size.abs(),
                updatedOldQuoteReserve,
                updatedOldBaseReserve
            );

            SignedDecimal.signedDecimal memory _posNotional = MixedDecimal.fromDecimal(posNotional);
            if (isPositiveValue) {
                _posNotional = _posNotional.mulScalar(-1);
            }
            snapshotDeltaPosNotional[_position.liquidityHistoryIndex] = snapshotDeltaPosNotional[
                _position.liquidityHistoryIndex
            ]
                .addD(_posNotional);
        }

        {
            Decimal.decimal memory updatedNewBaseReserve;
            Decimal.decimal memory updatedNewQuoteReserve;
            if (notionalDelta.toInt() != 0) {
                Decimal.decimal memory baseAssetWorth =
                    _exchange.getInputPriceWithReserves(
                        notionalDelta.toInt() > 0 ? IExchangeTypes.Dir.ADD_TO_AMM : IExchangeTypes.Dir.REMOVE_FROM_AMM,
                        notionalDelta.abs(),
                        latestSnapshot.quoteAssetReserve,
                        latestSnapshot.baseAssetReserve
                    );
                updatedNewQuoteReserve = notionalDelta.addD(latestSnapshot.quoteAssetReserve).abs();
                if (notionalDelta.toInt() > 0) {
                    updatedNewBaseReserve = latestSnapshot.baseAssetReserve.subD(baseAssetWorth);
                } else {
                    updatedNewBaseReserve = latestSnapshot.baseAssetReserve.addD(baseAssetWorth);
                }
            } else {
                updatedNewQuoteReserve = latestSnapshot.quoteAssetReserve;
                updatedNewBaseReserve = latestSnapshot.baseAssetReserve;
            }

            // calculate and apply the required size on the new curve
            SignedDecimal.signedDecimal memory newBaseAsset =
                MixedDecimal.fromDecimal(
                    _exchange.getInputPriceWithReserves(
                        isPositiveValue ? IExchangeTypes.Dir.REMOVE_FROM_AMM : IExchangeTypes.Dir.ADD_TO_AMM,
                        posNotional,
                        updatedNewQuoteReserve,
                        updatedNewBaseReserve
                    )
                );

            return newBaseAsset.mulScalar(isPositiveValue ? 1 : int256(-1));
        }
    }

    function calcRemainMarginWithFundingPaymentAndOvernightFee(
        IExchange _exchange,
        ISakePerpTypes.Position memory _oldPosition,
        SignedDecimal.signedDecimal memory _marginDelta
    ) public view override onlySakePerp returns (RemainMarginInfo memory remainMarginInfo) {
        // calculate funding payment
        SignedDecimal.signedDecimal memory latestCumulativePremiumFraction =
            ISakePerp(SakePerp).getLatestCumulativePremiumFraction(_exchange);
        if (_oldPosition.size.toInt() != 0) {
            remainMarginInfo.fundingPayment = latestCumulativePremiumFraction
                .subD(_oldPosition.lastUpdatedCumulativePremiumFraction)
                .mulD(_oldPosition.size);
        }

        // calculate overnight feerate
        // Overnight Fee = openNotional * overnight fee rate
        Decimal.decimal memory latestCumulativeOvernightFeeRate =
            ISakePerp(SakePerp).getLatestCumulativeOvernightFeeRate(_exchange);
        if (_oldPosition.size.toInt() != 0) {
            remainMarginInfo.overnightFee = latestCumulativeOvernightFeeRate
                .subD(_oldPosition.lastUpdatedCumulativeOvernightFeeRate)
                .mulD(_oldPosition.openNotional);
        }

        // calculate remain margin
        SignedDecimal.signedDecimal memory signedRemainMargin =
            _marginDelta.subD(remainMarginInfo.fundingPayment).subD(remainMarginInfo.overnightFee).addD(
                _oldPosition.margin
            );

        // if remain margin is negative, set to zero and leave the rest to bad debt
        if (signedRemainMargin.toInt() < 0) {
            remainMarginInfo.badDebt = signedRemainMargin.abs();
        } else {
            remainMarginInfo.remainMargin = signedRemainMargin.abs();
        }
    }
}

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"SakePerp","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IExchange","name":"_exchange","type":"address"},{"components":[{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"size","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"margin","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"openNotional","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"lastUpdatedCumulativePremiumFraction","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"lastUpdatedCumulativeOvernightFeeRate","type":"tuple"},{"internalType":"uint256","name":"liquidityHistoryIndex","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"internalType":"struct ISakePerpTypes.Position","name":"_position","type":"tuple"},{"internalType":"uint256","name":"_latestLiquidityIndex","type":"uint256"}],"name":"calcPositionAfterLiquidityMigration","outputs":[{"components":[{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"size","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"margin","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"openNotional","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"lastUpdatedCumulativePremiumFraction","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"lastUpdatedCumulativeOvernightFeeRate","type":"tuple"},{"internalType":"uint256","name":"liquidityHistoryIndex","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"internalType":"struct ISakePerpTypes.Position","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IExchange","name":"_exchange","type":"address"},{"components":[{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"size","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"margin","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"openNotional","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"lastUpdatedCumulativePremiumFraction","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"lastUpdatedCumulativeOvernightFeeRate","type":"tuple"},{"internalType":"uint256","name":"liquidityHistoryIndex","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"internalType":"struct ISakePerpTypes.Position","name":"_position","type":"tuple"},{"internalType":"uint256","name":"_latestLiquidityIndex","type":"uint256"}],"name":"calcPositionAfterLiquidityMigrationWithoutNew","outputs":[{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IExchange","name":"_exchange","type":"address"},{"components":[{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"size","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"margin","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"openNotional","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"lastUpdatedCumulativePremiumFraction","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"lastUpdatedCumulativeOvernightFeeRate","type":"tuple"},{"internalType":"uint256","name":"liquidityHistoryIndex","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"internalType":"struct ISakePerpTypes.Position","name":"_oldPosition","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"_marginDelta","type":"tuple"}],"name":"calcRemainMarginWithFundingPaymentAndOvernightFee","outputs":[{"components":[{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"remainMargin","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"badDebt","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"fundingPayment","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"overnightFee","type":"tuple"}],"internalType":"struct ISakePerpState.RemainMarginInfo","name":"remainMarginInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_exchange","type":"address"},{"internalType":"address","name":"_trader","type":"address"},{"internalType":"enum ISakePerpTypes.Side","name":"_side","type":"uint8"}],"name":"checkWaitingPeriod","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IExchange","name":"_exchange","type":"address"},{"components":[{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"size","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"margin","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"openNotional","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"lastUpdatedCumulativePremiumFraction","type":"tuple"},{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"lastUpdatedCumulativeOvernightFeeRate","type":"tuple"},{"internalType":"uint256","name":"liquidityHistoryIndex","type":"uint256"},{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"internalType":"struct ISakePerpTypes.Position","name":"_position","type":"tuple"},{"internalType":"enum ISakePerpTypes.PnlCalcOption","name":"_pnlCalcOption","type":"uint8"}],"name":"getPositionNotionalAndUnrealizedPnl","outputs":[{"components":[{"internalType":"uint256","name":"d","type":"uint256"}],"internalType":"struct Decimal.decimal","name":"positionNotional","type":"tuple"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"unrealizedPnl","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWhiteList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_SakePerp","type":"address"},{"internalType":"uint256","name":"_waitingPeriodSecs","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"openInterestNotionalMap","outputs":[{"internalType":"uint256","name":"d","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_waitingPeriodSecs","type":"uint256"}],"name":"setWaitingPeriodSecs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_whitelist","type":"address"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"snapshotDeltaPosNotional","outputs":[{"internalType":"int256","name":"d","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"tradingState","outputs":[{"internalType":"uint256","name":"lastestLongTime","type":"uint256"},{"internalType":"uint256","name":"lastestShortTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IExchange","name":"_exchange","type":"address"},{"components":[{"internalType":"int256","name":"d","type":"int256"}],"internalType":"struct SignedDecimal.signedDecimal","name":"_amount","type":"tuple"}],"name":"updateOpenInterestNotional","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"waitingPeriodSecs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b506126a0806100206000396000f3fe608060405234801561001057600080fd5b50600436106101165760003560e01c80637a7e5223116100a25780638da5cb5b116100715780638da5cb5b1461025b578063b0ac5f2f14610263578063cc0ace0a14610276578063cd6dc68714610289578063f2fde38b1461029c57610116565b80637a7e5223146101f2578063854cff2f1461021357806389257117146102265780638b4a5bf31461023b57610116565b806359b8c599116100e957806359b8c5991461018e57806361d92829146101af578063635a3872146101cf5780636886925e146101e2578063715018a6146101ea57610116565b806302a3789e1461011b57806309a9d76c146101305780632f1d1bb21461014e578063542cdc1b1461016e575b600080fd5b61012e6101293660046120d7565b6102af565b005b610138610445565b60405161014591906121a3565b60405180910390f35b61016161015c366004612097565b610454565b60405161014591906125cc565b61018161017c366004611f94565b610a70565b60405161014591906121b7565b6101a161019c366004611f5c565b610bc7565b6040516101459291906125ed565b6101c26101bd366004612097565b610beb565b604051610145919061253a565b61012e6101dd36600461218b565b610f29565b610138610f63565b61012e610f72565b61020561020036600461200c565b610ff1565b6040516101459291906125bc565b61012e610221366004611f40565b611223565b61022e61127a565b6040516101459190612207565b61024e61024936600461204f565b611280565b604051610145919061258d565b6101386114b4565b61022e610271366004611f40565b6114c3565b61022e61028436600461218b565b6114d5565b61012e610297366004611fe1565b6114e7565b61012e6102aa366004611f40565b611594565b6102b761164b565b6098546001600160a01b039081169116146102ed5760405162461bcd60e51b81526004016102e490612345565b60405180910390fd5b6000610368836001600160a01b031663525454106040518163ffffffff1660e01b815260040160206040518083038186803b15801561032b57600080fd5b505afa15801561033f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103639190612170565b61164f565b905082811561043f57610379611dbe565b6001600160a01b0382166000908152609a60209081526040918290208251918201909252905481526103ac908590611653565b905060006103b98261164f565b12156103ca576103c76116c2565b90505b60006103d58561164f565b131561041857826103e5826116dd565b1115806103fc5750609c546001600160a01b031633145b6104185760405162461bcd60e51b81526004016102e490612263565b610421816116ef565b6001600160a01b0383166000908152609a6020526040902090519055505b50505050565b609c546001600160a01b031690565b61045c611dbe565b61046461164b565b6098546001600160a01b039081169116146104915760405162461bcd60e51b81526004016102e490612345565b610499611dd1565b6040516311bf8bf760e11b81526001600160a01b0386169063237f17ee906104c5908690600401612207565b60806040518083038186803b1580156104dd57600080fd5b505afa1580156104f1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610515919061210c565b905061051f611dbe565b5060a08401516000908152609b602090815260408083208151928301909152548152855190919081906105519061164f565b1361055d576000610560565b60015b905061056a611dbe565b610572611dd1565b60a08801516040516311bf8bf760e11b81526001600160a01b038b169163237f17ee916105a29190600401612207565b60806040518083038186803b1580156105ba57600080fd5b505afa1580156105ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f2919061210c565b90506105fc611dbe565b8151865161061591879161060f91611720565b90611746565b905061061f611dbe565b610627611dbe565b6106308361164f565b1561074a5761063d611dbe565b8c6001600160a01b03166350799c8160006106578761164f565b13610663576001610666565b60005b61066f876116ef565b886020015189604001516040518563ffffffff1660e01b815260040161069894939291906121de565b60206040518083038186803b1580156106b057600080fd5b505afa1580156106c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106e89190612170565b905061070961070486602001518661165390919063ffffffff16565b6116ef565b915060006107168561164f565b131561073257604085015161072b9082611763565b9250610744565b60408501516107419082611780565b92505b50610758565b505060208201516040830151905b8b6001600160a01b0316639bf5d1d487610773576001610776565b60005b8d51610781906116ef565b84866040518563ffffffff1660e01b81526004016107a294939291906121de565b60206040518083038186803b1580156107ba57600080fd5b505afa1580156107ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f29190612170565b94506107fc611dbe565b6108058661179d565b9050861561081c5761081981600019611801565b90505b60a08c01516000908152609b60209081526040918290208251918201909252905481526108499082611746565b60a08d01516000908152609b60205260409020905190555061086f9350611dbe92505050565b610877611dbe565b6108808561164f565b156109955761088d611dbe565b8a6001600160a01b03166350799c8160006108a78961164f565b136108b35760016108b6565b60005b6108bf896116ef565b8a602001518b604001516040518563ffffffff1660e01b81526004016108e894939291906121de565b60206040518083038186803b15801561090057600080fd5b505afa158015610914573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109389190612170565b905061095461070488602001518861165390919063ffffffff16565b915060006109618761164f565b131561097d5760408701516109769082611763565b925061098f565b604087015161098c9082611780565b92505b506109a3565b505060208401516040850151905b6109ab611dbe565b610a438b6001600160a01b03166350799c81876109c95760006109cc565b60015b8786886040518563ffffffff1660e01b81526004016109ee94939291906121de565b60206040518083038186803b158015610a0657600080fd5b505afa158015610a1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3e9190612170565b61179d565b9050610a5f85610a5557600019610a58565b60015b8290611801565b9750505050505050505b9392505050565b6000610a7a61164b565b6098546001600160a01b03908116911614610aa75760405162461bcd60e51b81526004016102e490612345565b6000826001811115610ab557fe5b1415610b3e576001600160a01b03808516600090815260976020908152604080832093871683529290522060010154610aec61181d565b609954610afa908390611821565b1115610b0a576000915050610a69565b610b1261181d565b6001600160a01b0380871660009081526097602090815260408083209389168352929052205550610bbd565b6001600160a01b03808516600090815260976020908152604080832093871683529290522054610b6c61181d565b609954610b7a908390611821565b1115610b8a576000915050610a69565b610b9261181d565b6001600160a01b03808716600090815260976020908152604080832093891683529290522060010155505b5060019392505050565b60976020908152600092835260408084209091529082529020805460019091015482565b610bf3611e10565b610bfb61164b565b6098546001600160a01b03908116911614610c285760405162461bcd60e51b81526004016102e490612345565b8251610c339061164f565b610c45575060a0820181905281610a69565b610c4d611dd1565b60a08401516040516311bf8bf760e11b81526001600160a01b0387169163237f17ee91610c7d9190600401612207565b60806040518083038186803b158015610c9557600080fd5b505afa158015610ca9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccd919061210c565b9050610cd7611dbe565b610d568260000151876001600160a01b03166329f9b17b6040518163ffffffff1660e01b815260040160206040518083038186803b158015610d1857600080fd5b505afa158015610d2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d509190612170565b90611720565b9050610d60611dbe565b610d68611dbe565b610d718361164f565b15610e8657610d7e611dbe565b886001600160a01b03166350799c816000610d988761164f565b13610da4576001610da7565b60005b610db0876116ef565b886020015189604001516040518563ffffffff1660e01b8152600401610dd994939291906121de565b60206040518083038186803b158015610df157600080fd5b505afa158015610e05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e299190612170565b9050610e4561070486602001518661165390919063ffffffff16565b91506000610e528561164f565b1315610e6e576040850151610e679082611763565b9250610e80565b6040850151610e7d9082611780565b92505b50610e94565b505060208201516040830151905b86516040516340d71cd960e01b81526001600160a01b038a16916340d71cd991610ec59190859087906004016125d6565b60206040518083038186803b158015610edd57600080fd5b505afa158015610ef1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f159190612170565b87525050505060a083019190915250919050565b610f3161164b565b6033546001600160a01b03908116911614610f5e5760405162461bcd60e51b81526004016102e490612445565b609955565b6098546001600160a01b031681565b610f7a61164b565b6033546001600160a01b03908116911614610fa75760405162461bcd60e51b81526004016102e490612445565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b610ff9611dbe565b611001611dbe565b61100961164b565b6098546001600160a01b039081169116146110365760405162461bcd60e51b81526004016102e490612345565b61103e611dbe565b8451611049906116ef565b90506110548161164f565b1561121a57600080611069876000015161164f565b12905060008161107a57600061107d565b60015b9050600186600281111561108d57fe5b1415611118576040516337d2176f60e11b81526001600160a01b03891690636fa42ede906110c190849087906004016121c2565b60206040518083038186803b1580156110d957600080fd5b505afa1580156110ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111119190612170565b94506111e3565b600086600281111561112657fe5b141561115a5760405163da0c592760e01b81526001600160a01b0389169063da0c5927906110c190849087906004016121c2565b611162611dbe565b886001600160a01b031663468f02d26040518163ffffffff1660e01b815260040160206040518083038186803b15801561119b57600080fd5b505afa1580156111af573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d39190612170565b90506111df8482611846565b9550505b81611204576111ff87604001516111f98761179d565b90611863565b611215565b611215856111f9896040015161179d565b935050505b50935093915050565b61122b61164b565b6033546001600160a01b039081169116146112585760405162461bcd60e51b81526004016102e490612445565b609c80546001600160a01b0319166001600160a01b0392909216919091179055565b60995481565b611288611dd1565b61129061164b565b6098546001600160a01b039081169116146112bd5760405162461bcd60e51b81526004016102e490612345565b6112c5611dbe565b609854604051636891397b60e01b81526001600160a01b0390911690636891397b906112f59088906004016121a3565b60206040518083038186803b15801561130d57600080fd5b505afa158015611321573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113459190612170565b9050611354846000015161164f565b1561137c57835160608501516113769190611370908490611720565b906118c8565b60408301525b611384611dbe565b6098546040516316f3f13160e21b81526001600160a01b0390911690635bcfc4c4906113b49089906004016121a3565b60206040518083038186803b1580156113cc57600080fd5b505afa1580156113e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114049190612170565b9050611413856000015161164f565b156114435761143d856040015161143787608001518461176390919063ffffffff16565b90611846565b60608401525b61144b611dbe565b611478866020015161147286606001516111f988604001518a61172090919063ffffffff16565b90611653565b905060006114858261164f565b121561149e57611494816116ef565b60208501526114aa565b6114a7816116ef565b84525b5050509392505050565b6033546001600160a01b031690565b609a6020526000908152604090205481565b609b6020526000908152604090205481565b600054610100900460ff168061150057506115006118e5565b8061150e575060005460ff16155b61152a5760405162461bcd60e51b81526004016102e490612375565b600054610100900460ff16158015611555576000805460ff1961ff0019909116610100171660011790555b61155d6118eb565b609880546001600160a01b0319166001600160a01b0385161790556099829055801561158f576000805461ff00191690555b505050565b61159c61164b565b6033546001600160a01b039081169116146115c95760405162461bcd60e51b81526004016102e490612445565b6001600160a01b0381166115ef5760405162461bcd60e51b81526004016102e490612287565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b5190565b61165b611dbe565b8180600001516001600160ff1b03101560405180606001604052806033815260200161263860339139906116a25760405162461bcd60e51b81526004016102e49190612210565b506116ab611dbe565b835185516116b89161197e565b8152949350505050565b6116ca611dbe565b5060408051602081019091526000815290565b60006116e8826116ef565b5192915050565b6116f7611dbe565b6116ff611dbe565b825160001315611715578251600003815261171a565b825181525b92915050565b611728611dbe565b611730611dbe565b8251845161173d916119c4565b81529392505050565b61174e611dbe565b611756611dbe565b8251845161173d9161197e565b61176b611dbe565b611773611dbe565b8251845161173d91611a0a565b611788611dbe565b611790611dbe565b8251845161173d91611821565b6117a5611dbe565b8180600001516001600160ff1b03101560405180606001604052806033815260200161263860339139906117ec5760405162461bcd60e51b81526004016102e49190612210565b50506040805160208101909152915182525090565b611809611dbe565b611811611dbe565b835161173d9084611a4c565b4290565b600082820183811015610a695760405162461bcd60e51b81526004016102e4906122cd565b61184e611dbe565b611856611dbe565b8251845161173d91611ab7565b61186b611dbe565b8180600001516001600160ff1b03101560405180606001604052806033815260200161263860339139906118b25760405162461bcd60e51b81526004016102e49190612210565b506118bb611dbe565b835185516116b8916119c4565b6118d0611dbe565b6118d8611dbe565b8251845161173d91611ac5565b303b1590565b600054610100900460ff168061190457506119046118e5565b80611912575060005460ff16155b61192e5760405162461bcd60e51b81526004016102e490612375565b600054610100900460ff16158015611959576000805460ff1961ff0019909116610100171660011790555b611961611ad3565b611969611b54565b801561197b576000805461ff00191690555b50565b60008282018183128015906119935750838112155b806119a857506000831280156119a857508381125b610a695760405162461bcd60e51b81526004016102e490612304565b60008183038183128015906119d95750838113155b806119ee57506000831280156119ee57508381135b610a695760405162461bcd60e51b81526004016102e4906124c1565b6000610a6983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611c2e565b600082611a5b5750600061171a565b82600019148015611a6f5750600160ff1b82145b15611a8c5760405162461bcd60e51b81526004016102e49061247a565b82820282848281611a9957fe5b0514610a695760405162461bcd60e51b81526004016102e49061247a565b6000610a6983836012611c5a565b6000610a6983836012611c80565b600054610100900460ff1680611aec5750611aec6118e5565b80611afa575060005460ff16155b611b165760405162461bcd60e51b81526004016102e490612375565b600054610100900460ff16158015611969576000805460ff1961ff001990911661010017166001179055801561197b576000805461ff001916905550565b600054610100900460ff1680611b6d5750611b6d6118e5565b80611b7b575060005460ff16155b611b975760405162461bcd60e51b81526004016102e490612375565b600054610100900460ff16158015611bc2576000805460ff1961ff0019909116610100171660011790555b6000611bcc61164b565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350801561197b576000805461ff001916905550565b60008184841115611c525760405162461bcd60e51b81526004016102e49190612210565b505050900390565b6000611c78611c6883611c9e565b611c728686611ca7565b90611ce1565b949350505050565b6000611c78611c8e83611c9e565b611c988686611a4c565b90611d23565b60ff16600a0a90565b600082611cb65750600061171a565b82820282848281611cc357fe5b0414610a695760405162461bcd60e51b81526004016102e490612404565b6000610a6983836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611d87565b600081611d425760405162461bcd60e51b81526004016102e490612505565b81600019148015611d565750600160ff1b83145b15611d735760405162461bcd60e51b81526004016102e4906123c3565b6000828481611d7e57fe5b05949350505050565b60008183611da85760405162461bcd60e51b81526004016102e49190612210565b506000838581611db457fe5b0495945050505050565b6040518060200160405280600081525090565b6040518060800160405280611de4611dbe565b8152602001611df1611dbe565b8152602001611dfe611dbe565b8152602001611e0b611dbe565b905290565b6040518060e00160405280611e23611dbe565b8152602001611e30611dbe565b8152602001611e3d611dbe565b8152602001611e4a611dbe565b8152602001611e57611dbe565b815260200160008152602001600081525090565b600060e08284031215611e7c578081fd5b611e8660e06125fb565b9050611e928383611ef6565b8152611ea18360208401611ef6565b6020820152611eb38360408401611ef6565b6040820152611ec58360608401611ef6565b6060820152611ed78360808401611ef6565b608082015260a082013560a082015260c082013560c082015292915050565b600060208284031215611f07578081fd5b611f1160206125fb565b9135825250919050565b600060208284031215611f2c578081fd5b611f3660206125fb565b9151825250919050565b600060208284031215611f51578081fd5b8135610a6981612622565b60008060408385031215611f6e578081fd5b8235611f7981612622565b91506020830135611f8981612622565b809150509250929050565b600080600060608486031215611fa8578081fd5b8335611fb381612622565b92506020840135611fc381612622565b9150604084013560028110611fd6578182fd5b809150509250925092565b60008060408385031215611ff3578182fd5b8235611ffe81612622565b946020939093013593505050565b60008060006101208486031215612021578283fd5b833561202c81612622565b925061203b8560208601611e6b565b915061010084013560038110611fd6578182fd5b60008060006101208486031215612064578283fd5b833561206f81612622565b925061207e8560208601611e6b565b915061208e856101008601611ef6565b90509250925092565b600080600061012084860312156120ac578283fd5b83356120b781612622565b92506120c68560208601611e6b565b915061010084013590509250925092565b600080604083850312156120e9578182fd5b82356120f481612622565b91506121038460208501611ef6565b90509250929050565b60006080828403121561211d578081fd5b61212760806125fb565b6121318484611f1b565b81526121408460208501611f1b565b60208201526121528460408501611f1b565b60408201526121648460608501611f1b565b60608201529392505050565b600060208284031215612181578081fd5b610a698383611f1b565b60006020828403121561219c578081fd5b5035919050565b6001600160a01b0391909116815260200190565b901515815260200190565b60408101600284106121d057fe5b928152905160209091015290565b60808101600286106121ec57fe5b94815292516020840152905160408301525160609091015290565b90815260200190565b6000602080835283518082850152825b8181101561223c57858101830151858201604001528201612220565b8181111561224d5783604083870101525b50601f01601f1916929092016040019392505050565b6020808252600a90820152691bdd995c881b1a5b5a5d60b21b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f6040820152607760f81b606082015260800190565b602080825260169082015275063616c6c6572206973206e6f742053616b65506572760541b604082015260600190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f5369676e6564536166654d6174683a206469766973696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526027908201527f5369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f604082015266766572666c6f7760c81b606082015260800190565b60208082526024908201527f5369676e6564536166654d6174683a207375627472616374696f6e206f766572604082015263666c6f7760e01b606082015260800190565b6020808252818101527f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f604082015260600190565b600060e0820190508251518252602083015151602083015260408301515160408301526060830151516060830152608083015151608083015260a083015160a083015260c083015160c083015292915050565b815151815260208083015151908201526040808301515190820152606091820151519181019190915260800190565b9151825251602082015260400190565b9051815260200190565b925183529051602083015251604082015260600190565b918252602082015260400190565b60405181810167ffffffffffffffff8111828210171561261a57600080fd5b604052919050565b6001600160a01b038116811461197b57600080fdfe4d69786564446563696d616c3a2075696e742076616c756520697320626967676572207468616e205f494e543235365f4d4158a2646970667358221220bb7d17da0aeea6a2c9a871cc580fc93867dd215bcd90aa17991210179df7873864736f6c634300060c0033

Deployed ByteCode Sourcemap

54420:15919:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57995:1091;;;;;;:::i;:::-;;:::i;:::-;;57758:98;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63601:4900;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;56278:875::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;54703:72::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;61230:2363::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;57319:132::-;;;;;;:::i;:::-;;:::i;54782:23::-;;;:::i;11321:148::-;;;:::i;59489:1733::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;57650:100::-;;;;;;:::i;:::-;;:::i;54812:32::-;;;:::i;:::-;;;;;;;:::i;68509:1827::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;10679:79::-;;;:::i;55043:66::-;;;;;;:::i;:::-;;:::i;55116:79::-;;;;;;:::i;:::-;;:::i;55973:203::-;;;;;;:::i;:::-;;:::i;11624:244::-;;;;;;:::i;:::-;;:::i;57995:1091::-;55906:12;:10;:12::i;:::-;55894:8;;-1:-1:-1;;;;;55894:8:0;;;:24;;;55886:59;;;;-1:-1:-1;;;55886:59:0;;;;;;;:::i;:::-;;;;;;;;;58206:11:::1;58220:47;:9;-1:-1:-1::0;;;;;58220:36:0::1;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:45;:47::i;:::-;58206:61:::0;-1:-1:-1;58304:9:0;58329:7;;58325:754:::1;;58353:62;;:::i;:::-;-1:-1:-1::0;;;;;58448:32:0;::::1;;::::0;;;:23:::1;:32;::::0;;;;;;;;58435:46;;;;::::1;::::0;;;;;;;::::1;::::0;:7;;:12:::1;:46::i;:::-;58353:128;;58661:1;58623:35;:27;:33;:35::i;:::-;:39;58619:130;;;58713:20;:18;:20::i;:::-;58683:50;;58619:130;58785:1;58767:15;:7;:13;:15::i;:::-;:19;58763:222;;;58924:3;58884:36;:27;:34;:36::i;:::-;:43;;:70;;;-1:-1:-1::0;58945:9:0::1;::::0;-1:-1:-1;;;;;58945:9:0::1;58931:10;:23;58884:70;58876:93;;;;-1:-1:-1::0;;;58876:93:0::1;;;;;;;:::i;:::-;59034:33;:27;:31;:33::i;:::-;-1:-1:-1::0;;;;;58999:32:0;::::1;;::::0;;;:23:::1;:32;::::0;;;;:68;;;;-1:-1:-1;58325:754:0::1;55956:1;;57995:1091:::0;;:::o;57758:98::-;57839:9;;-1:-1:-1;;;;;57839:9:0;57758:98;:::o;63601:4900::-;63822:34;;:::i;:::-;55906:12;:10;:12::i;:::-;55894:8;;-1:-1:-1;;;;;55894:8:0;;;:24;;;55886:59;;;;-1:-1:-1;;;55886:59:0;;;;;;;:::i;:::-;63869:56:::1;;:::i;:::-;63941:61;::::0;-1:-1:-1;;;63941:61:0;;-1:-1:-1;;;;;63941:38:0;::::1;::::0;::::1;::::0;:61:::1;::::0;63980:21;;63941:61:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63869:133;;64013:48;;:::i;:::-;-1:-1:-1::0;64089:31:0::1;::::0;::::1;::::0;64064:57:::1;::::0;;;:24:::1;:57;::::0;;;;;;;64013:108;;;;::::1;::::0;;;;;;64155:14;;64013:108;;64064:57;;;64155:22:::1;::::0;:20:::1;:22::i;:::-;:26;:41;;64191:5;64155:41;;;64184:4;64155:41;64132:64;;64207:34;;:::i;:::-;64269:54;;:::i;:::-;64382:31;::::0;::::1;::::0;64343:71:::1;::::0;-1:-1:-1;;;64343:71:0;;-1:-1:-1;;;;;64343:38:0;::::1;::::0;::::1;::::0;:71:::1;::::0;64382:31;64343:71:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64269:145;;64429:45;;:::i;:::-;64533:31:::0;;64494:33;;:91:::1;::::0;64571:13;;64494:71:::1;::::0;:38:::1;:71::i;:::-;:76:::0;::::1;:91::i;:::-;64429:156;;64705:44;;:::i;:::-;64764:45;;:::i;:::-;64828:18;:10;:16;:18::i;:::-;:23:::0;64824:1008:::1;;64872:37;;:::i;:::-;64933:9;-1:-1:-1::0;;;;;64933:35:0::1;;65016:1;64995:18;:10;:16;:18::i;:::-;:22;:91;;65052:34;64995:91;;;65020:29;64995:91;65113:16;:10;:14;:16::i;:::-;65156:12;:30;;;65213:12;:29;;;64933:332;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64872:393;;65309:53;:47;65325:12;:30;;;65309:10;:15;;:47;;;;:::i;:::-;:51;:53::i;:::-;65284:78;;65406:1;65385:18;:10;:16;:18::i;:::-;:22;65381:268;;;65456:29;::::0;::::1;::::0;:50:::1;::::0;65491:14;65456:34:::1;:50::i;:::-;65432:74;;65381:268;;;65579:29;::::0;::::1;::::0;:50:::1;::::0;65614:14;65579:34:::1;:50::i;:::-;65555:74;;65381:268;64824:1008;;;;-1:-1:-1::0;;65714:30:0::1;::::0;::::1;::::0;65787:29:::1;::::0;::::1;::::0;;64824:1008:::1;65993:9;-1:-1:-1::0;;;;;65993:36:0::1;;66048:15;:84;;66098:34;66048:84;;;66066:29;66048:84;66151:14:::0;;:20:::1;::::0;:18:::1;:20::i;:::-;66190:22;66231:21;65993:274;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65979:288;;66284:47;;:::i;:::-;66334:37;66359:11;66334:24;:37::i;:::-;66284:87;;66390:15;66386:97;;;66441:26;:12:::0;-1:-1:-1;;66441:22:0::1;:26::i;:::-;66426:41;;66386:97;66600:31;::::0;::::1;::::0;66557:89:::1;::::0;;;:24:::1;:89;::::0;;;;;;;;:112;;;;::::1;::::0;;;;;;;:126:::1;::::0;66670:12;66557:112:::1;:126::i;:::-;66522:31;::::0;::::1;::::0;66497:57:::1;::::0;;;:24:::1;:57;::::0;;;;:186;;;;-1:-1:-1;66722:44:0::1;::::0;-1:-1:-1;66722:44:0::1;::::0;-1:-1:-1;;;66722:44:0:i:1;:::-;66781:45;;:::i;:::-;66845:21;:13;:19;:21::i;:::-;:26:::0;66841:1037:::1;;66892:37;;:::i;:::-;66953:9;-1:-1:-1::0;;;;;66953:35:0::1;;67039:1;67015:21;:13;:19;:21::i;:::-;:25;:94;;67075:34;67015:94;;;67043:29;67015:94;67136:19;:13;:17;:19::i;:::-;67182:14;:32;;;67241:14;:31;;;66953:342;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;66892:403;;67339:58;:52;67358:14;:32;;;67339:13;:18;;:52;;;;:::i;:58::-;67314:83;;67444:1;67420:21;:13;:19;:21::i;:::-;:25;67416:275;;;67494:31;::::0;::::1;::::0;:52:::1;::::0;67531:14;67494:36:::1;:52::i;:::-;67470:76;;67416:275;;;67619:31;::::0;::::1;::::0;:52:::1;::::0;67656:14;67619:36:::1;:52::i;:::-;67595:76;;67416:275;66841:1037;;;;-1:-1:-1::0;;67756:32:0::1;::::0;::::1;::::0;67831:31:::1;::::0;::::1;::::0;;66841:1037:::1;67965:47;;:::i;:::-;68032:370;68079:9;-1:-1:-1::0;;;;;68079:35:0::1;;68141:15;:84;;68196:29;68141:84;;;68159:34;68141:84;68252:11;68290:22;68339:21;68079:304;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68032:24;:370::i;:::-;67965:437;;68426:56;68449:15;:32;;-1:-1:-1::0;;68449:32:0::1;;;68467:1;68449:32;68426:12:::0;;:22:::1;:56::i;:::-;68419:63;;;;;;;;;55956:1;63601:4900:::0;;;;;:::o;56278:875::-;56441:4;55906:12;:10;:12::i;:::-;55894:8;;-1:-1:-1;;;;;55894:8:0;;;:24;;;55886:59;;;;-1:-1:-1;;;55886:59:0;;;;;;;:::i;:::-;56471:23:::1;56462:5;:32;;;;;;;;;56458:666;;;-1:-1:-1::0;;;;;56538:23:0;;::::1;56511:24;56538:23:::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:49:::1;;::::0;56648:17:::1;:15;:17::i;:::-;56627;::::0;56606:39:::1;::::0;:16;;:20:::1;:39::i;:::-;:59;56602:112;;;56693:5;56686:12;;;;;56602:112;56779:17;:15;:17::i;:::-;-1:-1:-1::0;;;;;56728:23:0;;::::1;;::::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:68;-1:-1:-1;56458:666:0::1;;;-1:-1:-1::0;;;;;56855:23:0;;::::1;56829;56855::::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:48;56963:17:::1;:15;:17::i;:::-;56942;::::0;56922:38:::1;::::0;:15;;:19:::1;:38::i;:::-;:58;56918:111;;;57008:5;57001:12;;;;;56918:111;57095:17;:15;:17::i;:::-;-1:-1:-1::0;;;;;57043:23:0;;::::1;;::::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:49:::1;;:69:::0;-1:-1:-1;56458:666:0::1;-1:-1:-1::0;57141:4:0::1;56278:875:::0;;;;;:::o;54703:72::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61230:2363::-;61446:30;;:::i;:::-;55906:12;:10;:12::i;:::-;55894:8;;-1:-1:-1;;;;;55894:8:0;;;:24;;;55886:59;;;;-1:-1:-1;;;55886:59:0;;;;;;;:::i;:::-;61493:14;;:22:::1;::::0;:20:::1;:22::i;:::-;61489:146;;-1:-1:-1::0;61537:31:0::1;::::0;::::1;:55:::0;;;:9;61607:16:::1;;61489:146;61796:54;;:::i;:::-;61905:31;::::0;::::1;::::0;61866:71:::1;::::0;-1:-1:-1;;;61866:71:0;;-1:-1:-1;;;;;61866:38:0;::::1;::::0;::::1;::::0;:71:::1;::::0;61905:31;61866:71:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61796:141;;61948:48;;:::i;:::-;62012:71;62051:12;:31;;;62012:9;-1:-1:-1::0;;;;;62012:31:0::1;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38:::0;::::1;:71::i;:::-;61948:135;;62194:44;;:::i;:::-;62249:45;;:::i;:::-;62309:21;:13;:19;:21::i;:::-;:26:::0;62305:955:::1;;62352:37;;:::i;:::-;62409:9;-1:-1:-1::0;;;;;62409:35:0::1;;62491:1;62467:21;:13;:19;:21::i;:::-;:25;:94;;62527:34;62467:94;;;62495:29;62467:94;62584:19;:13;:17;:19::i;:::-;62626:12;:30;;;62679:12;:29;;;62409:318;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62352:375;;62767:56;:50;62786:12;:30;;;62767:13;:18;;:50;;;;:::i;:56::-;62742:81;;62866:1;62842:21;:13;:19;:21::i;:::-;:25;62838:255;;;62912:29;::::0;::::1;::::0;:50:::1;::::0;62947:14;62912:34:::1;:50::i;:::-;62888:74;;62838:255;;;63027:29;::::0;::::1;::::0;:50:::1;::::0;63062:14;63027:34:::1;:50::i;:::-;63003:74;;62838:255;62305:955;;;;-1:-1:-1::0;;63150:30:0::1;::::0;::::1;::::0;63219:29:::1;::::0;::::1;::::0;;62305:955:::1;63394:14:::0;;63333:159:::1;::::0;-1:-1:-1;;;63333:159:0;;-1:-1:-1;;;;;63333:46:0;::::1;::::0;::::1;::::0;:159:::1;::::0;63394:14;63423:22;;63460:21;;63333:159:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63316:176:::0;;-1:-1:-1;;;;63503:31:0::1;::::0;::::1;:55:::0;;;;-1:-1:-1;63316:176:0;61230:2363;-1:-1:-1;61230:2363:0:o;57319:132::-;10901:12;:10;:12::i;:::-;10891:6;;-1:-1:-1;;;;;10891:6:0;;;:22;;;10883:67;;;;-1:-1:-1;;;10883:67:0;;;;;;;:::i;:::-;57405:17:::1;:38:::0;57319:132::o;54782:23::-;;;-1:-1:-1;;;;;54782:23:0;;:::o;11321:148::-;10901:12;:10;:12::i;:::-;10891:6;;-1:-1:-1;;;;;10891:6:0;;;:22;;;10883:67;;;;-1:-1:-1;;;10883:67:0;;;;;;;:::i;:::-;11412:6:::1;::::0;11391:40:::1;::::0;11428:1:::1;::::0;-1:-1:-1;;;;;11412:6:0::1;::::0;11391:40:::1;::::0;11428:1;;11391:40:::1;11442:6;:19:::0;;-1:-1:-1;;;;;;11442:19:0::1;::::0;;11321:148::o;59489:1733::-;59764:39;;:::i;:::-;59805:48;;:::i;:::-;55906:12;:10;:12::i;:::-;55894:8;;-1:-1:-1;;;;;55894:8:0;;;:24;;;55886:59;;;;-1:-1:-1;;;55886:59:0;;;;;;;:::i;:::-;59871:38:::1;;:::i;:::-;59912:14:::0;;:20:::1;::::0;:18:::1;:20::i;:::-;59871:61;;59947:24;:15;:22;:24::i;:::-;:29:::0;59943:1272:::1;;59993:20;60041:1:::0;60016:22:::1;:9;:14;;;:20;:22::i;:::-;:26;59993:49;;60057:22;60099:15;:84;;60154:29;60099:84;;;60117:34;60099:84;60057:126:::0;-1:-1:-1;60220:33:0::1;60202:14;:51;;;;;;;;;60198:505;;;60293:45;::::0;-1:-1:-1;;;60293:45:0;;-1:-1:-1;;;;;60293:23:0;::::1;::::0;::::1;::::0;:45:::1;::::0;60317:3;;60322:15;;60293:45:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60274:64;;60198:505;;;60383:39;60365:14;:57;;;;;;;;;60361:342;;;60462:46;::::0;-1:-1:-1;;;60462:46:0;;-1:-1:-1;;;;;60462:24:0;::::1;::::0;::::1;::::0;:46:::1;::::0;60487:3;;60492:15;;60462:46:::1;;;:::i;60361:342::-;60549:34;;:::i;:::-;60586:9;-1:-1:-1::0;;;;;60586:28:0::1;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60549:67:::0;-1:-1:-1;60654:33:0::1;:15:::0;60549:67;60654:20:::1;:33::i;:::-;60635:52;;60361:342;;61006:15;:197;;61132:71;61180:9;:22;;;61132:42;61157:16;61132:24;:42::i;:::-;:47:::0;::::1;:71::i;:::-;61006:197;;;61041:71;61095:16;61041:48;61066:9;:22;;;61041:24;:48::i;:71::-;60990:213;;59943:1272;;;55956:1;59489:1733:::0;;;;;;:::o;57650:100::-;10901:12;:10;:12::i;:::-;10891:6;;-1:-1:-1;;;;;10891:6:0;;;:22;;;10883:67;;;;-1:-1:-1;;;10883:67:0;;;;;;;:::i;:::-;57720:9:::1;:22:::0;;-1:-1:-1;;;;;;57720:22:0::1;-1:-1:-1::0;;;;;57720:22:0;;;::::1;::::0;;;::::1;::::0;;57650:100::o;54812:32::-;;;;:::o;68509:1827::-;68760:40;;:::i;:::-;55906:12;:10;:12::i;:::-;55894:8;;-1:-1:-1;;;;;55894:8:0;;;:24;;;55886:59;;;;-1:-1:-1;;;55886:59:0;;;;;;;:::i;:::-;68851:66:::1;;:::i;:::-;68943:8;::::0;68933:65:::1;::::0;-1:-1:-1;;;68933:65:0;;-1:-1:-1;;;;;68943:8:0;;::::1;::::0;68933:54:::1;::::0;:65:::1;::::0;68988:9;;68933:65:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68851:147;;69013:25;:12;:17;;;:23;:25::i;:::-;:30:::0;69009:244:::1;;69223:17:::0;;69149:49:::1;::::0;::::1;::::0;69094:147:::1;::::0;69223:17;69094:105:::1;::::0;:31;;:54:::1;:105::i;:::-;:128:::0;::::1;:147::i;:::-;69060:31;::::0;::::1;:181:::0;69009:244:::1;69367:55;;:::i;:::-;69448:8;::::0;69438:66:::1;::::0;-1:-1:-1;;;69438:66:0;;-1:-1:-1;;;;;69448:8:0;;::::1;::::0;69438:55:::1;::::0;:66:::1;::::0;69494:9;;69438:66:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;69367:137;;69519:25;:12;:17;;;:23;:25::i;:::-;:30:::0;69515:252:::1;;69598:157;69729:12;:25;;;69598:107;69654:12;:50;;;69598:32;:55;;:107;;;;:::i;:::-;:130:::0;::::1;:157::i;:::-;69566:29;::::0;::::1;:189:::0;69515:252:::1;69815:53;;:::i;:::-;69884:144;69994:12;:19;;;69884:86;69940:16;:29;;;69884:50;69902:16;:31;;;69884:12;:17;;:50;;;;:::i;:86::-;:91:::0;::::1;:144::i;:::-;69815:213;;70159:1;70130:26;:18;:24;:26::i;:::-;:30;70126:203;;;70204:24;:18;:22;:24::i;:::-;70177;::::0;::::1;:51:::0;70126:203:::1;;;70293:24;:18;:22;:24::i;:::-;70261:56:::0;;70126:203:::1;55956:1;;;68509:1827:::0;;;;;:::o;10679:79::-;10744:6;;-1:-1:-1;;;;;10744:6:0;10679:79;:::o;55043:66::-;;;;;;;;;;;;;:::o;55116:79::-;;;;;;;;;;;;;:::o;55973:203::-;7016:13;;;;;;;;:33;;;7033:16;:14;:16::i;:::-;7016:50;;;-1:-1:-1;7054:12:0;;;;7053:13;7016:50;7008:109;;;;-1:-1:-1;;;7008:109:0;;;;;;;:::i;:::-;7130:19;7153:13;;;;;;7152:14;7177:101;;;;7212:13;:20;;-1:-1:-1;;;;7212:20:0;;;;;7247:19;7228:4;7247:19;;;7177:101;56070:16:::1;:14;:16::i;:::-;56099:8;:20:::0;;-1:-1:-1;;;;;;56099:20:0::1;-1:-1:-1::0;;;;;56099:20:0;::::1;;::::0;;56130:17:::1;:38:::0;;;7304:68;;;;7355:5;7339:21;;-1:-1:-1;;7339:21:0;;;7304:68;55973:203;;;:::o;11624:244::-;10901:12;:10;:12::i;:::-;10891:6;;-1:-1:-1;;;;;10891:6:0;;;:22;;;10883:67;;;;-1:-1:-1;;;10883:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11713:22:0;::::1;11705:73;;;;-1:-1:-1::0;;;11705:73:0::1;;;;;;;:::i;:::-;11815:6;::::0;11794:38:::1;::::0;-1:-1:-1;;;;;11794:38:0;;::::1;::::0;11815:6:::1;::::0;11794:38:::1;::::0;11815:6:::1;::::0;11794:38:::1;11843:6;:17:::0;;-1:-1:-1;;;;;;11843:17:0::1;-1:-1:-1::0;;;;;11843:17:0;;;::::1;::::0;;;::::1;::::0;;11624:244::o;8952:106::-;9040:10;8952:106;:::o;14154:95::-;14238:3;;14154:95::o;52053:304::-;52205:34;;:::i;:::-;52184:1;51536;:3;;;-1:-1:-1;;;;;51521:18:0;;51541:21;;;;;;;;;;;;;;;;;51513:50;;;;;-1:-1:-1;;;51513:50:0;;;;;;;;:::i;:::-;;52257:36:::1;;:::i;:::-;52325:3:::0;;52310;;:20:::1;::::0;:7:::1;:20::i;:::-;52304:26:::0;;;52053:304;-1:-1:-1;;;;52053:304:0:o;20811:103::-;20850:20;;:::i;:::-;-1:-1:-1;20890:16:0;;;;;;;;;-1:-1:-1;20890:16:0;;20811:103;:::o;51827:121::-;51904:7;51931;:1;:5;:7::i;:::-;:9;;51827:121;-1:-1:-1;;51827:121:0:o;21202:269::-;21262:22;;:::i;:::-;21297:24;;:::i;:::-;21336:3;;21342:1;-1:-1:-1;21332:113:0;;;21378:3;;;21374:7;21360:22;;21332:113;;;21429:3;;21415:18;;21332:113;21462:1;21202:269;-1:-1:-1;;21202:269:0:o;21750:196::-;21835:20;;:::i;:::-;21868:22;;:::i;:::-;21915:3;;21907;;:12;;:7;:12::i;:::-;21901:18;;;21750:196;-1:-1:-1;;;21750:196:0:o;21510:::-;21595:20;;:::i;:::-;21628:22;;:::i;:::-;21675:3;;21667;;:12;;:7;:12::i;14901:172::-;14974:14;;:::i;:::-;15001:16;;:::i;:::-;15042:3;;15034;;:12;;:7;:12::i;14685:172::-;14758:14;;:::i;:::-;14785:16;;:::i;:::-;14826:3;;14818;;:12;;:7;:12::i;51591:228::-;51712:34;;:::i;:::-;51691:1;51536;:3;;;-1:-1:-1;;;;;51521:18:0;;51541:21;;;;;;;;;;;;;;;;;51513:50;;;;;-1:-1:-1;;;51513:50:0;;;;;;;;:::i;:::-;-1:-1:-1;;51771:40:0::1;::::0;;::::1;::::0;::::1;::::0;;;51806:3;;51771:40;;-1:-1:-1;51771:40:0;51591:228::o;22246:185::-;22322:20;;:::i;:::-;22355:22;;:::i;:::-;22394:3;;:10;;22402:1;22394:7;:10::i;50734:108::-;50819:15;50734:108;:::o;998:181::-;1056:7;1088:5;;;1112:6;;;;1104:46;;;;-1:-1:-1;;;1104:46:0;;;;;;;:::i;15117:173::-;15190:14;;:::i;:::-;15217:16;;:::i;:::-;15259:3;;15250;;:13;;:8;:13::i;52466:304::-;52618:34;;:::i;:::-;52597:1;51536;:3;;;-1:-1:-1;;;;;51521:18:0;;51541:21;;;;;;;;;;;;;;;;;51513:50;;;;;-1:-1:-1;;;51513:50:0;;;;;;;;:::i;:::-;;52670:36:::1;;:::i;:::-;52738:3:::0;;52723;;:20:::1;::::0;:7:::1;:20::i;21990:197::-:0;22075:20;;:::i;:::-;22108:22;;:::i;:::-;22156:3;;22147;;:13;;:8;:13::i;7472:604::-;7914:4;8025:17;8061:7;7472:604;:::o;10265:129::-;7016:13;;;;;;;;:33;;;7033:16;:14;:16::i;:::-;7016:50;;;-1:-1:-1;7054:12:0;;;;7053:13;7016:50;7008:109;;;;-1:-1:-1;;;7008:109:0;;;;;;;:::i;:::-;7130:19;7153:13;;;;;;7152:14;7177:101;;;;7212:13;:20;;-1:-1:-1;;;;7212:20:0;;;;;7247:19;7228:4;7247:19;;;7177:101;10323:26:::1;:24;:26::i;:::-;10360;:24;:26::i;:::-;7308:14:::0;7304:68;;;7355:5;7339:21;;-1:-1:-1;;7339:21:0;;;7304:68;10265:129;:::o;18554:215::-;18610:6;18640:5;;;18665:6;;;;;;:16;;;18680:1;18675;:6;;18665:16;18664:38;;;;18691:1;18687;:5;:14;;;;;18700:1;18696;:5;18687:14;18656:84;;;;-1:-1:-1;;;18656:84:0;;;;;;;:::i;18091:218::-;18147:6;18177:5;;;18202:6;;;;;;:16;;;18217:1;18212;:6;;18202:16;18201:38;;;;18228:1;18224;:5;:14;;;;;18237:1;18233;:5;18224:14;18193:87;;;;-1:-1:-1;;;18193:87:0;;;;;;;:::i;1462:136::-;1520:7;1547:43;1551:1;1554;1547:43;;;;;;;;;;;;;;;;;:3;:43::i;16527:568::-;16583:6;16827;16823:47;;-1:-1:-1;16857:1:0;16850:8;;16823:47;16892:1;-1:-1:-1;;16892:7:0;:27;;;;;-1:-1:-1;;;16903:1:0;:16;16892:27;16890:30;16882:82;;;;-1:-1:-1;;;16882:82:0;;;;;;;:::i;:::-;16988:5;;;16992:1;16988;:5;:1;17012:5;;;;;:10;17004:62;;;;-1:-1:-1;;;17004:62:0;;;;;;;:::i;12844:108::-;12903:7;12930:14;12935:1;12938;12941:2;12930:4;:14::i;19702:105::-;19759:6;19785:14;19790:1;19793;19796:2;19785:4;:14::i;8881:65::-;7016:13;;;;;;;;:33;;;7033:16;:14;:16::i;:::-;7016:50;;;-1:-1:-1;7054:12:0;;;;7053:13;7016:50;7008:109;;;;-1:-1:-1;;;7008:109:0;;;;;;;:::i;:::-;7130:19;7153:13;;;;;;7152:14;7177:101;;;;7212:13;:20;;-1:-1:-1;;;;7212:20:0;;;;;7247:19;7228:4;7247:19;;;7308:14;7304:68;;;7355:5;7339:21;;-1:-1:-1;;7339:21:0;;;8881:65;:::o;10402:196::-;7016:13;;;;;;;;:33;;;7033:16;:14;:16::i;:::-;7016:50;;;-1:-1:-1;7054:12:0;;;;7053:13;7016:50;7008:109;;;;-1:-1:-1;;;7008:109:0;;;;;;;:::i;:::-;7130:19;7153:13;;;;;;7152:14;7177:101;;;;7212:13;:20;;-1:-1:-1;;;;7212:20:0;;;;;7247:19;7228:4;7247:19;;;7177:101;10470:17:::1;10490:12;:10;:12::i;:::-;10513:6;:18:::0;;-1:-1:-1;;;;;;10513:18:0::1;-1:-1:-1::0;;;;;10513:18:0;::::1;::::0;;::::1;::::0;;;10547:43:::1;::::0;10513:18;;-1:-1:-1;10513:18:0;-1:-1:-1;;10547:43:0::1;::::0;-1:-1:-1;;10547:43:0::1;7290:1;7308:14:::0;7304:68;;;7355:5;7339:21;;-1:-1:-1;;7339:21:0;;;10402:196;:::o;1901:192::-;1987:7;2023:12;2015:6;;;;2007:29;;;;-1:-1:-1;;;2007:29:0;;;;;;;;:::i;:::-;-1:-1:-1;;;2059:5:0;;;1901:192::o;13053:172::-;13162:7;13189:28;13202:14;13207:8;13202:4;:14::i;:::-;13189:8;:1;13195;13189:5;:8::i;:::-;:12;;:28::i;:::-;13182:35;13053:172;-1:-1:-1;;;;13053:172:0:o;19908:169::-;20015:6;20041:28;20054:14;20059:8;20054:4;:14::i;:::-;20041:8;:1;20047;20041:5;:8::i;:::-;:12;;:28::i;12254:109::-;12338:17;;12334:2;:21;;12254:109::o;2352:471::-;2410:7;2655:6;2651:47;;-1:-1:-1;2685:1:0;2678:8;;2651:47;2722:5;;;2726:1;2722;:5;:1;2746:5;;;;;:10;2738:56;;;;-1:-1:-1;;;2738:56:0;;;;;;;:::i;3299:132::-;3357:7;3384:39;3388:1;3391;3384:39;;;;;;;;;;;;;;;;;:3;:39::i;17569:271::-;17625:6;17652;17644:51;;;;-1:-1:-1;;;17644:51:0;;;;;;;:::i;:::-;17716:1;-1:-1:-1;;17716:7:0;:27;;;;;-1:-1:-1;;;17727:1:0;:16;17716:27;17714:30;17706:76;;;;-1:-1:-1;;;17706:76:0;;;;;;;:::i;:::-;17795:8;17810:1;17806;:5;;;;;;;17569:271;-1:-1:-1;;;;17569:271:0:o;3927:278::-;4013:7;4048:12;4041:5;4033:28;;;;-1:-1:-1;;;4033:28:0;;;;;;;;:::i;:::-;;4072:9;4088:1;4084;:5;;;;;;;3927:278;-1:-1:-1;;;;;3927:278:0:o;-1:-1:-1:-;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::o;2003:1424::-;;2118:4;2106:9;2101:3;2097:19;2093:30;2090:2;;;-1:-1;;2126:12;2090:2;2154:20;2118:4;2154:20;:::i;:::-;2145:29;;2256:80;2332:3;2308:22;2256:80;:::i;:::-;2238:16;2231:106;2433:73;2502:3;2400:2;2482:9;2478:22;2433:73;:::i;:::-;2400:2;2419:5;2415:16;2408:99;2609:73;2678:3;2576:2;2658:9;2654:22;2609:73;:::i;:::-;2576:2;2595:5;2591:16;2584:99;2809:80;2885:3;2776:2;2865:9;2861:22;2809:80;:::i;:::-;2776:2;2795:5;2791:16;2784:106;3018:73;3087:3;2984;3067:9;3063:22;3018:73;:::i;:::-;2984:3;3004:5;3000:16;2993:99;3170:3;3229:9;3225:22;5001:20;3170:3;3190:5;3186:16;3179:75;3322:3;3381:9;3377:22;5001:20;3322:3;3342:5;3338:16;3331:75;2084:1343;;;;:::o;3463:319::-;;3576:4;3564:9;3559:3;3555:19;3551:30;3548:2;;;-1:-1;;3584:12;3548:2;3612:20;3576:4;3612:20;:::i;:::-;5001;;3686:75;;-1:-1;3603:29;3542:240;-1:-1;3542:240::o;3818:341::-;;3942:4;3930:9;3925:3;3921:19;3917:30;3914:2;;;-1:-1;;3950:12;3914:2;3978:20;3942:4;3978:20;:::i;:::-;5149:13;;4052:86;;-1:-1;3969:29;3908:251;-1:-1;3908:251::o;5212:241::-;;5316:2;5304:9;5295:7;5291:23;5287:32;5284:2;;;-1:-1;;5322:12;5284:2;85:6;72:20;97:33;124:5;97:33;:::i;5460:366::-;;;5581:2;5569:9;5560:7;5556:23;5552:32;5549:2;;;-1:-1;;5587:12;5549:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;5639:63;-1:-1;5739:2;5778:22;;72:20;97:33;72:20;97:33;:::i;:::-;5747:63;;;;5543:283;;;;;:::o;5833:509::-;;;;5980:2;5968:9;5959:7;5955:23;5951:32;5948:2;;;-1:-1;;5986:12;5948:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6038:63;-1:-1;6138:2;6177:22;;72:20;97:33;72:20;97:33;:::i;:::-;6146:63;-1:-1;6246:2;6294:22;;564:20;33669:1;33659:12;;33649:2;;-1:-1;;33675:12;33649:2;6254:72;;;;5942:400;;;;;:::o;6349:366::-;;;6470:2;6458:9;6449:7;6445:23;6441:32;6438:2;;;-1:-1;;6476:12;6438:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6528:63;6628:2;6667:22;;;;5001:20;;-1:-1;;;6432:283::o;6722:617::-;;;;6922:3;6910:9;6901:7;6897:23;6893:33;6890:2;;;-1:-1;;6929:12;6890:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;6981:81;-1:-1;7117:79;7188:7;7099:2;7164:22;;7117:79;:::i;:::-;7107:89;;7233:3;7295:9;7291:22;400:20;33559:1;33552:5;33549:12;33539:2;;-1:-1;;33565:12;7346:643;;;;7559:3;7547:9;7538:7;7534:23;7530:33;7527:2;;;-1:-1;;7566:12;7527:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;7618:81;-1:-1;7754:79;7825:7;7736:2;7801:22;;7754:79;:::i;:::-;7744:89;;7889:84;7965:7;7870:3;7945:9;7941:22;7889:84;:::i;:::-;7879:94;;7521:468;;;;;:::o;7996:581::-;;;;8178:3;8166:9;8157:7;8153:23;8149:33;8146:2;;;-1:-1;;8185:12;8146:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;8237:81;-1:-1;8373:79;8444:7;8355:2;8420:22;;8373:79;:::i;:::-;8363:89;;8489:3;8533:9;8529:22;5001:20;8498:63;;8140:437;;;;;:::o;8584:464::-;;;8754:2;8742:9;8733:7;8729:23;8725:32;8722:2;;;-1:-1;;8760:12;8722:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;8812:81;-1:-1;8948:84;9024:7;8930:2;9000:22;;8948:84;:::i;:::-;8938:94;;8716:332;;;;;:::o;9055:348::-;;9212:3;9200:9;9191:7;9187:23;9183:33;9180:2;;;-1:-1;;9219:12;9180:2;1148:20;9212:3;1148:20;:::i;:::-;1264:91;1351:3;1327:22;1264:91;:::i;:::-;1246:16;1239:117;1463:84;1543:3;1430:2;1523:9;1519:22;1463:84;:::i;:::-;1430:2;1449:5;1445:16;1438:110;1654:84;1734:3;1621:2;1714:9;1710:22;1654:84;:::i;:::-;1621:2;1640:5;1636:16;1629:110;1846:91;1933:3;1813:2;1913:9;1909:22;1846:91;:::i;:::-;1813:2;1828:16;;1821:117;1832:5;9174:229;-1:-1;;;9174:229::o;9410:311::-;;9549:2;9537:9;9528:7;9524:23;9520:32;9517:2;;;-1:-1;;9555:12;9517:2;9617:88;9697:7;9673:22;9617:88;:::i;10060:241::-;;10164:2;10152:9;10143:7;10139:23;10135:32;10132:2;;;-1:-1;;10170:12;10132:2;-1:-1;5001:20;;10126:175;-1:-1;10126:175::o;20401:222::-;-1:-1;;;;;32129:54;;;;10379:37;;20528:2;20513:18;;20499:124::o;20630:210::-;31718:13;;31711:21;10493:34;;20751:2;20736:18;;20722:118::o;21112:441::-;21321:2;21306:18;;33159:1;33149:12;;33139:2;;33165:9;33139:2;10785:56;;;18852:23;;21539:2;21524:18;;;10912:36;21292:261;:::o;21560:856::-;21921:3;21906:19;;33159:1;33149:12;;33139:2;;33165:9;33139:2;10785:56;;;18852:23;;22140:2;22125:18;;10912:36;18852:23;;22271:2;22256:18;;10912:36;18852:23;22402:2;22387:18;;;10912:36;21892:524;:::o;22423:218::-;10912:36;;;22548:2;22533:18;;22519:122::o;22648:310::-;;22795:2;;22816:17;22809:47;11222:5;31341:12;31498:6;22795:2;22784:9;22780:18;31486:19;-1:-1;32773:101;32787:6;32784:1;32781:13;32773:101;;;32854:11;;;;;32848:18;32835:11;;;31526:14;32835:11;32828:39;32802:10;;32773:101;;;32889:6;32886:1;32883:13;32880:2;;;-1:-1;31526:14;32945:6;22784:9;32936:16;;32929:27;32880:2;-1:-1;33061:7;33045:14;-1:-1;;33041:28;11380:39;;;;31526:14;11380:39;;22766:192;-1:-1;;;22766:192::o;22965:416::-;23165:2;23179:47;;;11656:2;23150:18;;;31486:19;-1:-1;;;31526:14;;;11672:33;11724:12;;;23136:245::o;23388:416::-;23588:2;23602:47;;;11975:2;23573:18;;;31486:19;12011:34;31526:14;;;11991:55;-1:-1;;;12066:12;;;12059:30;12108:12;;;23559:245::o;23811:416::-;24011:2;24025:47;;;12359:2;23996:18;;;31486:19;12395:29;31526:14;;;12375:50;12444:12;;;23982:245::o;24234:416::-;24434:2;24448:47;;;12695:2;24419:18;;;31486:19;12731:34;31526:14;;;12711:55;-1:-1;;;12786:12;;;12779:25;12823:12;;;24405:245::o;24657:416::-;24857:2;24871:47;;;13074:2;24842:18;;;31486:19;-1:-1;;;31526:14;;;13090:45;13154:12;;;24828:245::o;25080:416::-;25280:2;25294:47;;;13405:2;25265:18;;;31486:19;13441:34;31526:14;;;13421:55;-1:-1;;;13496:12;;;13489:38;13546:12;;;25251:245::o;25503:416::-;25703:2;25717:47;;;13797:2;25688:18;;;31486:19;13833:34;31526:14;;;13813:55;-1:-1;;;13888:12;;;13881:25;13925:12;;;25674:245::o;25926:416::-;26126:2;26140:47;;;14176:2;26111:18;;;31486:19;14212:34;31526:14;;;14192:55;-1:-1;;;14267:12;;;14260:25;14304:12;;;26097:245::o;26349:416::-;26549:2;26563:47;;;26534:18;;;31486:19;14591:34;31526:14;;;14571:55;14645:12;;;26520:245::o;26772:416::-;26972:2;26986:47;;;14896:2;26957:18;;;31486:19;14932:34;31526:14;;;14912:55;-1:-1;;;14987:12;;;14980:31;15030:12;;;26943:245::o;27195:416::-;27395:2;27409:47;;;15281:2;27380:18;;;31486:19;15317:34;31526:14;;;15297:55;-1:-1;;;15372:12;;;15365:28;15412:12;;;27366:245::o;27618:416::-;27818:2;27832:47;;;27803:18;;;31486:19;15699:34;31526:14;;;15679:55;15753:12;;;27789:245::o;28041:327::-;;28220:3;28209:9;28205:19;28197:27;;16067:16;16061:23;18852;10919:3;10912:36;16296:4;16289:5;16285:16;16279:23;18852;16296:4;16408:3;16404:14;10912:36;16506:4;16499:5;16495:16;16489:23;18852;16506:4;16618:3;16614:14;10912:36;16740:4;16733:5;16729:16;16723:23;18852;16740:4;16866:3;16862:14;10912:36;16989:4;16982:5;16978:16;16972:23;18852;16989:4;17101:3;17097:14;10912:36;17208:4;17201:5;17197:16;17191:23;17208:4;17272:3;17268:14;10912:36;17369:4;17362:5;17358:16;17352:23;17369:4;17433:3;17429:14;10912:36;28191:177;;;;:::o;28375:359::-;17794:23;;18852;10912:36;;18016:4;18005:16;;;17999:23;18852;18124:14;;;10912:36;18228:4;18217:16;;;18211:23;18852;18350:14;;;10912:36;18452:4;18441:16;;;18435:23;18852;18560:14;;;10912:36;;;;28570:3;28555:19;;28541:193::o;28741:553::-;18852:23;;10912:36;;19638:23;29280:2;29265:18;;10912:36;29006:2;28991:18;;28977:317::o;29301:346::-;19638:23;;10912:36;;29490:2;29475:18;;29461:186::o;29654:760::-;19638:23;;10912:36;;18852:23;;30269:2;30254:18;;10912:36;18852:23;30400:2;30385:18;;10912:36;29995:2;29980:18;;29966:448::o;30650:333::-;10912:36;;;30969:2;30954:18;;10912:36;30805:2;30790:18;;30776:207::o;30990:256::-;31052:2;31046:9;31078:17;;;31153:18;31138:34;;31174:22;;;31135:62;31132:2;;;31210:1;;31200:12;31132:2;31052;31219:22;31030:216;;-1:-1;31030:216::o;33188:117::-;-1:-1;;;;;32129:54;;33247:35;;33237:2;;33296:1;;33286:12

Swarm Source

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