APE Price: $0.77 (-15.94%)

Contract

0x218d777353b94a8A04F9189545a4ECeBbb6cB8E9

Overview

APE Balance

Apechain LogoApechain LogoApechain Logo0 APE

APE Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

Please try again later

Parent Transaction Hash Block From To
View All Internal Transactions

Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GNSMultiCollatDiamond

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 800 runs

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

import "../interfaces/IGNSDiamond.sol";

import "./abstract/GNSAddressStore.sol";
import "./abstract/GNSDiamondStorage.sol";
import "./abstract/GNSDiamondCut.sol";
import "./abstract/GNSDiamondLoupe.sol";

/**
 * @dev Diamond that contains all code for the gTrade leverage trading platform
 */
contract GNSMultiCollatDiamond is
    GNSAddressStore, // base: Initializable + global storage, always first
    GNSDiamondStorage, // storage for each facet
    GNSDiamondCut, // diamond management
    GNSDiamondLoupe, // diamond getters
    IGNSDiamond // diamond interface (types only), always last
{
    /// @custom:oz-upgrades-unsafe-allow constructor
    constructor() {
        _disableInitializers();
    }
}

File 2 of 32 : LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface LinkTokenInterface {
  function allowance(address owner, address spender) external view returns (uint256 remaining);

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

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

  function decimals() external view returns (uint8 decimalPlaces);

  function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);

  function increaseApproval(address spender, uint256 subtractedValue) external;

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

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

  function totalSupply() external view returns (uint256 totalTokensIssued);

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

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  ) external returns (bool success);

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

File 3 of 32 : 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 4 of 32 : 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 5 of 32 : 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 6 of 32 : GNSDiamondCut.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "./GNSAddressStore.sol";

import "../../interfaces/IGNSDiamondCut.sol";

import "../../libraries/DiamondUtils.sol";

/**
 * @author Nick Mudge <[email protected]> (https://twitter.com/mudgen)
 * @author Gains Network
 * @dev Based on EIP-2535: Diamonds (https://eips.ethereum.org/EIPS/eip-2535)
 * @dev Follows diamond-3 implementation (https://github.com/mudgen/diamond-3-hardhat/)
 * @dev Manages all actions (calls, updates and initializations) related to the diamond and its facets.
 */
abstract contract GNSDiamondCut is GNSAddressStore, IGNSDiamondCut {
    /**
     * @dev Forwards call to the right facet using msg.sig using delegatecall. Reverts if signature is not known.
     */
    fallback() external payable {
        DiamondStorage storage s = DiamondUtils._getStorage();

        // get facet from function selector
        address facet = s.selectorToFacetAndPosition[msg.sig].facetAddress;

        if (facet == address(0)) revert NotFound();

        // Execute external function from facet using delegatecall and return any value.
        assembly {
            // copy function selector and any arguments
            calldatacopy(0, 0, calldatasize())
            // execute function call using the facet
            let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
            // get any return value
            returndatacopy(0, 0, returndatasize())
            // return any return value or error back to the caller
            switch result
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /**
     * @dev Allows the contract to receive ether
     */
    receive() external payable {}

    /// @inheritdoc IGNSDiamondCut
    function diamondCut(
        FacetCut[] calldata _faceCut,
        address _init,
        bytes calldata _calldata
    ) external onlyRole(Role.GOV_TIMELOCK) {
        _diamondCut(_faceCut, _init, _calldata);
    }

    /**
     * @dev Internal function for diamondCut()
     */
    function _diamondCut(FacetCut[] memory _facetCut, address _init, bytes memory _calldata) internal {
        for (uint256 facetIndex; facetIndex < _facetCut.length; facetIndex++) {
            FacetCutAction action = _facetCut[facetIndex].action;

            if (action == FacetCutAction.ADD) {
                _addFunctions(_facetCut[facetIndex].facetAddress, _facetCut[facetIndex].functionSelectors);
            } else if (action == FacetCutAction.REPLACE) {
                _replaceFunctions(_facetCut[facetIndex].facetAddress, _facetCut[facetIndex].functionSelectors);
            } else if (action == FacetCutAction.REMOVE) {
                _removeFunctions(_facetCut[facetIndex].facetAddress, _facetCut[facetIndex].functionSelectors);
            } else {
                revert InvalidFacetCutAction();
            }
        }

        emit DiamondCut(_facetCut, _init, _calldata);
        _initializeDiamondCut(_init, _calldata);
    }

    /**
     * @dev Adds the facet if it wasn't added yet, and adds its functions to the diamond
     * @param _facetAddress address of the facet contract
     * @param _functionSelectors array of function selectors
     */
    function _addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage s = DiamondUtils._getStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");

        uint96 selectorPosition = uint96(s.facetFunctionSelectors[_facetAddress].functionSelectors.length);

        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            _addFacet(s, _facetAddress);
        }

        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = s.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists");
            _addFunction(s, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    /**
     * @dev Updates facet contract address for given function selectors
     * @param _facetAddress address of the facet contract
     * @param _functionSelectors array of function selectors
     */
    function _replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage s = DiamondUtils._getStorage();
        require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)");

        uint96 selectorPosition = uint96(s.facetFunctionSelectors[_facetAddress].functionSelectors.length);

        // add new facet address if it does not exist
        if (selectorPosition == 0) {
            _addFacet(s, _facetAddress);
        }

        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = s.selectorToFacetAndPosition[selector].facetAddress;
            require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function");

            _removeFunction(s, oldFacetAddress, selector);
            _addFunction(s, selector, selectorPosition, _facetAddress);
            selectorPosition++;
        }
    }

    /**
     * @dev Removes some function selectors of a facet from diamond
     * @param _facetAddress address of the facet contract
     * @param _functionSelectors array of function selectors
     */
    function _removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal {
        require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut");
        DiamondStorage storage s = DiamondUtils._getStorage();
        // if function does not exist then do nothing and return
        require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)");
        for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) {
            bytes4 selector = _functionSelectors[selectorIndex];
            address oldFacetAddress = s.selectorToFacetAndPosition[selector].facetAddress;
            _removeFunction(s, oldFacetAddress, selector);
        }
    }

    /**
     * @dev Adds a new facet contract address to the diamond
     * @param s diamond storage pointer
     * @param _facetAddress address of the new facet contract
     */
    function _addFacet(DiamondStorage storage s, address _facetAddress) internal {
        _enforceHasContractCode(_facetAddress);
        s.facetFunctionSelectors[_facetAddress].facetAddressPosition = s.facetAddresses.length;
        s.facetAddresses.push(_facetAddress);
    }

    /**
     * @dev Adds a new function to the diamond for a given facet contract
     * @param s diamond storage pointer
     * @param _selector function selector
     * @param _selectorPosition position of the function selector in the facet selectors array
     * @param _facetAddress address of the facet contract
     */
    function _addFunction(
        DiamondStorage storage s,
        bytes4 _selector,
        uint96 _selectorPosition,
        address _facetAddress
    ) internal {
        s.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
        s.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
        s.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
    }

    /**
     * @dev Removes a function from a facet of the diamond
     * @param s diamond storage pointer
     * @param _facetAddress address of the facet contract
     * @param _selector function selector
     */
    function _removeFunction(DiamondStorage storage s, address _facetAddress, bytes4 _selector) internal {
        require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist");
        // an immutable function is a function defined directly in a diamond
        require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function");

        // replace selector with last selector, then delete last selector
        uint256 selectorPosition = s.selectorToFacetAndPosition[_selector].functionSelectorPosition;
        uint256 lastSelectorPosition = s.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1;

        // if not the same then replace _selector with lastSelector
        if (selectorPosition != lastSelectorPosition) {
            bytes4 lastSelector = s.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
            s.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
            s.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition);
        }

        // delete the last selector
        s.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
        delete s.selectorToFacetAndPosition[_selector];

        // if no more selectors for facet address then delete the facet address
        if (lastSelectorPosition == 0) {
            // replace facet address with last facet address and delete last facet address
            uint256 lastFacetAddressPosition = s.facetAddresses.length - 1;
            uint256 facetAddressPosition = s.facetFunctionSelectors[_facetAddress].facetAddressPosition;

            if (facetAddressPosition != lastFacetAddressPosition) {
                address lastFacetAddress = s.facetAddresses[lastFacetAddressPosition];
                s.facetAddresses[facetAddressPosition] = lastFacetAddress;
                s.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
            }
            s.facetAddresses.pop();
            delete s.facetFunctionSelectors[_facetAddress].facetAddressPosition;
        }
    }

    /**
     * @dev Initializes a facet after updating the diamond using delegatecall
     * @param _init address of the contract to execute _calldata
     * @param _calldata function call (selector and arguments)
     */
    function _initializeDiamondCut(address _init, bytes memory _calldata) internal {
        if (_init == address(0)) {
            return;
        }
        _enforceHasContractCode(_init);

        (bool success, bytes memory error) = _init.delegatecall(_calldata);
        if (!success) {
            if (error.length > 0) {
                // bubble up error
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(error)
                    revert(add(32, error), returndata_size)
                }
            } else {
                revert InitializationFunctionReverted(_init, _calldata);
            }
        }
    }

    /**
     * @dev Reverts if the given address is not a contract
     * @param _contract address to check
     */
    function _enforceHasContractCode(address _contract) internal view {
        uint256 contractSize;
        assembly {
            contractSize := extcodesize(_contract)
        }

        if (contractSize == 0) revert NotContract();
    }
}

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

