Update tests to start at epoch 1
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user