diff --git a/contracts/staking/CHANGELOG.json b/contracts/staking/CHANGELOG.json index 625793f960..da9df57fe2 100644 --- a/contracts/staking/CHANGELOG.json +++ b/contracts/staking/CHANGELOG.json @@ -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 } ] } diff --git a/contracts/staking/contracts/src/Staking.sol b/contracts/staking/contracts/src/Staking.sol index a4051400d1..e832188e76 100644 --- a/contracts/staking/contracts/src/Staking.sol +++ b/contracts/staking/contracts/src/Staking.sol @@ -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, diff --git a/contracts/staking/contracts/src/immutable/MixinStorage.sol b/contracts/staking/contracts/src/immutable/MixinStorage.sol index 05446258b2..ee9ed4c4aa 100644 --- a/contracts/staking/contracts/src/immutable/MixinStorage.sol +++ b/contracts/staking/contracts/src/immutable/MixinStorage.sol @@ -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; diff --git a/contracts/staking/contracts/src/staking_pools/MixinCumulativeRewards.sol b/contracts/staking/contracts/src/staking_pools/MixinCumulativeRewards.sol index decfa1fc05..c22fb94e36 100644 --- a/contracts/staking/contracts/src/staking_pools/MixinCumulativeRewards.sol +++ b/contracts/staking/contracts/src/staking_pools/MixinCumulativeRewards.sol @@ -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 - ) - private + /// @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 + ) { - // Add dependency by increasing the reference counter - _cumulativeRewardsByPoolReferenceCounter[poolId][epoch] = - _cumulativeRewardsByPoolReferenceCounter[poolId][epoch].safeAdd(1); + // Return CR at `epoch`, given it's set. + cumulativeReward = _cumulativeRewardsByPool[poolId][epoch]; + if (_isCumulativeRewardSet(cumulativeReward)) { + return (cumulativeReward, epoch); + } - // Set CR to most recent reward (if it is not already set) - _trySetCumulativeReward( - poolId, - epoch, - mostRecentCumulativeReward - ); - } + // Return CR at `epoch-1`, given it's set. + uint256 lastEpoch = epoch.safeSub(1); + cumulativeReward = _cumulativeRewardsByPool[poolId][lastEpoch]; + if (_isCumulativeRewardSet(cumulativeReward)) { + return (cumulativeReward, lastEpoch); + } - /// @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 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); + } + } - // Clear cumulative reward from state, if it is no longer needed - _tryUnsetCumulativeReward(poolId, epoch); + // Could not find a CR for `epoch` + revert("CR_INVALID_EPOCH"); } } diff --git a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol index ab66124779..f620565333 100644 --- a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol +++ b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol @@ -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,112 +304,121 @@ 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( - unfinalizedMembersReward, - unfinalizedMembersStake, - _stake - ); - } - } + // We account for rewards over 3 intervals, below. - // 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]; + // 1/3 Unfinalized rewards earned in `currentEpoch - 1`. + reward = _computeUnfinalizedDelegatorReward( + unsyncedStake, + _currentEpoch, + unfinalizedMembersReward, + unfinalizedMembersStake + ); - // 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) { - reward = reward.safeAdd( - _computeMemberRewardOverInterval( - poolId, - unsyncedStake.nextEpochBalance, - nextStakeEpoch, - lastRewardEpoch - ) - ); - } + + // 3/3 Finalized rewards earned in epoch `unsyncedStake.currentEpoch`. + reward = reward.safeAdd( + _computeMemberRewardOverInterval( + poolId, + unsyncedStake.nextEpochBalance, + 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( - poolId, - uint256(_delegatedStakeToPoolByOwner.currentEpoch).safeAdd(1), - mostRecentCumulativeReward, - isDependent - ); - } + // Delegator depends on the Cumulative Reward for this epoch - ensure it is set. + _trySetCumulativeReward( + poolId, + _delegatedStakeToPoolByOwner.currentEpoch, + mostRecentCumulativeReward + ); } /// @dev Increments rewards for a pool. diff --git a/contracts/staking/contracts/test/TestCumulativeRewardTracking.sol b/contracts/staking/contracts/test/TestCumulativeRewardTracking.sol index 4a1f3a1c15..25720d7bed 100644 --- a/contracts/staking/contracts/test/TestCumulativeRewardTracking.sol +++ b/contracts/staking/contracts/test/TestCumulativeRewardTracking.sol @@ -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, diff --git a/contracts/staking/test/cumulative_reward_tracking_test.ts b/contracts/staking/test/cumulative_reward_tracking_test.ts index bdc8e50a59..e23191ee6d 100644 --- a/contracts/staking/test/cumulative_reward_tracking_test.ts +++ b/contracts/staking/test/cumulative_reward_tracking_test.ts @@ -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 }], ); }); }); diff --git a/contracts/staking/test/utils/cumulative_reward_tracking_simulation.ts b/contracts/staking/test/utils/cumulative_reward_tracking_simulation.ts index 9af5885bd7..fa25922bfc 100644 --- a/contracts/staking/test/utils/cumulative_reward_tracking_simulation.ts +++ b/contracts/staking/test/utils/cumulative_reward_tracking_simulation.ts @@ -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;