Update tests to start at epoch 1

This commit is contained in:
Amir Bandeali
2019-10-19 18:13:44 -07:00
parent 1a409c3731
commit 1885957bd3
6 changed files with 502 additions and 499 deletions

View File

@@ -32,391 +32,94 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
});
describe('Tracking Cumulative Rewards (CR)', () => {
it('pool created at epoch 0', async () => {
it('pool created at epoch 1', async () => {
await simulation.runTestAsync([], [TestAction.CreatePool], []);
});
it('pool created in epoch >0', async () => {
it('pool created in epoch >1', async () => {
await simulation.runTestAsync([TestAction.Finalize], [TestAction.CreatePool], []);
});
it('delegating in the same epoch pool is created', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
// Creates CR for epoch 1
TestAction.CreatePool,
],
[
// Updates CR for epoch 0
// Creates CR for epoch 1
// Updates CR for epoch 1
// Creates CR for epoch 2
TestAction.Delegate,
],
[],
[{ event: 'SetCumulativeReward', epoch: 1 }],
);
});
it('re-delegating in the same epoch', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
// Creates CR for epoch 1
TestAction.CreatePool,
],
[
// Updates CR for epoch 0
// Updates CR for epoch 1
TestAction.Delegate,
// Updates CR for epoch 0
TestAction.Delegate,
],
[],
);
});
it('delegating in new epoch', async () => {
// since there was no delegation in epoch 0 there is no longer a dependency on the CR for epoch 0
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Moves to epoch 1
TestAction.Finalize,
],
[
// Creates a CR for epoch 1
// Sets MRCR to epoch 1
// Unsets the CR for epoch 0
// Updates CR for epoch 1
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 1 }],
);
});
it('delegating in new epoch', async () => {
// since there was no delegation in epoch 1 there is no longer a dependency on the CR for epoch 1
await simulation.runTestAsync(
[
// Creates CR for epoch 1
TestAction.CreatePool,
// Moves to epoch 2
TestAction.Finalize,
],
[
// Creates a CR for epoch 2
// Sets MRCR to epoch 2
// Unsets the CR for epoch 1
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 2 }],
);
});
it('re-delegating in a new epoch', async () => {
await simulation.runTestAsync(
[
// Creates CR in epoch 0
// Creates CR in epoch 1
TestAction.CreatePool,
// Updates CR for epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Moves to epoch 1
TestAction.Finalize,
],
[
// Updates CR for epoch 1
// Sets MRCR to epoch 1
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 1 }],
);
});
it('delegating in epoch 1 then again in epoch 2', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Moves to epoch 1
TestAction.Finalize,
// Creates CR for epoch 1
// Sets MRCR to epoch 1
TestAction.Delegate,
// Move to epoch 2
TestAction.Finalize,
],
[
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3
// Clears CR for epoch 1
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 1 then undelegate in epoch 2', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Moves to epoch 1
TestAction.Finalize,
// Creates CR for epoch 1
// Sets MRCR to epoch 0
// Clears CR for epoch 0
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
],
[
// Update CR for epoch 2
// Set MRCR to epoch 2
// Clear CR for epoch 1
TestAction.Undelegate,
],
[{ event: 'SetCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 0 and epoch 1, then undelegate half in epoch 2', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 0
TestAction.CreatePool,
// Updates CR for epoch 0
// Sets MRCR to epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Moves to epoch 1
TestAction.Finalize,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
// Clears CR for epoch 0
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
],
[
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3 (because there will still be stake)
// Clears CR for epoch 1
TestAction.Undelegate,
],
[{ event: 'SetCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 1 and 2 then again in 3', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Updates CR for epoch 0
// Sets MRCR to epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Moves to epoch 1
TestAction.Finalize,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
// Clears CR for epoch 0
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
],
[
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3
// Clears CR for epoch 1
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 0, earn reward in epoch 1', async () => {
it('delegating in epoch 2 then again in epoch 3', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 0
TestAction.CreatePool,
// Updates CR for epoch 0
// Sets MRCR to epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Moves to epoch 1
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
],
[
TestAction.CreatePool,
// Moves to epoch 2
TestAction.Finalize,
// Creates CR for epoch 2
// Sets MRCR to epoch 2
TestAction.Finalize,
],
[{ event: 'SetCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 0, epoch 2, earn reward in epoch 3, then delegate', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 0
TestAction.CreatePool,
// Updates CR for epoch 0
// Sets MRCR to epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Moves to epoch 1
TestAction.Finalize,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
// Clears CR for epoch 0
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 3
// Creates CR for epoch 3
// Sets MRCR to epoch 3
// Move to epoch 3
TestAction.Finalize,
],
[
// Updates CR for epoch 3
// Creates CR for epoch 4
// Clears CR for epoch 1
// Clears CR for epoch 2
TestAction.Delegate,
],
[],
);
});
it('delegate in epoch 0 and 1, earn reward in epoch 3, then undelegate half', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 0
TestAction.CreatePool,
// Updates CR for epoch 0
// Sets MRCR to epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Moves to epoch 1
TestAction.Finalize,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
// Clears CR for epoch 0
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 3
// Creates CR for epoch 3
// Sets MRCR to epoch 3
TestAction.Finalize,
],
[
// Updates CR for epoch 3
// Creates CR for epoch 4 (because there is still stake remaming)
// Clears CR for epoch 1
// Clears CR for epoch 2
TestAction.Undelegate,
],
[],
);
});
it('delegate in epoch 1, 2, earn rewards in epoch 3, skip to epoch 4, then delegate', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 0
TestAction.CreatePool,
// Updates CR for epoch 0
// Sets MRCR to epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Moves to epoch 1
TestAction.Finalize,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
// Clears CR for epoch 0
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 3
// Creates CR for epoch 3
// Sets MRCR to epoch 3
TestAction.Finalize,
// Moves to epoch 4
TestAction.Finalize,
],
[
// Creates CR for epoch 4
// Sets MRCR to epoch 4
// Clears CR for epoch 3
// Creates CR for epoch 5
// Clears CR for epoch 1
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 4 }],
);
});
it('earn reward in epoch 1 with no stake, then delegate', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Credit pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 1
// That's it, because there's no active pools.
TestAction.Finalize,
],
[
// Updates CR to epoch 1
// Sets MRCR to epoch 1
// Clears CR for epoch 0
// Creates CR for epoch 2
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 1 }],
);
});
it('delegate in epoch 1, 3, then delegate in epoch 4', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Moves to epoch 1
TestAction.Finalize,
// Creates CR for epoch 1
// Sets MRCR to epoch 0
// Clears CR for epoch 0
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Moves to epoch 3
TestAction.Finalize,
// Creates CR for epoch 3
// Sets MRCR to epoch 3
// Clears CR for epoch 1
// Creates CR for epoch 4
// Clears CR for epoch 2
TestAction.Delegate,
// Moves to epoch 4
TestAction.Finalize,
],
[
// Updates CR for epoch 4
// Sets MRCR to epoch 4
// Clears CR for epoch 3
// Creates CR for epoch 5
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 4 }],
);
});
it('delegate in epoch 1, then epoch 3', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Moves to epoch 1
TestAction.Finalize,
// Creates CR for epoch 1
// Sets MRCR to epoch 0
// Clears CR for epoch 0
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Moves to epoch 3
TestAction.Finalize,
],
[
// Creates CR for epoch 3
// Sets MRCR to epoch 3
// Clears CR for epoch 1
// Creates CR for epoch 4
// Clears CR for epoch 2
TestAction.Delegate,
@@ -424,6 +127,303 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
[{ event: 'SetCumulativeReward', epoch: 3 }],
);
});
it('delegate in epoch 2 then undelegate in epoch 3', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 1
TestAction.CreatePool,
// Moves to epoch 2
TestAction.Finalize,
// Creates CR for epoch 2
// Sets MRCR to epoch 1
// Clears CR for epoch 1
// Creates CR for epoch 3
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
],
[
// Update CR for epoch 3
// Set MRCR to epoch 3
// Clear CR for epoch 2
TestAction.Undelegate,
],
[{ event: 'SetCumulativeReward', epoch: 3 }],
);
});
it('delegate in epoch 1 and epoch 2, then undelegate half in epoch 3', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 1
TestAction.CreatePool,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3
// Clears CR for epoch 1
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
],
[
// Updates CR for epoch 3
// Sets MRCR to epoch 3
// Creates CR for epoch 4 (because there will still be stake)
// Clears CR for epoch 2
TestAction.Undelegate,
],
[{ event: 'SetCumulativeReward', epoch: 3 }],
);
});
it('delegate in epoch 2 and 3 then again in 3', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 1
TestAction.CreatePool,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3
// Clears CR for epoch 1
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
],
[
// Updates CR for epoch 3
// Sets MRCR to epoch 3
// Creates CR for epoch 4
// Clears CR for epoch 2
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 3 }],
);
});
it('delegate in epoch 1, earn reward in epoch 2', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 1
TestAction.CreatePool,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
],
[
// Moves to epoch 3
// Creates CR for epoch 3
// Sets MRCR to epoch 3
TestAction.Finalize,
],
[{ event: 'SetCumulativeReward', epoch: 3 }],
);
});
it('delegate in epoch 1, epoch 3, earn reward in epoch 4, then delegate', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 1
TestAction.CreatePool,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3
// Clears CR for epoch 1
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 4
// Creates CR for epoch 4
// Sets MRCR to epoch 4
TestAction.Finalize,
],
[
// Updates CR for epoch 4
// Creates CR for epoch 5
// Clears CR for epoch 2
// Clears CR for epoch 3
TestAction.Delegate,
],
[],
);
});
it('delegate in epoch 1 and 2, earn reward in epoch 4, then undelegate half', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 1
TestAction.CreatePool,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3
// Clears CR for epoch 1
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 4
// Creates CR for epoch 4
// Sets MRCR to epoch 4
TestAction.Finalize,
],
[
// Updates CR for epoch 4
// Creates CR for epoch 5 (because there is still stake remaming)
// Clears CR for epoch 2
// Clears CR for epoch 3
TestAction.Undelegate,
],
[],
);
});
it('delegate in epoch 2, 3, earn rewards in epoch 4, skip to epoch 5, then delegate', async () => {
await simulation.runTestAsync(
[
// Create CR for epoch 1
TestAction.CreatePool,
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
TestAction.Delegate,
// Moves to epoch 2
TestAction.Finalize,
// Updates CR for epoch 2
// Sets MRCR to epoch 2
// Creates CR for epoch 3
// Clears CR for epoch 1
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
// Credits pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 4
// Creates CR for epoch 4
// Sets MRCR to epoch 4
TestAction.Finalize,
// Moves to epoch 5
TestAction.Finalize,
],
[
// Creates CR for epoch 5
// Sets MRCR to epoch 5
// Clears CR for epoch 4
// Creates CR for epoch 6
// Clears CR for epoch 2
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 5 }],
);
});
it('earn reward in epoch 2 with no stake, then delegate', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 1
TestAction.CreatePool,
// Credit pool with rewards
TestAction.PayProtocolFee,
// Moves to epoch 2
// That's it, because there's no active pools.
TestAction.Finalize,
],
[
// Updates CR to epoch 2
// Sets MRCR to epoch 2
// Clears CR for epoch 1
// Creates CR for epoch 3
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 2, 4, then delegate in epoch 5', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 1
TestAction.CreatePool,
// Moves to epoch 2
TestAction.Finalize,
// Creates CR for epoch 2
// Sets MRCR to epoch 1
// Clears CR for epoch 1
// Creates CR for epoch 3
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
// Moves to epoch 4
TestAction.Finalize,
// Creates CR for epoch 4
// Sets MRCR to epoch 4
// Clears CR for epoch 2
// Creates CR for epoch 5
// Clears CR for epoch 3
TestAction.Delegate,
// Moves to epoch 5
TestAction.Finalize,
],
[
// Updates CR for epoch 5
// Sets MRCR to epoch 5
// Clears CR for epoch 4
// Creates CR for epoch 6
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 5 }],
);
});
it('delegate in epoch 2, then epoch 4', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 1
TestAction.CreatePool,
// Moves to epoch 2
TestAction.Finalize,
// Creates CR for epoch 2
// Sets MRCR to epoch 1
// Clears CR for epoch 1
// Creates CR for epoch 3
TestAction.Delegate,
// Moves to epoch 3
TestAction.Finalize,
// Moves to epoch 4
TestAction.Finalize,
],
[
// Creates CR for epoch 4
// Sets MRCR to epoch 4
// Clears CR for epoch 2
// Creates CR for epoch 5
// Clears CR for epoch 3
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 4 }],
);
});
});
});
// tslint:enable:no-unnecessary-type-assertion

