@@ -72,7 +72,9 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
7272 * @param _metadataURI is the metadata URI for the AVS
7373 * @dev only callable by the owner
7474 */
75- function updateAVSMetadataURI (string memory _metadataURI ) public virtual onlyOwner {
75+ function updateAVSMetadataURI (
76+ string memory _metadataURI
77+ ) public virtual onlyOwner {
7678 _avsDirectory.updateAVSMetadataURI (_metadataURI);
7779 }
7880
@@ -87,25 +89,95 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
8789 * @dev This function will revert if the `rewardsSubmission` is malformed,
8890 * e.g. if the `strategies` and `weights` arrays are of non-equal lengths
8991 */
90- function createAVSRewardsSubmission (IRewardsCoordinator.RewardsSubmission[] calldata rewardsSubmissions )
91- public
92- virtual
93- onlyRewardsInitiator
94- {
92+ function createAVSRewardsSubmission (
93+ IRewardsCoordinator.RewardsSubmission[] calldata rewardsSubmissions
94+ ) public virtual onlyRewardsInitiator {
9595 for (uint256 i = 0 ; i < rewardsSubmissions.length ; ++ i) {
9696 // transfer token to ServiceManager and approve RewardsCoordinator to transfer again
9797 // in createAVSRewardsSubmission() call
98- rewardsSubmissions[i].token.transferFrom (msg .sender , address (this ), rewardsSubmissions[i].amount);
99- uint256 allowance =
100- rewardsSubmissions[i].token.allowance (address (this ), address (_rewardsCoordinator));
98+ rewardsSubmissions[i].token.transferFrom (
99+ msg .sender ,
100+ address (this ),
101+ rewardsSubmissions[i].amount
102+ );
103+ uint256 allowance = rewardsSubmissions[i].token.allowance (
104+ address (this ),
105+ address (_rewardsCoordinator)
106+ );
101107 rewardsSubmissions[i].token.approve (
102- address (_rewardsCoordinator), rewardsSubmissions[i].amount + allowance
108+ address (_rewardsCoordinator),
109+ rewardsSubmissions[i].amount + allowance
103110 );
104111 }
105112
106113 _rewardsCoordinator.createAVSRewardsSubmission (rewardsSubmissions);
107114 }
108115
116+ /**
117+ * @notice Creates a new operator-directed rewards submission, to be split amongst the operators and
118+ * set of stakers delegated to operators who are registered to this `avs`.
119+ * @param operatorDirectedRewardsSubmissions The operator-directed rewards submissions being created.
120+ * @dev Only callabe by the permissioned rewardsInitiator address
121+ * @dev The duration of the `rewardsSubmission` cannot exceed `MAX_REWARDS_DURATION`
122+ * @dev The tokens are sent to the `RewardsCoordinator` contract
123+ * @dev This contract needs a token approval of sum of all `operatorRewards` in the `operatorDirectedRewardsSubmissions`, before calling this function.
124+ * @dev Strategies must be in ascending order of addresses to check for duplicates
125+ * @dev Operators must be in ascending order of addresses to check for duplicates.
126+ * @dev This function will revert if the `operatorDirectedRewardsSubmissions` is malformed.
127+ */
128+ function createOperatorDirectedAVSRewardsSubmission (
129+ IRewardsCoordinator.OperatorDirectedRewardsSubmission[]
130+ calldata operatorDirectedRewardsSubmissions
131+ ) public virtual onlyRewardsInitiator {
132+ for (
133+ uint256 i = 0 ;
134+ i < operatorDirectedRewardsSubmissions.length ;
135+ ++ i
136+ ) {
137+ // Calculate total amount of token to transfer
138+ uint256 totalAmount = 0 ;
139+ for (
140+ uint256 j = 0 ;
141+ j <
142+ operatorDirectedRewardsSubmissions[i].operatorRewards.length ;
143+ ++ j
144+ ) {
145+ totalAmount += operatorDirectedRewardsSubmissions[i]
146+ .operatorRewards[j]
147+ .amount;
148+ }
149+
150+ // Transfer token to ServiceManager and approve RewardsCoordinator to transfer again
151+ // in createAVSPerformanceRewardsSubmission() call
152+ operatorDirectedRewardsSubmissions[i].token.transferFrom (
153+ msg .sender ,
154+ address (this ),
155+ totalAmount
156+ );
157+ uint256 allowance = operatorDirectedRewardsSubmissions[i]
158+ .token
159+ .allowance (address (this ), address (_rewardsCoordinator));
160+ operatorDirectedRewardsSubmissions[i].token.approve (
161+ address (_rewardsCoordinator),
162+ totalAmount + allowance
163+ );
164+ }
165+
166+ _rewardsCoordinator.createOperatorDirectedAVSRewardsSubmission (
167+ address (this ),
168+ operatorDirectedRewardsSubmissions
169+ );
170+ }
171+
172+ /**
173+ * @notice Forwards a call to Eigenlayer's RewardsCoordinator contract to set the address of the entity that can call `processClaim` on behalf of this contract.
174+ * @param claimer The address of the entity that can call `processClaim` on behalf of the earner
175+ * @dev Only callabe by the owner.
176+ */
177+ function setClaimerFor (address claimer ) public virtual onlyOwner {
178+ _rewardsCoordinator.setClaimerFor (claimer);
179+ }
180+
109181 /**
110182 * @notice Forwards a call to EigenLayer's AVSDirectory contract to confirm operator registration with the AVS
111183 * @param operator The address of the operator to register.
@@ -122,7 +194,9 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
122194 * @notice Forwards a call to EigenLayer's AVSDirectory contract to confirm operator deregistration from the AVS
123195 * @param operator The address of the operator to deregister.
124196 */
125- function deregisterOperatorFromAVS (address operator ) public virtual onlyRegistryCoordinator {
197+ function deregisterOperatorFromAVS (
198+ address operator
199+ ) public virtual onlyRegistryCoordinator {
126200 _avsDirectory.deregisterOperatorFromAVS (operator);
127201 }
128202
@@ -131,7 +205,9 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
131205 * @param newRewardsInitiator The new rewards initiator address
132206 * @dev only callable by the owner
133207 */
134- function setRewardsInitiator (address newRewardsInitiator ) external onlyOwner {
208+ function setRewardsInitiator (
209+ address newRewardsInitiator
210+ ) external onlyOwner {
135211 _setRewardsInitiator (newRewardsInitiator);
136212 }
137213
@@ -146,7 +222,12 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
146222 * @dev No guarantee is made on uniqueness of each element in the returned array.
147223 * The off-chain service should do that validation separately
148224 */
149- function getRestakeableStrategies () external virtual view returns (address [] memory ) {
225+ function getRestakeableStrategies ()
226+ external
227+ view
228+ virtual
229+ returns (address [] memory )
230+ {
150231 uint256 quorumCount = _registryCoordinator.quorumCount ();
151232
152233 if (quorumCount == 0 ) {
@@ -161,10 +242,13 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
161242 address [] memory restakedStrategies = new address [](strategyCount);
162243 uint256 index = 0 ;
163244 for (uint256 i = 0 ; i < _registryCoordinator.quorumCount (); i++ ) {
164- uint256 strategyParamsLength = _stakeRegistry.strategyParamsLength (uint8 (i));
245+ uint256 strategyParamsLength = _stakeRegistry.strategyParamsLength (
246+ uint8 (i)
247+ );
165248 for (uint256 j = 0 ; j < strategyParamsLength; j++ ) {
166- restakedStrategies[index] =
167- address (_stakeRegistry.strategyParamsByIndex (uint8 (i), j).strategy);
249+ restakedStrategies[index] = address (
250+ _stakeRegistry.strategyParamsByIndex (uint8 (i), j).strategy
251+ );
168252 index++ ;
169253 }
170254 }
@@ -178,35 +262,41 @@ abstract contract ServiceManagerBase is ServiceManagerBaseStorage {
178262 * @dev No guarantee is made on whether the operator has shares for a strategy in a quorum or uniqueness
179263 * of each element in the returned array. The off-chain service should do that validation separately
180264 */
181- function getOperatorRestakedStrategies (address operator )
182- external
183- virtual
184- view
185- returns (address [] memory )
186- {
265+ function getOperatorRestakedStrategies (
266+ address operator
267+ ) external view virtual returns (address [] memory ) {
187268 bytes32 operatorId = _registryCoordinator.getOperatorId (operator);
188- uint192 operatorBitmap = _registryCoordinator.getCurrentQuorumBitmap (operatorId);
269+ uint192 operatorBitmap = _registryCoordinator.getCurrentQuorumBitmap (
270+ operatorId
271+ );
189272
190273 if (operatorBitmap == 0 || _registryCoordinator.quorumCount () == 0 ) {
191274 return new address [](0 );
192275 }
193276
194277 // Get number of strategies for each quorum in operator bitmap
195- bytes memory operatorRestakedQuorums = BitmapUtils.bitmapToBytesArray (operatorBitmap);
278+ bytes memory operatorRestakedQuorums = BitmapUtils.bitmapToBytesArray (
279+ operatorBitmap
280+ );
196281 uint256 strategyCount;
197282 for (uint256 i = 0 ; i < operatorRestakedQuorums.length ; i++ ) {
198- strategyCount += _stakeRegistry.strategyParamsLength (uint8 (operatorRestakedQuorums[i]));
283+ strategyCount += _stakeRegistry.strategyParamsLength (
284+ uint8 (operatorRestakedQuorums[i])
285+ );
199286 }
200287
201288 // Get strategies for each quorum in operator bitmap
202289 address [] memory restakedStrategies = new address [](strategyCount);
203290 uint256 index = 0 ;
204291 for (uint256 i = 0 ; i < operatorRestakedQuorums.length ; i++ ) {
205292 uint8 quorum = uint8 (operatorRestakedQuorums[i]);
206- uint256 strategyParamsLength = _stakeRegistry.strategyParamsLength (quorum);
293+ uint256 strategyParamsLength = _stakeRegistry.strategyParamsLength (
294+ quorum
295+ );
207296 for (uint256 j = 0 ; j < strategyParamsLength; j++ ) {
208- restakedStrategies[index] =
209- address (_stakeRegistry.strategyParamsByIndex (quorum, j).strategy);
297+ restakedStrategies[index] = address (
298+ _stakeRegistry.strategyParamsByIndex (quorum, j).strategy
299+ );
210300 index++ ;
211301 }
212302 }
0 commit comments