APE Price: $1.24 (+6.83%)

Contract

0xf106816a401259D859006a35187638933Ce04B81

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x6080604046789602024-11-19 16:15:223 days ago1732032922IN
 Create: GNSPairsStorage
0 APE0.0914085825.42069

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GNSPairsStorage

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 800 runs

Other Settings:
paris EvmVersion
File 1 of 13 : GNSPairsStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "../abstract/GNSAddressStore.sol";

import "../../interfaces/libraries/IPairsStorageUtils.sol";

import "../../libraries/PairsStorageUtils.sol";

/**
 * @dev Facet #1: Pairs storage
 */
contract GNSPairsStorage is GNSAddressStore, IPairsStorageUtils {
    // Initialization

    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }

    /// @inheritdoc IPairsStorageUtils
    function initializeGroupLiquidationParams(
        IPairsStorage.GroupLiquidationParams[] memory _groupLiquidationParams
    ) external reinitializer(14) {
        PairsStorageUtils.initializeGroupLiquidationParams(_groupLiquidationParams);
    }

    /// @inheritdoc IPairsStorageUtils
    function initializeNewFees(IPairsStorage.GlobalTradeFeeParams memory _tradeFeeParams) external reinitializer(16) {
        PairsStorageUtils.initializeNewFees(_tradeFeeParams);
    }

    // Management Setters

    /// @inheritdoc IPairsStorageUtils
    function addPairs(Pair[] calldata _pairs) external onlyRole(Role.GOV) {
        PairsStorageUtils.addPairs(_pairs);
    }

    /// @inheritdoc IPairsStorageUtils
    function updatePairs(
        uint256[] calldata _pairIndices,
        Pair[] calldata _pairs
    ) external onlyRoles(Role.GOV_TIMELOCK, Role.GOV_EMERGENCY) {
        PairsStorageUtils.updatePairs(_pairIndices, _pairs);
    }

    /// @inheritdoc IPairsStorageUtils
    function addGroups(Group[] calldata _groups) external onlyRole(Role.GOV) {
        PairsStorageUtils.addGroups(_groups);
    }

    /// @inheritdoc IPairsStorageUtils
    function updateGroups(uint256[] calldata _ids, Group[] calldata _groups) external onlyRole(Role.GOV) {
        PairsStorageUtils.updateGroups(_ids, _groups);
    }

    /// @inheritdoc IPairsStorageUtils
    function addFees(FeeGroup[] calldata _fees) external onlyRole(Role.GOV) {
        PairsStorageUtils.addFees(_fees);
    }

    /// @inheritdoc IPairsStorageUtils
    function updateFees(
        uint256[] calldata _ids,
        FeeGroup[] calldata _fees
    ) external onlyRoles(Role.GOV_TIMELOCK, Role.GOV_EMERGENCY) {
        PairsStorageUtils.updateFees(_ids, _fees);
    }

    /// @inheritdoc IPairsStorageUtils
    function setGroupLiquidationParams(
        uint256 _groupIndex,
        IPairsStorage.GroupLiquidationParams memory _params
    ) external onlyRoles(Role.GOV_TIMELOCK, Role.GOV_EMERGENCY) {
        PairsStorageUtils.setGroupLiquidationParams(_groupIndex, _params);
    }

    /// @inheritdoc IPairsStorageUtils
    function setGlobalTradeFeeParams(IPairsStorage.GlobalTradeFeeParams memory _feeParams) external onlyRole(Role.GOV) {
        PairsStorageUtils.setGlobalTradeFeeParams(_feeParams);
    }

    /// @inheritdoc IPairsStorageUtils
    function setPairCustomMaxLeverages(
        uint256[] calldata _indices,
        uint256[] calldata _values
    ) external onlyRole(Role.MANAGER) {
        PairsStorageUtils.setPairCustomMaxLeverages(_indices, _values);
    }

    // Getters

    /// @inheritdoc IPairsStorageUtils
    function pairJob(uint256 _pairIndex) external view returns (string memory, string memory) {
        return PairsStorageUtils.pairJob(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function isPairListed(string calldata _from, string calldata _to) external view returns (bool) {
        return PairsStorageUtils.isPairListed(_from, _to);
    }

    /// @inheritdoc IPairsStorageUtils
    function isPairIndexListed(uint256 _pairIndex) external view returns (bool) {
        return PairsStorageUtils.isPairIndexListed(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairs(uint256 _index) external view returns (Pair memory) {
        return PairsStorageUtils.pairs(_index);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairsCount() external view returns (uint256) {
        return PairsStorageUtils.pairsCount();
    }

    /// @inheritdoc IPairsStorageUtils
    function pairSpreadP(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairSpreadP(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairMinLeverage(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairMinLeverage(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairTotalPositionSizeFeeP(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairTotalPositionSizeFeeP(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairTotalLiqCollateralFeeP(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairTotalLiqCollateralFeeP(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairOraclePositionSizeFeeP(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairOraclePositionSizeFeeP(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairMinPositionSizeUsd(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairMinPositionSizeUsd(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function getGlobalTradeFeeParams() external view returns (IPairsStorage.GlobalTradeFeeParams memory) {
        return PairsStorageUtils.getGlobalTradeFeeParams();
    }

    /// @inheritdoc IPairsStorageUtils
    function pairMinFeeUsd(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairMinFeeUsd(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function groups(uint256 _index) external view returns (Group memory) {
        return PairsStorageUtils.groups(_index);
    }

    /// @inheritdoc IPairsStorageUtils
    function groupsCount() external view returns (uint256) {
        return PairsStorageUtils.groupsCount();
    }

    /// @inheritdoc IPairsStorageUtils
    function fees(uint256 _index) external view returns (FeeGroup memory) {
        return PairsStorageUtils.fees(_index);
    }

    /// @inheritdoc IPairsStorageUtils
    function feesCount() external view returns (uint256) {
        return PairsStorageUtils.feesCount();
    }

    /// @inheritdoc IPairsStorageUtils
    function pairMaxLeverage(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairMaxLeverage(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function pairCustomMaxLeverage(uint256 _pairIndex) external view returns (uint256) {
        return PairsStorageUtils.pairCustomMaxLeverage(_pairIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function getAllPairsRestrictedMaxLeverage() external view returns (uint256[] memory) {
        return PairsStorageUtils.getAllPairsRestrictedMaxLeverage();
    }

    /// @inheritdoc IPairsStorageUtils
    function getGroupLiquidationParams(
        uint256 _groupIndex
    ) external view returns (IPairsStorage.GroupLiquidationParams memory) {
        return PairsStorageUtils.getGroupLiquidationParams(_groupIndex);
    }

    /// @inheritdoc IPairsStorageUtils
    function getPairLiquidationParams(
        uint256 _pairIndex
    ) external view returns (IPairsStorage.GroupLiquidationParams memory) {
        return PairsStorageUtils.getPairLiquidationParams(_pairIndex);
    }
}

File 2 of 13 : Initializable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.2;

import "../../utils/AddressUpgradeable.sol";

/**
 * @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 proxied contracts do not make use of 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.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * 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 {ERC1967Proxy-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.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Indicates that the contract has been initialized.
     * @custom:oz-retyped-from bool
     */
    uint8 private _initialized;

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

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint8 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
     * constructor.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        bool isTopLevelCall = !_initializing;
        require(
            (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
            "Initializable: contract is already initialized"
        );
        _initialized = 1;
        if (isTopLevelCall) {
            _initializing = true;
        }
        _;
        if (isTopLevelCall) {
            _initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: setting the version to 255 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint8 version) {
        require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
        _initialized = version;
        _initializing = true;
        _;
        _initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        require(_initializing, "Initializable: contract is not initializing");
        _;
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        require(!_initializing, "Initializable: contract is initializing");
        if (_initialized != type(uint8).max) {
            _initialized = type(uint8).max;
            emit Initialized(type(uint8).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint8) {
        return _initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _initializing;
    }
}

File 3 of 13 : AddressUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library AddressUpgradeable {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 4 of 13 : GNSAddressStore.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";

import "../../interfaces/IGNSAddressStore.sol";

/**
 * @dev Proxy base for the diamond and its facet contracts to store addresses and manage access control
 */
abstract contract GNSAddressStore is Initializable, IGNSAddressStore {
    AddressStore private addressStore;

    /// @inheritdoc IGNSAddressStore
    function initialize(address _govTimelock) external initializer {
        if (_govTimelock == address(0)) {
            revert IGeneralErrors.InitError();
        }

        _setRole(_govTimelock, Role.GOV_TIMELOCK, true);
    }

    // Addresses

    /// @inheritdoc IGNSAddressStore
    function getAddresses() external view returns (Addresses memory) {
        return addressStore.globalAddresses;
    }

    // Roles

    /// @inheritdoc IGNSAddressStore
    function hasRole(address _account, Role _role) public view returns (bool) {
        return addressStore.accessControl[_account][_role];
    }

    /// @inheritdoc IGNSAddressStore
    function hasRoles(address _account, Role _roleA, Role _roleB) public view returns (bool) {
        return addressStore.accessControl[_account][_roleA] || addressStore.accessControl[_account][_roleB];
    }

    /**
     * @dev Update role for account
     * @param _account account to update
     * @param _role role to set
     * @param _value true if allowed, false if not
     */
    function _setRole(address _account, Role _role, bool _value) internal {
        addressStore.accessControl[_account][_role] = _value;
        emit AccessControlUpdated(_account, _role, _value);
    }

    /// @inheritdoc IGNSAddressStore
    function setRoles(
        address[] calldata _accounts,
        Role[] calldata _roles,
        bool[] calldata _values
    ) external onlyRole(Role.GOV_TIMELOCK) {
        if (_accounts.length != _roles.length || _accounts.length != _values.length) {
            revert IGeneralErrors.InvalidInputLength();
        }

        for (uint256 i = 0; i < _accounts.length; ++i) {
            if (_roles[i] == Role.GOV_TIMELOCK && _accounts[i] == msg.sender) {
                revert NotAllowed();
            }

            _setRole(_accounts[i], _roles[i], _values[i]);
        }
    }

    /**
     * @dev Reverts if caller does not have role
     * @param _role role to enforce
     */
    function _enforceRole(Role _role) internal view {
        if (!hasRole(msg.sender, _role)) {
            revert WrongAccess();
        }
    }

    /**
     * @dev Reverts if caller does not have at least one of the two roles
     * @param _roleA role to enforce
     * @param _roleB role to enforce
     */
    function _enforceRoles(Role _roleA, Role _roleB) internal view {
        if (!hasRoles(msg.sender, _roleA, _roleB)) {
            revert WrongAccess();
        }
    }

    /**
     * @dev Reverts if caller does not have role
     */
    modifier onlyRole(Role _role) {
        _enforceRole(_role);
        _;
    }

    /**
     * @dev Reverts if caller does not have either of the roles
     */
    modifier onlyRoles(Role _roleA, Role _roleB) {
        _enforceRoles(_roleA, _roleB);
        _;
    }

    /**
     * @dev Reverts if caller isn't this same contract (facets calling other facets)
     */
    modifier onlySelf() {
        if (msg.sender != address(this)) {
            revert WrongAccess();
        }
        _;
    }
}

File 5 of 13 : IGeneralErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Interface for errors potentially used in all libraries (general names)
 */
interface IGeneralErrors {
    error InitError();
    error InvalidAddresses();
    error InvalidAddress();
    error InvalidInputLength();
    error InvalidCollateralIndex();
    error WrongParams();
    error WrongLength();
    error WrongOrder();
    error WrongIndex();
    error BlockOrder();
    error Overflow();
    error ZeroAddress();
    error ZeroValue();
    error AlreadyExists();
    error DoesntExist();
    error Paused();
    error BelowMin();
    error AboveMax();
    error NotAuthorized();
    error WrongTradeType();
    error WrongOrderType();
    error InsufficientBalance();
    error UnsupportedChain();
}

File 6 of 13 : IGNSAddressStore.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "./types/IAddressStore.sol";
import "./IGeneralErrors.sol";

/**
 * @dev Interface for AddressStoreUtils library
 */
interface IGNSAddressStore is IAddressStore, IGeneralErrors {
    /**
     * @dev Initializes address store facet
     * @param _rolesManager roles manager address
     */
    function initialize(address _rolesManager) external;

    /**
     * @dev Returns addresses current values
     */
    function getAddresses() external view returns (Addresses memory);

    /**
     * @dev Returns whether an account has been granted a particular role
     * @param _account account address to check
     * @param _role role to check
     */
    function hasRole(address _account, Role _role) external view returns (bool);

    /**
     * @dev Returns whether an account has been granted at least one of two roles
     * @param _account address to check
     * @param _roleA first role to check
     * @param _roleB second role to check
     */
    function hasRoles(address _account, Role _roleA, Role _roleB) external view returns (bool);

    /**
     * @dev Updates access control for a list of accounts
     * @param _accounts accounts addresses to update
     * @param _roles corresponding roles to update
     * @param _values corresponding new values to set
     */
    function setRoles(address[] calldata _accounts, Role[] calldata _roles, bool[] calldata _values) external;

    /**
     * @dev Emitted when addresses are updated
     * @param addresses new addresses values
     */
    event AddressesUpdated(Addresses addresses);

    /**
     * @dev Emitted when access control is updated for an account
     * @param target account address to update
     * @param role role to update
     * @param access whether role is granted or revoked
     */
    event AccessControlUpdated(address target, Role role, bool access);

    error NotAllowed();
    error WrongAccess();
}

File 7 of 13 : IPairsStorageUtils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "../types/IPairsStorage.sol";

/**
 * @dev Interface for GNSPairsStorage facet (inherits types and also contains functions, events, and custom errors)
 */
interface IPairsStorageUtils is IPairsStorage {
    /**
     * @dev Initializes liquidation params for all existing groups
     * @param _groupLiquidationParams liquidation params for each group (index corresponds to group index)
     */
    function initializeGroupLiquidationParams(
        IPairsStorage.GroupLiquidationParams[] memory _groupLiquidationParams
    ) external;

    /**
     * @dev Copies all existing fee groups to new mapping, multiplies existing groups min/max lev by 1e3, initializes new global trade fee params
     * @param _tradeFeeParams global trade fee params
     */
    function initializeNewFees(IPairsStorage.GlobalTradeFeeParams memory _tradeFeeParams) external;

    /**
     * @dev Adds new trading pairs
     * @param _pairs pairs to add
     */
    function addPairs(Pair[] calldata _pairs) external;

    /**
     * @dev Updates trading pairs
     * @param _pairIndices indices of pairs
     * @param _pairs new pairs values
     */
    function updatePairs(uint256[] calldata _pairIndices, Pair[] calldata _pairs) external;

    /**
     * @dev Adds new pair groups
     * @param _groups groups to add
     */
    function addGroups(Group[] calldata _groups) external;

    /**
     * @dev Updates pair groups
     * @param _ids indices of groups
     * @param _groups new groups values
     */
    function updateGroups(uint256[] calldata _ids, Group[] calldata _groups) external;

    /**
     * @dev Adds new pair fees groups
     * @param _fees fees to add
     */
    function addFees(FeeGroup[] calldata _fees) external;

    /**
     * @dev Updates pair fees groups
     * @param _ids indices of fees
     * @param _fees new fees values
     */
    function updateFees(uint256[] calldata _ids, FeeGroup[] calldata _fees) external;

    /**
     * @dev Updates pair custom max leverages (if unset group default is used); useful to delist a pair if new value is below the pair's group minLeverage
     * @param _indices indices of pairs
     * @param _values new custom max leverages (1e3 precision)
     */
    function setPairCustomMaxLeverages(uint256[] calldata _indices, uint256[] calldata _values) external;

    /**
     * @dev Updates group liquidation params (will only apply for trades opened after the change)
     * @param _groupIndex index of group
     * @param _params new liquidation params
     */
    function setGroupLiquidationParams(
        uint256 _groupIndex,
        IPairsStorage.GroupLiquidationParams memory _params
    ) external;

    /**
     * @dev Updates global trade fee params
     * @param _feeParams new fee params
     */
    function setGlobalTradeFeeParams(IPairsStorage.GlobalTradeFeeParams memory _feeParams) external;

    /**
     * @dev Returns data needed by price aggregator when doing a new price request
     * @param _pairIndex index of pair
     * @return from pair from (eg. BTC)
     * @return to pair to (eg. USD)
     */
    function pairJob(uint256 _pairIndex) external view returns (string memory from, string memory to);

    /**
     * @dev Returns whether a pair is listed
     * @param _from pair from (eg. BTC)
     * @param _to pair to (eg. USD)
     */
    function isPairListed(string calldata _from, string calldata _to) external view returns (bool);

    /**
     * @dev Returns whether a pair index is listed
     * @param _pairIndex index of pair to check
     */
    function isPairIndexListed(uint256 _pairIndex) external view returns (bool);

    /**
     * @dev Returns a pair's details
     * @param _index index of pair
     */
    function pairs(uint256 _index) external view returns (Pair memory);

    /**
     * @dev Returns number of listed pairs
     */
    function pairsCount() external view returns (uint256);

    /**
     * @dev Returns a pair's spread % (1e10 precision)
     * @param _pairIndex index of pair
     */
    function pairSpreadP(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns a pair's min leverage (1e3 precision)
     * @param _pairIndex index of pair
     */
    function pairMinLeverage(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns a pair's total position size fee % (1e10 precision)
     * @param _pairIndex index of pair
     */
    function pairTotalPositionSizeFeeP(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns a pair's total liquidation collateral fee % (1e10 precision)
     * @param _pairIndex index of pair
     */
    function pairTotalLiqCollateralFeeP(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns a pair's oracle position size fee % (1e10 precision)
     * @param _pairIndex index of pair
     */
    function pairOraclePositionSizeFeeP(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns a pair's min position size in USD (1e18 precision)
     * @param _pairIndex index of pair
     */
    function pairMinPositionSizeUsd(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns global trade fee params
     */
    function getGlobalTradeFeeParams() external view returns (IPairsStorage.GlobalTradeFeeParams memory);

    /**
     * @dev Returns a pair's minimum trading fee in USD (1e18 precision)
     * @param _pairIndex index of pair
     */
    function pairMinFeeUsd(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns a group details
     * @param _index index of group
     */
    function groups(uint256 _index) external view returns (Group memory);

    /**
     * @dev Returns number of listed groups
     */
    function groupsCount() external view returns (uint256);

    /**
     * @dev Returns a fee group details
     * @param _index index of fee group
     */
    function fees(uint256 _index) external view returns (FeeGroup memory);

    /**
     * @dev Returns number of listed fee groups
     */
    function feesCount() external view returns (uint256);

    /**
     * @dev Returns a pair's active max leverage; custom if set, otherwise group default (1e3 precision)
     * @param _pairIndex index of pair
     */
    function pairMaxLeverage(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns a pair's custom max leverage; 0 if not set (1e3 precision)
     * @param _pairIndex index of pair
     */
    function pairCustomMaxLeverage(uint256 _pairIndex) external view returns (uint256);

    /**
     * @dev Returns all listed pairs custom max leverages (1e3 precision)
     */
    function getAllPairsRestrictedMaxLeverage() external view returns (uint256[] memory);

    /**
     * @dev Returns a group's liquidation params
     */
    function getGroupLiquidationParams(
        uint256 _groupIndex
    ) external view returns (IPairsStorage.GroupLiquidationParams memory);

    /**
     * @dev Returns a pair's group liquidation params
     */
    function getPairLiquidationParams(
        uint256 _pairIndex
    ) external view returns (IPairsStorage.GroupLiquidationParams memory);

    /**
     * @dev Emitted when a new pair is listed
     * @param index index of pair
     * @param from pair from (eg. BTC)
     * @param to pair to (eg. USD)
     */
    event PairAdded(uint256 index, string from, string to);

    /**
     * @dev Emitted when a pair is updated
     * @param index index of pair
     */
    event PairUpdated(uint256 index);

    /**
     * @dev Emitted when a pair's custom max leverage is updated
     * @param index index of pair
     * @param maxLeverage new max leverage (1e3 precision)
     */
    event PairCustomMaxLeverageUpdated(uint256 indexed index, uint256 maxLeverage);

    /**
     * @dev Emitted when a new group is added
     * @param index index of group
     * @param name name of group
     */
    event GroupAdded(uint256 index, string name);

    /**
     * @dev Emitted when a group is updated
     * @param index index of group
     */
    event GroupUpdated(uint256 index);

    /**
     * @dev Emitted when a new fee group is added
     * @param index index of fee group
     * @param feeGroup fee group
     */
    event FeeAdded(uint256 index, FeeGroup feeGroup);

    /**
     * @dev Emitted when a fee group is updated
     * @param index index of fee group
     * @param feeGroup updated fee group
     */
    event FeeUpdated(uint256 index, FeeGroup feeGroup);

    /**
     * @dev Emitted when a group liquidation params are updated
     * @param index index of group
     * @param params new group liquidation params
     */
    event GroupLiquidationParamsUpdated(uint256 index, IPairsStorage.GroupLiquidationParams params);

    /**
     * @dev Emitted when global trade fee params are updated
     * @param feeParams new fee params
     */
    event GlobalTradeFeeParamsUpdated(IPairsStorage.GlobalTradeFeeParams feeParams);

    error PairNotListed();
    error GroupNotListed();
    error FeeNotListed();
    error WrongLeverages();
    error WrongFees();
    error PairAlreadyListed();
    error MaxLiqSpreadPTooHigh();
    error WrongLiqParamsThresholds();
    error WrongLiqParamsLeverages();
    error StartLiqThresholdTooHigh();
    error EndLiqThresholdTooLow();
    error StartLeverageTooLow();
    error EndLeverageTooHigh();
}

File 8 of 13 : IAddressStore.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSAddressStore facet
 */
interface IAddressStore {
    enum Role {
        GOV_TIMELOCK,
        GOV,
        MANAGER,
        GOV_EMERGENCY
    }

    struct Addresses {
        address gns;
        address gnsStaking;
        address treasury;
    }

    struct AddressStore {
        uint256 __deprecated; // previously globalAddresses (gns token only, 1 slot)
        mapping(address => mapping(Role => bool)) accessControl;
        Addresses globalAddresses;
        uint256[7] __gap1; // gap for global addresses
        // insert new storage here
        uint256[38] __gap2; // gap for rest of diamond storage
    }
}

File 9 of 13 : IPairsStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSPairsStorage facet
 */
interface IPairsStorage {
    struct PairsStorage {
        mapping(uint256 => Pair) pairs;
        mapping(uint256 => Group) groups;
        mapping(uint256 => Fee) fees; /// @custom:deprecated
        mapping(string => mapping(string => bool)) isPairListed;
        mapping(uint256 => uint256) pairCustomMaxLeverage; // 1e3 precision
        uint256 currentOrderId; /// @custom:deprecated
        uint256 pairsCount;
        uint256 groupsCount;
        uint256 feesCount;
        mapping(uint256 => GroupLiquidationParams) groupLiquidationParams;
        mapping(uint256 => FeeGroup) feeGroups;
        GlobalTradeFeeParams globalTradeFeeParams;
        uint256[38] __gap;
    }

    struct Pair {
        string from;
        string to;
        Feed feed; /// @custom:deprecated
        uint256 spreadP; // 1e10
        uint256 groupIndex;
        uint256 feeIndex;
    }

    struct Group {
        string name;
        bytes32 job; /// @custom:deprecated
        uint256 minLeverage; // 1e3 precision
        uint256 maxLeverage; // 1e3 precision
    }

    struct GlobalTradeFeeParams {
        uint24 referralFeeP; // 1e3 (%)
        uint24 govFeeP; // 1e3 (%)
        uint24 triggerOrderFeeP; // 1e3 (%)
        uint24 gnsOtcFeeP; // 1e3 (%)
        uint24 gTokenFeeP; // 1e3 (%)
        uint136 __placeholder;
    }

    struct FeeGroup {
        uint40 totalPositionSizeFeeP; // 1e10 (%)
        uint40 totalLiqCollateralFeeP; // 1e10 (%)
        uint40 oraclePositionSizeFeeP; // 1e10 (%)
        uint32 minPositionSizeUsd; // 1e3
        uint104 __placeholder;
    }

    struct TradeFees {
        uint256 totalFeeCollateral; // collateral precision
        uint256 referralFeeCollateral; // collateral precision
        uint256 govFeeCollateral; // collateral precision
        uint256 triggerOrderFeeCollateral; // collateral precision
        uint256 gnsOtcFeeCollateral; // collateral precision
        uint256 gTokenFeeCollateral; // collateral precision
    }

    struct GroupLiquidationParams {
        uint40 maxLiqSpreadP; // 1e10 (%)
        uint40 startLiqThresholdP; // 1e10 (%)
        uint40 endLiqThresholdP; // 1e10 (%)
        uint24 startLeverage; // 1e3
        uint24 endLeverage; // 1e3
    }

    // Deprecated structs
    enum FeedCalculation {
        DEFAULT,
        INVERT,
        COMBINE
    } /// @custom:deprecated
    struct Feed {
        address feed1;
        address feed2;
        FeedCalculation feedCalculation;
        uint256 maxDeviationP;
    } /// @custom:deprecated
    struct Fee {
        string name;
        uint256 openFeeP; // 1e10 (% of position size)
        uint256 closeFeeP; // 1e10 (% of position size)
        uint256 oracleFeeP; // 1e10 (% of position size)
        uint256 triggerOrderFeeP; // 1e10 (% of position size)
        uint256 minPositionSizeUsd; // 1e18 (collateral x leverage, useful for min fee)
    } /// @custom:deprecated
}

File 10 of 13 : ITradingStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "./IPairsStorage.sol";

/**
 * @dev Contains the types for the GNSTradingStorage facet
 */
interface ITradingStorage {
    struct TradingStorage {
        TradingActivated tradingActivated; // 8 bits
        uint8 lastCollateralIndex; // 8 bits
        uint240 __placeholder; // 240 bits
        mapping(uint8 => Collateral) collaterals;
        mapping(uint8 => address) gTokens;
        mapping(address => uint8) collateralIndex;
        mapping(address => mapping(uint32 => Trade)) trades;
        mapping(address => mapping(uint32 => TradeInfo)) tradeInfos;
        mapping(address => mapping(uint32 => mapping(PendingOrderType => uint256))) tradePendingOrderBlock;
        mapping(address => mapping(uint32 => PendingOrder)) pendingOrders;
        mapping(address => mapping(CounterType => Counter)) userCounters;
        address[] traders;
        mapping(address => bool) traderStored;
        mapping(address => mapping(uint32 => IPairsStorage.GroupLiquidationParams)) tradeLiquidationParams;
        uint256[38] __gap;
    }

    enum PendingOrderType {
        MARKET_OPEN,
        MARKET_CLOSE,
        LIMIT_OPEN,
        STOP_OPEN,
        TP_CLOSE,
        SL_CLOSE,
        LIQ_CLOSE,
        UPDATE_LEVERAGE,
        MARKET_PARTIAL_OPEN,
        MARKET_PARTIAL_CLOSE
    }

    enum CounterType {
        TRADE,
        PENDING_ORDER
    }

    enum TradeType {
        TRADE,
        LIMIT,
        STOP
    }

    enum TradingActivated {
        ACTIVATED,
        CLOSE_ONLY,
        PAUSED
    }

    enum ContractsVersion {
        BEFORE_V9_2,
        V9_2
    }

    struct Collateral {
        // slot 1
        address collateral; // 160 bits
        bool isActive; // 8 bits
        uint88 __placeholder; // 88 bits
        // slot 2
        uint128 precision;
        uint128 precisionDelta;
    }

    struct Id {
        address user; // 160 bits
        uint32 index; // max: 4,294,967,295
    }

    struct Trade {
        // slot 1
        address user; // 160 bits
        uint32 index; // max: 4,294,967,295
        uint16 pairIndex; // max: 65,535
        uint24 leverage; // 1e3; max: 16,777.215
        bool long; // 8 bits
        bool isOpen; // 8 bits
        uint8 collateralIndex; // max: 255
        // slot 2
        TradeType tradeType; // 8 bits
        uint120 collateralAmount; // 1e18; max: 3.402e+38
        uint64 openPrice; // 1e10; max: 1.8e19
        uint64 tp; // 1e10; max: 1.8e19
        // slot 3 (192 bits left)
        uint64 sl; // 1e10; max: 1.8e19
        uint192 __placeholder;
    }

    struct TradeInfo {
        uint32 createdBlock; // for lookbacks
        uint32 tpLastUpdatedBlock; // for lookbacks
        uint32 slLastUpdatedBlock; // for lookbacks
        uint16 maxSlippageP; // 1e3 (%)
        uint48 lastOiUpdateTs; // deprecated
        uint48 collateralPriceUsd; // 1e8 collateral price at trade open
        ContractsVersion contractsVersion;
        uint32 lastPosIncreaseBlock; // for protection close factor
        uint8 __placeholder;
    }

    struct PendingOrder {
        // slots 1-3
        Trade trade;
        // slot 4
        address user; // 160 bits
        uint32 index; // max: 4,294,967,295
        bool isOpen; // 8 bits
        PendingOrderType orderType; // 8 bits
        uint32 createdBlock; // max: 4,294,967,295
        uint16 maxSlippageP; // 1e3 (%), max: 65.535%
    }

    struct Counter {
        uint32 currentIndex;
        uint32 openCount;
        uint192 __placeholder;
    }
}

File 11 of 13 : ConstantsUtils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "../interfaces/types/ITradingStorage.sol";

/**
 *
 * @dev Internal library for important constants commonly used in many places
 */
library ConstantsUtils {
    uint256 internal constant P_10 = 1e10; // 10 decimals (DO NOT UPDATE)
    uint256 internal constant MAX_PNL_P = 100000; // 100,000% PnL (practically disabled)
    uint256 internal constant SL_LIQ_BUFFER_P = 10 * P_10; // SL has to be 10% closer than liq price
    uint256 internal constant LEGACY_LIQ_THRESHOLD_P = 90 * P_10; // -90% pnl
    uint256 internal constant MIN_LIQ_THRESHOLD_P = 50 * P_10; // -50% pnl
    uint256 internal constant MAX_OPEN_NEGATIVE_PNL_P = 40 * P_10; // -40% pnl
    uint256 internal constant MAX_LIQ_SPREAD_P = (5 * P_10) / 100; // 0.05%
    uint16 internal constant DEFAULT_MAX_CLOSING_SLIPPAGE_P = 1 * 1e3; // 1%

    function getMarketOrderTypes() internal pure returns (ITradingStorage.PendingOrderType[5] memory) {
        return [
            ITradingStorage.PendingOrderType.MARKET_OPEN,
            ITradingStorage.PendingOrderType.MARKET_CLOSE,
            ITradingStorage.PendingOrderType.UPDATE_LEVERAGE,
            ITradingStorage.PendingOrderType.MARKET_PARTIAL_OPEN,
            ITradingStorage.PendingOrderType.MARKET_PARTIAL_CLOSE
        ];
    }

    /**
     * @dev Returns pending order type (market open/limit open/stop open) for a trade type (trade/limit/stop)
     * @param _tradeType the trade type
     */
    function getPendingOpenOrderType(
        ITradingStorage.TradeType _tradeType
    ) internal pure returns (ITradingStorage.PendingOrderType) {
        return
            _tradeType == ITradingStorage.TradeType.TRADE
                ? ITradingStorage.PendingOrderType.MARKET_OPEN
                : _tradeType == ITradingStorage.TradeType.LIMIT
                ? ITradingStorage.PendingOrderType.LIMIT_OPEN
                : ITradingStorage.PendingOrderType.STOP_OPEN;
    }

    /**
     * @dev Returns true if order type is market
     * @param _orderType order type
     */
    function isOrderTypeMarket(ITradingStorage.PendingOrderType _orderType) internal pure returns (bool) {
        ITradingStorage.PendingOrderType[5] memory marketOrderTypes = ConstantsUtils.getMarketOrderTypes();
        for (uint256 i; i < marketOrderTypes.length; ++i) {
            if (_orderType == marketOrderTypes[i]) return true;
        }
        return false;
    }
}

File 12 of 13 : PairsStorageUtils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "../interfaces/libraries/IPairsStorageUtils.sol";
import "../interfaces/types/IPairsStorage.sol";
import "../interfaces/IGeneralErrors.sol";

import "./StorageUtils.sol";
import "./ConstantsUtils.sol";

/**
 * @dev GNSPairsStorage facet internal library
 */
library PairsStorageUtils {
    uint256 private constant MIN_LEVERAGE = 1.1e3; // 1.1x (1e3 precision)
    uint256 private constant MAX_LEVERAGE = 1000e3; // 1000x (1e3 precision)

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function initializeGroupLiquidationParams(
        IPairsStorage.GroupLiquidationParams[] memory _groupLiquidationParams
    ) internal {
        IPairsStorage.PairsStorage storage s = _getStorage();
        if (_groupLiquidationParams.length != s.groupsCount) revert IGeneralErrors.WrongLength();

        for (uint256 i = 0; i < _groupLiquidationParams.length; ++i) {
            setGroupLiquidationParams(i, _groupLiquidationParams[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function initializeNewFees(IPairsStorage.GlobalTradeFeeParams memory _tradeFeeParams) internal {
        IPairsStorage.PairsStorage storage s = _getStorage();

        // 1. Copy existing fees to new mapping
        uint256 existingFeesCount = s.feesCount;
        s.feesCount = 0;

        for (uint256 i = 0; i < existingFeesCount; ++i) {
            IPairsStorage.Fee memory oldFeeGroup = s.fees[i];

            _addFee(
                IPairsStorage.FeeGroup(
                    uint40(oldFeeGroup.openFeeP * 2 + oldFeeGroup.triggerOrderFeeP),
                    uint40(10 * ConstantsUtils.P_10),
                    uint40(oldFeeGroup.oracleFeeP),
                    uint32((oldFeeGroup.minPositionSizeUsd * 1e3) / 1e18),
                    0
                )
            );
        }

        // 2. Multiply existing groups min/max lev by 1e3
        for (uint256 i = 0; i < s.groupsCount; ++i) {
            IPairsStorage.Group storage oldGroup = s.groups[i];
            oldGroup.minLeverage *= 1e3;
            oldGroup.maxLeverage *= 1e3;
        }

        // 3. Global trade fee params
        setGlobalTradeFeeParams(_tradeFeeParams);
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function addPairs(IPairsStorage.Pair[] calldata _pairs) internal {
        for (uint256 i = 0; i < _pairs.length; ++i) {
            _addPair(_pairs[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function updatePairs(uint256[] calldata _pairIndices, IPairsStorage.Pair[] calldata _pairs) internal {
        if (_pairIndices.length != _pairs.length) revert IGeneralErrors.WrongLength();

        for (uint256 i = 0; i < _pairs.length; ++i) {
            _updatePair(_pairIndices[i], _pairs[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function addGroups(IPairsStorage.Group[] calldata _groups) internal {
        for (uint256 i = 0; i < _groups.length; ++i) {
            _addGroup(_groups[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function updateGroups(uint256[] calldata _ids, IPairsStorage.Group[] calldata _groups) internal {
        if (_ids.length != _groups.length) revert IGeneralErrors.WrongLength();

        for (uint256 i = 0; i < _groups.length; ++i) {
            _updateGroup(_ids[i], _groups[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function addFees(IPairsStorage.FeeGroup[] memory _fees) internal {
        for (uint256 i = 0; i < _fees.length; ++i) {
            _addFee(_fees[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function updateFees(uint256[] calldata _ids, IPairsStorage.FeeGroup[] memory _fees) internal {
        if (_ids.length != _fees.length) revert IGeneralErrors.WrongLength();

        for (uint256 i = 0; i < _fees.length; ++i) {
            _updateFee(_ids[i], _fees[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function setPairCustomMaxLeverages(uint256[] calldata _indices, uint256[] calldata _values) internal {
        if (_indices.length != _values.length) revert IGeneralErrors.WrongLength();

        IPairsStorage.PairsStorage storage s = _getStorage();

        for (uint256 i; i < _indices.length; ++i) {
            s.pairCustomMaxLeverage[_indices[i]] = _values[i];

            emit IPairsStorageUtils.PairCustomMaxLeverageUpdated(_indices[i], _values[i]);
        }
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function setGroupLiquidationParams(
        uint256 _groupIndex,
        IPairsStorage.GroupLiquidationParams memory _params
    ) internal groupListed(_groupIndex) {
        IPairsStorage.PairsStorage storage s = _getStorage();

        if (
            _params.maxLiqSpreadP == 0 ||
            _params.startLiqThresholdP == 0 ||
            _params.endLiqThresholdP == 0 ||
            _params.startLeverage == 0 ||
            _params.endLeverage == 0
        ) revert IGeneralErrors.ZeroValue();

        if (_params.maxLiqSpreadP > ConstantsUtils.MAX_LIQ_SPREAD_P) revert IPairsStorageUtils.MaxLiqSpreadPTooHigh();

        if (_params.startLiqThresholdP < _params.endLiqThresholdP) revert IPairsStorageUtils.WrongLiqParamsThresholds();
        if (_params.startLiqThresholdP > ConstantsUtils.LEGACY_LIQ_THRESHOLD_P)
            revert IPairsStorageUtils.StartLiqThresholdTooHigh();
        if (_params.endLiqThresholdP < ConstantsUtils.MIN_LIQ_THRESHOLD_P)
            revert IPairsStorageUtils.EndLiqThresholdTooLow();

        if (_params.startLeverage > _params.endLeverage) revert IPairsStorageUtils.WrongLiqParamsLeverages();
        if (_params.startLeverage < groups(_groupIndex).minLeverage) revert IPairsStorageUtils.StartLeverageTooLow();
        if (_params.endLeverage > groups(_groupIndex).maxLeverage) revert IPairsStorageUtils.EndLeverageTooHigh();

        s.groupLiquidationParams[_groupIndex] = _params;

        emit IPairsStorageUtils.GroupLiquidationParamsUpdated(_groupIndex, _params);
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function setGlobalTradeFeeParams(IPairsStorage.GlobalTradeFeeParams memory _feeParams) internal {
        if (
            _feeParams.referralFeeP == 0 ||
            _feeParams.govFeeP == 0 ||
            _feeParams.triggerOrderFeeP == 0 ||
            _feeParams.gnsOtcFeeP == 0 ||
            _feeParams.gTokenFeeP == 0 ||
            _feeParams.__placeholder != 0
        ) revert IGeneralErrors.ZeroValue();

        if (
            _feeParams.referralFeeP +
                _feeParams.govFeeP +
                _feeParams.triggerOrderFeeP +
                _feeParams.gnsOtcFeeP +
                _feeParams.gTokenFeeP !=
            100 * 1e3
        ) revert IGeneralErrors.WrongParams();

        _getStorage().globalTradeFeeParams = _feeParams;

        emit IPairsStorageUtils.GlobalTradeFeeParamsUpdated(_feeParams);
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairJob(uint256 _pairIndex) internal view returns (string memory, string memory) {
        IPairsStorage.PairsStorage storage s = _getStorage();

        IPairsStorage.Pair storage p = s.pairs[_pairIndex];
        if (!s.isPairListed[p.from][p.to]) revert IPairsStorageUtils.PairNotListed();

        return (p.from, p.to);
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function isPairListed(string calldata _from, string calldata _to) internal view returns (bool) {
        return _getStorage().isPairListed[_from][_to];
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function isPairIndexListed(uint256 _pairIndex) internal view returns (bool) {
        return _pairIndex < _getStorage().pairsCount;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairs(uint256 _index) internal view returns (IPairsStorage.Pair storage) {
        return _getStorage().pairs[_index];
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairsCount() internal view returns (uint256) {
        return _getStorage().pairsCount;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairSpreadP(uint256 _pairIndex) internal view returns (uint256) {
        return pairs(_pairIndex).spreadP;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairMinLeverage(uint256 _pairIndex) internal view returns (uint256) {
        return groups(pairs(_pairIndex).groupIndex).minLeverage;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairTotalPositionSizeFeeP(uint256 _pairIndex) internal view returns (uint256) {
        return fees(pairs(_pairIndex).feeIndex).totalPositionSizeFeeP;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairTotalLiqCollateralFeeP(uint256 _pairIndex) internal view returns (uint256) {
        return fees(pairs(_pairIndex).feeIndex).totalLiqCollateralFeeP;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairOraclePositionSizeFeeP(uint256 _pairIndex) internal view returns (uint256) {
        return fees(pairs(_pairIndex).feeIndex).oraclePositionSizeFeeP;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairMinPositionSizeUsd(uint256 _pairIndex) internal view returns (uint256) {
        return (uint256(fees(pairs(_pairIndex).feeIndex).minPositionSizeUsd) * 1e18) / 1e3;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function getGlobalTradeFeeParams() internal view returns (IPairsStorage.GlobalTradeFeeParams memory) {
        return _getStorage().globalTradeFeeParams;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairMinFeeUsd(uint256 _pairIndex) internal view returns (uint256) {
        return (pairMinPositionSizeUsd(_pairIndex) * pairTotalPositionSizeFeeP(_pairIndex)) / ConstantsUtils.P_10 / 100;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairFeeIndex(uint256 _pairIndex) internal view returns (uint256) {
        return _getStorage().pairs[_pairIndex].feeIndex;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function groups(uint256 _index) internal view returns (IPairsStorage.Group storage) {
        return _getStorage().groups[_index];
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function groupsCount() internal view returns (uint256) {
        return _getStorage().groupsCount;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function fees(uint256 _index) internal view returns (IPairsStorage.FeeGroup memory) {
        return _getStorage().feeGroups[_index];
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function feesCount() internal view returns (uint256) {
        return _getStorage().feesCount;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairMaxLeverage(uint256 _pairIndex) internal view returns (uint256) {
        IPairsStorage.PairsStorage storage s = _getStorage();

        uint256 maxLeverage = s.pairCustomMaxLeverage[_pairIndex];
        return maxLeverage > 0 ? maxLeverage : s.groups[s.pairs[_pairIndex].groupIndex].maxLeverage;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function pairCustomMaxLeverage(uint256 _pairIndex) internal view returns (uint256) {
        return _getStorage().pairCustomMaxLeverage[_pairIndex];
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function getAllPairsRestrictedMaxLeverage() internal view returns (uint256[] memory) {
        uint256[] memory lev = new uint256[](pairsCount());

        for (uint256 i; i < lev.length; ++i) {
            lev[i] = pairCustomMaxLeverage(i);
        }

        return lev;
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function getGroupLiquidationParams(
        uint256 _groupIndex
    ) internal view returns (IPairsStorage.GroupLiquidationParams memory) {
        return _getStorage().groupLiquidationParams[_groupIndex];
    }

    /**
     * @dev Check IPairsStorageUtils interface for documentation
     */
    function getPairLiquidationParams(
        uint256 _pairIndex
    ) internal view returns (IPairsStorage.GroupLiquidationParams memory) {
        return _getStorage().groupLiquidationParams[pairs(_pairIndex).groupIndex];
    }

    /**
     * @dev Returns storage slot to use when fetching storage relevant to library
     */
    function _getSlot() internal pure returns (uint256) {
        return StorageUtils.GLOBAL_PAIRS_STORAGE_SLOT;
    }

    /**
     * @dev Returns storage pointer for storage struct in diamond contract, at defined slot
     */
    function _getStorage() internal pure returns (IPairsStorage.PairsStorage storage s) {
        uint256 storageSlot = _getSlot();
        assembly {
            s.slot := storageSlot
        }
    }

    /**
     * Reverts if group is not listed
     * @param _groupIndex group index to check
     */
    modifier groupListed(uint256 _groupIndex) {
        if (_getStorage().groups[_groupIndex].minLeverage == 0) revert IPairsStorageUtils.GroupNotListed();
        _;
    }

    /**
     * Reverts if fee is not listed
     * @param _feeIndex fee index to check
     */
    modifier feeListed(uint256 _feeIndex) {
        if (_getStorage().feeGroups[_feeIndex].totalPositionSizeFeeP == 0) revert IPairsStorageUtils.FeeNotListed();
        _;
    }

    /**
     * Reverts if group is not valid
     * @param _group group to check
     */
    modifier groupOk(IPairsStorage.Group calldata _group) {
        if (
            _group.minLeverage < MIN_LEVERAGE ||
            _group.maxLeverage > MAX_LEVERAGE ||
            _group.minLeverage >= _group.maxLeverage
        ) revert IPairsStorageUtils.WrongLeverages();
        _;
    }

    /**
     * @dev Reverts if fee is not valid
     * @param _fee fee to check
     */
    modifier feeOk(IPairsStorage.FeeGroup memory _fee) {
        if (
            _fee.totalPositionSizeFeeP == 0 ||
            _fee.totalLiqCollateralFeeP == 0 ||
            _fee.oraclePositionSizeFeeP == 0 ||
            _fee.oraclePositionSizeFeeP > _fee.totalPositionSizeFeeP ||
            _fee.minPositionSizeUsd == 0 ||
            _fee.__placeholder != 0
        ) revert IPairsStorageUtils.WrongFees();
        _;
    }

    /**
     * @dev Adds a new trading pair
     * @param _pair pair to add
     */
    function _addPair(
        IPairsStorage.Pair calldata _pair
    ) internal groupListed(_pair.groupIndex) feeListed(_pair.feeIndex) {
        IPairsStorage.PairsStorage storage s = _getStorage();
        if (s.isPairListed[_pair.from][_pair.to]) revert IPairsStorageUtils.PairAlreadyListed();

        s.pairs[s.pairsCount] = _pair;
        s.isPairListed[_pair.from][_pair.to] = true;

        emit IPairsStorageUtils.PairAdded(s.pairsCount++, _pair.from, _pair.to);
    }

    /**
     * @dev Updates an existing trading pair
     * @param _pairIndex index of pair to update
     * @param _pair new pair value
     */
    function _updatePair(
        uint256 _pairIndex,
        IPairsStorage.Pair calldata _pair
    ) internal groupListed(_pair.groupIndex) feeListed(_pair.feeIndex) {
        IPairsStorage.PairsStorage storage s = _getStorage();

        IPairsStorage.Pair storage p = s.pairs[_pairIndex];
        if (!s.isPairListed[p.from][p.to]) revert IPairsStorageUtils.PairNotListed();

        p.feed = _pair.feed;
        p.spreadP = _pair.spreadP;
        p.groupIndex = _pair.groupIndex;
        p.feeIndex = _pair.feeIndex;

        emit IPairsStorageUtils.PairUpdated(_pairIndex);
    }

    /**
     * @dev Adds a new pair group
     * @param _group group to add
     */
    function _addGroup(IPairsStorage.Group calldata _group) internal groupOk(_group) {
        IPairsStorage.PairsStorage storage s = _getStorage();
        s.groups[s.groupsCount] = _group;

        emit IPairsStorageUtils.GroupAdded(s.groupsCount++, _group.name);
    }

    /**
     * @dev Updates an existing pair group
     * @param _id index of group to update
     * @param _group new group value
     */
    function _updateGroup(uint256 _id, IPairsStorage.Group calldata _group) internal groupListed(_id) groupOk(_group) {
        _getStorage().groups[_id] = _group;

        emit IPairsStorageUtils.GroupUpdated(_id);
    }

    /**
     * @dev Adds a new pair fee group
     * @param _fee fee to add
     */
    function _addFee(IPairsStorage.FeeGroup memory _fee) internal feeOk(_fee) {
        IPairsStorage.PairsStorage storage s = _getStorage();
        s.feeGroups[s.feesCount] = _fee;

        emit IPairsStorageUtils.FeeAdded(s.feesCount++, _fee);
    }

    /**
     * @dev Updates an existing pair fee group
     * @param _id index of fee to update
     * @param _fee new fee value
     */
    function _updateFee(uint256 _id, IPairsStorage.FeeGroup memory _fee) internal feeListed(_id) feeOk(_fee) {
        _getStorage().feeGroups[_id] = _fee;

        emit IPairsStorageUtils.FeeUpdated(_id, _fee);
    }
}

File 13 of 13 : StorageUtils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 *
 * @dev Internal library to manage storage slots of GNSMultiCollatDiamond contract diamond storage structs.
 *
 * BE EXTREMELY CAREFUL, DO NOT EDIT THIS WITHOUT A GOOD REASON
 *
 */
library StorageUtils {
    uint256 internal constant GLOBAL_ADDRESSES_SLOT = 3;
    uint256 internal constant GLOBAL_PAIRS_STORAGE_SLOT = 51;
    uint256 internal constant GLOBAL_REFERRALS_SLOT = 101;
    uint256 internal constant GLOBAL_FEE_TIERS_SLOT = 151;
    uint256 internal constant GLOBAL_PRICE_IMPACT_SLOT = 201;
    uint256 internal constant GLOBAL_DIAMOND_SLOT = 251;
    uint256 internal constant GLOBAL_TRADING_STORAGE_SLOT = 301;
    uint256 internal constant GLOBAL_TRIGGER_REWARDS_SLOT = 351;
    uint256 internal constant GLOBAL_TRADING_SLOT = 401;
    uint256 internal constant GLOBAL_TRADING_CALLBACKS_SLOT = 451;
    uint256 internal constant GLOBAL_BORROWING_FEES_SLOT = 501;
    uint256 internal constant GLOBAL_PRICE_AGGREGATOR_SLOT = 551;
    uint256 internal constant GLOBAL_OTC_SLOT = 601;
    uint256 internal constant GLOBAL_CHAIN_CONFIG_SLOT = 651;
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "evmVersion": "paris",
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AboveMax","type":"error"},{"inputs":[],"name":"AlreadyExists","type":"error"},{"inputs":[],"name":"BelowMin","type":"error"},{"inputs":[],"name":"BlockOrder","type":"error"},{"inputs":[],"name":"DoesntExist","type":"error"},{"inputs":[],"name":"EndLeverageTooHigh","type":"error"},{"inputs":[],"name":"EndLiqThresholdTooLow","type":"error"},{"inputs":[],"name":"FeeNotListed","type":"error"},{"inputs":[],"name":"GroupNotListed","type":"error"},{"inputs":[],"name":"InitError","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAddresses","type":"error"},{"inputs":[],"name":"InvalidCollateralIndex","type":"error"},{"inputs":[],"name":"InvalidInputLength","type":"error"},{"inputs":[],"name":"MaxLiqSpreadPTooHigh","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"Overflow","type":"error"},{"inputs":[],"name":"PairAlreadyListed","type":"error"},{"inputs":[],"name":"PairNotListed","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"StartLeverageTooLow","type":"error"},{"inputs":[],"name":"StartLiqThresholdTooHigh","type":"error"},{"inputs":[],"name":"UnsupportedChain","type":"error"},{"inputs":[],"name":"WrongAccess","type":"error"},{"inputs":[],"name":"WrongFees","type":"error"},{"inputs":[],"name":"WrongIndex","type":"error"},{"inputs":[],"name":"WrongLength","type":"error"},{"inputs":[],"name":"WrongLeverages","type":"error"},{"inputs":[],"name":"WrongLiqParamsLeverages","type":"error"},{"inputs":[],"name":"WrongLiqParamsThresholds","type":"error"},{"inputs":[],"name":"WrongOrder","type":"error"},{"inputs":[],"name":"WrongOrderType","type":"error"},{"inputs":[],"name":"WrongParams","type":"error"},{"inputs":[],"name":"WrongTradeType","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroValue","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"enum IAddressStore.Role","name":"role","type":"uint8"},{"indexed":false,"internalType":"bool","name":"access","type":"bool"}],"name":"AccessControlUpdated","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"gns","type":"address"},{"internalType":"address","name":"gnsStaking","type":"address"},{"internalType":"address","name":"treasury","type":"address"}],"indexed":false,"internalType":"struct IAddressStore.Addresses","name":"addresses","type":"tuple"}],"name":"AddressesUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"components":[{"internalType":"uint40","name":"totalPositionSizeFeeP","type":"uint40"},{"internalType":"uint40","name":"totalLiqCollateralFeeP","type":"uint40"},{"internalType":"uint40","name":"oraclePositionSizeFeeP","type":"uint40"},{"internalType":"uint32","name":"minPositionSizeUsd","type":"uint32"},{"internalType":"uint104","name":"__placeholder","type":"uint104"}],"indexed":false,"internalType":"struct IPairsStorage.FeeGroup","name":"feeGroup","type":"tuple"}],"name":"FeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"components":[{"internalType":"uint40","name":"totalPositionSizeFeeP","type":"uint40"},{"internalType":"uint40","name":"totalLiqCollateralFeeP","type":"uint40"},{"internalType":"uint40","name":"oraclePositionSizeFeeP","type":"uint40"},{"internalType":"uint32","name":"minPositionSizeUsd","type":"uint32"},{"internalType":"uint104","name":"__placeholder","type":"uint104"}],"indexed":false,"internalType":"struct IPairsStorage.FeeGroup","name":"feeGroup","type":"tuple"}],"name":"FeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint24","name":"referralFeeP","type":"uint24"},{"internalType":"uint24","name":"govFeeP","type":"uint24"},{"internalType":"uint24","name":"triggerOrderFeeP","type":"uint24"},{"internalType":"uint24","name":"gnsOtcFeeP","type":"uint24"},{"internalType":"uint24","name":"gTokenFeeP","type":"uint24"},{"internalType":"uint136","name":"__placeholder","type":"uint136"}],"indexed":false,"internalType":"struct IPairsStorage.GlobalTradeFeeParams","name":"feeParams","type":"tuple"}],"name":"GlobalTradeFeeParamsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"GroupAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"components":[{"internalType":"uint40","name":"maxLiqSpreadP","type":"uint40"},{"internalType":"uint40","name":"startLiqThresholdP","type":"uint40"},{"internalType":"uint40","name":"endLiqThresholdP","type":"uint40"},{"internalType":"uint24","name":"startLeverage","type":"uint24"},{"internalType":"uint24","name":"endLeverage","type":"uint24"}],"indexed":false,"internalType":"struct IPairsStorage.GroupLiquidationParams","name":"params","type":"tuple"}],"name":"GroupLiquidationParamsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"GroupUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"string","name":"from","type":"string"},{"indexed":false,"internalType":"string","name":"to","type":"string"}],"name":"PairAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"maxLeverage","type":"uint256"}],"name":"PairCustomMaxLeverageUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"PairUpdated","type":"event"},{"inputs":[{"components":[{"internalType":"uint40","name":"totalPositionSizeFeeP","type":"uint40"},{"internalType":"uint40","name":"totalLiqCollateralFeeP","type":"uint40"},{"internalType":"uint40","name":"oraclePositionSizeFeeP","type":"uint40"},{"internalType":"uint32","name":"minPositionSizeUsd","type":"uint32"},{"internalType":"uint104","name":"__placeholder","type":"uint104"}],"internalType":"struct IPairsStorage.FeeGroup[]","name":"_fees","type":"tuple[]"}],"name":"addFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes32","name":"job","type":"bytes32"},{"internalType":"uint256","name":"minLeverage","type":"uint256"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"}],"internalType":"struct IPairsStorage.Group[]","name":"_groups","type":"tuple[]"}],"name":"addGroups","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string","name":"from","type":"string"},{"internalType":"string","name":"to","type":"string"},{"components":[{"internalType":"address","name":"feed1","type":"address"},{"internalType":"address","name":"feed2","type":"address"},{"internalType":"enum IPairsStorage.FeedCalculation","name":"feedCalculation","type":"uint8"},{"internalType":"uint256","name":"maxDeviationP","type":"uint256"}],"internalType":"struct IPairsStorage.Feed","name":"feed","type":"tuple"},{"internalType":"uint256","name":"spreadP","type":"uint256"},{"internalType":"uint256","name":"groupIndex","type":"uint256"},{"internalType":"uint256","name":"feeIndex","type":"uint256"}],"internalType":"struct IPairsStorage.Pair[]","name":"_pairs","type":"tuple[]"}],"name":"addPairs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"fees","outputs":[{"components":[{"internalType":"uint40","name":"totalPositionSizeFeeP","type":"uint40"},{"internalType":"uint40","name":"totalLiqCollateralFeeP","type":"uint40"},{"internalType":"uint40","name":"oraclePositionSizeFeeP","type":"uint40"},{"internalType":"uint32","name":"minPositionSizeUsd","type":"uint32"},{"internalType":"uint104","name":"__placeholder","type":"uint104"}],"internalType":"struct IPairsStorage.FeeGroup","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feesCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAddresses","outputs":[{"components":[{"internalType":"address","name":"gns","type":"address"},{"internalType":"address","name":"gnsStaking","type":"address"},{"internalType":"address","name":"treasury","type":"address"}],"internalType":"struct IAddressStore.Addresses","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllPairsRestrictedMaxLeverage","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGlobalTradeFeeParams","outputs":[{"components":[{"internalType":"uint24","name":"referralFeeP","type":"uint24"},{"internalType":"uint24","name":"govFeeP","type":"uint24"},{"internalType":"uint24","name":"triggerOrderFeeP","type":"uint24"},{"internalType":"uint24","name":"gnsOtcFeeP","type":"uint24"},{"internalType":"uint24","name":"gTokenFeeP","type":"uint24"},{"internalType":"uint136","name":"__placeholder","type":"uint136"}],"internalType":"struct IPairsStorage.GlobalTradeFeeParams","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_groupIndex","type":"uint256"}],"name":"getGroupLiquidationParams","outputs":[{"components":[{"internalType":"uint40","name":"maxLiqSpreadP","type":"uint40"},{"internalType":"uint40","name":"startLiqThresholdP","type":"uint40"},{"internalType":"uint40","name":"endLiqThresholdP","type":"uint40"},{"internalType":"uint24","name":"startLeverage","type":"uint24"},{"internalType":"uint24","name":"endLeverage","type":"uint24"}],"internalType":"struct IPairsStorage.GroupLiquidationParams","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"getPairLiquidationParams","outputs":[{"components":[{"internalType":"uint40","name":"maxLiqSpreadP","type":"uint40"},{"internalType":"uint40","name":"startLiqThresholdP","type":"uint40"},{"internalType":"uint40","name":"endLiqThresholdP","type":"uint40"},{"internalType":"uint24","name":"startLeverage","type":"uint24"},{"internalType":"uint24","name":"endLeverage","type":"uint24"}],"internalType":"struct IPairsStorage.GroupLiquidationParams","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"groups","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes32","name":"job","type":"bytes32"},{"internalType":"uint256","name":"minLeverage","type":"uint256"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"}],"internalType":"struct IPairsStorage.Group","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"groupsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"enum IAddressStore.Role","name":"_role","type":"uint8"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"enum IAddressStore.Role","name":"_roleA","type":"uint8"},{"internalType":"enum IAddressStore.Role","name":"_roleB","type":"uint8"}],"name":"hasRoles","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_govTimelock","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint40","name":"maxLiqSpreadP","type":"uint40"},{"internalType":"uint40","name":"startLiqThresholdP","type":"uint40"},{"internalType":"uint40","name":"endLiqThresholdP","type":"uint40"},{"internalType":"uint24","name":"startLeverage","type":"uint24"},{"internalType":"uint24","name":"endLeverage","type":"uint24"}],"internalType":"struct IPairsStorage.GroupLiquidationParams[]","name":"_groupLiquidationParams","type":"tuple[]"}],"name":"initializeGroupLiquidationParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint24","name":"referralFeeP","type":"uint24"},{"internalType":"uint24","name":"govFeeP","type":"uint24"},{"internalType":"uint24","name":"triggerOrderFeeP","type":"uint24"},{"internalType":"uint24","name":"gnsOtcFeeP","type":"uint24"},{"internalType":"uint24","name":"gTokenFeeP","type":"uint24"},{"internalType":"uint136","name":"__placeholder","type":"uint136"}],"internalType":"struct IPairsStorage.GlobalTradeFeeParams","name":"_tradeFeeParams","type":"tuple"}],"name":"initializeNewFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"isPairIndexListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_from","type":"string"},{"internalType":"string","name":"_to","type":"string"}],"name":"isPairListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairCustomMaxLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairJob","outputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairMaxLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairMinFeeUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairMinLeverage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairMinPositionSizeUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairOraclePositionSizeFeeP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairSpreadP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairTotalLiqCollateralFeeP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pairIndex","type":"uint256"}],"name":"pairTotalPositionSizeFeeP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"pairs","outputs":[{"components":[{"internalType":"string","name":"from","type":"string"},{"internalType":"string","name":"to","type":"string"},{"components":[{"internalType":"address","name":"feed1","type":"address"},{"internalType":"address","name":"feed2","type":"address"},{"internalType":"enum IPairsStorage.FeedCalculation","name":"feedCalculation","type":"uint8"},{"internalType":"uint256","name":"maxDeviationP","type":"uint256"}],"internalType":"struct IPairsStorage.Feed","name":"feed","type":"tuple"},{"internalType":"uint256","name":"spreadP","type":"uint256"},{"internalType":"uint256","name":"groupIndex","type":"uint256"},{"internalType":"uint256","name":"feeIndex","type":"uint256"}],"internalType":"struct IPairsStorage.Pair","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint24","name":"referralFeeP","type":"uint24"},{"internalType":"uint24","name":"govFeeP","type":"uint24"},{"internalType":"uint24","name":"triggerOrderFeeP","type":"uint24"},{"internalType":"uint24","name":"gnsOtcFeeP","type":"uint24"},{"internalType":"uint24","name":"gTokenFeeP","type":"uint24"},{"internalType":"uint136","name":"__placeholder","type":"uint136"}],"internalType":"struct IPairsStorage.GlobalTradeFeeParams","name":"_feeParams","type":"tuple"}],"name":"setGlobalTradeFeeParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_groupIndex","type":"uint256"},{"components":[{"internalType":"uint40","name":"maxLiqSpreadP","type":"uint40"},{"internalType":"uint40","name":"startLiqThresholdP","type":"uint40"},{"internalType":"uint40","name":"endLiqThresholdP","type":"uint40"},{"internalType":"uint24","name":"startLeverage","type":"uint24"},{"internalType":"uint24","name":"endLeverage","type":"uint24"}],"internalType":"struct IPairsStorage.GroupLiquidationParams","name":"_params","type":"tuple"}],"name":"setGroupLiquidationParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_indices","type":"uint256[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"}],"name":"setPairCustomMaxLeverages","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"},{"internalType":"enum IAddressStore.Role[]","name":"_roles","type":"uint8[]"},{"internalType":"bool[]","name":"_values","type":"bool[]"}],"name":"setRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"components":[{"internalType":"uint40","name":"totalPositionSizeFeeP","type":"uint40"},{"internalType":"uint40","name":"totalLiqCollateralFeeP","type":"uint40"},{"internalType":"uint40","name":"oraclePositionSizeFeeP","type":"uint40"},{"internalType":"uint32","name":"minPositionSizeUsd","type":"uint32"},{"internalType":"uint104","name":"__placeholder","type":"uint104"}],"internalType":"struct IPairsStorage.FeeGroup[]","name":"_fees","type":"tuple[]"}],"name":"updateFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"bytes32","name":"job","type":"bytes32"},{"internalType":"uint256","name":"minLeverage","type":"uint256"},{"internalType":"uint256","name":"maxLeverage","type":"uint256"}],"internalType":"struct IPairsStorage.Group[]","name":"_groups","type":"tuple[]"}],"name":"updateGroups","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pairIndices","type":"uint256[]"},{"components":[{"internalType":"string","name":"from","type":"string"},{"internalType":"string","name":"to","type":"string"},{"components":[{"internalType":"address","name":"feed1","type":"address"},{"internalType":"address","name":"feed2","type":"address"},{"internalType":"enum IPairsStorage.FeedCalculation","name":"feedCalculation","type":"uint8"},{"internalType":"uint256","name":"maxDeviationP","type":"uint256"}],"internalType":"struct IPairsStorage.Feed","name":"feed","type":"tuple"},{"internalType":"uint256","name":"spreadP","type":"uint256"},{"internalType":"uint256","name":"groupIndex","type":"uint256"},{"internalType":"uint256","name":"feeIndex","type":"uint256"}],"internalType":"struct IPairsStorage.Pair[]","name":"_pairs","type":"tuple[]"}],"name":"updatePairs","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b613f9a80620000f36000396000f3fe608060405234801561001057600080fd5b50600436106102925760003560e01c80636633ced611610160578063b81b2b71116100d8578063c927b4b61161008c578063d79261fd11610071578063d79261fd14610643578063db7c3f9d14610656578063fbf3f9111461066957600080fd5b8063c927b4b61461061d578063d0cb753e1461063057600080fd5b8063b9c97229116100bd578063b9c97229146105e4578063c4d66de8146105f7578063c85ac7481461060a57600080fd5b8063b81b2b71146105bc578063b91ac788146105c457600080fd5b8063885e27501161012f57806396324bd41161011457806396324bd414610504578063a1d54e9b14610524578063a39fac121461053757600080fd5b8063885e2750146104e957806395a8c58d146104f157600080fd5b80636633ced61461049b578063678b3fb0146104ae5780638078bfbe146104c357806385d4390e146104d657600080fd5b8063281b7ead1161020e57806359a992d0116101c25780635f57a073116101a75780635f57a0731461046d57806360283cba14610480578063658de48a1461049357600080fd5b806359a992d0146104475780635e26ff4e1461045a57600080fd5b80633572929c116101f35780633572929c1461039b57806348fc3ef3146103bb5780634acc79ed1461042757600080fd5b8063281b7ead14610367578063302f81fc1461037a57600080fd5b806311d79ef5116102655780631cf71b9b1161024a5780631cf71b9b1461032e57806324a9686514610341578063281b693c1461035457600080fd5b806311d79ef5146102f85780631628bfeb1461030b57600080fd5b80630cf34255146102975780630e5c75af146102bd578063101e6503146102d257806310efa5d5146102e5575b600080fd5b6102aa6102a5366004612e90565b61067c565b6040519081526020015b60405180910390f35b6102d06102cb366004612ef5565b61068d565b005b6102d06102e0366004612f7c565b6106f8565b6102d06102f3366004613016565b61085d565b6102d0610306366004613016565b61087f565b61031e6103193660046130c4565b61089d565b60405190151581526020016102b4565b6102d061033c366004613124565b6108b4565b6102aa61034f366004612e90565b61091f565b6102aa610362366004612e90565b61092a565b61031e610375366004612e90565b610935565b61038d610388366004612e90565b610940565b6040516102b49291906131ca565b6103ae6103a9366004612e90565b610955565b6040516102b491906131ef565b6103c3610989565b6040516102b49190600060c08201905062ffffff808451168352806020850151166020840152806040850151166040840152806060850151166060840152806080850151166080840152506001600160881b0360a08401511660a083015292915050565b61043a610435366004612e90565b6109c8565b6040516102b49190613240565b6102aa610455366004612e90565b6109fc565b6102aa610468366004612e90565b610a07565b6102d061047b366004613323565b610a12565b6102d061048e3660046133d0565b610a2a565b6102aa610a3f565b6103ae6104a9366004612e90565b610a49565b6104b6610a7d565b6040516102b49190613406565b6102aa6104d1366004612e90565b610a87565b6102d06104e43660046134d0565b610a92565b6102aa610b7f565b61031e6104ff3660046135a4565b610b89565b610517610512366004612e90565b610be0565b6040516102b491906135d9565b6102aa610532366004612e90565b610cd9565b61058a604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b03908116825260208085015182169083015292820151909216908201526060016102b4565b6102aa610ce4565b6105d76105d2366004612e90565b610cee565b6040516102b49190613635565b61031e6105f23660046136e7565b610edc565b6102d061060536600461372c565b610f8d565b6102d0610618366004613323565b6110c3565b6102aa61062b366004612e90565b611165565b6102d061063e366004613749565b611170565b6102d0610651366004613016565b61118e565b6102d06106643660046133d0565b6111a5565b6102aa610677366004612e90565b6111ba565b6000610687826111c5565b92915050565b6001610698816111ed565b6106f38383808060200260200160405190810160405280939291908181526020016000905b828210156106e9576106da60a0830286013681900381019061376d565b815260200190600101906106bd565b5050505050611217565b505050565b6000610703816111ed565b85841415806107125750858214155b1561073057604051637db491eb60e01b815260040160405180910390fd5b60005b8681101561085357600086868381811061074f5761074f6137fc565b90506020020160208101906107649190613812565b60038111156107755761077561361f565b1480156107b0575033888883818110610790576107906137fc565b90506020020160208101906107a5919061372c565b6001600160a01b0316145b156107ce57604051631eb49d6d60e11b815260040160405180910390fd5b61084b8888838181106107e3576107e36137fc565b90506020020160208101906107f8919061372c565b87878481811061080a5761080a6137fc565b905060200201602081019061081f9190613812565b868685818110610831576108316137fc565b9050602002016020810190610846919061382d565b61124d565b600101610733565b5050505050505050565b6000600361086b82826112ef565b61087786868686611317565b505050505050565b600161088a816111ed565b6108968585858561138f565b5050505050565b60006108ab85858585611407565b95945050505050565b600060036108c282826112ef565b61087786868686808060200260200160405190810160405280939291908181526020016000905b828210156109155761090660a0830286013681900381019061376d565b815260200190600101906108e9565b505050505061145f565b6000610687826114cf565b6000610687826114ed565b600061068782611542565b60608061094c83611558565b91509150915091565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261068782611705565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526109c36117a7565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261068782611862565b600061068782611911565b600061068782611932565b6001610a1d816111ed565b610a2682611969565b5050565b6001610a35816111ed565b6106f38383611bc7565b60006109c3611c06565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261068782611c19565b60606109c3611cd1565b600061068782611d61565b600054600e90610100900460ff16158015610ab4575060005460ff8083169116105b610b1c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055610b3982611d91565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b60006109c3611df9565b6001600160a01b038216600090815260026020526040812081836003811115610bb457610bb461361f565b6003811115610bc557610bc561361f565b815260208101919091526040016000205460ff169392505050565b610c0e6040518060800160405280606081526020016000801916815260200160008152602001600081525090565b610c1782611e0c565b604051806080016040529081600082018054610c329061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e9061384f565b8015610cab5780601f10610c8057610100808354040283529160200191610cab565b820191906000526020600020905b815481529060010190602001808311610c8e57829003601f168201915b5050505050815260200160018201548152602001600282015481526020016003820154815250509050919050565b600061068782611e29565b60006109c3611e3e565b610cf6612e31565b610cff82611e51565b6040518060c0016040529081600082018054610d1a9061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054610d469061384f565b8015610d935780601f10610d6857610100808354040283529160200191610d93565b820191906000526020600020905b815481529060010190602001808311610d7657829003601f168201915b50505050508152602001600182018054610dac9061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd89061384f565b8015610e255780601f10610dfa57610100808354040283529160200191610e25565b820191906000526020600020905b815481529060010190602001808311610e0857829003601f168201915b505050918352505060408051608081018252600284810180546001600160a01b03908116845260038701549081166020808601919091529095019492939092908401917401000000000000000000000000000000000000000090910460ff1690811115610e9457610e9461361f565b6002811115610ea557610ea561361f565b8152602001600282015481525050815260200160058201548152602001600682015481526020016007820154815250509050919050565b6001600160a01b038316600090815260026020526040812081846003811115610f0757610f0761361f565b6003811115610f1857610f1861361f565b815260208101919091526040016000205460ff1680610f8357506001600160a01b038416600090815260026020526040812090836003811115610f5d57610f5d61361f565b6003811115610f6e57610f6e61361f565b815260208101919091526040016000205460ff165b90505b9392505050565b600054610100900460ff1615808015610fad5750600054600160ff909116105b80610fc75750303b158015610fc7575060005460ff166001145b61102a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b13565b6000805460ff19166001179055801561104d576000805461ff0019166101001790555b6001600160a01b03821661107457604051632c1c702960e21b815260040160405180910390fd5b611081826000600161124d565b8015610a26576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610b73565b600054601090610100900460ff161580156110e5575060005460ff8083169116105b6111485760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b13565b6000805461ffff191660ff831617610100179055610b3982611e6b565b600061068782612082565b6000600361117e82826112ef565b611188848461209e565b50505050565b6002611199816111ed565b610896858585856123fe565b60016111b0816111ed565b6106f383836124f1565b600061068782612530565b60006111dc6111d383611e51565b60070154611862565b6040015164ffffffffff1692915050565b6111f73382610b89565b61121457604051631b17ff5560e21b815260040160405180910390fd5b50565b60005b8151811015610a2657611245828281518110611238576112386137fc565b602002602001015161254f565b60010161121a565b6001600160a01b038316600090815260026020526040812082918460038111156112795761127961361f565b600381111561128a5761128a61361f565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d8383836040516112e293929190613883565b60405180910390a1505050565b6112fa338383610edc565b610a2657604051631b17ff5560e21b815260040160405180910390fd5b828114611337576040516349552d5960e11b815260040160405180910390fd5b60005b8181101561089657611387858583818110611357576113576137fc565b90506020020135848484818110611370576113706137fc565b905060200281019061138291906138b9565b612719565b60010161133a565b8281146113af576040516349552d5960e11b815260040160405180910390fd5b60005b81811015610896576113ff8585838181106113cf576113cf6137fc565b905060200201358484848181106113e8576113e86137fc565b90506020028101906113fa91906138da565b61288f565b6001016113b2565b6000611411612970565b60030185856040516114249291906138f0565b908152602001604051809103902083836040516114429291906138f0565b9081526040519081900360200190205460ff169050949350505050565b80518214611480576040516349552d5960e11b815260040160405180910390fd5b60005b8151811015611188576114c78484838181106114a1576114a16137fc565b905060200201358383815181106114ba576114ba6137fc565b602002602001015161297a565b600101611483565b60006114d9612970565b600092835260040160205250604090205490565b6000806114f8612970565b600084815260048201602052604090205490915080611538576000848152602083815260408083206006015483526001850190915290206003015461153a565b805b949350505050565b600061154c612970565b60060154909110919050565b6060806000611565612970565b60008581526020829052604090819020905191925090600383019061158b908390613900565b9081526020016040518091039020816001016040516115aa9190613900565b9081526040519081900360200190205460ff166115da576040516323d1634160e01b815260040160405180910390fd5b80600001816001018180546115ee9061384f565b80601f016020809104026020016040519081016040528092919081815260200182805461161a9061384f565b80156116675780601f1061163c57610100808354040283529160200191611667565b820191906000526020600020905b81548152906001019060200180831161164a57829003601f168201915b5050505050915080805461167a9061384f565b80601f01602080910402602001604051908101604052809291908181526020018280546116a69061384f565b80156116f35780601f106116c8576101008083540402835291602001916116f3565b820191906000526020600020905b8154815290600101906020018083116116d657829003601f168201915b50505050509050935093505050915091565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611738612970565b60009283526009016020908152604092839020835160a081018552905464ffffffffff8082168352650100000000008204811693830193909352600160501b81049092169381019390935262ffffff600160781b820481166060850152600160901b9091041660808301525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526117e1612970565b6040805160c081018252600b929092015462ffffff808216845263010000008204811660208501526601000000000000820481169284019290925269010000000000000000008104821660608401526c0100000000000000000000000081049091166080830152600160781b90046001600160881b031660a0820152919050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611895612970565b6000928352600a016020908152604092839020835160a081018552905464ffffffffff8082168352650100000000008204811693830193909352600160501b810490921693810193909352600160781b810463ffffffff166060840152600160981b90046cffffffffffffffffffffffffff1660808301525090565b600061192861191f83611e51565b60060154611e0c565b6002015492915050565b60006103e86119436111d384611e51565b6060015161195f9063ffffffff16670de0b6b3a764000061398c565b61068791906139a3565b805162ffffff1615806119835750602081015162ffffff16155b806119955750604081015162ffffff16155b806119a75750606081015162ffffff16155b806119b95750608081015162ffffff16155b806119d0575060a08101516001600160881b031615155b156119ee57604051637c946ed760e01b815260040160405180910390fd5b60808101516060820151604083015160208401518451611a0e91906139c5565b611a1891906139c5565b611a2291906139c5565b611a2c91906139c5565b62ffffff16620186a014611a5357604051635863f78960e01b815260040160405180910390fd5b80611a5c612970565b8151600b91909101805460208401516040808601516060870151608088015160a0909801516001600160881b0316600160781b026effffffffffffffffffffffffffffff62ffffff998a166c0100000000000000000000000002166bffffffffffffffffffffffff928a166901000000000000000000026bffffff00000000000000000019948b16660100000000000002949094166bffffffffffff00000000000019968b1663010000000265ffffffffffff199098169a9099169990991795909517939093169590951794909417169390931792909217909155517fbbd4d37e525bc0d0bf80d0c56879b81ebcccbe7bfd22e484e19eb0f369c011a490611bbc908390600060c08201905062ffffff808451168352806020850151166020840152806040850151166040840152806060850151166060840152806080850151166080840152506001600160881b0360a08401511660a083015292915050565b60405180910390a150565b60005b818110156106f357611bfe838383818110611be757611be76137fc565b9050602002810190611bf991906138da565b612b6c565b600101611bca565b6000611c10612970565b60080154905090565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c4c612970565b6009016000611c5a84611e51565b6006015481526020808201929092526040908101600020815160a081018352905464ffffffffff8082168352650100000000008204811694830194909452600160501b81049093169181019190915262ffffff600160781b830481166060830152600160901b909204909116608082015292915050565b60606000611cdd611e3e565b67ffffffffffffffff811115611cf557611cf561329b565b604051908082528060200260200182016040528015611d1e578160200160208202803683370190505b50905060005b8151811015611d5b57611d36816114cf565b828281518110611d4857611d486137fc565b6020908102919091010152600101611d24565b50919050565b600060646402540be400611d7484612082565b611d7d85611932565b611d87919061398c565b61195f91906139a3565b6000611d9b612970565b90508060070154825114611dc2576040516349552d5960e11b815260040160405180910390fd5b60005b82518110156106f357611df181848381518110611de457611de46137fc565b602002602001015161209e565b600101611dc5565b6000611e03612970565b60070154905090565b6000611e16612970565b6000928352600101602052506040902090565b6000611e3482611e51565b6005015492915050565b6000611e48612970565b60060154905090565b6000611e5b612970565b6000928352602052506040902090565b6000611e75612970565b6008810180546000918290559192505b81811015612016576000818152600284016020526040808220815160c08101909252805482908290611eb69061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054611ee29061384f565b8015611f2f5780601f10611f0457610100808354040283529160200191611f2f565b820191906000526020600020905b815481529060010190602001808311611f1257829003601f168201915b5050505050815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481525050905061200d6040518060a00160405280836080015184602001516002611f90919061398c565b611f9a91906139e8565b64ffffffffff168152602001611fb66402540be400600a61398c565b64ffffffffff168152602001836060015164ffffffffff168152602001670de0b6b3a76400008460a001516103e8611fee919061398c565b611ff891906139a3565b63ffffffff168152600060209091015261254f565b50600101611e85565b5060005b8260070154811015612078576000818152600184016020526040812060028101805491926103e89261204d90849061398c565b925050819055506103e881600301600082825461206a919061398c565b90915550505060010161201a565b506106f383611969565b60006120906111d383611e51565b5164ffffffffff1692915050565b816120a7612970565b6000828152600191909101602052604081206002015490036120dc5760405163252e058d60e21b815260040160405180910390fd5b60006120e6612970565b835190915064ffffffffff1615806121075750602083015164ffffffffff16155b8061211b5750604083015164ffffffffff16155b8061212d5750606083015162ffffff16155b8061213f5750608083015162ffffff16155b1561215d57604051637c946ed760e01b815260040160405180910390fd5b606461216f6402540be400600561398c565b61217991906139a3565b835164ffffffffff1611156121a15760405163cd1049ff60e01b815260040160405180910390fd5b826040015164ffffffffff16836020015164ffffffffff1610156121d857604051630bedb6fd60e01b815260040160405180910390fd5b6121e86402540be400605a61398c565b836020015164ffffffffff16111561221357604051635b99296f60e01b815260040160405180910390fd5b6122236402540be400603261398c565b836040015164ffffffffff16101561224e576040516321b5730d60e01b815260040160405180910390fd5b826080015162ffffff16836060015162ffffff1611156122815760405163a1d0527960e01b815260040160405180910390fd5b61228a84611e0c565b60020154836060015162ffffff1610156122b75760405163a3d1c4d160e01b815260040160405180910390fd5b6122c084611e0c565b60030154836080015162ffffff1611156122ed57604051636588aba360e11b815260040160405180910390fd5b6000848152600982016020908152604091829020855181549287015187850151606089015160808a015164ffffffffff94851669ffffffffffffffffffff199097169690961765010000000000938516939093029290921771ffffffffffffffff000000000000000000001916600160501b939091169290920271ffffff000000000000000000000000000000191691909117600160781b62ffffff92831602177fffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffff16600160901b9190931602919091179055517f7e8e79d406657a52635b68c3f3ad15d2526e71077df1b40afad9d323eacbabfc906123f090869086906139fb565b60405180910390a150505050565b82811461241e576040516349552d5960e11b815260040160405180910390fd5b6000612428612970565b905060005b8481101561087757838382818110612447576124476137fc565b90506020020135826004016000888885818110612466576124666137fc565b90506020020135815260200190815260200160002081905550858582818110612491576124916137fc565b905060200201357f5d6c9d6dd6c84fa315e799a455ccb71230e5b88e171c48c4853425ce044e9bce8585848181106124cb576124cb6137fc565b905060200201356040516124e191815260200190565b60405180910390a260010161242d565b60005b818110156106f357612528838383818110612511576125116137fc565b905060200281019061252391906138b9565b612c38565b6001016124f4565b600061253e6111d383611e51565b6020015164ffffffffff1692915050565b8051819064ffffffffff16158061256f5750602081015164ffffffffff16155b806125835750604081015164ffffffffff16155b806125a35750806000015164ffffffffff16816040015164ffffffffff16115b806125b65750606081015163ffffffff16155b806125d3575060808101516cffffffffffffffffffffffffff1615155b156125f157604051630352e4ef60e21b815260040160405180910390fd5b60006125fb612970565b6008810180546000908152600a83016020908152604080832088518154938a0151928a015160608b015160808c01516cffffffffffffffffffffffffff16600160981b0272ffffffffffffffffffffffffffffffffffffff63ffffffff909216600160781b0272ffffffff0000000000000000000000000000001964ffffffffff948516600160501b021672ffffffffffffffffff0000000000000000000019978516650100000000000269ffffffffffffffffffff199099169490951693909317969096179490941691909117179190911691909117905581549293507f13b1e39f208d3f600b2dfd43c294bc9fb9518d7b57f027fdb0572d8a84cee27892919061270683613a52565b91905055846040516112e2929190613a6b565b8060e00135612726612970565b60008281526001919091016020526040812060020154900361275b5760405163252e058d60e21b815260040160405180910390fd5b816101000135612769612970565b6000828152600a91909101602052604081205464ffffffffff1690036127a25760405163490b7f1160e11b815260040160405180910390fd5b60006127ac612970565b6000868152602082905260409081902090519192509060038301906127d2908390613900565b9081526020016040518091039020816001016040516127f19190613900565b9081526040519081900360200190205460ff16612821576040516323d1634160e01b815260040160405180910390fd5b60408501600282016128338282613acc565b505060c0850135600582015560e0850135600682015561010085013560078201556040518681527f123a1b961ae93e7acda9790b318237b175b45ac09277cd3614305d8baa3f19539060200160405180910390a1505050505050565b81612898612970565b6000828152600191909101602052604081206002015490036128cd5760405163252e058d60e21b815260040160405180910390fd5b8161044c816040013510806128e85750620f42408160600135115b806128fb57508060600135816040013510155b156129195760405163523ae9c760e01b815260040160405180910390fd5b82612922612970565b60008681526001919091016020526040902061293e8282613cec565b50506040518481527fcfde8f228364c70f12cbbac5a88fc91ceca76dd750ac93364991a333b34afb8e906020016123f0565b6000806033610687565b81612983612970565b6000828152600a91909101602052604081205464ffffffffff1690036129bc5760405163490b7f1160e11b815260040160405180910390fd5b8151829064ffffffffff1615806129dc5750602081015164ffffffffff16155b806129f05750604081015164ffffffffff16155b80612a105750806000015164ffffffffff16816040015164ffffffffff16115b80612a235750606081015163ffffffff16155b80612a40575060808101516cffffffffffffffffffffffffff1615155b15612a5e57604051630352e4ef60e21b815260040160405180910390fd5b82612a67612970565b6000868152600a91909101602090815260409182902083518154928501518585015160608701516080909701516cffffffffffffffffffffffffff16600160981b0272ffffffffffffffffffffffffffffffffffffff63ffffffff909816600160781b0272ffffffff0000000000000000000000000000001964ffffffffff938416600160501b021672ffffffffffffffffff0000000000000000000019948416650100000000000269ffffffffffffffffffff199098169390951692909217959095179190911691909117179390931617909155517fb38258bbe4602eb8456888a284ddf8f9f9acc06f4699fce677ddd34941ed35cb906123f09086908690613a6b565b8061044c81604001351080612b875750620f42408160600135115b80612b9a57508060600135816040013510155b15612bb85760405163523ae9c760e01b815260040160405180910390fd5b6000612bc2612970565b6007810154600090815260018201602052604090209091508390612be68282613cec565b50506007810180547faf17de8e82beccc440012117a600dc37e26925225d0f1ee192fc107eb3dcbca4916000612c1b83613a52565b90915550612c298580613b9d565b6040516112e293929190613dff565b8060e00135612c45612970565b600082815260019190910160205260408120600201549003612c7a5760405163252e058d60e21b815260040160405180910390fd5b816101000135612c88612970565b6000828152600a91909101602052604081205464ffffffffff169003612cc15760405163490b7f1160e11b815260040160405180910390fd5b6000612ccb612970565b905060038101612cdb8580613b9d565b604051612ce99291906138f0565b9081526020016040518091039020848060200190612d079190613b9d565b604051612d159291906138f0565b9081526040519081900360200190205460ff1615612d46576040516392214ba360e01b815260040160405180910390fd5b600681015460009081526020829052604090208490612d658282613e19565b506001905060038201612d788680613b9d565b604051612d869291906138f0565b9081526020016040518091039020858060200190612da49190613b9d565b604051612db29291906138f0565b908152604051908190036020019020805491151560ff199092169190911790556006810180547f3adfd40f2b74073df2a84238acdb7f460565a557b3cc13bddc8833289bf38e09916000612e0583613a52565b90915550612e138680613b9d565b612e206020890189613b9d565b6040516123f0959493929190613f2b565b6040518060c001604052806060815260200160608152602001612e756040805160808101825260008082526020820181905290918201908152602001600081525090565b81526020016000815260200160008152602001600081525090565b600060208284031215612ea257600080fd5b5035919050565b60008083601f840112612ebb57600080fd5b50813567ffffffffffffffff811115612ed357600080fd5b60208301915083602060a083028501011115612eee57600080fd5b9250929050565b60008060208385031215612f0857600080fd5b823567ffffffffffffffff811115612f1f57600080fd5b612f2b85828601612ea9565b90969095509350505050565b60008083601f840112612f4957600080fd5b50813567ffffffffffffffff811115612f6157600080fd5b6020830191508360208260051b8501011115612eee57600080fd5b60008060008060008060608789031215612f9557600080fd5b863567ffffffffffffffff80821115612fad57600080fd5b612fb98a838b01612f37565b90985096506020890135915080821115612fd257600080fd5b612fde8a838b01612f37565b90965094506040890135915080821115612ff757600080fd5b5061300489828a01612f37565b979a9699509497509295939492505050565b6000806000806040858703121561302c57600080fd5b843567ffffffffffffffff8082111561304457600080fd5b61305088838901612f37565b9096509450602087013591508082111561306957600080fd5b5061307687828801612f37565b95989497509550505050565b60008083601f84011261309457600080fd5b50813567ffffffffffffffff8111156130ac57600080fd5b602083019150836020828501011115612eee57600080fd5b600080600080604085870312156130da57600080fd5b843567ffffffffffffffff808211156130f257600080fd5b6130fe88838901613082565b9096509450602087013591508082111561311757600080fd5b5061307687828801613082565b6000806000806040858703121561313a57600080fd5b843567ffffffffffffffff8082111561315257600080fd5b61315e88838901612f37565b9096509450602087013591508082111561317757600080fd5b5061307687828801612ea9565b6000815180845260005b818110156131aa5760208185018101518683018201520161318e565b506000602082860101526020601f19601f83011685010191505092915050565b6040815260006131dd6040830185613184565b82810360208401526108ab8185613184565b60a08101610687828464ffffffffff80825116835280602083015116602084015280604083015116604084015250606081015162ffffff808216606085015280608084015116608085015250505050565b60a08101610687828464ffffffffff8082511683528060208301511660208401528060408301511660408401525063ffffffff60608201511660608301526cffffffffffffffffffffffffff60808201511660808301525050565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156132d4576132d461329b565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156133035761330361329b565b604052919050565b803562ffffff8116811461331e57600080fd5b919050565b600060c0828403121561333557600080fd5b60405160c0810181811067ffffffffffffffff821117156133585761335861329b565b6040526133648361330b565b81526133726020840161330b565b60208201526133836040840161330b565b60408201526133946060840161330b565b60608201526133a56080840161330b565b608082015260a08301356001600160881b03811681146133c457600080fd5b60a08201529392505050565b600080602083850312156133e357600080fd5b823567ffffffffffffffff8111156133fa57600080fd5b612f2b85828601612f37565b6020808252825182820181905260009190848201906040850190845b8181101561343e57835183529284019291840191600101613422565b50909695505050505050565b803564ffffffffff8116811461331e57600080fd5b600060a0828403121561347157600080fd5b6134796132b1565b90506134848261344a565b81526134926020830161344a565b60208201526134a36040830161344a565b60408201526134b46060830161330b565b60608201526134c56080830161330b565b608082015292915050565b600060208083850312156134e357600080fd5b823567ffffffffffffffff808211156134fb57600080fd5b818501915085601f83011261350f57600080fd5b8135818111156135215761352161329b565b61352f848260051b016132da565b818152848101925060a091820284018501918883111561354e57600080fd5b938501935b8285101561357457613565898661345f565b84529384019392850192613553565b50979650505050505050565b6001600160a01b038116811461121457600080fd5b80356004811061331e57600080fd5b600080604083850312156135b757600080fd5b82356135c281613580565b91506135d060208401613595565b90509250929050565b6020815260008251608060208401526135f560a0840182613184565b90506020840151604084015260408401516060840152606084015160808401528091505092915050565b634e487b7160e01b600052602160045260246000fd5b6020815260008251610120806020850152613654610140850183613184565b91506020850151601f198584030160408601526136718382613184565b92505060408501516001600160a01b03808251166060870152806020830151166080870152506040810151600381106136ac576136ac61361f565b8060a087015250606081015160c086015250606085015160e0850152608085015161010085015260a085015181850152508091505092915050565b6000806000606084860312156136fc57600080fd5b833561370781613580565b925061371560208501613595565b915061372360408501613595565b90509250925092565b60006020828403121561373e57600080fd5b8135610f8681613580565b60008060c0838503121561375c57600080fd5b823591506135d0846020850161345f565b600060a0828403121561377f57600080fd5b6137876132b1565b6137908361344a565b815261379e6020840161344a565b60208201526137af6040840161344a565b6040820152606083013563ffffffff811681146137cb57600080fd5b606082015260808301356cffffffffffffffffffffffffff811681146137f057600080fd5b60808201529392505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561382457600080fd5b610f8682613595565b60006020828403121561383f57600080fd5b81358015158114610f8657600080fd5b600181811c9082168061386357607f821691505b602082108103611d5b57634e487b7160e01b600052602260045260246000fd5b6001600160a01b038416815260608101600484106138a3576138a361361f565b8360208301528215156040830152949350505050565b6000823561011e198336030181126138d057600080fd5b9190910192915050565b60008235607e198336030181126138d057600080fd5b8183823760009101908152919050565b600080835461390e8161384f565b60018281168015613926576001811461393b5761396a565b60ff198416875282151583028701945061396a565b8760005260208060002060005b858110156139615781548a820152908401908201613948565b50505082870194505b50929695505050505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761068757610687613976565b6000826139c057634e487b7160e01b600052601260045260246000fd5b500490565b62ffffff8181168382160190808211156139e1576139e1613976565b5092915050565b8082018082111561068757610687613976565b82815260c08101610f86602083018464ffffffffff80825116835280602083015116602084015280604083015116604084015250606081015162ffffff808216606085015280608084015116608085015250505050565b600060018201613a6457613a64613976565b5060010190565b82815260c08101610f86602083018464ffffffffff8082511683528060208301511660208401528060408301511660408401525063ffffffff60608201511660608301526cffffffffffffffffffffffffff60808201511660808301525050565b8135613ad781613580565b815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03821617825550600181016020830135613b1081613580565b815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03821617825550604083013560038110613b4957600080fd5b815474ff00000000000000000000000000000000000000008260a01b167fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8216178355505050606082013560028201555050565b6000808335601e19843603018112613bb457600080fd5b83018035915067ffffffffffffffff821115613bcf57600080fd5b602001915036819003821315612eee57600080fd5b601f8211156106f3576000816000526020600020601f850160051c81016020861015613c0d5750805b601f850160051c820191505b8181101561087757828155600101613c19565b67ffffffffffffffff831115613c4457613c4461329b565b613c5883613c52835461384f565b83613be4565b6000601f841160018114613c8c5760008515613c745750838201355b600019600387901b1c1916600186901b178355610896565b600083815260209020601f19861690835b82811015613cbd5786850135825560209485019460019092019101613c9d565b5086821015613cda5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b613cf68283613b9d565b67ffffffffffffffff811115613d0e57613d0e61329b565b613d2281613d1c855461384f565b85613be4565b6000601f821160018114613d565760008315613d3e5750838201355b600019600385901b1c1916600184901b178555613db0565b600085815260209020601f19841690835b82811015613d875786850135825560209485019460019092019101613d67565b5084821015613da45760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506020820135600182015560408201356002820155606082013560038201555050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8381526040602082015260006108ab604083018486613dd6565b613e238283613b9d565b67ffffffffffffffff811115613e3b57613e3b61329b565b613e4981613d1c855461384f565b6000601f821160018114613e7d5760008315613e655750838201355b600019600385901b1c1916600184901b178555613ed7565b600085815260209020601f19841690835b82811015613eae5786850135825560209485019460019092019101613e8e565b5084821015613ecb5760001960f88660031b161c19848701351681555b505060018360011b0185555b50505050613ee86020830183613b9d565b613ef6818360018601613c2c565b5050613f086040830160028301613acc565b60c0820135600582015560e0820135600682015561010082013560078201555050565b858152606060208201526000613f45606083018688613dd6565b8281036040840152613f58818587613dd6565b9897505050505050505056fea26469706673582212202122d231ec59d3ccbab58401ad55b4a8149f1f966a86d71a3ee150f17881f5b564736f6c63430008170033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102925760003560e01c80636633ced611610160578063b81b2b71116100d8578063c927b4b61161008c578063d79261fd11610071578063d79261fd14610643578063db7c3f9d14610656578063fbf3f9111461066957600080fd5b8063c927b4b61461061d578063d0cb753e1461063057600080fd5b8063b9c97229116100bd578063b9c97229146105e4578063c4d66de8146105f7578063c85ac7481461060a57600080fd5b8063b81b2b71146105bc578063b91ac788146105c457600080fd5b8063885e27501161012f57806396324bd41161011457806396324bd414610504578063a1d54e9b14610524578063a39fac121461053757600080fd5b8063885e2750146104e957806395a8c58d146104f157600080fd5b80636633ced61461049b578063678b3fb0146104ae5780638078bfbe146104c357806385d4390e146104d657600080fd5b8063281b7ead1161020e57806359a992d0116101c25780635f57a073116101a75780635f57a0731461046d57806360283cba14610480578063658de48a1461049357600080fd5b806359a992d0146104475780635e26ff4e1461045a57600080fd5b80633572929c116101f35780633572929c1461039b57806348fc3ef3146103bb5780634acc79ed1461042757600080fd5b8063281b7ead14610367578063302f81fc1461037a57600080fd5b806311d79ef5116102655780631cf71b9b1161024a5780631cf71b9b1461032e57806324a9686514610341578063281b693c1461035457600080fd5b806311d79ef5146102f85780631628bfeb1461030b57600080fd5b80630cf34255146102975780630e5c75af146102bd578063101e6503146102d257806310efa5d5146102e5575b600080fd5b6102aa6102a5366004612e90565b61067c565b6040519081526020015b60405180910390f35b6102d06102cb366004612ef5565b61068d565b005b6102d06102e0366004612f7c565b6106f8565b6102d06102f3366004613016565b61085d565b6102d0610306366004613016565b61087f565b61031e6103193660046130c4565b61089d565b60405190151581526020016102b4565b6102d061033c366004613124565b6108b4565b6102aa61034f366004612e90565b61091f565b6102aa610362366004612e90565b61092a565b61031e610375366004612e90565b610935565b61038d610388366004612e90565b610940565b6040516102b49291906131ca565b6103ae6103a9366004612e90565b610955565b6040516102b491906131ef565b6103c3610989565b6040516102b49190600060c08201905062ffffff808451168352806020850151166020840152806040850151166040840152806060850151166060840152806080850151166080840152506001600160881b0360a08401511660a083015292915050565b61043a610435366004612e90565b6109c8565b6040516102b49190613240565b6102aa610455366004612e90565b6109fc565b6102aa610468366004612e90565b610a07565b6102d061047b366004613323565b610a12565b6102d061048e3660046133d0565b610a2a565b6102aa610a3f565b6103ae6104a9366004612e90565b610a49565b6104b6610a7d565b6040516102b49190613406565b6102aa6104d1366004612e90565b610a87565b6102d06104e43660046134d0565b610a92565b6102aa610b7f565b61031e6104ff3660046135a4565b610b89565b610517610512366004612e90565b610be0565b6040516102b491906135d9565b6102aa610532366004612e90565b610cd9565b61058a604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b03908116825260208085015182169083015292820151909216908201526060016102b4565b6102aa610ce4565b6105d76105d2366004612e90565b610cee565b6040516102b49190613635565b61031e6105f23660046136e7565b610edc565b6102d061060536600461372c565b610f8d565b6102d0610618366004613323565b6110c3565b6102aa61062b366004612e90565b611165565b6102d061063e366004613749565b611170565b6102d0610651366004613016565b61118e565b6102d06106643660046133d0565b6111a5565b6102aa610677366004612e90565b6111ba565b6000610687826111c5565b92915050565b6001610698816111ed565b6106f38383808060200260200160405190810160405280939291908181526020016000905b828210156106e9576106da60a0830286013681900381019061376d565b815260200190600101906106bd565b5050505050611217565b505050565b6000610703816111ed565b85841415806107125750858214155b1561073057604051637db491eb60e01b815260040160405180910390fd5b60005b8681101561085357600086868381811061074f5761074f6137fc565b90506020020160208101906107649190613812565b60038111156107755761077561361f565b1480156107b0575033888883818110610790576107906137fc565b90506020020160208101906107a5919061372c565b6001600160a01b0316145b156107ce57604051631eb49d6d60e11b815260040160405180910390fd5b61084b8888838181106107e3576107e36137fc565b90506020020160208101906107f8919061372c565b87878481811061080a5761080a6137fc565b905060200201602081019061081f9190613812565b868685818110610831576108316137fc565b9050602002016020810190610846919061382d565b61124d565b600101610733565b5050505050505050565b6000600361086b82826112ef565b61087786868686611317565b505050505050565b600161088a816111ed565b6108968585858561138f565b5050505050565b60006108ab85858585611407565b95945050505050565b600060036108c282826112ef565b61087786868686808060200260200160405190810160405280939291908181526020016000905b828210156109155761090660a0830286013681900381019061376d565b815260200190600101906108e9565b505050505061145f565b6000610687826114cf565b6000610687826114ed565b600061068782611542565b60608061094c83611558565b91509150915091565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261068782611705565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526109c36117a7565b905090565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261068782611862565b600061068782611911565b600061068782611932565b6001610a1d816111ed565b610a2682611969565b5050565b6001610a35816111ed565b6106f38383611bc7565b60006109c3611c06565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915261068782611c19565b60606109c3611cd1565b600061068782611d61565b600054600e90610100900460ff16158015610ab4575060005460ff8083169116105b610b1c5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff831617610100179055610b3982611d91565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a15050565b60006109c3611df9565b6001600160a01b038216600090815260026020526040812081836003811115610bb457610bb461361f565b6003811115610bc557610bc561361f565b815260208101919091526040016000205460ff169392505050565b610c0e6040518060800160405280606081526020016000801916815260200160008152602001600081525090565b610c1782611e0c565b604051806080016040529081600082018054610c329061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e9061384f565b8015610cab5780601f10610c8057610100808354040283529160200191610cab565b820191906000526020600020905b815481529060010190602001808311610c8e57829003601f168201915b5050505050815260200160018201548152602001600282015481526020016003820154815250509050919050565b600061068782611e29565b60006109c3611e3e565b610cf6612e31565b610cff82611e51565b6040518060c0016040529081600082018054610d1a9061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054610d469061384f565b8015610d935780601f10610d6857610100808354040283529160200191610d93565b820191906000526020600020905b815481529060010190602001808311610d7657829003601f168201915b50505050508152602001600182018054610dac9061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd89061384f565b8015610e255780601f10610dfa57610100808354040283529160200191610e25565b820191906000526020600020905b815481529060010190602001808311610e0857829003601f168201915b505050918352505060408051608081018252600284810180546001600160a01b03908116845260038701549081166020808601919091529095019492939092908401917401000000000000000000000000000000000000000090910460ff1690811115610e9457610e9461361f565b6002811115610ea557610ea561361f565b8152602001600282015481525050815260200160058201548152602001600682015481526020016007820154815250509050919050565b6001600160a01b038316600090815260026020526040812081846003811115610f0757610f0761361f565b6003811115610f1857610f1861361f565b815260208101919091526040016000205460ff1680610f8357506001600160a01b038416600090815260026020526040812090836003811115610f5d57610f5d61361f565b6003811115610f6e57610f6e61361f565b815260208101919091526040016000205460ff165b90505b9392505050565b600054610100900460ff1615808015610fad5750600054600160ff909116105b80610fc75750303b158015610fc7575060005460ff166001145b61102a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b13565b6000805460ff19166001179055801561104d576000805461ff0019166101001790555b6001600160a01b03821661107457604051632c1c702960e21b815260040160405180910390fd5b611081826000600161124d565b8015610a26576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610b73565b600054601090610100900460ff161580156110e5575060005460ff8083169116105b6111485760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610b13565b6000805461ffff191660ff831617610100179055610b3982611e6b565b600061068782612082565b6000600361117e82826112ef565b611188848461209e565b50505050565b6002611199816111ed565b610896858585856123fe565b60016111b0816111ed565b6106f383836124f1565b600061068782612530565b60006111dc6111d383611e51565b60070154611862565b6040015164ffffffffff1692915050565b6111f73382610b89565b61121457604051631b17ff5560e21b815260040160405180910390fd5b50565b60005b8151811015610a2657611245828281518110611238576112386137fc565b602002602001015161254f565b60010161121a565b6001600160a01b038316600090815260026020526040812082918460038111156112795761127961361f565b600381111561128a5761128a61361f565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d8383836040516112e293929190613883565b60405180910390a1505050565b6112fa338383610edc565b610a2657604051631b17ff5560e21b815260040160405180910390fd5b828114611337576040516349552d5960e11b815260040160405180910390fd5b60005b8181101561089657611387858583818110611357576113576137fc565b90506020020135848484818110611370576113706137fc565b905060200281019061138291906138b9565b612719565b60010161133a565b8281146113af576040516349552d5960e11b815260040160405180910390fd5b60005b81811015610896576113ff8585838181106113cf576113cf6137fc565b905060200201358484848181106113e8576113e86137fc565b90506020028101906113fa91906138da565b61288f565b6001016113b2565b6000611411612970565b60030185856040516114249291906138f0565b908152602001604051809103902083836040516114429291906138f0565b9081526040519081900360200190205460ff169050949350505050565b80518214611480576040516349552d5960e11b815260040160405180910390fd5b60005b8151811015611188576114c78484838181106114a1576114a16137fc565b905060200201358383815181106114ba576114ba6137fc565b602002602001015161297a565b600101611483565b60006114d9612970565b600092835260040160205250604090205490565b6000806114f8612970565b600084815260048201602052604090205490915080611538576000848152602083815260408083206006015483526001850190915290206003015461153a565b805b949350505050565b600061154c612970565b60060154909110919050565b6060806000611565612970565b60008581526020829052604090819020905191925090600383019061158b908390613900565b9081526020016040518091039020816001016040516115aa9190613900565b9081526040519081900360200190205460ff166115da576040516323d1634160e01b815260040160405180910390fd5b80600001816001018180546115ee9061384f565b80601f016020809104026020016040519081016040528092919081815260200182805461161a9061384f565b80156116675780601f1061163c57610100808354040283529160200191611667565b820191906000526020600020905b81548152906001019060200180831161164a57829003601f168201915b5050505050915080805461167a9061384f565b80601f01602080910402602001604051908101604052809291908181526020018280546116a69061384f565b80156116f35780601f106116c8576101008083540402835291602001916116f3565b820191906000526020600020905b8154815290600101906020018083116116d657829003601f168201915b50505050509050935093505050915091565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611738612970565b60009283526009016020908152604092839020835160a081018552905464ffffffffff8082168352650100000000008204811693830193909352600160501b81049092169381019390935262ffffff600160781b820481166060850152600160901b9091041660808301525090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526117e1612970565b6040805160c081018252600b929092015462ffffff808216845263010000008204811660208501526601000000000000820481169284019290925269010000000000000000008104821660608401526c0100000000000000000000000081049091166080830152600160781b90046001600160881b031660a0820152919050565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611895612970565b6000928352600a016020908152604092839020835160a081018552905464ffffffffff8082168352650100000000008204811693830193909352600160501b810490921693810193909352600160781b810463ffffffff166060840152600160981b90046cffffffffffffffffffffffffff1660808301525090565b600061192861191f83611e51565b60060154611e0c565b6002015492915050565b60006103e86119436111d384611e51565b6060015161195f9063ffffffff16670de0b6b3a764000061398c565b61068791906139a3565b805162ffffff1615806119835750602081015162ffffff16155b806119955750604081015162ffffff16155b806119a75750606081015162ffffff16155b806119b95750608081015162ffffff16155b806119d0575060a08101516001600160881b031615155b156119ee57604051637c946ed760e01b815260040160405180910390fd5b60808101516060820151604083015160208401518451611a0e91906139c5565b611a1891906139c5565b611a2291906139c5565b611a2c91906139c5565b62ffffff16620186a014611a5357604051635863f78960e01b815260040160405180910390fd5b80611a5c612970565b8151600b91909101805460208401516040808601516060870151608088015160a0909801516001600160881b0316600160781b026effffffffffffffffffffffffffffff62ffffff998a166c0100000000000000000000000002166bffffffffffffffffffffffff928a166901000000000000000000026bffffff00000000000000000019948b16660100000000000002949094166bffffffffffff00000000000019968b1663010000000265ffffffffffff199098169a9099169990991795909517939093169590951794909417169390931792909217909155517fbbd4d37e525bc0d0bf80d0c56879b81ebcccbe7bfd22e484e19eb0f369c011a490611bbc908390600060c08201905062ffffff808451168352806020850151166020840152806040850151166040840152806060850151166060840152806080850151166080840152506001600160881b0360a08401511660a083015292915050565b60405180910390a150565b60005b818110156106f357611bfe838383818110611be757611be76137fc565b9050602002810190611bf991906138da565b612b6c565b600101611bca565b6000611c10612970565b60080154905090565b6040805160a081018252600080825260208201819052918101829052606081018290526080810191909152611c4c612970565b6009016000611c5a84611e51565b6006015481526020808201929092526040908101600020815160a081018352905464ffffffffff8082168352650100000000008204811694830194909452600160501b81049093169181019190915262ffffff600160781b830481166060830152600160901b909204909116608082015292915050565b60606000611cdd611e3e565b67ffffffffffffffff811115611cf557611cf561329b565b604051908082528060200260200182016040528015611d1e578160200160208202803683370190505b50905060005b8151811015611d5b57611d36816114cf565b828281518110611d4857611d486137fc565b6020908102919091010152600101611d24565b50919050565b600060646402540be400611d7484612082565b611d7d85611932565b611d87919061398c565b61195f91906139a3565b6000611d9b612970565b90508060070154825114611dc2576040516349552d5960e11b815260040160405180910390fd5b60005b82518110156106f357611df181848381518110611de457611de46137fc565b602002602001015161209e565b600101611dc5565b6000611e03612970565b60070154905090565b6000611e16612970565b6000928352600101602052506040902090565b6000611e3482611e51565b6005015492915050565b6000611e48612970565b60060154905090565b6000611e5b612970565b6000928352602052506040902090565b6000611e75612970565b6008810180546000918290559192505b81811015612016576000818152600284016020526040808220815160c08101909252805482908290611eb69061384f565b80601f0160208091040260200160405190810160405280929190818152602001828054611ee29061384f565b8015611f2f5780601f10611f0457610100808354040283529160200191611f2f565b820191906000526020600020905b815481529060010190602001808311611f1257829003601f168201915b5050505050815260200160018201548152602001600282015481526020016003820154815260200160048201548152602001600582015481525050905061200d6040518060a00160405280836080015184602001516002611f90919061398c565b611f9a91906139e8565b64ffffffffff168152602001611fb66402540be400600a61398c565b64ffffffffff168152602001836060015164ffffffffff168152602001670de0b6b3a76400008460a001516103e8611fee919061398c565b611ff891906139a3565b63ffffffff168152600060209091015261254f565b50600101611e85565b5060005b8260070154811015612078576000818152600184016020526040812060028101805491926103e89261204d90849061398c565b925050819055506103e881600301600082825461206a919061398c565b90915550505060010161201a565b506106f383611969565b60006120906111d383611e51565b5164ffffffffff1692915050565b816120a7612970565b6000828152600191909101602052604081206002015490036120dc5760405163252e058d60e21b815260040160405180910390fd5b60006120e6612970565b835190915064ffffffffff1615806121075750602083015164ffffffffff16155b8061211b5750604083015164ffffffffff16155b8061212d5750606083015162ffffff16155b8061213f5750608083015162ffffff16155b1561215d57604051637c946ed760e01b815260040160405180910390fd5b606461216f6402540be400600561398c565b61217991906139a3565b835164ffffffffff1611156121a15760405163cd1049ff60e01b815260040160405180910390fd5b826040015164ffffffffff16836020015164ffffffffff1610156121d857604051630bedb6fd60e01b815260040160405180910390fd5b6121e86402540be400605a61398c565b836020015164ffffffffff16111561221357604051635b99296f60e01b815260040160405180910390fd5b6122236402540be400603261398c565b836040015164ffffffffff16101561224e576040516321b5730d60e01b815260040160405180910390fd5b826080015162ffffff16836060015162ffffff1611156122815760405163a1d0527960e01b815260040160405180910390fd5b61228a84611e0c565b60020154836060015162ffffff1610156122b75760405163a3d1c4d160e01b815260040160405180910390fd5b6122c084611e0c565b60030154836080015162ffffff1611156122ed57604051636588aba360e11b815260040160405180910390fd5b6000848152600982016020908152604091829020855181549287015187850151606089015160808a015164ffffffffff94851669ffffffffffffffffffff199097169690961765010000000000938516939093029290921771ffffffffffffffff000000000000000000001916600160501b939091169290920271ffffff000000000000000000000000000000191691909117600160781b62ffffff92831602177fffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffff16600160901b9190931602919091179055517f7e8e79d406657a52635b68c3f3ad15d2526e71077df1b40afad9d323eacbabfc906123f090869086906139fb565b60405180910390a150505050565b82811461241e576040516349552d5960e11b815260040160405180910390fd5b6000612428612970565b905060005b8481101561087757838382818110612447576124476137fc565b90506020020135826004016000888885818110612466576124666137fc565b90506020020135815260200190815260200160002081905550858582818110612491576124916137fc565b905060200201357f5d6c9d6dd6c84fa315e799a455ccb71230e5b88e171c48c4853425ce044e9bce8585848181106124cb576124cb6137fc565b905060200201356040516124e191815260200190565b60405180910390a260010161242d565b60005b818110156106f357612528838383818110612511576125116137fc565b905060200281019061252391906138b9565b612c38565b6001016124f4565b600061253e6111d383611e51565b6020015164ffffffffff1692915050565b8051819064ffffffffff16158061256f5750602081015164ffffffffff16155b806125835750604081015164ffffffffff16155b806125a35750806000015164ffffffffff16816040015164ffffffffff16115b806125b65750606081015163ffffffff16155b806125d3575060808101516cffffffffffffffffffffffffff1615155b156125f157604051630352e4ef60e21b815260040160405180910390fd5b60006125fb612970565b6008810180546000908152600a83016020908152604080832088518154938a0151928a015160608b015160808c01516cffffffffffffffffffffffffff16600160981b0272ffffffffffffffffffffffffffffffffffffff63ffffffff909216600160781b0272ffffffff0000000000000000000000000000001964ffffffffff948516600160501b021672ffffffffffffffffff0000000000000000000019978516650100000000000269ffffffffffffffffffff199099169490951693909317969096179490941691909117179190911691909117905581549293507f13b1e39f208d3f600b2dfd43c294bc9fb9518d7b57f027fdb0572d8a84cee27892919061270683613a52565b91905055846040516112e2929190613a6b565b8060e00135612726612970565b60008281526001919091016020526040812060020154900361275b5760405163252e058d60e21b815260040160405180910390fd5b816101000135612769612970565b6000828152600a91909101602052604081205464ffffffffff1690036127a25760405163490b7f1160e11b815260040160405180910390fd5b60006127ac612970565b6000868152602082905260409081902090519192509060038301906127d2908390613900565b9081526020016040518091039020816001016040516127f19190613900565b9081526040519081900360200190205460ff16612821576040516323d1634160e01b815260040160405180910390fd5b60408501600282016128338282613acc565b505060c0850135600582015560e0850135600682015561010085013560078201556040518681527f123a1b961ae93e7acda9790b318237b175b45ac09277cd3614305d8baa3f19539060200160405180910390a1505050505050565b81612898612970565b6000828152600191909101602052604081206002015490036128cd5760405163252e058d60e21b815260040160405180910390fd5b8161044c816040013510806128e85750620f42408160600135115b806128fb57508060600135816040013510155b156129195760405163523ae9c760e01b815260040160405180910390fd5b82612922612970565b60008681526001919091016020526040902061293e8282613cec565b50506040518481527fcfde8f228364c70f12cbbac5a88fc91ceca76dd750ac93364991a333b34afb8e906020016123f0565b6000806033610687565b81612983612970565b6000828152600a91909101602052604081205464ffffffffff1690036129bc5760405163490b7f1160e11b815260040160405180910390fd5b8151829064ffffffffff1615806129dc5750602081015164ffffffffff16155b806129f05750604081015164ffffffffff16155b80612a105750806000015164ffffffffff16816040015164ffffffffff16115b80612a235750606081015163ffffffff16155b80612a40575060808101516cffffffffffffffffffffffffff1615155b15612a5e57604051630352e4ef60e21b815260040160405180910390fd5b82612a67612970565b6000868152600a91909101602090815260409182902083518154928501518585015160608701516080909701516cffffffffffffffffffffffffff16600160981b0272ffffffffffffffffffffffffffffffffffffff63ffffffff909816600160781b0272ffffffff0000000000000000000000000000001964ffffffffff938416600160501b021672ffffffffffffffffff0000000000000000000019948416650100000000000269ffffffffffffffffffff199098169390951692909217959095179190911691909117179390931617909155517fb38258bbe4602eb8456888a284ddf8f9f9acc06f4699fce677ddd34941ed35cb906123f09086908690613a6b565b8061044c81604001351080612b875750620f42408160600135115b80612b9a57508060600135816040013510155b15612bb85760405163523ae9c760e01b815260040160405180910390fd5b6000612bc2612970565b6007810154600090815260018201602052604090209091508390612be68282613cec565b50506007810180547faf17de8e82beccc440012117a600dc37e26925225d0f1ee192fc107eb3dcbca4916000612c1b83613a52565b90915550612c298580613b9d565b6040516112e293929190613dff565b8060e00135612c45612970565b600082815260019190910160205260408120600201549003612c7a5760405163252e058d60e21b815260040160405180910390fd5b816101000135612c88612970565b6000828152600a91909101602052604081205464ffffffffff169003612cc15760405163490b7f1160e11b815260040160405180910390fd5b6000612ccb612970565b905060038101612cdb8580613b9d565b604051612ce99291906138f0565b9081526020016040518091039020848060200190612d079190613b9d565b604051612d159291906138f0565b9081526040519081900360200190205460ff1615612d46576040516392214ba360e01b815260040160405180910390fd5b600681015460009081526020829052604090208490612d658282613e19565b506001905060038201612d788680613b9d565b604051612d869291906138f0565b9081526020016040518091039020858060200190612da49190613b9d565b604051612db29291906138f0565b908152604051908190036020019020805491151560ff199092169190911790556006810180547f3adfd40f2b74073df2a84238acdb7f460565a557b3cc13bddc8833289bf38e09916000612e0583613a52565b90915550612e138680613b9d565b612e206020890189613b9d565b6040516123f0959493929190613f2b565b6040518060c001604052806060815260200160608152602001612e756040805160808101825260008082526020820181905290918201908152602001600081525090565b81526020016000815260200160008152602001600081525090565b600060208284031215612ea257600080fd5b5035919050565b60008083601f840112612ebb57600080fd5b50813567ffffffffffffffff811115612ed357600080fd5b60208301915083602060a083028501011115612eee57600080fd5b9250929050565b60008060208385031215612f0857600080fd5b823567ffffffffffffffff811115612f1f57600080fd5b612f2b85828601612ea9565b90969095509350505050565b60008083601f840112612f4957600080fd5b50813567ffffffffffffffff811115612f6157600080fd5b6020830191508360208260051b8501011115612eee57600080fd5b60008060008060008060608789031215612f9557600080fd5b863567ffffffffffffffff80821115612fad57600080fd5b612fb98a838b01612f37565b90985096506020890135915080821115612fd257600080fd5b612fde8a838b01612f37565b90965094506040890135915080821115612ff757600080fd5b5061300489828a01612f37565b979a9699509497509295939492505050565b6000806000806040858703121561302c57600080fd5b843567ffffffffffffffff8082111561304457600080fd5b61305088838901612f37565b9096509450602087013591508082111561306957600080fd5b5061307687828801612f37565b95989497509550505050565b60008083601f84011261309457600080fd5b50813567ffffffffffffffff8111156130ac57600080fd5b602083019150836020828501011115612eee57600080fd5b600080600080604085870312156130da57600080fd5b843567ffffffffffffffff808211156130f257600080fd5b6130fe88838901613082565b9096509450602087013591508082111561311757600080fd5b5061307687828801613082565b6000806000806040858703121561313a57600080fd5b843567ffffffffffffffff8082111561315257600080fd5b61315e88838901612f37565b9096509450602087013591508082111561317757600080fd5b5061307687828801612ea9565b6000815180845260005b818110156131aa5760208185018101518683018201520161318e565b506000602082860101526020601f19601f83011685010191505092915050565b6040815260006131dd6040830185613184565b82810360208401526108ab8185613184565b60a08101610687828464ffffffffff80825116835280602083015116602084015280604083015116604084015250606081015162ffffff808216606085015280608084015116608085015250505050565b60a08101610687828464ffffffffff8082511683528060208301511660208401528060408301511660408401525063ffffffff60608201511660608301526cffffffffffffffffffffffffff60808201511660808301525050565b634e487b7160e01b600052604160045260246000fd5b60405160a0810167ffffffffffffffff811182821017156132d4576132d461329b565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156133035761330361329b565b604052919050565b803562ffffff8116811461331e57600080fd5b919050565b600060c0828403121561333557600080fd5b60405160c0810181811067ffffffffffffffff821117156133585761335861329b565b6040526133648361330b565b81526133726020840161330b565b60208201526133836040840161330b565b60408201526133946060840161330b565b60608201526133a56080840161330b565b608082015260a08301356001600160881b03811681146133c457600080fd5b60a08201529392505050565b600080602083850312156133e357600080fd5b823567ffffffffffffffff8111156133fa57600080fd5b612f2b85828601612f37565b6020808252825182820181905260009190848201906040850190845b8181101561343e57835183529284019291840191600101613422565b50909695505050505050565b803564ffffffffff8116811461331e57600080fd5b600060a0828403121561347157600080fd5b6134796132b1565b90506134848261344a565b81526134926020830161344a565b60208201526134a36040830161344a565b60408201526134b46060830161330b565b60608201526134c56080830161330b565b608082015292915050565b600060208083850312156134e357600080fd5b823567ffffffffffffffff808211156134fb57600080fd5b818501915085601f83011261350f57600080fd5b8135818111156135215761352161329b565b61352f848260051b016132da565b818152848101925060a091820284018501918883111561354e57600080fd5b938501935b8285101561357457613565898661345f565b84529384019392850192613553565b50979650505050505050565b6001600160a01b038116811461121457600080fd5b80356004811061331e57600080fd5b600080604083850312156135b757600080fd5b82356135c281613580565b91506135d060208401613595565b90509250929050565b6020815260008251608060208401526135f560a0840182613184565b90506020840151604084015260408401516060840152606084015160808401528091505092915050565b634e487b7160e01b600052602160045260246000fd5b6020815260008251610120806020850152613654610140850183613184565b91506020850151601f198584030160408601526136718382613184565b92505060408501516001600160a01b03808251166060870152806020830151166080870152506040810151600381106136ac576136ac61361f565b8060a087015250606081015160c086015250606085015160e0850152608085015161010085015260a085015181850152508091505092915050565b6000806000606084860312156136fc57600080fd5b833561370781613580565b925061371560208501613595565b915061372360408501613595565b90509250925092565b60006020828403121561373e57600080fd5b8135610f8681613580565b60008060c0838503121561375c57600080fd5b823591506135d0846020850161345f565b600060a0828403121561377f57600080fd5b6137876132b1565b6137908361344a565b815261379e6020840161344a565b60208201526137af6040840161344a565b6040820152606083013563ffffffff811681146137cb57600080fd5b606082015260808301356cffffffffffffffffffffffffff811681146137f057600080fd5b60808201529392505050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561382457600080fd5b610f8682613595565b60006020828403121561383f57600080fd5b81358015158114610f8657600080fd5b600181811c9082168061386357607f821691505b602082108103611d5b57634e487b7160e01b600052602260045260246000fd5b6001600160a01b038416815260608101600484106138a3576138a361361f565b8360208301528215156040830152949350505050565b6000823561011e198336030181126138d057600080fd5b9190910192915050565b60008235607e198336030181126138d057600080fd5b8183823760009101908152919050565b600080835461390e8161384f565b60018281168015613926576001811461393b5761396a565b60ff198416875282151583028701945061396a565b8760005260208060002060005b858110156139615781548a820152908401908201613948565b50505082870194505b50929695505050505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761068757610687613976565b6000826139c057634e487b7160e01b600052601260045260246000fd5b500490565b62ffffff8181168382160190808211156139e1576139e1613976565b5092915050565b8082018082111561068757610687613976565b82815260c08101610f86602083018464ffffffffff80825116835280602083015116602084015280604083015116604084015250606081015162ffffff808216606085015280608084015116608085015250505050565b600060018201613a6457613a64613976565b5060010190565b82815260c08101610f86602083018464ffffffffff8082511683528060208301511660208401528060408301511660408401525063ffffffff60608201511660608301526cffffffffffffffffffffffffff60808201511660808301525050565b8135613ad781613580565b815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03821617825550600181016020830135613b1081613580565b815473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03821617825550604083013560038110613b4957600080fd5b815474ff00000000000000000000000000000000000000008260a01b167fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff8216178355505050606082013560028201555050565b6000808335601e19843603018112613bb457600080fd5b83018035915067ffffffffffffffff821115613bcf57600080fd5b602001915036819003821315612eee57600080fd5b601f8211156106f3576000816000526020600020601f850160051c81016020861015613c0d5750805b601f850160051c820191505b8181101561087757828155600101613c19565b67ffffffffffffffff831115613c4457613c4461329b565b613c5883613c52835461384f565b83613be4565b6000601f841160018114613c8c5760008515613c745750838201355b600019600387901b1c1916600186901b178355610896565b600083815260209020601f19861690835b82811015613cbd5786850135825560209485019460019092019101613c9d565b5086821015613cda5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b613cf68283613b9d565b67ffffffffffffffff811115613d0e57613d0e61329b565b613d2281613d1c855461384f565b85613be4565b6000601f821160018114613d565760008315613d3e5750838201355b600019600385901b1c1916600184901b178555613db0565b600085815260209020601f19841690835b82811015613d875786850135825560209485019460019092019101613d67565b5084821015613da45760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506020820135600182015560408201356002820155606082013560038201555050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b8381526040602082015260006108ab604083018486613dd6565b613e238283613b9d565b67ffffffffffffffff811115613e3b57613e3b61329b565b613e4981613d1c855461384f565b6000601f821160018114613e7d5760008315613e655750838201355b600019600385901b1c1916600184901b178555613ed7565b600085815260209020601f19841690835b82811015613eae5786850135825560209485019460019092019101613e8e565b5084821015613ecb5760001960f88660031b161c19848701351681555b505060018360011b0185555b50505050613ee86020830183613b9d565b613ef6818360018601613c2c565b5050613f086040830160028301613acc565b60c0820135600582015560e0820135600682015561010082013560078201555050565b858152606060208201526000613f45606083018688613dd6565b8281036040840152613f58818587613dd6565b9897505050505050505056fea26469706673582212202122d231ec59d3ccbab58401ad55b4a8149f1f966a86d71a3ee150f17881f5b564736f6c63430008170033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]

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