Cryo Explorer Ethereum Mainnet

Address Contract Verified

Address 0x6DC18a14c7CfA54Cc34Ee6A776adC0D0D6f3BcCF
Balance 0 ETH
Nonce 1
Code Size 3602 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

3602 bytes
0x608060405234801561001057600080fd5b50600436106101735760003560e01c806375b238fc116100de578063a217fddf11610097578063dfcfa25011610071578063dfcfa250146103de578063e1e01bf3146103f1578063e1f1c4a714610404578063ed8431341461040d57600080fd5b8063a217fddf14610382578063c8b3c4601461038a578063d547741f146103cb57600080fd5b806375b238fc14610301578063836a01871461031657806385725b581461032957806391d14854146103495780639c8e2de91461035c5780639cb7de4b1461036f57600080fd5b806336def2c81161013057806336def2c8146102555780633fb8b3231461026857806346ea87af1461027b578063534ef8831461029e57806356b4b2ad146102ce57806371a6a790146102e157600080fd5b806301ffc9a714610178578063039af9eb146101a05780631582a018146101dc578063248a9ca31461020a5780632f2ff15d1461022d57806336568abe14610242575b600080fd5b61018b610186366004610c00565b610420565b60405190151581526020015b60405180910390f35b6101c76101ae366004610c31565b6003602052600090815260409020805460019091015482565b60408051928352602083019190915201610197565b6101fc6101ea366004610c66565b60026020526000908152604090205481565b604051908152602001610197565b6101fc610218366004610c31565b60009081526020819052604090206001015490565b61024061023b366004610c81565b610457565b005b610240610250366004610c81565b610482565b610240610263366004610c31565b6104ba565b610240610276366004610cad565b61059d565b61018b610289366004610c66565b60046020526000908152604090205460ff1681565b6102b16102ac366004610c66565b6105fd565b604080519283526001600160a01b03909116602083015201610197565b6102406102dc366004610cad565b610643565b6101fc6102ef366004610c66565b60016020526000908152604090205481565b6101fc600080516020610dbd83398151915281565b610240610324366004610cd7565b6106bb565b6101fc610337366004610c66565b60066020526000908152604090205481565b61018b610357366004610c81565b6107cc565b61024061036a366004610c31565b6107f5565b61024061037d366004610d03565b61086d565b6101fc600081565b6103b3610398366004610c31565b6005602052600090815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610197565b6102406103d9366004610c81565b6108da565b6102406103ec366004610c81565b6108ff565b6102406103ff366004610c31565b61098e565b6101fc61271081565b61024061041b366004610c81565b61099b565b60006001600160e01b03198216637965db0b60e01b148061045157506301ffc9a760e01b6001600160e01b03198316145b92915050565b60008281526020819052604090206001015461047281610a79565b61047c8383610a83565b50505050565b6001600160a01b03811633146104ab5760405163334bd91960e11b815260040160405180910390fd5b6104b58282610b15565b505050565b806104e05760405162461bcd60e51b81526004016104d790610d3f565b60405180910390fd5b6000818152600560205260409020546001600160a01b0316156105515760405162461bcd60e51b8152602060048201526024808201527f526566657272616c53746f726167653a20636f646520616c72656164792065786044820152636973747360e01b60648201526084016104d7565b60008181526005602052604080822080546001600160a01b03191633908117909155905183927f04f82286a2a3b2ee5c8555de8304dfe2ea70991613213184b73a9e408d2d802991a350565b600080516020610dbd8339815191526105b581610a79565b6001600160a01b038316600081815260026020526040808220859055518492917f7696855cdbb94bb5a44cb0a95caff6f29173aa1cbfba193834b12b90827ce2bc91a3505050565b6001600160a01b038116600090815260066020526040812054819081811561063957506000818152600560205260409020546001600160a01b03165b9094909350915050565b3360009081526004602052604090205460ff166106ad5760405162461bcd60e51b815260206004820152602260248201527f526566657272616c53746f726167653a204d75737420626520612068616e646c60448201526132b960f11b60648201526084016104d7565b6106b78282610b80565b5050565b600080516020610dbd8339815191526106d381610a79565b6127108311156107315760405162461bcd60e51b8152602060048201526024808201527f526566657272616c53746f726167653a20696e76616c696420746f74616c52656044820152636261746560e01b60648201526084016104d7565b6127108211156107535760405162461bcd60e51b81526004016104d790610d76565b600084815260036020818152604080842081518083018352888152808401888152958a9052939092528251825592516001909101559051839086907f4ebd23a492b2bd79586cb57cae40d7793408265f20320f68b478b971e696f4c7906107bd9088815260200190565b60405180910390a35050505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b600080516020610dbd83398151915261080d81610a79565b61271082111561082f5760405162461bcd60e51b81526004016104d790610d76565b33600081815260016020526040808220859055518492917fbd224f3917462b0fa80805fe3ec29be3a37f664955aad6224e5ece036224c42991a35050565b600080516020610dbd83398151915261088581610a79565b6001600160a01b038316600081815260046020526040808220805460ff191686151590811790915590519092917fd373464a39404e5f98fdb4b152b8ba9a094561e97e5c4b4ea11eb18cd9e6695e91a3505050565b6000828152602081905260409020600101546108f581610a79565b61047c8383610b15565b600080516020610dbd83398151915261091781610a79565b826109345760405162461bcd60e51b81526004016104d790610d3f565b60008381526005602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051909185917f6431f88c655dd0e2b8d09b6405c007c515c66d67f2998e69c902873a8c8f3e979190a3505050565b6109983382610b80565b50565b816109b85760405162461bcd60e51b81526004016104d790610d3f565b6000828152600560205260409020546001600160a01b0316338114610a1f5760405162461bcd60e51b815260206004820152601a60248201527f526566657272616c53746f726167653a20666f7262696464656e00000000000060448201526064016104d7565b60008381526005602052604080822080546001600160a01b0319166001600160a01b0386169081179091559051859233917f5640856798d41ce9ca0a109b54c20a06eb99ba9c36ab4547115dafb8473cf3979190a4505050565b6109988133610bc7565b6000610a8f83836107cc565b610b0d576000838152602081815260408083206001600160a01b03861684529091529020805460ff19166001179055610ac53390565b6001600160a01b0316826001600160a01b0316847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a4506001610451565b506000610451565b6000610b2183836107cc565b15610b0d576000838152602081815260408083206001600160a01b0386168085529252808320805460ff1916905551339286917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a4506001610451565b6001600160a01b038216600081815260066020526040808220849055518392917f43825f14567dda057e821be2e51a5aa79aa51f3907a647e3ed2bd486a01050f191a35050565b610bd182826107cc565b6106b75760405163e2517d3f60e01b81526001600160a01b0382166004820152602481018390526044016104d7565b600060208284031215610c1257600080fd5b81356001600160e01b031981168114610c2a57600080fd5b9392505050565b600060208284031215610c4357600080fd5b5035919050565b80356001600160a01b0381168114610c6157600080fd5b919050565b600060208284031215610c7857600080fd5b610c2a82610c4a565b60008060408385031215610c9457600080fd5b82359150610ca460208401610c4a565b90509250929050565b60008060408385031215610cc057600080fd5b610cc983610c4a565b946020939093013593505050565b600080600060608486031215610cec57600080fd5b505081359360208301359350604090920135919050565b60008060408385031215610d1657600080fd5b610d1f83610c4a565b915060208301358015158114610d3457600080fd5b809150509250929050565b6020808252601e908201527f526566657272616c53746f726167653a20696e76616c6964205f636f64650000604082015260600190565b60208082526026908201527f526566657272616c53746f726167653a20696e76616c696420646973636f756e60408201526574536861726560d01b60608201526080019056fea49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a26469706673582212203e41a6ef20c39954e8e2ead9a17a2174de8aa3fdf447a40093dfebce33354c9764736f6c634300081b0033

