Contract 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a9 1

Contract Overview

Balance:
0 BNB
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x97ef772467a0f5b3712a0efea463445c7f05e642ab805405f46acaa5c3ebcf4f0x6080604067884572021-03-04 7:03:08202 days 19 hrs ago0x20000b9b01e93a39db9d286e9264eff7f2af16e9 IN  Contract Creation0 BNB0.03609434
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0xa3742f4a37ecdd1c23bdafd8f330727bebfd54888e7902a89c754928b777131784143332021-04-29 21:53:12146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xa3742f4a37ecdd1c23bdafd8f330727bebfd54888e7902a89c754928b777131784143332021-04-29 21:53:12146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xa3742f4a37ecdd1c23bdafd8f330727bebfd54888e7902a89c754928b777131784143332021-04-29 21:53:12146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xa3742f4a37ecdd1c23bdafd8f330727bebfd54888e7902a89c754928b777131784143332021-04-29 21:53:12146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x1c048764ef12b37154e69cf92380e92d942f2aefdc1105c4e15291986f61412a84143242021-04-29 21:52:45146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x1c048764ef12b37154e69cf92380e92d942f2aefdc1105c4e15291986f61412a84143242021-04-29 21:52:45146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x1c048764ef12b37154e69cf92380e92d942f2aefdc1105c4e15291986f61412a84143242021-04-29 21:52:45146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x1c048764ef12b37154e69cf92380e92d942f2aefdc1105c4e15291986f61412a84143242021-04-29 21:52:45146 days 4 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xe3d9cb77f631341590e3c40078cac211d0caee56bdac3f014640afb1f78d827c84070352021-04-29 15:48:16146 days 10 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xe3d9cb77f631341590e3c40078cac211d0caee56bdac3f014640afb1f78d827c84070352021-04-29 15:48:16146 days 10 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xe3d9cb77f631341590e3c40078cac211d0caee56bdac3f014640afb1f78d827c84070352021-04-29 15:48:16146 days 10 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xe3d9cb77f631341590e3c40078cac211d0caee56bdac3f014640afb1f78d827c84070352021-04-29 15:48:16146 days 10 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xe3d9cb77f631341590e3c40078cac211d0caee56bdac3f014640afb1f78d827c84070352021-04-29 15:48:16146 days 10 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0xe3d9cb77f631341590e3c40078cac211d0caee56bdac3f014640afb1f78d827c84070352021-04-29 15:48:16146 days 10 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x08a30cf8545b6895953c23d8346cad6e2c697715e703804681ebab236090516384035532021-04-29 12:54:10146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x08a30cf8545b6895953c23d8346cad6e2c697715e703804681ebab236090516384035532021-04-29 12:54:10146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x08a30cf8545b6895953c23d8346cad6e2c697715e703804681ebab236090516384035532021-04-29 12:54:10146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x08a30cf8545b6895953c23d8346cad6e2c697715e703804681ebab236090516384035532021-04-29 12:54:10146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x08a30cf8545b6895953c23d8346cad6e2c697715e703804681ebab236090516384035532021-04-29 12:54:10146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x08a30cf8545b6895953c23d8346cad6e2c697715e703804681ebab236090516384035532021-04-29 12:54:10146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x2971ac8259abbf1096f0980f219cd22b4d24ad1b5784652d71036d70953573d484035502021-04-29 12:54:01146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x2971ac8259abbf1096f0980f219cd22b4d24ad1b5784652d71036d70953573d484035502021-04-29 12:54:01146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x2971ac8259abbf1096f0980f219cd22b4d24ad1b5784652d71036d70953573d484035502021-04-29 12:54:01146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x2971ac8259abbf1096f0980f219cd22b4d24ad1b5784652d71036d70953573d484035502021-04-29 12:54:01146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
0x2971ac8259abbf1096f0980f219cd22b4d24ad1b5784652d71036d70953573d484035502021-04-29 12:54:01146 days 13 hrs ago 0xac4715fdd8f35c15fbc766c0e125981c4c795fee 0xc8262a9e01360c0b2c9297f10fd06a0d24ce36a90 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CFDState

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

// 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: @openzeppelin/contracts-upgradeable/proxy/Initializable.sol


// solhint-disable-next-line compiler-version


