Update to consolidate withdrawStakes and search marketplacehistory

This commit is contained in:
2025-09-12 15:51:48 +02:00
parent 8a802718d3
commit 34091848be

View File

@@ -35,12 +35,6 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
uint256 percentage; uint256 percentage;
} }
struct WithdrawVesting {
uint256 vestingId;
uint256 amount;
uint256 unlockTime;
address token;
}
// Epoch-based staking structures // Epoch-based staking structures
struct Epoch { struct Epoch {
@@ -55,6 +49,7 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
uint256 stakeId; uint256 stakeId;
uint256 amount; uint256 amount;
uint256 unlockTime; uint256 unlockTime;
address token;
} }
struct SellStake { struct SellStake {
@@ -94,9 +89,8 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
// BSC USDT token address for stake rewards and marketplace payments // BSC USDT token address for stake rewards and marketplace payments
address private constant BSC_TOKEN = 0x55d398326f99059fF775485246999027B3197955; address private constant BSC_TOKEN = 0x55d398326f99059fF775485246999027B3197955;
mapping(address => WithdrawVesting[]) private withdrawVestingActual;
uint256 private withdrawVestingCounterActual;
uint256 private stakeIdCounter; uint256 private stakeIdCounter;
uint256 private vestingStakeIdCounter;
// Track total withdraw vesting liabilities by token address // Track total withdraw vesting liabilities by token address
mapping(address => uint256) public withdrawVestingLiabilities; mapping(address => uint256) public withdrawVestingLiabilities;
@@ -118,6 +112,7 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
SellStakeKey[] public sellStakeKeys; // Array for iteration over active sell stakes SellStakeKey[] public sellStakeKeys; // Array for iteration over active sell stakes
mapping(address => mapping(uint256 => uint256)) private sellStakeKeyIndex; // Track position in keys array mapping(address => mapping(uint256 => uint256)) private sellStakeKeyIndex; // Track position in keys array
MarketplaceHistory[] public marketplaceHistory; // Complete history of all transactions MarketplaceHistory[] public marketplaceHistory; // Complete history of all transactions
mapping(address => uint256) public totalClaimed; // Track total amount claimed and sent to withdrawStakes per user
// Events // Events
event VestingCreated(address indexed user, uint256 amount, uint256 bonus); event VestingCreated(address indexed user, uint256 amount, uint256 bonus);
@@ -415,11 +410,15 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
// Reset their last claimed epoch to current // Reset their last claimed epoch to current
userLastClaimedEpoch[msg.sender] = currentEpochId; userLastClaimedEpoch[msg.sender] = currentEpochId;
// Track total claimed amount
totalClaimed[msg.sender] += unclaimedAmount;
// Create withdrawable stake with unlock delay // Create withdrawable stake with unlock delay
withdrawStakes[msg.sender].push(WithdrawStake({ withdrawStakes[msg.sender].push(WithdrawStake({
stakeId: block.timestamp, // Using timestamp as unique ID stakeId: stakeIdCounter,
amount: unclaimedAmount, amount: unclaimedAmount,
unlockTime: block.timestamp + unlockDelay unlockTime: block.timestamp + unlockDelay,
token: BSC_TOKEN
})); }));
emit FundsClaimed(msg.sender, unclaimedAmount); emit FundsClaimed(msg.sender, unclaimedAmount);
@@ -436,10 +435,16 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
require(block.timestamp >= stake.unlockTime, "Stake locked"); require(block.timestamp >= stake.unlockTime, "Stake locked");
uint256 amount = stake.amount; uint256 amount = stake.amount;
address token = stake.token;
stake.amount = 0; // Mark as withdrawn stake.amount = 0; // Mark as withdrawn
// Transfer BSC USDT tokens to user // Decrement withdraw vesting liabilities for non-BSC tokens
IERC20(BSC_TOKEN).safeTransfer(msg.sender, amount); if (token != BSC_TOKEN) {
withdrawVestingLiabilities[token] -= amount;
}
// Transfer tokens to user based on the specified token
IERC20(token).safeTransfer(msg.sender, amount);
emit StakeWithdrawn(msg.sender, amount, stakeId); emit StakeWithdrawn(msg.sender, amount, stakeId);
return; return;
@@ -465,12 +470,16 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
userBigStake[msg.sender] -= amount; userBigStake[msg.sender] -= amount;
totalBigStakes -= amount; totalBigStakes -= amount;
// Track total claimed amount
totalClaimed[msg.sender] += payoutAmount;
// Create withdrawable stake with unlock delay (like claimUnlockedFunds) // Create withdrawable stake with unlock delay (like claimUnlockedFunds)
stakeIdCounter++; stakeIdCounter++;
withdrawStakes[msg.sender].push(WithdrawStake({ withdrawStakes[msg.sender].push(WithdrawStake({
stakeId: stakeIdCounter, stakeId: stakeIdCounter,
amount: payoutAmount, amount: payoutAmount,
unlockTime: block.timestamp + unlockDelay unlockTime: block.timestamp + unlockDelay,
token: BSC_TOKEN
})); }));
emit FundsClaimed(msg.sender, payoutAmount); emit FundsClaimed(msg.sender, payoutAmount);
@@ -1008,9 +1017,9 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
} }
vestedTotal[vesting.token] -= amountToClaim; vestedTotal[vesting.token] -= amountToClaim;
// Add vesting claims to cooldown queue // Add vesting claims to unified withdrawal queue
withdrawVestingActual[msg.sender].push(WithdrawVesting({ withdrawStakes[msg.sender].push(WithdrawStake({
vestingId: withdrawVestingCounterActual++, stakeId: vestingStakeIdCounter++,
amount: amountToClaim, amount: amountToClaim,
unlockTime: block.timestamp + unlockDelay, unlockTime: block.timestamp + unlockDelay,
token: vesting.token token: vesting.token
@@ -1056,9 +1065,9 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
} }
vestedTotal[_token] -= totalReward; vestedTotal[_token] -= totalReward;
// Add vesting claims to cooldown queue // Add vesting claims to unified withdrawal queue
withdrawVestingActual[msg.sender].push(WithdrawVesting({ withdrawStakes[msg.sender].push(WithdrawStake({
vestingId: withdrawVestingCounterActual++, stakeId: vestingStakeIdCounter++,
amount: totalReward, amount: totalReward,
unlockTime: block.timestamp + unlockDelay, unlockTime: block.timestamp + unlockDelay,
token: _token token: _token
@@ -1084,58 +1093,20 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
vesting.claimedBonus += bonusToClaim; vesting.claimedBonus += bonusToClaim;
// Track total claimed amount
totalClaimed[msg.sender] += bonusToClaim;
// Create withdrawable stake with unlock delay (add 1e6 to distinguish from normal stakes) // Create withdrawable stake with unlock delay (add 1e6 to distinguish from normal stakes)
withdrawStakes[msg.sender].push(WithdrawStake({ withdrawStakes[msg.sender].push(WithdrawStake({
stakeId: _vestingIndex + 1e6, stakeId: _vestingIndex + 1e6,
amount: bonusToClaim, amount: bonusToClaim,
unlockTime: block.timestamp + unlockDelay unlockTime: block.timestamp + unlockDelay,
token: BSC_TOKEN
})); }));
emit BonusClaimed(msg.sender, bonusToClaim); emit BonusClaimed(msg.sender, bonusToClaim);
} }
/// @notice Function that returns an array of all the user's withdrawVestings.
/// @param user The address to evaluate.
/// @return An array of WithdrawVesting for the given user.
function getAllWithdrawVestings(address user) external view returns (WithdrawVesting[] memory) {
return withdrawVestingActual[user];
}
/// @notice Returns the current withdraw vesting counter value
/// @return Current counter value for tracking unique withdrawal IDs
function getWithdrawVestingCounter() external view returns (uint256) {
return withdrawVestingCounterActual;
}
/// @notice Withdraws vesting tokens after cooldown period
/// @param _vestingId The vesting ID to withdraw
function withdrawVestingToken(uint256 _vestingId) external nonReentrant {
WithdrawVesting[] storage userVestings = withdrawVestingActual[msg.sender];
require(userVestings.length > 0, "No vestings available");
for (uint256 i = 0; i < userVestings.length; i++) {
WithdrawVesting storage vestingWithdraw = userVestings[i];
if (vestingWithdraw.vestingId == _vestingId && vestingWithdraw.amount > 0) {
require(block.timestamp >= vestingWithdraw.unlockTime, "Vesting locked");
uint256 amount = vestingWithdraw.amount;
address token = vestingWithdraw.token;
// Mark as withdrawn
vestingWithdraw.amount = 0;
// Decrement withdraw vesting liabilities for this token
withdrawVestingLiabilities[token] -= amount;
// Transfer tokens
IERC20(token).safeTransfer(msg.sender, amount);
emit StakeWithdrawn(msg.sender, amount, _vestingId);
return;
}
}
revert("Vesting not found");
}
// Marketplace View Functions // Marketplace View Functions
@@ -1206,6 +1177,47 @@ contract CunaFinanceBsc is Initializable, ReentrancyGuardUpgradeable {
return marketplace_sales[user]; return marketplace_sales[user];
} }
/// @notice Get user's total claimed amount sent to withdrawStakes
/// @param user The user address
/// @return Total amount claimed and sent to withdrawStakes for the user
function getUserTotalClaimed(address user) external view returns (uint256) {
return totalClaimed[user];
}
/// @notice Search marketplace history for stakes where address was seller or buyer
/// @param targetAddress The address to search for as seller or buyer
/// @return Array of MarketplaceHistory structs where address was involved
function searchMarketplaceHistory(address targetAddress) external view returns (MarketplaceHistory[] memory) {
require(targetAddress != address(0), "Invalid address");
// Count matches first to size the result array properly
uint256 matchCount = 0;
for (uint256 i = 0; i < marketplaceHistory.length; i++) {
if (marketplaceHistory[i].seller == targetAddress || marketplaceHistory[i].buyer == targetAddress) {
matchCount++;
}
}
// Return empty array if no matches
if (matchCount == 0) {
return new MarketplaceHistory[](0);
}
// Create result array with exact size needed
MarketplaceHistory[] memory result = new MarketplaceHistory[](matchCount);
uint256 resultIndex = 0;
// Populate result array
for (uint256 i = 0; i < marketplaceHistory.length; i++) {
if (marketplaceHistory[i].seller == targetAddress || marketplaceHistory[i].buyer == targetAddress) {
result[resultIndex] = marketplaceHistory[i];
resultIndex++;
}
}
return result;
}
/// @notice Test function for upgrade verification /// @notice Test function for upgrade verification
/// @return Returns a constant value to verify upgrade worked /// @return Returns a constant value to verify upgrade worked
function testUpgradeFunction() external pure returns (uint256) { function testUpgradeFunction() external pure returns (uint256) {