Verified Source Code Full Match

Compiler: v0.8.27+commit.40a35a09 EVM: paris Optimization: Yes (200 runs)
AccessControl.sol 209 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/AccessControl.sol)

pragma solidity ^0.8.20;

import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```solidity
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```solidity
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
 * to enforce additional security measures for this role.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address account => bool) hasRole;
        bytes32 adminRole;
    }

    mapping(bytes32 role => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with an {AccessControlUnauthorizedAccount} error including the required role.
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual returns (bool) {
        return _roles[role].hasRole[account];
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
     * is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
     * is missing `role`.
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert AccessControlUnauthorizedAccount(account, role);
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address callerConfirmation) public virtual {
        if (callerConfirmation != _msgSender()) {
            revert AccessControlBadConfirmation();
        }

        _revokeRole(role, callerConfirmation);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
        if (!hasRole(role, account)) {
            _roles[role].hasRole[account] = true;
            emit RoleGranted(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
        if (hasRole(role, account)) {
            _roles[role].hasRole[account] = false;
            emit RoleRevoked(role, account, _msgSender());
            return true;
        } else {
            return false;
        }
    }
}
IAccessControl.sol 98 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/IAccessControl.sol)

pragma solidity ^0.8.20;

/**
 * @dev External interface of AccessControl declared to support ERC-165 detection.
 */
interface IAccessControl {
    /**
     * @dev The `account` is missing a role.
     */
    error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);

    /**
     * @dev The caller of a function is not the expected one.
     *
     * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
     */
    error AccessControlBadConfirmation();

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted to signal this.
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
     * Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     */
    function renounceRole(bytes32 role, address callerConfirmation) external;
}
Context.sol 28 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}
ERC165.sol 27 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "./IERC165.sol";

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}
IERC165.sol 25 lines
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
IReferralStorage.sol 11 lines
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

