Merge pull request #2188 from 0xProject/feature/staking/remove-ref-counting

Remove reference counting for cumulative rewards
This commit is contained in:
Greg Hysz 2019-09-24 14:00:17 -07:00 committed by GitHub
commit b65fd06e95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 148 additions and 362 deletions

View File

@ -61,6 +61,14 @@
{
"note": "Introduce multi-block finalization.",
"pr": 2155
},
{
"note": "Removed reference counting for cumulative rewards.",
"pr": 2188
},
{
"note": "Removed explicit dependency on epoch+1 when delegating.",
"pr": 2188
}
]
}

View File

@ -261,14 +261,6 @@ contract Staking is
)
slot := add(slot, 0x1)
assertSlotAndOffset(
_cumulativeRewardsByPoolReferenceCounter_slot,
_cumulativeRewardsByPoolReferenceCounter_offset,
slot,
offset
)
slot := add(slot, 0x1)
assertSlotAndOffset(
_cumulativeRewardsByPoolLastStored_slot,
_cumulativeRewardsByPoolLastStored_offset,

View File

@ -94,9 +94,6 @@ contract MixinStorage is
// mapping from Pool Id to Epoch to Reward Ratio
mapping (bytes32 => mapping (uint256 => IStructs.Fraction)) internal _cumulativeRewardsByPool;
// mapping from Pool Id to Epoch to Cumulative Rewards Reference Counter
mapping (bytes32 => mapping (uint256 => uint256)) internal _cumulativeRewardsByPoolReferenceCounter;
// mapping from Pool Id to Epoch
mapping (bytes32 => uint256) internal _cumulativeRewardsByPoolLastStored;

View File

@ -63,30 +63,6 @@ contract MixinCumulativeRewards is
return cumulativeReward.denominator != 0;
}
/// @dev Returns true iff the cumulative reward for `poolId` at `epoch` can
/// be unset.
/// @param poolId Unique id of pool.
/// @param epoch Epoch of the cumulative reward.
function _canUnsetCumulativeReward(bytes32 poolId, uint256 epoch)
internal
view
returns (bool)
{
// Must be a value to unset
if (!_isCumulativeRewardSet(_cumulativeRewardsByPool[poolId][epoch])) {
return false;
}
// Must be no references to this CR
if (_cumulativeRewardsByPoolReferenceCounter[poolId][epoch] != 0) {
return false;
}
// Must not be the most recently *stored* CR.
if (_cumulativeRewardsByPoolLastStored[poolId] == epoch) {
return false;
}
return true;
}
/// @dev Tries to set a cumulative reward for `poolId` at `epoch`.
/// @param poolId Unique Id of pool.
/// @param epoch Epoch of cumulative reward.
@ -129,27 +105,6 @@ contract MixinCumulativeRewards is
}
}
/// @dev Tries to unset the cumulative reward for `poolId` at `epoch`.
/// @param poolId Unique id of pool.
/// @param epoch Epoch of cumulative reward to unset.
function _tryUnsetCumulativeReward(bytes32 poolId, uint256 epoch)
internal
{
if (!_canUnsetCumulativeReward(poolId, epoch)) {
return;
}
_forceUnsetCumulativeReward(poolId, epoch);
}
/// @dev Unsets the cumulative reward for `poolId` at `epoch`.
/// @param poolId Unique id of pool.
/// @param epoch Epoch of cumulative reward to unset.
function _forceUnsetCumulativeReward(bytes32 poolId, uint256 epoch)
internal
{
delete _cumulativeRewardsByPool[poolId][epoch];
}
/// @dev Tries to set the epoch of the most recent cumulative reward.
/// The value will only be set if the input epoch is greater than the
/// current most recent value.
@ -191,37 +146,6 @@ contract MixinCumulativeRewards is
// Sanity check that we're not trying to go back in time
assert(newMostRecentEpoch >= currentMostRecentEpoch);
_cumulativeRewardsByPoolLastStored[poolId] = newMostRecentEpoch;
// Unset the previous most recent reward, if it is no longer needed
_tryUnsetCumulativeReward(poolId, currentMostRecentEpoch);
}
/// @dev Adds a dependency on a cumulative reward for a given epoch.
/// @param poolId Unique Id of pool.
/// @param epoch Epoch to remove dependency from.
/// @param mostRecentCumulativeReward The most recent cumulative reward.
/// @param isDependent True iff there is a dependency on the cumulative
/// reward for `poolId` at `epoch`
function _addOrRemoveDependencyOnCumulativeReward(
bytes32 poolId,
uint256 epoch,
IStructs.Fraction memory mostRecentCumulativeReward,
bool isDependent
)
internal
{
if (isDependent) {
_addDependencyOnCumulativeReward(
poolId,
epoch,
mostRecentCumulativeReward
);
} else {
_removeDependencyOnCumulativeReward(
poolId,
epoch
);
}
}
/// @dev Computes a member's reward over a given epoch interval.
@ -241,22 +165,22 @@ contract MixinCumulativeRewards is
view
returns (uint256 reward)
{
if (memberStakeOverInterval == 0) {
// Sanity check if we can skip computation, as it will result in zero.
if (memberStakeOverInterval == 0 || beginEpoch == endEpoch) {
return 0;
}
// Sanity check interval
require(beginEpoch <= endEpoch, "CR_INTERVAL_INVALID");
require(beginEpoch < endEpoch, "CR_INTERVAL_INVALID");
// Sanity check begin reward
IStructs.Fraction memory beginReward =
_cumulativeRewardsByPool[poolId][beginEpoch];
require(_isCumulativeRewardSet(beginReward), "CR_INTERVAL_INVALID_BEGIN");
(IStructs.Fraction memory beginReward, uint256 beginRewardStoredAt) = _getCumulativeRewardAtEpoch(poolId, beginEpoch);
(IStructs.Fraction memory endReward, uint256 endRewardStoredAt) = _getCumulativeRewardAtEpoch(poolId, endEpoch);
// Sanity check end reward
IStructs.Fraction memory endReward =
_cumulativeRewardsByPool[poolId][endEpoch];
require(_isCumulativeRewardSet(endReward), "CR_INTERVAL_INVALID_END");
// If the rewards were stored at the same epoch then the computation will result in zero.
if (beginRewardStoredAt == endRewardStoredAt) {
return 0;
}
// Compute reward
reward = LibFractions.scaleDifference(
@ -280,43 +204,44 @@ contract MixinCumulativeRewards is
return _cumulativeRewardsByPool[poolId][lastStoredEpoch];
}
/// @dev Adds a dependency on a cumulative reward for a given epoch.
/// @param poolId Unique Id of pool.
/// @param epoch Epoch to remove dependency from.
/// @param mostRecentCumulativeReward The most recent cumulative reward.
function _addDependencyOnCumulativeReward(
bytes32 poolId,
uint256 epoch,
IStructs.Fraction memory mostRecentCumulativeReward
/// @dev Fetch the cumulative reward for a given epoch.
/// If the corresponding CR does not exist in state, then we backtrack
/// to find its value by querying `epoch-1` and then most recent CR.
/// @param poolId Unique ID of pool.
/// @param epoch The epoch to find the
/// @return cumulativeReward The cumulative reward for `poolId` at `epoch`.
/// @return cumulativeRewardStoredAt Epoch that the `cumulativeReward` is stored at.
function _getCumulativeRewardAtEpoch(bytes32 poolId, uint256 epoch)
internal
view
returns (
IStructs.Fraction memory cumulativeReward,
uint256 cumulativeRewardStoredAt
)
private
{
// Add dependency by increasing the reference counter
_cumulativeRewardsByPoolReferenceCounter[poolId][epoch] =
_cumulativeRewardsByPoolReferenceCounter[poolId][epoch].safeAdd(1);
// Set CR to most recent reward (if it is not already set)
_trySetCumulativeReward(
poolId,
epoch,
mostRecentCumulativeReward
);
// Return CR at `epoch`, given it's set.
cumulativeReward = _cumulativeRewardsByPool[poolId][epoch];
if (_isCumulativeRewardSet(cumulativeReward)) {
return (cumulativeReward, epoch);
}
/// @dev Removes a dependency on a cumulative reward for a given epoch.
/// @param poolId Unique Id of pool.
/// @param epoch Epoch to remove dependency from.
function _removeDependencyOnCumulativeReward(
bytes32 poolId,
uint256 epoch
)
private
{
// Remove dependency by decreasing reference counter
_cumulativeRewardsByPoolReferenceCounter[poolId][epoch] =
_cumulativeRewardsByPoolReferenceCounter[poolId][epoch].safeSub(1);
// Return CR at `epoch-1`, given it's set.
uint256 lastEpoch = epoch.safeSub(1);
cumulativeReward = _cumulativeRewardsByPool[poolId][lastEpoch];
if (_isCumulativeRewardSet(cumulativeReward)) {
return (cumulativeReward, lastEpoch);
}
// Clear cumulative reward from state, if it is no longer needed
_tryUnsetCumulativeReward(poolId, epoch);
// Return the most recent CR, given it's less than `epoch`.
uint256 mostRecentEpoch = _cumulativeRewardsByPoolLastStored[poolId];
if (mostRecentEpoch < epoch) {
cumulativeReward = _cumulativeRewardsByPool[poolId][mostRecentEpoch];
if (_isCumulativeRewardSet(cumulativeReward)) {
return (cumulativeReward, mostRecentEpoch);
}
}
// Could not find a CR for `epoch`
revert("CR_INVALID_EPOCH");
}
}

View File

@ -116,7 +116,6 @@ contract MixinStakingPoolRewards is
return _computeDelegatorReward(
poolId,
_loadUnsyncedBalance(_delegatedStakeToPoolByOwner[member][poolId]),
currentEpoch,
unfinalizedMembersReward,
unfinalizedMembersStake
);
@ -144,24 +143,14 @@ contract MixinStakingPoolRewards is
_finalizePoolAndWithdrawDelegatorRewards(
poolId,
member,
initialDelegatedStakeToPoolByOwner,
currentEpoch
initialDelegatedStakeToPoolByOwner
);
// Add dependencies on cumulative rewards for this epoch and the next
// epoch, if necessary.
_setCumulativeRewardDependenciesForDelegator(
poolId,
finalDelegatedStakeToPoolByOwner,
true
);
// Remove dependencies on previous cumulative rewards, if they are no
// longer needed.
_setCumulativeRewardDependenciesForDelegator(
poolId,
initialDelegatedStakeToPoolByOwner,
false
finalDelegatedStakeToPoolByOwner
);
}
@ -270,8 +259,7 @@ contract MixinStakingPoolRewards is
function _finalizePoolAndWithdrawDelegatorRewards(
bytes32 poolId,
address member,
IStructs.StoredBalance memory unsyncedStake,
uint256 currentEpoch
IStructs.StoredBalance memory unsyncedStake
)
private
{
@ -282,7 +270,6 @@ contract MixinStakingPoolRewards is
uint256 balance = _computeDelegatorReward(
poolId,
unsyncedStake,
currentEpoch,
// No unfinalized values because we ensured the pool is already
// finalized.
0,
@ -302,15 +289,12 @@ contract MixinStakingPoolRewards is
/// @dev Computes the reward balance in ETH of a specific member of a pool.
/// @param poolId Unique id of pool.
/// @param unsyncedStake Unsynced delegated stake to pool by owner
/// @param currentEpoch The epoch in which this call is executing
/// @param unfinalizedMembersReward Unfinalized total members reward
/// (if any).
/// @param unfinalizedMembersReward Unfinalized total members reward (if any).
/// @param unfinalizedMembersStake Unfinalized total members stake (if any).
/// @return totalReward Balance in ETH.
/// @return reward Balance in WETH.
function _computeDelegatorReward(
bytes32 poolId,
IStructs.StoredBalance memory unsyncedStake,
uint256 currentEpoch,
uint256 unfinalizedMembersReward,
uint256 unfinalizedMembersStake
)
@ -320,113 +304,122 @@ contract MixinStakingPoolRewards is
{
// There can be no rewards in epoch 0 because there is no delegated
// stake.
if (currentEpoch == 0) {
uint256 _currentEpoch = currentEpoch;
if (_currentEpoch == 0) {
return 0;
}
// There can be no rewards if the last epoch when stake was synced is
// equal to the current epoch, because all prior rewards, including
// rewards finalized this epoch have been claimed.
if (unsyncedStake.currentEpoch == currentEpoch) {
if (unsyncedStake.currentEpoch == _currentEpoch) {
return 0;
}
// If there are unfinalized rewards this epoch, compute the member's
// share.
if (unfinalizedMembersReward != 0 && unfinalizedMembersStake != 0) {
// Unfinalized rewards are always earned from stake in
// the prior epoch so we want the stake at `currentEpoch-1`.
uint256 _stake = unsyncedStake.currentEpoch >= currentEpoch.safeSub(1) ?
unsyncedStake.currentEpochBalance :
unsyncedStake.nextEpochBalance;
if (_stake != 0) {
reward = LibMath.getPartialAmountFloor(
// We account for rewards over 3 intervals, below.
// 1/3 Unfinalized rewards earned in `currentEpoch - 1`.
reward = _computeUnfinalizedDelegatorReward(
unsyncedStake,
_currentEpoch,
unfinalizedMembersReward,
unfinalizedMembersStake,
_stake
unfinalizedMembersStake
);
}
}
// Get the last epoch where a reward was credited to this pool, which
// also happens to be when we last created a cumulative reward entry.
uint256 lastRewardEpoch = _cumulativeRewardsByPoolLastStored[poolId];
// If the stake has been touched since the last reward epoch,
// it has already been claimed.
if (unsyncedStake.currentEpoch >= lastRewardEpoch) {
return reward;
}
// From here we know: `unsyncedStake.currentEpoch < currentEpoch > 0`.
uint256 nextStakeEpoch = uint256(unsyncedStake.currentEpoch).safeAdd(1);
// 2/3 Finalized rewards earned in epochs [`unsyncedStake.currentEpoch + 1` .. `currentEpoch - 1`]
uint256 unsyncedStakeNextEpoch = uint256(unsyncedStake.currentEpoch).safeAdd(1);
reward = reward.safeAdd(
_computeMemberRewardOverInterval(
poolId,
unsyncedStake.currentEpochBalance,
unsyncedStake.currentEpoch,
nextStakeEpoch
unsyncedStakeNextEpoch
)
);
if (nextStakeEpoch < lastRewardEpoch) {
// 3/3 Finalized rewards earned in epoch `unsyncedStake.currentEpoch`.
reward = reward.safeAdd(
_computeMemberRewardOverInterval(
poolId,
unsyncedStake.nextEpochBalance,
nextStakeEpoch,
lastRewardEpoch
unsyncedStakeNextEpoch,
_currentEpoch
)
);
}
return reward;
}
/// @dev Computes the unfinalized rewards earned by a delegator in the last epoch.
/// @param unsyncedStake Unsynced delegated stake to pool by owner
/// @param currentEpoch The epoch in which this call is executing
/// @param unfinalizedMembersReward Unfinalized total members reward (if any).
/// @param unfinalizedMembersStake Unfinalized total members stake (if any).
/// @return reward Balance in WETH.
function _computeUnfinalizedDelegatorReward(
IStructs.StoredBalance memory unsyncedStake,
uint256 currentEpoch,
uint256 unfinalizedMembersReward,
uint256 unfinalizedMembersStake
)
private
view
returns (uint256)
{
// If there are unfinalized rewards this epoch, compute the member's
// share.
if (unfinalizedMembersReward == 0 || unfinalizedMembersStake == 0) {
return 0;
}
// Unfinalized rewards are always earned from stake in
// the prior epoch so we want the stake at `currentEpoch-1`.
uint256 unfinalizedStakeBalance = unsyncedStake.currentEpoch >= currentEpoch.safeSub(1) ?
unsyncedStake.currentEpochBalance :
unsyncedStake.nextEpochBalance;
// Sanity check to save gas on computation
if (unfinalizedStakeBalance == 0) {
return 0;
}
// Compute unfinalized reward
return LibMath.getPartialAmountFloor(
unfinalizedMembersReward,
unfinalizedMembersStake,
unfinalizedStakeBalance
);
}
/// @dev Adds or removes cumulative reward dependencies for a delegator.
/// A delegator always depends on the cumulative reward for the current
/// and next epoch, if they would still have stake in the next epoch.
/// @param poolId Unique id of pool.
/// @param _delegatedStakeToPoolByOwner Amount of stake the member has
/// delegated to the pool.
/// @param isDependent is true iff adding a dependency. False, otherwise.
function _setCumulativeRewardDependenciesForDelegator(
bytes32 poolId,
IStructs.StoredBalance memory _delegatedStakeToPoolByOwner,
bool isDependent
IStructs.StoredBalance memory _delegatedStakeToPoolByOwner
)
private
{
// If this delegator is not yet initialized then there's no dependency
// to unset.
if (!isDependent && !_delegatedStakeToPoolByOwner.isInitialized) {
return;
}
// Get the most recent cumulative reward, which will serve as a
// reference point when updating dependencies
IStructs.Fraction memory mostRecentCumulativeReward = _getMostRecentCumulativeReward(poolId);
// Record dependency on current epoch.
if (_delegatedStakeToPoolByOwner.currentEpochBalance != 0
|| _delegatedStakeToPoolByOwner.nextEpochBalance != 0)
{
_addOrRemoveDependencyOnCumulativeReward(
poolId,
_delegatedStakeToPoolByOwner.currentEpoch,
mostRecentCumulativeReward,
isDependent
);
// The delegator depends on the Cumulative Reward for this epoch
// only if they are currently staked or will be staked next epoch.
if (_delegatedStakeToPoolByOwner.currentEpochBalance == 0 && _delegatedStakeToPoolByOwner.nextEpochBalance == 0) {
return;
}
// Record dependency on the next epoch
if (_delegatedStakeToPoolByOwner.nextEpochBalance != 0) {
_addOrRemoveDependencyOnCumulativeReward(
// Delegator depends on the Cumulative Reward for this epoch - ensure it is set.
_trySetCumulativeReward(
poolId,
uint256(_delegatedStakeToPoolByOwner.currentEpoch).safeAdd(1),
mostRecentCumulativeReward,
isDependent
_delegatedStakeToPoolByOwner.currentEpoch,
mostRecentCumulativeReward
);
}
}
/// @dev Increments rewards for a pool.
/// @param poolId Unique id of pool.

View File

@ -30,11 +30,6 @@ contract TestCumulativeRewardTracking is
uint256 epoch
);
event UnsetCumulativeReward(
bytes32 poolId,
uint256 epoch
);
event SetMostRecentCumulativeReward(
bytes32 poolId,
uint256 epoch
@ -59,13 +54,6 @@ contract TestCumulativeRewardTracking is
);
}
function _forceUnsetCumulativeReward(bytes32 poolId, uint256 epoch)
internal
{
emit UnsetCumulativeReward(poolId, epoch);
MixinCumulativeRewards._forceUnsetCumulativeReward(poolId, epoch);
}
function _forceSetMostRecentCumulativeRewardEpoch(
bytes32 poolId,
uint256 currentMostRecentEpoch,

View File

@ -53,7 +53,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Creates CR for epoch 1
TestAction.Delegate,
],
[{ event: 'SetCumulativeReward', epoch: 0 }, { event: 'SetCumulativeReward', epoch: 1 }],
[{ event: 'SetCumulativeReward', epoch: 0 }],
);
});
it('re-delegating in the same epoch', async () => {
@ -64,34 +64,11 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
],
[
// Updates CR for epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
// Updates CR for epoch 0
// Updates CR for epoch 1
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 0 },
{ event: 'SetCumulativeReward', epoch: 1 },
{ event: 'SetCumulativeReward', epoch: 0 },
{ event: 'SetCumulativeReward', epoch: 1 },
],
);
});
it('delegating then undelegating in the same epoch', async () => {
await simulation.runTestAsync(
[
// Creates CR for epoch 0
TestAction.CreatePool,
// Updates CR for epoch 0
// Creates CR for epoch 1
TestAction.Delegate,
],
[
// Unsets the CR for epoch 1
TestAction.Undelegate,
],
[{ event: 'UnsetCumulativeReward', epoch: 1 }],
[{ event: 'SetCumulativeReward', epoch: 0 }, { event: 'SetCumulativeReward', epoch: 0 }],
);
});
it('delegating in new epoch', async () => {
@ -107,15 +84,9 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Creates a CR for epoch 1
// Sets MRCR to epoch 1
// Unsets the CR for epoch 0
// Creates a CR for epoch 2
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 1 },
{ event: 'SetMostRecentCumulativeReward', epoch: 1 },
{ event: 'UnsetCumulativeReward', epoch: 0 },
{ event: 'SetCumulativeReward', epoch: 2 },
],
[{ event: 'SetCumulativeReward', epoch: 1 }, { event: 'SetMostRecentCumulativeReward', epoch: 1 }],
);
});
it('re-delegating in a new epoch', async () => {
@ -132,38 +103,9 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
[
// Updates CR for epoch 1
// Sets MRCR to epoch 1
// Creates CR for epoch 2
// Clears CR for epoch 0
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 1 },
{ event: 'SetMostRecentCumulativeReward', epoch: 1 },
{ event: 'SetCumulativeReward', epoch: 2 },
{ event: 'UnsetCumulativeReward', epoch: 0 },
],
);
});
it('delegate then undelegate to remove all dependencies', 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
// Clears CR for epoch 0
// Creates CR for epoch 2
TestAction.Delegate,
],
[
// Clears CR from epoch 2
// Does NOT clear CR from epoch 1 because it is the current
// epoch.
TestAction.Undelegate,
],
[{ event: 'UnsetCumulativeReward', epoch: 2 }],
[{ event: 'SetCumulativeReward', epoch: 1 }, { event: 'SetMostRecentCumulativeReward', epoch: 1 }],
);
});
it('delegating in epoch 1 then again in epoch 2', async () => {
@ -175,8 +117,6 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
TestAction.Finalize,
// Creates CR for epoch 1
// Sets MRCR to epoch 1
// Clears CR for epoch 0
// Creates CR for epoch 2
TestAction.Delegate,
// Move to epoch 2
TestAction.Finalize,
@ -188,12 +128,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clears CR for epoch 1
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 2 },
{ event: 'SetMostRecentCumulativeReward', epoch: 2 },
{ event: 'SetCumulativeReward', epoch: 3 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
],
[{ event: 'SetCumulativeReward', epoch: 2 }, { event: 'SetMostRecentCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 1 then undelegate in epoch 2', async () => {
@ -217,11 +152,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clear CR for epoch 1
TestAction.Undelegate,
],
[
{ event: 'SetCumulativeReward', epoch: 2 },
{ event: 'SetMostRecentCumulativeReward', epoch: 2 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
],
[{ event: 'SetCumulativeReward', epoch: 2 }, { event: 'SetMostRecentCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 0 and epoch 1, then undelegate half in epoch 2', async () => {
@ -250,12 +181,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clears CR for epoch 1
TestAction.Undelegate,
],
[
{ event: 'SetCumulativeReward', epoch: 2 },
{ event: 'SetMostRecentCumulativeReward', epoch: 2 },
{ event: 'SetCumulativeReward', epoch: 3 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
],
[{ event: 'SetCumulativeReward', epoch: 2 }, { event: 'SetMostRecentCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 1 and 2 then again in 3', async () => {
@ -284,12 +210,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clears CR for epoch 1
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 2 },
{ event: 'SetMostRecentCumulativeReward', epoch: 2 },
{ event: 'SetCumulativeReward', epoch: 3 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
],
[{ event: 'SetCumulativeReward', epoch: 2 }, { event: 'SetMostRecentCumulativeReward', epoch: 2 }],
);
});
it('delegate in epoch 0, earn reward in epoch 1', async () => {
@ -347,12 +268,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clears CR for epoch 2
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 3 },
{ event: 'SetCumulativeReward', epoch: 4 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
{ event: 'UnsetCumulativeReward', epoch: 2 },
],
[{ event: 'SetCumulativeReward', epoch: 3 }],
);
});
it('delegate in epoch 0 and 1, earn reward in epoch 3, then undelegate half', async () => {
@ -387,12 +303,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clears CR for epoch 2
TestAction.Undelegate,
],
[
{ event: 'SetCumulativeReward', epoch: 3 },
{ event: 'SetCumulativeReward', epoch: 4 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
{ event: 'UnsetCumulativeReward', epoch: 2 },
],
[{ event: 'SetCumulativeReward', epoch: 3 }],
);
});
it('delegate in epoch 1, 2, earn rewards in epoch 3, skip to epoch 4, then delegate', async () => {
@ -430,14 +341,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clears CR for epoch 1
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 4 },
{ event: 'SetMostRecentCumulativeReward', epoch: 4 },
{ event: 'UnsetCumulativeReward', epoch: 3 },
{ event: 'SetCumulativeReward', epoch: 5 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
{ event: 'UnsetCumulativeReward', epoch: 2 },
],
[{ event: 'SetCumulativeReward', epoch: 4 }, { event: 'SetMostRecentCumulativeReward', epoch: 4 }],
);
});
it('earn reward in epoch 1 with no stake, then delegate', async () => {
@ -458,12 +362,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Creates CR for epoch 2
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 1 },
{ event: 'SetMostRecentCumulativeReward', epoch: 1 },
{ event: 'UnsetCumulativeReward', epoch: 0 },
{ event: 'SetCumulativeReward', epoch: 2 },
],
[{ event: 'SetCumulativeReward', epoch: 1 }, { event: 'SetMostRecentCumulativeReward', epoch: 1 }],
);
});
it('delegate in epoch 1, 3, then delegate in epoch 4', async () => {
@ -498,12 +397,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Creates CR for epoch 5
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 4 },
{ event: 'SetMostRecentCumulativeReward', epoch: 4 },
{ event: 'SetCumulativeReward', epoch: 5 },
{ event: 'UnsetCumulativeReward', epoch: 3 },
],
[{ event: 'SetCumulativeReward', epoch: 4 }, { event: 'SetMostRecentCumulativeReward', epoch: 4 }],
);
});
it('delegate in epoch 1, then epoch 3', async () => {
@ -531,13 +425,7 @@ blockchainTests.resets('Cumulative Reward Tracking', env => {
// Clears CR for epoch 2
TestAction.Delegate,
],
[
{ event: 'SetCumulativeReward', epoch: 3 },
{ event: 'SetMostRecentCumulativeReward', epoch: 3 },
{ event: 'SetCumulativeReward', epoch: 4 },
{ event: 'UnsetCumulativeReward', epoch: 1 },
{ event: 'UnsetCumulativeReward', epoch: 2 },
],
[{ event: 'SetCumulativeReward', epoch: 3 }, { event: 'SetMostRecentCumulativeReward', epoch: 3 }],
);
});
});

View File

@ -46,11 +46,6 @@ export class CumulativeRewardTrackingSimulation {
event: log.event,
epoch: log.args.epoch.toNumber(),
});
} else if (log.event === TestCumulativeRewardTrackingEvents.UnsetCumulativeReward) {
logs.push({
event: log.event,
epoch: log.args.epoch.toNumber(),
});
}
}
return logs;