@@ -213,6 +213,80 @@ library AllocationManagerLib {
213
213
);
214
214
}
215
215
216
+ /**
217
+ * @notice Resize an allocation
218
+ * @dev Will lock or release tokens in the provision tracker depending on the new allocation size.
219
+ * Rewards accrued but not issued before the resize will be accounted for as pending rewards.
220
+ * These will be paid out when the indexer presents a POI.
221
+ *
222
+ * Requirements:
223
+ * - `_indexer` must be the owner of the allocation
224
+ * - Allocation must be open
225
+ * - `_tokens` must be different from the current allocation size
226
+ *
227
+ * Emits a {AllocationResized} event.
228
+ *
229
+ * @param _allocationId The id of the allocation to be resized
230
+ * @param _tokens The new amount of tokens to allocate
231
+ * @param _delegationRatio The delegation ratio to consider when locking tokens
232
+ */
233
+ function resizeAllocation (
234
+ mapping (address allocationId = > Allocation.State allocation ) storage _allocations ,
235
+ mapping (address indexer = > uint256 tokens ) storage allocationProvisionTracker ,
236
+ mapping (bytes32 subgraphDeploymentId = > uint256 tokens ) storage _subgraphAllocatedTokens ,
237
+ IHorizonStaking graphStaking ,
238
+ IRewardsManager graphRewardsManager ,
239
+ address _allocationId ,
240
+ uint256 _tokens ,
241
+ uint32 _delegationRatio
242
+ ) external {
243
+ Allocation.State memory allocation = _allocations.get (_allocationId);
244
+ require (allocation.isOpen (), AllocationManager.AllocationManagerAllocationClosed (_allocationId));
245
+ require (
246
+ _tokens != allocation.tokens,
247
+ AllocationManager.AllocationManagerAllocationSameSize (_allocationId, _tokens)
248
+ );
249
+
250
+ // Update provision tracker
251
+ uint256 oldTokens = allocation.tokens;
252
+ if (_tokens > oldTokens) {
253
+ allocationProvisionTracker.lock (graphStaking, allocation.indexer, _tokens - oldTokens, _delegationRatio);
254
+ } else {
255
+ allocationProvisionTracker.release (allocation.indexer, oldTokens - _tokens);
256
+ }
257
+
258
+ // Calculate rewards that have been accrued since the last snapshot but not yet issued
259
+ uint256 accRewardsPerAllocatedToken = graphRewardsManager.onSubgraphAllocationUpdate (
260
+ allocation.subgraphDeploymentId
261
+ );
262
+ uint256 accRewardsPerAllocatedTokenPending = ! allocation.isAltruistic ()
263
+ ? accRewardsPerAllocatedToken - allocation.accRewardsPerAllocatedToken
264
+ : 0 ;
265
+
266
+ // Update the allocation
267
+ _allocations[_allocationId].tokens = _tokens;
268
+ _allocations[_allocationId].accRewardsPerAllocatedToken = accRewardsPerAllocatedToken;
269
+ _allocations[_allocationId].accRewardsPending += graphRewardsManager.calcRewards (
270
+ oldTokens,
271
+ accRewardsPerAllocatedTokenPending
272
+ );
273
+
274
+ // Update total allocated tokens for the subgraph deployment
275
+ if (_tokens > oldTokens) {
276
+ _subgraphAllocatedTokens[allocation.subgraphDeploymentId] += (_tokens - oldTokens);
277
+ } else {
278
+ _subgraphAllocatedTokens[allocation.subgraphDeploymentId] -= (oldTokens - _tokens);
279
+ }
280
+
281
+ emit AllocationManager.AllocationResized (
282
+ allocation.indexer,
283
+ _allocationId,
284
+ allocation.subgraphDeploymentId,
285
+ _tokens,
286
+ oldTokens
287
+ );
288
+ }
289
+
216
290
/**
217
291
* @notice Checks if an allocation is over-allocated
218
292
* @param _indexer The address of the indexer
0 commit comments