interface IReferralStorage {
    function setTraderReferralCode(address _account, bytes32 _code) external;
    function getTraderReferralInfo(address _account) external view returns (bytes32, address);
    function setHandler(address _handler, bool _isHandler) external;
    function registerCode(bytes32 _code) external;
    function setTraderReferralCodeByUser(bytes32 _code) external;
}
ReferralStorage.sol 122 lines
// SPDX-License-Identifier: MIT

pragma solidity 0.8.27;

import {IReferralStorage} from "../interfaces/IReferralStorage.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";

contract ReferralStorage is IReferralStorage, AccessControl {

    bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");

    // NOTE: We will change this system as we want to setup 4 tiers of referral program
    struct Tier {
        uint256 totalRebate; // e.g. 2400 for 24%
        uint256 discountShare; // 5000 for 50%/50%, 7000 for 30% rebates/70% discount
    }

    uint256 public constant BASIS_POINTS = 10000;

    mapping (address => uint256) public referrerDiscountShares; // to override default value in tier
    mapping (address => uint256) public referrerTiers; // link between user <> tier
    mapping (uint256 => Tier) public tiers;

    mapping (address => bool) public isHandler;

    mapping (bytes32 => address) public codeOwners;
    mapping (address => bytes32) public traderReferralCodes;

    event SetHandler(address indexed handler, bool indexed isActive);
    event SetTraderReferralCode(address indexed account, bytes32 indexed code);
    event SetTier(uint256 indexed tierId, uint256 totalRebate, uint256 indexed discountShare);
    event SetReferrerTier(address indexed referrer, uint256 indexed tierId);
    event SetReferrerDiscountShare(address indexed referrer, uint256 indexed discountShare);
    event RegisterCode(address indexed account, bytes32 indexed code);
    event SetCodeOwner(address indexed account, address indexed newAccount, bytes32 indexed code);
    event GovSetCodeOwner(bytes32 indexed code, address indexed newAccount);

    modifier onlyHandler() {
        require(isHandler[msg.sender], "ReferralStorage: Must be a handler");
        _;
    }

    constructor() {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(ADMIN_ROLE, msg.sender);
    }

    function setHandler(address _handler, bool _isActive) external onlyRole(ADMIN_ROLE) {
        isHandler[_handler] = _isActive;
        emit SetHandler(_handler, _isActive);
    }

    function setTier(uint256 _tierId, uint256 _totalRebate, uint256 _discountShare) external onlyRole(ADMIN_ROLE) {
        require(_totalRebate <= BASIS_POINTS, "ReferralStorage: invalid totalRebate");
        require(_discountShare <= BASIS_POINTS, "ReferralStorage: invalid discountShare");

        Tier memory tier = tiers[_tierId];
        tier.totalRebate = _totalRebate;
        tier.discountShare = _discountShare;
        tiers[_tierId] = tier;
        emit SetTier(_tierId, _totalRebate, _discountShare);
    }

    function setReferrerTier(address _referrer, uint256 _tierId) external onlyRole(ADMIN_ROLE) {
        referrerTiers[_referrer] = _tierId;
        emit SetReferrerTier(_referrer, _tierId);
    }

    function setReferrerDiscountShare(uint256 _discountShare) external onlyRole(ADMIN_ROLE) {
        require(_discountShare <= BASIS_POINTS, "ReferralStorage: invalid discountShare");

        referrerDiscountShares[msg.sender] = _discountShare;
        emit SetReferrerDiscountShare(msg.sender, _discountShare);
    }

    function setTraderReferralCode(address _account, bytes32 _code) external override onlyHandler {
        _setTraderReferralCode(_account, _code);
    }

    function setTraderReferralCodeByUser(bytes32 _code) external {
        _setTraderReferralCode(msg.sender, _code);
    }

    function registerCode(bytes32 _code) external {
        require(_code != bytes32(0), "ReferralStorage: invalid _code");
        require(codeOwners[_code] == address(0), "ReferralStorage: code already exists");

        codeOwners[_code] = msg.sender;
        emit RegisterCode(msg.sender, _code);
    }

    function setCodeOwner(bytes32 _code, address _newAccount) external {
        require(_code != bytes32(0), "ReferralStorage: invalid _code");

        address account = codeOwners[_code];
        require(msg.sender == account, "ReferralStorage: forbidden");

        codeOwners[_code] = _newAccount;
        emit SetCodeOwner(msg.sender, _newAccount, _code);
    }

    function govSetCodeOwner(bytes32 _code, address _newAccount) external onlyRole(ADMIN_ROLE) {
        require(_code != bytes32(0), "ReferralStorage: invalid _code");

        codeOwners[_code] = _newAccount;
        emit GovSetCodeOwner(_code, _newAccount);
    }

    function getTraderReferralInfo(address _account) external override view returns (bytes32, address) {
        bytes32 code = traderReferralCodes[_account];
        address referrer;
        if (code != bytes32(0)) {
            referrer = codeOwners[code];
        }
        return (code, referrer);
    }

    function _setTraderReferralCode(address _account, bytes32 _code) private {
        traderReferralCodes[_account] = _code;
        emit SetTraderReferralCode(_account, _code);
    }
}

