Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
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
Contract Source Code (Solidity Standard Json-Input format)
// 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(); } }
// 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); }
// 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; } }
// 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); } } }
// 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(); } _; } }
// 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(); } }
// 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; } }
// 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 }
// 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); }
// 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(); }
// 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(); }
// 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 { }
// 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(); }
// 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_); }
// 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); }
// 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 } }
// 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; } }
// 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; } }
// 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; } }
// 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; } }
// 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 } }
// 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 }
// 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 } }
// 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; } }
// 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; } }
// 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; } }
// 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; } }
// 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; } }
// 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; } }
// 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 {}
// 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 } } }
// 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; }
{ "optimizer": { "enabled": true, "runs": 800 }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61205280620000ed6000396000f3fe6080604052600436106100b55760003560e01c8063a39fac1211610069578063b9c972291161004e578063b9c97229146102ac578063c4d66de8146102cc578063cdffacc6146102ec576100bc565b8063a39fac12146101ed578063adfca15e1461027f576100bc565b806352ef6b2c1161009a57806352ef6b2c146101705780637a0ed6271461019b57806395a8c58d146101bd576100bc565b8063101e6503146101305780631f931c1c14610150576100bc565b366100bc57005b60006100c6610324565b600080356001600160e01b0319168152602082905260409020549091506001600160a01b03168061010a5760405163c5723b5160e01b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610129573d6000f35b3d6000fd5b005b34801561013c57600080fd5b5061012e61014b36600461185a565b610330565b34801561015c57600080fd5b5061012e61016b366004611910565b610495565b34801561017c57600080fd5b506101856104f2565b60405161019291906119be565b60405180910390f35b3480156101a757600080fd5b506101b061055e565b6040516101929190611a51565b3480156101c957600080fd5b506101dd6101d8366004611add565b610711565b6040519015158152602001610192565b3480156101f957600080fd5b5061024d604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b0390811682526020808501518216908301529282015190921690820152606001610192565b34801561028b57600080fd5b5061029f61029a366004611b14565b610768565b6040516101929190611b36565b3480156102b857600080fd5b506101dd6102c7366004611b78565b610827565b3480156102d857600080fd5b5061012e6102e7366004611b14565b6108d6565b3480156102f857600080fd5b5061030c610307366004611bd9565b610a28565b6040516001600160a01b039091168152602001610192565b60008060fb5b92915050565b600061033b81610a5d565b858414158061034a5750858214155b1561036857604051637db491eb60e01b815260040160405180910390fd5b60005b8681101561048b57600086868381811061038757610387611c0a565b905060200201602081019061039c9190611c20565b60038111156103ad576103ad611bf4565b1480156103e85750338888838181106103c8576103c8611c0a565b90506020020160208101906103dd9190611b14565b6001600160a01b0316145b1561040657604051631eb49d6d60e11b815260040160405180910390fd5b61048388888381811061041b5761041b611c0a565b90506020020160208101906104309190611b14565b87878481811061044257610442611c0a565b90506020020160208101906104579190611c20565b86868581811061046957610469611c0a565b905060200201602081019061047e9190611c3d565b610a87565b60010161036b565b5050505050505050565b60006104a081610a5d565b6104ea6104ad8688611cf3565b8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b2992505050565b505050505050565b606060006104fe610324565b6002810180546040805160208084028201810190925282815293945083018282801561055357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610535575b505050505091505090565b6060600061056a610324565b60028101549091508067ffffffffffffffff81111561058b5761058b611c5f565b6040519080825280602002602001820160405280156105d157816020015b6040805180820190915260008152606060208201528152602001906001900390816105a95790505b50925060005b8181101561070b5760008360020182815481106105f6576105f6611c0a565b9060005260206000200160009054906101000a90046001600160a01b031690508085838151811061062957610629611c0a565b6020908102919091018101516001600160a01b0392831690529082166000908152600186018252604090819020805482518185028101850190935280835291929091908301828280156106dd57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161068a5790505b50505050508583815181106106f4576106f4611c0a565b6020908102919091018101510152506001016105d7565b50505090565b6001600160a01b03821660009081526002602052604081208183600381111561073c5761073c611bf4565b600381111561074d5761074d611bf4565b815260208101919091526040016000205460ff169392505050565b60606000610774610324565b6001600160a01b0384166000908152600182016020908152604091829020805483518184028101840190945280845293945091929083018282801561081a57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116107c75790505b5050505050915050919050565b6001600160a01b03831660009081526002602052604081208184600381111561085257610852611bf4565b600381111561086357610863611bf4565b815260208101919091526040016000205460ff16806108ce57506001600160a01b0384166000908152600260205260408120908360038111156108a8576108a8611bf4565b60038111156108b9576108b9611bf4565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff16158080156108f65750600054600160ff909116105b806109105750303b158015610910575060005460ff166001145b6109875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff1916600117905580156109aa576000805461ff0019166101001790555b6001600160a01b0382166109d157604051632c1c702960e21b815260040160405180910390fd5b6109de8260006001610a87565b8015610a24576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600080610a33610324565b6001600160e01b03199093166000908152602093909352505060409020546001600160a01b031690565b610a673382610711565b610a8457604051631b17ff5560e21b815260040160405180910390fd5b50565b6001600160a01b03831660009081526002602052604081208291846003811115610ab357610ab3611bf4565b6003811115610ac457610ac4611bf4565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610b1c93929190611e40565b60405180910390a1505050565b60005b8351811015610ca6576000848281518110610b4957610b49611c0a565b602002602001015160200151905060006003811115610b6a57610b6a611bf4565b816003811115610b7c57610b7c611bf4565b03610bca57610bc5858381518110610b9657610b96611c0a565b602002602001015160000151868481518110610bb457610bb4611c0a565b602002602001015160400151610cf1565b610c9d565b6001816003811115610bde57610bde611bf4565b03610c2757610bc5858381518110610bf857610bf8611c0a565b602002602001015160000151868481518110610c1657610c16611c0a565b602002602001015160400151610efc565b6002816003811115610c3b57610c3b611bf4565b03610c8457610bc5858381518110610c5557610c55611c0a565b602002602001015160000151868481518110610c7357610c73611c0a565b602002602001015160400151611110565b60405163609c600560e11b815260040160405180910390fd5b50600101610b2c565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610cda93929190611ebf565b60405180910390a1610cec828261126b565b505050565b6000815111610d565760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610d60610324565b90506001600160a01b038316610dcd5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003610e0857610e088285611318565b60005b8351811015610ef5576000848281518110610e2857610e28611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03168015610ece5760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c7265616479206578697374730000000000000000000000606482015260840161097e565b610eda8583868a611369565b83610ee481611f8a565b94505060019092019150610e0b9050565b5050505050565b6000815111610f615760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610f6b610324565b90506001600160a01b038316610fd85760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003611013576110138285611318565b60005b8351811015610ef557600084828151811061103357611033611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681036110de5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000606482015260840161097e565b6110e985828461140e565b6110f58583868a611369565b836110ff81611f8a565b945050600190920191506110169050565b60008151116111755760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b600061117f610324565b90506001600160a01b038316156111fe5760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d757374206265206164647265737328302900000000000000000000606482015260840161097e565b60005b825181101561126557600083828151811061121e5761121e611c0a565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031661125b84828461140e565b5050600101611201565b50505050565b6001600160a01b03821661127d575050565b611286826117ea565b600080836001600160a01b0316836040516112a19190611fb5565b600060405180830381855af49150503d80600081146112dc576040519150601f19603f3d011682016040523d82523d6000602084013e6112e1565b606091505b509150915081611265578051156112fb5780518082602001fd5b838360405163192105d760e01b815260040161097e929190611fd1565b611321816117ea565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546bffffffffffffffffffffffff909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b03821661148a5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e2774206578697374000000000000000000606482015260840161097e565b306001600160a01b038316036115085760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e000000000000000000000000000000000000606482015260840161097e565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046bffffffffffffffffffffffff16929161155c91611ff3565b9050808214611653576001600160a01b0384166000908152600186016020526040812080548390811061159157611591611c0a565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b9250829190859081106115e2576115e2611c0a565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6bffffffffffffffffffffffff8516021790555b6001600160a01b0384166000908152600186016020526040902080548061167c5761167c612006565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b03198516825286905260408120819055819003610ef55760028501546000906116df90600190611ff3565b6001600160a01b038616600090815260018089016020526040909120015490915080821461178e57600087600201838154811061171e5761171e611c0a565b6000918252602090912001546002890180546001600160a01b03909216925082918490811061174f5761174f611c0a565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b866002018054806117a1576117a1612006565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b803b6000819003610a2457604051636f7c43f160e01b815260040160405180910390fd5b60008083601f84011261182057600080fd5b50813567ffffffffffffffff81111561183857600080fd5b6020830191508360208260051b850101111561185357600080fd5b9250929050565b6000806000806000806060878903121561187357600080fd5b863567ffffffffffffffff8082111561188b57600080fd5b6118978a838b0161180e565b909850965060208901359150808211156118b057600080fd5b6118bc8a838b0161180e565b909650945060408901359150808211156118d557600080fd5b506118e289828a0161180e565b979a9699509497509295939492505050565b80356001600160a01b038116811461190b57600080fd5b919050565b60008060008060006060868803121561192857600080fd5b853567ffffffffffffffff8082111561194057600080fd5b61194c89838a0161180e565b9097509550859150611960602089016118f4565b9450604088013591508082111561197657600080fd5b818801915088601f83011261198a57600080fd5b81358181111561199957600080fd5b8960208285010111156119ab57600080fd5b9699959850939650602001949392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160a01b0316835292840192918401916001016119da565b50909695505050505050565b60008151808452602080850194506020840160005b83811015611a465781516001600160e01b03191687529582019590820190600101611a20565b509495945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015611ac257888303603f19018552815180516001600160a01b03168452870151878401879052611aaf87850182611a0b565b9588019593505090860190600101611a7a565b509098975050505050505050565b60048110610a8457600080fd5b60008060408385031215611af057600080fd5b611af9836118f4565b91506020830135611b0981611ad0565b809150509250929050565b600060208284031215611b2657600080fd5b611b2f826118f4565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160e01b03191683529284019291840191600101611b52565b600080600060608486031215611b8d57600080fd5b611b96846118f4565b92506020840135611ba681611ad0565b91506040840135611bb681611ad0565b809150509250925092565b80356001600160e01b03198116811461190b57600080fd5b600060208284031215611beb57600080fd5b611b2f82611bc1565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060208284031215611c3257600080fd5b8135611b2f81611ad0565b600060208284031215611c4f57600080fd5b81358015158114611b2f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611c9857611c98611c5f565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611cc757611cc7611c5f565b604052919050565b600067ffffffffffffffff821115611ce957611ce9611c5f565b5060051b60200190565b6000611d06611d0184611ccf565b611c9e565b83815260208082019190600586811b860136811115611d2457600080fd5b865b81811015611e1557803567ffffffffffffffff80821115611d475760008081fd5b818a01915060608236031215611d5d5760008081fd5b611d65611c75565b611d6e836118f4565b815286830135611d7d81611ad0565b8188015260408381013583811115611d955760008081fd5b939093019236601f850112611dac57600092508283fd5b83359250611dbc611d0184611ccf565b83815292871b84018801928881019036851115611dd95760008081fd5b948901945b84861015611dfe57611def86611bc1565b82529489019490890190611dde565b918301919091525088525050948301948301611d26565b5092979650505050505050565b60048110610a8457634e487b7160e01b600052602160045260246000fd5b6001600160a01b038416815260608101611e5984611e22565b8360208301528215156040830152949350505050565b60005b83811015611e8a578181015183820152602001611e72565b50506000910152565b60008151808452611eab816020860160208601611e6f565b601f01601f19169290920160200192915050565b600060608083016060845280875180835260808601915060808160051b87010192506020808a0160005b83811015611f4557888603607f19018552815180516001600160a01b0316875283810151611f1681611e22565b87850152604090810151908701889052611f3288880182611a0b565b9650509382019390820190600101611ee9565b50506001600160a01b0389169087015250508381036040850152611f698186611e93565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818103611fab57611fab611f74565b6001019392505050565b60008251611fc7818460208701611e6f565b9190910192915050565b6001600160a01b03831681526040602082015260006108ce6040830184611e93565b8181038181111561032a5761032a611f74565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220fcccfba1864229fd64de2711a9f3007b396a492619cd130ea8d3f90a161049e064736f6c63430008170033
Deployed Bytecode
0x6080604052600436106100b55760003560e01c8063a39fac1211610069578063b9c972291161004e578063b9c97229146102ac578063c4d66de8146102cc578063cdffacc6146102ec576100bc565b8063a39fac12146101ed578063adfca15e1461027f576100bc565b806352ef6b2c1161009a57806352ef6b2c146101705780637a0ed6271461019b57806395a8c58d146101bd576100bc565b8063101e6503146101305780631f931c1c14610150576100bc565b366100bc57005b60006100c6610324565b600080356001600160e01b0319168152602082905260409020549091506001600160a01b03168061010a5760405163c5723b5160e01b815260040160405180910390fd5b3660008037600080366000845af43d6000803e808015610129573d6000f35b3d6000fd5b005b34801561013c57600080fd5b5061012e61014b36600461185a565b610330565b34801561015c57600080fd5b5061012e61016b366004611910565b610495565b34801561017c57600080fd5b506101856104f2565b60405161019291906119be565b60405180910390f35b3480156101a757600080fd5b506101b061055e565b6040516101929190611a51565b3480156101c957600080fd5b506101dd6101d8366004611add565b610711565b6040519015158152602001610192565b3480156101f957600080fd5b5061024d604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b0390811682526020808501518216908301529282015190921690820152606001610192565b34801561028b57600080fd5b5061029f61029a366004611b14565b610768565b6040516101929190611b36565b3480156102b857600080fd5b506101dd6102c7366004611b78565b610827565b3480156102d857600080fd5b5061012e6102e7366004611b14565b6108d6565b3480156102f857600080fd5b5061030c610307366004611bd9565b610a28565b6040516001600160a01b039091168152602001610192565b60008060fb5b92915050565b600061033b81610a5d565b858414158061034a5750858214155b1561036857604051637db491eb60e01b815260040160405180910390fd5b60005b8681101561048b57600086868381811061038757610387611c0a565b905060200201602081019061039c9190611c20565b60038111156103ad576103ad611bf4565b1480156103e85750338888838181106103c8576103c8611c0a565b90506020020160208101906103dd9190611b14565b6001600160a01b0316145b1561040657604051631eb49d6d60e11b815260040160405180910390fd5b61048388888381811061041b5761041b611c0a565b90506020020160208101906104309190611b14565b87878481811061044257610442611c0a565b90506020020160208101906104579190611c20565b86868581811061046957610469611c0a565b905060200201602081019061047e9190611c3d565b610a87565b60010161036b565b5050505050505050565b60006104a081610a5d565b6104ea6104ad8688611cf3565b8585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610b2992505050565b505050505050565b606060006104fe610324565b6002810180546040805160208084028201810190925282815293945083018282801561055357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610535575b505050505091505090565b6060600061056a610324565b60028101549091508067ffffffffffffffff81111561058b5761058b611c5f565b6040519080825280602002602001820160405280156105d157816020015b6040805180820190915260008152606060208201528152602001906001900390816105a95790505b50925060005b8181101561070b5760008360020182815481106105f6576105f6611c0a565b9060005260206000200160009054906101000a90046001600160a01b031690508085838151811061062957610629611c0a565b6020908102919091018101516001600160a01b0392831690529082166000908152600186018252604090819020805482518185028101850190935280835291929091908301828280156106dd57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168152602001906004019060208260030104928301926001038202915080841161068a5790505b50505050508583815181106106f4576106f4611c0a565b6020908102919091018101510152506001016105d7565b50505090565b6001600160a01b03821660009081526002602052604081208183600381111561073c5761073c611bf4565b600381111561074d5761074d611bf4565b815260208101919091526040016000205460ff169392505050565b60606000610774610324565b6001600160a01b0384166000908152600182016020908152604091829020805483518184028101840190945280845293945091929083018282801561081a57602002820191906000526020600020906000905b82829054906101000a900460e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190600401906020826003010492830192600103820291508084116107c75790505b5050505050915050919050565b6001600160a01b03831660009081526002602052604081208184600381111561085257610852611bf4565b600381111561086357610863611bf4565b815260208101919091526040016000205460ff16806108ce57506001600160a01b0384166000908152600260205260408120908360038111156108a8576108a8611bf4565b60038111156108b9576108b9611bf4565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff16158080156108f65750600054600160ff909116105b806109105750303b158015610910575060005460ff166001145b6109875760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff1916600117905580156109aa576000805461ff0019166101001790555b6001600160a01b0382166109d157604051632c1c702960e21b815260040160405180910390fd5b6109de8260006001610a87565b8015610a24576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b600080610a33610324565b6001600160e01b03199093166000908152602093909352505060409020546001600160a01b031690565b610a673382610711565b610a8457604051631b17ff5560e21b815260040160405180910390fd5b50565b6001600160a01b03831660009081526002602052604081208291846003811115610ab357610ab3611bf4565b6003811115610ac457610ac4611bf4565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610b1c93929190611e40565b60405180910390a1505050565b60005b8351811015610ca6576000848281518110610b4957610b49611c0a565b602002602001015160200151905060006003811115610b6a57610b6a611bf4565b816003811115610b7c57610b7c611bf4565b03610bca57610bc5858381518110610b9657610b96611c0a565b602002602001015160000151868481518110610bb457610bb4611c0a565b602002602001015160400151610cf1565b610c9d565b6001816003811115610bde57610bde611bf4565b03610c2757610bc5858381518110610bf857610bf8611c0a565b602002602001015160000151868481518110610c1657610c16611c0a565b602002602001015160400151610efc565b6002816003811115610c3b57610c3b611bf4565b03610c8457610bc5858381518110610c5557610c55611c0a565b602002602001015160000151868481518110610c7357610c73611c0a565b602002602001015160400151611110565b60405163609c600560e11b815260040160405180910390fd5b50600101610b2c565b507f8faa70878671ccd212d20771b795c50af8fd3ff6cf27f4bde57e5d4de0aeb673838383604051610cda93929190611ebf565b60405180910390a1610cec828261126b565b505050565b6000815111610d565760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610d60610324565b90506001600160a01b038316610dcd5760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003610e0857610e088285611318565b60005b8351811015610ef5576000848281518110610e2857610e28611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b03168015610ece5760405162461bcd60e51b815260206004820152603560248201527f4c69624469616d6f6e644375743a2043616e2774206164642066756e6374696f60448201527f6e207468617420616c7265616479206578697374730000000000000000000000606482015260840161097e565b610eda8583868a611369565b83610ee481611f8a565b94505060019092019150610e0b9050565b5050505050565b6000815111610f615760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b6000610f6b610324565b90506001600160a01b038316610fd85760405162461bcd60e51b815260206004820152602c60248201527f4c69624469616d6f6e644375743a204164642066616365742063616e2774206260448201526b65206164647265737328302960a01b606482015260840161097e565b6001600160a01b0383166000908152600182016020526040812054906bffffffffffffffffffffffff82169003611013576110138285611318565b60005b8351811015610ef557600084828151811061103357611033611c0a565b6020908102919091018101516001600160e01b031981166000908152918690526040909120549091506001600160a01b0390811690871681036110de5760405162461bcd60e51b815260206004820152603860248201527f4c69624469616d6f6e644375743a2043616e2774207265706c6163652066756e60448201527f6374696f6e20776974682073616d652066756e6374696f6e0000000000000000606482015260840161097e565b6110e985828461140e565b6110f58583868a611369565b836110ff81611f8a565b945050600190920191506110169050565b60008151116111755760405162461bcd60e51b815260206004820152602b60248201527f4c69624469616d6f6e644375743a204e6f2073656c6563746f727320696e206660448201526a1858d95d081d1bc818dd5d60aa1b606482015260840161097e565b600061117f610324565b90506001600160a01b038316156111fe5760405162461bcd60e51b815260206004820152603660248201527f4c69624469616d6f6e644375743a2052656d6f7665206661636574206164647260448201527f657373206d757374206265206164647265737328302900000000000000000000606482015260840161097e565b60005b825181101561126557600083828151811061121e5761121e611c0a565b6020908102919091018101516001600160e01b031981166000908152918590526040909120549091506001600160a01b031661125b84828461140e565b5050600101611201565b50505050565b6001600160a01b03821661127d575050565b611286826117ea565b600080836001600160a01b0316836040516112a19190611fb5565b600060405180830381855af49150503d80600081146112dc576040519150601f19603f3d011682016040523d82523d6000602084013e6112e1565b606091505b509150915081611265578051156112fb5780518082602001fd5b838360405163192105d760e01b815260040161097e929190611fd1565b611321816117ea565b6002820180546001600160a01b0390921660008181526001948501602090815260408220860185905594840183559182529290200180546001600160a01b0319169091179055565b6001600160e01b0319831660008181526020868152604080832080546bffffffffffffffffffffffff909716600160a01b026001600160a01b0397881617815594909516808352600180890183529583208054968701815583528183206008870401805460e09890981c60046007909816979097026101000a96870263ffffffff9097021990971695909517909555529290915281546001600160a01b031916179055565b6001600160a01b03821661148a5760405162461bcd60e51b815260206004820152603760248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f76652066756e6360448201527f74696f6e207468617420646f65736e2774206578697374000000000000000000606482015260840161097e565b306001600160a01b038316036115085760405162461bcd60e51b815260206004820152602e60248201527f4c69624469616d6f6e644375743a2043616e27742072656d6f766520696d6d7560448201527f7461626c652066756e6374696f6e000000000000000000000000000000000000606482015260840161097e565b6001600160e01b03198116600090815260208481526040808320546001600160a01b0386168452600180880190935290832054600160a01b9091046bffffffffffffffffffffffff16929161155c91611ff3565b9050808214611653576001600160a01b0384166000908152600186016020526040812080548390811061159157611591611c0a565b600091825260208083206008830401546001600160a01b038916845260018a019091526040909220805460079092166004026101000a90920460e01b9250829190859081106115e2576115e2611c0a565b600091825260208083206008830401805463ffffffff60079094166004026101000a938402191660e09590951c929092029390931790556001600160e01b03199290921682528690526040902080546001600160a01b0316600160a01b6bffffffffffffffffffffffff8516021790555b6001600160a01b0384166000908152600186016020526040902080548061167c5761167c612006565b60008281526020808220600860001990940193840401805463ffffffff600460078716026101000a0219169055919092556001600160e01b03198516825286905260408120819055819003610ef55760028501546000906116df90600190611ff3565b6001600160a01b038616600090815260018089016020526040909120015490915080821461178e57600087600201838154811061171e5761171e611c0a565b6000918252602090912001546002890180546001600160a01b03909216925082918490811061174f5761174f611c0a565b600091825260208083209190910180546001600160a01b0319166001600160a01b03948516179055929091168152600189810190925260409020018190555b866002018054806117a1576117a1612006565b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0388168252600189810190915260408220015550505050505050565b803b6000819003610a2457604051636f7c43f160e01b815260040160405180910390fd5b60008083601f84011261182057600080fd5b50813567ffffffffffffffff81111561183857600080fd5b6020830191508360208260051b850101111561185357600080fd5b9250929050565b6000806000806000806060878903121561187357600080fd5b863567ffffffffffffffff8082111561188b57600080fd5b6118978a838b0161180e565b909850965060208901359150808211156118b057600080fd5b6118bc8a838b0161180e565b909650945060408901359150808211156118d557600080fd5b506118e289828a0161180e565b979a9699509497509295939492505050565b80356001600160a01b038116811461190b57600080fd5b919050565b60008060008060006060868803121561192857600080fd5b853567ffffffffffffffff8082111561194057600080fd5b61194c89838a0161180e565b9097509550859150611960602089016118f4565b9450604088013591508082111561197657600080fd5b818801915088601f83011261198a57600080fd5b81358181111561199957600080fd5b8960208285010111156119ab57600080fd5b9699959850939650602001949392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160a01b0316835292840192918401916001016119da565b50909695505050505050565b60008151808452602080850194506020840160005b83811015611a465781516001600160e01b03191687529582019590820190600101611a20565b509495945050505050565b600060208083018184528085518083526040925060408601915060408160051b87010184880160005b83811015611ac257888303603f19018552815180516001600160a01b03168452870151878401879052611aaf87850182611a0b565b9588019593505090860190600101611a7a565b509098975050505050505050565b60048110610a8457600080fd5b60008060408385031215611af057600080fd5b611af9836118f4565b91506020830135611b0981611ad0565b809150509250929050565b600060208284031215611b2657600080fd5b611b2f826118f4565b9392505050565b6020808252825182820181905260009190848201906040850190845b818110156119ff5783516001600160e01b03191683529284019291840191600101611b52565b600080600060608486031215611b8d57600080fd5b611b96846118f4565b92506020840135611ba681611ad0565b91506040840135611bb681611ad0565b809150509250925092565b80356001600160e01b03198116811461190b57600080fd5b600060208284031215611beb57600080fd5b611b2f82611bc1565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b600060208284031215611c3257600080fd5b8135611b2f81611ad0565b600060208284031215611c4f57600080fd5b81358015158114611b2f57600080fd5b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff81118282101715611c9857611c98611c5f565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715611cc757611cc7611c5f565b604052919050565b600067ffffffffffffffff821115611ce957611ce9611c5f565b5060051b60200190565b6000611d06611d0184611ccf565b611c9e565b83815260208082019190600586811b860136811115611d2457600080fd5b865b81811015611e1557803567ffffffffffffffff80821115611d475760008081fd5b818a01915060608236031215611d5d5760008081fd5b611d65611c75565b611d6e836118f4565b815286830135611d7d81611ad0565b8188015260408381013583811115611d955760008081fd5b939093019236601f850112611dac57600092508283fd5b83359250611dbc611d0184611ccf565b83815292871b84018801928881019036851115611dd95760008081fd5b948901945b84861015611dfe57611def86611bc1565b82529489019490890190611dde565b918301919091525088525050948301948301611d26565b5092979650505050505050565b60048110610a8457634e487b7160e01b600052602160045260246000fd5b6001600160a01b038416815260608101611e5984611e22565b8360208301528215156040830152949350505050565b60005b83811015611e8a578181015183820152602001611e72565b50506000910152565b60008151808452611eab816020860160208601611e6f565b601f01601f19169290920160200192915050565b600060608083016060845280875180835260808601915060808160051b87010192506020808a0160005b83811015611f4557888603607f19018552815180516001600160a01b0316875283810151611f1681611e22565b87850152604090810151908701889052611f3288880182611a0b565b9650509382019390820190600101611ee9565b50506001600160a01b0389169087015250508381036040850152611f698186611e93565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b60006bffffffffffffffffffffffff808316818103611fab57611fab611f74565b6001019392505050565b60008251611fc7818460208701611e6f565b9190910192915050565b6001600160a01b03831681526040602082015260006108ce6040830184611e93565b8181038181111561032a5761032a611f74565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220fcccfba1864229fd64de2711a9f3007b396a492619cd130ea8d3f90a161049e064736f6c63430008170033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.