Skip to content

Commit 059f634

Browse files
committed
Revert when not enough precision to assign a delegation share
1 parent 99c39db commit 059f634

File tree

2 files changed

+46
-28
lines changed

2 files changed

+46
-28
lines changed

contracts/staking/Staking.sol

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ contract Staking is StakingV2Storage, GraphUpgradeable, IStaking {
186186
/**
187187
* @dev Check if the caller is the slasher.
188188
*/
189-
modifier onlySlasher {
189+
modifier onlySlasher() {
190190
require(slashers[msg.sender] == true, "!slasher");
191191
_;
192192
}
@@ -976,10 +976,10 @@ contract Staking is StakingV2Storage, GraphUpgradeable, IStaking {
976976

977977
// -- Collect protocol tax --
978978
// If the Allocation is not active or closed we are going to charge a 100% protocol tax
979-
uint256 usedProtocolPercentage =
980-
(allocState == AllocationState.Active || allocState == AllocationState.Closed)
981-
? protocolPercentage
982-
: MAX_PPM;
979+
uint256 usedProtocolPercentage = (allocState == AllocationState.Active ||
980+
allocState == AllocationState.Closed)
981+
? protocolPercentage
982+
: MAX_PPM;
983983
uint256 protocolTax = _collectTax(graphToken, queryFees, usedProtocolPercentage);
984984
queryFees = queryFees.sub(protocolTax);
985985

@@ -1114,17 +1114,16 @@ contract Staking is StakingV2Storage, GraphUpgradeable, IStaking {
11141114
// Creates an allocation
11151115
// Allocation identifiers are not reused
11161116
// The assetHolder address can send collected funds to the allocation
1117-
Allocation memory alloc =
1118-
Allocation(
1119-
_indexer,
1120-
_subgraphDeploymentID,
1121-
_tokens, // Tokens allocated
1122-
epochManager().currentEpoch(), // createdAtEpoch
1123-
0, // closedAtEpoch
1124-
0, // Initialize collected fees
1125-
0, // Initialize effective allocation
1126-
_updateRewards(_subgraphDeploymentID) // Initialize accumulated rewards per stake allocated
1127-
);
1117+
Allocation memory alloc = Allocation(
1118+
_indexer,
1119+
_subgraphDeploymentID,
1120+
_tokens, // Tokens allocated
1121+
epochManager().currentEpoch(), // createdAtEpoch
1122+
0, // closedAtEpoch
1123+
0, // Initialize collected fees
1124+
0, // Initialize effective allocation
1125+
_updateRewards(_subgraphDeploymentID) // Initialize accumulated rewards per stake allocated
1126+
);
11281127
allocations[_allocationID] = alloc;
11291128

11301129
// Mark allocated tokens as used
@@ -1134,8 +1133,7 @@ contract Staking is StakingV2Storage, GraphUpgradeable, IStaking {
11341133
// Used for rewards calculations
11351134
subgraphAllocations[alloc.subgraphDeploymentID] = subgraphAllocations[
11361135
alloc.subgraphDeploymentID
1137-
]
1138-
.add(alloc.tokens);
1136+
].add(alloc.tokens);
11391137

11401138
emit AllocationCreated(
11411139
_indexer,
@@ -1207,8 +1205,7 @@ contract Staking is StakingV2Storage, GraphUpgradeable, IStaking {
12071205
// Used for rewards calculations
12081206
subgraphAllocations[alloc.subgraphDeploymentID] = subgraphAllocations[
12091207
alloc.subgraphDeploymentID
1210-
]
1211-
.sub(alloc.tokens);
1208+
].sub(alloc.tokens);
12121209

12131210
emit AllocationClosed(
12141211
alloc.indexer,
@@ -1310,16 +1307,16 @@ contract Staking is StakingV2Storage, GraphUpgradeable, IStaking {
13101307
uint256 delegatedTokens = _tokens.sub(delegationTax);
13111308

13121309
// Calculate shares to issue
1313-
uint256 shares =
1314-
(pool.tokens == 0)
1315-
? delegatedTokens
1316-
: delegatedTokens.mul(pool.shares).div(pool.tokens);
1310+
uint256 shares = (pool.tokens == 0)
1311+
? delegatedTokens
1312+
: delegatedTokens.mul(pool.shares).div(pool.tokens);
1313+
require(shares > 0, "!shares");
13171314

13181315
// Update the delegation pool
13191316
pool.tokens = pool.tokens.add(delegatedTokens);
13201317
pool.shares = pool.shares.add(shares);
13211318

1322-
// Update the delegation
1319+
// Update the individual delegation
13231320
delegation.shares = delegation.shares.add(shares);
13241321

13251322
emit StakeDelegated(_indexer, _delegator, delegatedTokens, shares);

test/staking/delegation.test.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ describe('Staking::Delegation', () => {
400400
await shouldDelegate(delegator2, toGRT('5000'))
401401
})
402402

403-
it('should delegate a high number of tokens', async function () {
403+
it('should delegate a high amount of tokens', async function () {
404404
await shouldDelegate(delegator, toGRT('100'))
405405
await shouldDelegate(delegator, toGRT('1000000000000000000'))
406406
})
@@ -416,9 +416,10 @@ describe('Staking::Delegation', () => {
416416
await shouldDelegate(delegator, toGRT('10000000'))
417417
})
418418

419-
it('should delegate and burn delegation deposit tax (100%)', async function () {
419+
it('reject delegate with delegation deposit tax (100%)', async function () {
420420
await staking.setDelegationTaxPercentage(1000000)
421-
await shouldDelegate(delegator, toGRT('10000000'))
421+
const tx = staking.connect(delegator.signer).delegate(indexer.address, toGRT('10000000'))
422+
await expect(tx).revertedWith('!shares')
422423
})
423424
})
424425
})
@@ -649,5 +650,25 @@ describe('Staking::Delegation', () => {
649650
const afterDelegationPool = await staking.delegationPools(indexer.address)
650651
expect(afterDelegationPool.tokens).eq(beforeDelegationPool.tokens.add(delegationFees))
651652
})
653+
654+
it('revert if it cannot assign the smallest amount of shares', async function () {
655+
// Init the delegation pool
656+
await shouldDelegate(delegator, tokensToDelegate)
657+
658+
// Collect funds thru full allocation cycle
659+
await staking.connect(governor.signer).setDelegationRatio(10)
660+
await staking.connect(indexer.signer).setDelegationParameters(0, 0, 0)
661+
await setupAllocation(tokensToAllocate)
662+
await staking.connect(assetHolder.signer).collect(tokensToCollect, allocationID)
663+
await advanceToNextEpoch(epochManager)
664+
await staking.connect(indexer.signer).closeAllocation(allocationID, poi)
665+
await advanceToNextEpoch(epochManager)
666+
await staking.connect(indexer.signer).claim(allocationID, true)
667+
668+
// Delegate with such small amount of tokens (1 wei) that we do not have enough precision
669+
// to even assign 1 wei of shares
670+
const tx = staking.connect(delegator.signer).delegate(indexer.address, toBN(1))
671+
await expect(tx).revertedWith('!shares')
672+
})
652673
})
653674
})

0 commit comments

Comments
 (0)