S Price: $0.440033 (-13.48%)

Contract Diff Checker

Contract Name:
UserStakeDetails

Contract Source Code:

File 1 of 1 : UserStakeDetails

/**
 *Submitted for verification at BscScan.com on 2025-01-17
*/

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

interface IPacaFinance {
    struct Stake {
        uint256 amount;
        uint256 lastClaimed;
        uint256 dailyRewardRate;
        uint256 unlockTime;
        bool complete;
    }

    function stakes(address user, uint256 index) external view returns (Stake memory);
}

contract UserStakeDetails {
    IPacaFinance public pacaFinanceContract;

    constructor(address _pacaFinanceAddress) {
        pacaFinanceContract = IPacaFinance(_pacaFinanceAddress);
    }

    /**
     * @dev Returns all stakes of a user as sorted by a chosen field.
     * @param user The address of the user to check.
     * @param sortBy 0 = amount, 1 = remaining days.
     * @return stakeIds Sorted array of stake IDs.
     * @return amounts Sorted array of stake amounts.
     * @return dailyRewardRates Sorted array of daily reward rates.
     * @return remainingDays Sorted array of remaining unlock times in days.
     * @return completions Sorted array of stake completion statuses.
     */
    function getSortedStakeDetails(address user, uint8 sortBy)
        external
        view
        returns (
            uint256[] memory stakeIds,
            uint256[] memory amounts,
            uint256[] memory dailyRewardRates,
            uint256[] memory remainingDays,
            bool[] memory completions
        )
    {
        // Get all stakes first
        (
            uint256[] memory tempStakeIds,
            uint256[] memory tempAmounts,
            uint256[] memory tempDailyRates,
            uint256[] memory tempRemainingDays,
            bool[] memory tempCompletions
        ) = getAllStakeDetails(user);

        uint256 stakeCount = tempStakeIds.length;

        // Perform bubble sort based on the chosen criterion in descending order
        for (uint256 i = 0; i < stakeCount; i++) {
            for (uint256 j = 0; j < stakeCount - 1; j++) {
                bool shouldSwap = false;

                if (sortBy == 0 && tempAmounts[j] < tempAmounts[j + 1]) {
                    // Sort by amount (descending)
                    shouldSwap = true;
                } else if (sortBy == 1 && tempRemainingDays[j] < tempRemainingDays[j + 1]) {
                    // Sort by remaining days (descending)
                    shouldSwap = true;
                }

                if (shouldSwap) {
                    // Swap all relevant fields
                    (tempStakeIds[j], tempStakeIds[j + 1]) = (tempStakeIds[j + 1], tempStakeIds[j]);
                    (tempAmounts[j], tempAmounts[j + 1]) = (tempAmounts[j + 1], tempAmounts[j]);
                    (tempDailyRates[j], tempDailyRates[j + 1]) = (tempDailyRates[j + 1], tempDailyRates[j]);
                    (tempRemainingDays[j], tempRemainingDays[j + 1]) = (tempRemainingDays[j + 1], tempRemainingDays[j]);
                    (tempCompletions[j], tempCompletions[j + 1]) = (tempCompletions[j + 1], tempCompletions[j]);
                }
            }
        }

        // Return sorted arrays
        return (tempStakeIds, tempAmounts, tempDailyRates, tempRemainingDays, tempCompletions);
    }

    /**
     * @dev Returns all stakes of a user as a single array split into individual arrays for each field.
     * Adds stake IDs, converts unlock time to remaining days.
     * Loops dynamically until an invalid (zeroed) stake is found.
     * @param user The address of the user to check.
     * @return stakeIds An array containing all stake IDs.
     * @return amounts An array containing all stake amounts.
     * @return dailyRewardRates An array containing all daily reward rates.
     * @return remainingDays An array containing all remaining unlock times in days.
     * @return completions An array containing all stake completion statuses.
     */
    function getAllStakeDetails(address user)
        public
        view
        returns (
            uint256[] memory stakeIds,
            uint256[] memory amounts,
            uint256[] memory dailyRewardRates,
            uint256[] memory remainingDays,
            bool[] memory completions
        )
    {
        uint256 maxIterations = 750; // Prevent infinite loops
        uint256 index = 0;
        uint256 currentTime = block.timestamp;

        // Temporary storage arrays to collect stake details
        uint256[] memory tempStakeIds = new uint256[](maxIterations);
        uint256[] memory tempAmounts = new uint256[](maxIterations);
        uint256[] memory tempDailyRates = new uint256[](maxIterations);
        uint256[] memory tempRemainingDays = new uint256[](maxIterations);
        bool[] memory tempCompletions = new bool[](maxIterations);

        while (index < maxIterations) {
            try pacaFinanceContract.stakes(user, index) returns (IPacaFinance.Stake memory stake) {
                if (stake.amount == 0 && stake.unlockTime == 0) {
                    break; // Exit when invalid stake is reached
                }
                tempStakeIds[index] = index; // Add stake ID
                tempAmounts[index] = stake.amount;
                tempDailyRates[index] = stake.dailyRewardRate;
                if (stake.unlockTime > currentTime) {
                    tempRemainingDays[index] = (stake.unlockTime - currentTime) / 1 days;
                } else {
                    tempRemainingDays[index] = 0; // Unlock time passed
                }
                tempCompletions[index] = stake.complete;
            } catch {
                break; // Exit safely on error
            }
            index++;
        }

        // Final arrays sized correctly
        stakeIds = new uint256[](index);
        amounts = new uint256[](index);
        dailyRewardRates = new uint256[](index);
        remainingDays = new uint256[](index);
        completions = new bool[](index);

        for (uint256 i = 0; i < index; i++) {
            stakeIds[i] = tempStakeIds[i];
            amounts[i] = tempAmounts[i];
            dailyRewardRates[i] = tempDailyRates[i];
            remainingDays[i] = tempRemainingDays[i];
            completions[i] = tempCompletions[i];
        }

        return (stakeIds, amounts, dailyRewardRates, remainingDays, completions);
    }
}

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

Context size (optional):