Skip to content

Commit 26f0b87

Browse files
committed
staking: optimize closeAllocation to reduce SLOAD
Reduce the gas used by 7%
1 parent 8fdf968 commit 26f0b87

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

contracts/staking/Staking.sol

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -952,8 +952,8 @@ contract Staking is StakingV1Storage, GraphUpgradeable, IStaking {
952952
allocState == AllocationState.Closed)
953953
? protocolPercentage
954954
: MAX_PPM;
955-
uint256 protocolFees = _collectTax(graphToken, queryFees, usedProtocolPercentage);
956-
queryFees = queryFees.sub(protocolFees);
955+
uint256 protocolTax = _collectTax(graphToken, queryFees, usedProtocolPercentage);
956+
queryFees = queryFees.sub(protocolTax);
957957

958958
// -- Collect curation fees --
959959
// Only if the subgraph deployment is curated
@@ -1128,12 +1128,12 @@ contract Staking is StakingV1Storage, GraphUpgradeable, IStaking {
11281128
require(allocState == AllocationState.Active, "!active");
11291129

11301130
// Get allocation
1131-
Allocation storage alloc = allocations[_allocationID];
1131+
Allocation memory alloc = allocations[_allocationID];
11321132

11331133
// Validate that an allocation cannot be closed before one epoch
1134-
uint256 currentEpoch = epochManager().currentEpoch();
1135-
uint256 epochs = alloc.createdAtEpoch < currentEpoch
1136-
? currentEpoch.sub(alloc.createdAtEpoch)
1134+
alloc.closedAtEpoch = epochManager().currentEpoch();
1135+
uint256 epochs = alloc.createdAtEpoch < alloc.closedAtEpoch
1136+
? alloc.closedAtEpoch.sub(alloc.createdAtEpoch)
11371137
: 0;
11381138
require(epochs > 0, "<epochs");
11391139

@@ -1146,13 +1146,20 @@ contract Staking is StakingV1Storage, GraphUpgradeable, IStaking {
11461146
require(isIndexer, "!auth");
11471147
}
11481148

1149+
// Calculate effective allocation for the amount of epochs it remained allocated
1150+
alloc.effectiveAllocation = _getEffectiveAllocation(
1151+
maxAllocationEpochs,
1152+
alloc.tokens,
1153+
epochs
1154+
);
1155+
11491156
// Close the allocation and start counting a period to settle remaining payments from
11501157
// state channels.
1151-
alloc.closedAtEpoch = currentEpoch;
1152-
alloc.effectiveAllocation = _getEffectiveAllocation(alloc.tokens, epochs);
1158+
allocations[_allocationID].closedAtEpoch = alloc.closedAtEpoch;
1159+
allocations[_allocationID].effectiveAllocation = alloc.effectiveAllocation;
11531160

11541161
// Account collected fees and effective allocation in rebate pool for the epoch
1155-
Rebates.Pool storage rebatePool = rebates[currentEpoch];
1162+
Rebates.Pool storage rebatePool = rebates[alloc.closedAtEpoch];
11561163
if (!rebatePool.exists()) {
11571164
rebatePool.init(alphaNumerator, alphaDenominator);
11581165
}
@@ -1196,23 +1203,21 @@ contract Staking is StakingV1Storage, GraphUpgradeable, IStaking {
11961203
require(allocState == AllocationState.Finalized, "!finalized");
11971204

11981205
// Get allocation
1199-
Allocation storage alloc = allocations[_allocationID];
1200-
address indexer = alloc.indexer;
1201-
uint256 closedAtEpoch = alloc.closedAtEpoch;
1206+
Allocation memory alloc = allocations[_allocationID];
12021207

12031208
// Only the indexer or operator can decide if to restake
1204-
bool restake = _isAuth(indexer) ? _restake : false;
1209+
bool restake = _isAuth(alloc.indexer) ? _restake : false;
12051210

12061211
// Process rebate reward
1207-
Rebates.Pool storage rebatePool = rebates[closedAtEpoch];
1212+
Rebates.Pool storage rebatePool = rebates[alloc.closedAtEpoch];
12081213
uint256 tokensToClaim = rebatePool.redeem(alloc.collectedFees, alloc.effectiveAllocation);
12091214

1210-
// Calculate delegation rewards and add them to the delegation pool
1211-
uint256 delegationRewards = _collectDelegationQueryRewards(indexer, tokensToClaim);
1215+
// Add delegation rewards to the delegation pool
1216+
uint256 delegationRewards = _collectDelegationQueryRewards(alloc.indexer, tokensToClaim);
12121217
tokensToClaim = tokensToClaim.sub(delegationRewards);
12131218

12141219
// Update the allocate state
1215-
alloc.tokens = 0; // This avoid collect(), close() and claim() to be called
1220+
allocations[_allocationID].tokens = 0; // This avoid collect(), close() and claim() to be called
12161221

12171222
// -- Interactions --
12181223

@@ -1221,27 +1226,27 @@ contract Staking is StakingV1Storage, GraphUpgradeable, IStaking {
12211226
// When all allocations processed then burn unclaimed fees and prune rebate pool
12221227
if (rebatePool.unclaimedAllocationsCount == 0) {
12231228
_burnTokens(graphToken, rebatePool.unclaimedFees());
1224-
delete rebates[closedAtEpoch];
1229+
delete rebates[alloc.closedAtEpoch];
12251230
}
12261231

12271232
// When there are tokens to claim from the rebate pool, transfer or restake
12281233
if (tokensToClaim > 0) {
12291234
// Assign claimed tokens
12301235
if (restake) {
12311236
// Restake to place fees into the indexer stake
1232-
_stake(indexer, tokensToClaim);
1237+
_stake(alloc.indexer, tokensToClaim);
12331238
} else {
12341239
// Transfer funds back to the indexer
1235-
require(graphToken.transfer(indexer, tokensToClaim), "!transfer");
1240+
require(graphToken.transfer(alloc.indexer, tokensToClaim), "!transfer");
12361241
}
12371242
}
12381243

12391244
emit RebateClaimed(
1240-
indexer,
1245+
alloc.indexer,
12411246
alloc.subgraphDeploymentID,
12421247
_allocationID,
12431248
epochManager().currentEpoch(),
1244-
closedAtEpoch,
1249+
alloc.closedAtEpoch,
12451250
tokensToClaim,
12461251
rebatePool.unclaimedAllocationsCount,
12471252
delegationRewards
@@ -1504,17 +1509,18 @@ contract Staking is StakingV1Storage, GraphUpgradeable, IStaking {
15041509

15051510
/**
15061511
* @dev Get the effective stake allocation considering epochs from allocation to closing.
1512+
* @param _maxAllocationEpochs Max amount of epochs to cap the allocated stake
15071513
* @param _tokens Amount of tokens allocated
15081514
* @param _numEpochs Number of epochs that passed from allocation to closing
15091515
* @return Effective allocated tokens across epochs
15101516
*/
1511-
function _getEffectiveAllocation(uint256 _tokens, uint256 _numEpochs)
1512-
private
1513-
view
1514-
returns (uint256)
1515-
{
1516-
bool shouldCap = maxAllocationEpochs > 0 && _numEpochs > maxAllocationEpochs;
1517-
return _tokens.mul((shouldCap) ? maxAllocationEpochs : _numEpochs);
1517+
function _getEffectiveAllocation(
1518+
uint256 _maxAllocationEpochs,
1519+
uint256 _tokens,
1520+
uint256 _numEpochs
1521+
) private pure returns (uint256) {
1522+
bool shouldCap = _maxAllocationEpochs > 0 && _numEpochs > _maxAllocationEpochs;
1523+
return _tokens.mul((shouldCap) ? _maxAllocationEpochs : _numEpochs);
15181524
}
15191525

15201526
/**

0 commit comments

Comments
 (0)