Read Contract

ADMIN_ROLE 0x75b238fc → bytes32
BASIS_POINTS 0xe1f1c4a7 → uint256
DEFAULT_ADMIN_ROLE 0xa217fddf → bytes32
codeOwners 0xc8b3c460 → address
getRoleAdmin 0x248a9ca3 → bytes32
getTraderReferralInfo 0x534ef883 → bytes32, address
hasRole 0x91d14854 → bool
isHandler 0x46ea87af → bool
referrerDiscountShares 0x71a6a790 → uint256
referrerTiers 0x1582a018 → uint256
supportsInterface 0x01ffc9a7 → bool
tiers 0x039af9eb → uint256, uint256
traderReferralCodes 0x85725b58 → bytes32

Write Contract 12 functions

These functions modify contract state and require a wallet transaction to execute.

govSetCodeOwner 0xdfcfa250
bytes32 _code
address _newAccount
grantRole 0x2f2ff15d
bytes32 role
address account
registerCode 0x36def2c8
bytes32 _code
renounceRole 0x36568abe
bytes32 role
address callerConfirmation
revokeRole 0xd547741f
bytes32 role
address account
setCodeOwner 0xed843134
bytes32 _code
address _newAccount
setHandler 0x9cb7de4b
address _handler
bool _isActive
setReferrerDiscountShare 0x9c8e2de9
uint256 _discountShare
setReferrerTier 0x3fb8b323
address _referrer
uint256 _tierId
setTier 0x836a0187
uint256 _tierId
uint256 _totalRebate
uint256 _discountShare
setTraderReferralCode 0x56b4b2ad
address _account
bytes32 _code
setTraderReferralCodeByUser 0xe1e01bf3
bytes32 _code

Recent Transactions

No transactions found for this address