Readability Improvements
This commit is contained in:
parent
b5be162fa2
commit
da83f75a13
@ -207,8 +207,8 @@ contract MixinExchangeFees is
|
|||||||
bytes32 poolId = activePoolsThisEpoch[i];
|
bytes32 poolId = activePoolsThisEpoch[i];
|
||||||
|
|
||||||
// compute weighted stake
|
// compute weighted stake
|
||||||
uint256 totalStakeDelegatedToPool = getTotalStakeDelegatedToPool(poolId).current;
|
uint256 totalStakeDelegatedToPool = getTotalStakeDelegatedToPool(poolId).currentEpochBalance;
|
||||||
uint256 stakeHeldByPoolOperator = getStakeDelegatedToPoolByOwner(getStakingPoolOperator(poolId), poolId).current; // @TODO Update
|
uint256 stakeHeldByPoolOperator = getStakeDelegatedToPoolByOwner(getStakingPoolOperator(poolId), poolId).currentEpochBalance;
|
||||||
uint256 weightedStake = stakeHeldByPoolOperator.safeAdd(
|
uint256 weightedStake = stakeHeldByPoolOperator.safeAdd(
|
||||||
totalStakeDelegatedToPool
|
totalStakeDelegatedToPool
|
||||||
.safeSub(stakeHeldByPoolOperator)
|
.safeSub(stakeHeldByPoolOperator)
|
||||||
|
@ -42,19 +42,24 @@ contract MixinStorage is
|
|||||||
address internal stakingContract;
|
address internal stakingContract;
|
||||||
|
|
||||||
// mapping from Owner to Amount of Active Stake
|
// mapping from Owner to Amount of Active Stake
|
||||||
mapping (address => IStructs.DelayedBalance) internal activeStakeByOwner;
|
// (access using _loadAndSyncBalance or _loadUnsyncedBalance)
|
||||||
|
mapping (address => IStructs.StoredBalance) internal activeStakeByOwner;
|
||||||
|
|
||||||
// mapping from Owner to Amount of Inactive Stake
|
// mapping from Owner to Amount of Inactive Stake
|
||||||
mapping (address => IStructs.DelayedBalance) internal inactiveStakeByOwner;
|
// (access using _loadAndSyncBalance or _loadUnsyncedBalance)
|
||||||
|
mapping (address => IStructs.StoredBalance) internal inactiveStakeByOwner;
|
||||||
|
|
||||||
// mapping from Owner to Amount Delegated
|
// mapping from Owner to Amount Delegated
|
||||||
mapping (address => IStructs.DelayedBalance) internal delegatedStakeByOwner;
|
// (access using _loadAndSyncBalance or _loadUnsyncedBalance)
|
||||||
|
mapping (address => IStructs.StoredBalance) internal delegatedStakeByOwner;
|
||||||
|
|
||||||
// mapping from Owner to Pool Id to Amount Delegated
|
// mapping from Owner to Pool Id to Amount Delegated
|
||||||
mapping (address => mapping (bytes32 => IStructs.DelayedBalance)) internal delegatedStakeToPoolByOwner;
|
// (access using _loadAndSyncBalance or _loadUnsyncedBalance)
|
||||||
|
mapping (address => mapping (bytes32 => IStructs.StoredBalance)) internal delegatedStakeToPoolByOwner;
|
||||||
|
|
||||||
// mapping from Pool Id to Amount Delegated
|
// mapping from Pool Id to Amount Delegated
|
||||||
mapping (bytes32 => IStructs.DelayedBalance) internal delegatedStakeByPoolId;
|
// (access using _loadAndSyncBalance or _loadUnsyncedBalance)
|
||||||
|
mapping (bytes32 => IStructs.StoredBalance) internal delegatedStakeByPoolId;
|
||||||
|
|
||||||
// mapping from Owner to Amount of Withdrawable Stake
|
// mapping from Owner to Amount of Withdrawable Stake
|
||||||
mapping (address => uint256) internal withdrawableStakeByOwner;
|
mapping (address => uint256) internal withdrawableStakeByOwner;
|
||||||
|
@ -25,9 +25,9 @@ interface IStakingEvents {
|
|||||||
event MoveStake(
|
event MoveStake(
|
||||||
address indexed owner,
|
address indexed owner,
|
||||||
uint256 amount,
|
uint256 amount,
|
||||||
uint8 fromState,
|
uint8 fromStatus,
|
||||||
bytes32 indexed fromPool,
|
bytes32 indexed fromPool,
|
||||||
uint8 toState,
|
uint8 toStatus,
|
||||||
bytes32 indexed toProol
|
bytes32 indexed toProol
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ interface IStructs {
|
|||||||
address makerAddress;
|
address makerAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev State for Staking Pools (see MixinStakingPool).
|
/// @dev Status for Staking Pools (see MixinStakingPool).
|
||||||
/// @param operatorAddress Address of pool operator.
|
/// @param operatorAddress Address of pool operator.
|
||||||
/// @param operatorShare Portion of pool rewards owned by operator, in ppm.
|
/// @param operatorShare Portion of pool rewards owned by operator, in ppm.
|
||||||
struct Pool {
|
struct Pool {
|
||||||
@ -47,7 +47,7 @@ interface IStructs {
|
|||||||
uint32 operatorShare;
|
uint32 operatorShare;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev State for a pool that actively traded during the current epoch.
|
/// @dev Status for a pool that actively traded during the current epoch.
|
||||||
/// (see MixinExchangeFees).
|
/// (see MixinExchangeFees).
|
||||||
/// @param poolId Unique Id of staking pool.
|
/// @param poolId Unique Id of staking pool.
|
||||||
/// @param feesCollected Fees collected in ETH by this pool in the current epoch.
|
/// @param feesCollected Fees collected in ETH by this pool in the current epoch.
|
||||||
@ -59,33 +59,39 @@ interface IStructs {
|
|||||||
uint256 delegatedStake;
|
uint256 delegatedStake;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev A delayed balance allows values to be computed
|
/// @dev Encapsulates a balance for the current and next epochs.
|
||||||
struct DelayedBalance {
|
/// Note that these balances may be stale if the current epoch
|
||||||
uint96 current;
|
/// is greater than `currentEpoch`.
|
||||||
uint96 next;
|
/// Always load this struct using _loadAndSyncBalance or _loadUnsyncedBalance.
|
||||||
uint64 lastStored;
|
/// @param currentEpoch the current epoch
|
||||||
|
/// @param currentEpochBalance balance in the current epoch.
|
||||||
|
/// @param nextEpochBalance balance in the next epoch.
|
||||||
|
struct StoredBalance {
|
||||||
|
uint64 currentEpoch;
|
||||||
|
uint96 currentEpochBalance;
|
||||||
|
uint96 nextEpochBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Balance struct for stake.
|
/// @dev Balance struct for stake.
|
||||||
/// @param current Balance in the current epoch.
|
/// @param currentEpochBalance Balance in the current epoch.
|
||||||
/// @param next Balance in the next epoch.
|
/// @param nextEpochBalance Balance in the next epoch.
|
||||||
struct StakeBalance {
|
struct StakeBalance {
|
||||||
uint256 current;
|
uint256 currentEpochBalance;
|
||||||
uint256 next;
|
uint256 nextEpochBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev States that stake can exist in.
|
/// @dev Statuses that stake can exist in.
|
||||||
enum StakeState {
|
enum StakeStatus {
|
||||||
ACTIVE,
|
ACTIVE,
|
||||||
INACTIVE,
|
INACTIVE,
|
||||||
DELEGATED
|
DELEGATED
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Info used to describe a state.
|
/// @dev Info used to describe a status.
|
||||||
/// @param state of the stake.
|
/// @param status of the stake.
|
||||||
/// @param poolId Unique Id of pool. This is set when state=DELEGATED.
|
/// @param poolId Unique Id of pool. This is set when status=DELEGATED.
|
||||||
struct StakeStateInfo {
|
struct StakeInfo {
|
||||||
StakeState state;
|
StakeStatus status;
|
||||||
bytes32 poolId;
|
bytes32 poolId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,17 +122,17 @@ library LibStakingRichErrors {
|
|||||||
bytes4 internal constant INVALID_COBB_DOUGLAS_ALPHA_ERROR_SELECTOR =
|
bytes4 internal constant INVALID_COBB_DOUGLAS_ALPHA_ERROR_SELECTOR =
|
||||||
0x8f8e73de;
|
0x8f8e73de;
|
||||||
|
|
||||||
// bytes4(keccak256("EthVaultNotSet()"))
|
// bytes4(keccak256("EthVaultNotSetError()"))
|
||||||
bytes4 internal constant ETH_VAULT_NOT_SET =
|
bytes4 internal constant ETH_VAULT_NOT_SET_ERROR_SELECTOR =
|
||||||
0xdb3f0be8;
|
0xa067f596;
|
||||||
|
|
||||||
// bytes4(keccak256("RewardVaultNotSet()"))
|
// bytes4(keccak256("RewardVaultNotSetError()"))
|
||||||
bytes4 internal constant REWARD_VAULT_NOT_SET =
|
bytes4 internal constant REWARD_VAULT_NOT_SET_ERROR_SELECTOR =
|
||||||
0xfcb260f7;
|
0xe6976d70;
|
||||||
|
|
||||||
// bytes4(keccak256("InvalidStakeState(uint256)"))
|
// bytes4(keccak256("InvalidStakeStatusError(uint256)"))
|
||||||
bytes4 internal constant INVALID_STAKE_STATE =
|
bytes4 internal constant INVALID_STAKE_STATUS_ERROR_SELECTOR =
|
||||||
0xe6586728;
|
0xb7161acd;
|
||||||
|
|
||||||
// solhint-disable func-name-mixedcase
|
// solhint-disable func-name-mixedcase
|
||||||
function MiscalculatedRewardsError(
|
function MiscalculatedRewardsError(
|
||||||
@ -475,34 +475,34 @@ library LibStakingRichErrors {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function EthVaultNotSet()
|
function EthVaultNotSetError()
|
||||||
internal
|
internal
|
||||||
pure
|
pure
|
||||||
returns (bytes memory)
|
returns (bytes memory)
|
||||||
{
|
{
|
||||||
return abi.encodeWithSelector(
|
return abi.encodeWithSelector(
|
||||||
ETH_VAULT_NOT_SET
|
ETH_VAULT_NOT_SET_ERROR_SELECTOR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function RewardVaultNotSet()
|
function RewardVaultNotSetError()
|
||||||
internal
|
internal
|
||||||
pure
|
pure
|
||||||
returns (bytes memory)
|
returns (bytes memory)
|
||||||
{
|
{
|
||||||
return abi.encodeWithSelector(
|
return abi.encodeWithSelector(
|
||||||
REWARD_VAULT_NOT_SET
|
REWARD_VAULT_NOT_SET_ERROR_SELECTOR
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function InvalidStakeState(uint256 state)
|
function InvalidStakeStatusError(uint256 status)
|
||||||
internal
|
internal
|
||||||
pure
|
pure
|
||||||
returns (bytes memory)
|
returns (bytes memory)
|
||||||
{
|
{
|
||||||
return abi.encodeWithSelector(
|
return abi.encodeWithSelector(
|
||||||
INVALID_STAKE_STATE,
|
INVALID_STAKE_STATUS_ERROR_SELECTOR,
|
||||||
state
|
status
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ contract MixinStake is
|
|||||||
using LibSafeMath for uint256;
|
using LibSafeMath for uint256;
|
||||||
|
|
||||||
/// @dev Stake ZRX tokens. Tokens are deposited into the ZRX Vault. Unstake to retrieve the ZRX.
|
/// @dev Stake ZRX tokens. Tokens are deposited into the ZRX Vault. Unstake to retrieve the ZRX.
|
||||||
/// Stake is in the 'Active' state.
|
/// Stake is in the 'Active' status.
|
||||||
/// @param amount of ZRX to stake.
|
/// @param amount of ZRX to stake.
|
||||||
function stake(uint256 amount)
|
function stake(uint256 amount)
|
||||||
external
|
external
|
||||||
@ -55,7 +55,7 @@ contract MixinStake is
|
|||||||
_depositFromOwnerIntoZrxVault(owner, amount);
|
_depositFromOwnerIntoZrxVault(owner, amount);
|
||||||
|
|
||||||
// mint stake
|
// mint stake
|
||||||
_mintBalance(activeStakeByOwner[owner], amount);
|
_incrementCurrentAndNextBalance(activeStakeByOwner[owner], amount);
|
||||||
|
|
||||||
// notify
|
// notify
|
||||||
emit Stake(
|
emit Stake(
|
||||||
@ -65,7 +65,7 @@ contract MixinStake is
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Unstake. Tokens are withdrawn from the ZRX Vault and returned to the owner.
|
/// @dev Unstake. Tokens are withdrawn from the ZRX Vault and returned to the owner.
|
||||||
/// Stake must be in the 'inactive' state for at least one full epoch to unstake.
|
/// Stake must be in the 'inactive' status for at least one full epoch to unstake.
|
||||||
/// @param amount of ZRX to unstake.
|
/// @param amount of ZRX to unstake.
|
||||||
function unstake(uint256 amount)
|
function unstake(uint256 amount)
|
||||||
external
|
external
|
||||||
@ -84,7 +84,7 @@ contract MixinStake is
|
|||||||
}
|
}
|
||||||
|
|
||||||
// burn inactive stake
|
// burn inactive stake
|
||||||
_burnBalance(inactiveStakeByOwner[owner], amount);
|
_decrementCurrentAndNextBalance(inactiveStakeByOwner[owner], amount);
|
||||||
|
|
||||||
// update withdrawable field
|
// update withdrawable field
|
||||||
withdrawableStakeByOwner[owner] = currentWithdrawableStake.safeSub(amount);
|
withdrawableStakeByOwner[owner] = currentWithdrawableStake.safeSub(amount);
|
||||||
@ -99,30 +99,30 @@ contract MixinStake is
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Moves stake between states: 'active', 'inactive' or 'delegated'.
|
/// @dev Moves stake between statuses: 'active', 'inactive' or 'delegated'.
|
||||||
/// This change comes into effect next epoch.
|
/// This change comes into effect next epoch.
|
||||||
/// @param from state to move stake out of.
|
/// @param from status to move stake out of.
|
||||||
/// @param to state to move stake into.
|
/// @param to status to move stake into.
|
||||||
/// @param amount of stake to move.
|
/// @param amount of stake to move.
|
||||||
function moveStake(
|
function moveStake(
|
||||||
IStructs.StakeStateInfo calldata from,
|
IStructs.StakeInfo calldata from,
|
||||||
IStructs.StakeStateInfo calldata to,
|
IStructs.StakeInfo calldata to,
|
||||||
uint256 amount
|
uint256 amount
|
||||||
)
|
)
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
// sanity check - do nothing if moving stake between the same state
|
// sanity check - do nothing if moving stake between the same status
|
||||||
if (from.state != IStructs.StakeState.DELEGATED && from.state == to.state) {
|
if (from.status != IStructs.StakeStatus.DELEGATED && from.status == to.status) {
|
||||||
return;
|
return;
|
||||||
} else if (from.state == IStructs.StakeState.DELEGATED && from.poolId == to.poolId) {
|
} else if (from.status == IStructs.StakeStatus.DELEGATED && from.poolId == to.poolId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
address payable owner = msg.sender;
|
address payable owner = msg.sender;
|
||||||
|
|
||||||
// handle delegation; this must be done before moving stake as the current
|
// handle delegation; this must be done before moving stake as the current
|
||||||
// (out-of-sync) state is used during delegation.
|
// (out-of-sync) status is used during delegation.
|
||||||
if (from.state == IStructs.StakeState.DELEGATED) {
|
if (from.status == IStructs.StakeStatus.DELEGATED) {
|
||||||
_undelegateStake(
|
_undelegateStake(
|
||||||
from.poolId,
|
from.poolId,
|
||||||
owner,
|
owner,
|
||||||
@ -130,7 +130,7 @@ contract MixinStake is
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to.state == IStructs.StakeState.DELEGATED) {
|
if (to.status == IStructs.StakeStatus.DELEGATED) {
|
||||||
_delegateStake(
|
_delegateStake(
|
||||||
to.poolId,
|
to.poolId,
|
||||||
owner,
|
owner,
|
||||||
@ -138,28 +138,28 @@ contract MixinStake is
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// cache the current withdrawal state if we're moving out of the inactive state.
|
// cache the current withdrawal amoiunt, which may change if we're moving out of the inactive status.
|
||||||
uint256 cachedWithdrawableStakeByOwner = (from.state == IStructs.StakeState.INACTIVE)
|
uint256 withdrawableStake = (from.status == IStructs.StakeStatus.INACTIVE)
|
||||||
? getWithdrawableStake(owner)
|
? getWithdrawableStake(owner)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
// execute move
|
// execute move
|
||||||
IStructs.DelayedBalance storage fromPtr = _getBalancePtrFromState(from.state);
|
IStructs.StoredBalance storage fromPtr = _getBalancePtrFromStatus(owner, from.status);
|
||||||
IStructs.DelayedBalance storage toPtr = _getBalancePtrFromState(to.state);
|
IStructs.StoredBalance storage toPtr = _getBalancePtrFromStatus(owner, to.status);
|
||||||
_moveStake(fromPtr, toPtr, amount);
|
_moveStake(fromPtr, toPtr, amount);
|
||||||
|
|
||||||
// update withdrawable field, if necessary
|
// update withdrawable field, if necessary
|
||||||
if (from.state == IStructs.StakeState.INACTIVE) {
|
if (from.status == IStructs.StakeStatus.INACTIVE) {
|
||||||
withdrawableStakeByOwner[owner] = _computeWithdrawableStake(owner, cachedWithdrawableStakeByOwner);
|
withdrawableStakeByOwner[owner] = _computeWithdrawableStake(owner, withdrawableStake);
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify
|
// notify
|
||||||
emit MoveStake(
|
emit MoveStake(
|
||||||
owner,
|
owner,
|
||||||
amount,
|
amount,
|
||||||
uint8(from.state),
|
uint8(from.status),
|
||||||
from.poolId,
|
from.poolId,
|
||||||
uint8(to.state),
|
uint8(to.status),
|
||||||
to.poolId
|
to.poolId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -183,10 +183,10 @@ contract MixinStake is
|
|||||||
_syncCumulativeRewardsNeededByDelegator(poolId, currentEpoch);
|
_syncCumulativeRewardsNeededByDelegator(poolId, currentEpoch);
|
||||||
|
|
||||||
// increment how much stake the owner has delegated to the input pool
|
// increment how much stake the owner has delegated to the input pool
|
||||||
_incrementBalance(delegatedStakeToPoolByOwner[owner][poolId], amount);
|
_incrementNextBalance(delegatedStakeToPoolByOwner[owner][poolId], amount);
|
||||||
|
|
||||||
// increment how much stake has been delegated to pool
|
// increment how much stake has been delegated to pool
|
||||||
_incrementBalance(delegatedStakeByPoolId[poolId], amount);
|
_incrementNextBalance(delegatedStakeByPoolId[poolId], amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Un-Delegates a owners stake from a staking pool.
|
/// @dev Un-Delegates a owners stake from a staking pool.
|
||||||
@ -208,33 +208,33 @@ contract MixinStake is
|
|||||||
_syncCumulativeRewardsNeededByDelegator(poolId, currentEpoch);
|
_syncCumulativeRewardsNeededByDelegator(poolId, currentEpoch);
|
||||||
|
|
||||||
// decrement how much stake the owner has delegated to the input pool
|
// decrement how much stake the owner has delegated to the input pool
|
||||||
_decrementBalance(delegatedStakeToPoolByOwner[owner][poolId], amount);
|
_decrementNextBalance(delegatedStakeToPoolByOwner[owner][poolId], amount);
|
||||||
|
|
||||||
// decrement how much stake has been delegated to pool
|
// decrement how much stake has been delegated to pool
|
||||||
_decrementBalance(delegatedStakeByPoolId[poolId], amount);
|
_decrementNextBalance(delegatedStakeByPoolId[poolId], amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Returns a storage pointer to a user's stake in a given state.
|
/// @dev Returns a storage pointer to a user's stake in a given status.
|
||||||
/// @param state of user's stake to lookup.
|
/// @param owner of stake to query.
|
||||||
|
/// @param status of user's stake to lookup.
|
||||||
/// @return a storage pointer to the corresponding stake stake
|
/// @return a storage pointer to the corresponding stake stake
|
||||||
function _getBalancePtrFromState(IStructs.StakeState state)
|
function _getBalancePtrFromStatus(address owner, IStructs.StakeStatus status)
|
||||||
private
|
private
|
||||||
view
|
view
|
||||||
returns (IStructs.DelayedBalance storage)
|
returns (IStructs.StoredBalance storage)
|
||||||
{
|
{
|
||||||
// lookup state
|
// lookup status
|
||||||
address owner = msg.sender;
|
if (status == IStructs.StakeStatus.ACTIVE) {
|
||||||
if (state == IStructs.StakeState.ACTIVE) {
|
|
||||||
return activeStakeByOwner[owner];
|
return activeStakeByOwner[owner];
|
||||||
} else if (state == IStructs.StakeState.INACTIVE) {
|
} else if (status == IStructs.StakeStatus.INACTIVE) {
|
||||||
return inactiveStakeByOwner[owner];
|
return inactiveStakeByOwner[owner];
|
||||||
} else if (state == IStructs.StakeState.DELEGATED) {
|
} else if (status == IStructs.StakeStatus.DELEGATED) {
|
||||||
return delegatedStakeByOwner[owner];
|
return delegatedStakeByOwner[owner];
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalid state
|
// invalid status
|
||||||
LibRichErrors.rrevert(
|
LibRichErrors.rrevert(
|
||||||
LibStakingRichErrors.InvalidStakeState(uint256(state))
|
LibStakingRichErrors.InvalidStakeStatusError(uint256(status))
|
||||||
);
|
);
|
||||||
|
|
||||||
// required to compile ~ we should never hit this.
|
// required to compile ~ we should never hit this.
|
||||||
|
@ -59,10 +59,10 @@ contract MixinStakeBalances is
|
|||||||
view
|
view
|
||||||
returns (IStructs.StakeBalance memory balance)
|
returns (IStructs.StakeBalance memory balance)
|
||||||
{
|
{
|
||||||
IStructs.DelayedBalance memory storedBalance = _syncBalanceDestructive(activeStakeByOwner[owner]);
|
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(activeStakeByOwner[owner]);
|
||||||
return IStructs.StakeBalance({
|
return IStructs.StakeBalance({
|
||||||
current: storedBalance.current,
|
currentEpochBalance: storedBalance.currentEpochBalance,
|
||||||
next: storedBalance.next
|
nextEpochBalance: storedBalance.nextEpochBalance
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,10 +74,10 @@ contract MixinStakeBalances is
|
|||||||
view
|
view
|
||||||
returns (IStructs.StakeBalance memory balance)
|
returns (IStructs.StakeBalance memory balance)
|
||||||
{
|
{
|
||||||
IStructs.DelayedBalance memory storedBalance = _syncBalanceDestructive(inactiveStakeByOwner[owner]);
|
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(inactiveStakeByOwner[owner]);
|
||||||
return IStructs.StakeBalance({
|
return IStructs.StakeBalance({
|
||||||
current: storedBalance.current,
|
currentEpochBalance: storedBalance.currentEpochBalance,
|
||||||
next: storedBalance.next
|
nextEpochBalance: storedBalance.nextEpochBalance
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,8 +89,7 @@ contract MixinStakeBalances is
|
|||||||
view
|
view
|
||||||
returns (uint256)
|
returns (uint256)
|
||||||
{
|
{
|
||||||
uint256 cachedWithdrawableStakeByOwner = withdrawableStakeByOwner[owner];
|
return _computeWithdrawableStake(owner, withdrawableStakeByOwner[owner]);
|
||||||
return _computeWithdrawableStake(owner, cachedWithdrawableStakeByOwner);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Returns the stake delegated by a given owner.
|
/// @dev Returns the stake delegated by a given owner.
|
||||||
@ -101,10 +100,10 @@ contract MixinStakeBalances is
|
|||||||
view
|
view
|
||||||
returns (IStructs.StakeBalance memory balance)
|
returns (IStructs.StakeBalance memory balance)
|
||||||
{
|
{
|
||||||
IStructs.DelayedBalance memory storedBalance = _syncBalanceDestructive(delegatedStakeByOwner[owner]);
|
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(delegatedStakeByOwner[owner]);
|
||||||
return IStructs.StakeBalance({
|
return IStructs.StakeBalance({
|
||||||
current: storedBalance.current,
|
currentEpochBalance: storedBalance.currentEpochBalance,
|
||||||
next: storedBalance.next
|
nextEpochBalance: storedBalance.nextEpochBalance
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,10 +116,10 @@ contract MixinStakeBalances is
|
|||||||
view
|
view
|
||||||
returns (IStructs.StakeBalance memory balance)
|
returns (IStructs.StakeBalance memory balance)
|
||||||
{
|
{
|
||||||
IStructs.DelayedBalance memory storedBalance = _syncBalanceDestructive(delegatedStakeToPoolByOwner[owner][poolId]);
|
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(delegatedStakeToPoolByOwner[owner][poolId]);
|
||||||
return IStructs.StakeBalance({
|
return IStructs.StakeBalance({
|
||||||
current: storedBalance.current,
|
currentEpochBalance: storedBalance.currentEpochBalance,
|
||||||
next: storedBalance.next
|
nextEpochBalance: storedBalance.nextEpochBalance
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,31 +131,31 @@ contract MixinStakeBalances is
|
|||||||
view
|
view
|
||||||
returns (IStructs.StakeBalance memory balance)
|
returns (IStructs.StakeBalance memory balance)
|
||||||
{
|
{
|
||||||
IStructs.DelayedBalance memory storedBalance = _syncBalanceDestructive(delegatedStakeByPoolId[poolId]);
|
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(delegatedStakeByPoolId[poolId]);
|
||||||
return IStructs.StakeBalance({
|
return IStructs.StakeBalance({
|
||||||
current: storedBalance.current,
|
currentEpochBalance: storedBalance.currentEpochBalance,
|
||||||
next: storedBalance.next
|
nextEpochBalance: storedBalance.nextEpochBalance
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Returns the stake that can be withdrawn for a given owner.
|
/// @dev Returns the stake that can be withdrawn for a given owner.
|
||||||
/// This stake is in the "Deactive & Withdrawable" state.
|
|
||||||
/// @param owner to query.
|
/// @param owner to query.
|
||||||
|
/// @param lastStoredWithdrawableStake The amount of withdrawable stake that was last stored.
|
||||||
/// @return Withdrawable stake for owner.
|
/// @return Withdrawable stake for owner.
|
||||||
function _computeWithdrawableStake(address owner, uint256 cachedWithdrawableStakeByOwner)
|
function _computeWithdrawableStake(address owner, uint256 lastStoredWithdrawableStake)
|
||||||
internal
|
internal
|
||||||
view
|
view
|
||||||
returns (uint256)
|
returns (uint256)
|
||||||
{
|
{
|
||||||
// stake cannot be withdrawn if it has been reallocated for the `next` epoch;
|
// stake cannot be withdrawn if it has been reallocated for the `next` epoch;
|
||||||
// so the upper bound of withdrawable stake is always limited by the value of `next`.
|
// so the upper bound of withdrawable stake is always limited by the value of `next`.
|
||||||
IStructs.DelayedBalance memory storedBalance = inactiveStakeByOwner[owner];
|
IStructs.StoredBalance memory storedBalance = _loadUnsyncedBalance(inactiveStakeByOwner[owner]);
|
||||||
if (storedBalance.lastStored == currentEpoch) {
|
if (storedBalance.currentEpoch == currentEpoch) {
|
||||||
return storedBalance.next < cachedWithdrawableStakeByOwner ? storedBalance.next : cachedWithdrawableStakeByOwner;
|
return LibSafeMath.min256(storedBalance.nextEpochBalance, lastStoredWithdrawableStake);
|
||||||
} else if (uint256(storedBalance.lastStored).safeAdd(1) == currentEpoch) {
|
} else if (uint256(storedBalance.currentEpoch).safeAdd(1) == currentEpoch) {
|
||||||
return storedBalance.next < storedBalance.current ? storedBalance.next : storedBalance.current;
|
return LibSafeMath.min256(storedBalance.nextEpochBalance, storedBalance.currentEpochBalance);
|
||||||
} else {
|
} else {
|
||||||
return storedBalance.next;
|
return storedBalance.nextEpochBalance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,7 @@ contract MixinStakeStorage is
|
|||||||
{
|
{
|
||||||
|
|
||||||
using LibSafeMath for uint256;
|
using LibSafeMath for uint256;
|
||||||
|
using LibSafeDowncast for uint256;
|
||||||
|
|
||||||
/// @dev Moves stake between states: 'active', 'inactive' or 'delegated'.
|
/// @dev Moves stake between states: 'active', 'inactive' or 'delegated'.
|
||||||
/// This change comes into effect next epoch.
|
/// This change comes into effect next epoch.
|
||||||
@ -43,8 +44,8 @@ contract MixinStakeStorage is
|
|||||||
/// @param toPtr pointer to storage location of `to` stake.
|
/// @param toPtr pointer to storage location of `to` stake.
|
||||||
/// @param amount of stake to move.
|
/// @param amount of stake to move.
|
||||||
function _moveStake(
|
function _moveStake(
|
||||||
IStructs.DelayedBalance storage fromPtr,
|
IStructs.StoredBalance storage fromPtr,
|
||||||
IStructs.DelayedBalance storage toPtr,
|
IStructs.StoredBalance storage toPtr,
|
||||||
uint256 amount
|
uint256 amount
|
||||||
)
|
)
|
||||||
internal
|
internal
|
||||||
@ -55,104 +56,118 @@ contract MixinStakeStorage is
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load balance from storage and synchronize it
|
// load balance from storage and synchronize it
|
||||||
IStructs.DelayedBalance memory from = _syncBalanceDestructive(fromPtr);
|
IStructs.StoredBalance memory from = _loadAndSyncBalance(fromPtr);
|
||||||
IStructs.DelayedBalance memory to = _syncBalanceDestructive(toPtr);
|
IStructs.StoredBalance memory to = _loadAndSyncBalance(toPtr);
|
||||||
|
|
||||||
// sanity check on balance
|
// sanity check on balance
|
||||||
if (amount > from.next) {
|
if (amount > from.nextEpochBalance) {
|
||||||
LibRichErrors.rrevert(
|
LibRichErrors.rrevert(
|
||||||
LibStakingRichErrors.InsufficientBalanceError(
|
LibStakingRichErrors.InsufficientBalanceError(
|
||||||
amount,
|
amount,
|
||||||
from.next
|
from.nextEpochBalance
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// move stake for next epoch
|
// move stake for next epoch
|
||||||
from.next = LibSafeDowncast.downcastToUint96(uint256(from.next).safeSub(amount));
|
from.nextEpochBalance = uint256(from.nextEpochBalance).safeSub(amount).downcastToUint96();
|
||||||
to.next = LibSafeDowncast.downcastToUint96(uint256(to.next).safeAdd(amount));
|
to.nextEpochBalance = uint256(to.nextEpochBalance).safeAdd(amount).downcastToUint96();
|
||||||
|
|
||||||
// update state in storage
|
// update state in storage
|
||||||
_storeBalance(fromPtr, from);
|
_storeBalance(fromPtr, from);
|
||||||
_storeBalance(toPtr, to);
|
_storeBalance(toPtr, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Synchronizes the fields of a stored balance.
|
/// @dev Loads a balance from storage and synchronizes its current/next fields.
|
||||||
/// The structs `current` field is set to `next` if the
|
/// The structs `current` field is set to `next` if the
|
||||||
/// current epoch is greater than the epoch in which the struct
|
/// current epoch is greater than the epoch in which the struct
|
||||||
/// was stored.
|
/// was stored.
|
||||||
/// @param balance to update. This will be equal to the return value after calling.
|
/// @param balancePtr to load and sync.
|
||||||
/// @return synchronized balance.
|
/// @return synchronized balance.
|
||||||
function _syncBalanceDestructive(IStructs.DelayedBalance memory balance)
|
function _loadAndSyncBalance(IStructs.StoredBalance storage balancePtr)
|
||||||
internal
|
internal
|
||||||
view
|
view
|
||||||
returns (IStructs.DelayedBalance memory)
|
returns (IStructs.StoredBalance memory balance)
|
||||||
{
|
{
|
||||||
|
// load from storage
|
||||||
|
balance = balancePtr;
|
||||||
|
// sync
|
||||||
uint256 currentEpoch = getCurrentEpoch();
|
uint256 currentEpoch = getCurrentEpoch();
|
||||||
if (currentEpoch > balance.lastStored) {
|
if (currentEpoch > balance.currentEpoch) {
|
||||||
balance.lastStored = LibSafeDowncast.downcastToUint64(currentEpoch);
|
balance.currentEpoch = currentEpoch.downcastToUint64();
|
||||||
balance.current = balance.next;
|
balance.currentEpochBalance = balance.nextEpochBalance;
|
||||||
}
|
}
|
||||||
return balance;
|
return balance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Mints new value in a balance.
|
/// @dev Loads a balance from storage without synchronizing its fields.
|
||||||
/// This causes both the `current` and `next` fields to increase immediately.
|
/// This function exists so that developers will have to explicitly
|
||||||
|
/// communicate that they're loading a synchronized or unsynchronized balance.
|
||||||
|
/// These balances should never be accessed directly.
|
||||||
|
/// @param balancePtr to load.
|
||||||
|
/// @return unsynchronized balance.
|
||||||
|
function _loadUnsyncedBalance(IStructs.StoredBalance storage balancePtr)
|
||||||
|
internal
|
||||||
|
view
|
||||||
|
returns (IStructs.StoredBalance memory balance)
|
||||||
|
{
|
||||||
|
balance = balancePtr;
|
||||||
|
return balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @dev Increments both the `current` and `next` fields.
|
||||||
/// @param balancePtr storage pointer to balance.
|
/// @param balancePtr storage pointer to balance.
|
||||||
/// @param amount to mint.
|
/// @param amount to mint.
|
||||||
function _mintBalance(IStructs.DelayedBalance storage balancePtr, uint256 amount)
|
function _incrementCurrentAndNextBalance(IStructs.StoredBalance storage balancePtr, uint256 amount)
|
||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
// Remove stake from balance
|
// Remove stake from balance
|
||||||
IStructs.DelayedBalance memory balance = _syncBalanceDestructive(balancePtr);
|
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr);
|
||||||
balance.next = LibSafeDowncast.downcastToUint96(uint256(balance.next).safeAdd(amount));
|
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeAdd(amount).downcastToUint96();
|
||||||
balance.current = LibSafeDowncast.downcastToUint96(uint256(balance.current).safeAdd(amount));
|
balance.currentEpochBalance = uint256(balance.currentEpochBalance).safeAdd(amount).downcastToUint96();
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
_storeBalance(balancePtr, balance);
|
_storeBalance(balancePtr, balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Burns existing value in a balance.
|
/// @dev Decrements both the `current` and `next` fields.
|
||||||
/// This causes both the `current` and `next` fields to decrease immediately.
|
|
||||||
/// @param balancePtr storage pointer to balance.
|
/// @param balancePtr storage pointer to balance.
|
||||||
/// @param amount to mint.
|
/// @param amount to mint.
|
||||||
function _burnBalance(IStructs.DelayedBalance storage balancePtr, uint256 amount)
|
function _decrementCurrentAndNextBalance(IStructs.StoredBalance storage balancePtr, uint256 amount)
|
||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
// Remove stake from balance
|
// Remove stake from balance
|
||||||
IStructs.DelayedBalance memory balance = _syncBalanceDestructive(balancePtr);
|
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr);
|
||||||
balance.next = LibSafeDowncast.downcastToUint96(uint256(balance.next).safeSub(amount));
|
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeSub(amount).downcastToUint96();
|
||||||
balance.current = LibSafeDowncast.downcastToUint96(uint256(balance.current).safeSub(amount));
|
balance.currentEpochBalance = uint256(balance.currentEpochBalance).safeSub(amount).downcastToUint96();
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
_storeBalance(balancePtr, balance);
|
_storeBalance(balancePtr, balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Increments a balance.
|
/// @dev Increments the `next` field (but not the `current` field).
|
||||||
/// Ths updates the `next` field but not the `current` field.
|
|
||||||
/// @param balancePtr storage pointer to balance.
|
/// @param balancePtr storage pointer to balance.
|
||||||
/// @param amount to increment by.
|
/// @param amount to increment by.
|
||||||
function _incrementBalance(IStructs.DelayedBalance storage balancePtr, uint256 amount)
|
function _incrementNextBalance(IStructs.StoredBalance storage balancePtr, uint256 amount)
|
||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
// Add stake to balance
|
// Add stake to balance
|
||||||
IStructs.DelayedBalance memory balance = _syncBalanceDestructive(balancePtr);
|
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr);
|
||||||
balance.next = LibSafeDowncast.downcastToUint96(uint256(balance.next).safeAdd(amount));
|
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeAdd(amount).downcastToUint96();
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
_storeBalance(balancePtr, balance);
|
_storeBalance(balancePtr, balance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Decrements a balance.
|
/// @dev Decrements the `next` field (but not the `current` field).
|
||||||
/// Ths updates the `next` field but not the `current` field.
|
|
||||||
/// @param balancePtr storage pointer to balance.
|
/// @param balancePtr storage pointer to balance.
|
||||||
/// @param amount to decrement by.
|
/// @param amount to decrement by.
|
||||||
function _decrementBalance(IStructs.DelayedBalance storage balancePtr, uint256 amount)
|
function _decrementNextBalance(IStructs.StoredBalance storage balancePtr, uint256 amount)
|
||||||
internal
|
internal
|
||||||
{
|
{
|
||||||
// Remove stake from balance
|
// Remove stake from balance
|
||||||
IStructs.DelayedBalance memory balance = _syncBalanceDestructive(balancePtr);
|
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr);
|
||||||
balance.next = LibSafeDowncast.downcastToUint96(uint256(balance.next).safeSub(amount));
|
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeSub(amount).downcastToUint96();
|
||||||
|
|
||||||
// update state
|
// update state
|
||||||
_storeBalance(balancePtr, balance);
|
_storeBalance(balancePtr, balance);
|
||||||
@ -162,16 +177,16 @@ contract MixinStakeStorage is
|
|||||||
/// @param balancePtr points to where `balance` will be stored.
|
/// @param balancePtr points to where `balance` will be stored.
|
||||||
/// @param balance to save to storage.
|
/// @param balance to save to storage.
|
||||||
function _storeBalance(
|
function _storeBalance(
|
||||||
IStructs.DelayedBalance storage balancePtr,
|
IStructs.StoredBalance storage balancePtr,
|
||||||
IStructs.DelayedBalance memory balance
|
IStructs.StoredBalance memory balance
|
||||||
)
|
)
|
||||||
private
|
private
|
||||||
{
|
{
|
||||||
// note - this compresses into a single `sstore` when optimizations are enabled,
|
// note - this compresses into a single `sstore` when optimizations are enabled,
|
||||||
// since the StakeBalance struct occupies a single word of storage.
|
// since the StakeBalance struct occupies a single word of storage.
|
||||||
balancePtr.lastStored = balance.lastStored;
|
balancePtr.currentEpoch = balance.currentEpoch;
|
||||||
balancePtr.next = balance.next;
|
balancePtr.nextEpochBalance = balance.nextEpochBalance;
|
||||||
balancePtr.current = balance.current;
|
balancePtr.currentEpochBalance = balance.currentEpochBalance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @dev Returns true iff storage pointers resolve to same storage location.
|
/// @dev Returns true iff storage pointers resolve to same storage location.
|
||||||
@ -180,9 +195,9 @@ contract MixinStakeStorage is
|
|||||||
/// @return true iff pointers are equal.
|
/// @return true iff pointers are equal.
|
||||||
function _arePointersEqual(
|
function _arePointersEqual(
|
||||||
// solhint-disable-next-line no-unused-vars
|
// solhint-disable-next-line no-unused-vars
|
||||||
IStructs.DelayedBalance storage balancePtrA,
|
IStructs.StoredBalance storage balancePtrA,
|
||||||
// solhint-disable-next-line no-unused-vars
|
// solhint-disable-next-line no-unused-vars
|
||||||
IStructs.DelayedBalance storage balancePtrB
|
IStructs.StoredBalance storage balancePtrB
|
||||||
)
|
)
|
||||||
private
|
private
|
||||||
pure
|
pure
|
||||||
|
@ -73,7 +73,7 @@ contract MixinStakingPoolRewardVault is
|
|||||||
address payable rewardVaultAddress = address(uint160(address(rewardVault)));
|
address payable rewardVaultAddress = address(uint160(address(rewardVault)));
|
||||||
if (rewardVaultAddress == NIL_ADDRESS) {
|
if (rewardVaultAddress == NIL_ADDRESS) {
|
||||||
LibRichErrors.rrevert(
|
LibRichErrors.rrevert(
|
||||||
LibStakingRichErrors.RewardVaultNotSet()
|
LibStakingRichErrors.RewardVaultNotSetError()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +96,7 @@ contract MixinStakingPoolRewardVault is
|
|||||||
IStakingPoolRewardVault _rewardVault = rewardVault;
|
IStakingPoolRewardVault _rewardVault = rewardVault;
|
||||||
if (address(_rewardVault) == NIL_ADDRESS) {
|
if (address(_rewardVault) == NIL_ADDRESS) {
|
||||||
LibRichErrors.rrevert(
|
LibRichErrors.rrevert(
|
||||||
LibStakingRichErrors.RewardVaultNotSet()
|
LibStakingRichErrors.RewardVaultNotSetError()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,33 +48,32 @@ contract MixinStakingPoolRewards is
|
|||||||
returns (uint256 totalReward)
|
returns (uint256 totalReward)
|
||||||
{
|
{
|
||||||
// cache some values to reduce sloads
|
// cache some values to reduce sloads
|
||||||
IStructs.DelayedBalance memory delegatedStake = delegatedStakeToPoolByOwner[member][poolId];
|
IStructs.StoredBalance memory delegatedStake = _loadUnsyncedBalance(delegatedStakeToPoolByOwner[member][poolId]);
|
||||||
uint256 currentEpoch = getCurrentEpoch();
|
uint256 currentEpoch = getCurrentEpoch();
|
||||||
|
|
||||||
// value is always zero in these two scenarios:
|
// value is always zero in these two scenarios:
|
||||||
// 1. The current epoch is zero: delegation begins at epoch 1
|
// 1. The owner's delegated is current as of this epoch: their rewards have been moved to the ETH vault.
|
||||||
// 2. The owner's delegated is current as of this epoch: their rewards have been moved to the ETH vault.
|
// 2. The current epoch is zero: delegation begins at epoch 1
|
||||||
if (currentEpoch == 0 || delegatedStake.lastStored == currentEpoch) return 0;
|
if (delegatedStake.currentEpoch == currentEpoch || currentEpoch == 0) return 0;
|
||||||
|
|
||||||
// compute reward accumulated during `lastStored` epoch;
|
// compute reward accumulated during `delegatedStake.currentEpoch`;
|
||||||
// the `current` balance describes how much stake was collecting rewards when `lastStored` was set.
|
uint256 rewardsAccumulatedDuringLastStoredEpoch = (delegatedStake.currentEpochBalance != 0)
|
||||||
uint256 rewardsAccumulatedDuringLastStoredEpoch = (delegatedStake.current != 0)
|
|
||||||
? _computeMemberRewardOverInterval(
|
? _computeMemberRewardOverInterval(
|
||||||
poolId,
|
poolId,
|
||||||
delegatedStake.current,
|
delegatedStake.currentEpochBalance,
|
||||||
delegatedStake.lastStored - 1,
|
delegatedStake.currentEpoch - 1,
|
||||||
delegatedStake.lastStored
|
delegatedStake.currentEpoch
|
||||||
)
|
)
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
// compute the rewards accumulated by the `next` balance;
|
// compute the reward accumulated by the `next` balance;
|
||||||
// this starts at `lastStored + 1` and goes up until the last epoch, during which
|
// this starts at `delegatedStake.currentEpoch + 1` and goes up until the last epoch, during which
|
||||||
// rewards were accumulated. This is at most the most recently finalized epoch (current epoch - 1).
|
// rewards were accumulated. This is at most the most recently finalized epoch (current epoch - 1).
|
||||||
uint256 rewardsAccumulatedAfterLastStoredEpoch = (cumulativeRewardsByPoolLastStored[poolId] > delegatedStake.lastStored)
|
uint256 rewardsAccumulatedAfterLastStoredEpoch = (cumulativeRewardsByPoolLastStored[poolId] > delegatedStake.currentEpoch)
|
||||||
? _computeMemberRewardOverInterval(
|
? _computeMemberRewardOverInterval(
|
||||||
poolId,
|
poolId,
|
||||||
delegatedStake.next,
|
delegatedStake.nextEpochBalance,
|
||||||
delegatedStake.lastStored,
|
delegatedStake.currentEpoch,
|
||||||
cumulativeRewardsByPoolLastStored[poolId]
|
cumulativeRewardsByPoolLastStored[poolId]
|
||||||
)
|
)
|
||||||
: 0;
|
: 0;
|
||||||
|
@ -34,7 +34,7 @@ import "../interfaces/IVaultCore.sol";
|
|||||||
/// recoverable flaw/bug/vulnerability, simply detach the staking contract
|
/// recoverable flaw/bug/vulnerability, simply detach the staking contract
|
||||||
/// by setting its address to `address(0)`. Once in Catastrophic Failure Mode,
|
/// by setting its address to `address(0)`. Once in Catastrophic Failure Mode,
|
||||||
/// a vault cannot be reset to normal mode; this prevents corruption of related
|
/// a vault cannot be reset to normal mode; this prevents corruption of related
|
||||||
/// state in the staking contract.
|
/// status in the staking contract.
|
||||||
contract MixinVaultCore is
|
contract MixinVaultCore is
|
||||||
Authorizable,
|
Authorizable,
|
||||||
IVaultCore
|
IVaultCore
|
||||||
|
@ -280,7 +280,7 @@ contract StakingPoolRewardVault is
|
|||||||
IEthVault _ethVault = ethVault;
|
IEthVault _ethVault = ethVault;
|
||||||
if (address(_ethVault) == address(0)) {
|
if (address(_ethVault) == address(0)) {
|
||||||
LibRichErrors.rrevert(
|
LibRichErrors.rrevert(
|
||||||
LibStakingRichErrors.EthVaultNotSet()
|
LibStakingRichErrors.EthVaultNotSetError()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ export class Simulation {
|
|||||||
await this._withdrawRewardForStakingPoolMemberForDelegatorsByUndelegatingAsync(this._p);
|
await this._withdrawRewardForStakingPoolMemberForDelegatorsByUndelegatingAsync(this._p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @TODO cleanup state and verify the staking contract is empty
|
// @TODO cleanup status and verify the staking contract is empty
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _withdrawRewardForStakingPoolMemberForDelegatorsByUndelegatingAsync(
|
private async _withdrawRewardForStakingPoolMemberForDelegatorsByUndelegatingAsync(
|
||||||
|
@ -203,27 +203,27 @@ export class StakingWrapper {
|
|||||||
}
|
}
|
||||||
public async moveStakeAsync(
|
public async moveStakeAsync(
|
||||||
owner: string,
|
owner: string,
|
||||||
_fromState: {
|
_fromStatus: {
|
||||||
state: number,
|
status: number,
|
||||||
poolId?: string
|
poolId?: string
|
||||||
},
|
},
|
||||||
_toState: {
|
_toStatus: {
|
||||||
state: number,
|
status: number,
|
||||||
poolId?: string
|
poolId?: string
|
||||||
},
|
},
|
||||||
amount: BigNumber,
|
amount: BigNumber,
|
||||||
): Promise<TransactionReceiptWithDecodedLogs> {
|
): Promise<TransactionReceiptWithDecodedLogs> {
|
||||||
const fromState = {
|
const fromStatus = {
|
||||||
state: _fromState.state,
|
status: _fromStatus.status,
|
||||||
poolId: _fromState.poolId !== undefined ? _fromState.poolId : constants.NIL_POOL_ID
|
poolId: _fromStatus.poolId !== undefined ? _fromStatus.poolId : constants.NIL_POOL_ID
|
||||||
};
|
};
|
||||||
const toState = {
|
const toStatus = {
|
||||||
state: _toState.state,
|
status: _toStatus.status,
|
||||||
poolId: _toState.poolId !== undefined ? _toState.poolId : constants.NIL_POOL_ID
|
poolId: _toStatus.poolId !== undefined ? _toStatus.poolId : constants.NIL_POOL_ID
|
||||||
};
|
};
|
||||||
const calldata = this.getStakingContract().moveStake.getABIEncodedTransactionData(
|
const calldata = this.getStakingContract().moveStake.getABIEncodedTransactionData(
|
||||||
fromState,
|
fromStatus,
|
||||||
toState,
|
toStatus,
|
||||||
amount,
|
amount,
|
||||||
);
|
);
|
||||||
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
const txReceipt = await this._executeTransactionAsync(calldata, owner);
|
||||||
|
@ -50,11 +50,11 @@ export interface SimulationParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface StakeBalance {
|
export interface StakeBalance {
|
||||||
current: BigNumber,
|
currentEpochBalance: BigNumber,
|
||||||
next: BigNumber,
|
nextEpochBalance: BigNumber,
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum StakeStateId {
|
export enum StakeStatus {
|
||||||
ACTIVE,
|
ACTIVE,
|
||||||
INACTIVE,
|
INACTIVE,
|
||||||
DELEGATED
|
DELEGATED
|
||||||
|
@ -6,8 +6,6 @@ import "./LibSafeMathRichErrors.sol";
|
|||||||
|
|
||||||
library LibSafeMath {
|
library LibSafeMath {
|
||||||
|
|
||||||
using LibSafeMath for uint256;
|
|
||||||
|
|
||||||
function safeMul(uint256 a, uint256 b)
|
function safeMul(uint256 a, uint256 b)
|
||||||
internal
|
internal
|
||||||
pure
|
pure
|
||||||
|
@ -293,6 +293,7 @@ const types = [
|
|||||||
TransactionGasPriceError,
|
TransactionGasPriceError,
|
||||||
TransactionInvalidContextError,
|
TransactionInvalidContextError,
|
||||||
TransactionSignatureError,
|
TransactionSignatureError,
|
||||||
|
IncompleteFillError,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Register the types we've defined.
|
// Register the types we've defined.
|
||||||
|
@ -204,21 +204,21 @@ export class InvalidCobbDouglasAlphaError extends RevertError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class EthVaultNotSet extends RevertError {
|
export class EthVaultNotSetError extends RevertError {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('EthVaultNotSet', 'EthVaultNotSet()');
|
super('EthVaultNotSetError', 'EthVaultNotSetError()');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RewardVaultNotSet extends RevertError {
|
export class RewardVaultNotSetError extends RevertError {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('RewardVaultNotSet', 'RewardVaultNotSet()');
|
super('RewardVaultNotSetError', 'RewardVaultNotSetError()');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class InvalidStakeState extends RevertError {
|
export class InvalidStakeStatusError extends RevertError {
|
||||||
constructor(state?: BigNumber) {
|
constructor(status?: BigNumber) {
|
||||||
super('InvalidStakeState', 'InvalidStakeState(uint256 state)', { state });
|
super('InvalidStakeStatusError', 'InvalidStakeStatusError(uint256 status)', { status });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,9 +248,9 @@ const types = [
|
|||||||
InvalidPoolOperatorShareError,
|
InvalidPoolOperatorShareError,
|
||||||
PoolAlreadyExistsError,
|
PoolAlreadyExistsError,
|
||||||
InvalidCobbDouglasAlphaError,
|
InvalidCobbDouglasAlphaError,
|
||||||
EthVaultNotSet,
|
EthVaultNotSetError,
|
||||||
RewardVaultNotSet,
|
RewardVaultNotSetError,
|
||||||
InvalidStakeState
|
InvalidStakeStatusError
|
||||||
];
|
];
|
||||||
|
|
||||||
// Register the types we've defined.
|
// Register the types we've defined.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user