Skip to content

Commit

Permalink
feat: remove minium allocation duration restriction
Browse files Browse the repository at this point in the history
Signed-off-by: Tomás Migone <[email protected]>
  • Loading branch information
tmigone committed Jan 4, 2024
1 parent 37a59dd commit 0a7dca8
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 9 deletions.
14 changes: 8 additions & 6 deletions packages/contracts/contracts/staking/Staking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -812,18 +812,18 @@ abstract contract Staking is StakingV4Storage, GraphUpgradeable, IStakingBase, M
// Get allocation
Allocation memory alloc = __allocations[_allocationID];

// Validate that an allocation cannot be closed before one epoch
alloc.closedAtEpoch = epochManager().currentEpoch();

// Allocation duration in epochs
uint256 epochs = MathUtils.diffOrZero(alloc.closedAtEpoch, alloc.createdAtEpoch);
require(epochs > 0, "<epochs");

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

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

Expand Down
20 changes: 17 additions & 3 deletions packages/contracts/test/staking/allocation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -876,9 +876,23 @@ describe('Staking:Allocation', () => {
await expect(tx).revertedWith('!active')
})

it('reject close before at least one epoch has passed', async function () {
it('allow close before one epoch has passed', async function () {
const currentEpoch = await epochManager.currentEpoch()
const beforeAlloc = await staking.getAllocation(allocationID)

const tx = staking.connect(indexer).closeAllocation(allocationID, poi)
await expect(tx).revertedWith('<epochs')
await expect(tx)
.emit(staking, 'AllocationClosed')
.withArgs(
indexer.address,
subgraphDeploymentID,
currentEpoch,
beforeAlloc.tokens,
allocationID,
indexer.address,
poi,
false,
)
})

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

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

0 comments on commit 0a7dca8

Please sign in to comment.