Overview
APE Balance
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
GNSReferrals
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 {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../abstract/GNSAddressStore.sol"; import "../../interfaces/libraries/IReferralsUtils.sol"; import "../../libraries/ReferralsUtils.sol"; /** * @dev Facet #2: Referral system */ contract GNSReferrals is GNSAddressStore, IReferralsUtils { // Initialization /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } /// @inheritdoc IReferralsUtils function initializeReferrals( uint256 _allyFeeP, uint256 _startReferrerFeeP, uint256 _targetVolumeUsd ) external reinitializer(3) { ReferralsUtils.initializeReferrals(_allyFeeP, _startReferrerFeeP, _targetVolumeUsd); } // Management Setters /// @inheritdoc IReferralsUtils function updateAllyFeeP(uint256 _value) external onlyRole(Role.GOV) { ReferralsUtils.updateAllyFeeP(_value); } /// @inheritdoc IReferralsUtils function updateStartReferrerFeeP(uint256 _value) external onlyRole(Role.GOV) { ReferralsUtils.updateStartReferrerFeeP(_value); } /// @inheritdoc IReferralsUtils function updateReferralsTargetVolumeUsd(uint256 _value) external onlyRole(Role.GOV) { ReferralsUtils.updateReferralsTargetVolumeUsd(_value); } /// @inheritdoc IReferralsUtils function whitelistAllies(address[] calldata _allies) external onlyRole(Role.GOV) { ReferralsUtils.whitelistAllies(_allies); } /// @inheritdoc IReferralsUtils function unwhitelistAllies(address[] calldata _allies) external onlyRole(Role.GOV) { ReferralsUtils.unwhitelistAllies(_allies); } /// @inheritdoc IReferralsUtils function whitelistReferrers(address[] calldata _referrers, address[] calldata _allies) external onlyRole(Role.GOV) { ReferralsUtils.whitelistReferrers(_referrers, _allies); } /// @inheritdoc IReferralsUtils function unwhitelistReferrers(address[] calldata _referrers) external onlyRole(Role.GOV) { ReferralsUtils.unwhitelistReferrers(_referrers); } /// @inheritdoc IReferralsUtils function overrideReferralFeeP(address[] calldata _referrers, uint24[] calldata _referralFeeP) external onlyRole(Role.GOV) { ReferralsUtils.overrideReferralFeeP(_referrers, _referralFeeP); } /// @inheritdoc IReferralsUtils function overrideAllyFeeP(address[] calldata _allies, uint24[] calldata _allyFeeP) external onlyRole(Role.GOV) { ReferralsUtils.overrideAllyFeeP(_allies, _allyFeeP); } // Interactions /// @inheritdoc IReferralsUtils function registerPotentialReferrer(address _trader, address _referrer) external virtual onlySelf { ReferralsUtils.registerPotentialReferrer(_trader, _referrer); } /// @inheritdoc IReferralsUtils function distributeReferralReward( address _trader, uint256 _volumeUsd, uint256 _referrerFeeUsd, uint256 _gnsPriceUsd ) external virtual onlySelf { return ReferralsUtils.distributeReferralReward(_trader, _volumeUsd, _referrerFeeUsd, _gnsPriceUsd); } /// @inheritdoc IReferralsUtils function claimAllyRewards() external { ReferralsUtils.claimAllyRewards(); } /// @inheritdoc IReferralsUtils function claimReferrerRewards() external { ReferralsUtils.claimReferrerRewards(); } // Getters /// @inheritdoc IReferralsUtils function getReferrerFeeProgressP(address _referrer) external view returns (uint256) { return ReferralsUtils.getReferrerFeeProgressP(_referrer); } /// @inheritdoc IReferralsUtils function getTraderLastReferrer(address _trader) external view returns (address) { return ReferralsUtils.getTraderLastReferrer(_trader); } /// @inheritdoc IReferralsUtils function getTraderActiveReferrer(address _trader) external view returns (address) { return ReferralsUtils.getTraderActiveReferrer(_trader); } /// @inheritdoc IReferralsUtils function getReferrersReferred(address _ally) external view returns (address[] memory) { return ReferralsUtils.getReferrersReferred(_ally); } /// @inheritdoc IReferralsUtils function getTradersReferred(address _referrer) external view returns (address[] memory) { return ReferralsUtils.getTradersReferred(_referrer); } /// @inheritdoc IReferralsUtils function getReferralsAllyFeeP() external view returns (uint256) { return ReferralsUtils.getReferralsAllyFeeP(); } /// @inheritdoc IReferralsUtils function getReferralsStartReferrerFeeP() external view returns (uint256) { return ReferralsUtils.getReferralsStartReferrerFeeP(); } /// @inheritdoc IReferralsUtils function getReferralsTargetVolumeUsd() external view returns (uint256) { return ReferralsUtils.getReferralsTargetVolumeUsd(); } /// @inheritdoc IReferralsUtils function getAllyDetails(address _ally) external view returns (AllyDetails memory) { return ReferralsUtils.getAllyDetails(_ally); } /// @inheritdoc IReferralsUtils function getReferrerDetails(address _referrer) external view returns (ReferrerDetails memory) { return ReferralsUtils.getReferrerDetails(_referrer); } /// @inheritdoc IReferralsUtils function getReferralSettingsOverrides(address _address) external view returns (ReferralSettingsOverrides memory) { return ReferralsUtils.getReferralSettingsOverrides(_address); } }
// 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 // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// 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 Address { /** * @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 {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface for ERC20 tokens */ interface IERC20 is IERC20Metadata { function burn(address, uint256) external; function mint(address, uint256) external; function hasRole(bytes32, address) external view returns (bool); }
// 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 "../types/IReferrals.sol"; /** * @dev Interface for GNSReferrals facet (inherits types and also contains functions, events, and custom errors) */ interface IReferralsUtils is IReferrals { /** * * @param _allyFeeP % of total referral fee going to ally * @param _startReferrerFeeP initial % of total referral fee earned when zero volume referred * @param _targetVolumeUsd usd opening volume to refer to reach 100% of referral fee */ function initializeReferrals(uint256 _allyFeeP, uint256 _startReferrerFeeP, uint256 _targetVolumeUsd) external; /** * @dev Updates allyFeeP * @param _value new ally fee % */ function updateAllyFeeP(uint256 _value) external; /** * @dev Updates startReferrerFeeP * @param _value new start referrer fee % */ function updateStartReferrerFeeP(uint256 _value) external; /** * @dev Updates targetVolumeUsd * @param _value new target volume in usd */ function updateReferralsTargetVolumeUsd(uint256 _value) external; /** * @dev Whitelists ally addresses * @param _allies array of ally addresses */ function whitelistAllies(address[] calldata _allies) external; /** * @dev Unwhitelists ally addresses * @param _allies array of ally addresses */ function unwhitelistAllies(address[] calldata _allies) external; /** * @dev Whitelists referrer addresses * @param _referrers array of referrer addresses * @param _allies array of corresponding ally addresses */ function whitelistReferrers(address[] calldata _referrers, address[] calldata _allies) external; /** * @dev Unwhitelists referrer addresses * @param _referrers array of referrer addresses */ function unwhitelistReferrers(address[] calldata _referrers) external; /** * @dev Overrides referral fee % share of total trading fee for referrers * @param _referrers array of referrer addresses * @param _referralFeeP array of referral fee % (1e3) */ function overrideReferralFeeP(address[] calldata _referrers, uint24[] calldata _referralFeeP) external; /** * @dev Overrides ally fee % share of total trading fee for allies * @param _allies array of ally addresses * @param _allyFeeP array of ally fee % (1e3) */ function overrideAllyFeeP(address[] calldata _allies, uint24[] calldata _allyFeeP) external; /** * @dev Registers potential referrer for trader (only works if trader wasn't referred yet by someone else) * @param _trader trader address * @param _referral referrer address */ function registerPotentialReferrer(address _trader, address _referral) external; /** * @dev Distributes ally and referrer rewards * @param _trader trader address * @param _volumeUsd trading volume in usd (1e18 precision) * @param _referrerFeeUsd referrer fee in USD (1e18 precision) * @param _gnsPriceUsd token price in usd (1e10 precision) */ function distributeReferralReward( address _trader, uint256 _volumeUsd, // 1e18 uint256 _referrerFeeUsd, uint256 _gnsPriceUsd // 1e10 ) external; /** * @dev Claims pending GNS ally rewards of caller */ function claimAllyRewards() external; /** * @dev Claims pending GNS referrer rewards of caller */ function claimReferrerRewards() external; /** * @dev Returns referrer fee % progress towards earning 100% based on his volume referred (1e10) * @param _referrer referrer address */ function getReferrerFeeProgressP(address _referrer) external view returns (uint256); /** * @dev Returns last referrer of trader (whether referrer active or not) * @param _trader address of trader */ function getTraderLastReferrer(address _trader) external view returns (address); /** * @dev Returns active referrer of trader * @param _trader address of trader */ function getTraderActiveReferrer(address _trader) external view returns (address); /** * @dev Returns referrers referred by ally * @param _ally address of ally */ function getReferrersReferred(address _ally) external view returns (address[] memory); /** * @dev Returns traders referred by referrer * @param _referrer address of referrer */ function getTradersReferred(address _referrer) external view returns (address[] memory); /** * @dev Returns ally fee % of total referral fee */ function getReferralsAllyFeeP() external view returns (uint256); /** * @dev Returns start referrer fee % of total referral fee when zero volume was referred */ function getReferralsStartReferrerFeeP() external view returns (uint256); /** * @dev Returns target volume in usd to reach 100% of referral fee */ function getReferralsTargetVolumeUsd() external view returns (uint256); /** * @dev Returns ally details * @param _ally address of ally */ function getAllyDetails(address _ally) external view returns (AllyDetails memory); /** * @dev Returns referrer details * @param _referrer address of referrer */ function getReferrerDetails(address _referrer) external view returns (ReferrerDetails memory); /** * @dev Returns referral settings overrides * @param _address address of referrer/ally */ function getReferralSettingsOverrides(address _address) external view returns (ReferralSettingsOverrides memory); /** * @dev Emitted when allyFeeP is updated * @param value new ally fee % */ event UpdatedAllyFeeP(uint256 value); /** * @dev Emitted when startReferrerFeeP is updated * @param value new start referrer fee % */ event UpdatedStartReferrerFeeP(uint256 value); /** * @dev Emitted when openFeeP is updated * @param value new open fee % */ event UpdatedOpenFeeP(uint256 value); /** * @dev Emitted when targetVolumeUsd is updated * @param value new target volume in usd */ event UpdatedTargetVolumeUsd(uint256 value); /** * @dev Emitted when an ally is whitelisted * @param ally ally address */ event AllyWhitelisted(address indexed ally); /** * @dev Emitted when an ally is unwhitelisted * @param ally ally address */ event AllyUnwhitelisted(address indexed ally); /** * @dev Emitted when a referrer is whitelisted * @param referrer referrer address * @param ally ally address */ event ReferrerWhitelisted(address indexed referrer, address indexed ally); /** * @dev Emitted when a referrer is unwhitelisted * @param referrer referrer address */ event ReferrerUnwhitelisted(address indexed referrer); /** * @dev Emitted when a trader has a new active referrer */ event ReferrerRegistered(address indexed trader, address indexed referrer); /** * @dev Emitted when ally rewards are distributed for a trade * @param ally address of ally * @param trader address of trader * @param volumeUsd trade volume in usd (1e18 precision) * @param amountGns amount of GNS reward (1e18 precision) * @param amountValueUsd USD value of GNS reward (1e18 precision) */ event AllyRewardDistributed( address indexed ally, address indexed trader, uint256 volumeUsd, uint256 amountGns, uint256 amountValueUsd ); /** * @dev Emitted when referrer rewards are distributed for a trade * @param referrer address of referrer * @param trader address of trader * @param volumeUsd trade volume in usd (1e18 precision) * @param amountGns amount of GNS reward (1e18 precision) * @param amountValueUsd USD value of GNS reward (1e18 precision) */ event ReferrerRewardDistributed( address indexed referrer, address indexed trader, uint256 volumeUsd, uint256 amountGns, uint256 amountValueUsd ); /** * @dev Emitted when an ally claims his pending rewards * @param ally address of ally * @param amountGns GNS pending rewards amount */ event AllyRewardsClaimed(address indexed ally, uint256 amountGns); /** * @dev Emitted when a referrer claims his pending rewards * @param referrer address of referrer * @param amountGns GNS pending rewards amount */ event ReferrerRewardsClaimed(address indexed referrer, uint256 amountGns); /** * @dev Emitted when a referrer fee % is overridden * @param referrer referrer address * @param referralFeeP new referral fee % (1e3) */ event OverrodeReferralFeeP(address indexed referrer, uint24 referralFeeP); /** * @dev Emitted when an ally fee % is overridden * @param ally ally address * @param allyFeeP new ally fee % (1e3) */ event OverrodeAllyFeeP(address indexed ally, uint24 allyFeeP); error NoPendingRewards(); error AlreadyActive(); error AlreadyInactive(); error AllyNotActive(); }
// 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; /** * @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; /** * @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) mapping(address => ReferralSettingsOverrides) referralSettingsOverrides; uint256[42] __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; } struct ReferralSettingsOverrides { uint24 referralFeeOverrideP; // % of total trading fee (1e3), 0 means it uses globalTradeFeeParams value uint24 allyFeeOverrideP; // % of total trading fee (1e3), 0 means it uses default allyFeeP value uint208 __placeholder; } }
// 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; import "../interfaces/types/IAddressStore.sol"; import "./StorageUtils.sol"; /** * * @dev GNSAddressStore facet internal library */ library AddressStoreUtils { /** * @dev Returns storage slot to use when fetching addresses */ function _getSlot() internal pure returns (uint256) { return StorageUtils.GLOBAL_ADDRESSES_SLOT; } /** * @dev Returns storage pointer for Addresses struct in global diamond contract, at defined slot */ function getAddresses() internal pure returns (IAddressStore.Addresses storage s) { uint256 storageSlot = _getSlot(); assembly { s.slot := storageSlot } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; import "../interfaces/types/ITradingStorage.sol"; /** * * @dev Internal library for important constants commonly used in many places */ library ConstantsUtils { uint256 internal constant P_10 = 1e10; // 10 decimals (DO NOT UPDATE) uint256 internal constant SL_LIQ_BUFFER_P = 10 * P_10; // SL has to be 10% closer than liq price uint256 internal constant LEGACY_LIQ_THRESHOLD_P = 90 * P_10; // -90% pnl uint256 internal constant MIN_LIQ_THRESHOLD_P = 50 * P_10; // -50% pnl uint256 internal constant MAX_OPEN_NEGATIVE_PNL_P = 40 * P_10; // -40% pnl uint256 internal constant MAX_LIQ_SPREAD_P = (5 * P_10) / 100; // 0.05% uint16 internal constant DEFAULT_MAX_CLOSING_SLIPPAGE_P = 1 * 1e3; // 1% uint24 internal constant MAX_REFERRAL_FEE_P = 50e3; function getMarketOrderTypes() internal pure returns (ITradingStorage.PendingOrderType[5] memory) { return [ ITradingStorage.PendingOrderType.MARKET_OPEN, ITradingStorage.PendingOrderType.MARKET_CLOSE, ITradingStorage.PendingOrderType.UPDATE_LEVERAGE, ITradingStorage.PendingOrderType.MARKET_PARTIAL_OPEN, ITradingStorage.PendingOrderType.MARKET_PARTIAL_CLOSE ]; } /** * @dev Returns pending order type (market open/limit open/stop open) for a trade type (trade/limit/stop) * @param _tradeType the trade type */ function getPendingOpenOrderType( ITradingStorage.TradeType _tradeType ) internal pure returns (ITradingStorage.PendingOrderType) { return _tradeType == ITradingStorage.TradeType.TRADE ? ITradingStorage.PendingOrderType.MARKET_OPEN : _tradeType == ITradingStorage.TradeType.LIMIT ? ITradingStorage.PendingOrderType.LIMIT_OPEN : ITradingStorage.PendingOrderType.STOP_OPEN; } /** * @dev Returns true if order type is market * @param _orderType order type */ function isOrderTypeMarket(ITradingStorage.PendingOrderType _orderType) internal pure returns (bool) { ITradingStorage.PendingOrderType[5] memory marketOrderTypes = ConstantsUtils.getMarketOrderTypes(); for (uint256 i; i < marketOrderTypes.length; ++i) { if (_orderType == marketOrderTypes[i]) return true; } return false; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../interfaces/libraries/IReferralsUtils.sol"; import "../interfaces/IERC20.sol"; import "../interfaces/IGeneralErrors.sol"; import "./AddressStoreUtils.sol"; import "./StorageUtils.sol"; import "./ConstantsUtils.sol"; /** * @dev GNSReferrals facet internal library */ library ReferralsUtils { using SafeERC20 for IERC20; uint256 private constant MAX_ALLY_FEE_P = 50; uint256 private constant MAX_START_REFERRER_FEE_P = 100; uint256 private constant MAX_OPEN_FEE_P = 50; /** * @dev Check IReferralsUtils interface for documentation */ function initializeReferrals(uint256 _allyFeeP, uint256 _startReferrerFeeP, uint256 _targetVolumeUsd) internal { if (_allyFeeP > MAX_ALLY_FEE_P || _startReferrerFeeP > MAX_START_REFERRER_FEE_P || _targetVolumeUsd == 0) revert IGeneralErrors.WrongParams(); IReferralsUtils.ReferralsStorage storage s = _getStorage(); s.allyFeeP = _allyFeeP; s.startReferrerFeeP = _startReferrerFeeP; s.targetVolumeUsd = _targetVolumeUsd; } /** * @dev Check IReferralsUtils interface for documentation */ function updateAllyFeeP(uint256 _value) internal { if (_value > MAX_ALLY_FEE_P) revert IGeneralErrors.AboveMax(); _getStorage().allyFeeP = _value; emit IReferralsUtils.UpdatedAllyFeeP(_value); } /** * @dev Check IReferralsUtils interface for documentation */ function updateStartReferrerFeeP(uint256 _value) internal { if (_value > MAX_START_REFERRER_FEE_P) revert IGeneralErrors.AboveMax(); _getStorage().startReferrerFeeP = _value; emit IReferralsUtils.UpdatedStartReferrerFeeP(_value); } /** * @dev Check IReferralsUtils interface for documentation */ function updateReferralsTargetVolumeUsd(uint256 _value) internal { if (_value == 0) revert IGeneralErrors.ZeroValue(); _getStorage().targetVolumeUsd = _value; emit IReferralsUtils.UpdatedTargetVolumeUsd(_value); } /** * @dev Check IReferralsUtils interface for documentation */ function whitelistAllies(address[] calldata _allies) internal { for (uint256 i = 0; i < _allies.length; ++i) { _whitelistAlly(_allies[i]); } } /** * @dev Check IReferralsUtils interface for documentation */ function unwhitelistAllies(address[] calldata _allies) internal { for (uint256 i = 0; i < _allies.length; ++i) { _unwhitelistAlly(_allies[i]); } } /** * @dev Check IReferralsUtils interface for documentation */ function whitelistReferrers(address[] calldata _referrers, address[] calldata _allies) internal { if (_referrers.length != _allies.length) revert IGeneralErrors.WrongLength(); for (uint256 i = 0; i < _referrers.length; ++i) { _whitelistReferrer(_referrers[i], _allies[i]); } } /** * @dev Check IReferralsUtils interface for documentation */ function unwhitelistReferrers(address[] calldata _referrers) internal { for (uint256 i = 0; i < _referrers.length; ++i) { _unwhitelistReferrer(_referrers[i]); } } /** * @dev Check IReferralsUtils interface for documentation */ function overrideReferralFeeP(address[] calldata _referrers, uint24[] calldata _referralFeeP) internal { IReferrals.ReferralsStorage storage s = _getStorage(); for (uint256 i = 0; i < _referrers.length; ++i) { address referrer = _referrers[i]; if (!s.referrerDetails[referrer].active) continue; uint24 referralFeeP = _referralFeeP[i]; if(referralFeeP > ConstantsUtils.MAX_REFERRAL_FEE_P) revert IGeneralErrors.AboveMax(); s.referralSettingsOverrides[referrer].referralFeeOverrideP = referralFeeP; emit IReferralsUtils.OverrodeReferralFeeP(referrer, referralFeeP); } } /** * @dev Check IReferralsUtils interface for documentation */ function overrideAllyFeeP(address[] calldata _allies, uint24[] calldata _allyFeeP) internal { IReferrals.ReferralsStorage storage s = _getStorage(); for (uint256 i = 0; i < _allies.length; ++i) { address ally = _allies[i]; if (!s.allyDetails[ally].active) continue; uint24 allyFeeP = _allyFeeP[i]; if(allyFeeP > MAX_ALLY_FEE_P * 1e3) revert IGeneralErrors.AboveMax(); s.referralSettingsOverrides[ally].allyFeeOverrideP = allyFeeP; emit IReferralsUtils.OverrodeAllyFeeP(ally, allyFeeP); } } /** * @dev Check IReferralsUtils interface for documentation */ function registerPotentialReferrer(address _trader, address _referrer) internal { IReferralsUtils.ReferralsStorage storage s = _getStorage(); IReferralsUtils.ReferrerDetails storage r = s.referrerDetails[_referrer]; if (s.referrerByTrader[_trader] != address(0) || _referrer == address(0) || !r.active) { return; } s.referrerByTrader[_trader] = _referrer; r.tradersReferred.push(_trader); emit IReferralsUtils.ReferrerRegistered(_trader, _referrer); } /** * @dev Check IReferralsUtils interface for documentation */ function distributeReferralReward( address _trader, uint256 _volumeUsd, uint256 _referrerFeeUsd, uint256 _gnsPriceUsd ) internal { IReferralsUtils.ReferralsStorage storage s = _getStorage(); address referrer = s.referrerByTrader[_trader]; IReferralsUtils.ReferrerDetails storage r = s.referrerDetails[referrer]; if (!r.active) { return; } uint256 referrerRewardGns = (_referrerFeeUsd * ConstantsUtils.P_10) / _gnsPriceUsd; IERC20(AddressStoreUtils.getAddresses().gns).mint(address(this), referrerRewardGns); IReferralsUtils.AllyDetails storage a = s.allyDetails[r.ally]; uint256 allyRewardValueUsd; uint256 allyRewardGns; if (a.active) { uint24 allyFeeOverrideP = s.referralSettingsOverrides[r.ally].allyFeeOverrideP; uint256 allyFeeP = allyFeeOverrideP > 0 ? allyFeeOverrideP : s.allyFeeP * 1e3; allyRewardValueUsd = (_referrerFeeUsd * allyFeeP) / 100 / 1e3; allyRewardGns = (referrerRewardGns * allyFeeP) / 100 / 1e3; a.volumeReferredUsd += _volumeUsd; a.pendingRewardsGns += allyRewardGns; a.totalRewardsGns += allyRewardGns; a.totalRewardsValueUsd += allyRewardValueUsd; _referrerFeeUsd -= allyRewardValueUsd; referrerRewardGns -= allyRewardGns; emit IReferralsUtils.AllyRewardDistributed(r.ally, _trader, _volumeUsd, allyRewardGns, allyRewardValueUsd); } r.volumeReferredUsd += _volumeUsd; r.pendingRewardsGns += referrerRewardGns; r.totalRewardsGns += referrerRewardGns; r.totalRewardsValueUsd += _referrerFeeUsd; emit IReferralsUtils.ReferrerRewardDistributed( referrer, _trader, _volumeUsd, referrerRewardGns, _referrerFeeUsd ); } /** * @dev Check IReferralsUtils interface for documentation */ function claimAllyRewards() internal { IReferralsUtils.AllyDetails storage a = _getStorage().allyDetails[msg.sender]; uint256 rewardsGns = a.pendingRewardsGns; if (rewardsGns == 0) revert IReferralsUtils.NoPendingRewards(); a.pendingRewardsGns = 0; IERC20(AddressStoreUtils.getAddresses().gns).safeTransfer(msg.sender, rewardsGns); emit IReferralsUtils.AllyRewardsClaimed(msg.sender, rewardsGns); } /** * @dev Check IReferralsUtils interface for documentation */ function claimReferrerRewards() internal { IReferralsUtils.ReferrerDetails storage r = _getStorage().referrerDetails[msg.sender]; uint256 rewardsGns = r.pendingRewardsGns; if (rewardsGns == 0) revert IReferralsUtils.NoPendingRewards(); r.pendingRewardsGns = 0; IERC20(AddressStoreUtils.getAddresses().gns).safeTransfer(msg.sender, rewardsGns); emit IReferralsUtils.ReferrerRewardsClaimed(msg.sender, rewardsGns); } /** * @dev Check IReferralsUtils interface for documentation */ function getReferrerFeeProgressP(address _referrer) internal view returns (uint256 progressP) { IReferralsUtils.ReferralsStorage storage s = _getStorage(); uint256 volumeReferredUsd = s.referrerDetails[_referrer].volumeReferredUsd; uint256 targetVolumeUsd1e18 = s.targetVolumeUsd * 1e18; progressP = s.startReferrerFeeP * ConstantsUtils.P_10; progressP += ((100 * ConstantsUtils.P_10 - progressP) * (volumeReferredUsd > targetVolumeUsd1e18 ? targetVolumeUsd1e18 : volumeReferredUsd)) / targetVolumeUsd1e18; } /** * @dev Check IReferralsUtils interface for documentation */ function getTraderLastReferrer(address _trader) internal view returns (address) { return _getStorage().referrerByTrader[_trader]; } /** * @dev Check IReferralsUtils interface for documentation */ function getTraderActiveReferrer(address _trader) internal view returns (address) { address referrer = getTraderLastReferrer(_trader); return getReferrerDetails(referrer).active ? referrer : address(0); } /** * @dev Check IReferralsUtils interface for documentation */ function getReferrersReferred(address _ally) internal view returns (address[] memory) { return getAllyDetails(_ally).referrersReferred; } /** * @dev Check IReferralsUtils interface for documentation */ function getTradersReferred(address _referrer) internal view returns (address[] memory) { return getReferrerDetails(_referrer).tradersReferred; } /** * @dev Check IReferralsUtils interface for documentation */ function getReferralsAllyFeeP() internal view returns (uint256) { return _getStorage().allyFeeP; } /** * @dev Check IReferralsUtils interface for documentation */ function getReferralsStartReferrerFeeP() internal view returns (uint256) { return _getStorage().startReferrerFeeP; } /** * @dev Check IReferralsUtils interface for documentation */ function getReferralsTargetVolumeUsd() internal view returns (uint256) { return _getStorage().targetVolumeUsd; } /** * @dev Check IReferralsUtils interface for documentation */ function getAllyDetails(address _ally) internal view returns (IReferralsUtils.AllyDetails memory) { return _getStorage().allyDetails[_ally]; } /** * @dev Check IReferralsUtils interface for documentation */ function getReferrerDetails(address _referrer) internal view returns (IReferralsUtils.ReferrerDetails memory) { return _getStorage().referrerDetails[_referrer]; } function getReferralSettingsOverrides(address _address) internal view returns (IReferralsUtils.ReferralSettingsOverrides memory) { return _getStorage().referralSettingsOverrides[_address]; } /** * @dev Returns storage slot to use when fetching storage relevant to library */ function _getSlot() internal pure returns (uint256) { return StorageUtils.GLOBAL_REFERRALS_SLOT; } /** * @dev Returns storage pointer for storage struct in diamond contract, at defined slot */ function _getStorage() internal pure returns (IReferralsUtils.ReferralsStorage storage s) { uint256 storageSlot = _getSlot(); assembly { s.slot := storageSlot } } /** * @dev Whitelists new ally * @param _ally address of ally */ function _whitelistAlly(address _ally) internal { if (_ally == address(0)) revert IGeneralErrors.ZeroAddress(); IReferralsUtils.AllyDetails storage a = _getStorage().allyDetails[_ally]; if (a.active) revert IReferralsUtils.AlreadyActive(); a.active = true; emit IReferralsUtils.AllyWhitelisted(_ally); } /** * @dev Unwhitelists ally * @param _ally address of ally */ function _unwhitelistAlly(address _ally) internal { IReferralsUtils.AllyDetails storage a = _getStorage().allyDetails[_ally]; if (!a.active) revert IReferralsUtils.AlreadyInactive(); a.active = false; emit IReferralsUtils.AllyUnwhitelisted(_ally); } /** * @dev Whitelists new referrer * @param _referrer address of referrer * @param _ally address of ally */ function _whitelistReferrer(address _referrer, address _ally) internal { if (_referrer == address(0)) revert IGeneralErrors.ZeroAddress(); IReferralsUtils.ReferralsStorage storage s = _getStorage(); IReferralsUtils.ReferrerDetails storage r = s.referrerDetails[_referrer]; if (r.active) revert IReferralsUtils.AlreadyActive(); r.active = true; if (_ally != address(0)) { IReferralsUtils.AllyDetails storage a = s.allyDetails[_ally]; if (!a.active) revert IReferralsUtils.AllyNotActive(); r.ally = _ally; a.referrersReferred.push(_referrer); } emit IReferralsUtils.ReferrerWhitelisted(_referrer, _ally); } /** * @dev Unwhitelists referrer * @param _referrer address of referrer */ function _unwhitelistReferrer(address _referrer) internal { IReferralsUtils.ReferrerDetails storage r = _getStorage().referrerDetails[_referrer]; if (!r.active) revert IReferralsUtils.AlreadyInactive(); r.active = false; emit IReferralsUtils.ReferrerUnwhitelisted(_referrer); } }
// 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":"AllyNotActive","type":"error"},{"inputs":[],"name":"AlreadyActive","type":"error"},{"inputs":[],"name":"AlreadyExists","type":"error"},{"inputs":[],"name":"AlreadyInactive","type":"error"},{"inputs":[],"name":"BelowMin","type":"error"},{"inputs":[],"name":"BlockOrder","type":"error"},{"inputs":[],"name":"DoesntExist","type":"error"},{"inputs":[],"name":"InitError","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"InvalidAddress","type":"error"},{"inputs":[],"name":"InvalidAddresses","type":"error"},{"inputs":[],"name":"InvalidCollateralIndex","type":"error"},{"inputs":[],"name":"InvalidInputLength","type":"error"},{"inputs":[],"name":"NoPendingRewards","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[],"name":"NotAuthorized","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":[{"indexed":true,"internalType":"address","name":"ally","type":"address"},{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"uint256","name":"volumeUsd","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountGns","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountValueUsd","type":"uint256"}],"name":"AllyRewardDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ally","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountGns","type":"uint256"}],"name":"AllyRewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ally","type":"address"}],"name":"AllyUnwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ally","type":"address"}],"name":"AllyWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"ally","type":"address"},{"indexed":false,"internalType":"uint24","name":"allyFeeP","type":"uint24"}],"name":"OverrodeAllyFeeP","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint24","name":"referralFeeP","type":"uint24"}],"name":"OverrodeReferralFeeP","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"}],"name":"ReferrerRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":true,"internalType":"address","name":"trader","type":"address"},{"indexed":false,"internalType":"uint256","name":"volumeUsd","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountGns","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountValueUsd","type":"uint256"}],"name":"ReferrerRewardDistributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountGns","type":"uint256"}],"name":"ReferrerRewardsClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"}],"name":"ReferrerUnwhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":true,"internalType":"address","name":"ally","type":"address"}],"name":"ReferrerWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"UpdatedAllyFeeP","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"UpdatedOpenFeeP","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"UpdatedStartReferrerFeeP","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"UpdatedTargetVolumeUsd","type":"event"},{"inputs":[],"name":"claimAllyRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimReferrerRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_trader","type":"address"},{"internalType":"uint256","name":"_volumeUsd","type":"uint256"},{"internalType":"uint256","name":"_referrerFeeUsd","type":"uint256"},{"internalType":"uint256","name":"_gnsPriceUsd","type":"uint256"}],"name":"distributeReferralReward","outputs":[],"stateMutability":"nonpayable","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":"_ally","type":"address"}],"name":"getAllyDetails","outputs":[{"components":[{"internalType":"address[]","name":"referrersReferred","type":"address[]"},{"internalType":"uint256","name":"volumeReferredUsd","type":"uint256"},{"internalType":"uint256","name":"pendingRewardsGns","type":"uint256"},{"internalType":"uint256","name":"totalRewardsGns","type":"uint256"},{"internalType":"uint256","name":"totalRewardsValueUsd","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IReferrals.AllyDetails","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getReferralSettingsOverrides","outputs":[{"components":[{"internalType":"uint24","name":"referralFeeOverrideP","type":"uint24"},{"internalType":"uint24","name":"allyFeeOverrideP","type":"uint24"},{"internalType":"uint208","name":"__placeholder","type":"uint208"}],"internalType":"struct IReferrals.ReferralSettingsOverrides","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReferralsAllyFeeP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReferralsStartReferrerFeeP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReferralsTargetVolumeUsd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_referrer","type":"address"}],"name":"getReferrerDetails","outputs":[{"components":[{"internalType":"address","name":"ally","type":"address"},{"internalType":"address[]","name":"tradersReferred","type":"address[]"},{"internalType":"uint256","name":"volumeReferredUsd","type":"uint256"},{"internalType":"uint256","name":"pendingRewardsGns","type":"uint256"},{"internalType":"uint256","name":"totalRewardsGns","type":"uint256"},{"internalType":"uint256","name":"totalRewardsValueUsd","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"}],"internalType":"struct IReferrals.ReferrerDetails","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_referrer","type":"address"}],"name":"getReferrerFeeProgressP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_ally","type":"address"}],"name":"getReferrersReferred","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_trader","type":"address"}],"name":"getTraderActiveReferrer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_trader","type":"address"}],"name":"getTraderLastReferrer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_referrer","type":"address"}],"name":"getTradersReferred","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"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":"uint256","name":"_allyFeeP","type":"uint256"},{"internalType":"uint256","name":"_startReferrerFeeP","type":"uint256"},{"internalType":"uint256","name":"_targetVolumeUsd","type":"uint256"}],"name":"initializeReferrals","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_allies","type":"address[]"},{"internalType":"uint24[]","name":"_allyFeeP","type":"uint24[]"}],"name":"overrideAllyFeeP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_referrers","type":"address[]"},{"internalType":"uint24[]","name":"_referralFeeP","type":"uint24[]"}],"name":"overrideReferralFeeP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_trader","type":"address"},{"internalType":"address","name":"_referrer","type":"address"}],"name":"registerPotentialReferrer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_accounts","type":"address[]"},{"internalType":"enum IAddressStore.Role[]","name":"_roles","type":"uint8[]"},{"internalType":"bool[]","name":"_values","type":"bool[]"}],"name":"setRoles","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_allies","type":"address[]"}],"name":"unwhitelistAllies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_referrers","type":"address[]"}],"name":"unwhitelistReferrers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"updateAllyFeeP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"updateReferralsTargetVolumeUsd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"updateStartReferrerFeeP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_allies","type":"address[]"}],"name":"whitelistAllies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_referrers","type":"address[]"},{"internalType":"address[]","name":"_allies","type":"address[]"}],"name":"whitelistReferrers","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200001c62000022565b620000e3565b600054610100900460ff16156200008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811614620000e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6127de80620000f36000396000f3fe608060405234801561001057600080fd5b50600436106101da5760003560e01c80639397053b11610104578063a73a3e35116100a2578063cbe0f32e11610071578063cbe0f32e146104b2578063daeb463b146104d2578063ee6cf884146104e5578063fa3c8dbf146104ed57600080fd5b8063a73a3e3514610466578063b9c9722914610479578063c4d66de81461048c578063c72d02e31461049f57600080fd5b806397436b5f116100de57806397436b5f1461036b5780639b8ab68414610373578063a1ed461114610386578063a39fac12146103e157600080fd5b80639397053b1461032257806395a8c58d1461033557806397365b741461035857600080fd5b8063507cd8de1161017c57806371159fd11161014b57806371159fd1146102df578063843b9e5d146102e757806392b2bbae146102ef57806392e674061461030257600080fd5b8063507cd8de146102905780635d19b5d3146102a357806365cbd307146102c457806366ddd309146102cc57600080fd5b806332a7b732116101b857806332a7b732146102375780633450191e1461025757806338fb18c71461026a57806346dbf5721461027d57600080fd5b8063036787e5146101df57806303e374641461020f578063101e650314610224575b600080fd5b6101f26101ed36600461218e565b610500565b6040516001600160a01b0390911681526020015b60405180910390f35b61022261021d3660046121a9565b610511565b005b61022261023236600461220e565b610529565b61024a61024536600461218e565b61068e565b60405161020691906122a8565b6102226102653660046122f5565b610699565b610222610278366004612337565b6106b3565b6101f261028b36600461218e565b6107a3565b61022261029e366004612363565b6107ae565b6102b66102b136600461218e565b6107cc565b604051908152602001610206565b6102226107d7565b6102226102da3660046121a9565b6107e1565b6102b66107f5565b6102b6610804565b6102226102fd3660046122f5565b61080e565b61031561031036600461218e565b610823565b6040516102069190612414565b610222610330366004612363565b610867565b61034861034336600461247f565b61087e565b6040519015158152602001610206565b6102226103663660046121a9565b6108d5565b6102b66108e9565b6102226103813660046124b2565b6108f3565b61039961039436600461218e565b61091d565b60408051825162ffffff9081168252602080850151909116908201529181015179ffffffffffffffffffffffffffffffffffffffffffffffffffff1690820152606001610206565b610434604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b0390811682526020808501518216908301529282015190921690820152606001610206565b61024a61047436600461218e565b610943565b6103486104873660046124dc565b61094e565b61022261049a36600461218e565b6109fd565b6102226104ad3660046122f5565b610b3a565b6104c56104c036600461218e565b610b4f565b604051610206919061251f565b6102226104e0366004612363565b610ba3565b610222610bba565b6102226104fb36600461258f565b610bc2565b600061050b82610bf4565b92915050565b600161051c81610c23565b61052582610c4d565b5050565b600061053481610c23565b85841415806105435750858214155b1561056157604051637db491eb60e01b815260040160405180910390fd5b60005b86811015610684576000868683818110610580576105806125de565b905060200201602081019061059591906125f4565b60038111156105a6576105a66125c8565b1480156105e15750338888838181106105c1576105c16125de565b90506020020160208101906105d6919061218e565b6001600160a01b0316145b156105ff57604051631eb49d6d60e11b815260040160405180910390fd5b61067c888883818110610614576106146125de565b9050602002016020810190610629919061218e565b87878481811061063b5761063b6125de565b905060200201602081019061065091906125f4565b868685818110610662576106626125de565b9050602002016020810190610677919061261d565b610cb3565b600101610564565b5050505050505050565b606061050b82610d55565b60016106a481610c23565b6106ae8383610d6a565b505050565b600054600390610100900460ff161580156106d5575060005460ff8083169116105b61073d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff83161761010017905561075c848484610dac565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600061050b82610e05565b60016107b981610c23565b6107c585858585610e35565b5050505050565b600061050b82610ebe565b6107df610f6d565b565b60016107ec81610c23565b61052582611012565b60006107ff611070565b905090565b60006107ff611083565b600161081981610c23565b6106ae8383611096565b61085e6040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61050b826110d8565b600161087281610c23565b6107c5858585856111d5565b6001600160a01b0382166000908152600260205260408120818360038111156108a9576108a96125c8565b60038111156108ba576108ba6125c8565b815260208101919091526040016000205460ff169392505050565b60016108e081610c23565b6105258261131f565b60006107ff61137e565b33301461091357604051631b17ff5560e21b815260040160405180910390fd5b6105258282611391565b604080516060810182526000808252602082018190529181019190915261050b82611488565b606061050b82611522565b6001600160a01b038316600090815260026020526040812081846003811115610979576109796125c8565b600381111561098a5761098a6125c8565b815260208101919091526040016000205460ff16806109f557506001600160a01b0384166000908152600260205260408120908360038111156109cf576109cf6125c8565b60038111156109e0576109e06125c8565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff1615808015610a1d5750600054600160ff909116105b80610a375750303b158015610a37575060005460ff166001145b610a9a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610734565b6000805460ff191660011790558015610abd576000805461ff0019166101001790555b6001600160a01b038216610ae457604051632c1c702960e21b815260040160405180910390fd5b610af18260006001610cb3565b8015610525576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6001610b4581610c23565b6106ae8383611534565b610b9a6040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61050b82611576565b6001610bae81610c23565b6107c585858585611694565b6107df6117c2565b333014610be257604051631b17ff5560e21b815260040160405180910390fd5b610bee8484848461184b565b50505050565b600080610c0083610e05565b9050610c0b81611576565b60c00151610c1a576000610c1c565b805b9392505050565b610c2d338261087e565b610c4a57604051631b17ff5560e21b815260040160405180910390fd5b50565b6064811115610c6f57604051630ad1e31b60e01b815260040160405180910390fd5b80610c78611bad565b600401556040518181527fb85b70acaeb40f1a2351367c48842ee0ea24ec05d411d99d80bf7a020c0dbb0f906020015b60405180910390a150565b6001600160a01b03831660009081526002602052604081208291846003811115610cdf57610cdf6125c8565b6003811115610cf057610cf06125c8565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610d489392919061263a565b60405180910390a1505050565b6060610d6082611576565b6020015192915050565b60005b818110156106ae57610da4838383818110610d8a57610d8a6125de565b9050602002016020810190610d9f919061218e565b611bb7565b600101610d6d565b6032831180610dbb5750606482115b80610dc4575080155b15610de257604051635863f78960e01b815260040160405180910390fd5b6000610dec611bad565b6003810194909455506004830191909155600690910155565b6000610e0f611bad565b6001600160a01b0392831660009081526002919091016020526040902054909116919050565b828114610e55576040516349552d5960e11b815260040160405180910390fd5b60005b838110156107c557610eb6858583818110610e7557610e756125de565b9050602002016020810190610e8a919061218e565b848484818110610e9c57610e9c6125de565b9050602002016020810190610eb1919061218e565b611c46565b600101610e58565b600080610ec9611bad565b6001600160a01b0384166000908152600182016020526040812060020154600683015492935091610f0290670de0b6b3a7640000612694565b90506402540be4008360040154610f199190612694565b935080818311610f295782610f2b565b815b85610f3c6402540be4006064612694565b610f4691906126ab565b610f509190612694565b610f5a91906126be565b610f6490856126e0565b95945050505050565b6000610f77611bad565b33600090815260019190910160205260408120600381015490925090819003610fb357604051635b8f50bf60e11b815260040160405180910390fd5b60006003830155610fd83382610fc7611daa565b546001600160a01b03169190611db4565b60405181815233907f25deb48f8299e9863bda34f0d343d51341ac7ac30bf63dbeb2e8212bc4a20bf1906020015b60405180910390a25050565b8060000361103357604051637c946ed760e01b815260040160405180910390fd5b8061103c611bad565b600601556040518181527f7e6042545b314fbe2e138616211d5c38934823f783b83a140ea84f0eb2ae115d90602001610ca8565b600061107a611bad565b60060154905090565b600061108d611bad565b60040154905090565b60005b818110156106ae576110d08383838181106110b6576110b66125de565b90506020020160208101906110cb919061218e565b611e1b565b600101611099565b6111136040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61111b611bad565b6001600160a01b038316600090815260209182526040908190208151815460e09481028201850190935260c0810183815290939192849284919084018282801561118e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611170575b50505091835250506001820154602082015260028201546040820152600382015460608201526004820154608082015260059091015460ff16151560a09091015292915050565b60006111df611bad565b905060005b84811015611317576000868683818110611200576112006125de565b9050602002016020810190611215919061218e565b6001600160a01b03811660009081526020859052604090206005015490915060ff16611241575061130f565b6000858584818110611255576112556125de565b905060200201602081019061126a91906126f3565b905061127960326103e8612694565b8162ffffff16111561129e57604051630ad1e31b60e01b815260040160405180910390fd5b6001600160a01b0382166000818152600786016020908152604091829020805465ffffff0000001916630100000062ffffff87169081029190911790915591519182527fb5c3fde8238e94bb4bbaa413be4d5b14d90e9a399db8d4f405d791ccd383ec9d910160405180910390a250505b6001016111e4565b505050505050565b603281111561134157604051630ad1e31b60e01b815260040160405180910390fd5b8061134a611bad565b600301556040518181527f2f33e68d48a82acaa58e3dcb12a4c7738cdfe7041d35f0e29ec8c39b780b370c90602001610ca8565b6000611388611bad565b60030154905090565b600061139b611bad565b6001600160a01b03808416600090815260018301602090815260408083208885168452600286019092529091205492935091161515806113e257506001600160a01b038316155b806113f25750600681015460ff16155b156113fd5750505050565b6001600160a01b0380851660008181526002850160209081526040808320805495891673ffffffffffffffffffffffffffffffffffffffff19968716811790915560018781018054918201815585529284209092018054909516841790945592517f0e67f4bbcd5c51b7365ca2dd861dc8094e393ca60de2ceae9d831761a839e92a9190a350505050565b60408051606081018252600080825260208201819052918101919091526114ad611bad565b6001600160a01b03929092166000908152600790920160209081526040928390208351606081018552905462ffffff8082168352630100000082041692820192909252660100000000000090910479ffffffffffffffffffffffffffffffffffffffffffffffffffff16928101929092525090565b606061152d826110d8565b5192915050565b60005b818110156106ae5761156e838383818110611554576115546125de565b9050602002016020810190611569919061218e565b611ead565b600101611537565b6115c16040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6115c9611bad565b6001600160a01b03808416600090815260019283016020908152604091829020825160e081018452815490941684529384018054835181840281018401909452808452939493858301939283018282801561164d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161162f575b50505091835250506002820154602082015260038201546040820152600482015460608201526005820154608082015260069091015460ff16151560a09091015292915050565b600061169e611bad565b905060005b848110156113175760008686838181106116bf576116bf6125de565b90506020020160208101906116d4919061218e565b6001600160a01b038116600090815260018501602052604090206006015490915060ff1661170257506117ba565b6000858584818110611716576117166125de565b905060200201602081019061172b91906126f3565b905061c35062ffffff8216111561175557604051630ad1e31b60e01b815260040160405180910390fd5b6001600160a01b0382166000818152600786016020908152604091829020805462ffffff191662ffffff861690811790915591519182527f69b632ab0d5becac42ff599f05530699f7bafe35d60010b9f45122e921eb7496910160405180910390a250505b6001016116a3565b60006117cc611bad565b3360009081526020919091526040812060028101549092509081900361180557604051635b8f50bf60e11b815260040160405180910390fd5b600060028301556118193382610fc7611daa565b60405181815233907f3dfe9be199655709d01d635bf441264a809a090c98ed7aae9abdc85f7dcbc09d90602001611006565b6000611855611bad565b6001600160a01b038087166000908152600283016020908152604080832054909316808352600185019091529190206006810154929350909160ff1661189d57505050610bee565b6000846118af6402540be40088612694565b6118b991906126be565b90506118c3611daa565b546040516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401600060405180830381600087803b15801561190d57600080fd5b505af1158015611921573d6000803e3d6000fd5b505083546001600160a01b031660009081526020879052604081206005810154909350909150819060ff1615611ae55784546001600160a01b031660009081526007880160205260408120546301000000900462ffffff169081611995576003890154611990906103e8612694565b61199c565b8162ffffff165b90506103e860646119ad838e612694565b6119b791906126be565b6119c191906126be565b93506103e860646119d28389612694565b6119dc91906126be565b6119e691906126be565b92508b8560010160008282546119fc91906126e0565b9250508190555082856002016000828254611a1791906126e0565b9250508190555082856003016000828254611a3291906126e0565b9250508190555083856004016000828254611a4d91906126e0565b90915550611a5d9050848c6126ab565b9a50611a6983876126ab565b95508c6001600160a01b03168760000160009054906101000a90046001600160a01b03166001600160a01b03167f0d54fedb563328d37f00fe5ba0bf7689519f8cf02318562adfe7b4bfab8cf4b48e8688604051611ada939291909283526020830191909152604082015260600190565b60405180910390a350505b89856002016000828254611af991906126e0565b9250508190555083856003016000828254611b1491906126e0565b9250508190555083856004016000828254611b2f91906126e0565b9250508190555088856005016000828254611b4a91906126e0565b9091555050604080518b8152602081018690529081018a90526001600160a01b03808d1691908816907f74e9754b45c636e199e3d7bb764fae1a9acce47a984d10dcfd74849ec4babc4f9060600160405180910390a35050505050505050505050565b600080606561050b565b6000611bc1611bad565b6001600160a01b038316600090815260209190915260409020600581015490915060ff16611c025760405163232990cb60e01b815260040160405180910390fd5b60058101805460ff191690556040516001600160a01b038316907f6900afc1a924abca16a7f560e2dac3d71008c1cd1d88de8a85b6e4267116d18690600090a25050565b6001600160a01b038216611c6d5760405163d92e233d60e01b815260040160405180910390fd5b6000611c77611bad565b6001600160a01b0384166000908152600182016020526040902060068101549192509060ff1615611cbb57604051637cdf305160e11b815260040160405180910390fd5b60068101805460ff191660011790556001600160a01b03831615611d64576001600160a01b0383166000908152602083905260409020600581015460ff16611d16576040516383f6a90560e01b815260040160405180910390fd5b81546001600160a01b0380861673ffffffffffffffffffffffffffffffffffffffff199283161784558254600181018455600093845260209093209092018054928716929091169190911790555b826001600160a01b0316846001600160a01b03167f15ad1d28b052a6cc2dd1d34d9e06a1847055d520e2163017e6e8aad6431b7f6a60405160405180910390a350505050565b600080600361050b565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b1790526106ae908490611f67565b6000611e25611bad565b6001600160a01b038316600090815260019190910160205260409020600681015490915060ff16611e695760405163232990cb60e01b815260040160405180910390fd5b60068101805460ff191690556040516001600160a01b038316907f6dd169357c2e2b04fd13a8807a11892b88875b7c70eeb73c3b6642c58516f0db90600090a25050565b6001600160a01b038116611ed45760405163d92e233d60e01b815260040160405180910390fd5b6000611ede611bad565b6001600160a01b038316600090815260209190915260409020600581015490915060ff1615611f2057604051637cdf305160e11b815260040160405180910390fd5b60058101805460ff191660011790556040516001600160a01b038316907f80495287b7fdd5e00b7c8c1eb065c5b63474d11ffb062cc82c13da77dda8424d90600090a25050565b6000611fbc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661204f9092919063ffffffff16565b9050805160001480611fdd575080806020019051810190611fdd9190612718565b6106ae5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610734565b60606109f5848460008585600080866001600160a01b031685876040516120769190612759565b60006040518083038185875af1925050503d80600081146120b3576040519150601f19603f3d011682016040523d82523d6000602084013e6120b8565b606091505b50915091506120c9878383876120d4565b979650505050505050565b6060831561214357825160000361213c576001600160a01b0385163b61213c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610734565b50816109f5565b6109f583838151156121585781518083602001fd5b8060405162461bcd60e51b81526004016107349190612775565b80356001600160a01b038116811461218957600080fd5b919050565b6000602082840312156121a057600080fd5b610c1c82612172565b6000602082840312156121bb57600080fd5b5035919050565b60008083601f8401126121d457600080fd5b50813567ffffffffffffffff8111156121ec57600080fd5b6020830191508360208260051b850101111561220757600080fd5b9250929050565b6000806000806000806060878903121561222757600080fd5b863567ffffffffffffffff8082111561223f57600080fd5b61224b8a838b016121c2565b9098509650602089013591508082111561226457600080fd5b6122708a838b016121c2565b9096509450604089013591508082111561228957600080fd5b5061229689828a016121c2565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b818110156122e95783516001600160a01b0316835292840192918401916001016122c4565b50909695505050505050565b6000806020838503121561230857600080fd5b823567ffffffffffffffff81111561231f57600080fd5b61232b858286016121c2565b90969095509350505050565b60008060006060848603121561234c57600080fd5b505081359360208301359350604090920135919050565b6000806000806040858703121561237957600080fd5b843567ffffffffffffffff8082111561239157600080fd5b61239d888389016121c2565b909650945060208701359150808211156123b657600080fd5b506123c3878288016121c2565b95989497509550505050565b60008151808452602080850194506020840160005b838110156124095781516001600160a01b0316875295820195908201906001016123e4565b509495945050505050565b602081526000825160c0602084015261243060e08401826123cf565b9050602084015160408401526040840151606084015260608401516080840152608084015160a084015260a0840151151560c08401528091505092915050565b80356004811061218957600080fd5b6000806040838503121561249257600080fd5b61249b83612172565b91506124a960208401612470565b90509250929050565b600080604083850312156124c557600080fd5b6124ce83612172565b91506124a960208401612172565b6000806000606084860312156124f157600080fd5b6124fa84612172565b925061250860208501612470565b915061251660408501612470565b90509250925092565b602081526001600160a01b0382511660208201526000602083015160e0604084015261254f6101008401826123cf565b90506040840151606084015260608401516080840152608084015160a084015260a084015160c084015260c0840151151560e08401528091505092915050565b600080600080608085870312156125a557600080fd5b6125ae85612172565b966020860135965060408601359560600135945092505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561260657600080fd5b610c1c82612470565b8015158114610c4a57600080fd5b60006020828403121561262f57600080fd5b8135610c1c8161260f565b6001600160a01b0384168152606081016004841061266857634e487b7160e01b600052602160045260246000fd5b8360208301528215156040830152949350505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761050b5761050b61267e565b8181038181111561050b5761050b61267e565b6000826126db57634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561050b5761050b61267e565b60006020828403121561270557600080fd5b813562ffffff81168114610c1c57600080fd5b60006020828403121561272a57600080fd5b8151610c1c8161260f565b60005b83811015612750578181015183820152602001612738565b50506000910152565b6000825161276b818460208701612735565b9190910192915050565b6020815260008251806020840152612794816040850160208701612735565b601f01601f1916919091016040019291505056fea2646970667358221220ef02d1eae21cb707347b00915b30d8b992a81d06cd2b4956c0e27bdcd959fcd264736f6c63430008170033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101da5760003560e01c80639397053b11610104578063a73a3e35116100a2578063cbe0f32e11610071578063cbe0f32e146104b2578063daeb463b146104d2578063ee6cf884146104e5578063fa3c8dbf146104ed57600080fd5b8063a73a3e3514610466578063b9c9722914610479578063c4d66de81461048c578063c72d02e31461049f57600080fd5b806397436b5f116100de57806397436b5f1461036b5780639b8ab68414610373578063a1ed461114610386578063a39fac12146103e157600080fd5b80639397053b1461032257806395a8c58d1461033557806397365b741461035857600080fd5b8063507cd8de1161017c57806371159fd11161014b57806371159fd1146102df578063843b9e5d146102e757806392b2bbae146102ef57806392e674061461030257600080fd5b8063507cd8de146102905780635d19b5d3146102a357806365cbd307146102c457806366ddd309146102cc57600080fd5b806332a7b732116101b857806332a7b732146102375780633450191e1461025757806338fb18c71461026a57806346dbf5721461027d57600080fd5b8063036787e5146101df57806303e374641461020f578063101e650314610224575b600080fd5b6101f26101ed36600461218e565b610500565b6040516001600160a01b0390911681526020015b60405180910390f35b61022261021d3660046121a9565b610511565b005b61022261023236600461220e565b610529565b61024a61024536600461218e565b61068e565b60405161020691906122a8565b6102226102653660046122f5565b610699565b610222610278366004612337565b6106b3565b6101f261028b36600461218e565b6107a3565b61022261029e366004612363565b6107ae565b6102b66102b136600461218e565b6107cc565b604051908152602001610206565b6102226107d7565b6102226102da3660046121a9565b6107e1565b6102b66107f5565b6102b6610804565b6102226102fd3660046122f5565b61080e565b61031561031036600461218e565b610823565b6040516102069190612414565b610222610330366004612363565b610867565b61034861034336600461247f565b61087e565b6040519015158152602001610206565b6102226103663660046121a9565b6108d5565b6102b66108e9565b6102226103813660046124b2565b6108f3565b61039961039436600461218e565b61091d565b60408051825162ffffff9081168252602080850151909116908201529181015179ffffffffffffffffffffffffffffffffffffffffffffffffffff1690820152606001610206565b610434604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b0390811682526020808501518216908301529282015190921690820152606001610206565b61024a61047436600461218e565b610943565b6103486104873660046124dc565b61094e565b61022261049a36600461218e565b6109fd565b6102226104ad3660046122f5565b610b3a565b6104c56104c036600461218e565b610b4f565b604051610206919061251f565b6102226104e0366004612363565b610ba3565b610222610bba565b6102226104fb36600461258f565b610bc2565b600061050b82610bf4565b92915050565b600161051c81610c23565b61052582610c4d565b5050565b600061053481610c23565b85841415806105435750858214155b1561056157604051637db491eb60e01b815260040160405180910390fd5b60005b86811015610684576000868683818110610580576105806125de565b905060200201602081019061059591906125f4565b60038111156105a6576105a66125c8565b1480156105e15750338888838181106105c1576105c16125de565b90506020020160208101906105d6919061218e565b6001600160a01b0316145b156105ff57604051631eb49d6d60e11b815260040160405180910390fd5b61067c888883818110610614576106146125de565b9050602002016020810190610629919061218e565b87878481811061063b5761063b6125de565b905060200201602081019061065091906125f4565b868685818110610662576106626125de565b9050602002016020810190610677919061261d565b610cb3565b600101610564565b5050505050505050565b606061050b82610d55565b60016106a481610c23565b6106ae8383610d6a565b505050565b600054600390610100900460ff161580156106d5575060005460ff8083169116105b61073d5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff83161761010017905561075c848484610dac565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600061050b82610e05565b60016107b981610c23565b6107c585858585610e35565b5050505050565b600061050b82610ebe565b6107df610f6d565b565b60016107ec81610c23565b61052582611012565b60006107ff611070565b905090565b60006107ff611083565b600161081981610c23565b6106ae8383611096565b61085e6040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61050b826110d8565b600161087281610c23565b6107c5858585856111d5565b6001600160a01b0382166000908152600260205260408120818360038111156108a9576108a96125c8565b60038111156108ba576108ba6125c8565b815260208101919091526040016000205460ff169392505050565b60016108e081610c23565b6105258261131f565b60006107ff61137e565b33301461091357604051631b17ff5560e21b815260040160405180910390fd5b6105258282611391565b604080516060810182526000808252602082018190529181019190915261050b82611488565b606061050b82611522565b6001600160a01b038316600090815260026020526040812081846003811115610979576109796125c8565b600381111561098a5761098a6125c8565b815260208101919091526040016000205460ff16806109f557506001600160a01b0384166000908152600260205260408120908360038111156109cf576109cf6125c8565b60038111156109e0576109e06125c8565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff1615808015610a1d5750600054600160ff909116105b80610a375750303b158015610a37575060005460ff166001145b610a9a5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610734565b6000805460ff191660011790558015610abd576000805461ff0019166101001790555b6001600160a01b038216610ae457604051632c1c702960e21b815260040160405180910390fd5b610af18260006001610cb3565b8015610525576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6001610b4581610c23565b6106ae8383611534565b610b9a6040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61050b82611576565b6001610bae81610c23565b6107c585858585611694565b6107df6117c2565b333014610be257604051631b17ff5560e21b815260040160405180910390fd5b610bee8484848461184b565b50505050565b600080610c0083610e05565b9050610c0b81611576565b60c00151610c1a576000610c1c565b805b9392505050565b610c2d338261087e565b610c4a57604051631b17ff5560e21b815260040160405180910390fd5b50565b6064811115610c6f57604051630ad1e31b60e01b815260040160405180910390fd5b80610c78611bad565b600401556040518181527fb85b70acaeb40f1a2351367c48842ee0ea24ec05d411d99d80bf7a020c0dbb0f906020015b60405180910390a150565b6001600160a01b03831660009081526002602052604081208291846003811115610cdf57610cdf6125c8565b6003811115610cf057610cf06125c8565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610d489392919061263a565b60405180910390a1505050565b6060610d6082611576565b6020015192915050565b60005b818110156106ae57610da4838383818110610d8a57610d8a6125de565b9050602002016020810190610d9f919061218e565b611bb7565b600101610d6d565b6032831180610dbb5750606482115b80610dc4575080155b15610de257604051635863f78960e01b815260040160405180910390fd5b6000610dec611bad565b6003810194909455506004830191909155600690910155565b6000610e0f611bad565b6001600160a01b0392831660009081526002919091016020526040902054909116919050565b828114610e55576040516349552d5960e11b815260040160405180910390fd5b60005b838110156107c557610eb6858583818110610e7557610e756125de565b9050602002016020810190610e8a919061218e565b848484818110610e9c57610e9c6125de565b9050602002016020810190610eb1919061218e565b611c46565b600101610e58565b600080610ec9611bad565b6001600160a01b0384166000908152600182016020526040812060020154600683015492935091610f0290670de0b6b3a7640000612694565b90506402540be4008360040154610f199190612694565b935080818311610f295782610f2b565b815b85610f3c6402540be4006064612694565b610f4691906126ab565b610f509190612694565b610f5a91906126be565b610f6490856126e0565b95945050505050565b6000610f77611bad565b33600090815260019190910160205260408120600381015490925090819003610fb357604051635b8f50bf60e11b815260040160405180910390fd5b60006003830155610fd83382610fc7611daa565b546001600160a01b03169190611db4565b60405181815233907f25deb48f8299e9863bda34f0d343d51341ac7ac30bf63dbeb2e8212bc4a20bf1906020015b60405180910390a25050565b8060000361103357604051637c946ed760e01b815260040160405180910390fd5b8061103c611bad565b600601556040518181527f7e6042545b314fbe2e138616211d5c38934823f783b83a140ea84f0eb2ae115d90602001610ca8565b600061107a611bad565b60060154905090565b600061108d611bad565b60040154905090565b60005b818110156106ae576110d08383838181106110b6576110b66125de565b90506020020160208101906110cb919061218e565b611e1b565b600101611099565b6111136040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61111b611bad565b6001600160a01b038316600090815260209182526040908190208151815460e09481028201850190935260c0810183815290939192849284919084018282801561118e57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611170575b50505091835250506001820154602082015260028201546040820152600382015460608201526004820154608082015260059091015460ff16151560a09091015292915050565b60006111df611bad565b905060005b84811015611317576000868683818110611200576112006125de565b9050602002016020810190611215919061218e565b6001600160a01b03811660009081526020859052604090206005015490915060ff16611241575061130f565b6000858584818110611255576112556125de565b905060200201602081019061126a91906126f3565b905061127960326103e8612694565b8162ffffff16111561129e57604051630ad1e31b60e01b815260040160405180910390fd5b6001600160a01b0382166000818152600786016020908152604091829020805465ffffff0000001916630100000062ffffff87169081029190911790915591519182527fb5c3fde8238e94bb4bbaa413be4d5b14d90e9a399db8d4f405d791ccd383ec9d910160405180910390a250505b6001016111e4565b505050505050565b603281111561134157604051630ad1e31b60e01b815260040160405180910390fd5b8061134a611bad565b600301556040518181527f2f33e68d48a82acaa58e3dcb12a4c7738cdfe7041d35f0e29ec8c39b780b370c90602001610ca8565b6000611388611bad565b60030154905090565b600061139b611bad565b6001600160a01b03808416600090815260018301602090815260408083208885168452600286019092529091205492935091161515806113e257506001600160a01b038316155b806113f25750600681015460ff16155b156113fd5750505050565b6001600160a01b0380851660008181526002850160209081526040808320805495891673ffffffffffffffffffffffffffffffffffffffff19968716811790915560018781018054918201815585529284209092018054909516841790945592517f0e67f4bbcd5c51b7365ca2dd861dc8094e393ca60de2ceae9d831761a839e92a9190a350505050565b60408051606081018252600080825260208201819052918101919091526114ad611bad565b6001600160a01b03929092166000908152600790920160209081526040928390208351606081018552905462ffffff8082168352630100000082041692820192909252660100000000000090910479ffffffffffffffffffffffffffffffffffffffffffffffffffff16928101929092525090565b606061152d826110d8565b5192915050565b60005b818110156106ae5761156e838383818110611554576115546125de565b9050602002016020810190611569919061218e565b611ead565b600101611537565b6115c16040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6115c9611bad565b6001600160a01b03808416600090815260019283016020908152604091829020825160e081018452815490941684529384018054835181840281018401909452808452939493858301939283018282801561164d57602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161162f575b50505091835250506002820154602082015260038201546040820152600482015460608201526005820154608082015260069091015460ff16151560a09091015292915050565b600061169e611bad565b905060005b848110156113175760008686838181106116bf576116bf6125de565b90506020020160208101906116d4919061218e565b6001600160a01b038116600090815260018501602052604090206006015490915060ff1661170257506117ba565b6000858584818110611716576117166125de565b905060200201602081019061172b91906126f3565b905061c35062ffffff8216111561175557604051630ad1e31b60e01b815260040160405180910390fd5b6001600160a01b0382166000818152600786016020908152604091829020805462ffffff191662ffffff861690811790915591519182527f69b632ab0d5becac42ff599f05530699f7bafe35d60010b9f45122e921eb7496910160405180910390a250505b6001016116a3565b60006117cc611bad565b3360009081526020919091526040812060028101549092509081900361180557604051635b8f50bf60e11b815260040160405180910390fd5b600060028301556118193382610fc7611daa565b60405181815233907f3dfe9be199655709d01d635bf441264a809a090c98ed7aae9abdc85f7dcbc09d90602001611006565b6000611855611bad565b6001600160a01b038087166000908152600283016020908152604080832054909316808352600185019091529190206006810154929350909160ff1661189d57505050610bee565b6000846118af6402540be40088612694565b6118b991906126be565b90506118c3611daa565b546040516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401600060405180830381600087803b15801561190d57600080fd5b505af1158015611921573d6000803e3d6000fd5b505083546001600160a01b031660009081526020879052604081206005810154909350909150819060ff1615611ae55784546001600160a01b031660009081526007880160205260408120546301000000900462ffffff169081611995576003890154611990906103e8612694565b61199c565b8162ffffff165b90506103e860646119ad838e612694565b6119b791906126be565b6119c191906126be565b93506103e860646119d28389612694565b6119dc91906126be565b6119e691906126be565b92508b8560010160008282546119fc91906126e0565b9250508190555082856002016000828254611a1791906126e0565b9250508190555082856003016000828254611a3291906126e0565b9250508190555083856004016000828254611a4d91906126e0565b90915550611a5d9050848c6126ab565b9a50611a6983876126ab565b95508c6001600160a01b03168760000160009054906101000a90046001600160a01b03166001600160a01b03167f0d54fedb563328d37f00fe5ba0bf7689519f8cf02318562adfe7b4bfab8cf4b48e8688604051611ada939291909283526020830191909152604082015260600190565b60405180910390a350505b89856002016000828254611af991906126e0565b9250508190555083856003016000828254611b1491906126e0565b9250508190555083856004016000828254611b2f91906126e0565b9250508190555088856005016000828254611b4a91906126e0565b9091555050604080518b8152602081018690529081018a90526001600160a01b03808d1691908816907f74e9754b45c636e199e3d7bb764fae1a9acce47a984d10dcfd74849ec4babc4f9060600160405180910390a35050505050505050505050565b600080606561050b565b6000611bc1611bad565b6001600160a01b038316600090815260209190915260409020600581015490915060ff16611c025760405163232990cb60e01b815260040160405180910390fd5b60058101805460ff191690556040516001600160a01b038316907f6900afc1a924abca16a7f560e2dac3d71008c1cd1d88de8a85b6e4267116d18690600090a25050565b6001600160a01b038216611c6d5760405163d92e233d60e01b815260040160405180910390fd5b6000611c77611bad565b6001600160a01b0384166000908152600182016020526040902060068101549192509060ff1615611cbb57604051637cdf305160e11b815260040160405180910390fd5b60068101805460ff191660011790556001600160a01b03831615611d64576001600160a01b0383166000908152602083905260409020600581015460ff16611d16576040516383f6a90560e01b815260040160405180910390fd5b81546001600160a01b0380861673ffffffffffffffffffffffffffffffffffffffff199283161784558254600181018455600093845260209093209092018054928716929091169190911790555b826001600160a01b0316846001600160a01b03167f15ad1d28b052a6cc2dd1d34d9e06a1847055d520e2163017e6e8aad6431b7f6a60405160405180910390a350505050565b600080600361050b565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b1790526106ae908490611f67565b6000611e25611bad565b6001600160a01b038316600090815260019190910160205260409020600681015490915060ff16611e695760405163232990cb60e01b815260040160405180910390fd5b60068101805460ff191690556040516001600160a01b038316907f6dd169357c2e2b04fd13a8807a11892b88875b7c70eeb73c3b6642c58516f0db90600090a25050565b6001600160a01b038116611ed45760405163d92e233d60e01b815260040160405180910390fd5b6000611ede611bad565b6001600160a01b038316600090815260209190915260409020600581015490915060ff1615611f2057604051637cdf305160e11b815260040160405180910390fd5b60058101805460ff191660011790556040516001600160a01b038316907f80495287b7fdd5e00b7c8c1eb065c5b63474d11ffb062cc82c13da77dda8424d90600090a25050565b6000611fbc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661204f9092919063ffffffff16565b9050805160001480611fdd575080806020019051810190611fdd9190612718565b6106ae5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610734565b60606109f5848460008585600080866001600160a01b031685876040516120769190612759565b60006040518083038185875af1925050503d80600081146120b3576040519150601f19603f3d011682016040523d82523d6000602084013e6120b8565b606091505b50915091506120c9878383876120d4565b979650505050505050565b6060831561214357825160000361213c576001600160a01b0385163b61213c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610734565b50816109f5565b6109f583838151156121585781518083602001fd5b8060405162461bcd60e51b81526004016107349190612775565b80356001600160a01b038116811461218957600080fd5b919050565b6000602082840312156121a057600080fd5b610c1c82612172565b6000602082840312156121bb57600080fd5b5035919050565b60008083601f8401126121d457600080fd5b50813567ffffffffffffffff8111156121ec57600080fd5b6020830191508360208260051b850101111561220757600080fd5b9250929050565b6000806000806000806060878903121561222757600080fd5b863567ffffffffffffffff8082111561223f57600080fd5b61224b8a838b016121c2565b9098509650602089013591508082111561226457600080fd5b6122708a838b016121c2565b9096509450604089013591508082111561228957600080fd5b5061229689828a016121c2565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b818110156122e95783516001600160a01b0316835292840192918401916001016122c4565b50909695505050505050565b6000806020838503121561230857600080fd5b823567ffffffffffffffff81111561231f57600080fd5b61232b858286016121c2565b90969095509350505050565b60008060006060848603121561234c57600080fd5b505081359360208301359350604090920135919050565b6000806000806040858703121561237957600080fd5b843567ffffffffffffffff8082111561239157600080fd5b61239d888389016121c2565b909650945060208701359150808211156123b657600080fd5b506123c3878288016121c2565b95989497509550505050565b60008151808452602080850194506020840160005b838110156124095781516001600160a01b0316875295820195908201906001016123e4565b509495945050505050565b602081526000825160c0602084015261243060e08401826123cf565b9050602084015160408401526040840151606084015260608401516080840152608084015160a084015260a0840151151560c08401528091505092915050565b80356004811061218957600080fd5b6000806040838503121561249257600080fd5b61249b83612172565b91506124a960208401612470565b90509250929050565b600080604083850312156124c557600080fd5b6124ce83612172565b91506124a960208401612172565b6000806000606084860312156124f157600080fd5b6124fa84612172565b925061250860208501612470565b915061251660408501612470565b90509250925092565b602081526001600160a01b0382511660208201526000602083015160e0604084015261254f6101008401826123cf565b90506040840151606084015260608401516080840152608084015160a084015260a084015160c084015260c0840151151560e08401528091505092915050565b600080600080608085870312156125a557600080fd5b6125ae85612172565b966020860135965060408601359560600135945092505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561260657600080fd5b610c1c82612470565b8015158114610c4a57600080fd5b60006020828403121561262f57600080fd5b8135610c1c8161260f565b6001600160a01b0384168152606081016004841061266857634e487b7160e01b600052602160045260246000fd5b8360208301528215156040830152949350505050565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761050b5761050b61267e565b8181038181111561050b5761050b61267e565b6000826126db57634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561050b5761050b61267e565b60006020828403121561270557600080fd5b813562ffffff81168114610c1c57600080fd5b60006020828403121561272a57600080fd5b8151610c1c8161260f565b60005b83811015612750578181015183820152602001612738565b50506000910152565b6000825161276b818460208701612735565b9190910192915050565b6020815260008251806020840152612794816040850160208701612735565b601f01601f1916919091016040019291505056fea2646970667358221220ef02d1eae21cb707347b00915b30d8b992a81d06cd2b4956c0e27bdcd959fcd264736f6c63430008170033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.