/**
 * @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: @openzeppelin/contracts-upgradeable/GSN/ContextUpgradeable.sol




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




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



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



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



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




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: contracts/utils/SignedDecimal.sol





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: @openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol



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

pragma experimental ABIEncoderV2;




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

    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 pure returns (Decimal.decimal memory);

    function getOutputPriceWithReserves(
        Dir _dir,
        Decimal.decimal memory _baseAssetAmount,
        Decimal.decimal memory _quoteAssetPoolAmount,
        Decimal.decimal memory _baseAssetPoolAmount
    ) external pure 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 getBaseAssetDeltaThisFundingPeriod() external view returns (SignedDecimal.signedDecimal 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(address account, uint256 amount) external;

    function burn(address account, uint256 amount) external;

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

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

// File: contracts/interface/ICFD.sol





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

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

    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/interface/ICFDState.sol





interface ICFDState {
    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, ICFD.Side _side) external returns (bool);

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

    function getWhiteList() external view returns (address);

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

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

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

// File: contracts/utils/BlockContext.sol


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





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










contract CFDState is ICFDState, 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 CFD;
    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;

    // 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 onlyCFD() {
        require(CFD == _msgSender(), "caller is not CFD");
        _;
    }

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

        CFD = _CFD;
        waitingPeriodSecs = _waitingPeriodSecs;
    }

    /**
     * @notice trader can't do the reverse operation during waiting period
     */
    function checkWaitingPeriod(
        address _exchange,
        address _trader,
        ICFD.Side _side
    ) public override onlyCFD returns (bool) {
        if (_side == ICFD.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
        onlyCFD
    {
        // 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,
        ICFD.Position memory _position,
        ICFD.PnlCalcOption _pnlCalcOption
    )
        public
        view
        override
        onlyCFD
        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;
            IExchange.Dir dir = isShortPosition ? IExchange.Dir.REMOVE_FROM_AMM : IExchange.Dir.ADD_TO_AMM;
            if (_pnlCalcOption == ICFD.PnlCalcOption.TWAP) {
                positionNotional = _exchange.getOutputTwap(dir, positionSizeAbs);
            } else {
                positionNotional = _exchange.getOutputPrice(dir, positionSizeAbs);
            }
            // 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,
        ICFD.Position memory _position,
        uint256 _latestLiquidityIndex
    ) public view override onlyCFD returns (ICFD.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 ? IExchange.Dir.ADD_TO_AMM : IExchange.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 calcRemainMarginWithFundingPaymentAndOvernightFee(
        IExchange _exchange,
        ICFD.Position memory _oldPosition,
        SignedDecimal.signedDecimal memory _marginDelta
    ) public view override onlyCFD returns (RemainMarginInfo memory remainMarginInfo) {
        // calculate funding payment
        SignedDecimal.signedDecimal memory latestCumulativePremiumFraction =
            ICFD(CFD).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 =
            ICFD(CFD).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":"CFD","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 ICFD.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 ICFD.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 ICFD.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 ICFDState.RemainMarginInfo","name":"remainMarginInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_exchange","type":"address"},{"internalType":"address","name":"_trader","type":"address"},{"internalType":"enum ICFD.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 ICFD.Position","name":"_position","type":"tuple"},{"internalType":"enum ICFD.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":"_CFD","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":"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"}]

608060405234801561001057600080fd5b50611fae806100206000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80637a7e5223116100975780638da5cb5b116100665780638da5cb5b14610225578063b0ac5f2f1461022d578063cd6dc68714610240578063f2fde38b1461025357610100565b80637a7e5223146101bc578063854cff2f146101dd57806389257117146101f05780638b4a5bf31461020557610100565b806359b8c599116100d357806359b8c5991461016057806361d9282914610181578063635a3872146101a1578063715018a6146101b457610100565b806302a3789e1461010557806309a9d76c1461011a5780634821e63014610138578063542cdc1b14610140575b600080fd5b6101186101133660046119dc565b610266565b005b6101226103fc565b60405161012f9190611aa8565b60405180910390f35b61012261040b565b61015361014e36600461189f565b61041a565b60405161012f9190611abc565b61017361016e366004611867565b610572565b60405161012f929190611ee3565b61019461018f36600461199c565b610596565b60405161012f9190611e31565b6101186101af366004611a90565b6108d9565b610118610913565b6101cf6101ca366004611914565b610992565b60405161012f929190611eb3565b6101186101eb36600461184b565b610b7a565b6101f8610bd1565b60405161012f9190611eda565b610218610213366004611954565b610bd7565b60405161012f9190611e84565b610122610e0b565b6101f861023b36600461184b565b610e1a565b61011861024e3660046118e9565b610e2c565b61011861026136600461184b565b610ed9565b61026e610f90565b6098546001600160a01b039081169116146102a45760405162461bcd60e51b815260040161029b90611cd0565b60405180910390fd5b600061031f836001600160a01b031663525454106040518163ffffffff1660e01b815260040160206040518083038186803b1580156102e257600080fd5b505afa1580156102f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061031a9190611a75565b610f94565b90508281156103f6576103306116c9565b6001600160a01b0382166000908152609a6020908152604091829020825191820190925290548152610363908590610f9c565b9050600061037082610f94565b12156103815761037e61100b565b90505b600061038c85610f94565b13156103cf578261039c82611026565b1115806103b35750609b546001600160a01b031633145b6103cf5760405162461bcd60e51b815260040161029b90611b5f565b6103d881611038565b6001600160a01b0383166000908152609a6020526040902090519055505b50505050565b609b546001600160a01b031690565b6098546001600160a01b031681565b6000610424610f90565b6098546001600160a01b039081169116146104515760405162461bcd60e51b815260040161029b90611cd0565b600082600181111561045f57fe5b14156104e8576001600160a01b03808516600090815260976020908152604080832093871683529290522060010154610496611069565b6099546104a490839061106d565b11156104b457600091505061056b565b6104bc611069565b6001600160a01b0380871660009081526097602090815260408083209389168352929052205550610567565b6001600160a01b03808516600090815260976020908152604080832093871683529290522054610516611069565b60995461052490839061106d565b111561053457600091505061056b565b61053c611069565b6001600160a01b03808716600090815260976020908152604080832093891683529290522060010155505b5060015b9392505050565b60976020908152600092835260408084209091529082529020805460019091015482565b61059e6116dc565b6105a6610f90565b6098546001600160a01b039081169116146105d35760405162461bcd60e51b815260040161029b90611cd0565b82516105de90610f94565b6105f0575060a082018190528161056b565b6105f8611737565b60a08401516040516311bf8bf760e11b81526001600160a01b0387169163237f17ee916106289190600401611eda565b60806040518083038186803b15801561064057600080fd5b505afa158015610654573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106789190611a11565b90506106826116c9565b6107018260000151876001600160a01b03166329f9b17b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106c357600080fd5b505afa1580156106d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106fb9190611a75565b90611092565b905061070b6116c9565b6107136116c9565b61071c83610f94565b15610836576107296116c9565b886001600160a01b03166350799c81600061074387610f94565b1361074f576001610752565b60005b61075b87611038565b886020015189604001516040518563ffffffff1660e01b81526004016107849493929190611ae3565b60206040518083038186803b15801561079c57600080fd5b505afa1580156107b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d49190611a75565b90506107f56107f0866020015186610f9c90919063ffffffff16565b611038565b9150600061080285610f94565b131561081e57604085015161081790826110b8565b9250610830565b604085015161082d90826110d5565b92505b50610844565b505060208201516040830151905b86516040516340d71cd960e01b81526001600160a01b038a16916340d71cd991610875919085908790600401611ec3565b60206040518083038186803b15801561088d57600080fd5b505afa1580156108a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c59190611a75565b87525050505060a083019190915250919050565b6108e1610f90565b6033546001600160a01b0390811691161461090e5760405162461bcd60e51b815260040161029b90611d3c565b609955565b61091b610f90565b6033546001600160a01b039081169116146109485760405162461bcd60e51b815260040161029b90611d3c565b6033546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380546001600160a01b0319169055565b61099a6116c9565b6109a26116c9565b6109aa610f90565b6098546001600160a01b039081169116146109d75760405162461bcd60e51b815260040161029b90611cd0565b6109df6116c9565b84516109ea90611038565b90506109f581610f94565b15610b7157600080610a0a8760000151610f94565b129050600081610a1b576000610a1e565b60015b90506001866001811115610a2e57fe5b1415610ab9576040516337d2176f60e11b81526001600160a01b03891690636fa42ede90610a629084908790600401611ac7565b60206040518083038186803b158015610a7a57600080fd5b505afa158015610a8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ab29190611a75565b9450610b3a565b60405163da0c592760e01b81526001600160a01b0389169063da0c592790610ae79084908790600401611ac7565b60206040518083038186803b158015610aff57600080fd5b505afa158015610b13573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b379190611a75565b94505b81610b5b57610b568760400151610b50876110f2565b90611156565b610b6c565b610b6c85610b5089604001516110f2565b935050505b50935093915050565b610b82610f90565b6033546001600160a01b03908116911614610baf5760405162461bcd60e51b815260040161029b90611d3c565b609b80546001600160a01b0319166001600160a01b0392909216919091179055565b60995481565b610bdf611737565b610be7610f90565b6098546001600160a01b03908116911614610c145760405162461bcd60e51b815260040161029b90611cd0565b610c1c6116c9565b609854604051636891397b60e01b81526001600160a01b0390911690636891397b90610c4c908890600401611aa8565b60206040518083038186803b158015610c6457600080fd5b505afa158015610c78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c9c9190611a75565b9050610cab8460000151610f94565b15610cd35783516060850151610ccd9190610cc7908490611092565b906111bb565b60408301525b610cdb6116c9565b6098546040516316f3f13160e21b81526001600160a01b0390911690635bcfc4c490610d0b908990600401611aa8565b60206040518083038186803b158015610d2357600080fd5b505afa158015610d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5b9190611a75565b9050610d6a8560000151610f94565b15610d9a57610d948560400151610d8e8760800151846110b890919063ffffffff16565b906111d8565b60608401525b610da26116c9565b610dcf8660200151610dc98660600151610b5088604001518a61109290919063ffffffff16565b90610f9c565b90506000610ddc82610f94565b1215610df557610deb81611038565b6020850152610e01565b610dfe81611038565b84525b5050509392505050565b6033546001600160a01b031690565b609a6020526000908152604090205481565b600054610100900460ff1680610e455750610e456111f5565b80610e53575060005460ff16155b610e6f5760405162461bcd60e51b815260040161029b90611c41565b600054610100900460ff16158015610e9a576000805460ff1961ff0019909116610100171660011790555b610ea26111fb565b609880546001600160a01b0319166001600160a01b03851617905560998290558015610ed4576000805461ff00191690555b505050565b610ee1610f90565b6033546001600160a01b03908116911614610f0e5760405162461bcd60e51b815260040161029b90611d3c565b6001600160a01b038116610f345760405162461bcd60e51b815260040161029b90611b83565b6033546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380546001600160a01b0319166001600160a01b0392909216919091179055565b3390565b80515b919050565b610fa46116c9565b8180600001516001600160ff1b031015604051806060016040528060338152602001611f466033913990610feb5760405162461bcd60e51b815260040161029b9190611b0c565b50610ff46116c9565b835185516110019161128e565b8152949350505050565b6110136116c9565b5060408051602081019091526000815290565b600061103182611038565b5192915050565b6110406116c9565b6110486116c9565b82516000131561105e5782516000038152611063565b825181525b92915050565b4290565b60008282018381101561056b5760405162461bcd60e51b815260040161029b90611bc9565b61109a6116c9565b6110a26116c9565b825184516110af916112d4565b81529392505050565b6110c06116c9565b6110c86116c9565b825184516110af9161131a565b6110dd6116c9565b6110e56116c9565b825184516110af9161106d565b6110fa6116c9565b8180600001516001600160ff1b031015604051806060016040528060338152602001611f4660339139906111415760405162461bcd60e51b815260040161029b9190611b0c565b50506040805160208101909152915182525090565b61115e6116c9565b8180600001516001600160ff1b031015604051806060016040528060338152602001611f4660339139906111a55760405162461bcd60e51b815260040161029b9190611b0c565b506111ae6116c9565b83518551611001916112d4565b6111c36116c9565b6111cb6116c9565b825184516110af9161135c565b6111e06116c9565b6111e86116c9565b825184516110af9161136a565b303b1590565b600054610100900460ff168061121457506112146111f5565b80611222575060005460ff16155b61123e5760405162461bcd60e51b815260040161029b90611c41565b600054610100900460ff16158015611269576000805460ff1961ff0019909116610100171660011790555b611271611378565b6112796113f9565b801561128b576000805461ff00191690555b50565b60008282018183128015906112a35750838112155b806112b857506000831280156112b857508381125b61056b5760405162461bcd60e51b815260040161029b90611c00565b60008183038183128015906112e95750838113155b806112fe57506000831280156112fe57508381135b61056b5760405162461bcd60e51b815260040161029b90611db8565b600061056b83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f7700008152506114d3565b600061056b838360126114ff565b600061056b83836012611525565b600054610100900460ff168061139157506113916111f5565b8061139f575060005460ff16155b6113bb5760405162461bcd60e51b815260040161029b90611c41565b600054610100900460ff16158015611279576000805460ff1961ff001990911661010017166001179055801561128b576000805461ff001916905550565b600054610100900460ff168061141257506114126111f5565b80611420575060005460ff16155b61143c5760405162461bcd60e51b815260040161029b90611c41565b600054610100900460ff16158015611467576000805460ff1961ff0019909116610100171660011790555b6000611471610f90565b603380546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350801561128b576000805461ff001916905550565b600081848411156114f75760405162461bcd60e51b815260040161029b9190611b0c565b505050900390565b600061151d61150d83611543565b611517868661154c565b906115b7565b949350505050565b600061151d61153383611543565b61153d868661161b565b90611655565b60ff16600a0a90565b60008261155b57506000611063565b8260001914801561156f5750600160ff1b82145b1561158c5760405162461bcd60e51b815260040161029b90611d71565b8282028284828161159957fe5b051461056b5760405162461bcd60e51b815260040161029b90611d71565b6000816115d65760405162461bcd60e51b815260040161029b90611dfc565b816000191480156115ea5750600160ff1b83145b156116075760405162461bcd60e51b815260040161029b90611c8f565b600082848161161257fe5b05949350505050565b60008261162a57506000611063565b8282028284828161163757fe5b041461056b5760405162461bcd60e51b815260040161029b90611cfb565b600061056b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250600081836116b35760405162461bcd60e51b815260040161029b9190611b0c565b5060008385816116bf57fe5b0495945050505050565b6040518060200160405280600081525090565b6040518060e001604052806116ef6116c9565b81526020016116fc6116c9565b81526020016117096116c9565b81526020016117166116c9565b81526020016117236116c9565b815260200160008152602001600081525090565b604051806080016040528061174a6116c9565b81526020016117576116c9565b81526020016117646116c9565b81526020016117716116c9565b905290565b600060e08284031215611787578081fd5b61179160e0611ef1565b905061179d8383611801565b81526117ac8360208401611801565b60208201526117be8360408401611801565b60408201526117d08360608401611801565b60608201526117e28360808401611801565b608082015260a082013560a082015260c082013560c082015292915050565b600060208284031215611812578081fd5b61181c6020611ef1565b9135825250919050565b600060208284031215611837578081fd5b6118416020611ef1565b9151825250919050565b60006020828403121561185c578081fd5b813561056b81611f23565b60008060408385031215611879578081fd5b823561188481611f23565b9150602083013561189481611f23565b809150509250929050565b6000806000606084860312156118b3578081fd5b83356118be81611f23565b925060208401356118ce81611f23565b915060408401356118de81611f38565b809150509250925092565b600080604083850312156118fb578182fd5b823561190681611f23565b946020939093013593505050565b60008060006101208486031215611929578283fd5b833561193481611f23565b92506119438560208601611776565b91506101008401356118de81611f38565b60008060006101208486031215611969578283fd5b833561197481611f23565b92506119838560208601611776565b9150611993856101008601611801565b90509250925092565b600080600061012084860312156119b1578283fd5b83356119bc81611f23565b92506119cb8560208601611776565b915061010084013590509250925092565b600080604083850312156119ee578182fd5b82356119f981611f23565b9150611a088460208501611801565b90509250929050565b600060808284031215611a22578081fd5b611a2c6080611ef1565b611a368484611826565b8152611a458460208501611826565b6020820152611a578460408501611826565b6040820152611a698460608501611826565b60608201529392505050565b600060208284031215611a86578081fd5b61056b8383611826565b600060208284031215611aa1578081fd5b5035919050565b6001600160a01b0391909116815260200190565b901515815260200190565b60408101611ad484611f18565b82529151602090910152919050565b60808101611af086611f18565b8252935160208201529151604083015251606090910152919050565b6000602080835283518082850152825b81811015611b3857858101830151858201604001528201611b1c565b81811115611b495783604083870101525b50601f01601f1916929092016040019392505050565b6020808252600a90820152691bdd995c881b1a5b5a5d60b21b604082015260600190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601b908201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604082015260600190565b60208082526021908201527f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b60208082526021908201527f5369676e6564536166654d6174683a206469766973696f6e206f766572666c6f6040820152607760f81b606082015260800190565b60208082526011908201527018d85b1b195c881a5cc81b9bdd0810d191607a1b604082015260600190565b60208082526021908201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6040820152607760f81b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526027908201527f5369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f604082015266766572666c6f7760c81b606082015260800190565b60208082526024908201527f5369676e6564536166654d6174683a207375627472616374696f6e206f766572604082015263666c6f7760e01b606082015260800190565b6020808252818101527f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f604082015260600190565b600060e0820190508251518252602083015151602083015260408301515160408301526060830151516060830152608083015151608083015260a083015160a083015260c083015160c083015292915050565b815151815260208083015151908201526040808301515190820152606091820151519181019190915260800190565b9151825251602082015260400190565b925183529051602083015251604082015260600190565b90815260200190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715611f1057600080fd5b604052919050565b8060028110610f9757fe5b6001600160a01b038116811461128b57600080fd5b6002811061128b57600080fdfe4d69786564446563696d616c3a2075696e742076616c756520697320626967676572207468616e205f494e543235365f4d4158a264697066735822122022ab32cba96164d96df47e9d893640087fbcbaac2143da24fd0de6b73a2711e864736f6c634300060c0033

Deployed ByteCode Sourcemap

38230:10470:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41649:1086;;;;;;:::i;:::-;;:::i;:::-;;41412:98;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38582:18;;;:::i;39957:850::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;38503:72::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;44569:2328::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;40973:132::-;;;;;;:::i;:::-;;:::i;11195:148::-;;;:::i;43138:1423::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;41304:100::-;;;;;;:::i;:::-;;:::i;38607:32::-;;;:::i;:::-;;;;;;;:::i;46905:1792::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;10553:79::-;;;:::i;38838:66::-;;;;;;:::i;:::-;;:::i;39667:188::-;;;;;;:::i;:::-;;:::i;11498:244::-;;;;;;:::i;:::-;;:::i;41649:1086::-;39605:12;:10;:12::i;:::-;39598:3;;-1:-1:-1;;;;;39598:3:0;;;:19;;;39590:49;;;;-1:-1:-1;;;39590:49:0;;;;;;;:::i;:::-;;;;;;;;;41855:11:::1;41869:47;:9;-1:-1:-1::0;;;;;41869:36:0::1;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:45;:47::i;:::-;41855:61:::0;-1:-1:-1;41953:9:0;41978:7;;41974:754:::1;;42002:62;;:::i;:::-;-1:-1:-1::0;;;;;42097:32:0;::::1;;::::0;;;:23:::1;:32;::::0;;;;;;;;42084:46;;;;::::1;::::0;;;;;;;::::1;::::0;:7;;:12:::1;:46::i;:::-;42002:128;;42310:1;42272:35;:27;:33;:35::i;:::-;:39;42268:130;;;42362:20;:18;:20::i;:::-;42332:50;;42268:130;42434:1;42416:15;:7;:13;:15::i;:::-;:19;42412:222;;;42573:3;42533:36;:27;:34;:36::i;:::-;:43;;:70;;;-1:-1:-1::0;42594:9:0::1;::::0;-1:-1:-1;;;;;42594:9:0::1;42580:10;:23;42533:70;42525:93;;;;-1:-1:-1::0;;;42525:93:0::1;;;;;;;:::i;:::-;42683:33;:27;:31;:33::i;:::-;-1:-1:-1::0;;;;;42648:32:0;::::1;;::::0;;;:23:::1;:32;::::0;;;;:68;;;;-1:-1:-1;41974:754:0::1;39650:1;;41649:1086:::0;;:::o;41412:98::-;41493:9;;-1:-1:-1;;;;;41493:9:0;41412:98;:::o;38582:18::-;;;-1:-1:-1;;;;;38582:18:0;;:::o;39957:850::-;40105:4;39605:12;:10;:12::i;:::-;39598:3;;-1:-1:-1;;;;;39598:3:0;;;:19;;;39590:49;;;;-1:-1:-1;;;39590:49:0;;;;;;;:::i;:::-;40135:13:::1;40126:5;:22;;;;;;;;;40122:656;;;-1:-1:-1::0;;;;;40192:23:0;;::::1;40165:24;40192:23:::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:49:::1;;::::0;40302:17:::1;:15;:17::i;:::-;40281;::::0;40260:39:::1;::::0;:16;;:20:::1;:39::i;:::-;:59;40256:112;;;40347:5;40340:12;;;;;40256:112;40433:17;:15;:17::i;:::-;-1:-1:-1::0;;;;;40382:23:0;;::::1;;::::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:68;-1:-1:-1;40122:656:0::1;;;-1:-1:-1::0;;;;;40509:23:0;;::::1;40483;40509::::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:48;40617:17:::1;:15;:17::i;:::-;40596;::::0;40576:38:::1;::::0;:15;;:19:::1;:38::i;:::-;:58;40572:111;;;40662:5;40655:12;;;;;40572:111;40749:17;:15;:17::i;:::-;-1:-1:-1::0;;;;;40697:23:0;;::::1;;::::0;;;:12:::1;:23;::::0;;;;;;;:32;;::::1;::::0;;;;;;:49:::1;;:69:::0;-1:-1:-1;40122:656:0::1;-1:-1:-1::0;40795:4:0::1;39650:1;39957:850:::0;;;;;:::o;38503:72::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;44569:2328::-;44770:20;;:::i;:::-;39605:12;:10;:12::i;:::-;39598:3;;-1:-1:-1;;;;;39598:3:0;;;:19;;;39590:49;;;;-1:-1:-1;;;39590:49:0;;;;;;;:::i;:::-;44807:14;;:22:::1;::::0;:20:::1;:22::i;:::-;44803:146;;-1:-1:-1::0;44851:31:0::1;::::0;::::1;:55:::0;;;:9;44921:16:::1;;44803:146;45110:54;;:::i;:::-;45219:31;::::0;::::1;::::0;45180:71:::1;::::0;-1:-1:-1;;;45180:71:0;;-1:-1:-1;;;;;45180:38:0;::::1;::::0;::::1;::::0;:71:::1;::::0;45219:31;45180:71:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45110:141;;45262:48;;:::i;:::-;45326:71;45365:12;:31;;;45326:9;-1:-1:-1::0;;;;;45326:31:0::1;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38:::0;::::1;:71::i;:::-;45262:135;;45508:44;;:::i;:::-;45563:45;;:::i;:::-;45623:21;:13;:19;:21::i;:::-;:26:::0;45619:945:::1;;45666:37;;:::i;:::-;45723:9;-1:-1:-1::0;;;;;45723:35:0::1;;45805:1;45781:21;:13;:19;:21::i;:::-;:25;:84;;45836:29;45781:84;;;45809:24;45781:84;45888:19;:13;:17;:19::i;:::-;45930:12;:30;;;45983:12;:29;;;45723:308;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;45666:365;;46071:56;:50;46090:12;:30;;;46071:13;:18;;:50;;;;:::i;:::-;:54;:56::i;:::-;46046:81;;46170:1;46146:21;:13;:19;:21::i;:::-;:25;46142:255;;;46216:29;::::0;::::1;::::0;:50:::1;::::0;46251:14;46216:34:::1;:50::i;:::-;46192:74;;46142:255;;;46331:29;::::0;::::1;::::0;:50:::1;::::0;46366:14;46331:34:::1;:50::i;:::-;46307:74;;46142:255;45619:945;;;;-1:-1:-1::0;;46454:30:0::1;::::0;::::1;::::0;46523:29:::1;::::0;::::1;::::0;;45619:945:::1;46698:14:::0;;46637:159:::1;::::0;-1:-1:-1;;;46637:159:0;;-1:-1:-1;;;;;46637:46:0;::::1;::::0;::::1;::::0;:159:::1;::::0;46698:14;46727:22;;46764:21;;46637:159:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46620:176:::0;;-1:-1:-1;;;;46807:31:0::1;::::0;::::1;:55:::0;;;;-1:-1:-1;46620:176:0;44569:2328;-1:-1:-1;44569:2328:0:o;40973:132::-;10775:12;:10;:12::i;:::-;10765:6;;-1:-1:-1;;;;;10765:6:0;;;:22;;;10757:67;;;;-1:-1:-1;;;10757:67:0;;;;;;;:::i;:::-;41059:17:::1;:38:::0;40973:132::o;11195:148::-;10775:12;:10;:12::i;:::-;10765:6;;-1:-1:-1;;;;;10765:6:0;;;:22;;;10757:67;;;;-1:-1:-1;;;10757:67:0;;;;;;;:::i;:::-;11286:6:::1;::::0;11265:40:::1;::::0;11302:1:::1;::::0;-1:-1:-1;;;;;11286:6:0::1;::::0;11265:40:::1;::::0;11302:1;;11265:40:::1;11316:6;:19:::0;;-1:-1:-1;;;;;;11316:19:0::1;::::0;;11195:148::o;43138:1423::-;43388:39;;:::i;:::-;43429:48;;:::i;:::-;39605:12;:10;:12::i;:::-;39598:3;;-1:-1:-1;;;;;39598:3:0;;;:19;;;39590:49;;;;-1:-1:-1;;;39590:49:0;;;;;;;:::i;:::-;43495:38:::1;;:::i;:::-;43536:14:::0;;:20:::1;::::0;:18:::1;:20::i;:::-;43495:61;;43571:24;:15;:22;:24::i;:::-;:29:::0;43567:987:::1;;43617:20;43665:1:::0;43640:22:::1;:9;:14;;;:20;:22::i;:::-;:26;43617:49;;43681:17;43701:15;:74;;43751:24;43701:74;;;43719:29;43701:74;43681:94:::0;-1:-1:-1;43812:23:0::1;43794:14;:41;;;;;;;;;43790:252;;;43875:45;::::0;-1:-1:-1;;;43875:45:0;;-1:-1:-1;;;;;43875:23:0;::::1;::::0;::::1;::::0;:45:::1;::::0;43899:3;;43904:15;;43875:45:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43856:64;;43790:252;;;43980:46;::::0;-1:-1:-1;;;43980:46:0;;-1:-1:-1;;;;;43980:24:0;::::1;::::0;::::1;::::0;:46:::1;::::0;44005:3;;44010:15;;43980:46:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;43961:65;;43790:252;44345:15;:197;;44471:71;44519:9;:22;;;44471:42;44496:16;44471:24;:42::i;:::-;:47:::0;::::1;:71::i;:::-;44345:197;;;44380:71;44434:16;44380:48;44405:9;:22;;;44380:24;:48::i;:71::-;44329:213;;43567:987;;;39650:1;43138:1423:::0;;;;;;:::o;41304:100::-;10775:12;:10;:12::i;:::-;10765:6;;-1:-1:-1;;;;;10765:6:0;;;:22;;;10757:67;;;;-1:-1:-1;;;10757:67:0;;;;;;;:::i;:::-;41374:9:::1;:22:::0;;-1:-1:-1;;;;;;41374:22:0::1;-1:-1:-1::0;;;;;41374:22:0;;;::::1;::::0;;;::::1;::::0;;41304:100::o;38607:32::-;;;;:::o;46905:1792::-;47141:40;;:::i;:::-;39605:12;:10;:12::i;:::-;39598:3;;-1:-1:-1;;;;;39598:3:0;;;:19;;;39590:49;;;;-1:-1:-1;;;39590:49:0;;;;;;;:::i;:::-;47232:66:::1;;:::i;:::-;47319:3;::::0;47314:55:::1;::::0;-1:-1:-1;;;47314:55:0;;-1:-1:-1;;;;;47319:3:0;;::::1;::::0;47314:44:::1;::::0;:55:::1;::::0;47359:9;;47314:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47232:137;;47384:25;:12;:17;;;:23;:25::i;:::-;:30:::0;47380:244:::1;;47594:17:::0;;47520:49:::1;::::0;::::1;::::0;47465:147:::1;::::0;47594:17;47465:105:::1;::::0;:31;;:54:::1;:105::i;:::-;:128:::0;::::1;:147::i;:::-;47431:31;::::0;::::1;:181:::0;47380:244:::1;47738:55;;:::i;:::-;47814:3;::::0;47809:56:::1;::::0;-1:-1:-1;;;47809:56:0;;-1:-1:-1;;;;;47814:3:0;;::::1;::::0;47809:45:::1;::::0;:56:::1;::::0;47855:9;;47809:56:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;47738:127;;47880:25;:12;:17;;;:23;:25::i;:::-;:30:::0;47876:252:::1;;47959:157;48090:12;:25;;;47959:107;48015:12;:50;;;47959:32;:55;;:107;;;;:::i;:::-;:130:::0;::::1;:157::i;:::-;47927:29;::::0;::::1;:189:::0;47876:252:::1;48176:53;;:::i;:::-;48245:144;48355:12;:19;;;48245:86;48301:16;:29;;;48245:50;48263:16;:31;;;48245:12;:17;;:50;;;;:::i;:86::-;:91:::0;::::1;:144::i;:::-;48176:213;;48520:1;48491:26;:18;:24;:26::i;:::-;:30;48487:203;;;48565:24;:18;:22;:24::i;:::-;48538;::::0;::::1;:51:::0;48487:203:::1;;;48654:24;:18;:22;:24::i;:::-;48622:56:::0;;48487:203:::1;39650:1;;;46905:1792:::0;;;;;:::o;10553:79::-;10618:6;;-1:-1:-1;;;;;10618:6:0;10553:79;:::o;38838:66::-;;;;;;;;;;;;;:::o;39667:188::-;6969:13;;;;;;;;:33;;;6986:16;:14;:16::i;:::-;6969:50;;;-1:-1:-1;7007:12:0;;;;7006:13;6969:50;6961:109;;;;-1:-1:-1;;;6961:109:0;;;;;;;:::i;:::-;7083:19;7106:13;;;;;;7105:14;7130:101;;;;7165:13;:20;;-1:-1:-1;;;;7165:20:0;;;;;7200:19;7181:4;7200:19;;;7130:101;39759:16:::1;:14;:16::i;:::-;39788:3;:10:::0;;-1:-1:-1;;;;;;39788:10:0::1;-1:-1:-1::0;;;;;39788:10:0;::::1;;::::0;;39809:17:::1;:38:::0;;;7257:68;;;;7308:5;7292:21;;-1:-1:-1;;7292:21:0;;;7257:68;39667:188;;;:::o;11498:244::-;10775:12;:10;:12::i;:::-;10765:6;;-1:-1:-1;;;;;10765:6:0;;;:22;;;10757:67;;;;-1:-1:-1;;;10757:67:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;11587:22:0;::::1;11579:73;;;;-1:-1:-1::0;;;11579:73:0::1;;;;;;;:::i;:::-;11689:6;::::0;11668:38:::1;::::0;-1:-1:-1;;;;;11668:38:0;;::::1;::::0;11689:6:::1;::::0;11668:38:::1;::::0;11689:6:::1;::::0;11668:38:::1;11717:6;:17:::0;;-1:-1:-1;;;;;;11717:17:0::1;-1:-1:-1::0;;;;;11717:17:0;;;::::1;::::0;;;::::1;::::0;;11498:244::o;8859:106::-;8947:10;8859:106;:::o;18515:95::-;18599:3;;18515:95;;;;:::o;35881:304::-;36033:34;;:::i;:::-;36012:1;35364;:3;;;-1:-1:-1;;;;;35349:18:0;;35369:21;;;;;;;;;;;;;;;;;35341:50;;;;;-1:-1:-1;;;35341:50:0;;;;;;;;:::i;:::-;;36085:36:::1;;:::i;:::-;36153:3:::0;;36138;;:20:::1;::::0;:7:::1;:20::i;:::-;36132:26:::0;;;35881:304;-1:-1:-1;;;;35881:304:0:o;20546:103::-;20585:20;;:::i;:::-;-1:-1:-1;20625:16:0;;;;;;;;;-1:-1:-1;20625:16:0;;20546:103;:::o;35655:121::-;35732:7;35759;:1;:5;:7::i;:::-;:9;;35655:121;-1:-1:-1;;35655:121:0:o;20937:269::-;20997:22;;:::i;:::-;21032:24;;:::i;:::-;21071:3;;21077:1;-1:-1:-1;21067:113:0;;;21113:3;;;21109:7;21095:22;;21067:113;;;21164:3;;21150:18;;21067:113;21197:1;20937:269;-1:-1:-1;;20937:269:0:o;34588:108::-;34673:15;34588:108;:::o;998:181::-;1056:7;1088:5;;;1112:6;;;;1104:46;;;;-1:-1:-1;;;1104:46:0;;;;;;;:::i;21485:196::-;21570:20;;:::i;:::-;21603:22;;:::i;:::-;21650:3;;21642;;:12;;:7;:12::i;:::-;21636:18;;;21485:196;-1:-1:-1;;;21485:196:0:o;19262:172::-;19335:14;;:::i;:::-;19362:16;;:::i;:::-;19403:3;;19395;;:12;;:7;:12::i;19046:172::-;19119:14;;:::i;:::-;19146:16;;:::i;:::-;19187:3;;19179;;:12;;:7;:12::i;35419:228::-;35540:34;;:::i;:::-;35519:1;35364;:3;;;-1:-1:-1;;;;;35349:18:0;;35369:21;;;;;;;;;;;;;;;;;35341:50;;;;;-1:-1:-1;;;35341:50:0;;;;;;;;:::i;:::-;-1:-1:-1;;35599:40:0::1;::::0;;::::1;::::0;::::1;::::0;;;35634:3;;35599:40;;-1:-1:-1;35599:40:0;35419:228::o;36294:304::-;36446:34;;:::i;:::-;36425:1;35364;:3;;;-1:-1:-1;;;;;35349:18:0;;35369:21;;;;;;;;;;;;;;;;;35341:50;;;;;-1:-1:-1;;;35341:50:0;;;;;;;;:::i;:::-;;36498:36:::1;;:::i;:::-;36566:3:::0;;36551;;:20:::1;::::0;:7:::1;:20::i;21725:197::-:0;21810:20;;:::i;:::-;21843:22;;:::i;:::-;21891:3;;21882;;:13;;:8;:13::i;19478:173::-;19551:14;;:::i;:::-;19578:16;;:::i;:::-;19620:3;;19611;;:13;;:8;:13::i;7425:604::-;7867:4;7978:17;8014:7;7425:604;:::o;10139:129::-;6969:13;;;;;;;;:33;;;6986:16;:14;:16::i;:::-;6969:50;;;-1:-1:-1;7007:12:0;;;;7006:13;6969:50;6961:109;;;;-1:-1:-1;;;6961:109:0;;;;;;;:::i;:::-;7083:19;7106:13;;;;;;7105:14;7130:101;;;;7165:13;:20;;-1:-1:-1;;;;7165:20:0;;;;;7200:19;7181:4;7200:19;;;7130:101;10197:26:::1;:24;:26::i;:::-;10234;:24;:26::i;:::-;7261:14:::0;7257:68;;;7308:5;7292:21;;-1:-1:-1;;7292:21:0;;;7257:68;10139:129;:::o;14348:215::-;14404:6;14434:5;;;14459:6;;;;;;:16;;;14474:1;14469;:6;;14459:16;14458:38;;;;14485:1;14481;:5;:14;;;;;14494:1;14490;:5;14481:14;14450:84;;;;-1:-1:-1;;;14450:84:0;;;;;;;:::i;13885:218::-;13941:6;13971:5;;;13996:6;;;;;;:16;;;14011:1;14006;:6;;13996:16;13995:38;;;;14022:1;14018;:5;:14;;;;;14031:1;14027;:5;14018:14;13987:87;;;;-1:-1:-1;;;13987:87:0;;;;;;;:::i;1462:136::-;1520:7;1547:43;1551:1;1554;1547:43;;;;;;;;;;;;;;;;;:3;:43::i;15470:105::-;15527:6;15553:14;15558:1;15561;15564:2;15553:4;:14::i;17233:108::-;17292:7;17319:14;17324:1;17327;17330:2;17319:4;:14::i;8788:65::-;6969:13;;;;;;;;:33;;;6986:16;:14;:16::i;:::-;6969:50;;;-1:-1:-1;7007:12:0;;;;7006:13;6969:50;6961:109;;;;-1:-1:-1;;;6961:109:0;;;;;;;:::i;:::-;7083:19;7106:13;;;;;;7105:14;7130:101;;;;7165:13;:20;;-1:-1:-1;;;;7165:20:0;;;;;7200:19;7181:4;7200:19;;;7261:14;7257:68;;;7308:5;7292:21;;-1:-1:-1;;7292:21:0;;;8788:65;:::o;10276:196::-;6969:13;;;;;;;;:33;;;6986:16;:14;:16::i;:::-;6969:50;;;-1:-1:-1;7007:12:0;;;;7006:13;6969:50;6961:109;;;;-1:-1:-1;;;6961:109:0;;;;;;;:::i;:::-;7083:19;7106:13;;;;;;7105:14;7130:101;;;;7165:13;:20;;-1:-1:-1;;;;7165:20:0;;;;;7200:19;7181:4;7200:19;;;7130:101;10344:17:::1;10364:12;:10;:12::i;:::-;10387:6;:18:::0;;-1:-1:-1;;;;;;10387:18:0::1;-1:-1:-1::0;;;;;10387:18:0;::::1;::::0;;::::1;::::0;;;10421:43:::1;::::0;10387:18;;-1:-1:-1;10387:18:0;-1:-1:-1;;10421:43:0::1;::::0;-1:-1:-1;;10421:43:0::1;7243:1;7261:14:::0;7257:68;;;7308:5;7292:21;;-1:-1:-1;;7292:21:0;;;10276: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;15676:169::-;15783:6;15809:28;15822:14;15827:8;15822:4;:14::i;:::-;15809:8;:1;15815;15809:5;:8::i;:::-;:12;;:28::i;:::-;15802:35;15676:169;-1:-1:-1;;;;15676:169:0:o;17442:172::-;17551:7;17578:28;17591:14;17596:8;17591:4;:14::i;:::-;17578:8;:1;17584;17578:5;:8::i;:::-;:12;;:28::i;14879:116::-;14969:17;;14965:2;:21;;14879:116::o;12321:568::-;12377:6;12621;12617:47;;-1:-1:-1;12651:1:0;12644:8;;12617:47;12686:1;-1:-1:-1;;12686:7:0;:27;;;;;-1:-1:-1;;;12697:1:0;:16;12686:27;12684:30;12676:82;;;;-1:-1:-1;;;12676:82:0;;;;;;;:::i;:::-;12782:5;;;12786:1;12782;:5;:1;12806:5;;;;;:10;12798:62;;;;-1:-1:-1;;;12798:62:0;;;;;;;:::i;13363:271::-;13419:6;13446;13438:51;;;;-1:-1:-1;;;13438:51:0;;;;;;;:::i;:::-;13510:1;-1:-1:-1;;13510:7:0;:27;;;;;-1:-1:-1;;;13521:1:0;:16;13510:27;13508:30;13500:76;;;;-1:-1:-1;;;13500:76:0;;;;;;;:::i;:::-;13589:8;13604:1;13600;:5;;;;;;;13363:271;-1:-1:-1;;;;13363:271:0: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;;;;;;;;;;;;;;;;;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;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;:::o;1988:1424::-;;2103:4;2091:9;2086:3;2082:19;2078:30;2075:2;;;-1:-1;;2111:12;2075:2;2139:20;2103:4;2139:20;:::i;:::-;2130:29;;2241:80;2317:3;2293:22;2241:80;:::i;:::-;2223:16;2216:106;2418:73;2487:3;2385:2;2467:9;2463:22;2418:73;:::i;:::-;2385:2;2404:5;2400:16;2393:99;2594:73;2663:3;2561:2;2643:9;2639:22;2594:73;:::i;:::-;2561:2;2580:5;2576:16;2569:99;2794:80;2870:3;2761:2;2850:9;2846:22;2794:80;:::i;:::-;2761:2;2780:5;2776:16;2769:106;3003:73;3072:3;2969;3052:9;3048:22;3003:73;:::i;:::-;2969:3;2989:5;2985:16;2978:99;3155:3;3214:9;3210:22;4986:20;3155:3;3175:5;3171:16;3164:75;3307:3;3366:9;3362:22;4986:20;3307:3;3327:5;3323:16;3316:75;2069:1343;;;;:::o;3448:319::-;;3561:4;3549:9;3544:3;3540:19;3536:30;3533:2;;;-1:-1;;3569:12;3533:2;3597:20;3561:4;3597:20;:::i;:::-;4986;;3671:75;;-1:-1;3588:29;3527:240;-1:-1;3527:240::o;3803:341::-;;3927:4;3915:9;3910:3;3906:19;3902:30;3899:2;;;-1:-1;;3935:12;3899:2;3963:20;3927:4;3963:20;:::i;:::-;5134:13;;4037:86;;-1:-1;3954:29;3893:251;-1:-1;3893:251::o;5197:241::-;;5301:2;5289:9;5280:7;5276:23;5272:32;5269:2;;;-1:-1;;5307:12;5269:2;85:6;72:20;97:33;124:5;97:33;:::i;5445:366::-;;;5566:2;5554:9;5545:7;5541:23;5537:32;5534:2;;;-1:-1;;5572:12;5534:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;5624:63;-1:-1;5724:2;5763:22;;72:20;97:33;72:20;97:33;:::i;:::-;5732:63;;;;5528:283;;;;;:::o;5818:509::-;;;;5965:2;5953:9;5944:7;5940:23;5936:32;5933:2;;;-1:-1;;5971:12;5933:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6023:63;-1:-1;6123:2;6162:22;;72:20;97:33;72:20;97:33;:::i;:::-;6131:63;-1:-1;6231:2;6279:22;;400:20;425:51;400:20;425:51;:::i;:::-;6239:72;;;;5927:400;;;;;:::o;6334:366::-;;;6455:2;6443:9;6434:7;6430:23;6426:32;6423:2;;;-1:-1;;6461:12;6423:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6513:63;6613:2;6652:22;;;;4986:20;;-1:-1;;;6417:283::o;6707:617::-;;;;6907:3;6895:9;6886:7;6882:23;6878:33;6875:2;;;-1:-1;;6914:12;6875:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;6966:81;-1:-1;7102:79;7173:7;7084:2;7149:22;;7102:79;:::i;:::-;7092:89;;7218:3;7280:9;7276:22;400:20;425:51;470:5;425:51;:::i;7331:643::-;;;;7544:3;7532:9;7523:7;7519:23;7515:33;7512:2;;;-1:-1;;7551:12;7512:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;7603:81;-1:-1;7739:79;7810:7;7721:2;7786:22;;7739:79;:::i;:::-;7729:89;;7874:84;7950:7;7855:3;7930:9;7926:22;7874:84;:::i;:::-;7864:94;;7506:468;;;;;:::o;7981:581::-;;;;8163:3;8151:9;8142:7;8138:23;8134:33;8131:2;;;-1:-1;;8170:12;8131:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;8222:81;-1:-1;8358:79;8429:7;8340:2;8405:22;;8358:79;:::i;:::-;8348:89;;8474:3;8518:9;8514:22;4986:20;8483:63;;8125:437;;;;;:::o;8569:464::-;;;8739:2;8727:9;8718:7;8714:23;8710:32;8707:2;;;-1:-1;;8745:12;8707:2;240:6;227:20;252:51;297:5;252:51;:::i;:::-;8797:81;-1:-1;8933:84;9009:7;8915:2;8985:22;;8933:84;:::i;:::-;8923:94;;8701:332;;;;;:::o;9040:348::-;;9197:3;9185:9;9176:7;9172:23;9168:33;9165:2;;;-1:-1;;9204:12;9165:2;1143:20;9197:3;1143:20;:::i;:::-;1259:91;1346:3;1322:22;1259:91;:::i;:::-;1241:16;1234:117;1458:84;1538:3;1425:2;1518:9;1514:22;1458:84;:::i;:::-;1425:2;1444:5;1440:16;1433:110;1649:84;1729:3;1616:2;1709:9;1705:22;1649:84;:::i;:::-;1616:2;1635:5;1631:16;1624:110;1841:91;1928:3;1808:2;1908:9;1904:22;1841:91;:::i;:::-;1808:2;1823:16;;1816:117;1827:5;9159:229;-1:-1;;;9159:229::o;9395:311::-;;9534:2;9522:9;9513:7;9509:23;9505:32;9502:2;;;-1:-1;;9540:12;9502:2;9602:88;9682:7;9658:22;9602:88;:::i;10045:241::-;;10149:2;10137:9;10128:7;10124:23;10120:32;10117:2;;;-1:-1;;10155:12;10117:2;-1:-1;4986:20;;10111:175;-1:-1;10111:175::o;20234:222::-;-1:-1;;;;;31384:54;;;;10364:37;;20361:2;20346:18;;20332:124::o;20463:210::-;30973:13;;30966:21;10478:34;;20584:2;20569:18;;20555:118::o;20945:441::-;21154:2;21139:18;;31911:32;10819:5;31911:32;:::i;:::-;10770:56;;18685:23;;21372:2;21357:18;;;10897:36;21125:261;;-1:-1;21125:261::o;21393:856::-;21754:3;21739:19;;31911:32;10819:5;31911:32;:::i;:::-;10770:56;;18685:23;;21973:2;21958:18;;10897:36;18685:23;;22104:2;22089:18;;10897:36;18685:23;22235:2;22220:18;;;10897:36;21725:524;;-1:-1;21725:524::o;22256:310::-;;22403:2;;22424:17;22417:47;11090:5;30596:12;30753:6;22403:2;22392:9;22388:18;30741:19;-1:-1;32028:101;32042:6;32039:1;32036:13;32028:101;;;32109:11;;;;;32103:18;32090:11;;;30781:14;32090:11;32083:39;32057:10;;32028:101;;;32144:6;32141:1;32138:13;32135:2;;;-1:-1;30781:14;32200:6;22392:9;32191:16;;32184:27;32135:2;-1:-1;32316:7;32300:14;-1:-1;;32296:28;11248:39;;;;30781:14;11248:39;;22374:192;-1:-1;;;22374:192::o;22573:416::-;22773:2;22787:47;;;11524:2;22758:18;;;30741:19;-1:-1;;;30781:14;;;11540:33;11592:12;;;22744:245::o;22996:416::-;23196:2;23210:47;;;11843:2;23181:18;;;30741:19;11879:34;30781:14;;;11859:55;-1:-1;;;11934:12;;;11927:30;11976:12;;;23167:245::o;23419:416::-;23619:2;23633:47;;;12227:2;23604:18;;;30741:19;12263:29;30781:14;;;12243:50;12312:12;;;23590:245::o;23842:416::-;24042:2;24056:47;;;12563:2;24027:18;;;30741:19;12599:34;30781:14;;;12579:55;-1:-1;;;12654:12;;;12647:25;12691:12;;;24013:245::o;24265:416::-;24465:2;24479:47;;;12942:2;24450:18;;;30741:19;12978:34;30781:14;;;12958:55;-1:-1;;;13033:12;;;13026:38;13083:12;;;24436:245::o;24688:416::-;24888:2;24902:47;;;13334:2;24873:18;;;30741:19;13370:34;30781:14;;;13350:55;-1:-1;;;13425:12;;;13418:25;13462:12;;;24859:245::o;25111:416::-;25311:2;25325:47;;;13713:2;25296:18;;;30741:19;-1:-1;;;30781:14;;;13729:40;13788:12;;;25282:245::o;25534:416::-;25734:2;25748:47;;;14039:2;25719:18;;;30741:19;14075:34;30781:14;;;14055:55;-1:-1;;;14130:12;;;14123:25;14167:12;;;25705:245::o;25957:416::-;26157:2;26171:47;;;26142:18;;;30741:19;14454:34;30781:14;;;14434:55;14508:12;;;26128:245::o;26380:416::-;26580:2;26594:47;;;14759:2;26565:18;;;30741:19;14795:34;30781:14;;;14775:55;-1:-1;;;14850:12;;;14843:31;14893:12;;;26551:245::o;26803:416::-;27003:2;27017:47;;;15144:2;26988:18;;;30741:19;15180:34;30781:14;;;15160:55;-1:-1;;;15235:12;;;15228:28;15275:12;;;26974:245::o;27226:416::-;27426:2;27440:47;;;27411:18;;;30741:19;15562:34;30781:14;;;15542:55;15616:12;;;27397:245::o;27649:327::-;;27828:3;27817:9;27813:19;27805:27;;15910:16;15904:23;18685;10904:3;10897:36;16139:4;16132:5;16128:16;16122:23;18685;16139:4;16251:3;16247:14;10897:36;16349:4;16342:5;16338:16;16332:23;18685;16349:4;16461:3;16457:14;10897:36;16583:4;16576:5;16572:16;16566:23;18685;16583:4;16709:3;16705:14;10897:36;16832:4;16825:5;16821:16;16815:23;18685;16832:4;16944:3;16940:14;10897:36;17051:4;17044:5;17040:16;17034:23;17051:4;17115:3;17111:14;10897:36;17212:4;17205:5;17201:16;17195:23;17212:4;17276:3;17272:14;10897:36;27799:177;;;;:::o;27983:359::-;17627:23;;18685;10897:36;;17849:4;17838:16;;;17832:23;18685;17957:14;;;10897:36;18061:4;18050:16;;;18044:23;18685;18183:14;;;10897:36;18285:4;18274:16;;;18268:23;18685;18393:14;;;10897:36;;;;28178:3;28163:19;;28149:193::o;28349:553::-;18685:23;;10897:36;;19471:23;28888:2;28873:18;;10897:36;28614:2;28599:18;;28585:317::o;28909:760::-;19471:23;;10897:36;;18685:23;;29524:2;29509:18;;10897:36;18685:23;29655:2;29640:18;;10897:36;29250:2;29235:18;;29221:448::o;29676:222::-;10897:36;;;29803:2;29788:18;;29774:124::o;29905:333::-;10897:36;;;30224:2;30209:18;;10897:36;30060:2;30045:18;;30031:207::o;30245:256::-;30307:2;30301:9;30333:17;;;30408:18;30393:34;;30429:22;;;30390:62;30387:2;;;30465:1;;30455:12;30387:2;30307;30474:22;30285:216;;-1:-1;30285:216::o;31115:122::-;31174:16;32414:1;32404:12;;32394:2;;32420:9;32443:117;-1:-1;;;;;31384:54;;32502:35;;32492:2;;32551:1;;32541:12;32727:112;32814:1;32807:5;32804:12;32794:2;;32830:1;;32820:12

Swarm Source

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