View File

@@ -242,7 +242,7 @@ blockchainTests.resets('Testing Rewards', env => {
});
});
it('Should split pool reward between delegators, when they join in different epochs', async () => {
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
const stakeAmounts = [toBaseUnitAmount(4), toBaseUnitAmount(6)];
const totalStakeAmount = toBaseUnitAmount(10);
@@ -256,7 +256,7 @@ blockchainTests.resets('Testing Rewards', env => {
// skip epoch, so staker can start earning rewards
await payProtocolFeeAndFinalize();
// second staker delegates (epoch 1)
// second staker delegates (epoch 2)
await stakers[1].stakeAsync(stakeAmounts[1]);
await stakers[1].moveStakeAsync(
new StakeInfo(StakeStatus.Undelegated),
@@ -281,11 +281,11 @@ blockchainTests.resets('Testing Rewards', env => {
it('Should give pool reward to delegators only for the epoch during which they delegated', async () => {
const stakeAmounts = [toBaseUnitAmount(4), toBaseUnitAmount(6)];
const totalStakeAmount = toBaseUnitAmount(10);
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
await stakers[0].stakeWithPoolAsync(poolId, stakeAmounts[0]);
// skip epoch, so first staker can start earning rewards
await payProtocolFeeAndFinalize();
// second staker delegates (epoch 1)
// second staker delegates (epoch 2)
await stakers[1].stakeWithPoolAsync(poolId, stakeAmounts[1]);
// only the first staker will get this reward
const rewardForOnlyFirstDelegator = toBaseUnitAmount(10);
@@ -321,11 +321,11 @@ blockchainTests.resets('Testing Rewards', env => {
const totalSharedRewards = new BigNumber(totalSharedRewardsAsNumber);
const stakeAmounts = [toBaseUnitAmount(4), toBaseUnitAmount(6)];
const totalStakeAmount = toBaseUnitAmount(10);
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
await stakers[0].stakeWithPoolAsync(poolId, stakeAmounts[0]);
// skip epoch, so first staker can start earning rewards
await payProtocolFeeAndFinalize();
// second staker delegates (epoch 1)
// second staker delegates (epoch 2)
await stakers[1].stakeWithPoolAsync(poolId, stakeAmounts[1]);
// only the first staker will get this reward
await payProtocolFeeAndFinalize(rewardForOnlyFirstDelegator);
@@ -345,7 +345,7 @@ blockchainTests.resets('Testing Rewards', env => {
});
it('Should withdraw existing rewards when undelegating stake', async () => {
const stakeAmount = toBaseUnitAmount(4);
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
await stakers[0].stakeWithPoolAsync(poolId, stakeAmount);
// skip epoch, so first staker can start earning rewards
await payProtocolFeeAndFinalize();
@@ -366,7 +366,7 @@ blockchainTests.resets('Testing Rewards', env => {
});
it('Should withdraw existing rewards correctly when delegating more stake', async () => {
const stakeAmount = toBaseUnitAmount(4);
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
await stakers[0].stakeWithPoolAsync(poolId, stakeAmount);
// skip epoch, so first staker can start earning rewards
await payProtocolFeeAndFinalize();
@@ -394,11 +394,11 @@ blockchainTests.resets('Testing Rewards', env => {
const totalRewardsAfterAddingMoreStake = BigNumber.sum(...rewardsAfterAddingMoreStake);
const stakeAmounts = [toBaseUnitAmount(4), toBaseUnitAmount(6)];
const totalStake = BigNumber.sum(...stakeAmounts);
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
await stakers[0].stakeWithPoolAsync(poolId, stakeAmounts[0]);
// skip epoch, so first staker can start earning rewards
await payProtocolFeeAndFinalize();
// second staker delegates (epoch 1)
// second staker delegates (epoch 2)
await stakers[1].stakeWithPoolAsync(poolId, stakeAmounts[1]);
// only the first staker will get this reward
await payProtocolFeeAndFinalize(rewardBeforeAddingMoreStake);
@@ -423,7 +423,7 @@ blockchainTests.resets('Testing Rewards', env => {
});
});
it('Should stop collecting rewards after undelegating', async () => {
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
const rewardForDelegator = toBaseUnitAmount(10);
const rewardNotForDelegator = toBaseUnitAmount(7);
const stakeAmount = toBaseUnitAmount(4);
@@ -452,7 +452,7 @@ blockchainTests.resets('Testing Rewards', env => {
});
});
it('Should stop collecting rewards after undelegating, after several epochs', async () => {
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
const rewardForDelegator = toBaseUnitAmount(10);
const rewardsNotForDelegator = [
toBaseUnitAmount(20),
@@ -487,7 +487,7 @@ blockchainTests.resets('Testing Rewards', env => {
});
});
it('Should collect fees correctly when leaving and returning to a pool', async () => {
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
const rewardsForDelegator = [toBaseUnitAmount(10), toBaseUnitAmount(15)];
const rewardNotForDelegator = toBaseUnitAmount(7);
const stakeAmount = toBaseUnitAmount(4);
@@ -525,7 +525,7 @@ blockchainTests.resets('Testing Rewards', env => {
it('Should collect fees correctly when re-delegating after un-delegating', async () => {
// Note - there are two ranges over which payouts are computed (see _computeRewardBalanceOfDelegator).
// This triggers the first range (rewards for `delegatedStake.currentEpoch`), but not the second.
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
const rewardForDelegator = toBaseUnitAmount(10);
const stakeAmount = toBaseUnitAmount(4);
await stakers[0].stakeAsync(stakeAmount);
@@ -560,7 +560,7 @@ blockchainTests.resets('Testing Rewards', env => {
});
});
it('Should withdraw delegator rewards when calling `withdrawDelegatorRewards`', async () => {
// first staker delegates (epoch 0)
// first staker delegates (epoch 1)
const rewardForDelegator = toBaseUnitAmount(10);
const stakeAmount = toBaseUnitAmount(4);
await stakers[0].stakeAsync(stakeAmount);

View File

@@ -73,7 +73,7 @@ blockchainTests.resets('Stake Statuses', env => {
});
describe('Move Stake', () => {
it("should be able to rebalance next epoch's stake", async () => {
// epoch 1
// epoch 2
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(
@@ -81,7 +81,7 @@ blockchainTests.resets('Stake Statuses', env => {
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// still epoch 1 ~ should be able to move stake again
// still epoch 2 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Undelegated),
@@ -89,7 +89,7 @@ blockchainTests.resets('Stake Statuses', env => {
);
});
it("should be able to reassign next epoch's stake", async () => {
// epoch 1
// epoch 2
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(
@@ -97,7 +97,7 @@ blockchainTests.resets('Stake Statuses', env => {
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// still epoch 1 ~ should be able to move stake again
// still epoch 2 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Delegated, poolIds[1]),
@@ -105,7 +105,7 @@ blockchainTests.resets('Stake Statuses', env => {
);
});
it('should fail to move the same stake more than once', async () => {
// epoch 1
// epoch 2
const amount = toBaseUnitAmount(10);
await staker.stakeAsync(amount);
await staker.moveStakeAsync(
@@ -124,14 +124,14 @@ blockchainTests.resets('Stake Statuses', env => {
});
describe('Stake and Move', () => {
it("should be able to rebalance next epoch's stake", async () => {
// epoch 1
// epoch 2
const amount = toBaseUnitAmount(10);
await staker.stakeAndMoveAsync(
new StakeInfo(StakeStatus.Undelegated),
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
amount,
);
// still epoch 1 ~ should be able to move stake again
// still epoch 2 ~ should be able to move stake again
await staker.moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolIds[0]),
new StakeInfo(StakeStatus.Undelegated),
@@ -139,7 +139,7 @@ blockchainTests.resets('Stake Statuses', env => {
);
});
it('should fail to move the same stake more than once', async () => {
// epoch 1
// epoch 2
const amount = toBaseUnitAmount(10);
await staker.stakeAndMoveAsync(
new StakeInfo(StakeStatus.Undelegated),

View File

@@ -226,13 +226,13 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
}
describe('computeRewardBalanceOfOperator()', () => {
it('nothing in epoch 0', async () => {
it('nothing in epoch 1', async () => {
const { poolId } = await rewardPoolAsync();
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
expect(operatorReward).to.bignumber.eq(0);
});
it('nothing in epoch 1', async () => {
it('nothing in epoch 2', async () => {
await advanceEpochAsync();
const { poolId } = await rewardPoolAsync();
const operatorReward = await getOperatorRewardBalanceAsync(poolId);
@@ -282,77 +282,77 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
});
describe('computeRewardBalanceOfDelegator()', () => {
it('nothing in epoch 0 for delegator with no stake', async () => {
const { poolId } = await rewardPoolAsync();
const delegator = randomAddress();
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0);
});
it('nothing in epoch 1 for delegator with no stake', async () => {
await advanceEpochAsync(); // epoch 1
const { poolId } = await rewardPoolAsync();
const delegator = randomAddress();
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0);
});
it('nothing in epoch 0 for delegator staked in epoch 0', async () => {
it('nothing in epoch 2 for delegator with no stake', async () => {
await advanceEpochAsync(); // epoch 2
const { poolId } = await rewardPoolAsync();
// Assign active stake to pool in epoch 0, which is usuaslly not
const delegator = randomAddress();
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0);
});
it('nothing in epoch 1 for delegator staked in epoch 1', async () => {
const { poolId } = await rewardPoolAsync();
// Assign active stake to pool in epoch 1, which is usuaslly not
// possible due to delegating delays.
const { delegator } = await delegateStakeNowAsync(poolId);
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0);
});
it('nothing in epoch 1 for delegator delegating in epoch 1', async () => {
await advanceEpochAsync(); // epoch 1
it('nothing in epoch 2 for delegator delegating in epoch 2', async () => {
await advanceEpochAsync(); // epoch 2
const { poolId } = await rewardPoolAsync();
const { delegator } = await delegateStakeAsync(poolId);
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0);
});
it('nothing in epoch 1 for delegator delegating in epoch 0', async () => {
it('nothing in epoch 2 for delegator delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
// rewards paid for stake in epoch 0.
await advanceEpochAsync(); // epoch 2 (stake now active)
// rewards paid for stake in epoch 1.
await rewardPoolAsync({ poolId, membersStake: stake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0);
});
it('all rewards from epoch 2 for delegator delegating in epoch 0', async () => {
it('all rewards from epoch 3 for delegator delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1.
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(reward);
});
it('all rewards from epoch 2 and 3 for delegator delegating in epoch 0', async () => {
it('all rewards from epoch 3 and 3 for delegator delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: stake });
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: stake });
await advanceEpochAsync(); // epoch 4
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: stake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
assertRoughlyEquals(delegatorReward, BigNumber.sum(reward1, reward2));
});
it('partial rewards from epoch 2 and 3 for delegator partially delegating in epoch 0', async () => {
it('partial rewards from epoch 3 and 3 for delegator partially delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake: delegatorStake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1.
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2.
const { membersReward: reward, membersStake: rewardStake } = await rewardPoolAsync({
poolId,
membersStake: new BigNumber(delegatorStake).times(2),
@@ -365,9 +365,9 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('has correct reward immediately after undelegating', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1.
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const { delegatorTransfers: withdrawal } = await undelegateStakeAsync(poolId, delegator);
assertRoughlyEquals(withdrawal, reward);
@@ -378,9 +378,9 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('has correct reward immediately after undelegating and redelegating', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1.
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const { delegatorTransfers: withdrawal } = await undelegateStakeAsync(poolId, delegator);
assertRoughlyEquals(withdrawal, reward);
@@ -392,15 +392,15 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('has correct reward immediately after undelegating, redelegating, and rewarding fees', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1.
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2.
await rewardPoolAsync({ poolId, membersStake: stake });
await undelegateStakeAsync(poolId, delegator);
await delegateStakeAsync(poolId, { delegator, stake });
await advanceEpochAsync(); // epoch 3
await advanceEpochAsync(); // epoch 4
// rewards paid for stake in epoch 3.
await advanceEpochAsync(); // epoch 5
// rewards paid for stake in epoch 4.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
assertRoughlyEquals(delegatorReward, reward);
@@ -410,10 +410,10 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
const poolId = hexRandom();
// stake at 0
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
// Pay rewards for epoch 0.
await advanceEpochAsync(); // epoch 2
await advanceEpochAsync(); // epoch 2 (stake now active)
// Pay rewards for epoch 1.
await advanceEpochAsync(); // epoch 3
// Pay rewards for epoch 2.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(reward);
@@ -423,21 +423,21 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
const poolId = hexRandom();
// stake at 0
const { delegator, stake: stake1 } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake1 now active)
await advanceEpochAsync(); // epoch 2
await advanceEpochAsync(); // epoch 2 (stake1 now active)
await advanceEpochAsync(); // epoch 3
const stake2 = getRandomInteger(0, stake1);
const totalStake = BigNumber.sum(stake1, stake2);
// Make the total stake in rewards > totalStake so delegator never
// receives 100% of rewards.
const rewardStake = totalStake.times(2);
// Pay rewards for epoch 1.
// Pay rewards for epoch 2.
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
// add extra stake
const { delegatorTransfers: withdrawal } = await delegateStakeAsync(poolId, { delegator, stake: stake2 });
await advanceEpochAsync(); // epoch 3 (stake2 now active)
// Pay rewards for epoch 2.
await advanceEpochAsync(); // epoch 4
await advanceEpochAsync(); // epoch 4 (stake2 now active)
// Pay rewards for epoch 3.
await advanceEpochAsync(); // epoch 5
// Pay rewards for epoch 4.
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
const expectedDelegatorReward = BigNumber.sum(
@@ -451,18 +451,18 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
const poolId = hexRandom();
// stake at 0
const { delegator, stake: stake1 } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake1 now active)
await advanceEpochAsync(); // epoch 2 (stake1 now active)
// add extra stake
const { stake: stake2 } = await delegateStakeAsync(poolId, { delegator });
const totalStake = BigNumber.sum(stake1, stake2);
await advanceEpochAsync(); // epoch 2 (stake2 now active)
await advanceEpochAsync(); // epoch 3 (stake2 now active)
// Make the total stake in rewards > totalStake so delegator never
// receives 100% of rewards.
const rewardStake = totalStake.times(2);
// Pay rewards for epoch 1.
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
await advanceEpochAsync(); // epoch 3
// Pay rewards for epoch 2.
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
await advanceEpochAsync(); // epoch 4
// Pay rewards for epoch 3.
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
const expectedDelegatorReward = BigNumber.sum(
@@ -475,14 +475,14 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('computes correct rewards for 2 staggered delegators', async () => {
const poolId = hexRandom();
const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake A now active)
await advanceEpochAsync(); // epoch 2 (stake A now active)
const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId);
const totalStake = BigNumber.sum(stakeA, stakeB);
await advanceEpochAsync(); // epoch 2 (stake B now active)
// rewards paid for stake in epoch 1 (delegator A only)
await advanceEpochAsync(); // epoch 3 (stake B now active)
// rewards paid for stake in epoch 2 (delegator A only)
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: stakeA });
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2 (delegator A and B)
await advanceEpochAsync(); // epoch 4
// rewards paid for stake in epoch 3 (delegator A and B)
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: totalStake });
const delegatorRewardA = await getDelegatorRewardBalanceAsync(poolId, delegatorA);
const expectedDelegatorRewardA = BigNumber.sum(
@@ -498,15 +498,15 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('computes correct rewards for 2 staggered delegators with a 2 epoch gap between payments', async () => {
const poolId = hexRandom();
const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake A now active)
await advanceEpochAsync(); // epoch 2 (stake A now active)
const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId);
const totalStake = BigNumber.sum(stakeA, stakeB);
await advanceEpochAsync(); // epoch 2 (stake B now active)
// rewards paid for stake in epoch 1 (delegator A only)
await advanceEpochAsync(); // epoch 3 (stake B now active)
// rewards paid for stake in epoch 2 (delegator A only)
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: stakeA });
await advanceEpochAsync(); // epoch 3
await advanceEpochAsync(); // epoch 4
// rewards paid for stake in epoch 3 (delegator A and B)
await advanceEpochAsync(); // epoch 5
// rewards paid for stake in epoch 4 (delegator A and B)
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: totalStake });
const delegatorRewardA = await getDelegatorRewardBalanceAsync(poolId, delegatorA);
const expectedDelegatorRewardA = BigNumber.sum(
@@ -522,15 +522,15 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('correct rewards for rewards with different stakes', async () => {
const poolId = hexRandom();
const { delegator, stake: delegatorStake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1.
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2.
const { membersReward: reward1, membersStake: rewardStake1 } = await rewardPoolAsync({
poolId,
membersStake: new BigNumber(delegatorStake).times(2),
});
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2
await advanceEpochAsync(); // epoch 4
// rewards paid for stake in epoch 3
const { membersReward: reward2, membersStake: rewardStake2 } = await rewardPoolAsync({
poolId,
membersStake: new BigNumber(delegatorStake).times(3),
@@ -544,41 +544,27 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
});
describe('with unfinalized rewards', async () => {
it('nothing with only unfinalized rewards from epoch 1 for delegator with nothing delegated', async () => {
it('nothing with only unfinalized rewards from epoch 2 for delegator with nothing delegated', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId, { stake: 0 });
await advanceEpochAsync(); // epoch 1
await setUnfinalizedPoolRewardAsync({ poolId, membersStake: stake });
const reward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(reward).to.bignumber.eq(0);
});
it('nothing with only unfinalized rewards from epoch 1 for delegator delegating in epoch 0', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1
await setUnfinalizedPoolRewardAsync({ poolId, membersStake: stake });
const reward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(reward).to.bignumber.eq(0);
});
it('returns unfinalized rewards from epoch 2 for delegator delegating in epoch 0', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1
await advanceEpochAsync(); // epoch 2
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
poolId,
membersStake: stake,
});
await setUnfinalizedPoolRewardAsync({ poolId, membersStake: stake });
const reward = await getDelegatorRewardBalanceAsync(poolId, delegator);
assertRoughlyEquals(reward, unfinalizedReward);
expect(reward).to.bignumber.eq(0);
});
it('returns unfinalized rewards from epoch 3 for delegator delegating in epoch 0', async () => {
it('nothing with only unfinalized rewards from epoch 2 for delegator delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 2
await setUnfinalizedPoolRewardAsync({ poolId, membersStake: stake });
const reward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(reward).to.bignumber.eq(0);
});
it('returns unfinalized rewards from epoch 3 for delegator delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1
await advanceEpochAsync(); // epoch 2
await advanceEpochAsync(); // epoch 3
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
@@ -589,13 +575,27 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
assertRoughlyEquals(reward, unfinalizedReward);
});
it('returns unfinalized rewards from epoch 3 + rewards from epoch 2 for delegator delegating in epoch 0', async () => {
it('returns unfinalized rewards from epoch 4 for delegator delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1
await advanceEpochAsync(); // epoch 2
await advanceEpochAsync(); // epoch 3
await advanceEpochAsync(); // epoch 4
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
poolId,
membersStake: stake,
});
const reward = await getDelegatorRewardBalanceAsync(poolId, delegator);
assertRoughlyEquals(reward, unfinalizedReward);
});
it('returns unfinalized rewards from epoch 4 + rewards from epoch 3 for delegator delegating in epoch 1', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 2
await advanceEpochAsync(); // epoch 3
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: stake });
await advanceEpochAsync(); // epoch 3
await advanceEpochAsync(); // epoch 4
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
poolId,
membersStake: stake,
@@ -605,14 +605,14 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
assertRoughlyEquals(reward, expectedReward);
});
it('returns unfinalized rewards from epoch 4 + rewards from epoch 2 for delegator delegating in epoch 1', async () => {
it('returns unfinalized rewards from epoch 5 + rewards from epoch 3 for delegator delegating in epoch 2', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1
await advanceEpochAsync(); // epoch 2
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: stake });
await advanceEpochAsync(); // epoch 3
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: stake });
await advanceEpochAsync(); // epoch 4
await advanceEpochAsync(); // epoch 5
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
poolId,
membersStake: stake,
@@ -625,14 +625,14 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('returns correct rewards if unfinalized stake is different from previous rewards', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1
await advanceEpochAsync(); // epoch 2
await advanceEpochAsync(); // epoch 3
const { membersReward: prevReward, membersStake: prevStake } = await rewardPoolAsync({
poolId,
membersStake: new BigNumber(stake).times(2),
});
await advanceEpochAsync(); // epoch 3
await advanceEpochAsync(); // epoch 4
await advanceEpochAsync(); // epoch 5
const {
membersReward: unfinalizedReward,
membersStake: unfinalizedStake,
@@ -654,9 +654,9 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
it('transfers all rewards to delegator when touching stake', async () => {
const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1
await advanceEpochAsync(); // epoch 2 (stake now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const { delegatorTransfers: withdrawal } = await touchStakeAsync(poolId, delegator);
const finalRewardBalance = await getDelegatorRewardBalanceAsync(poolId, delegator);
@@ -671,17 +671,17 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
stakeResults.push(await delegateStakeAsync(poolId));
const { delegator, stake } = stakeResults[0];
const rewardStake = new BigNumber(stake).times(2);
await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2 (stake now active)
// add more stake.
stakeResults.push(await delegateStakeAsync(poolId, { delegator, stake }));
await advanceEpochAsync(); // epoch 1 (2 * stake now active)
// reward for epoch 1, using 2 * stake so delegator should
await advanceEpochAsync(); // epoch 2 (2 * stake now active)
// reward for epoch 2, using 2 * stake so delegator should
// only be entitled to a fraction of the rewards.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
await advanceEpochAsync(); // epoch 2
await advanceEpochAsync(); // epoch 3
// touch the stake one last time
stakeResults.push(await touchStakeAsync(poolId, delegator));
// Should only see deposits for epoch 2.
// Should only see deposits for epoch 3.
const allDeposits = stakeResults.map(r => r.delegatorTransfers);
const expectedReward = computeDelegatorRewards(reward, stake, rewardStake);
assertRoughlyEquals(BigNumber.sum(...allDeposits), expectedReward);
@@ -694,19 +694,19 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
stakeResults.push(await delegateStakeAsync(poolId));
const { delegator, stake } = stakeResults[0];
const rewardStake = new BigNumber(stake).times(2);
await advanceEpochAsync(); // epoch 1 (full stake now active)
// reward for epoch 0
await advanceEpochAsync(); // epoch 2 (full stake now active)
// reward for epoch 1
await rewardPoolAsync({ poolId, membersStake: rewardStake });
// unstake some
const unstake = new BigNumber(stake).dividedToIntegerBy(2);
stakeResults.push(await undelegateStakeAsync(poolId, delegator, unstake));
await advanceEpochAsync(); // epoch 2 (half active stake)
// reward for epoch 1
await advanceEpochAsync(); // epoch 3 (half active stake)
// reward for epoch 2
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
// re-stake
stakeResults.push(await delegateStakeAsync(poolId, { delegator, stake: unstake }));
await advanceEpochAsync(); // epoch 3 (full stake now active)
// reward for epoch 2
await advanceEpochAsync(); // epoch 4 (full stake now active)
// reward for epoch 3
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
// touch the stake to claim rewards
stakeResults.push(await touchStakeAsync(poolId, delegator));
@@ -723,9 +723,9 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId);
const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId);
const totalStake = BigNumber.sum(stakeA, stakeB);
await advanceEpochAsync(); // epoch 1 (stakes now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1
await advanceEpochAsync(); // epoch 2 (stakes now active)
await advanceEpochAsync(); // epoch 3
// rewards paid for stake in epoch 2
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
// delegator A will finalize and collect rewards by touching stake.
const { delegatorTransfers: withdrawalA } = await touchStakeAsync(poolId, delegatorA);
@@ -740,12 +740,12 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId);
const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId);
const totalStake = BigNumber.sum(stakeA, stakeB);
await advanceEpochAsync(); // epoch 1 (stakes now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
await advanceEpochAsync(); // epoch 2 (stakes now active)
await advanceEpochAsync(); // epoch 3
// unfinalized rewards for stake in epoch 2
// rewards paid for stake in epoch 2
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
await advanceEpochAsync(); // epoch 4
// unfinalized rewards for stake in epoch 3
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
poolId,
membersStake: totalStake,
@@ -764,12 +764,12 @@ blockchainTests.resets('Delegator rewards unit tests', env => {
const { delegator: delegatorA, stake: stakeA } = await delegateStakeAsync(poolId);
const { delegator: delegatorB, stake: stakeB } = await delegateStakeAsync(poolId);
const totalStake = BigNumber.sum(stakeA, stakeB);
await advanceEpochAsync(); // epoch 1 (stakes now active)
await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
await advanceEpochAsync(); // epoch 2 (stakes now active)
await advanceEpochAsync(); // epoch 3
// unfinalized rewards for stake in epoch 2
// rewards paid for stake in epoch 2
const { membersReward: prevReward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
await advanceEpochAsync(); // epoch 4
// unfinalized rewards for stake in epoch 3
const { membersReward: unfinalizedReward } = await setUnfinalizedPoolRewardAsync({
poolId,
membersStake: totalStake,

View File

@@ -22,11 +22,11 @@ import {
TestFinalizerDepositStakingPoolRewardsEventArgs as DepositStakingPoolRewardsEventArgs,
TestFinalizerEvents,
} from '../../src';
import { constants as stakingConstants } from '../utils/constants';
import { assertIntegerRoughlyEquals, getRandomInteger, toBaseUnitAmount } from '../utils/number_utils';
blockchainTests.resets('Finalizer unit tests', env => {
const { ZERO_AMOUNT } = constants;
const INITIAL_EPOCH = 0;
const INITIAL_BALANCE = toBaseUnitAmount(32);
let operatorRewardsReceiver: string;
let membersRewardsReceiver: string;
@@ -186,7 +186,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
// Assert the `EpochFinalized` logs.
const epochFinalizedEvents = getEpochFinalizedEvents(finalizationLogs);
expect(epochFinalizedEvents.length).to.eq(1);
expect(epochFinalizedEvents[0].epoch).to.bignumber.eq(currentEpoch - 1);
expect(epochFinalizedEvents[0].epoch).to.bignumber.eq(currentEpoch.minus(1));
assertIntegerRoughlyEquals(epochFinalizedEvents[0].rewardsPaid, totalRewards);
assertIntegerRoughlyEquals(epochFinalizedEvents[0].rewardsRemaining, rewardsRemaining);
@@ -262,8 +262,8 @@ blockchainTests.resets('Finalizer unit tests', env => {
return filterLogsToArguments<IStakingEventsRewardsPaidEventArgs>(logs, IStakingEventsEvents.RewardsPaid);
}
async function getCurrentEpochAsync(): Promise<number> {
return (await testContract.currentEpoch.callAsync()).toNumber();
async function getCurrentEpochAsync(): Promise<BigNumber> {
return testContract.currentEpoch.callAsync();
}
async function getBalanceOfAsync(whom: string): Promise<BigNumber> {
@@ -274,13 +274,13 @@ blockchainTests.resets('Finalizer unit tests', env => {
it('advances the epoch', async () => {
await testContract.endEpoch.awaitTransactionSuccessAsync();
const currentEpoch = await testContract.currentEpoch.callAsync();
expect(currentEpoch).to.bignumber.eq(INITIAL_EPOCH + 1);
expect(currentEpoch).to.bignumber.eq(stakingConstants.INITIAL_EPOCH.plus(1));
});
it('emits an `EpochEnded` event', async () => {
const receipt = await testContract.endEpoch.awaitTransactionSuccessAsync();
assertEpochEndedEvent(receipt.logs, {
epoch: new BigNumber(INITIAL_EPOCH),
epoch: stakingConstants.INITIAL_EPOCH,
numActivePools: ZERO_AMOUNT,
rewardsAvailable: INITIAL_BALANCE,
totalFeesCollected: ZERO_AMOUNT,
@@ -291,7 +291,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
it('immediately finalizes if there are no active pools', async () => {
const receipt = await testContract.endEpoch.awaitTransactionSuccessAsync();
assertEpochFinalizedEvent(receipt.logs, {
epoch: new BigNumber(INITIAL_EPOCH),
epoch: stakingConstants.INITIAL_EPOCH,
rewardsPaid: ZERO_AMOUNT,
rewardsRemaining: INITIAL_BALANCE,
});
@@ -312,7 +312,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
await addActivePoolAsync();
await testContract.endEpoch.awaitTransactionSuccessAsync();
const epoch = await testContract.currentEpoch.callAsync();
expect(epoch).to.bignumber.eq(INITIAL_EPOCH + 1);
expect(epoch).to.bignumber.eq(stakingConstants.INITIAL_EPOCH.plus(1));
const numActivePools = await testContract.numActivePoolsThisEpoch.callAsync();
const totalFees = await testContract.totalFeesCollectedThisEpoch.callAsync();
const totalStake = await testContract.totalWeightedStakeThisEpoch.callAsync();
@@ -337,7 +337,10 @@ blockchainTests.resets('Finalizer unit tests', env => {
await addActivePoolAsync();
await testContract.endEpoch.awaitTransactionSuccessAsync();
const tx = testContract.endEpoch.awaitTransactionSuccessAsync();
const expectedError = new StakingRevertErrors.PreviousEpochNotFinalizedError(INITIAL_EPOCH, 1);
const expectedError = new StakingRevertErrors.PreviousEpochNotFinalizedError(
stakingConstants.INITIAL_EPOCH,
1,
);
return expect(tx).to.revertWith(expectedError);
});
});
@@ -380,7 +383,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
await testContract.endEpoch.awaitTransactionSuccessAsync();
await finalizePoolsAsync([pool.poolId]);
const poolState = await testContract.getActivePoolFromEpoch.callAsync(
new BigNumber(INITIAL_EPOCH),
stakingConstants.INITIAL_EPOCH,
pool.poolId,
);
expect(poolState.feesCollected).to.bignumber.eq(0);
@@ -430,7 +433,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
await testContract.endEpoch.awaitTransactionSuccessAsync();
await finalizePoolsAsync([pool.poolId]);
await testContract.endEpoch.awaitTransactionSuccessAsync();
return expect(getCurrentEpochAsync()).to.become(INITIAL_EPOCH + 2);
return expect(getCurrentEpochAsync()).to.become(stakingConstants.INITIAL_EPOCH.plus(2));
});
it('does not reward a pool that was only active 2 epochs ago', async () => {
@@ -439,7 +442,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
await finalizePoolsAsync([pool1.poolId]);
await addActivePoolAsync();
await testContract.endEpoch.awaitTransactionSuccessAsync();
expect(getCurrentEpochAsync()).to.become(INITIAL_EPOCH + 2);
expect(getCurrentEpochAsync()).to.become(stakingConstants.INITIAL_EPOCH.plus(2));
const logs = await finalizePoolsAsync([pool1.poolId]);
const rewardsPaidEvents = getRewardsPaidEvents(logs);
expect(rewardsPaidEvents).to.deep.eq([]);
@@ -452,13 +455,13 @@ blockchainTests.resets('Finalizer unit tests', env => {
await testContract.endEpoch.awaitTransactionSuccessAsync();
await addActivePoolAsync();
await testContract.endEpoch.awaitTransactionSuccessAsync();
expect(getCurrentEpochAsync()).to.become(INITIAL_EPOCH + 3);
expect(getCurrentEpochAsync()).to.become(stakingConstants.INITIAL_EPOCH.plus(3));
const logs = await finalizePoolsAsync([pool1.poolId]);
const rewardsPaidEvents = getRewardsPaidEvents(logs);
expect(rewardsPaidEvents).to.deep.eq([]);
});
it('rolls over leftover rewards into th next epoch', async () => {
it('rolls over leftover rewards into the next epoch', async () => {
const poolIds = _.times(3, () => hexRandom());
await Promise.all(poolIds.map(async id => addActivePoolAsync({ poolId: id })));
await testContract.endEpoch.awaitTransactionSuccessAsync();
@@ -495,7 +498,7 @@ blockchainTests.resets('Finalizer unit tests', env => {
membersStake: 0,
};
it('returns empty if epoch is 0', async () => {
it('returns empty if epoch is 1', async () => {
const poolId = hexRandom();
return assertUnfinalizedPoolRewardsAsync(poolId, ZERO_REWARDS);
});

View File

@@ -9,7 +9,7 @@ export const constants = {
SECOND_POOL_ID: '0x0000000000000000000000000000000000000000000000000000000000000002',
NIL_POOL_ID: '0x0000000000000000000000000000000000000000000000000000000000000000',
NIL_ADDRESS: '0x0000000000000000000000000000000000000000',
INITIAL_EPOCH: new BigNumber(0),
INITIAL_EPOCH: new BigNumber(1),
DEFAULT_PARAMS: {
epochDurationInSeconds: new BigNumber(TEN_DAYS),
rewardDelegatedStakeWeight: new BigNumber(PPM * 0.9),