@@ -5,58 +5,75 @@ import "forge-std/Script.sol";
55import "forge-std/console2.sol " ;
66import {Deployed} from "../../deploys/Deployed.s.sol " ;
77import {EtherFiRestaker} from "../../../src/EtherFiRestaker.sol " ;
8- // import {ILidoWithdrawalQueue} from "../../../src/interfaces/ILiquifier.sol";
8+ import {ILidoWithdrawalQueue} from "../../../src/interfaces/ILiquifier.sol " ;
99
10- interface ILidoWithdrawalQueue {
11- function getLastFinalizedRequestId () external view returns (uint256 );
12- function getLastCheckpointIndex () external view returns (uint256 );
13- function findCheckpointHints (uint256 [] calldata _requestIds , uint256 _firstIndex , uint256 _lastIndex ) external view returns (uint256 [] memory hintIds );
14- }
15-
16- // forge script script/operations/steth-claim-withdrawals/ClaimStEthWithdrawals.s.sol --fork-url $MAINNET_RPC_URL -vvvv
10+ // forge script script/operations/steth-management/ClaimStEthWithdrawals.s.sol --fork-url $MAINNET_RPC_URL -vvvv
1711
1812contract ClaimStEthWithdrawals is Script , Deployed {
1913
2014 EtherFiRestaker constant etherFiRestaker = EtherFiRestaker (payable (ETHERFI_RESTAKER));
2115
2216 function run () external {
23- uint256 startId = 113785 ; // Set this to the first request you want to claim
24- uint256 endId = 113863 ; // Set this to the last request you want to claim
25-
2617 ILidoWithdrawalQueue lidoWithdrawalQueue = ILidoWithdrawalQueue (address (etherFiRestaker.lidoWithdrawalQueue ()));
27- console2.log ("LidoWithdrawalQueue: " , address (lidoWithdrawalQueue));
18+ console2.log ("EtherFiRestaker: " , address (etherFiRestaker));
19+ console2.log ("LidoWithdrawalQueue: " , address (lidoWithdrawalQueue));
20+
21+ // 1. Fetch all withdrawal request IDs owned by the restaker
22+ uint256 [] memory allRequestIds = lidoWithdrawalQueue.getWithdrawalRequests (address (etherFiRestaker));
23+ console2.log ("Total pending requests for restaker: " , allRequestIds.length );
24+
25+ if (allRequestIds.length == 0 ) {
26+ console2.log ("No pending withdrawal requests found. Nothing to claim. " );
27+ return ;
28+ }
29+
30+ // 2. Get statuses for all requests
31+ ILidoWithdrawalQueue.WithdrawalRequestStatus[] memory statuses =
32+ lidoWithdrawalQueue.getWithdrawalStatus (allRequestIds);
2833
29- // Cap endId to the last finalized request
30- uint256 lastFinalizedId = ILidoWithdrawalQueue (address (lidoWithdrawalQueue)).getLastFinalizedRequestId ();
31- console2.log ("Last finalized request ID: " , lastFinalizedId);
34+ // 3. Filter to finalized & unclaimed requests
35+ uint256 claimableCount = 0 ;
36+ for (uint256 i = 0 ; i < statuses.length ; i++ ) {
37+ if (statuses[i].isFinalized && ! statuses[i].isClaimed) {
38+ claimableCount++ ;
39+ }
40+ }
41+
42+ console2.log ("Claimable (finalized & unclaimed): " , claimableCount);
43+
44+ if (claimableCount == 0 ) {
45+ console2.log ("No claimable requests at this time. Nothing to claim. " );
46+ return ;
47+ }
3248
33- if (endId > lastFinalizedId) {
34- console2.log ("WARNING: endId " , endId, "exceeds last finalized ID, capping to " , lastFinalizedId);
35- endId = lastFinalizedId;
49+ uint256 [] memory requestIds = new uint256 [](claimableCount);
50+ uint256 idx = 0 ;
51+ for (uint256 i = 0 ; i < allRequestIds.length ; i++ ) {
52+ if (statuses[i].isFinalized && ! statuses[i].isClaimed) {
53+ requestIds[idx] = allRequestIds[i];
54+ idx++ ;
55+ }
3656 }
37- require (startId <= endId, "No finalized requests in range " );
3857
39- uint256 count = endId - startId + 1 ;
40- console2.log ("Claiming " , count, "requests: " , startId);
41- console2.log (" to " , endId);
58+ _sortAscending (requestIds);
4259
43- uint256 [] memory requestIds = new uint256 [](count );
44- for (uint256 i = 0 ; i < count ; i++ ) {
45- requestIds[i] = startId + i ;
60+ console2. log ( " Claiming request IDs: " );
61+ for (uint256 i = 0 ; i < requestIds. length ; i++ ) {
62+ console2. log ( " " , requestIds[i]) ;
4663 }
4764
48- // Get checkpoint hints
49- uint256 lastCheckpointIndex = ILidoWithdrawalQueue ( address ( lidoWithdrawalQueue)) .getLastCheckpointIndex ();
65+ // 4. Get checkpoint hints for the claimable requests
66+ uint256 lastCheckpointIndex = lidoWithdrawalQueue.getLastCheckpointIndex ();
5067 console2.log ("Last checkpoint index: " , lastCheckpointIndex);
5168
52- uint256 [] memory hints = ILidoWithdrawalQueue ( address ( lidoWithdrawalQueue)) .findCheckpointHints (requestIds, 1 , lastCheckpointIndex);
69+ uint256 [] memory hints = lidoWithdrawalQueue.findCheckpointHints (requestIds, 1 , lastCheckpointIndex);
5370
54- console2.log ("Hints found for " , hints.length , "requests " );
71+ console2.log ("Hints found for " , hints.length , "requests: " );
5572 for (uint256 i = 0 ; i < hints.length ; i++ ) {
5673 console2.log (" requestId: " , requestIds[i], "hint: " , hints[i]);
5774 }
5875
59- // Encode the calldata
76+ // 5. Encode calldata for multisig / safe submission
6077 bytes memory callData = abi.encodeWithSelector (
6178 EtherFiRestaker.stEthClaimWithdrawals.selector ,
6279 requestIds,
@@ -68,16 +85,29 @@ contract ClaimStEthWithdrawals is Script, Deployed {
6885 console2.log ("Target: " , address (etherFiRestaker));
6986 console2.logBytes (callData);
7087
71- // Simulate the transaction on fork as operating admin
88+ // 6. Simulate on fork as operating admin
7289 console2.log ("" );
7390 console2.log ("=== Simulating on fork === " );
74- uint256 liquidityPoolbalanceBefore = LIQUIDITY_POOL.balance;
75- console2.log ("LiquidityPool balance before: " , uint256 (liquidityPoolbalanceBefore) / 1e18 );
91+ uint256 lpBalanceBefore = LIQUIDITY_POOL.balance;
92+ console2.log ("LiquidityPool balance before: " , lpBalanceBefore / 1e18 );
7693 vm.prank (ETHERFI_OPERATING_ADMIN);
7794 etherFiRestaker.stEthClaimWithdrawals (requestIds, hints);
78- uint256 liquidityPoolbalanceAfter = LIQUIDITY_POOL.balance;
79- console2.log ("LiquidityPool balance after: " , uint256 (liquidityPoolbalanceAfter) / 1e18 );
80- console2.log ("ETH claimed: " , (liquidityPoolbalanceAfter - liquidityPoolbalanceBefore ) / 1e18 );
95+ uint256 lpBalanceAfter = LIQUIDITY_POOL.balance;
96+ console2.log ("LiquidityPool balance after: " , lpBalanceAfter / 1e18 );
97+ console2.log ("ETH claimed: " , (lpBalanceAfter - lpBalanceBefore ) / 1e18 );
8198 console2.log ("Simulation successful " );
8299 }
100+
101+ function _sortAscending (uint256 [] memory arr ) internal pure {
102+ uint256 length = arr.length ;
103+ for (uint256 i = 1 ; i < length; i++ ) {
104+ uint256 key = arr[i];
105+ uint256 j = i;
106+ while (j > 0 && arr[j - 1 ] > key) {
107+ arr[j] = arr[j - 1 ];
108+ j-- ;
109+ }
110+ arr[j] = key;
111+ }
112+ }
83113}
0 commit comments