import "./GNSAddressStore.sol";

import "../../interfaces/IGNSDiamondLoupe.sol";

import "../../libraries/DiamondUtils.sol";

/**
 * @author Nick Mudge <[email protected]> (https://twitter.com/mudgen)
 * @author Gains Network
 * @dev Based on EIP-2535: Diamonds (https://eips.ethereum.org/EIPS/eip-2535)
 * @dev Follows diamond-3 implementation (https://github.com/mudgen/diamond-3-hardhat/)
 * @dev Returns useful information about the diamond and its facets.
 */
abstract contract GNSDiamondLoupe is IGNSDiamondLoupe {
    /// @notice Gets all facets and their selectors.
    /// @return facets_ Facet
    function facets() external view returns (Facet[] memory facets_) {
        IDiamondStorage.DiamondStorage storage s = DiamondUtils._getStorage();
        uint256 numFacets = s.facetAddresses.length;
        facets_ = new Facet[](numFacets);
        for (uint256 i; i < numFacets; i++) {
            address facetAddress_ = s.facetAddresses[i];
            facets_[i].facetAddress = facetAddress_;
            facets_[i].functionSelectors = s.facetFunctionSelectors[facetAddress_].functionSelectors;
        }
    }

    /// @notice Gets all the function selectors provided by a facet.
    /// @param _facet The facet address.
    /// @return facetFunctionSelectors_ the function selectors.
    function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_) {
        IDiamondStorage.DiamondStorage storage s = DiamondUtils._getStorage();
        facetFunctionSelectors_ = s.facetFunctionSelectors[_facet].functionSelectors;
    }

    /// @notice Get all the facet addresses used by a diamond.
    /// @return facetAddresses_ the facet addresses
    function facetAddresses() external view returns (address[] memory facetAddresses_) {
        IDiamondStorage.DiamondStorage storage s = DiamondUtils._getStorage();
        facetAddresses_ = s.facetAddresses;
    }

    /// @notice Gets the facet that supports the given selector.
    /// @dev If facet is not found return address(0).
    /// @param _functionSelector The function selector.
    /// @return facetAddress_ The facet address.
    function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_) {
        IDiamondStorage.DiamondStorage storage s = DiamondUtils._getStorage();
        facetAddress_ = s.selectorToFacetAndPosition[_functionSelector].facetAddress;
    }
}

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

import "./GNSAddressStore.sol";

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

/**
 * @dev Sets storage slot layout for diamond facets.
 */
abstract contract GNSDiamondStorage is GNSAddressStore, ITypes {
    PairsStorage private pairsStorage;
    ReferralsStorage private referralsStorage;
    FeeTiersStorage private feeTiersStorage;
    PriceImpactStorage private priceImpactStorage;
    DiamondStorage private diamondStorage;
    TradingStorage private tradingStorage;
    TriggerRewardsStorage private triggerRewardsStorage;
    TradingInteractionsStorage private tradingInteractionsStorage;
    TradingCallbacksStorage private tradingCallbacksStorage;
    BorrowingFeesStorage private borrowingFeesStorage;
    PriceAggregatorStorage private priceAggregatorStorage;
    OtcStorage private otcStorage;
    ChainConfigStorage private chainConfigStorage;

    // New storage goes at end of list
}

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

/**
 * @dev Interface for Chainlink feeds
 */
interface IChainlinkFeed {
    function latestRoundData() external view returns (uint80, int256, uint256, uint256, uint80);

    function decimals() external view returns (uint8);
}

File 10 of 32 : 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 11 of 32 : 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 12 of 32 : IGNSDiamond.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "./IGNSAddressStore.sol";
import "./IGNSDiamondCut.sol";
import "./IGNSDiamondLoupe.sol";
import "./types/ITypes.sol";

/**
 * @dev the non-expanded interface for multi-collat diamond, only contains types/structs/enums
 */

interface IGNSDiamond is IGNSAddressStore, IGNSDiamondCut, IGNSDiamondLoupe, ITypes {

}

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

import "./types/IDiamondStorage.sol";

/**
 * @author Nick Mudge <[email protected]> (https://twitter.com/mudgen)
 * @author Gains Network
 * @dev Based on EIP-2535: Diamonds (https://eips.ethereum.org/EIPS/eip-2535)
 * @dev Follows diamond-3 implementation (https://github.com/mudgen/diamond-3-hardhat/)
 * @dev One of the diamond standard interfaces, used for diamond management.
 */
interface IGNSDiamondCut is IDiamondStorage {
    /**
     * @notice Add/replace/remove any number of functions and optionally execute a function with delegatecall
     * @param _diamondCut Contains the facet addresses and function selectors
     * @param _init The address of the contract or facet to execute _calldata
     * @param _calldata A function call, including function selector and arguments _calldata is executed with delegatecall on _init
     */
    function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) external;

    /**
     * @dev Emitted when function selectors of a facet of the diamond is added, replaced, or removed
     * @param _diamondCut Contains the update data (facet addresses, action, function selectors)
     * @param _init The address of the contract or facet to execute _calldata
     * @param _calldata Function call to execute after the diamond cut
     */
    event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);

    error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata);
    error InvalidFacetCutAction();
    error NotContract();
    error NotFound();
}

