@@ -741,6 +741,7 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
741741 prov.tokensThawing = prov.tokensThawing + _tokens;
742742
743743 bytes32 thawRequestId = _createThawRequest (
744+ ThawRequestType.Provision,
744745 _serviceProvider,
745746 _verifier,
746747 _serviceProvider,
@@ -765,15 +766,18 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
765766 uint256 tokensThawed_ = 0 ;
766767 uint256 sharesThawing = prov.sharesThawing;
767768 uint256 tokensThawing = prov.tokensThawing;
768- (tokensThawed_, tokensThawing, sharesThawing) = _fulfillThawRequests (
769- _serviceProvider,
770- _verifier,
771- _serviceProvider,
772- tokensThawing,
773- sharesThawing,
774- _nThawRequests,
775- prov.thawingNonce
776- );
769+
770+ FulfillThawRequestsParams memory params = FulfillThawRequestsParams ({
771+ requestType: ThawRequestType.Provision,
772+ serviceProvider: _serviceProvider,
773+ verifier: _verifier,
774+ owner: _serviceProvider,
775+ tokensThawing: tokensThawing,
776+ sharesThawing: sharesThawing,
777+ nThawRequests: _nThawRequests,
778+ thawingNonce: prov.thawingNonce
779+ });
780+ (tokensThawed_, tokensThawing, sharesThawing) = _fulfillThawRequests (params);
777781
778782 prov.tokens = prov.tokens - tokensThawed_;
779783 prov.sharesThawing = sharesThawing;
@@ -860,6 +864,7 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
860864 delegation.shares = delegation.shares - _shares;
861865
862866 bytes32 thawRequestId = _createThawRequest (
867+ ThawRequestType.Delegation,
863868 _serviceProvider,
864869 _verifier,
865870 _beneficiary,
@@ -894,15 +899,18 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
894899 uint256 tokensThawed = 0 ;
895900 uint256 sharesThawing = pool.sharesThawing;
896901 uint256 tokensThawing = pool.tokensThawing;
897- (tokensThawed, tokensThawing, sharesThawing) = _fulfillThawRequests (
898- _serviceProvider,
899- _verifier,
900- msg .sender ,
901- tokensThawing,
902- sharesThawing,
903- _nThawRequests,
904- pool.thawingNonce
905- );
902+
903+ FulfillThawRequestsParams memory params = FulfillThawRequestsParams ({
904+ requestType: ThawRequestType.Delegation,
905+ serviceProvider: _serviceProvider,
906+ verifier: _verifier,
907+ owner: msg .sender ,
908+ tokensThawing: tokensThawing,
909+ sharesThawing: sharesThawing,
910+ nThawRequests: _nThawRequests,
911+ thawingNonce: pool.thawingNonce
912+ });
913+ (tokensThawed, tokensThawing, sharesThawing) = _fulfillThawRequests (params);
906914
907915 // The next subtraction should never revert becase: pool.tokens >= pool.tokensThawing and pool.tokensThawing >= tokensThawed
908916 // In the event the pool gets completely slashed tokensThawed will fulfil to 0.
@@ -936,69 +944,103 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
936944 * @return The ID of the thaw request
937945 */
938946 function _createThawRequest (
947+ ThawRequestType _requestType ,
939948 address _serviceProvider ,
940949 address _verifier ,
941950 address _owner ,
942951 uint256 _shares ,
943952 uint64 _thawingUntil ,
944953 uint256 _thawingNonce
945954 ) private returns (bytes32 ) {
946- LinkedList.List storage thawRequestList = _thawRequestLists[_serviceProvider][_verifier][_owner];
955+ LinkedList.List storage thawRequestList = _getThawRequestList (
956+ _requestType,
957+ _serviceProvider,
958+ _verifier,
959+ _owner
960+ );
947961 require (thawRequestList.count < MAX_THAW_REQUESTS, HorizonStakingTooManyThawRequests ());
948962
949963 bytes32 thawRequestId = keccak256 (abi.encodePacked (_serviceProvider, _verifier, _owner, thawRequestList.nonce));
950- _thawRequests[thawRequestId] = ThawRequest ({
951- shares: _shares,
952- thawingUntil: _thawingUntil,
953- next: bytes32 (0 ),
954- thawingNonce: _thawingNonce
955- });
964+ ThawRequest storage thawRequest = _getThawRequest (_requestType, thawRequestId);
965+ thawRequest.shares = _shares;
966+ thawRequest.thawingUntil = _thawingUntil;
967+ thawRequest.next = bytes32 (0 );
968+ thawRequest.thawingNonce = _thawingNonce;
956969
957- if (thawRequestList.count != 0 ) _thawRequests[ thawRequestList.tail] .next = thawRequestId;
970+ if (thawRequestList.count != 0 ) _getThawRequest (_requestType, thawRequestList.tail) .next = thawRequestId;
958971 thawRequestList.addTail (thawRequestId);
959972
960973 emit ThawRequestCreated (_serviceProvider, _verifier, _owner, _shares, _thawingUntil, thawRequestId);
961974 return thawRequestId;
962975 }
963976
977+ /**
978+ * @param requestType The type of thaw request (Provision or Delegation)
979+ * @param serviceProvider The address of the service provider
980+ * @param verifier The address of the verifier
981+ * @param owner The address of the owner of the thaw request
982+ * @param tokensThawing The current amount of tokens already thawing
983+ * @param sharesThawing The current amount of shares already thawing
984+ * @param nThawRequests The number of thaw requests to fulfill. If set to 0, all thaw requests are fulfilled.
985+ * @param thawingNonce The current valid thawing nonce. Any thaw request with a different nonce is invalid and should be ignored.
986+ */
987+ struct FulfillThawRequestsParams {
988+ ThawRequestType requestType;
989+ address serviceProvider;
990+ address verifier;
991+ address owner;
992+ uint256 tokensThawing;
993+ uint256 sharesThawing;
994+ uint256 nThawRequests;
995+ uint256 thawingNonce;
996+ }
997+
964998 /**
965999 * @notice Traverses a thaw request list and fulfills expired thaw requests.
9661000 * @dev Emits a {ThawRequestsFulfilled} event and a {ThawRequestFulfilled} event for each thaw request fulfilled.
967- * @param _serviceProvider The address of the service provider
968- * @param _verifier The address of the verifier
969- * @param _owner The address of the owner of the thaw request
970- * @param _tokensThawing The current amount of tokens already thawing
971- * @param _sharesThawing The current amount of shares already thawing
972- * @param _nThawRequests The number of thaw requests to fulfill. If set to 0, all thaw requests are fulfilled.
973- * @param _thawingNonce The current valid thawing nonce. Any thaw request with a different nonce is invalid and should be ignored.
1001+ * @param params The parameters for fulfilling thaw requests
9741002 * @return The amount of thawed tokens
9751003 * @return The amount of tokens still thawing
9761004 * @return The amount of shares still thawing
9771005 */
978- function _fulfillThawRequests (
979- address _serviceProvider ,
980- address _verifier ,
981- address _owner ,
982- uint256 _tokensThawing ,
983- uint256 _sharesThawing ,
984- uint256 _nThawRequests ,
985- uint256 _thawingNonce
986- ) private returns (uint256 , uint256 , uint256 ) {
987- LinkedList.List storage thawRequestList = _thawRequestLists[_serviceProvider][_verifier][_owner];
1006+ function _fulfillThawRequests (FulfillThawRequestsParams memory params ) private returns (uint256 , uint256 , uint256 ) {
1007+ LinkedList.List storage thawRequestList = _getThawRequestList (
1008+ params.requestType,
1009+ params.serviceProvider,
1010+ params.verifier,
1011+ params.owner
1012+ );
9881013 require (thawRequestList.count > 0 , HorizonStakingNothingThawing ());
9891014
990- uint256 tokensThawed = 0 ;
1015+ function (bytes32 ) view returns (bytes32 ) getNextItem = _getNextItemCallback (params.requestType);
1016+ function (bytes32 ) deleteItem = _getDeleteThawRequest (params.requestType);
1017+ bytes memory acc = abi.encode (
1018+ params.requestType,
1019+ uint256 (0 ),
1020+ params.tokensThawing,
1021+ params.sharesThawing,
1022+ params.thawingNonce
1023+ );
9911024 (uint256 thawRequestsFulfilled , bytes memory data ) = thawRequestList.traverse (
992- _getNextThawRequest ,
1025+ getNextItem ,
9931026 _fulfillThawRequest,
994- _deleteThawRequest ,
995- abi.encode (tokensThawed, _tokensThawing, _sharesThawing, _thawingNonce) ,
996- _nThawRequests
1027+ deleteItem ,
1028+ acc ,
1029+ params.nThawRequests
9971030 );
9981031
999- (tokensThawed, _tokensThawing, _sharesThawing) = abi.decode (data, (uint256 , uint256 , uint256 ));
1000- emit ThawRequestsFulfilled (_serviceProvider, _verifier, _owner, thawRequestsFulfilled, tokensThawed);
1001- return (tokensThawed, _tokensThawing, _sharesThawing);
1032+ (, uint256 tokensThawed , uint256 tokensThawing , uint256 sharesThawing ) = abi.decode (
1033+ data,
1034+ (ThawRequestType, uint256 , uint256 , uint256 )
1035+ );
1036+ emit ThawRequestsFulfilled (
1037+ params.serviceProvider,
1038+ params.verifier,
1039+ params.owner,
1040+ thawRequestsFulfilled,
1041+ tokensThawed
1042+ );
1043+ return (tokensThawed, tokensThawing, sharesThawing);
10021044 }
10031045
10041046 /**
@@ -1013,19 +1055,22 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
10131055 * @return The updated accumulator data
10141056 */
10151057 function _fulfillThawRequest (bytes32 _thawRequestId , bytes memory _acc ) private returns (bool , bytes memory ) {
1016- ThawRequest storage thawRequest = _thawRequests[_thawRequestId];
1058+ // decode
1059+ (
1060+ ThawRequestType requestType ,
1061+ uint256 tokensThawed ,
1062+ uint256 tokensThawing ,
1063+ uint256 sharesThawing ,
1064+ uint256 thawingNonce
1065+ ) = abi.decode (_acc, (ThawRequestType, uint256 , uint256 , uint256 , uint256 ));
1066+
1067+ ThawRequest storage thawRequest = _getThawRequest (requestType, _thawRequestId);
10171068
10181069 // early exit
10191070 if (thawRequest.thawingUntil > block .timestamp ) {
10201071 return (true , LinkedList.NULL_BYTES);
10211072 }
10221073
1023- // decode
1024- (uint256 tokensThawed , uint256 tokensThawing , uint256 sharesThawing , uint256 thawingNonce ) = abi.decode (
1025- _acc,
1026- (uint256 , uint256 , uint256 , uint256 )
1027- );
1028-
10291074 // process - only fulfill thaw requests for the current valid nonce
10301075 uint256 tokens = 0 ;
10311076 bool validThawRequest = thawRequest.thawingNonce == thawingNonce;
@@ -1044,17 +1089,39 @@ contract HorizonStaking is HorizonStakingBase, IHorizonStakingMain {
10441089 );
10451090
10461091 // encode
1047- _acc = abi.encode (tokensThawed, tokensThawing, sharesThawing, thawingNonce);
1092+ _acc = abi.encode (requestType, tokensThawed, tokensThawing, sharesThawing, thawingNonce);
10481093 return (false , _acc);
10491094 }
10501095
10511096 /**
1052- * @notice Deletes a ThawRequest.
1053- * @dev This function is used as a callback in the thaw requests linked list traversal.
1054- * @param _thawRequestId The ID of the thaw request to delete
1097+ * @notice Determines the correct callback function for `deleteItem` based on the request type.
1098+ * @param _requestType The type of thaw request (Provision or Delegation).
1099+ * @return A function pointer to the appropriate `deleteItem` callback.
1100+ */
1101+ function _getDeleteThawRequest (ThawRequestType _requestType ) private pure returns (function (bytes32 )) {
1102+ if (_requestType == ThawRequestType.Provision) {
1103+ return _deleteProvisionThawRequest;
1104+ } else if (_requestType == ThawRequestType.Delegation) {
1105+ return _deleteDelegationThawRequest;
1106+ } else {
1107+ revert ("Unknown ThawRequestType " );
1108+ }
1109+ }
1110+
1111+ /**
1112+ * @notice Deletes a thaw request for a provision.
1113+ * @param _thawRequestId The ID of the thaw request to delete.
1114+ */
1115+ function _deleteProvisionThawRequest (bytes32 _thawRequestId ) private {
1116+ delete _provisionThawRequests[_thawRequestId];
1117+ }
1118+
1119+ /**
1120+ * @notice Deletes a thaw request for a delegation.
1121+ * @param _thawRequestId The ID of the thaw request to delete.
10551122 */
1056- function _deleteThawRequest (bytes32 _thawRequestId ) private {
1057- delete _thawRequests [_thawRequestId];
1123+ function _deleteDelegationThawRequest (bytes32 _thawRequestId ) private {
1124+ delete _delegationThawRequests [_thawRequestId];
10581125 }
10591126
10601127 /**
0 commit comments