Skip to content

Commit 0a7dca8

Browse files
committed
feat: remove minium allocation duration restriction
Signed-off-by: Tomás Migone <[email protected]>
1 parent 37a59dd commit 0a7dca8

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

packages/contracts/contracts/staking/Staking.sol

+8-6
Original file line numberDiff line numberDiff line change
@@ -812,18 +812,18 @@ abstract contract Staking is StakingV4Storage, GraphUpgradeable, IStakingBase, M
812812
// Get allocation
813813
Allocation memory alloc = __allocations[_allocationID];
814814

815-
// Validate that an allocation cannot be closed before one epoch
816815
alloc.closedAtEpoch = epochManager().currentEpoch();
816+
817+
// Allocation duration in epochs
817818
uint256 epochs = MathUtils.diffOrZero(alloc.closedAtEpoch, alloc.createdAtEpoch);
818-
require(epochs > 0, "<epochs");
819819

820820
// Indexer or operator can close an allocation
821821
// Anyone is allowed to close ONLY under two concurrent conditions
822822
// - After maxAllocationEpochs passed
823823
// - When the allocation is for non-zero amount of tokens
824-
bool isIndexer = _isAuth(alloc.indexer);
824+
bool isIndexerOrOperator = _isAuth(alloc.indexer);
825825
if (epochs <= __maxAllocationEpochs || alloc.tokens == 0) {
826-
require(isIndexer, "!auth");
826+
require(isIndexerOrOperator, "!auth");
827827
}
828828

829829
// Close the allocation
@@ -834,7 +834,9 @@ abstract contract Staking is StakingV4Storage, GraphUpgradeable, IStakingBase, M
834834
// Process non-zero-allocation rewards tracking
835835
if (alloc.tokens > 0) {
836836
// Distribute rewards if proof of indexing was presented by the indexer or operator
837-
if (isIndexer && _poi != 0) {
837+
// and the allocation is at least one epoch old (most indexed chains require the EBO
838+
// posting epoch block numbers to produce a valid POI which happens once per epoch)
839+
if (isIndexerOrOperator && _poi != 0 && epochs > 0) {
838840
_distributeRewards(_allocationID, alloc.indexer);
839841
} else {
840842
_updateRewards(alloc.subgraphDeploymentID);
@@ -858,7 +860,7 @@ abstract contract Staking is StakingV4Storage, GraphUpgradeable, IStakingBase, M
858860
_allocationID,
859861
msg.sender,
860862
_poi,
861-
!isIndexer
863+
!isIndexerOrOperator
862864
);
863865
}
864866

packages/contracts/test/staking/allocation.test.ts

+17-3
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,23 @@ describe('Staking:Allocation', () => {
876876
await expect(tx).revertedWith('!active')
877877
})
878878

879-
it('reject close before at least one epoch has passed', async function () {
879+
it('allow close before one epoch has passed', async function () {
880+
const currentEpoch = await epochManager.currentEpoch()
881+
const beforeAlloc = await staking.getAllocation(allocationID)
882+
880883
const tx = staking.connect(indexer).closeAllocation(allocationID, poi)
881-
await expect(tx).revertedWith('<epochs')
884+
await expect(tx)
885+
.emit(staking, 'AllocationClosed')
886+
.withArgs(
887+
indexer.address,
888+
subgraphDeploymentID,
889+
currentEpoch,
890+
beforeAlloc.tokens,
891+
allocationID,
892+
indexer.address,
893+
poi,
894+
false,
895+
)
882896
})
883897

884898
it('reject close if not the owner of allocation', async function () {
@@ -923,7 +937,7 @@ describe('Staking:Allocation', () => {
923937
it('should close an allocation (by public) only if allocation is non-zero', async function () {
924938
// Reject to close if public address and under max allocation epochs
925939
const tx1 = staking.connect(me).closeAllocation(allocationID, poi)
926-
await expect(tx1).revertedWith('<epochs')
940+
await expect(tx1).revertedWith('!auth')
927941

928942
// Move max allocation epochs to close by delegator
929943
const maxAllocationEpochs = await staking.maxAllocationEpochs()

0 commit comments

Comments
 (0)