@@ -345,11 +345,15 @@ describe('Staking:Allocation', () => {
345
345
} )
346
346
347
347
it ( 'reject allocate if no tokens staked' , async function ( ) {
348
- const tokensOverCapacity = tokensToStake . add ( toBN ( '1' ) )
349
- const tx = allocate ( tokensOverCapacity )
348
+ const tx = allocate ( toBN ( '1' ) )
350
349
await expect ( tx ) . revertedWith ( '!capacity' )
351
350
} )
352
351
352
+ it ( 'reject allocate zero tokens if no tokens staked' , async function ( ) {
353
+ const tx = allocate ( toBN ( '0' ) )
354
+ await expect ( tx ) . revertedWith ( '!stake' )
355
+ } )
356
+
353
357
context ( '> when staked' , function ( ) {
354
358
beforeEach ( async function ( ) {
355
359
await staking . connect ( indexer . signer ) . stake ( tokensToStake )
@@ -563,185 +567,200 @@ describe('Staking:Allocation', () => {
563
567
beforeEach ( async function ( ) {
564
568
// Stake and allocate
565
569
await staking . connect ( indexer . signer ) . stake ( tokensToStake )
566
- await allocate ( tokensToAllocate )
567
- } )
568
-
569
- it ( 'reject close a non-existing allocation' , async function ( ) {
570
- const invalidAllocationID = randomHexBytes ( 20 )
571
- const tx = staking . connect ( indexer . signer ) . closeAllocation ( invalidAllocationID , poi )
572
- await expect ( tx ) . revertedWith ( '!active' )
573
570
} )
574
571
575
- it ( 'reject close before at least one epoch has passed' , async function ( ) {
576
- const tx = staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
577
- await expect ( tx ) . revertedWith ( '<epochs' )
578
- } )
579
-
580
- it ( 'reject close if not the owner of allocation' , async function ( ) {
581
- // Move at least one epoch to be able to close
582
- await advanceToNextEpoch ( epochManager )
572
+ for ( const tokensToAllocate of [ toBN ( 100 ) , toBN ( 0 ) ] ) {
573
+ context ( `> with ${ tokensToAllocate } allocated tokens` , async function ( ) {
574
+ beforeEach ( async function ( ) {
575
+ await allocate ( tokensToAllocate )
576
+ } )
583
577
584
- // Close allocation
585
- const tx = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
586
- await expect ( tx ) . revertedWith ( '!auth' )
587
- } )
578
+ it ( 'reject close a non-existing allocation' , async function ( ) {
579
+ const invalidAllocationID = randomHexBytes ( 20 )
580
+ const tx = staking . connect ( indexer . signer ) . closeAllocation ( invalidAllocationID , poi )
581
+ await expect ( tx ) . revertedWith ( '!active' )
582
+ } )
588
583
589
- it ( 'reject close if allocation is already closed' , async function ( ) {
590
- // Move at least one epoch to be able to close
591
- await advanceToNextEpoch ( epochManager )
584
+ it ( 'reject close before at least one epoch has passed' , async function ( ) {
585
+ const tx = staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
586
+ await expect ( tx ) . revertedWith ( '<epochs' )
587
+ } )
592
588
593
- // First closing
594
- await staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
589
+ it ( 'reject close if not the owner of allocation' , async function ( ) {
590
+ // Move at least one epoch to be able to close
591
+ await advanceToNextEpoch ( epochManager )
595
592
596
- // Second closing
597
- const tx = staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
598
- await expect ( tx ) . revertedWith ( '!active ' )
599
- } )
593
+ // Close allocation
594
+ const tx = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
595
+ await expect ( tx ) . revertedWith ( '!auth ' )
596
+ } )
600
597
601
- it ( 'should close an allocation' , async function ( ) {
602
- // Before state
603
- const beforeStake = await staking . stakes ( indexer . address )
604
- const beforeAlloc = await staking . getAllocation ( allocationID )
605
- const beforeRebatePool = await staking . rebates (
606
- ( await epochManager . currentEpoch ( ) ) . add ( toBN ( '2' ) ) ,
607
- )
598
+ it ( 'reject close if allocation is already closed' , async function ( ) {
599
+ // Move at least one epoch to be able to close
600
+ await advanceToNextEpoch ( epochManager )
608
601
609
- // Move at least one epoch to be able to close
610
- await advanceToNextEpoch ( epochManager )
611
- await advanceToNextEpoch ( epochManager )
602
+ // First closing
603
+ await staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
612
604
613
- // Calculations
614
- const currentEpoch = await epochManager . currentEpoch ( )
615
- const epochs = currentEpoch . sub ( beforeAlloc . createdAtEpoch )
616
- const maxAllocationEpochs = toBN ( await staking . maxAllocationEpochs ( ) )
617
- const effectiveAllocation = calculateEffectiveAllocation (
618
- beforeAlloc . tokens ,
619
- epochs ,
620
- maxAllocationEpochs ,
621
- )
605
+ // Second closing
606
+ const tx = staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
607
+ await expect ( tx ) . revertedWith ( '!active' )
608
+ } )
622
609
623
- // Close allocation
624
- const tx = staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
625
- await expect ( tx )
626
- . emit ( staking , 'AllocationClosed' )
627
- . withArgs (
628
- indexer . address ,
629
- subgraphDeploymentID ,
630
- currentEpoch ,
631
- beforeAlloc . tokens ,
632
- allocationID ,
633
- effectiveAllocation ,
634
- indexer . address ,
635
- poi ,
636
- false ,
637
- )
610
+ it ( 'should close an allocation' , async function ( ) {
611
+ // Before state
612
+ const beforeStake = await staking . stakes ( indexer . address )
613
+ const beforeAlloc = await staking . getAllocation ( allocationID )
614
+ const beforeRebatePool = await staking . rebates (
615
+ ( await epochManager . currentEpoch ( ) ) . add ( toBN ( '2' ) ) ,
616
+ )
638
617
639
- // After state
640
- const afterStake = await staking . stakes ( indexer . address )
641
- const afterAlloc = await staking . getAllocation ( allocationID )
642
- const afterRebatePool = await staking . rebates ( currentEpoch )
643
-
644
- // Stake updated
645
- expect ( afterStake . tokensAllocated ) . eq ( beforeStake . tokensAllocated . sub ( beforeAlloc . tokens ) )
646
- // Allocation updated
647
- expect ( afterAlloc . closedAtEpoch ) . eq ( currentEpoch )
648
- expect ( afterAlloc . effectiveAllocation ) . eq ( effectiveAllocation )
649
- // Rebate updated
650
- expect ( afterRebatePool . fees ) . eq ( beforeRebatePool . fees . add ( beforeAlloc . collectedFees ) )
651
- expect ( afterRebatePool . effectiveAllocatedStake ) . eq (
652
- beforeRebatePool . effectiveAllocatedStake . add ( effectiveAllocation ) ,
653
- )
654
- expect ( afterRebatePool . unclaimedAllocationsCount ) . eq (
655
- beforeRebatePool . unclaimedAllocationsCount + 1 ,
656
- )
657
- } )
618
+ // Move at least one epoch to be able to close
619
+ await advanceToNextEpoch ( epochManager )
620
+ await advanceToNextEpoch ( epochManager )
621
+
622
+ // Calculations
623
+ const currentEpoch = await epochManager . currentEpoch ( )
624
+ const epochs = currentEpoch . sub ( beforeAlloc . createdAtEpoch )
625
+ const maxAllocationEpochs = toBN ( await staking . maxAllocationEpochs ( ) )
626
+ const effectiveAllocation = calculateEffectiveAllocation (
627
+ beforeAlloc . tokens ,
628
+ epochs ,
629
+ maxAllocationEpochs ,
630
+ )
658
631
659
- it ( 'should close an allocation (by operator)' , async function ( ) {
660
- // Move at least one epoch to be able to close
661
- await advanceToNextEpoch ( epochManager )
662
- await advanceToNextEpoch ( epochManager )
632
+ // Close allocation
633
+ const tx = staking . connect ( indexer . signer ) . closeAllocation ( allocationID , poi )
634
+ await expect ( tx )
635
+ . emit ( staking , 'AllocationClosed' )
636
+ . withArgs (
637
+ indexer . address ,
638
+ subgraphDeploymentID ,
639
+ currentEpoch ,
640
+ beforeAlloc . tokens ,
641
+ allocationID ,
642
+ effectiveAllocation ,
643
+ indexer . address ,
644
+ poi ,
645
+ false ,
646
+ )
663
647
664
- // Reject to close if the address is not operator
665
- const tx1 = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
666
- await expect ( tx1 ) . revertedWith ( '!auth' )
648
+ // After state
649
+ const afterStake = await staking . stakes ( indexer . address )
650
+ const afterAlloc = await staking . getAllocation ( allocationID )
651
+ const afterRebatePool = await staking . rebates ( currentEpoch )
652
+
653
+ // Stake updated
654
+ expect ( afterStake . tokensAllocated ) . eq ( beforeStake . tokensAllocated . sub ( beforeAlloc . tokens ) )
655
+ // Allocation updated
656
+ expect ( afterAlloc . closedAtEpoch ) . eq ( currentEpoch )
657
+ expect ( afterAlloc . effectiveAllocation ) . eq ( effectiveAllocation )
658
+ // Rebate updated
659
+ expect ( afterRebatePool . fees ) . eq ( beforeRebatePool . fees . add ( beforeAlloc . collectedFees ) )
660
+ expect ( afterRebatePool . effectiveAllocatedStake ) . eq (
661
+ beforeRebatePool . effectiveAllocatedStake . add ( effectiveAllocation ) ,
662
+ )
663
+ expect ( afterRebatePool . unclaimedAllocationsCount ) . eq (
664
+ beforeRebatePool . unclaimedAllocationsCount + 1 ,
665
+ )
666
+ } )
667
667
668
- // Should close if given operator auth
669
- await staking . connect ( indexer . signer ) . setOperator ( me . address , true )
670
- await staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
671
- } )
668
+ it ( 'should close an allocation (by operator)' , async function ( ) {
669
+ // Move at least one epoch to be able to close
670
+ await advanceToNextEpoch ( epochManager )
671
+ await advanceToNextEpoch ( epochManager )
672
672
673
- it ( 'should close an allocation (by public)' , async function ( ) {
674
- // Reject to close if public address and under max allocation epochs
675
- const tx1 = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
676
- await expect ( tx1 ) . revertedWith ( '<epochs' )
677
-
678
- // Move max allocation epochs to close by delegator
679
- const maxAllocationEpochs = await staking . maxAllocationEpochs ( )
680
- await advanceEpochs ( epochManager , maxAllocationEpochs )
681
-
682
- // Calculations
683
- const beforeAlloc = await staking . getAllocation ( allocationID )
684
- const currentEpoch = await epochManager . currentEpoch ( )
685
- const epochs = currentEpoch . sub ( beforeAlloc . createdAtEpoch )
686
- const effectiveAllocation = calculateEffectiveAllocation (
687
- beforeAlloc . tokens ,
688
- epochs ,
689
- toBN ( maxAllocationEpochs ) ,
690
- )
673
+ // Reject to close if the address is not operator
674
+ const tx1 = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
675
+ await expect ( tx1 ) . revertedWith ( '!auth' )
691
676
692
- // Setup
693
- await grt . connect ( governor . signer ) . mint ( me . address , toGRT ( '1' ) )
694
- await grt . connect ( me . signer ) . approve ( staking . address , toGRT ( '1' ) )
677
+ // Should close if given operator auth
678
+ await staking . connect ( indexer . signer ) . setOperator ( me . address , true )
679
+ await staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
680
+ } )
695
681
696
- // Should close by public
697
- const tx = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
698
- await expect ( tx )
699
- . emit ( staking , 'AllocationClosed' )
700
- . withArgs (
701
- indexer . address ,
702
- subgraphDeploymentID ,
703
- currentEpoch ,
704
- beforeAlloc . tokens ,
705
- allocationID ,
706
- effectiveAllocation ,
707
- me . address ,
708
- poi ,
709
- true ,
710
- )
711
- } )
682
+ it ( 'should close an allocation (by public) only if allocation is non-zero' , async function ( ) {
683
+ // Reject to close if public address and under max allocation epochs
684
+ const tx1 = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
685
+ await expect ( tx1 ) . revertedWith ( '<epochs' )
686
+
687
+ // Move max allocation epochs to close by delegator
688
+ const maxAllocationEpochs = await staking . maxAllocationEpochs ( )
689
+ await advanceEpochs ( epochManager , maxAllocationEpochs )
690
+
691
+ // Closing should only be possible if allocated tokens > 0
692
+ const alloc = await staking . getAllocation ( allocationID )
693
+ if ( alloc . tokens . gt ( 0 ) ) {
694
+ // Calculations
695
+ const beforeAlloc = await staking . getAllocation ( allocationID )
696
+ const currentEpoch = await epochManager . currentEpoch ( )
697
+ const epochs = currentEpoch . sub ( beforeAlloc . createdAtEpoch )
698
+ const effectiveAllocation = calculateEffectiveAllocation (
699
+ beforeAlloc . tokens ,
700
+ epochs ,
701
+ toBN ( maxAllocationEpochs ) ,
702
+ )
712
703
713
- it ( 'should close many allocations in batch' , async function ( ) {
714
- // Setup a second allocation
715
- await staking . connect ( indexer . signer ) . stake ( tokensToAllocate )
716
- const channelKey2 = deriveChannelKey ( )
717
- const allocationID2 = channelKey2 . address
718
- await staking
719
- . connect ( indexer . signer )
720
- . allocate (
721
- subgraphDeploymentID ,
722
- tokensToAllocate ,
723
- allocationID2 ,
724
- metadata ,
725
- await channelKey2 . generateProof ( indexer . address ) ,
726
- )
704
+ // Setup
705
+ await grt . connect ( governor . signer ) . mint ( me . address , toGRT ( '1' ) )
706
+ await grt . connect ( me . signer ) . approve ( staking . address , toGRT ( '1' ) )
707
+
708
+ // Should close by public
709
+ const tx = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
710
+ await expect ( tx )
711
+ . emit ( staking , 'AllocationClosed' )
712
+ . withArgs (
713
+ indexer . address ,
714
+ subgraphDeploymentID ,
715
+ currentEpoch ,
716
+ beforeAlloc . tokens ,
717
+ allocationID ,
718
+ effectiveAllocation ,
719
+ me . address ,
720
+ poi ,
721
+ true ,
722
+ )
723
+ } else {
724
+ // closing by the public on a zero allocation is not authorized
725
+ const tx = staking . connect ( me . signer ) . closeAllocation ( allocationID , poi )
726
+ await expect ( tx ) . revertedWith ( '!auth' )
727
+ }
728
+ } )
727
729
728
- // Move at least one epoch to be able to close
729
- await advanceToNextEpoch ( epochManager )
730
- await advanceToNextEpoch ( epochManager )
730
+ it ( 'should close many allocations in batch' , async function ( ) {
731
+ // Setup a second allocation
732
+ await staking . connect ( indexer . signer ) . stake ( tokensToStake )
733
+ const channelKey2 = deriveChannelKey ( )
734
+ const allocationID2 = channelKey2 . address
735
+ await staking
736
+ . connect ( indexer . signer )
737
+ . allocate (
738
+ subgraphDeploymentID ,
739
+ tokensToAllocate ,
740
+ allocationID2 ,
741
+ metadata ,
742
+ await channelKey2 . generateProof ( indexer . address ) ,
743
+ )
731
744
732
- // Close multiple allocations in one tx
733
- const requests = [
734
- {
735
- allocationID : allocationID ,
736
- poi : poi ,
737
- } ,
738
- {
739
- allocationID : allocationID2 ,
740
- poi : poi ,
741
- } ,
742
- ]
743
- await staking . connect ( indexer . signer ) . closeAllocationMany ( requests )
744
- } )
745
+ // Move at least one epoch to be able to close
746
+ await advanceToNextEpoch ( epochManager )
747
+ await advanceToNextEpoch ( epochManager )
748
+
749
+ // Close multiple allocations in one tx
750
+ const requests = [
751
+ {
752
+ allocationID : allocationID ,
753
+ poi : poi ,
754
+ } ,
755
+ {
756
+ allocationID : allocationID2 ,
757
+ poi : poi ,
758
+ } ,
759
+ ]
760
+ await staking . connect ( indexer . signer ) . closeAllocationMany ( requests )
761
+ } )
762
+ } )
763
+ }
745
764
} )
746
765
747
766
describe ( 'closeAndAllocate' , function ( ) {
0 commit comments