1
1
import { expect } from 'chai'
2
2
import { constants , BigNumber } from 'ethers'
3
+ import { BigNumber as BN } from 'bignumber.js'
3
4
4
5
import { NetworkFixture } from '../lib/fixtures'
5
6
@@ -25,8 +26,7 @@ const MAX_PPM = 1000000
25
26
26
27
const { HashZero, WeiPerEther } = constants
27
28
28
- const toFloat = ( n : BigNumber ) => parseFloat ( formatGRT ( n ) )
29
- const toRound = ( n : BigNumber ) => Math . round ( toFloat ( n ) )
29
+ const toRound = ( n : BigNumber ) => formatGRT ( n ) . split ( '.' ) [ 0 ]
30
30
31
31
describe ( 'Rewards' , ( ) => {
32
32
let delegator : Account
@@ -55,9 +55,11 @@ describe('Rewards', () => {
55
55
const ISSUANCE_RATE_PER_BLOCK = toBN ( '1012272234429039270' ) // % increase every block
56
56
57
57
// Core formula that gets accumulated rewards per signal for a period of time
58
- const getRewardsPerSignal = ( p : BigNumber , r : BigNumber , t : BigNumber , s : BigNumber ) : number => {
59
- if ( ! toFloat ( s ) ) return 0
60
- return ( toRound ( p ) * toFloat ( r ) ** t . toNumber ( ) - toFloat ( p ) ) / toFloat ( s )
58
+ const getRewardsPerSignal = ( p : BN , r : BN , t : BN , s : BN ) : string => {
59
+ if ( s . eq ( 0 ) ) {
60
+ return '0'
61
+ }
62
+ return p . times ( r . pow ( t ) ) . minus ( p ) . div ( s ) . toPrecision ( 18 ) . toString ( )
61
63
}
62
64
63
65
// Tracks the accumulated rewards as totalSignalled or supply changes across snapshots
@@ -74,7 +76,7 @@ describe('Rewards', () => {
74
76
}
75
77
76
78
async snapshot ( ) {
77
- this . accumulated = this . accumulated . add ( await this . accruedGRT ( ) )
79
+ this . accumulated = this . accumulated . add ( await this . accrued ( ) )
78
80
this . totalSupply = await grt . totalSupply ( )
79
81
this . totalSignalled = await grt . balanceOf ( curation . address )
80
82
this . lastUpdatedBlock = await latestBlock ( )
@@ -88,21 +90,13 @@ describe('Rewards', () => {
88
90
89
91
async accrued ( ) {
90
92
const nBlocks = await this . elapsedBlocks ( )
91
- return getRewardsPerSignal (
92
- this . totalSupply ,
93
- ISSUANCE_RATE_PER_BLOCK ,
94
- nBlocks ,
95
- this . totalSignalled ,
93
+ const n = getRewardsPerSignal (
94
+ new BN ( this . totalSupply . toString ( ) ) ,
95
+ new BN ( ISSUANCE_RATE_PER_BLOCK . toString ( ) ) . div ( 1e18 ) ,
96
+ new BN ( nBlocks . toString ( ) ) ,
97
+ new BN ( this . totalSignalled . toString ( ) ) ,
96
98
)
97
- }
98
-
99
- async accruedGRT ( ) {
100
- const n = await this . accrued ( )
101
- return toGRT ( n . toString ( ) )
102
- }
103
-
104
- async accruedRounded ( ) {
105
- return Math . round ( await this . accrued ( ) )
99
+ return toGRT ( n )
106
100
}
107
101
}
108
102
@@ -119,10 +113,10 @@ describe('Rewards', () => {
119
113
// Contract calculation
120
114
const contractAccrued = await rewardsManager . getNewRewardsPerSignal ( )
121
115
// Local calculation
122
- const expectedAccrued = await tracker . accruedRounded ( )
116
+ const expectedAccrued = await tracker . accrued ( )
123
117
124
118
// Check
125
- expect ( expectedAccrued ) . eq ( toRound ( contractAccrued ) )
119
+ expect ( toRound ( expectedAccrued ) ) . eq ( toRound ( contractAccrued ) )
126
120
return expectedAccrued
127
121
}
128
122
@@ -268,8 +262,8 @@ describe('Rewards', () => {
268
262
const contractAccrued = await rewardsManager . accRewardsPerSignal ( )
269
263
270
264
// Check
271
- const expectedAccrued = await tracker . accruedRounded ( )
272
- expect ( expectedAccrued ) . eq ( toRound ( contractAccrued ) )
265
+ const expectedAccrued = await tracker . accrued ( )
266
+ expect ( toRound ( expectedAccrued ) ) . eq ( toRound ( contractAccrued ) )
273
267
} )
274
268
275
269
it ( 'update the accumulated rewards per signal state after many blocks' , async function ( ) {
@@ -286,8 +280,8 @@ describe('Rewards', () => {
286
280
const contractAccrued = await rewardsManager . accRewardsPerSignal ( )
287
281
288
282
// Check
289
- const expectedAccrued = await tracker . accruedRounded ( )
290
- expect ( expectedAccrued ) . eq ( toRound ( contractAccrued ) )
283
+ const expectedAccrued = await tracker . accrued ( )
284
+ expect ( toRound ( expectedAccrued ) ) . eq ( toRound ( contractAccrued ) )
291
285
} )
292
286
} )
293
287
@@ -350,13 +344,13 @@ describe('Rewards', () => {
350
344
// Check
351
345
const contractRewardsSG1 = ( await rewardsManager . subgraphs ( subgraphDeploymentID1 ) )
352
346
. accRewardsForSubgraph
353
- const rewardsPerSignal1 = await tracker1 . accruedGRT ( )
347
+ const rewardsPerSignal1 = await tracker1 . accrued ( )
354
348
const expectedRewardsSG1 = rewardsPerSignal1 . mul ( signalled1 ) . div ( WeiPerEther )
355
349
expect ( toRound ( expectedRewardsSG1 ) ) . eq ( toRound ( contractRewardsSG1 ) )
356
350
357
351
const contractAccrued = await rewardsManager . accRewardsPerSignal ( )
358
- const expectedAccrued = await tracker1 . accruedRounded ( )
359
- expect ( expectedAccrued ) . eq ( toRound ( contractAccrued ) )
352
+ const expectedAccrued = await tracker1 . accrued ( )
353
+ expect ( toRound ( expectedAccrued ) ) . eq ( toRound ( contractAccrued ) )
360
354
361
355
const contractBlockUpdated = await rewardsManager . accRewardsPerSignalLastBlockUpdated ( )
362
356
const expectedBlockUpdated = await latestBlock ( )
@@ -426,8 +420,8 @@ describe('Rewards', () => {
426
420
// Prepare expected results
427
421
// NOTE: calculated the expected result manually as the above code has 1 off block difference
428
422
// replace with a RewardsManagerMock
429
- const expectedSubgraphRewards = 891695471
430
- const expectedRewardsAT = 51572
423
+ const expectedSubgraphRewards = toGRT ( '891695470' )
424
+ const expectedRewardsAT = toGRT ( '51571' )
431
425
432
426
// Update
433
427
await rewardsManager . onSubgraphAllocationUpdate ( subgraphDeploymentID1 )
@@ -439,8 +433,8 @@ describe('Rewards', () => {
439
433
)
440
434
const contractRewardsAT = subgraph . accRewardsPerAllocatedToken
441
435
442
- expect ( expectedSubgraphRewards ) . eq ( toRound ( contractSubgraphRewards ) )
443
- expect ( expectedRewardsAT ) . eq ( toRound ( contractRewardsAT ) )
436
+ expect ( toRound ( expectedSubgraphRewards ) ) . eq ( toRound ( contractSubgraphRewards ) )
437
+ expect ( toRound ( expectedRewardsAT ) ) . eq ( toRound ( contractRewardsAT ) )
444
438
} )
445
439
} )
446
440
@@ -486,37 +480,59 @@ describe('Rewards', () => {
486
480
queryFeeCut : BigNumber
487
481
cooldownBlocks : number
488
482
}
483
+ async function setupIndexerAllocation ( ) {
484
+ // Setup
485
+ await epochManager . setEpochLength ( 10 )
486
+
487
+ // Update total signalled
488
+ const signalled1 = toGRT ( '1500' )
489
+ await curation . connect ( curator1 . signer ) . mint ( subgraphDeploymentID1 , signalled1 )
489
490
490
- async function setupIndexerDelegation (
491
+ // Allocate
492
+ const tokensToAllocate = toGRT ( '12500' )
493
+ await staking . connect ( indexer1 . signer ) . stake ( tokensToAllocate )
494
+ await staking
495
+ . connect ( indexer1 . signer )
496
+ . allocate (
497
+ subgraphDeploymentID1 ,
498
+ tokensToAllocate ,
499
+ channelPubKey ,
500
+ assetHolder . address ,
501
+ metadata ,
502
+ )
503
+ }
504
+
505
+ async function setupIndexerAllocationWithDelegation (
491
506
tokensToDelegate : BigNumber ,
492
507
delegationParams : DelegationParameters ,
493
508
) {
509
+ const tokensToAllocate = toGRT ( '12500' )
510
+
511
+ // Setup
512
+ await epochManager . setEpochLength ( 10 )
513
+
494
514
// Transfer some funds from the curator, I don't want to mint new tokens
495
515
await grt . connect ( curator1 . signer ) . transfer ( delegator . address , tokensToDelegate )
496
516
await grt . connect ( delegator . signer ) . approve ( staking . address , tokensToDelegate )
497
517
498
- // Delegate
518
+ // Stake and set delegation parameters
519
+ await staking . connect ( indexer1 . signer ) . stake ( tokensToAllocate )
499
520
await staking
500
521
. connect ( indexer1 . signer )
501
522
. setDelegationParameters (
502
523
delegationParams . indexingRewardCut ,
503
524
delegationParams . queryFeeCut ,
504
525
delegationParams . cooldownBlocks ,
505
526
)
506
- await staking . connect ( delegator . signer ) . delegate ( indexer1 . address , tokensToDelegate )
507
- }
508
527
509
- async function setupIndexerAllocation ( ) {
510
- // Setup
511
- await epochManager . setEpochLength ( 10 )
528
+ // Delegate
529
+ await staking . connect ( delegator . signer ) . delegate ( indexer1 . address , tokensToDelegate )
512
530
513
531
// Update total signalled
514
532
const signalled1 = toGRT ( '1500' )
515
533
await curation . connect ( curator1 . signer ) . mint ( subgraphDeploymentID1 , signalled1 )
516
534
517
535
// Allocate
518
- const tokensToAllocate = toGRT ( '12500' )
519
- await staking . connect ( indexer1 . signer ) . stake ( tokensToAllocate )
520
536
await staking
521
537
. connect ( indexer1 . signer )
522
538
. allocate (
@@ -569,14 +585,13 @@ describe('Rewards', () => {
569
585
it ( 'should distribute rewards on closed allocation w/delegators' , async function ( ) {
570
586
// Setup
571
587
const delegationParams = {
572
- indexingRewardCut : toBN ( '50000 ' ) , // 5 %
588
+ indexingRewardCut : toBN ( '823000 ' ) , // 82.30 %
573
589
queryFeeCut : toBN ( '80000' ) , // 8%
574
590
cooldownBlocks : 5 ,
575
591
}
576
592
const tokensToDelegate = toGRT ( '2000' )
577
593
578
- await setupIndexerDelegation ( tokensToDelegate , delegationParams )
579
- await setupIndexerAllocation ( )
594
+ await setupIndexerAllocationWithDelegation ( tokensToDelegate , delegationParams )
580
595
581
596
// Jump
582
597
await advanceBlocks ( await epochManager . epochLength ( ) )
@@ -597,7 +612,7 @@ describe('Rewards', () => {
597
612
// Check that rewards are put into indexer stake (only indexer cut)
598
613
// Check that rewards are put into delegators pool accordingly
599
614
// NOTE: calculated manually on a spreadsheet
600
- const expectedIndexingRewards = toGRT ( '1471954234 ' )
615
+ const expectedIndexingRewards = toGRT ( '1454109066 ' )
601
616
// Calculate delegators cut
602
617
const indexerRewards = delegationParams . indexingRewardCut
603
618
. mul ( expectedIndexingRewards )
0 commit comments