Sonic Blaze Testnet

Contract Diff Checker

Contract Name:
Referral

Contract Source Code:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

interface IManager {
    function getContract(string memory name) external view returns (address);
    function owner() external view returns (address);
}

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.24;

import "./interfaces/IManager.sol";

contract Referral {
    struct ReferralInfo {
        address[] referrals;
        uint256[] timeOfReferrals;
    }

    mapping(address => string) private shortReferralCodes;
    mapping(string => address) private shortCodeOwners;

    mapping(address => bytes32) private bytesReferralCodes;
    mapping(bytes32 => address) private codeOwnersBytes;

    mapping(address => ReferralInfo) private referrals;
    mapping(address => address) private referrers;

    mapping(address => bool) private isAuthorized;
    bool public isStarted = false;

    uint256 private salt;

    IManager private Manager;

    //--------------------------------------------------//

    constructor(address _manager) {
        Manager = IManager(_manager);
    }

    //--------------------------------------------------//

    modifier onlyStaking() {
        address _Staking = Manager.getContract("Staking");
        require(
            msg.sender == _Staking || msg.sender == Manager.owner(),
            "Only Staking can call this function"
        );
        _;
    }

    modifier onlyOwner() {
        require(
            msg.sender == Manager.owner(),
            "Only owner can call this function"
        );
        _;
    }

    //--------------------------------------------------//

    function setManager(address _manager) external onlyOwner {
        Manager = IManager(_manager);
    }

    function setIsStarted(bool _isStarted) external onlyOwner {
        isStarted = _isStarted;
    }

    function setIsAuthorizedBatch(
        address[] memory users,
        bool _isAuthorized
    ) external onlyOwner {
        for (uint256 i = 0; i < users.length; i++) {
            isAuthorized[users[i]] = _isAuthorized;
        }
    }

    function setIsAuthorized(
        address user,
        bool _isAuthorized
    ) external onlyOwner {
        isAuthorized[user] = _isAuthorized;
    }

    //--------------------------------------------------//

    /**
     * @dev generates a referral code for the caller
     */
    function generateReferralCode() external {
        address sender = msg.sender;
        require(isStarted || isAuthorized[sender], "Not authorized");
        require(
            bytesReferralCodes[sender] == 0,
            "Referral code already generated"
        );

        bytes32 referralCode;
        string memory shortCode;

        do {
            salt++;
            referralCode = keccak256(abi.encodePacked(sender, salt));
            shortCode = _toShortCode(referralCode);
        } while (
            codeOwnersBytes[referralCode] != address(0) ||
                shortCodeOwners[shortCode] != address(0)
        );

        shortReferralCodes[sender] = shortCode;
        shortCodeOwners[shortCode] = sender;

        bytesReferralCodes[sender] = referralCode;
        codeOwnersBytes[referralCode] = sender;
    }

    /**
     * @dev uses a referral code to set the referrer of the caller
     * @param code the referral code to be used
     */
    function useReferralCode(string memory code) external {
        address sender = msg.sender;
        address _referrer = shortCodeOwners[code];
        require(_referrer != address(0), "Referral code does not exist");
        require(sender != _referrer, "Cannot use your own referral code");
        require(
            referrers[sender] == address(0),
            "Already used a referral code"
        );
        referrals[_referrer].referrals.push(sender);
        referrals[_referrer].timeOfReferrals.push(block.timestamp);
        referrers[sender] = _referrer;
    }

    //--------------------------------------------------//

    function _toShortCode(
        bytes32 hashCode
    ) private pure returns (string memory) {
        bytes memory alphabet = "0123456789abcdef";

        bytes memory str = new bytes(10);
        for (uint8 i = 0; i < 10; i++) {
            str[i] = alphabet[uint8(hashCode[i]) & 0x0f];
        }

        return string(str);
    }

    //--------------------------------------------------//

    function getUserFromCode(
        string memory code
    ) external view onlyStaking returns (address) {
        return shortCodeOwners[code];
    }

    function getReferrals(
        address user
    ) external view onlyStaking returns (address[] memory) {
        return referrals[user].referrals;
    }

    function getTimeOfReferrals(
        address user
    ) external view onlyStaking returns (uint256[] memory) {
        return referrals[user].timeOfReferrals;
    }

    /**
     * @dev gets the referral code of a user
     * @param user the user to get the referral code of
     */
    function getCodeFromUser(
        address user
    ) external view returns (string memory) {
        return shortReferralCodes[user];
    }

    /**
     * @dev gets the referrer of a user
     * @param user the user to get the referrer of
     */
    function getReferrer(address user) external view returns (address) {
        return referrers[user];
    }

    /**
     * @dev gets the amount of referrals a user has
     * @param user the user to get the amount of referrals of
     */
    function getAmountOfReferrals(
        address user
    ) external view returns (uint256) {
        return referrals[user].referrals.length;
    }

    /**
     * @dev returns either if a user has a referral code or not
     * @param user the user to check
     */
    function getHasAReferralCode(address user) external view returns (bool) {
        return bytesReferralCodes[user] != 0;
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):