Overview
APE Balance
0 APE
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 4678975 | 46 hrs ago | IN | 0 APE | 0.05146764 |
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); } // 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); } }
// 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 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 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); 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) uint256[43] __gap; } struct AllyDetails { address[] referrersReferred; uint256 volumeReferredUsd; // 1e18 uint256 pendingRewardsGns; // 1e18 uint256 totalRewardsGns; // 1e18 uint256 totalRewardsValueUsd; // 1e18 bool active; } struct ReferrerDetails { address ally; address[] tradersReferred; uint256 volumeReferredUsd; // 1e18 uint256 pendingRewardsGns; // 1e18 uint256 totalRewardsGns; // 1e18 uint256 totalRewardsValueUsd; // 1e18 bool active; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.23; import "./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 MAX_PNL_P = 100000; // 100,000% PnL (practically disabled) uint256 internal constant SL_LIQ_BUFFER_P = 10 * P_10; // SL has to be 10% closer than liq price uint256 internal constant LEGACY_LIQ_THRESHOLD_P = 90 * P_10; // -90% pnl uint256 internal constant MIN_LIQ_THRESHOLD_P = 50 * P_10; // -50% pnl uint256 internal constant MAX_OPEN_NEGATIVE_PNL_P = 40 * P_10; // -40% pnl uint256 internal constant MAX_LIQ_SPREAD_P = (5 * P_10) / 100; // 0.05% uint16 internal constant DEFAULT_MAX_CLOSING_SLIPPAGE_P = 1 * 1e3; // 1% function getMarketOrderTypes() internal pure returns (ITradingStorage.PendingOrderType[5] memory) { return [ ITradingStorage.PendingOrderType.MARKET_OPEN, ITradingStorage.PendingOrderType.MARKET_CLOSE, ITradingStorage.PendingOrderType.UPDATE_LEVERAGE, ITradingStorage.PendingOrderType.MARKET_PARTIAL_OPEN, ITradingStorage.PendingOrderType.MARKET_PARTIAL_CLOSE ]; } /** * @dev Returns pending order type (market open/limit open/stop open) for a trade type (trade/limit/stop) * @param _tradeType the trade type */ function getPendingOpenOrderType( ITradingStorage.TradeType _tradeType ) internal pure returns (ITradingStorage.PendingOrderType) { return _tradeType == ITradingStorage.TradeType.TRADE ? ITradingStorage.PendingOrderType.MARKET_OPEN : _tradeType == ITradingStorage.TradeType.LIMIT ? ITradingStorage.PendingOrderType.LIMIT_OPEN : ITradingStorage.PendingOrderType.STOP_OPEN; } /** * @dev Returns true if order type is market * @param _orderType order type */ function isOrderTypeMarket(ITradingStorage.PendingOrderType _orderType) internal pure returns (bool) { ITradingStorage.PendingOrderType[5] memory marketOrderTypes = ConstantsUtils.getMarketOrderTypes(); for (uint256 i; i < marketOrderTypes.length; ++i) { if (_orderType == marketOrderTypes[i]) return true; } return false; } }
// 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 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) { uint256 allyFeeP = s.allyFeeP; allyRewardValueUsd = (_referrerFeeUsd * allyFeeP) / 100; allyRewardGns = (referrerRewardGns * allyFeeP) / 100; 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]; } /** * @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":"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":[],"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":"_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
608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b61232a80620000ed6000396000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c806392b2bbae116100f9578063a73a3e3511610097578063c72d02e311610071578063c72d02e314610410578063cbe0f32e14610423578063ee6cf88414610443578063fa3c8dbf1461044b57600080fd5b8063a73a3e35146103d7578063b9c97229146103ea578063c4d66de8146103fd57600080fd5b806397365b74116100d357806397365b741461032457806397436b5f146103375780639b8ab6841461033f578063a39fac121461035257600080fd5b806392b2bbae146102ce57806392e67406146102e157806395a8c58d1461030157600080fd5b806346dbf5721161016657806365cbd3071161014057806365cbd307146102a357806366ddd309146102ab57806371159fd1146102be578063843b9e5d146102c657600080fd5b806346dbf5721461025c578063507cd8de1461026f5780635d19b5d31461028257600080fd5b806332a7b7321161019757806332a7b732146102165780633450191e1461023657806338fb18c71461024957600080fd5b8063036787e5146101be57806303e37464146101ee578063101e650314610203575b600080fd5b6101d16101cc366004611cff565b61045e565b6040516001600160a01b0390911681526020015b60405180910390f35b6102016101fc366004611d1a565b61046f565b005b610201610211366004611d7f565b610487565b610229610224366004611cff565b6105ec565b6040516101e59190611e19565b610201610244366004611e66565b6105f7565b610201610257366004611ea8565b610611565b6101d161026a366004611cff565b610701565b61020161027d366004611ed4565b61070c565b610295610290366004611cff565b61072a565b6040519081526020016101e5565b610201610735565b6102016102b9366004611d1a565b61073f565b610295610753565b610295610762565b6102016102dc366004611e66565b61076c565b6102f46102ef366004611cff565b610781565b6040516101e59190611f85565b61031461030f366004611ff0565b6107c5565b60405190151581526020016101e5565b610201610332366004611d1a565b61081c565b610295610830565b61020161034d366004612023565b61083a565b6103a5604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b03908116825260208085015182169083015292820151909216908201526060016101e5565b6102296103e5366004611cff565b610864565b6103146103f836600461204d565b61086f565b61020161040b366004611cff565b61091e565b61020161041e366004611e66565b610a5b565b610436610431366004611cff565b610a70565b6040516101e59190612090565b610201610ac4565b610201610459366004612100565b610acc565b600061046982610afe565b92915050565b600161047a81610b2d565b61048382610b57565b5050565b600061049281610b2d565b85841415806104a15750858214155b156104bf57604051637db491eb60e01b815260040160405180910390fd5b60005b868110156105e25760008686838181106104de576104de61214f565b90506020020160208101906104f39190612165565b600381111561050457610504612139565b14801561053f57503388888381811061051f5761051f61214f565b90506020020160208101906105349190611cff565b6001600160a01b0316145b1561055d57604051631eb49d6d60e11b815260040160405180910390fd5b6105da8888838181106105725761057261214f565b90506020020160208101906105879190611cff565b8787848181106105995761059961214f565b90506020020160208101906105ae9190612165565b8686858181106105c0576105c061214f565b90506020020160208101906105d5919061218e565b610bbd565b6001016104c2565b5050505050505050565b606061046982610c5f565b600161060281610b2d565b61060c8383610c74565b505050565b600054600390610100900460ff16158015610633575060005460ff8083169116105b61069b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff8316176101001790556106ba848484610cb6565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600061046982610d0f565b600161071781610b2d565b61072385858585610d3f565b5050505050565b600061046982610dc8565b61073d610e77565b565b600161074a81610b2d565b61048382610f1c565b600061075d610f7a565b905090565b600061075d610f8d565b600161077781610b2d565b61060c8383610fa0565b6107bc6040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61046982610fe2565b6001600160a01b0382166000908152600260205260408120818360038111156107f0576107f0612139565b600381111561080157610801612139565b815260208101919091526040016000205460ff169392505050565b600161082781610b2d565b610483826110df565b600061075d61113e565b33301461085a57604051631b17ff5560e21b815260040160405180910390fd5b6104838282611151565b606061046982611248565b6001600160a01b03831660009081526002602052604081208184600381111561089a5761089a612139565b60038111156108ab576108ab612139565b815260208101919091526040016000205460ff168061091657506001600160a01b0384166000908152600260205260408120908360038111156108f0576108f0612139565b600381111561090157610901612139565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff161580801561093e5750600054600160ff909116105b806109585750303b158015610958575060005460ff166001145b6109bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610692565b6000805460ff1916600117905580156109de576000805461ff0019166101001790555b6001600160a01b038216610a0557604051632c1c702960e21b815260040160405180910390fd5b610a128260006001610bbd565b8015610483576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6001610a6681610b2d565b61060c838361125a565b610abb6040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6104698261129c565b61073d6113ba565b333014610aec57604051631b17ff5560e21b815260040160405180910390fd5b610af884848484611443565b50505050565b600080610b0a83610d0f565b9050610b158161129c565b60c00151610b24576000610b26565b805b9392505050565b610b3733826107c5565b610b5457604051631b17ff5560e21b815260040160405180910390fd5b50565b6064811115610b7957604051630ad1e31b60e01b815260040160405180910390fd5b80610b8261171e565b600401556040518181527fb85b70acaeb40f1a2351367c48842ee0ea24ec05d411d99d80bf7a020c0dbb0f906020015b60405180910390a150565b6001600160a01b03831660009081526002602052604081208291846003811115610be957610be9612139565b6003811115610bfa57610bfa612139565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610c52939291906121ab565b60405180910390a1505050565b6060610c6a8261129c565b6020015192915050565b60005b8181101561060c57610cae838383818110610c9457610c9461214f565b9050602002016020810190610ca99190611cff565b611728565b600101610c77565b6032831180610cc55750606482115b80610cce575080155b15610cec57604051635863f78960e01b815260040160405180910390fd5b6000610cf661171e565b6003810194909455506004830191909155600690910155565b6000610d1961171e565b6001600160a01b0392831660009081526002919091016020526040902054909116919050565b828114610d5f576040516349552d5960e11b815260040160405180910390fd5b60005b8381101561072357610dc0858583818110610d7f57610d7f61214f565b9050602002016020810190610d949190611cff565b848484818110610da657610da661214f565b9050602002016020810190610dbb9190611cff565b6117b7565b600101610d62565b600080610dd361171e565b6001600160a01b0384166000908152600182016020526040812060020154600683015492935091610e0c90670de0b6b3a7640000612205565b90506402540be4008360040154610e239190612205565b935080818311610e335782610e35565b815b85610e466402540be4006064612205565b610e50919061221c565b610e5a9190612205565b610e64919061222f565b610e6e9085612251565b95945050505050565b6000610e8161171e565b33600090815260019190910160205260408120600381015490925090819003610ebd57604051635b8f50bf60e11b815260040160405180910390fd5b60006003830155610ee23382610ed161191b565b546001600160a01b03169190611925565b60405181815233907f25deb48f8299e9863bda34f0d343d51341ac7ac30bf63dbeb2e8212bc4a20bf1906020015b60405180910390a25050565b80600003610f3d57604051637c946ed760e01b815260040160405180910390fd5b80610f4661171e565b600601556040518181527f7e6042545b314fbe2e138616211d5c38934823f783b83a140ea84f0eb2ae115d90602001610bb2565b6000610f8461171e565b60060154905090565b6000610f9761171e565b60040154905090565b60005b8181101561060c57610fda838383818110610fc057610fc061214f565b9050602002016020810190610fd59190611cff565b61198c565b600101610fa3565b61101d6040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61102561171e565b6001600160a01b038316600090815260209182526040908190208151815460e09481028201850190935260c0810183815290939192849284919084018282801561109857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161107a575b50505091835250506001820154602082015260028201546040820152600382015460608201526004820154608082015260059091015460ff16151560a09091015292915050565b603281111561110157604051630ad1e31b60e01b815260040160405180910390fd5b8061110a61171e565b600301556040518181527f2f33e68d48a82acaa58e3dcb12a4c7738cdfe7041d35f0e29ec8c39b780b370c90602001610bb2565b600061114861171e565b60030154905090565b600061115b61171e565b6001600160a01b03808416600090815260018301602090815260408083208885168452600286019092529091205492935091161515806111a257506001600160a01b038316155b806111b25750600681015460ff16155b156111bd5750505050565b6001600160a01b0380851660008181526002850160209081526040808320805495891673ffffffffffffffffffffffffffffffffffffffff19968716811790915560018781018054918201815585529284209092018054909516841790945592517f0e67f4bbcd5c51b7365ca2dd861dc8094e393ca60de2ceae9d831761a839e92a9190a350505050565b606061125382610fe2565b5192915050565b60005b8181101561060c5761129483838381811061127a5761127a61214f565b905060200201602081019061128f9190611cff565b611a1e565b60010161125d565b6112e76040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6112ef61171e565b6001600160a01b03808416600090815260019283016020908152604091829020825160e081018452815490941684529384018054835181840281018401909452808452939493858301939283018282801561137357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611355575b50505091835250506002820154602082015260038201546040820152600482015460608201526005820154608082015260069091015460ff16151560a09091015292915050565b60006113c461171e565b336000908152602091909152604081206002810154909250908190036113fd57604051635b8f50bf60e11b815260040160405180910390fd5b600060028301556114113382610ed161191b565b60405181815233907f3dfe9be199655709d01d635bf441264a809a090c98ed7aae9abdc85f7dcbc09d90602001610f10565b600061144d61171e565b6001600160a01b038087166000908152600283016020908152604080832054909316808352600185019091529190206006810154929350909160ff1661149557505050610af8565b6000846114a76402540be40088612205565b6114b1919061222f565b90506114bb61191b565b546040516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401600060405180830381600087803b15801561150557600080fd5b505af1158015611519573d6000803e3d6000fd5b505083546001600160a01b031660009081526020879052604081206005810154909350909150819060ff1615611656576003870154606461155a828c612205565b611564919061222f565b925060646115728287612205565b61157c919061222f565b91508a8460010160008282546115929190612251565b92505081905550818460020160008282546115ad9190612251565b92505081905550818460030160008282546115c89190612251565b92505081905550828460040160008282546115e39190612251565b909155506115f39050838b61221c565b99506115ff828661221c565b8654604080518e8152602081018690529081018690529196506001600160a01b038e8116929116907f0d54fedb563328d37f00fe5ba0bf7689519f8cf02318562adfe7b4bfab8cf4b49060600160405180910390a3505b8985600201600082825461166a9190612251565b92505081905550838560030160008282546116859190612251565b92505081905550838560040160008282546116a09190612251565b92505081905550888560050160008282546116bb9190612251565b9091555050604080518b8152602081018690529081018a90526001600160a01b03808d1691908816907f74e9754b45c636e199e3d7bb764fae1a9acce47a984d10dcfd74849ec4babc4f9060600160405180910390a35050505050505050505050565b6000806065610469565b600061173261171e565b6001600160a01b038316600090815260209190915260409020600581015490915060ff166117735760405163232990cb60e01b815260040160405180910390fd5b60058101805460ff191690556040516001600160a01b038316907f6900afc1a924abca16a7f560e2dac3d71008c1cd1d88de8a85b6e4267116d18690600090a25050565b6001600160a01b0382166117de5760405163d92e233d60e01b815260040160405180910390fd5b60006117e861171e565b6001600160a01b0384166000908152600182016020526040902060068101549192509060ff161561182c57604051637cdf305160e11b815260040160405180910390fd5b60068101805460ff191660011790556001600160a01b038316156118d5576001600160a01b0383166000908152602083905260409020600581015460ff16611887576040516383f6a90560e01b815260040160405180910390fd5b81546001600160a01b0380861673ffffffffffffffffffffffffffffffffffffffff199283161784558254600181018455600093845260209093209092018054928716929091169190911790555b826001600160a01b0316846001600160a01b03167f15ad1d28b052a6cc2dd1d34d9e06a1847055d520e2163017e6e8aad6431b7f6a60405160405180910390a350505050565b6000806003610469565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b17905261060c908490611ad8565b600061199661171e565b6001600160a01b038316600090815260019190910160205260409020600681015490915060ff166119da5760405163232990cb60e01b815260040160405180910390fd5b60068101805460ff191690556040516001600160a01b038316907f6dd169357c2e2b04fd13a8807a11892b88875b7c70eeb73c3b6642c58516f0db90600090a25050565b6001600160a01b038116611a455760405163d92e233d60e01b815260040160405180910390fd5b6000611a4f61171e565b6001600160a01b038316600090815260209190915260409020600581015490915060ff1615611a9157604051637cdf305160e11b815260040160405180910390fd5b60058101805460ff191660011790556040516001600160a01b038316907f80495287b7fdd5e00b7c8c1eb065c5b63474d11ffb062cc82c13da77dda8424d90600090a25050565b6000611b2d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bc09092919063ffffffff16565b9050805160001480611b4e575080806020019051810190611b4e9190612264565b61060c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610692565b6060610916848460008585600080866001600160a01b03168587604051611be791906122a5565b60006040518083038185875af1925050503d8060008114611c24576040519150601f19603f3d011682016040523d82523d6000602084013e611c29565b606091505b5091509150611c3a87838387611c45565b979650505050505050565b60608315611cb4578251600003611cad576001600160a01b0385163b611cad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610692565b5081610916565b6109168383815115611cc95781518083602001fd5b8060405162461bcd60e51b815260040161069291906122c1565b80356001600160a01b0381168114611cfa57600080fd5b919050565b600060208284031215611d1157600080fd5b610b2682611ce3565b600060208284031215611d2c57600080fd5b5035919050565b60008083601f840112611d4557600080fd5b50813567ffffffffffffffff811115611d5d57600080fd5b6020830191508360208260051b8501011115611d7857600080fd5b9250929050565b60008060008060008060608789031215611d9857600080fd5b863567ffffffffffffffff80821115611db057600080fd5b611dbc8a838b01611d33565b90985096506020890135915080821115611dd557600080fd5b611de18a838b01611d33565b90965094506040890135915080821115611dfa57600080fd5b50611e0789828a01611d33565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b81811015611e5a5783516001600160a01b031683529284019291840191600101611e35565b50909695505050505050565b60008060208385031215611e7957600080fd5b823567ffffffffffffffff811115611e9057600080fd5b611e9c85828601611d33565b90969095509350505050565b600080600060608486031215611ebd57600080fd5b505081359360208301359350604090920135919050565b60008060008060408587031215611eea57600080fd5b843567ffffffffffffffff80821115611f0257600080fd5b611f0e88838901611d33565b90965094506020870135915080821115611f2757600080fd5b50611f3487828801611d33565b95989497509550505050565b60008151808452602080850194506020840160005b83811015611f7a5781516001600160a01b031687529582019590820190600101611f55565b509495945050505050565b602081526000825160c06020840152611fa160e0840182611f40565b9050602084015160408401526040840151606084015260608401516080840152608084015160a084015260a0840151151560c08401528091505092915050565b803560048110611cfa57600080fd5b6000806040838503121561200357600080fd5b61200c83611ce3565b915061201a60208401611fe1565b90509250929050565b6000806040838503121561203657600080fd5b61203f83611ce3565b915061201a60208401611ce3565b60008060006060848603121561206257600080fd5b61206b84611ce3565b925061207960208501611fe1565b915061208760408501611fe1565b90509250925092565b602081526001600160a01b0382511660208201526000602083015160e060408401526120c0610100840182611f40565b90506040840151606084015260608401516080840152608084015160a084015260a084015160c084015260c0840151151560e08401528091505092915050565b6000806000806080858703121561211657600080fd5b61211f85611ce3565b966020860135965060408601359560600135945092505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561217757600080fd5b610b2682611fe1565b8015158114610b5457600080fd5b6000602082840312156121a057600080fd5b8135610b2681612180565b6001600160a01b038416815260608101600484106121d957634e487b7160e01b600052602160045260246000fd5b8360208301528215156040830152949350505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610469576104696121ef565b81810381811115610469576104696121ef565b60008261224c57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610469576104696121ef565b60006020828403121561227657600080fd5b8151610b2681612180565b60005b8381101561229c578181015183820152602001612284565b50506000910152565b600082516122b7818460208701612281565b9190910192915050565b60208152600082518060208401526122e0816040850160208701612281565b601f01601f1916919091016040019291505056fea2646970667358221220c3b727325c5206e249710d42725215c4a8f7b2345d6ff645649270898ca6ec2064736f6c63430008170033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101b95760003560e01c806392b2bbae116100f9578063a73a3e3511610097578063c72d02e311610071578063c72d02e314610410578063cbe0f32e14610423578063ee6cf88414610443578063fa3c8dbf1461044b57600080fd5b8063a73a3e35146103d7578063b9c97229146103ea578063c4d66de8146103fd57600080fd5b806397365b74116100d357806397365b741461032457806397436b5f146103375780639b8ab6841461033f578063a39fac121461035257600080fd5b806392b2bbae146102ce57806392e67406146102e157806395a8c58d1461030157600080fd5b806346dbf5721161016657806365cbd3071161014057806365cbd307146102a357806366ddd309146102ab57806371159fd1146102be578063843b9e5d146102c657600080fd5b806346dbf5721461025c578063507cd8de1461026f5780635d19b5d31461028257600080fd5b806332a7b7321161019757806332a7b732146102165780633450191e1461023657806338fb18c71461024957600080fd5b8063036787e5146101be57806303e37464146101ee578063101e650314610203575b600080fd5b6101d16101cc366004611cff565b61045e565b6040516001600160a01b0390911681526020015b60405180910390f35b6102016101fc366004611d1a565b61046f565b005b610201610211366004611d7f565b610487565b610229610224366004611cff565b6105ec565b6040516101e59190611e19565b610201610244366004611e66565b6105f7565b610201610257366004611ea8565b610611565b6101d161026a366004611cff565b610701565b61020161027d366004611ed4565b61070c565b610295610290366004611cff565b61072a565b6040519081526020016101e5565b610201610735565b6102016102b9366004611d1a565b61073f565b610295610753565b610295610762565b6102016102dc366004611e66565b61076c565b6102f46102ef366004611cff565b610781565b6040516101e59190611f85565b61031461030f366004611ff0565b6107c5565b60405190151581526020016101e5565b610201610332366004611d1a565b61081c565b610295610830565b61020161034d366004612023565b61083a565b6103a5604080516060810182526000808252602082018190529181019190915250604080516060810182526003546001600160a01b03908116825260045481166020830152600554169181019190915290565b6040805182516001600160a01b03908116825260208085015182169083015292820151909216908201526060016101e5565b6102296103e5366004611cff565b610864565b6103146103f836600461204d565b61086f565b61020161040b366004611cff565b61091e565b61020161041e366004611e66565b610a5b565b610436610431366004611cff565b610a70565b6040516101e59190612090565b610201610ac4565b610201610459366004612100565b610acc565b600061046982610afe565b92915050565b600161047a81610b2d565b61048382610b57565b5050565b600061049281610b2d565b85841415806104a15750858214155b156104bf57604051637db491eb60e01b815260040160405180910390fd5b60005b868110156105e25760008686838181106104de576104de61214f565b90506020020160208101906104f39190612165565b600381111561050457610504612139565b14801561053f57503388888381811061051f5761051f61214f565b90506020020160208101906105349190611cff565b6001600160a01b0316145b1561055d57604051631eb49d6d60e11b815260040160405180910390fd5b6105da8888838181106105725761057261214f565b90506020020160208101906105879190611cff565b8787848181106105995761059961214f565b90506020020160208101906105ae9190612165565b8686858181106105c0576105c061214f565b90506020020160208101906105d5919061218e565b610bbd565b6001016104c2565b5050505050505050565b606061046982610c5f565b600161060281610b2d565b61060c8383610c74565b505050565b600054600390610100900460ff16158015610633575060005460ff8083169116105b61069b5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805461ffff191660ff8316176101001790556106ba848484610cb6565b6000805461ff001916905560405160ff821681527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050565b600061046982610d0f565b600161071781610b2d565b61072385858585610d3f565b5050505050565b600061046982610dc8565b61073d610e77565b565b600161074a81610b2d565b61048382610f1c565b600061075d610f7a565b905090565b600061075d610f8d565b600161077781610b2d565b61060c8383610fa0565b6107bc6040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61046982610fe2565b6001600160a01b0382166000908152600260205260408120818360038111156107f0576107f0612139565b600381111561080157610801612139565b815260208101919091526040016000205460ff169392505050565b600161082781610b2d565b610483826110df565b600061075d61113e565b33301461085a57604051631b17ff5560e21b815260040160405180910390fd5b6104838282611151565b606061046982611248565b6001600160a01b03831660009081526002602052604081208184600381111561089a5761089a612139565b60038111156108ab576108ab612139565b815260208101919091526040016000205460ff168061091657506001600160a01b0384166000908152600260205260408120908360038111156108f0576108f0612139565b600381111561090157610901612139565b815260208101919091526040016000205460ff165b949350505050565b600054610100900460ff161580801561093e5750600054600160ff909116105b806109585750303b158015610958575060005460ff166001145b6109bb5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610692565b6000805460ff1916600117905580156109de576000805461ff0019166101001790555b6001600160a01b038216610a0557604051632c1c702960e21b815260040160405180910390fd5b610a128260006001610bbd565b8015610483576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b6001610a6681610b2d565b61060c838361125a565b610abb6040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6104698261129c565b61073d6113ba565b333014610aec57604051631b17ff5560e21b815260040160405180910390fd5b610af884848484611443565b50505050565b600080610b0a83610d0f565b9050610b158161129c565b60c00151610b24576000610b26565b805b9392505050565b610b3733826107c5565b610b5457604051631b17ff5560e21b815260040160405180910390fd5b50565b6064811115610b7957604051630ad1e31b60e01b815260040160405180910390fd5b80610b8261171e565b600401556040518181527fb85b70acaeb40f1a2351367c48842ee0ea24ec05d411d99d80bf7a020c0dbb0f906020015b60405180910390a150565b6001600160a01b03831660009081526002602052604081208291846003811115610be957610be9612139565b6003811115610bfa57610bfa612139565b815260200190815260200160002060006101000a81548160ff0219169083151502179055507f8d7fdec37f50c07219a6a0859420936836eb9254bf412035e3acede18b8b093d838383604051610c52939291906121ab565b60405180910390a1505050565b6060610c6a8261129c565b6020015192915050565b60005b8181101561060c57610cae838383818110610c9457610c9461214f565b9050602002016020810190610ca99190611cff565b611728565b600101610c77565b6032831180610cc55750606482115b80610cce575080155b15610cec57604051635863f78960e01b815260040160405180910390fd5b6000610cf661171e565b6003810194909455506004830191909155600690910155565b6000610d1961171e565b6001600160a01b0392831660009081526002919091016020526040902054909116919050565b828114610d5f576040516349552d5960e11b815260040160405180910390fd5b60005b8381101561072357610dc0858583818110610d7f57610d7f61214f565b9050602002016020810190610d949190611cff565b848484818110610da657610da661214f565b9050602002016020810190610dbb9190611cff565b6117b7565b600101610d62565b600080610dd361171e565b6001600160a01b0384166000908152600182016020526040812060020154600683015492935091610e0c90670de0b6b3a7640000612205565b90506402540be4008360040154610e239190612205565b935080818311610e335782610e35565b815b85610e466402540be4006064612205565b610e50919061221c565b610e5a9190612205565b610e64919061222f565b610e6e9085612251565b95945050505050565b6000610e8161171e565b33600090815260019190910160205260408120600381015490925090819003610ebd57604051635b8f50bf60e11b815260040160405180910390fd5b60006003830155610ee23382610ed161191b565b546001600160a01b03169190611925565b60405181815233907f25deb48f8299e9863bda34f0d343d51341ac7ac30bf63dbeb2e8212bc4a20bf1906020015b60405180910390a25050565b80600003610f3d57604051637c946ed760e01b815260040160405180910390fd5b80610f4661171e565b600601556040518181527f7e6042545b314fbe2e138616211d5c38934823f783b83a140ea84f0eb2ae115d90602001610bb2565b6000610f8461171e565b60060154905090565b6000610f9761171e565b60040154905090565b60005b8181101561060c57610fda838383818110610fc057610fc061214f565b9050602002016020810190610fd59190611cff565b61198c565b600101610fa3565b61101d6040518060c0016040528060608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b61102561171e565b6001600160a01b038316600090815260209182526040908190208151815460e09481028201850190935260c0810183815290939192849284919084018282801561109857602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831161107a575b50505091835250506001820154602082015260028201546040820152600382015460608201526004820154608082015260059091015460ff16151560a09091015292915050565b603281111561110157604051630ad1e31b60e01b815260040160405180910390fd5b8061110a61171e565b600301556040518181527f2f33e68d48a82acaa58e3dcb12a4c7738cdfe7041d35f0e29ec8c39b780b370c90602001610bb2565b600061114861171e565b60030154905090565b600061115b61171e565b6001600160a01b03808416600090815260018301602090815260408083208885168452600286019092529091205492935091161515806111a257506001600160a01b038316155b806111b25750600681015460ff16155b156111bd5750505050565b6001600160a01b0380851660008181526002850160209081526040808320805495891673ffffffffffffffffffffffffffffffffffffffff19968716811790915560018781018054918201815585529284209092018054909516841790945592517f0e67f4bbcd5c51b7365ca2dd861dc8094e393ca60de2ceae9d831761a839e92a9190a350505050565b606061125382610fe2565b5192915050565b60005b8181101561060c5761129483838381811061127a5761127a61214f565b905060200201602081019061128f9190611cff565b611a1e565b60010161125d565b6112e76040518060e0016040528060006001600160a01b0316815260200160608152602001600081526020016000815260200160008152602001600081526020016000151581525090565b6112ef61171e565b6001600160a01b03808416600090815260019283016020908152604091829020825160e081018452815490941684529384018054835181840281018401909452808452939493858301939283018282801561137357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611355575b50505091835250506002820154602082015260038201546040820152600482015460608201526005820154608082015260069091015460ff16151560a09091015292915050565b60006113c461171e565b336000908152602091909152604081206002810154909250908190036113fd57604051635b8f50bf60e11b815260040160405180910390fd5b600060028301556114113382610ed161191b565b60405181815233907f3dfe9be199655709d01d635bf441264a809a090c98ed7aae9abdc85f7dcbc09d90602001610f10565b600061144d61171e565b6001600160a01b038087166000908152600283016020908152604080832054909316808352600185019091529190206006810154929350909160ff1661149557505050610af8565b6000846114a76402540be40088612205565b6114b1919061222f565b90506114bb61191b565b546040516340c10f1960e01b8152306004820152602481018390526001600160a01b03909116906340c10f1990604401600060405180830381600087803b15801561150557600080fd5b505af1158015611519573d6000803e3d6000fd5b505083546001600160a01b031660009081526020879052604081206005810154909350909150819060ff1615611656576003870154606461155a828c612205565b611564919061222f565b925060646115728287612205565b61157c919061222f565b91508a8460010160008282546115929190612251565b92505081905550818460020160008282546115ad9190612251565b92505081905550818460030160008282546115c89190612251565b92505081905550828460040160008282546115e39190612251565b909155506115f39050838b61221c565b99506115ff828661221c565b8654604080518e8152602081018690529081018690529196506001600160a01b038e8116929116907f0d54fedb563328d37f00fe5ba0bf7689519f8cf02318562adfe7b4bfab8cf4b49060600160405180910390a3505b8985600201600082825461166a9190612251565b92505081905550838560030160008282546116859190612251565b92505081905550838560040160008282546116a09190612251565b92505081905550888560050160008282546116bb9190612251565b9091555050604080518b8152602081018690529081018a90526001600160a01b03808d1691908816907f74e9754b45c636e199e3d7bb764fae1a9acce47a984d10dcfd74849ec4babc4f9060600160405180910390a35050505050505050505050565b6000806065610469565b600061173261171e565b6001600160a01b038316600090815260209190915260409020600581015490915060ff166117735760405163232990cb60e01b815260040160405180910390fd5b60058101805460ff191690556040516001600160a01b038316907f6900afc1a924abca16a7f560e2dac3d71008c1cd1d88de8a85b6e4267116d18690600090a25050565b6001600160a01b0382166117de5760405163d92e233d60e01b815260040160405180910390fd5b60006117e861171e565b6001600160a01b0384166000908152600182016020526040902060068101549192509060ff161561182c57604051637cdf305160e11b815260040160405180910390fd5b60068101805460ff191660011790556001600160a01b038316156118d5576001600160a01b0383166000908152602083905260409020600581015460ff16611887576040516383f6a90560e01b815260040160405180910390fd5b81546001600160a01b0380861673ffffffffffffffffffffffffffffffffffffffff199283161784558254600181018455600093845260209093209092018054928716929091169190911790555b826001600160a01b0316846001600160a01b03167f15ad1d28b052a6cc2dd1d34d9e06a1847055d520e2163017e6e8aad6431b7f6a60405160405180910390a350505050565b6000806003610469565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b17905261060c908490611ad8565b600061199661171e565b6001600160a01b038316600090815260019190910160205260409020600681015490915060ff166119da5760405163232990cb60e01b815260040160405180910390fd5b60068101805460ff191690556040516001600160a01b038316907f6dd169357c2e2b04fd13a8807a11892b88875b7c70eeb73c3b6642c58516f0db90600090a25050565b6001600160a01b038116611a455760405163d92e233d60e01b815260040160405180910390fd5b6000611a4f61171e565b6001600160a01b038316600090815260209190915260409020600581015490915060ff1615611a9157604051637cdf305160e11b815260040160405180910390fd5b60058101805460ff191660011790556040516001600160a01b038316907f80495287b7fdd5e00b7c8c1eb065c5b63474d11ffb062cc82c13da77dda8424d90600090a25050565b6000611b2d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bc09092919063ffffffff16565b9050805160001480611b4e575080806020019051810190611b4e9190612264565b61060c5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610692565b6060610916848460008585600080866001600160a01b03168587604051611be791906122a5565b60006040518083038185875af1925050503d8060008114611c24576040519150601f19603f3d011682016040523d82523d6000602084013e611c29565b606091505b5091509150611c3a87838387611c45565b979650505050505050565b60608315611cb4578251600003611cad576001600160a01b0385163b611cad5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610692565b5081610916565b6109168383815115611cc95781518083602001fd5b8060405162461bcd60e51b815260040161069291906122c1565b80356001600160a01b0381168114611cfa57600080fd5b919050565b600060208284031215611d1157600080fd5b610b2682611ce3565b600060208284031215611d2c57600080fd5b5035919050565b60008083601f840112611d4557600080fd5b50813567ffffffffffffffff811115611d5d57600080fd5b6020830191508360208260051b8501011115611d7857600080fd5b9250929050565b60008060008060008060608789031215611d9857600080fd5b863567ffffffffffffffff80821115611db057600080fd5b611dbc8a838b01611d33565b90985096506020890135915080821115611dd557600080fd5b611de18a838b01611d33565b90965094506040890135915080821115611dfa57600080fd5b50611e0789828a01611d33565b979a9699509497509295939492505050565b6020808252825182820181905260009190848201906040850190845b81811015611e5a5783516001600160a01b031683529284019291840191600101611e35565b50909695505050505050565b60008060208385031215611e7957600080fd5b823567ffffffffffffffff811115611e9057600080fd5b611e9c85828601611d33565b90969095509350505050565b600080600060608486031215611ebd57600080fd5b505081359360208301359350604090920135919050565b60008060008060408587031215611eea57600080fd5b843567ffffffffffffffff80821115611f0257600080fd5b611f0e88838901611d33565b90965094506020870135915080821115611f2757600080fd5b50611f3487828801611d33565b95989497509550505050565b60008151808452602080850194506020840160005b83811015611f7a5781516001600160a01b031687529582019590820190600101611f55565b509495945050505050565b602081526000825160c06020840152611fa160e0840182611f40565b9050602084015160408401526040840151606084015260608401516080840152608084015160a084015260a0840151151560c08401528091505092915050565b803560048110611cfa57600080fd5b6000806040838503121561200357600080fd5b61200c83611ce3565b915061201a60208401611fe1565b90509250929050565b6000806040838503121561203657600080fd5b61203f83611ce3565b915061201a60208401611ce3565b60008060006060848603121561206257600080fd5b61206b84611ce3565b925061207960208501611fe1565b915061208760408501611fe1565b90509250925092565b602081526001600160a01b0382511660208201526000602083015160e060408401526120c0610100840182611f40565b90506040840151606084015260608401516080840152608084015160a084015260a084015160c084015260c0840151151560e08401528091505092915050565b6000806000806080858703121561211657600080fd5b61211f85611ce3565b966020860135965060408601359560600135945092505050565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561217757600080fd5b610b2682611fe1565b8015158114610b5457600080fd5b6000602082840312156121a057600080fd5b8135610b2681612180565b6001600160a01b038416815260608101600484106121d957634e487b7160e01b600052602160045260246000fd5b8360208301528215156040830152949350505050565b634e487b7160e01b600052601160045260246000fd5b8082028115828204841417610469576104696121ef565b81810381811115610469576104696121ef565b60008261224c57634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610469576104696121ef565b60006020828403121561227657600080fd5b8151610b2681612180565b60005b8381101561229c578181015183820152602001612284565b50506000910152565b600082516122b7818460208701612281565b9190910192915050565b60208152600082518060208401526122e0816040850160208701612281565b601f01601f1916919091016040019291505056fea2646970667358221220c3b727325c5206e249710d42725215c4a8f7b2345d6ff645649270898ca6ec2064736f6c63430008170033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.