@@ -57,11 +57,11 @@ contract LayerEdgeStaking is
5757 event TierChanged (address indexed user , Tier to );
5858 event APYUpdated (Tier indexed tier , uint256 rate , uint256 timestamp );
5959 event RewardsDeposited (address indexed sender , uint256 amount );
60+ event UnstakedQueued (address indexed user , uint256 index , uint256 amount );
6061
6162 // User information
6263 struct UserInfo {
6364 uint256 balance; // Current staked balance
64- uint256 depositTime; // When user first deposited
6565 uint256 lastClaimTime; // Last time user claimed or updated interest
6666 uint256 interestEarned; // Unclaimed interest earned
6767 uint256 totalClaimed; // Total interest claimed
@@ -85,11 +85,19 @@ contract LayerEdgeStaking is
8585 uint256 timestamp;
8686 }
8787
88+ // Add a struct for unstake requests
89+ struct UnstakeRequest {
90+ uint256 amount;
91+ uint256 timestamp;
92+ bool completed;
93+ }
94+
8895 // Storage
8996 mapping (Tier => APYPeriod[]) public tierAPYHistory; // tier => APY periods
9097 mapping (address => UserInfo) public users;
9198 mapping (uint256 => address ) public stakerAddress;
9299 mapping (address => TierEvent[]) public stakerTierHistory;
100+ mapping (address => UnstakeRequest[]) public unstakeRequests;
93101 uint256 public stakerCountInTree;
94102 uint256 public stakerCountOutOfTree;
95103 uint256 public totalStaked;
@@ -166,15 +174,23 @@ contract LayerEdgeStaking is
166174 * @param amount Amount to unstake
167175 */
168176 function unstake (uint256 amount ) external nonReentrant whenNotPaused {
169- _unstake (amount, msg .sender , false );
177+ _unstake (amount, msg .sender );
170178 }
171179
172180 /**
173- * @notice Unstake native tokens
174- * @param amount Amount to unstake
181+ * @notice Complete a specific unstake request
182+ * @param index Index of the unstake request to complete
183+ */
184+ function completeUnstake (uint256 index ) external nonReentrant whenNotPaused {
185+ _completeUnstake (msg .sender , index, false );
186+ }
187+
188+ /**
189+ * @notice Complete a specific unstake request with native token
190+ * @param index Index of the unstake request to complete
175191 */
176- function unstakeNative (uint256 amount ) external nonReentrant whenNotPaused {
177- _unstake (amount, msg .sender , true );
192+ function completeUnstakeNative (uint256 index ) external nonReentrant whenNotPaused {
193+ _completeUnstake ( msg .sender , index , true );
178194 }
179195
180196 /**
@@ -498,23 +514,16 @@ contract LayerEdgeStaking is
498514 * @return balance Current staked balance
499515 * @return tier Current tier
500516 * @return apy Current APY rate
501- * @return depositTime Initial deposit time
502517 * @return pendingRewards Unclaimed rewards
503518 */
504519 function getUserInfo (address userAddr )
505520 external
506521 view
507- returns (uint256 balance , Tier tier , uint256 apy , uint256 depositTime , uint256 pendingRewards )
522+ returns (uint256 balance , Tier tier , uint256 apy , uint256 pendingRewards )
508523 {
509524 UserInfo memory user = users[userAddr];
510525
511- return (
512- user.balance,
513- getCurrentTier (userAddr),
514- getUserAPY (userAddr),
515- user.depositTime,
516- calculateUnclaimedInterest (userAddr)
517- );
526+ return (user.balance, getCurrentTier (userAddr), getUserAPY (userAddr), calculateUnclaimedInterest (userAddr));
518527 }
519528
520529 /**
@@ -621,19 +630,11 @@ contract LayerEdgeStaking is
621630 function getAllInfoOfUser (address userAddr )
622631 external
623632 view
624- returns (
625- UserInfo memory user ,
626- Tier tier ,
627- uint256 apy ,
628- uint256 depositTime ,
629- uint256 pendingRewards ,
630- TierEvent[] memory tierHistory
631- )
633+ returns (UserInfo memory user , Tier tier , uint256 apy , uint256 pendingRewards , TierEvent[] memory tierHistory )
632634 {
633635 user = users[userAddr];
634636 tier = getCurrentTier (userAddr);
635637 apy = getUserAPY (userAddr);
636- depositTime = user.depositTime;
637638 pendingRewards = calculateUnclaimedInterest (userAddr);
638639 tierHistory = stakerTierHistory[userAddr];
639640 }
@@ -713,7 +714,6 @@ contract LayerEdgeStaking is
713714
714715 // Update user balances
715716 user.balance += amount;
716- user.depositTime = block .timestamp ;
717717 user.lastClaimTime = block .timestamp ;
718718
719719 // Update total staked
@@ -722,13 +722,11 @@ contract LayerEdgeStaking is
722722 emit Staked (userAddr, amount, tier);
723723 }
724724
725- function _unstake (uint256 amount , address userAddr , bool isNative ) internal {
725+ function _unstake (uint256 amount , address userAddr ) internal {
726726 UserInfo storage user = users[userAddr];
727727
728728 // require(user.isActive, "No active stake");
729729 require (user.balance >= amount, "Insufficient balance " );
730- require (block .timestamp >= user.depositTime + UNSTAKE_WINDOW, "Unstaking window not reached " );
731-
732730 // Update interest before changing balance
733731 _updateInterest (userAddr);
734732
@@ -750,16 +748,32 @@ contract LayerEdgeStaking is
750748 _checkBoundariesAndRecord (true );
751749 }
752750
753- // Transfer tokens from contract to user
751+ // Add unstake request instead of immediate transfer
752+ unstakeRequests[userAddr].push (UnstakeRequest ({amount: amount, timestamp: block .timestamp , completed: false }));
753+
754+ emit UnstakedQueued (userAddr, unstakeRequests[userAddr].length - 1 , amount);
755+ }
756+
757+ function _completeUnstake (address userAddr , uint256 index , bool isNative ) internal {
758+ UnstakeRequest[] storage requests = unstakeRequests[userAddr];
759+ require (index < requests.length , "Invalid unstake request index " );
760+
761+ UnstakeRequest storage request = requests[index];
762+ require (! request.completed, "Unstake request already completed " );
763+ require (block .timestamp >= request.timestamp + UNSTAKE_WINDOW, "Unstaking window not reached " );
764+
765+ request.completed = true ;
766+
767+ // Transfer tokens back to user
754768 if (! isNative) {
755- require (stakingToken.transfer (userAddr, amount), "Token transfer failed " );
769+ require (stakingToken.transfer (userAddr, request. amount), "Token transfer failed " );
756770 } else {
757- IWETH (address (stakingToken)).withdraw (amount);
758- (bool success ,) = payable (userAddr).call {value: amount}("" );
771+ IWETH (address (stakingToken)).withdraw (request. amount);
772+ (bool success ,) = payable (userAddr).call {value: request. amount}("" );
759773 require (success, "Unstake native transfer failed " );
760774 }
761775
762- emit Unstaked (userAddr, amount);
776+ emit Unstaked (userAddr, request. amount);
763777 }
764778
765779 function _claimInterest (address userAddr , bool isNative ) internal {
0 commit comments