protocol/contracts/staking/contracts/test/TestDelegatorRewards.sol
2019-09-22 12:10:41 -04:00

192 lines
5.8 KiB
Solidity

/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "../src/interfaces/IStructs.sol";
import "./TestStaking.sol";
contract TestDelegatorRewards is
TestStaking
{
event Deposit(
bytes32 poolId,
address member,
uint256 balance
);
event FinalizePool(
bytes32 poolId,
uint256 reward,
uint256 stake
);
struct UnfinalizedMembersReward {
uint256 reward;
uint256 stake;
}
constructor() public {
init();
}
mapping (uint256 => mapping (bytes32 => UnfinalizedMembersReward)) private
unfinalizedMembersRewardByPoolByEpoch;
/// @dev Expose _finalizePool
function internalFinalizePool(bytes32 poolId) external {
_finalizePool(poolId);
}
/// @dev Set unfinalized members reward for a pool in the current epoch.
function setUnfinalizedMembersRewards(
bytes32 poolId,
uint256 membersReward,
uint256 membersStake
)
external
{
unfinalizedMembersRewardByPoolByEpoch[currentEpoch][poolId] =
UnfinalizedMembersReward({
reward: membersReward,
stake: membersStake
});
}
/// @dev Advance the epoch.
function advanceEpoch() external {
currentEpoch += 1;
}
/// @dev Create and delegate stake that is active in the current epoch.
/// Only used to test purportedly unreachable states.
/// Also withdraws pending rewards to the eth vault.
function delegateStakeNow(
address delegator,
bytes32 poolId,
uint256 stake
)
external
{
_transferDelegatorsAccumulatedRewardsToEthVault(poolId, delegator);
_syncCumulativeRewardsNeededByDelegator(poolId, currentEpoch);
IStructs.StoredBalance storage _stake =
delegatedStakeToPoolByOwner[delegator][poolId];
_stake.currentEpochBalance += uint96(stake);
_stake.nextEpochBalance += uint96(stake);
_stake.currentEpoch = uint64(currentEpoch);
}
/// @dev Create and delegate stake that will occur in the next epoch
/// (normal behavior).
/// Also withdraws pending rewards to the eth vault.
function delegateStake(
address delegator,
bytes32 poolId,
uint256 stake
)
external
{
_transferDelegatorsAccumulatedRewardsToEthVault(poolId, delegator);
_syncCumulativeRewardsNeededByDelegator(poolId, currentEpoch);
IStructs.StoredBalance storage _stake =
delegatedStakeToPoolByOwner[delegator][poolId];
if (_stake.currentEpoch < currentEpoch) {
_stake.currentEpochBalance = _stake.nextEpochBalance;
}
_stake.nextEpochBalance += uint96(stake);
_stake.currentEpoch = uint64(currentEpoch);
}
/// @dev Clear stake that will occur in the next epoch
/// (normal behavior).
/// Also withdraws pending rewards to the eth vault.
function undelegateStake(
address delegator,
bytes32 poolId,
uint256 stake
)
external
{
_transferDelegatorsAccumulatedRewardsToEthVault(poolId, delegator);
_syncCumulativeRewardsNeededByDelegator(poolId, currentEpoch);
IStructs.StoredBalance storage _stake =
delegatedStakeToPoolByOwner[delegator][poolId];
if (_stake.currentEpoch < currentEpoch) {
_stake.currentEpochBalance = _stake.nextEpochBalance;
}
_stake.nextEpochBalance -= uint96(stake);
_stake.currentEpoch = uint64(currentEpoch);
}
/// @dev Expose `_recordDepositInRewardVaultFor`.
function recordRewardForDelegators(
bytes32 poolId,
uint256 reward,
uint256 amountOfDelegatedStake
)
external
{
_recordRewardForDelegators(poolId, reward, amountOfDelegatedStake);
}
/// @dev Overridden to just emit events.
function _transferMemberBalanceToEthVault(
bytes32 poolId,
address member,
uint256 balance
)
internal
{
emit Deposit(
poolId,
member,
balance
);
}
/// @dev Overridden to realize unfinalizedMembersRewardByPoolByEpoch in
/// the current epoch and eit a event,
function _finalizePool(bytes32 poolId)
internal
returns (IStructs.PoolRewards memory rewards)
{
UnfinalizedMembersReward memory reward =
unfinalizedMembersRewardByPoolByEpoch[currentEpoch][poolId];
delete unfinalizedMembersRewardByPoolByEpoch[currentEpoch][poolId];
rewards.membersReward = reward.reward;
rewards.membersStake = reward.stake;
_recordRewardForDelegators(poolId, reward.reward, reward.stake);
emit FinalizePool(poolId, reward.reward, reward.stake);
}
/// @dev Overridden to use unfinalizedMembersRewardByPoolByEpoch.
function _getUnfinalizedPoolRewards(bytes32 poolId)
internal
view
returns (IStructs.PoolRewards memory rewards)
{
UnfinalizedMembersReward storage reward =
unfinalizedMembersRewardByPoolByEpoch[currentEpoch][poolId];
rewards.membersReward = reward.reward;
rewards.membersStake = reward.stake;
}
}