Sonic Blaze Testnet

Contract Diff Checker

Contract Name:
SonicMiner

Contract Source Code:

File 1 of 1 : SonicMiner

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

contract SonicMiner {
    address public owner;
    address payable public marketingWallet;
    address payable public devWallet;
    address payable public devRewardWallet;
    uint256 public totalInvested;
    uint256 public totalWithdrawn;
    uint256 public totalDeposits;
    uint256 public totalReferralRewards;
    uint256 public totalDevReferralReinvested;

    uint256 public constant BASE_DAILY_PERCENT = 50; // 5.0% daily (50 / 1000)
    uint256 public constant BOOST_INCREMENT = 1; // 0.1% per day (1 / 1000)
    uint256 public constant MAX_BOOST_DAYS = 10;
    uint256 public constant REFERRAL_PERCENT = 80; // 8% referral reward
    uint256 public constant DEV_FEE = 30; // 3% dev fee
    uint256 public constant DEV_REFERRAL_BOOST = 170; // 17% boost if dev referral is used on Day 1
    uint256 public constant USER_REFERRAL_BOOST = 133; // 13.3% boost if normal user referral is used on Day 1
    uint256 public constant NORMAL_USER_BOOST = 50; // 5% base boost for normal investors
    uint256 public constant DEV_REFERRAL_REINVEST = 20; // 2% of dev referral reinvested into contract
    uint256 public constant DEV_TVL_REINVEST = 50; // 5% of dev referral goes back into TVL
    uint256 public constant DEV_DIRECT_REWARD = 50; // 5% of dev referral stays in dev reward wallet
    uint256[10] public TAX_SCHEDULE = [90, 80, 70, 60, 50, 40, 20, 15, 10, 5];

    struct User {
        uint256 invested;
        uint256 withdrawn;
        uint256 lastActionTime;
        uint256 boostDays;
        uint256 depositTime;
        address referrer;
        uint256 referralRewards;
        bool devReferralUsed;
        bool userReferralUsed;
    }

    mapping(address => User) public users;
    mapping(address => address[]) public referredUsers;

    modifier onlyOwner() {
        require(msg.sender == owner, "Not authorized");
        _;
    }

    event Deposit(address indexed user, uint256 amount);
    event Withdraw(address indexed user, uint256 amount, uint256 tax);
    event ReferralReward(
        address indexed referrer,
        address indexed user,
        uint256 amount
    );
    event Debug(string message);

    function getTaxSchedule(uint256 index) public view returns (uint256) {
        require(index < TAX_SCHEDULE.length, "Index out of bounds");
        return TAX_SCHEDULE[index];
    }

    function updateTaxSchedule(uint256[10] memory newTaxSchedule)
        external
        onlyOwner
    {
        TAX_SCHEDULE = newTaxSchedule;
    }

    function getReferralRewards(address user) public view returns (uint256) {
        return users[user].referralRewards;
    }

    function getReferredUsers(address user)
        public
        view
        returns (address[] memory)
    {
        return referredUsers[user];
    }

    function updateWallets(
        address payable _marketingWallet,
        address payable _devWallet,
        address payable _devRewardWallet
    ) external onlyOwner {
        marketingWallet = _marketingWallet;
        devWallet = _devWallet;
        devRewardWallet = _devRewardWallet;
    }

    function withdraw(uint256 amount) external {
        User storage user = users[msg.sender];
        require(
            block.timestamp >= user.depositTime + 1 minutes,
            "Withdrawals are restricted in the first 24 hours"
        );
        require(
            amount <= user.invested * 3,
            "Max single withdrawal limit exceeded"
        );
        require(
            block.timestamp - user.lastActionTime >= 1 minutes,
            "Can only withdraw once per day"
        );

        uint256 index = user.boostDays >= TAX_SCHEDULE.length
            ? TAX_SCHEDULE.length - 1
            : user.boostDays;
        uint256 taxRate = TAX_SCHEDULE[index];
        uint256 taxAmount = (amount * taxRate) / 100;
        uint256 netAmount = amount - taxAmount;

        user.withdrawn += amount;
        user.boostDays = 0;

        (bool success, ) = payable(msg.sender).call{value: netAmount}("");
        require(success, "Transfer failed");
        user.lastActionTime = block.timestamp;

        emit Withdraw(msg.sender, amount, taxAmount);
    }

    function compound() external {
        User storage user = users[msg.sender];
        require(user.invested > 0, "No investment found");
        require(
            block.timestamp - user.lastActionTime >= 1 minutes,
            "Can only compound once per minute"
        );

        // Get available rewards using the same time-based calculation
        uint256 earnings = getAvailableRewards(msg.sender);

        user.invested += earnings;
        user.boostDays = user.boostDays < MAX_BOOST_DAYS
            ? user.boostDays + 1
            : MAX_BOOST_DAYS;
        user.lastActionTime = block.timestamp;

        emit Deposit(msg.sender, earnings);
    }

    function deposit(address referrer) external payable {
        require(msg.value > 0, "Must send Sonic");

        uint256 devFee = (msg.value * DEV_FEE) / 1000;
        uint256 depositAmount = msg.value - devFee;

        (bool devSuccess, ) = devWallet.call{value: devFee}("");
        if (!devSuccess) {
            emit Debug("Dev fee transfer failed");
        }

        User storage user = users[msg.sender];
        user.invested += depositAmount;
        user.lastActionTime = block.timestamp;
        user.depositTime = block.timestamp;

        if (
            referrer != address(0) &&
            referrer != msg.sender &&
            users[referrer].invested > 0
        ) {
            uint256 referralReward = (msg.value * REFERRAL_PERCENT) / 1000;
            (bool refSuccess, ) = payable(referrer).call{value: referralReward}(
                ""
            );
            if (!refSuccess) {
                emit Debug("Referral reward transfer failed");
            }
            users[referrer].referralRewards += referralReward;
            totalReferralRewards += referralReward;
            referredUsers[referrer].push(msg.sender);
        }

        totalInvested += depositAmount;
        totalDeposits++;

        emit Deposit(msg.sender, depositAmount);
    }

    /**
     * @dev Calculates available rewards for a user based on their current investment and boost
     * @param userAddress Address of the user to check
     * @return Amount of rewards currently available
     */
    function getAvailableRewards(address userAddress)
        public
        view
        returns (uint256)
    {
        User storage user = users[userAddress];
        if (user.invested == 0) {
            return 0;
        }

        // Calculate time elapsed since last action (in seconds)
        uint256 timeElapsed = block.timestamp - user.lastActionTime;

        // Calculate daily percent with boost
        uint256 dailyPercent = BASE_DAILY_PERCENT +
            (user.boostDays * BOOST_INCREMENT);

        // Convert daily rate to time-proportional rate
        // 86400 seconds in a day
        uint256 earnings = (user.invested * dailyPercent * timeElapsed) /
            (86400 * 1000);

        return earnings;
    }

    /**
     * @dev Returns the current tax rate for a user based on their boost days
     * @param userAddress Address of the user to check
     * @return Current tax rate percentage
     */
    function getCurrentTaxRate(address userAddress)
        public
        view
        returns (uint256)
    {
        User storage user = users[userAddress];
        uint256 index = user.boostDays >= TAX_SCHEDULE.length
            ? TAX_SCHEDULE.length - 1
            : user.boostDays;
        return TAX_SCHEDULE[index];
    }

    function getUserInfo(address userAddress)
        public
        view
        returns (
            uint256 invested,
            uint256 withdrawn,
            uint256 availableRewards,
            uint256 boostDays,
            uint256 currentDailyRate,
            uint256 currentTaxRate,
            uint256 referralRewards,
            uint256 lastActionTime,
            uint256 depositTime
        )
    {
        User storage user = users[userAddress];

        // Calculate daily percent with boost
        uint256 dailyPercent = BASE_DAILY_PERCENT +
            (user.boostDays * BOOST_INCREMENT);

        // Calculate time-based rewards
        uint256 timeElapsed = block.timestamp - user.lastActionTime;
        uint256 earnings = 0;

        if (user.invested > 0) {
            // Convert daily rate to time-proportional rate (86400 seconds in a day)
            earnings =
                (user.invested * dailyPercent * timeElapsed) /
                (86400 * 1000);
        }

        // Get current tax rate
        uint256 index = user.boostDays >= TAX_SCHEDULE.length
            ? TAX_SCHEDULE.length - 1
            : user.boostDays;
        uint256 taxRate = TAX_SCHEDULE[index];

        return (
            user.invested,
            user.withdrawn,
            earnings,
            user.boostDays,
            dailyPercent,
            taxRate,
            user.referralRewards,
            user.lastActionTime,
            user.depositTime
        );
    }

    constructor() {
        owner = msg.sender;
        marketingWallet = payable(0x2c5896b947882Bf265A43996bB735b247C6DA0ce);
        devWallet = payable(0xc31354e0178D3B7abaa992C6aCD6929B657E6bC5);
        devRewardWallet = payable(0xeB79bF0ed0eC013A45BfD3Ed2B44e81349b7e2a9);
    }
}

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

Context size (optional):