Skip to content

Commit efe5605

Browse files
authored
Merge pull request #819 from graphprotocol/ab/snapshot-on-collect
fix: update snapshot on query fee collect
2 parents ed86d23 + 66f8237 commit efe5605

File tree

3 files changed

+72
-4
lines changed

3 files changed

+72
-4
lines changed

contracts/staking/Staking.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,7 @@ abstract contract Staking is StakingV3Storage, GraphUpgradeable, IStakingBase, M
10231023
// Transfer and call collect()
10241024
// This function transfer tokens to a trusted protocol contracts
10251025
// Then we call collect() to do the transfer bookeeping
1026+
rewardsManager().onSubgraphSignalUpdate(_subgraphDeploymentID);
10261027
TokenUtils.pushTokens(_graphToken, address(curation), curationFees);
10271028
curation.collect(_subgraphDeploymentID, curationFees);
10281029
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@graphprotocol/contracts",
3-
"version": "5.0.0",
3+
"version": "5.0.1",
44
"description": "Contracts for the Graph Protocol",
55
"directories": {
66
"test": "test"

test/rewards/rewards.test.ts

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { expect } from 'chai'
22
import { constants, BigNumber } from 'ethers'
33
import { BigNumber as BN } from 'bignumber.js'
44

5-
import { deployContract } from '../lib/deployment'
65
import { NetworkFixture } from '../lib/fixtures'
76

87
import { Curation } from '../../build/types/Curation'
@@ -23,6 +22,7 @@ import {
2322
Account,
2423
advanceToNextEpoch,
2524
provider,
25+
advanceBlock,
2626
} from '../lib/testHelpers'
2727

2828
const MAX_PPM = 1000000
@@ -39,6 +39,7 @@ describe('Rewards', () => {
3939
let indexer1: Account
4040
let indexer2: Account
4141
let oracle: Account
42+
let assetHolder: Account
4243

4344
let fixture: NetworkFixture
4445

@@ -131,7 +132,8 @@ describe('Rewards', () => {
131132
}
132133

133134
before(async function () {
134-
;[delegator, governor, curator1, curator2, indexer1, indexer2, oracle] = await getAccounts()
135+
;[delegator, governor, curator1, curator2, indexer1, indexer2, oracle, assetHolder] =
136+
await getAccounts()
135137

136138
fixture = new NetworkFixture()
137139
;({ grt, curation, epochManager, staking, rewardsManager } = await fixture.load(
@@ -142,7 +144,7 @@ describe('Rewards', () => {
142144
await rewardsManager.connect(governor.signer).setIssuancePerBlock(ISSUANCE_PER_BLOCK)
143145

144146
// Distribute test funds
145-
for (const wallet of [indexer1, indexer2, curator1, curator2]) {
147+
for (const wallet of [indexer1, indexer2, curator1, curator2, assetHolder]) {
146148
await grt.connect(governor.signer).mint(wallet.address, toGRT('1000000'))
147149
await grt.connect(wallet.signer).approve(staking.address, toGRT('1000000'))
148150
await grt.connect(wallet.signer).approve(curation.address, toGRT('1000000'))
@@ -955,4 +957,69 @@ describe('Rewards', () => {
955957
expect(event1.amount).eq(event2.amount)
956958
})
957959
})
960+
961+
describe('rewards progression when collecting query fees', function () {
962+
it('collect query fees with two subgraphs and one allocation', async function () {
963+
async function getRewardsAccrual(subgraphs) {
964+
const [sg1, sg2] = await Promise.all(
965+
subgraphs.map((sg) => rewardsManager.getAccRewardsForSubgraph(sg)),
966+
)
967+
return {
968+
sg1,
969+
sg2,
970+
all: sg1.add(sg2),
971+
}
972+
}
973+
974+
// set curation percentage
975+
await staking.setCurationPercentage(100000)
976+
977+
// allow the asset holder
978+
const tokensToCollect = toGRT('10000')
979+
await staking.connect(governor.signer).setAssetHolder(assetHolder.address, true)
980+
981+
// signal in two subgraphs in the same block
982+
const subgraphs = [subgraphDeploymentID1, subgraphDeploymentID2]
983+
for (const sub of subgraphs) {
984+
await curation.connect(curator1.signer).mint(sub, toGRT('1500'), 0)
985+
}
986+
987+
// snapshot block before any accrual (we substract 1 because accrual starts after the first mint happens)
988+
const b1 = await epochManager.blockNum().then((x) => x.toNumber() - 1)
989+
990+
// allocate
991+
const tokensToAllocate = toGRT('12500')
992+
await staking
993+
.connect(indexer1.signer)
994+
.multicall([
995+
await staking.populateTransaction.stake(tokensToAllocate).then((tx) => tx.data),
996+
await staking.populateTransaction
997+
.allocateFrom(
998+
indexer1.address,
999+
subgraphDeploymentID1,
1000+
tokensToAllocate,
1001+
allocationID1,
1002+
metadata,
1003+
await channelKey1.generateProof(indexer1.address),
1004+
)
1005+
.then((tx) => tx.data),
1006+
])
1007+
1008+
// move time fwd
1009+
await advanceBlock()
1010+
1011+
// collect funds into staking for that sub
1012+
await staking.connect(assetHolder.signer).collect(tokensToCollect, allocationID1)
1013+
1014+
// check rewards diff
1015+
await rewardsManager.getRewards(allocationID1).then(formatGRT)
1016+
1017+
await advanceBlock()
1018+
const accrual = await getRewardsAccrual(subgraphs)
1019+
const b2 = await epochManager.blockNum().then((x) => x.toNumber())
1020+
1021+
// round comparison because there is a small precision error due to dividing and accrual per signal
1022+
expect(toRound(accrual.all)).eq(toRound(ISSUANCE_PER_BLOCK.mul(b2 - b1)))
1023+
})
1024+
})
9581025
})

0 commit comments

Comments
 (0)