File 14 of 32 : IGNSDiamondLoupe.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @author Nick Mudge <[email protected]> (https://twitter.com/mudgen)
 * @author Gains Network
 * @dev Based on EIP-2535: Diamonds (https://eips.ethereum.org/EIPS/eip-2535)
 * @dev Follows diamond-3 implementation (https://github.com/mudgen/diamond-3-hardhat/)
 * @dev One of the diamond standard interfaces, used to inspect the diamond like a magnifying glass.
 */
interface IGNSDiamondLoupe {
    /// These functions are expected to be called frequently
    /// by tools.

    struct Facet {
        address facetAddress;
        bytes4[] functionSelectors;
    }

    /// @notice Gets all facet addresses and their four byte function selectors.
    /// @return facets_ Facet
    function facets() external view returns (Facet[] memory facets_);

    /// @notice Gets all the function selectors supported by a specific facet.
    /// @param _facet The facet address.
    /// @return facetFunctionSelectors_
    function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetFunctionSelectors_);

    /// @notice Get all the facet addresses used by a diamond.
    /// @return facetAddresses_
    function facetAddresses() external view returns (address[] memory facetAddresses_);

    /// @notice Gets the facet that supports the given selector.
    /// @dev If facet is not found return address(0).
    /// @param _functionSelector The function selector.
    /// @return facetAddress_ The facet address.
    function facetAddress(bytes4 _functionSelector) external view returns (address facetAddress_);
}

File 15 of 32 : ILiquidityPool.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @custom:version 8
 * @dev Generic interface for liquidity pool methods for fetching observations (to calculate TWAP) and other basic information
 */
interface ILiquidityPool {
    /**
     * @dev AlgebraPool V1.9 equivalent of Uniswap V3 `observe` function
     * See https://github.com/cryptoalgebra/AlgebraV1.9/blob/main/src/core/contracts/interfaces/pool/IAlgebraPoolDerivedState.sol for more information
     */
    function getTimepoints(
        uint32[] calldata secondsAgos
    )
        external
        view
        returns (
            int56[] memory tickCumulatives,
            uint160[] memory secondsPerLiquidityCumulatives,
            uint112[] memory volatilityCumulatives,
            uint256[] memory volumePerAvgLiquiditys
        );

    /**
     * @dev Uniswap V3 `observe` function
     * See `https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/pool/IUniswapV3PoolDerivedState.sol` for more information
     */
    function observe(
        uint32[] calldata secondsAgos
    ) external view returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);

    /**
     * @notice The first of the two tokens of the pool, sorted by address
     * @return The token contract address
     */
    function token0() external view returns (address);

    /**
     * @notice The second of the two tokens of the pool, sorted by address
     * @return The token contract address
     */
    function token1() external view returns (address);
}

File 16 of 32 : 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 17 of 32 : IBorrowingFees.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "./IPairsStorage.sol";

/**
 * @dev Contains the types for the GNSBorrowingFees facet
 */
interface IBorrowingFees {
    struct BorrowingFeesStorage {
        mapping(uint8 => mapping(uint16 => BorrowingData)) pairs;
        mapping(uint8 => mapping(uint16 => BorrowingPairGroup[])) pairGroups;
        mapping(uint8 => mapping(uint16 => OpenInterest)) pairOis;
        mapping(uint8 => mapping(uint16 => BorrowingData)) groups;
        mapping(uint8 => mapping(uint16 => OpenInterest)) groupOis;
        mapping(uint8 => mapping(address => mapping(uint32 => BorrowingInitialAccFees))) initialAccFees;
        uint256[44] __gap;
    }

    struct BorrowingData {
        uint32 feePerBlock; // 1e10 (%)
        uint64 accFeeLong; // 1e10 (%)
        uint64 accFeeShort; // 1e10 (%)
        uint48 accLastUpdatedBlock;
        uint48 feeExponent;
    }

    struct BorrowingPairGroup {
        uint16 groupIndex;
        uint48 block;
        uint64 initialAccFeeLong; // 1e10 (%)
        uint64 initialAccFeeShort; // 1e10 (%)
        uint64 prevGroupAccFeeLong; // 1e10 (%)
        uint64 prevGroupAccFeeShort; // 1e10 (%)
        uint64 pairAccFeeLong; // 1e10 (%)
        uint64 pairAccFeeShort; // 1e10 (%)
        uint64 __placeholder; // might be useful later
    }

    struct OpenInterest {
        uint72 long; // 1e10 (collateral)
        uint72 short; // 1e10 (collateral)
        uint72 max; // 1e10 (collateral)
        uint40 __placeholder; // might be useful later
    }

    struct BorrowingInitialAccFees {
        uint64 accPairFee; // 1e10 (%)
        uint64 accGroupFee; // 1e10 (%)
        uint48 block;
        uint80 __placeholder; // might be useful later
    }

    struct BorrowingPairParams {
        uint16 groupIndex;
        uint32 feePerBlock; // 1e10 (%)
        uint48 feeExponent;
        uint72 maxOi;
    }

    struct BorrowingGroupParams {
        uint32 feePerBlock; // 1e10 (%)
        uint72 maxOi; // 1e10
        uint48 feeExponent;
    }

    struct BorrowingFeeInput {
        uint8 collateralIndex;
        address trader;
        uint16 pairIndex;
        uint32 index;
        bool long;
        uint256 collateral; // 1e18 | 1e6 (collateral)
        uint256 leverage; // 1e3
    }

    struct LiqPriceInput {
        uint8 collateralIndex;
        address trader;
        uint16 pairIndex;
        uint32 index;
        uint64 openPrice; // 1e10
        bool long;
        uint256 collateral; // 1e18 | 1e6 (collateral)
        uint256 leverage; // 1e3
        bool useBorrowingFees;
        IPairsStorage.GroupLiquidationParams liquidationParams;
    }

    struct PendingBorrowingAccFeesInput {
        uint64 accFeeLong; // 1e10 (%)
        uint64 accFeeShort; // 1e10 (%)
        uint256 oiLong; // 1e18 | 1e6
        uint256 oiShort; // 1e18 | 1e6
        uint32 feePerBlock; // 1e10
        uint256 currentBlock;
        uint256 accLastUpdatedBlock;
        uint72 maxOi; // 1e10
        uint48 feeExponent;
        uint128 collateralPrecision;
    }
}

File 18 of 32 : IChainConfig.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSChainConfig facet
 */
interface IChainConfig {
    struct ChainConfigStorage {
        uint256 reentrancyLock; // HAS TO BE FIRST AND TAKE A FULL SLOT (GNSReentrancyGuard expects it)
        uint16 nativeTransferGasLimit; // 16 bits. 64,535 max value
        bool nativeTransferEnabled; // When true, the diamond is allowed to unwrap native tokens on transfer out
        uint232 __placeholder;
        uint256[48] __gap;
    }
}

File 19 of 32 : IDiamondStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @author Nick Mudge <[email protected]> (https://twitter.com/mudgen)
 * @author Gains Network
 * @dev Based on EIP-2535: Diamonds (https://eips.ethereum.org/EIPS/eip-2535)
 * @dev Follows diamond-3 implementation (https://github.com/mudgen/diamond-3-hardhat/)
 * @dev Contains the types used in the diamond management contracts.
 */
interface IDiamondStorage {
    struct DiamondStorage {
        // maps function selector to the facet address and
        // the position of the selector in the facetFunctionSelectors.selectors array
        mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition;
        // maps facet addresses to function selectors
        mapping(address => FacetFunctionSelectors) facetFunctionSelectors;
        // facet addresses
        address[] facetAddresses;
        address[47] __gap;
    }

    struct FacetAddressAndPosition {
        address facetAddress;
        uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
    }

    struct FacetFunctionSelectors {
        bytes4[] functionSelectors;
        uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
    }

    enum FacetCutAction {
        ADD,
        REPLACE,
        REMOVE,
        NOP
    }

    struct FacetCut {
        address facetAddress;
        FacetCutAction action;
        bytes4[] functionSelectors;
    }
}

File 20 of 32 : IFeeTiers.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSFeeTiers facet
 */
interface IFeeTiers {
    struct FeeTiersStorage {
        FeeTier[8] feeTiers;
        mapping(uint256 => uint256) groupVolumeMultipliers; // groupIndex (pairs storage) => multiplier (1e3)
        mapping(address => TraderInfo) traderInfos; // trader => TraderInfo
        mapping(address => mapping(uint32 => TraderDailyInfo)) traderDailyInfos; // trader => day => TraderDailyInfo
        mapping(address => TraderEnrollment) traderEnrollments; // trader => TraderEnrollment
        mapping(address => uint224) unclaimedPoints; // trader => points (1e18)
        uint256[37] __gap;
    }

    enum TraderEnrollmentStatus {
        ENROLLED,
        EXCLUDED
    }

    enum CreditType {
        IMMEDIATE,
        CLAIMABLE
    }

    struct FeeTier {
        uint32 feeMultiplier; // 1e3
        uint32 pointsThreshold;
    }

    struct TraderInfo {
        uint32 lastDayUpdated;
        uint224 trailingPoints; // 1e18
    }

    struct TraderDailyInfo {
        uint32 feeMultiplierCache; // 1e3
        uint224 points; // 1e18
    }

    struct TraderEnrollment {
        TraderEnrollmentStatus status;
        uint248 __placeholder;
    }
}

File 21 of 32 : IOtc.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSPairsStorage facet
 */
interface IOtc {
    struct OtcStorage {
        mapping(uint8 => uint256) collateralBalances; // collateralIndex => available OTC value (collateral precision)
        OtcConfig otcConfig;
        uint256[47] __gap;
    }

    struct OtcConfig {
        address gnsTreasury; /// @custom:deprecated Use `AddressStore.globalAddresses.treasury` instead
        uint64 treasuryShareP; // %, 1e10 precision
        uint64 stakingShareP; // %, 1e10 precision
        uint64 burnShareP; // %, 1e10 precision
        uint64 premiumP; // %, 1e10 precision
    }
}

File 22 of 32 : 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 23 of 32 : IPriceAggregator.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import {LinkTokenInterface} from "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";

import "./ITradingStorage.sol";
import "../IChainlinkFeed.sol";
import "../ILiquidityPool.sol";

/**
 * @dev Contains the types for the GNSPriceAggregator facet
 */
interface IPriceAggregator {
    struct PriceAggregatorStorage {
        // slot 1
        IChainlinkFeed linkUsdPriceFeed; // 160 bits
        uint24 twapInterval; // 24 bits
        uint8 minAnswers; // 8 bits
        // slot 2, 3, 4, 5, 6, 7, 8
        bytes32[2] jobIds; // 2 slots
        address[] oracles;
        mapping(uint8 => LiquidityPoolInfo) collateralGnsLiquidityPools;
        mapping(uint8 => IChainlinkFeed) collateralUsdPriceFeed;
        mapping(bytes32 => Order) orders;
        mapping(address => mapping(uint32 => OrderAnswer[])) orderAnswers;
        // Chainlink Client (slots 9, 10, 11)
        LinkTokenInterface linkErc677; // 160 bits
        uint96 __placeholder; // 96 bits
        uint256 requestCount; // 256 bits
        mapping(bytes32 => address) pendingRequests;
        uint256[39] __gap;
    }

    struct LiquidityPoolInfo {
        ILiquidityPool pool; // 160 bits
        bool isGnsToken0InLp; // 8 bits
        PoolType poolType; // 8 bits
        uint80 __placeholder; // 80 bits
    }

    struct Order {
        address user; // 160 bits
        uint32 index; // 32 bits
        ITradingStorage.PendingOrderType orderType; // 8 bits
        uint16 pairIndex; // 16 bits
        bool isLookback; // 8 bits
        uint32 __placeholder; // 32 bits
    }

    struct OrderAnswer {
        uint64 open;
        uint64 high;
        uint64 low;
        uint64 ts;
    }

    struct LiquidityPoolInput {
        ILiquidityPool pool;
        PoolType poolType;
    }

    enum PoolType {
        UNISWAP_V3,
        ALGEBRA_v1_9
    }
}

File 24 of 32 : IPriceImpact.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSPriceImpact facet
 */
interface IPriceImpact {
    struct PriceImpactStorage {
        OiWindowsSettings oiWindowsSettings;
        mapping(uint48 => mapping(uint256 => mapping(uint256 => PairOi))) windows; // duration => pairIndex => windowId => Oi
        mapping(uint256 => PairDepth) pairDepths; // pairIndex => depth (USD)
        mapping(address => mapping(uint32 => TradePriceImpactInfo)) tradePriceImpactInfos; // deprecated
        mapping(uint256 => PairFactors) pairFactors;
        uint40 negPnlCumulVolMultiplier;
        uint216 __placeholder;
        mapping(address => bool) protectionCloseFactorWhitelist;
        uint256[43] __gap;
    }

    struct OiWindowsSettings {
        uint48 startTs;
        uint48 windowsDuration;
        uint48 windowsCount;
    }

    struct PairOi {
        uint128 oiLongUsd; // 1e18 USD
        uint128 oiShortUsd; // 1e18 USD
    }

    struct OiWindowUpdate {
        address trader;
        uint32 index;
        uint48 windowsDuration;
        uint256 pairIndex;
        uint256 windowId;
        bool long;
        bool open;
        bool isPnlPositive;
        uint128 openInterestUsd; // 1e18 USD
    }

    struct PairDepth {
        uint128 onePercentDepthAboveUsd; // USD
        uint128 onePercentDepthBelowUsd; // USD
    }

    struct PairFactors {
        uint40 protectionCloseFactor; // 1e10; max 109.95x
        uint32 protectionCloseFactorBlocks;
        uint40 cumulativeFactor; // 1e10; max 109.95x
        bool exemptOnOpen;
        bool exemptAfterProtectionCloseFactor;
        uint128 __placeholder;
    }

    // Deprecated
    struct TradePriceImpactInfo {
        uint128 lastWindowOiUsd;
        uint128 __placeholder;
    }
}

File 25 of 32 : IReferrals.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSReferrals facet
 */
interface IReferrals {
    struct ReferralsStorage {
        mapping(address => AllyDetails) allyDetails;
        mapping(address => ReferrerDetails) referrerDetails;
        mapping(address => address) referrerByTrader;
        uint256 allyFeeP; // % (of referrer fees going to allies, eg. 10)
        uint256 startReferrerFeeP; // % (of referrer fee when 0 volume referred, eg. 75)
        uint256 openFeeP; /// @custom:deprecated
        uint256 targetVolumeUsd; // USD (to reach maximum referral system fee, eg. 1e8)
        uint256[43] __gap;
    }

    struct AllyDetails {
        address[] referrersReferred;
        uint256 volumeReferredUsd; // 1e18
        uint256 pendingRewardsGns; // 1e18
        uint256 totalRewardsGns; // 1e18
        uint256 totalRewardsValueUsd; // 1e18
        bool active;
    }

    struct ReferrerDetails {
        address ally;
        address[] tradersReferred;
        uint256 volumeReferredUsd; // 1e18
        uint256 pendingRewardsGns; // 1e18
        uint256 totalRewardsGns; // 1e18
        uint256 totalRewardsValueUsd; // 1e18
        bool active;
    }
}

File 26 of 32 : ITradingCallbacks.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

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

/**
 * @dev Contains the types for the GNSTradingCallbacks facet
 */
interface ITradingCallbacks {
    struct TradingCallbacksStorage {
        uint8 vaultClosingFeeP;
        uint248 __placeholder;
        mapping(uint8 => uint256) pendingGovFees; // collateralIndex => pending gov fee (collateral)
        uint256[48] __gap;
    }

    enum CancelReason {
        NONE,
        PAUSED, // deprecated
        MARKET_CLOSED,
        SLIPPAGE,
        TP_REACHED,
        SL_REACHED,
        EXPOSURE_LIMITS,
        PRICE_IMPACT,
        MAX_LEVERAGE,
        NO_TRADE,
        WRONG_TRADE, // deprecated
        NOT_HIT,
        LIQ_REACHED
    }

    struct AggregatorAnswer {
        ITradingStorage.Id orderId;
        uint256 spreadP;
        uint64 price;
        uint64 open;
        uint64 high;
        uint64 low;
    }

    // Useful to avoid stack too deep errors
    struct Values {
        int256 profitP;
        uint256 executionPrice;
        uint256 liqPrice;
        uint256 amountSentToTrader;
        uint256 collateralPriceUsd;
        bool exactExecution;
        uint256 collateralLeftInStorage;
        uint256 oraclePrice;
        uint32 limitIndex;
        uint256 priceImpactP;
    }
}

File 27 of 32 : ITradingInteractions.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSTradingInteractions facet
 */
interface ITradingInteractions {
    struct TradingInteractionsStorage {
        address senderOverride; // 160 bits
        uint16 marketOrdersTimeoutBlocks; // 16 bits
        uint80 __placeholder;
        mapping(address => address) delegations;
        mapping(address => bool) byPassTriggerLink;
        uint256[47] __gap;
    }
}

File 28 of 32 : 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 29 of 32 : ITriggerRewards.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/**
 * @dev Contains the types for the GNSTriggerRewards facet
 */
interface ITriggerRewards {
    struct TriggerRewardsStorage {
        uint16 triggerTimeoutBlocks; // 16 bits
        uint240 __placeholder; // 240 bits
        mapping(address => uint256) pendingRewardsGns;
        uint256[48] __gap;
    }
}

File 30 of 32 : ITypes.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

import "./IDiamondStorage.sol";
import "./IPairsStorage.sol";
import "./IReferrals.sol";
import "./IFeeTiers.sol";
import "./IPriceImpact.sol";
import "./ITradingStorage.sol";
import "./ITriggerRewards.sol";
import "./ITradingInteractions.sol";
import "./ITradingCallbacks.sol";
import "./IBorrowingFees.sol";
import "./IPriceAggregator.sol";
import "./IOtc.sol";
import "./IChainConfig.sol";

/**
 * @dev Contains the types of all diamond facets
 */
interface ITypes is
    IDiamondStorage,
    IPairsStorage,
    IReferrals,
    IFeeTiers,
    IPriceImpact,
    ITradingStorage,
    ITriggerRewards,
    ITradingInteractions,
    ITradingCallbacks,
    IBorrowingFees,
    IPriceAggregator,
    IOtc,
    IChainConfig
{}

File 31 of 32 : DiamondUtils.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

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

import "./StorageUtils.sol";

/**
 *
 * @dev Diamond standard internal library to access storage
 */
library DiamondUtils {
    /**
     * @dev Returns storage slot for diamond data (facets, selectors, etc.)
     */
    function _getSlot() internal pure returns (uint256) {
        return StorageUtils.GLOBAL_DIAMOND_SLOT;
    }

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

File 32 of 32 : 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":"InitError","type":"error"},{"inputs":[{"internalType":"address","name":"_initializationContractAddress","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"InitializationFunctionReverted","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAddresses","type":"error"},{"inputs":[],"name":"InvalidCollateralIndex","type":"error"},{"inputs":[],"name":"InvalidFacetCutAction","type":"error"},{"inputs":[],"name":"InvalidInputLength","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[],"name":"NotAuthorized","type":"error"},{"inputs":[],"name":"NotContract","type":"error"},{"inputs":[],"name":"NotFound","type":"error"},{"inputs":[],"name":"Overflow","type":"error"},{"inputs":[],"name":"Paused","type":"error"},{"inputs":[],"name":"UnsupportedChain","type":"error"},{"inputs":[],"name":"WrongAccess","type":"error"},{"inputs":[],"name":"WrongIndex","type":"error"},{"inputs":[],"name":"WrongLength","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":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondStorage.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"struct IDiamondStorage.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"DiamondCut","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enum IDiamondStorage.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IDiamondStorage.FacetCut[]","name":"_faceCut","type":"tuple[]"},{"internalType":"address","name":"_init","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_functionSelector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facetAddress_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"facetAddresses_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"facetFunctionSelectors_","type":"bytes4[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"struct IGNSDiamondLoupe.Facet[]","name":"facets_","type":"tuple[]"}],"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":[{"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":[{"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"},{"stateMutability":"payable","type":"receive"}]

608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61205280620000ed6000396000f3fe6080604052600436106100b55760003560e01c8063a39fac1211610069578063b9c972291161004e578063b9c97229146102ac578063c4d66de8146102cc578063cdffacc6146102ec576100bc565b8063a39fac12146101ed578063adfca15e1461027f576100bc565b806352ef6b2c1161009a57806352ef6b2c146101705780637a0ed6271461019b57806395a8c58d146101bd576100bc565b8063101e6503146101305780631f931c1c14610150576100bc565b366100bc57005b60006100c6610324565b600080356001600160e01b0319168152602082905260409020549091506001600160a01b03168061010a5760405163c5723b5160e01b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610129573d6000f35b3d6000fd5b005b34801561013c57600080fd5b5061012e61014b36600461185a565b610330565b34801561015c57600080fd5b5061012e61016b366004611910565b610495565b34801561017c57600080fd5b506101856104f2565b60405161019291906119be565b60405180910390f35b3480156101a757600080fd5b506101b061055e565b6040516101929190611a51565b3480156101c957600080fd5b506101dd6101d8366004611add565b610711565b6040519015158152602001610192565b3480156101f957600080fd5b5061024d604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b0390811682526020808501518216908301529282015190921690820152606001610192565b34801561028b57600080fd5b5061029f61029a366004611b14565b610768565b6040516101929190611b36565b3480156102b857600080fd5b506101dd6102c7366004611b78565b610827565b3480156102d857600080fd5b5061012e6102e7366004611b14565b6108d6565b3480156102f857600080fd5b5061030c610307366004611bd9565b610a28565b6040516001600160a01b039091168152602001610192565b60008060fb5b92915050565b600061033b81610a5d565b858414158061034a5750858214155b1561036857604051637db491eb60e01b815260040160405180910390fd5b60005b8681101561048b57600086868381811061038757610387611c0a565b905060200201602081019061039c9190611c20565b60038111156103ad576103ad611bf4565b1480156103e85750338888838181106103c8576103c8611c0a565b90506020020160208101906103dd9190611b14565b6001600160a01b0316145b1561040657604051631eb49d6d60e11b815260040160405180910390fd5b61048388888381811061041b5761041b611c0a565b90506020020160208101906104309190611b14565b87878481811061044257610442611c0a565b90506020020160208101906104579190611c20565b86868581811061046957610469611c0a565b905060200201602081019061047e9190611c3d565b610a87565b60010161036b565b5050505050505050565b60006104a081610a5d565b6104ea6104ad8688611cf3565b8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b2992505050565b505050505050565b606060006104fe610324565b6002810180546040805160208084028201810190925282815293945083018282801561055357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610535575b505050505091505090565b6060600061056a610324565b60028101549091508067ffffffffffffffff81111561058b5761058b611c5f565b6040519080825280602002602001820160405280156105d157816020015b6040805180820190915260008152606060208201528152602001906001900390816105a95790505b50925060005b8181101561070b5760008360020182815481106105f6576105f6611c0a565b9060005260206000200160009054906101000a90046001600160a01b031690508085838151811061062957610629611c0a565b6020908102919091018101516001600160a01b0392831690529082166000908152600186018252604090819020805482518185028101850190935280835291929091908301828280156106dd57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161068a5790505b50505050508583815181106106f4576106f4611c0a565b6020908102919091018101510152506001016105d7565b50505090565b6001600160a01b03821660009081526002602052604081208183600381111561073c5761073c611bf4565b600381111561074d5761074d611bf4565b815260208101919091526040016000205460ff169392505050565b60606000610774610324565b6001600160a01b0384166000908152600182016020908152604091829020805483518184028101840190945280845293945091929083018282801561081a57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116107c75790505b5050505050915050919050565b6001600160a01b03831660009081526002602052604081208184600381111561085257610852611bf4565b600381111561086357610863611bf4565b815260208101919091526040016000205460ff16806108ce57506001600160a01b0384166000908152600260205260408120908360038111156108a8576108a8611bf4565b60038111156108b9576108b9611bf4565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff16158080156108f65750600054600160ff909116105b806109105750303b158015610910575060005460ff166001145b6109875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff1916600117905580156109aa576000805461ff0019166101001790555b6001600160a01b0382166109d157604051632c1c702960e21b815260040160405180910390fd5b6109de8260006001610a87565b8015610a24576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600080610a33610324565b6001600160e01b03199093166000908152602093909352505060409020546001600160a01b031690565b610a673382610711565b610a8457604051631b17ff5560e21b815260040160405180910390fd5b50565b6001600160a01b03831660009081526002602052604081208291846003811115610ab357610ab3611bf4565b6003811115610ac457610ac4611bf4565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610b1c93929190611e40565b60405180910390a1505050565b60005b8351811015610ca6576000848281518110610b4957610b49611c0a565b602002602001015160200151905060006003811115610b6a57610b6a611bf4565b816003811115610b7c57610b7c611bf4565b03610bca57610bc5858381518110610b9657610b96611c0a565b602002602001015160000151868481518110610bb457610bb4611c0a565b602002602001015160400151610cf1565b610c9d565b6001816003811115610bde57610bde611bf4565b03610c2757610bc5858381518110610bf857610bf8611c0a565b602002602001015160000151868481518110610c1657610c16611c0a565b602002602001015160400151610efc565b6002816003811115610c3b57610c3b611bf4565b03610c8457610bc5858381518110610c5557610c55611c0a565b602002602001015160000151868481518110610c7357610c73611c0a565b602002602001015160400151611110565b60405163609c600560e11b815260040160405180910390fd5b50600101610b2c565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610cda93929190611ebf565b60405180910390a1610cec828261126b565b505050565b6000815111610d565760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610d60610324565b90506001600160a01b038316610dcd5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003610e0857610e088285611318565b60005b8351811015610ef5576000848281518110610e2857610e28611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03168015610ece5760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c7265616479206578697374730000000000000000000000606482015260840161097e565b610eda8583868a611369565b83610ee481611f8a565b94505060019092019150610e0b9050565b5050505050565b6000815111610f615760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610f6b610324565b90506001600160a01b038316610fd85760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003611013576110138285611318565b60005b8351811015610ef557600084828151811061103357611033611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681036110de5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000606482015260840161097e565b6110e985828461140e565b6110f58583868a611369565b836110ff81611f8a565b945050600190920191506110169050565b60008151116111755760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b600061117f610324565b90506001600160a01b038316156111fe5760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d757374206265206164647265737328302900000000000000000000606482015260840161097e565b60005b825181101561126557600083828151811061121e5761121e611c0a565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031661125b84828461140e565b5050600101611201565b50505050565b6001600160a01b03821661127d575050565b611286826117ea565b600080836001600160a01b0316836040516112a19190611fb5565b600060405180830381855af49150503d80600081146112dc576040519150601f19603f3d011682016040523d82523d6000602084013e6112e1565b606091505b509150915081611265578051156112fb5780518082602001fd5b838360405163192105d760e01b815260040161097e929190611fd1565b611321816117ea565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546bffffffffffffffffffffffff909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b03821661148a5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e2774206578697374000000000000000000606482015260840161097e565b306001600160a01b038316036115085760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e000000000000000000000000000000000000606482015260840161097e565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046bffffffffffffffffffffffff16929161155c91611ff3565b9050808214611653576001600160a01b0384166000908152600186016020526040812080548390811061159157611591611c0a565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b9250829190859081106115e2576115e2611c0a565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6bffffffffffffffffffffffff8516021790555b6001600160a01b0384166000908152600186016020526040902080548061167c5761167c612006565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b03198516825286905260408120819055819003610ef55760028501546000906116df90600190611ff3565b6001600160a01b038616600090815260018089016020526040909120015490915080821461178e57600087600201838154811061171e5761171e611c0a565b6000918252602090912001546002890180546001600160a01b03909216925082918490811061174f5761174f611c0a565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b866002018054806117a1576117a1612006565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b803b6000819003610a2457604051636f7c43f160e01b815260040160405180910390fd5b60008083601f84011261182057600080fd5b50813567ffffffffffffffff81111561183857600080fd5b6020830191508360208260051b850101111561185357600080fd5b9250929050565b6000806000806000806060878903121561187357600080fd5b863567ffffffffffffffff8082111561188b57600080fd5b6118978a838b0161180e565b909850965060208901359150808211156118b057600080fd5b6118bc8a838b0161180e565b909650945060408901359150808211156118d557600080fd5b506118e289828a0161180e565b979a9699509497509295939492505050565b80356001600160a01b038116811461190b57600080fd5b919050565b60008060008060006060868803121561192857600080fd5b853567ffffffffffffffff8082111561194057600080fd5b61194c89838a0161180e565b9097509550859150611960602089016118f4565b9450604088013591508082111561197657600080fd5b818801915088601f83011261198a57600080fd5b81358181111561199957600080fd5b8960208285010111156119ab57600080fd5b9699959850939650602001949392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160a01b0316835292840192918401916001016119da565b50909695505050505050565b60008151808452602080850194506020840160005b83811015611a465781516001600160e01b03191687529582019590820190600101611a20565b509495945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015611ac257888303603f19018552815180516001600160a01b03168452870151878401879052611aaf87850182611a0b565b9588019593505090860190600101611a7a565b509098975050505050505050565b60048110610a8457600080fd5b60008060408385031215611af057600080fd5b611af9836118f4565b91506020830135611b0981611ad0565b809150509250929050565b600060208284031215611b2657600080fd5b611b2f826118f4565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160e01b03191683529284019291840191600101611b52565b600080600060608486031215611b8d57600080fd5b611b96846118f4565b92506020840135611ba681611ad0565b91506040840135611bb681611ad0565b809150509250925092565b80356001600160e01b03198116811461190b57600080fd5b600060208284031215611beb57600080fd5b611b2f82611bc1565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060208284031215611c3257600080fd5b8135611b2f81611ad0565b600060208284031215611c4f57600080fd5b81358015158114611b2f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611c9857611c98611c5f565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611cc757611cc7611c5f565b604052919050565b600067ffffffffffffffff821115611ce957611ce9611c5f565b5060051b60200190565b6000611d06611d0184611ccf565b611c9e565b83815260208082019190600586811b860136811115611d2457600080fd5b865b81811015611e1557803567ffffffffffffffff80821115611d475760008081fd5b818a01915060608236031215611d5d5760008081fd5b611d65611c75565b611d6e836118f4565b815286830135611d7d81611ad0565b8188015260408381013583811115611d955760008081fd5b939093019236601f850112611dac57600092508283fd5b83359250611dbc611d0184611ccf565b83815292871b84018801928881019036851115611dd95760008081fd5b948901945b84861015611dfe57611def86611bc1565b82529489019490890190611dde565b918301919091525088525050948301948301611d26565b5092979650505050505050565b60048110610a8457634e487b7160e01b600052602160045260246000fd5b6001600160a01b038416815260608101611e5984611e22565b8360208301528215156040830152949350505050565b60005b83811015611e8a578181015183820152602001611e72565b50506000910152565b60008151808452611eab816020860160208601611e6f565b601f01601f19169290920160200192915050565b600060608083016060845280875180835260808601915060808160051b87010192506020808a0160005b83811015611f4557888603607f19018552815180516001600160a01b0316875283810151611f1681611e22565b87850152604090810151908701889052611f3288880182611a0b565b9650509382019390820190600101611ee9565b50506001600160a01b0389169087015250508381036040850152611f698186611e93565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818103611fab57611fab611f74565b6001019392505050565b60008251611fc7818460208701611e6f565b9190910192915050565b6001600160a01b03831681526040602082015260006108ce6040830184611e93565b8181038181111561032a5761032a611f74565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220fcccfba1864229fd64de2711a9f3007b396a492619cd130ea8d3f90a161049e064736f6c63430008170033

Deployed Bytecode

0x6080604052600436106100b55760003560e01c8063a39fac1211610069578063b9c972291161004e578063b9c97229146102ac578063c4d66de8146102cc578063cdffacc6146102ec576100bc565b8063a39fac12146101ed578063adfca15e1461027f576100bc565b806352ef6b2c1161009a57806352ef6b2c146101705780637a0ed6271461019b57806395a8c58d146101bd576100bc565b8063101e6503146101305780631f931c1c14610150576100bc565b366100bc57005b60006100c6610324565b600080356001600160e01b0319168152602082905260409020549091506001600160a01b03168061010a5760405163c5723b5160e01b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610129573d6000f35b3d6000fd5b005b34801561013c57600080fd5b5061012e61014b36600461185a565b610330565b34801561015c57600080fd5b5061012e61016b366004611910565b610495565b34801561017c57600080fd5b506101856104f2565b60405161019291906119be565b60405180910390f35b3480156101a757600080fd5b506101b061055e565b6040516101929190611a51565b3480156101c957600080fd5b506101dd6101d8366004611add565b610711565b6040519015158152602001610192565b3480156101f957600080fd5b5061024d604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b0390811682526020808501518216908301529282015190921690820152606001610192565b34801561028b57600080fd5b5061029f61029a366004611b14565b610768565b6040516101929190611b36565b3480156102b857600080fd5b506101dd6102c7366004611b78565b610827565b3480156102d857600080fd5b5061012e6102e7366004611b14565b6108d6565b3480156102f857600080fd5b5061030c610307366004611bd9565b610a28565b6040516001600160a01b039091168152602001610192565b60008060fb5b92915050565b600061033b81610a5d565b858414158061034a5750858214155b1561036857604051637db491eb60e01b815260040160405180910390fd5b60005b8681101561048b57600086868381811061038757610387611c0a565b905060200201602081019061039c9190611c20565b60038111156103ad576103ad611bf4565b1480156103e85750338888838181106103c8576103c8611c0a565b90506020020160208101906103dd9190611b14565b6001600160a01b0316145b1561040657604051631eb49d6d60e11b815260040160405180910390fd5b61048388888381811061041b5761041b611c0a565b90506020020160208101906104309190611b14565b87878481811061044257610442611c0a565b90506020020160208101906104579190611c20565b86868581811061046957610469611c0a565b905060200201602081019061047e9190611c3d565b610a87565b60010161036b565b5050505050505050565b60006104a081610a5d565b6104ea6104ad8688611cf3565b8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b2992505050565b505050505050565b606060006104fe610324565b6002810180546040805160208084028201810190925282815293945083018282801561055357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610535575b505050505091505090565b6060600061056a610324565b60028101549091508067ffffffffffffffff81111561058b5761058b611c5f565b6040519080825280602002602001820160405280156105d157816020015b6040805180820190915260008152606060208201528152602001906001900390816105a95790505b50925060005b8181101561070b5760008360020182815481106105f6576105f6611c0a565b9060005260206000200160009054906101000a90046001600160a01b031690508085838151811061062957610629611c0a565b6020908102919091018101516001600160a01b0392831690529082166000908152600186018252604090819020805482518185028101850190935280835291929091908301828280156106dd57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161068a5790505b50505050508583815181106106f4576106f4611c0a565b6020908102919091018101510152506001016105d7565b50505090565b6001600160a01b03821660009081526002602052604081208183600381111561073c5761073c611bf4565b600381111561074d5761074d611bf4565b815260208101919091526040016000205460ff169392505050565b60606000610774610324565b6001600160a01b0384166000908152600182016020908152604091829020805483518184028101840190945280845293945091929083018282801561081a57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116107c75790505b5050505050915050919050565b6001600160a01b03831660009081526002602052604081208184600381111561085257610852611bf4565b600381111561086357610863611bf4565b815260208101919091526040016000205460ff16806108ce57506001600160a01b0384166000908152600260205260408120908360038111156108a8576108a8611bf4565b60038111156108b9576108b9611bf4565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff16158080156108f65750600054600160ff909116105b806109105750303b158015610910575060005460ff166001145b6109875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff1916600117905580156109aa576000805461ff0019166101001790555b6001600160a01b0382166109d157604051632c1c702960e21b815260040160405180910390fd5b6109de8260006001610a87565b8015610a24576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600080610a33610324565b6001600160e01b03199093166000908152602093909352505060409020546001600160a01b031690565b610a673382610711565b610a8457604051631b17ff5560e21b815260040160405180910390fd5b50565b6001600160a01b03831660009081526002602052604081208291846003811115610ab357610ab3611bf4565b6003811115610ac457610ac4611bf4565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610b1c93929190611e40565b60405180910390a1505050565b60005b8351811015610ca6576000848281518110610b4957610b49611c0a565b602002602001015160200151905060006003811115610b6a57610b6a611bf4565b816003811115610b7c57610b7c611bf4565b03610bca57610bc5858381518110610b9657610b96611c0a565b602002602001015160000151868481518110610bb457610bb4611c0a565b602002602001015160400151610cf1565b610c9d565b6001816003811115610bde57610bde611bf4565b03610c2757610bc5858381518110610bf857610bf8611c0a565b602002602001015160000151868481518110610c1657610c16611c0a565b602002602001015160400151610efc565b6002816003811115610c3b57610c3b611bf4565b03610c8457610bc5858381518110610c5557610c55611c0a565b602002602001015160000151868481518110610c7357610c73611c0a565b602002602001015160400151611110565b60405163609c600560e11b815260040160405180910390fd5b50600101610b2c565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610cda93929190611ebf565b60405180910390a1610cec828261126b565b505050565b6000815111610d565760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610d60610324565b90506001600160a01b038316610dcd5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003610e0857610e088285611318565b60005b8351811015610ef5576000848281518110610e2857610e28611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03168015610ece5760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c7265616479206578697374730000000000000000000000606482015260840161097e565b610eda8583868a611369565b83610ee481611f8a565b94505060019092019150610e0b9050565b5050505050565b6000815111610f615760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610f6b610324565b90506001600160a01b038316610fd85760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003611013576110138285611318565b60005b8351811015610ef557600084828151811061103357611033611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681036110de5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000606482015260840161097e565b6110e985828461140e565b6110f58583868a611369565b836110ff81611f8a565b945050600190920191506110169050565b60008151116111755760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b600061117f610324565b90506001600160a01b038316156111fe5760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d757374206265206164647265737328302900000000000000000000606482015260840161097e565b60005b825181101561126557600083828151811061121e5761121e611c0a565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031661125b84828461140e565b5050600101611201565b50505050565b6001600160a01b03821661127d575050565b611286826117ea565b600080836001600160a01b0316836040516112a19190611fb5565b600060405180830381855af49150503d80600081146112dc576040519150601f19603f3d011682016040523d82523d6000602084013e6112e1565b606091505b509150915081611265578051156112fb5780518082602001fd5b838360405163192105d760e01b815260040161097e929190611fd1565b611321816117ea565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546bffffffffffffffffffffffff909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b03821661148a5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e2774206578697374000000000000000000606482015260840161097e565b306001600160a01b038316036115085760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e000000000000000000000000000000000000606482015260840161097e565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046bffffffffffffffffffffffff16929161155c91611ff3565b9050808214611653576001600160a01b0384166000908152600186016020526040812080548390811061159157611591611c0a565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b9250829190859081106115e2576115e2611c0a565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6bffffffffffffffffffffffff8516021790555b6001600160a01b0384166000908152600186016020526040902080548061167c5761167c612006565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b03198516825286905260408120819055819003610ef55760028501546000906116df90600190611ff3565b6001600160a01b038616600090815260018089016020526040909120015490915080821461178e57600087600201838154811061171e5761171e611c0a565b6000918252602090912001546002890180546001600160a01b03909216925082918490811061174f5761174f611c0a565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b866002018054806117a1576117a1612006565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b803b6000819003610a2457604051636f7c43f160e01b815260040160405180910390fd5b60008083601f84011261182057600080fd5b50813567ffffffffffffffff81111561183857600080fd5b6020830191508360208260051b850101111561185357600080fd5b9250929050565b6000806000806000806060878903121561187357600080fd5b863567ffffffffffffffff8082111561188b57600080fd5b6118978a838b0161180e565b909850965060208901359150808211156118b057600080fd5b6118bc8a838b0161180e565b909650945060408901359150808211156118d557600080fd5b506118e289828a0161180e565b979a9699509497509295939492505050565b80356001600160a01b038116811461190b57600080fd5b919050565b60008060008060006060868803121561192857600080fd5b853567ffffffffffffffff8082111561194057600080fd5b61194c89838a0161180e565b9097509550859150611960602089016118f4565b9450604088013591508082111561197657600080fd5b818801915088601f83011261198a57600080fd5b81358181111561199957600080fd5b8960208285010111156119ab57600080fd5b9699959850939650602001949392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160a01b0316835292840192918401916001016119da565b50909695505050505050565b60008151808452602080850194506020840160005b83811015611a465781516001600160e01b03191687529582019590820190600101611a20565b509495945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015611ac257888303603f19018552815180516001600160a01b03168452870151878401879052611aaf87850182611a0b565b9588019593505090860190600101611a7a565b509098975050505050505050565b60048110610a8457600080fd5b60008060408385031215611af057600080fd5b611af9836118f4565b91506020830135611b0981611ad0565b809150509250929050565b600060208284031215611b2657600080fd5b611b2f826118f4565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160e01b03191683529284019291840191600101611b52565b600080600060608486031215611b8d57600080fd5b611b96846118f4565b92506020840135611ba681611ad0565b91506040840135611bb681611ad0565b809150509250925092565b80356001600160e01b03198116811461190b57600080fd5b600060208284031215611beb57600080fd5b611b2f82611bc1565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060208284031215611c3257600080fd5b8135611b2f81611ad0565b600060208284031215611c4f57600080fd5b81358015158114611b2f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611c9857611c98611c5f565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611cc757611cc7611c5f565b604052919050565b600067ffffffffffffffff821115611ce957611ce9611c5f565b5060051b60200190565b6000611d06611d0184611ccf565b611c9e565b83815260208082019190600586811b860136811115611d2457600080fd5b865b81811015611e1557803567ffffffffffffffff80821115611d475760008081fd5b818a01915060608236031215611d5d5760008081fd5b611d65611c75565b611d6e836118f4565b815286830135611d7d81611ad0565b8188015260408381013583811115611d955760008081fd5b939093019236601f850112611dac57600092508283fd5b83359250611dbc611d0184611ccf565b83815292871b84018801928881019036851115611dd95760008081fd5b948901945b84861015611dfe57611def86611bc1565b82529489019490890190611dde565b918301919091525088525050948301948301611d26565b5092979650505050505050565b60048110610a8457634e487b7160e01b600052602160045260246000fd5b6001600160a01b038416815260608101611e5984611e22565b8360208301528215156040830152949350505050565b60005b83811015611e8a578181015183820152602001611e72565b50506000910152565b60008151808452611eab816020860160208601611e6f565b601f01601f19169290920160200192915050565b600060608083016060845280875180835260808601915060808160051b87010192506020808a0160005b83811015611f4557888603607f19018552815180516001600160a01b0316875283810151611f1681611e22565b87850152604090810151908701889052611f3288880182611a0b565b9650509382019390820190600101611ee9565b50506001600160a01b0389169087015250508381036040850152611f698186611e93565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818103611fab57611fab611f74565b6001019392505050565b60008251611fc7818460208701611e6f565b9190910192915050565b6001600160a01b03831681526040602082015260006108ce6040830184611e93565b8181038181111561032a5761032a611f74565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220fcccfba1864229fd64de2711a9f3007b396a492619cd130ea8d3f90a161049e064736f6c63430008170033

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

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.