moved natspec to above contract definition

This commit is contained in:
Greg Hysen
2019-08-20 16:07:05 -07:00
parent 41b372ffe6
commit c939fe2287
21 changed files with 256 additions and 272 deletions

View File

@@ -31,6 +31,15 @@ import "../staking_pools/MixinStakingPoolRewardVault.sol";
import "./MixinExchangeManager.sol";
/// @dev This mixin contains the logic for 0x protocol fees.
/// Protocol fees are sent by 0x exchanges every time there is a trade.
/// If the maker has associated their address with a pool (see MixinStakingPool.sol), then
/// the fee will be attributed to their pool. At the end of an epoch the maker and
/// their pool will receive a rebate that is proportional to (i) the fee volume attributed
/// to their pool over the epoch, and (ii) the amount of stake provided by the maker and
/// their delegators. Note that delegated stake (see MixinStake) is weighted less than
/// stake provided by directly by the maker; this is a disincentive for market makers to
/// monopolize a single pool that they all delegate to.
contract MixinExchangeFees is
IStakingEvents,
MixinDeploymentConstants,
@@ -45,16 +54,6 @@ contract MixinExchangeFees is
MixinStakeBalances
{
/// @dev This mixin contains the logic for 0x protocol fees.
/// Protocol fees are sent by 0x exchanges every time there is a trade.
/// If the maker has associated their address with a pool (see MixinStakingPool.sol), then
/// the fee will be attributed to their pool. At the end of an epoch the maker and
/// their pool will receive a rebate that is proportional to (i) the fee volume attributed
/// to their pool over the epoch, and (ii) the amount of stake provided by the maker and
/// their delegators. Note that delegated stake (see MixinStake) is weighted less than
/// stake provided by directly by the maker; this is a disincentive for market makers to
/// monopolize a single pool that they all delegate to.
using LibSafeMath for uint256;
/// @dev Pays a protocol fee in ETH.

View File

@@ -24,6 +24,10 @@ import "../immutable/MixinStorage.sol";
import "../sys/MixinOwnable.sol";
/// @dev This mixin contains logic for managing exchanges.
/// Any exchange contract that connects to the staking contract
/// must be added here. When an exchange contract is deprecated
/// then it should be removed.
contract MixinExchangeManager is
IStakingEvents,
MixinDeploymentConstants,
@@ -32,11 +36,6 @@ contract MixinExchangeManager is
MixinOwnable
{
/// @dev This mixin contains logic for managing exchanges.
/// Any exchange contract that connects to the staking contract
/// must be added here. When an exchange contract is deprecated
/// then it should be removed.
/// @dev Asserts that the call is coming from a valid exchange.
modifier onlyExchange() {
require(

View File

@@ -19,15 +19,14 @@
pragma solidity ^0.5.5;
/// @dev This vault manages staking pool rewards.
/// Rewards can be deposited and withdraw by the staking contract.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
interface IStakingPoolRewardVault {
/// @dev This vault manages staking pool rewards.
/// Rewards can be deposited and withdraw by the staking contract.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
/// @dev Holds the balance for a staking pool.
/// @param initialzed True iff the balance struct is initialized.
/// @param operatorShare Percentage of the total balance owned by the operator.

View File

@@ -19,20 +19,18 @@
pragma solidity ^0.5.5;
interface IVaultCore
{
/// @dev This mixin contains core logic for vaults.
/// This includes management of the staking contract
/// and setting the vault to "Catastrophic Failure Mode".
/// It's up to the vault how they handle this failure mode; however,
/// all vaults should disable all functionality aside from withdrawals.
/// Vaults should only be set to Catastrophic Failure Mode iff there is
/// non-recoverable corruption of the staking contracts. If there is a
/// recoverable flaw/bug/vulnerability, simply detach the staking contract
/// by setting its address to `address(0)`. Once in Catostrophic Failure Mode,
/// a vault cannot be reset to normal mode; this prevents corruption of related
/// state in the staking contract.
/// @dev This mixin contains core logic for vaults.
/// This includes management of the staking contract
/// and setting the vault to "Catastrophic Failure Mode".
/// It's up to the vault how they handle this failure mode; however,
/// all vaults should disable all functionality aside from withdrawals.
/// Vaults should only be set to Catastrophic Failure Mode iff there is
/// non-recoverable corruption of the staking contracts. If there is a
/// recoverable flaw/bug/vulnerability, simply detach the staking contract
/// by setting its address to `address(0)`. Once in Catostrophic Failure Mode,
/// a vault cannot be reset to normal mode; this prevents corruption of related
/// state in the staking contract.
interface IVaultCore {
/// @dev Emitted when the Staking contract is changed.
/// @param stakingContractAddress Address of the new Staking contract.

View File

@@ -19,16 +19,15 @@
pragma solidity ^0.5.5;
/// @dev This vault manages Zrx Tokens.
/// When a user mints stake, their Zrx Tokens are deposited into this vault.
/// Similarly, when they burn stake, their Zrx Tokens are withdrawn from this vault.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
interface IZrxVault {
/// @dev This vault manages Zrx Tokens.
/// When a user mints stake, their Zrx Tokens are deposited into this vault.
/// Similarly, when they burn stake, their Zrx Tokens are withdrawn from this vault.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
/// @dev Emitted when Zrx Tokens are deposited into the vault.
/// @param sender Address of sender (`msg.sender`).
/// @param owner of Zrx Tokens.

View File

@@ -21,19 +21,18 @@
pragma solidity ^0.5.5;
/// @dev This library implements math helpers for fee computation.
/// *** READ MixinExchangeFees BEFORE CONTINUING ***
/// @TODO - Optimization / Precision / SafeMath.
/// @TODO Once better nth root - choose a value that is not a divisor of 18, like 7.
/// @TODO Update these values for deployment.
/// There may be better, more efficient ways of implementing these functions.
/// This works well enough to test the end-to-system, but it would be really
/// good to get some math experts in here to check out this code. We should also
/// look at existing projects, in case similar functionality exists and has been
/// audited by a third-party.
library LibFeeMath {
/// @dev This library implements math helpers for fee computation.
/// *** READ MixinExchangeFees BEFORE CONTINUING ***
/// @TODO - Optimization / Precision / SafeMath.
/// @TODO Once better nth root - choose a value that is not a divisor of 18, like 7.
/// @TODO Update these values for deployment.
/// There may be better, more efficient ways of implementing these functions.
/// This works well enough to test the end-to-system, but it would be really
/// good to get some math experts in here to check out this code. We should also
/// look at existing projects, in case similar functionality exists and has been
/// audited by a third-party.
// Denominator of alpha in cobb-douglas function
uint256 constant internal COBB_DOUGLAS_ALPHA_DENOMINATOR = 6;

View File

@@ -21,11 +21,10 @@ pragma solidity ^0.5.5;
import "./LibSafeMath.sol";
/// @dev This library contains logic for computing the reward balances of staking pool members.
/// *** READ MixinStakingPoolRewards BEFORE CONTINUING ***
library LibRewardMath {
/// @dev This library contains logic for computing the reward balances of staking pool members.
/// *** READ MixinStakingPoolRewards BEFORE CONTINUING ***
using LibSafeMath for uint256;
/// @dev Computes a member's payout denominated in the real asset (ETH).

View File

@@ -31,6 +31,13 @@ import "./MixinStake.sol";
import "../staking_pools/MixinStakingPoolRewards.sol";
/// @dev This mixin contains logic for managing delegated stake.
/// **** Read MixinStake before continuing ****
/// Stake can be delegated to staking pools in order to trustlessly
/// leverage the weight of several stakers. The meaning of this
/// leverage depends on the context in which stake the is being utilized.
/// For example, the amount of fee-based rewards a market maker receives
/// is correlated to how much stake has been delegated to their pool (see MixinExchangeFees).
contract MixinDelegatedStake is
IStakingEvents,
MixinDeploymentConstants,
@@ -47,14 +54,6 @@ contract MixinDelegatedStake is
MixinStakingPoolRewards
{
/// @dev This mixin contains logic for managing delegated stake.
/// **** Read MixinStake before continuing ****
/// Stake can be delegated to staking pools in order to trustlessly
/// leverage the weight of several stakers. The meaning of this
/// leverage depends on the context in which stake the is being utilized.
/// For example, the amount of fee-based rewards a market maker receives
/// is correlated to how much stake has been delegated to their pool (see MixinExchangeFees).
using LibSafeMath for uint256;
/// @dev Deposit Zrx and mint stake in the "Activated & Delegated" state.

View File

@@ -30,6 +30,51 @@ import "./MixinStakeBalances.sol";
import "./MixinTimelockedStake.sol";
/// @dev This mixin contains logic for managing ZRX tokens and Stake.
/// Stake is minted when ZRX is deposited and burned when ZRX is withdrawn.
/// Stake can exist in one of many states:
/// 1. Activated
/// 2. Activated & Delegated
/// 3. Deactivated & Timelocked
/// 4. Deactivated & Withdrawable
///
/// -- State Definitions --
/// Activated Stake
/// Stake in this state can be used as a utility within the 0x ecosystem.
/// For example, it carries weight when computing fee-based rewards (see MixinExchangeFees).
/// In the future, it may be used to participate in the 0x governance system.
///
/// Activated & Delegated Stake
/// Stake in this state also serves as a utility that is shared between the delegator and delegate.
/// For example, if delegated to a staking pool then it carries weight when computing fee-based rewards for
/// the staking pool; however, in this case, delegated stake carries less weight that regular stake (see MixinStakingPool).
///
/// Deactivated & Timelocked Stake
/// Stake in this state cannot be used as a utility within the 0x ecosystem.
/// Stake is timelocked when it moves out of activated states (Activated / Activated & Delagated).
/// By limiting the portability of stake, we mitigate undesirable behavior such as switching staking pools
/// in the middle of an epoch.
///
/// Deactivated & Withdrawable
/// Stake in this state cannot be used as a utility with in the 0x ecosystem.
/// This stake can, however, be burned and withdrawn as Zrx tokens.
/// ----------------------------
///
/// -- Valid State Transtions --
/// Activated -> Deactivated & Timelocked
///
/// Activated & Delegated -> Deactivated & Timelocked
///
/// Deactivated & Timelocked -> Deactivated & Withdrawable
///
/// Deactivated & Withdrawable -> Activated
/// Deactivated & Withdrawable -> Activated & Delegated
/// Deactivated & Withdrawable -> Deactivated & Withdrawable
/// ----------------------------
///
/// Freshly minted stake is in the "Deactvated & Withdrawable" State, so it can
/// either be activated, delegated or withdrawn.
/// See MixinDelegatedStake and MixinTimelockedStake for more on respective state transitions.
contract MixinStake is
IStakingEvents,
MixinDeploymentConstants,
@@ -43,52 +88,6 @@ contract MixinStake is
MixinStakeBalances
{
/// @dev This mixin contains logic for managing ZRX tokens and Stake.
/// Stake is minted when ZRX is deposited and burned when ZRX is withdrawn.
/// Stake can exist in one of many states:
/// 1. Activated
/// 2. Activated & Delegated
/// 3. Deactivated & Timelocked
/// 4. Deactivated & Withdrawable
///
/// -- State Definitions --
/// Activated Stake
/// Stake in this state can be used as a utility within the 0x ecosystem.
/// For example, it carries weight when computing fee-based rewards (see MixinExchangeFees).
/// In the future, it may be used to participate in the 0x governance system.
///
/// Activated & Delegated Stake
/// Stake in this state also serves as a utility that is shared between the delegator and delegate.
/// For example, if delegated to a staking pool then it carries weight when computing fee-based rewards for
/// the staking pool; however, in this case, delegated stake carries less weight that regular stake (see MixinStakingPool).
///
/// Deactivated & Timelocked Stake
/// Stake in this state cannot be used as a utility within the 0x ecosystem.
/// Stake is timelocked when it moves out of activated states (Activated / Activated & Delagated).
/// By limiting the portability of stake, we mitigate undesirable behavior such as switching staking pools
/// in the middle of an epoch.
///
/// Deactivated & Withdrawable
/// Stake in this state cannot be used as a utility with in the 0x ecosystem.
/// This stake can, however, be burned and withdrawn as Zrx tokens.
/// ----------------------------
///
/// -- Valid State Transtions --
/// Activated -> Deactivated & Timelocked
///
/// Activated & Delegated -> Deactivated & Timelocked
///
/// Deactivated & Timelocked -> Deactivated & Withdrawable
///
/// Deactivated & Withdrawable -> Activated
/// Deactivated & Withdrawable -> Activated & Delegated
/// Deactivated & Withdrawable -> Deactivated & Withdrawable
/// ----------------------------
///
/// Freshly minted stake is in the "Deactvated & Withdrawable" State, so it can
/// either be activated, delegated or withdrawn.
/// See MixinDelegatedStake and MixinTimelockedStake for more on respective state transitions.
using LibSafeMath for uint256;
/// @dev Deposit Zrx. This mints stake for the sender that is in the "Deactivated & Withdrawable" state.

View File

@@ -27,6 +27,8 @@ import "../sys/MixinScheduler.sol";
import "./MixinTimelockedStake.sol";
/// @dev This mixin contains logic for querying stake balances.
/// **** Read MixinStake before continuing ****
contract MixinStakeBalances is
IStakingEvents,
MixinDeploymentConstants,
@@ -36,9 +38,6 @@ contract MixinStakeBalances is
MixinTimelockedStake
{
/// @dev This mixin contains logic for querying stake balances.
/// **** Read MixinStake before continuing ****
using LibSafeMath for uint256;
/// @dev Returns the total activated stake across all owners.

View File

@@ -26,6 +26,56 @@ import "../interfaces/IStakingEvents.sol";
import "../sys/MixinScheduler.sol";
/// @dev This mixin contains logic for timelocking stake.
/// **** Read MixinStake before continuing ****
/// When stake moves from an Activated state it must first go to
/// the Deactivated & Timelocked state. The stake will be timelocked
/// for a period of time, called a Timelock Period, which is measured in epochs.
/// (see MixinScheduler).
/// Stake remains timelocked for at least one full Timelock Period; so,
/// if your stake is locked sometime during Timelock Period #1 then it will
/// be un-timelocked at Timelock Period #3.
/// Note that no action is required by the user to un-timelock their stake, and
/// when stake is un-timelocked it is moved to the state Deactivated & Withdrawable.
/// (see MixinStake).
///
/// -- The Timelocking Data Structure --
/// Three fields are used to represent a timelock:
/// 1. Total timelocked stake (called `total`)
/// 2. Timelocked stake pending removal of timelock, on next Timelock Period (called `pending`)
/// 3. The most recent Timelock Period in which stake was timelocked. (called `lockedAt`)
///
/// Each user has exactly one instance of this timelock struct, which manages all of
/// their timelocked stake. This data structure is defined in `IStructs.Timelock`.
/// This data structure was designed to fit into one word of storage, as a gas optimization.
/// Its fields are updated only when a user interacts with their stake.
/// ------------------------------------
///
/// -- Timelocking Example --
/// In the example below, the user executes a series of actions on their stake (`Action`) during `Timelock Period` N.
/// The fields of the user's timelocked struct (`lockedAt`, `total`, `pending`) are illustrated exactly as
/// they would be represented in storage.
/// The field `un-timelocked` is the amount of un-timelocked stake, as represented *in storage*; however, because
/// state is only updated when the user interacts with their stake, this field may lag.
/// The field `un-timelocked (virtual)` is the true amount of un-timelocked stake, as represented in the system;
/// the value in this field represents stake that has moved from the state
/// "Deactivated & Timelocke" to "Deactivated & Withdrawable" (see MixinStake).
///
/// | Action | Timelock Period | lockedAt | total | pending | un-timelocked | un-timelocked (virtual) |
/// | | 0 | 0 | 0 | 0 | 0 | 0 |
/// | lock(5) | 1 | 1 | 5 | 0 | 0 | 0 |
/// | | 2 | 1 | 5 | 0 | 0 | 0 |
/// | lock(10) | 2 | 2 | 15 | 5 | 0 | 0 |
/// | | 3 | 2 | 15 | 5 | 0 | 5 |
/// | lock(15) | 3 | 3 | 30 | 15 | 5 | 5 |
/// | | 4 | 3 | 30 | 15 | 5 | 15 |
/// | | 5 | 3 | 30 | 15 | 5 | 30 |
/// | lock(0) | 5 | 5 | 30 | 30 | 30 | 30 |
/// | lock(20) | 6 | 6 | 50 | 30 | 30 | 30 |
/// | unlock(30) | 6 | 6 | 20 | 0 | 0 | 0 |
/// | | 7 | 6 | 20 | 0 | 0 | 0 |
/// | | 8 | 6 | 20 | 0 | 0 | 20 |
/// -------------------------------------------------------------------------------------------------------------
contract MixinTimelockedStake is
IStakingEvents,
MixinDeploymentConstants,
@@ -33,57 +83,6 @@ contract MixinTimelockedStake is
MixinStorage,
MixinScheduler
{
/// @dev This mixin contains logic for timelocking stake.
/// **** Read MixinStake before continuing ****
/// When stake moves from an Activated state it must first go to
/// the Deactivated & Timelocked state. The stake will be timelocked
/// for a period of time, called a Timelock Period, which is measured in epochs.
/// (see MixinScheduler).
/// Stake remains timelocked for at least one full Timelock Period; so,
/// if your stake is locked sometime during Timelock Period #1 then it will
/// be un-timelocked at Timelock Period #3.
/// Note that no action is required by the user to un-timelock their stake, and
/// when stake is un-timelocked it is moved to the state Deactivated & Withdrawable.
/// (see MixinStake).
///
/// -- The Timelocking Data Structure --
/// Three fields are used to represent a timelock:
/// 1. Total timelocked stake (called `total`)
/// 2. Timelocked stake pending removal of timelock, on next Timelock Period (called `pending`)
/// 3. The most recent Timelock Period in which stake was timelocked. (called `lockedAt`)
///
/// Each user has exactly one instance of this timelock struct, which manages all of
/// their timelocked stake. This data structure is defined in `IStructs.Timelock`.
/// This data structure was designed to fit into one word of storage, as a gas optimization.
/// Its fields are updated only when a user interacts with their stake.
/// ------------------------------------
///
/// -- Timelocking Example --
/// In the example below, the user executes a series of actions on their stake (`Action`) during `Timelock Period` N.
/// The fields of the user's timelocked struct (`lockedAt`, `total`, `pending`) are illustrated exactly as
/// they would be represented in storage.
/// The field `un-timelocked` is the amount of un-timelocked stake, as represented *in storage*; however, because
/// state is only updated when the user interacts with their stake, this field may lag.
/// The field `un-timelocked (virtual)` is the true amount of un-timelocked stake, as represented in the system;
/// the value in this field represents stake that has moved from the state
/// "Deactivated & Timelocke" to "Deactivated & Withdrawable" (see MixinStake).
///
/// | Action | Timelock Period | lockedAt | total | pending | un-timelocked | un-timelocked (virtual) |
/// | | 0 | 0 | 0 | 0 | 0 | 0 |
/// | lock(5) | 1 | 1 | 5 | 0 | 0 | 0 |
/// | | 2 | 1 | 5 | 0 | 0 | 0 |
/// | lock(10) | 2 | 2 | 15 | 5 | 0 | 0 |
/// | | 3 | 2 | 15 | 5 | 0 | 5 |
/// | lock(15) | 3 | 3 | 30 | 15 | 5 | 5 |
/// | | 4 | 3 | 30 | 15 | 5 | 15 |
/// | | 5 | 3 | 30 | 15 | 5 | 30 |
/// | lock(0) | 5 | 5 | 30 | 30 | 30 | 30 |
/// | lock(20) | 6 | 6 | 50 | 30 | 30 | 30 |
/// | unlock(30) | 6 | 6 | 20 | 0 | 0 | 0 |
/// | | 7 | 6 | 20 | 0 | 0 | 0 |
/// | | 8 | 6 | 20 | 0 | 0 | 20 |
/// -------------------------------------------------------------------------------------------------------------
using LibSafeMath for uint256;

View File

@@ -23,6 +23,8 @@ import "../immutable/MixinStorage.sol";
import "../sys/MixinOwnable.sol";
/// @dev This mixin contains logic for managing and interfacing with the Zrx Vault.
/// (see vaults/ZrxVault.sol).
contract MixinZrxVault is
IStakingEvents,
MixinDeploymentConstants,
@@ -31,9 +33,6 @@ contract MixinZrxVault is
MixinOwnable
{
/// @dev This mixin contains logic for managing and interfacing with the Zrx Vault.
/// (see vaults/ZrxVault.sol).
/// @dev Set the Zrx Vault.
/// @param zrxVaultAddress Address of the Zrx Vault.
function setZrxVault(address zrxVaultAddress)

View File

@@ -29,6 +29,29 @@ import "../immutable/MixinStorage.sol";
import "./MixinStakingPoolRewardVault.sol";
/// @dev This mixin contains logic for staking pools.
/// A pool has a single operator and any number of delegators (members).
/// Any staker can create a pool, although at present it is only beneficial
/// for market makers to create staking pools. A market maker *must* create a
/// pool in order to receive fee-based rewards at the end of each epoch (see MixinExchangeFees).
/// Moreover, creating a staking pool leverages the delegated stake within the pool,
/// which is counted towards a maker's total stake when computing rewards. A market maker
/// can register any number of makerAddresses with their pool, and can incentivize delegators
/// to join their pool by specifying a fixed percentage of their fee-based rewards to be split amonst
/// the members of their pool. Any rewards set aside for members of the pool is divided based on
/// how much stake each member delegated.
///
/// Terminology:
/// "Pool Id" - A unique id generated by this contract and assigned to each pool when it is created.
/// "Pool Operator" - The creator and operator of the pool.
/// "Pool Members" - Members of the pool who opted-in by delegating to the pool.
/// "Market Makers" - Market makers on the 0x protocol.
///
/// How-To for Market Makers:
/// 1. Create a pool, specifying what percentage of rewards kept for yourself.
/// The remaining is divided among members of your pool.
/// 2. Add the addresses that you use to market make on 0x.
/// 3. Leverage the staking power of others by convincing them to delegate to your pool.
contract MixinStakingPool is
IStakingEvents,
MixinDeploymentConstants,
@@ -38,30 +61,6 @@ contract MixinStakingPool is
MixinStakingPoolRewardVault
{
/// @dev This mixin contains logic for staking pools.
/// A pool has a single operator and any number of delegators (members).
/// Any staker can create a pool, although at present it is only beneficial
/// for market makers to create staking pools. A market maker *must* create a
/// pool in order to receive fee-based rewards at the end of each epoch (see MixinExchangeFees).
/// Moreover, creating a staking pool leverages the delegated stake within the pool,
/// which is counted towards a maker's total stake when computing rewards. A market maker
/// can register any number of makerAddresses with their pool, and can incentivize delegators
/// to join their pool by specifying a fixed percentage of their fee-based rewards to be split amonst
/// the members of their pool. Any rewards set aside for members of the pool is divided based on
/// how much stake each member delegated.
///
/// Terminology:
/// "Pool Id" - A unique id generated by this contract and assigned to each pool when it is created.
/// "Pool Operator" - The creator and operator of the pool.
/// "Pool Members" - Members of the pool who opted-in by delegating to the pool.
/// "Market Makers" - Market makers on the 0x protocol.
///
/// How-To for Market Makers:
/// 1. Create a pool, specifying what percentage of rewards kept for yourself.
/// The remaining is divided among members of your pool.
/// 2. Add the addresses that you use to market make on 0x.
/// 3. Leverage the staking power of others by convincing them to delegate to your pool.
using LibSafeMath for uint256;
/// @dev Asserts that the sender is the operator of the input pool.

View File

@@ -24,6 +24,9 @@ import "../immutable/MixinStorage.sol";
import "../sys/MixinOwnable.sol";
/// @dev This mixin contains logic for interfacing with the Staking Pool Reward Vault (vaults/StakingPoolRewardVault.sol)
/// Note that setters are callable only by the owner of this contract, and withdraw functionality is accessible only
/// from within this contract.
contract MixinStakingPoolRewardVault is
IStakingEvents,
MixinDeploymentConstants,
@@ -32,10 +35,6 @@ contract MixinStakingPoolRewardVault is
MixinOwnable
{
/// @dev This mixin contains logic for interfacing with the Staking Pool Reward Vault (vaults/StakingPoolRewardVault.sol)
/// Note that setters are callable only by the owner of this contract, and withdraw functionality is accessible only
/// from within this contract.
/// @dev Sets the address of the reward vault.
/// This can only be called by the owner of this contract.
function setStakingPoolRewardVault(address payable rewardVaultAddress)

View File

@@ -27,6 +27,37 @@ import "./MixinStakingPoolRewardVault.sol";
import "./MixinStakingPool.sol";
/// @dev This mixin contains logic for staking pool rewards.
/// Rewards for a pool are generated by their market makers trading on the 0x protocol (MixinStakingPool).
/// The operator of a pool receives a fixed percentage of all rewards; generally, the operator is the
/// sole market maker of a pool. The remaining rewards are divided among the members of a pool; each member
/// gets an amount proportional to how much stake they have delegated to the pool.
///
/// Note that members can freely join or leave a staking pool at any time, by delegating/undelegating their stake.
/// Moreover, there is no limit to how many members a pool can have. To limit the state-updates needed to track member balances,
/// we store only a single balance shared by all members. This state is updated every time a reward is paid to the pool - which
/// is currently at the end of each epoch. Additionally, each member has an associated "Shadow Balance" which is updated only
/// when a member delegates/undelegates stake to the pool, along with a "Total Shadow Balance" that represents the cumulative
/// Shadow Balances of all members in a pool.
///
/// -- Member Balances --
/// Terminology:
/// Real Balance - The reward balance in ETH of a member.
/// Total Real Balance - The sum total of reward balances in ETH across all members of a pool.
/// Shadow Balance - The realized reward balance of a member.
/// Total Shadow Balance - The sum total of realized reward balances across all members of a pool.
/// How it works:
/// 1. When a member delegates, their ownership of the pool increases; however, this new ownership applies
/// only to future rewards and must not change the rewards currently owned by other members. Thus, when a
/// member delegates stake, we *increase* their Shadow Balance and the Total Shadow Balance of the pool.
///
/// 2. When a member withdraws a portion of their reward, their realized balance increases but their ownership
/// within the pool remains unchanged. Thus, we simultaneously *decrease* their Real Balance and
/// *increase* their Shadow Balance by the amount withdrawn. The cumulative balance decrease and increase, respectively.
///
/// 3. When a member undelegates, the portion of their reward that corresponds to that stake is also withdrawn. Thus,
/// their realized balance *increases* while their ownership of the pool *decreases*. To reflect this, we
/// decrease their Shadow Balance, the Total Shadow Balance, their Real Balance, and the Total Real Balance.
contract MixinStakingPoolRewards is
IStakingEvents,
MixinDeploymentConstants,
@@ -40,38 +71,6 @@ contract MixinStakingPoolRewards is
MixinStakeBalances
{
/// @dev This mixin contains logic for staking pool rewards.
/// Rewards for a pool are generated by their market makers trading on the 0x protocol (MixinStakingPool).
/// The operator of a pool receives a fixed percentage of all rewards; generally, the operator is the
/// sole market maker of a pool. The remaining rewards are divided among the members of a pool; each member
/// gets an amount proportional to how much stake they have delegated to the pool.
///
/// Note that members can freely join or leave a staking pool at any time, by delegating/undelegating their stake.
/// Moreover, there is no limit to how many members a pool can have. To limit the state-updates needed to track member balances,
/// we store only a single balance shared by all members. This state is updated every time a reward is paid to the pool - which
/// is currently at the end of each epoch. Additionally, each member has an associated "Shadow Balance" which is updated only
/// when a member delegates/undelegates stake to the pool, along with a "Total Shadow Balance" that represents the cumulative
/// Shadow Balances of all members in a pool.
///
/// -- Member Balances --
/// Terminology:
/// Real Balance - The reward balance in ETH of a member.
/// Total Real Balance - The sum total of reward balances in ETH across all members of a pool.
/// Shadow Balance - The realized reward balance of a member.
/// Total Shadow Balance - The sum total of realized reward balances across all members of a pool.
/// How it works:
/// 1. When a member delegates, their ownership of the pool increases; however, this new ownership applies
/// only to future rewards and must not change the rewards currently owned by other members. Thus, when a
/// member delegates stake, we *increase* their Shadow Balance and the Total Shadow Balance of the pool.
///
/// 2. When a member withdraws a portion of their reward, their realized balance increases but their ownership
/// within the pool remains unchanged. Thus, we simultaneously *decrease* their Real Balance and
/// *increase* their Shadow Balance by the amount withdrawn. The cumulative balance decrease and increase, respectively.
///
/// 3. When a member undelegates, the portion of their reward that corresponds to that stake is also withdrawn. Thus,
/// their realized balance *increases* while their ownership of the pool *decreases*. To reflect this, we
/// decrease their Shadow Balance, the Total Shadow Balance, their Real Balance, and the Total Real Balance.
using LibSafeMath for uint256;
/// @dev Withdraws an amount in ETH of the reward for the pool operator.

View File

@@ -5,6 +5,11 @@ import "../interfaces/IStakingEvents.sol";
import "../immutable/MixinStorage.sol";
/// @dev This mixin contains logic for ownable contracts.
/// Note that unlike the standardized `ownable` contract,
/// there is no state declared here. It is instead located
/// in `immutable/MixinStorage.sol` and its value is set
/// by the delegating proxy (StakingProxy.sol)
contract MixinOwnable is
Ownable,
IStakingEvents,
@@ -13,10 +18,8 @@ contract MixinOwnable is
MixinStorage
{
/// @dev This mixin contains logic for ownable contracts.
/// Note that unlike the standardized `ownable` contract,
/// there is no state declared here. It is instead located
/// in `immutable/MixinStorage.sol` and its value is set
/// by the delegating proxy (StakingProxy.sol)
constructor() public {}
// solhint-disable no-empty-blocks
constructor()
public
{}
}

View File

@@ -26,18 +26,18 @@ import "../interfaces/IStructs.sol";
import "../interfaces/IStakingEvents.sol";
/// @dev This mixin contains logic for time-based scheduling.
/// All processes in the system are segmented into time intervals, called epochs.
/// Epochs have a fixed minimum time period that is configured when this contract is deployed.
/// The current epoch only changes by calling this contract, which can be invoked by anyone.
/// Epochs serve as the basis for all other time intervals, which provides a more stable
/// and consistent scheduling metric than time. Timelocks, for example, are measured in epochs.
contract MixinScheduler is
IStakingEvents,
MixinDeploymentConstants,
MixinConstants,
MixinStorage
{
/// @dev This mixin contains logic for time-based scheduling.
/// All processes in the system are segmented into time intervals, called epochs.
/// Epochs have a fixed minimum time period that is configured when this contract is deployed.
/// The current epoch only changes by calling this contract, which can be invoked by anyone.
/// Epochs serve as the basis for all other time intervals, which provides a more stable
/// and consistent scheduling metric than time. Timelocks, for example, are measured in epochs.
using LibSafeMath for uint256;
using LibSafeMath64 for uint64;

View File

@@ -22,23 +22,22 @@ import "@0x/contracts-utils/contracts/src/Authorizable.sol";
import "../interfaces/IVaultCore.sol";
/// @dev This mixin contains core logic for vaults.
/// This includes management of the staking contract
/// and setting the vault to "Catastrophic Failure Mode".
/// It's up to the vault how they handle this failure mode; however,
/// all vaults should disable all functionality aside from withdrawals.
/// Vaults should only be set to Catastrophic Failure Mode iff there is
/// non-recoverable corruption of the staking contracts. If there is a
/// recoverable flaw/bug/vulnerability, simply detach the staking contract
/// by setting its address to `address(0)`. Once in Catostrophic Failure Mode,
/// a vault cannot be reset to normal mode; this prevents corruption of related
/// state in the staking contract.
contract MixinVaultCore is
Authorizable,
IVaultCore
{
/// @dev This mixin contains core logic for vaults.
/// This includes management of the staking contract
/// and setting the vault to "Catastrophic Failure Mode".
/// It's up to the vault how they handle this failure mode; however,
/// all vaults should disable all functionality aside from withdrawals.
/// Vaults should only be set to Catastrophic Failure Mode iff there is
/// non-recoverable corruption of the staking contracts. If there is a
/// recoverable flaw/bug/vulnerability, simply detach the staking contract
/// by setting its address to `address(0)`. Once in Catostrophic Failure Mode,
/// a vault cannot be reset to normal mode; this prevents corruption of related
/// state in the staking contract.
// Address of staking contract
address payable internal stakingContractAddress;

View File

@@ -25,6 +25,15 @@ import "../interfaces/IStakingPoolRewardVault.sol";
import "../immutable/MixinConstants.sol";
/// @dev This vault manages staking pool rewards.
/// Rewards can be deposited and withdraw by the staking contract.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
///
/// When in Catastrophic Failure Mode, the Staking contract can still
/// perform withdrawals on behalf of its users.
contract StakingPoolRewardVault is
Authorizable,
IStakingPoolRewardVault,
@@ -36,16 +45,6 @@ contract StakingPoolRewardVault is
using LibSafeMath for uint256;
using LibSafeMath96 for uint96;
/// @dev This vault manages staking pool rewards.
/// Rewards can be deposited and withdraw by the staking contract.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
///
/// When in Catastrophic Failure Mode, the Staking contract can still
/// perform withdrawals on behalf of its users.
// mapping from Pool to Reward Balance in ETH
mapping (bytes32 => Balance) internal balanceByPoolId;

View File

@@ -25,20 +25,19 @@ import "@0x/contracts-erc20/contracts/src/interfaces/IERC20Token.sol";
import "./MixinVaultCore.sol";
/// @dev This vault manages Zrx Tokens.
/// When a user mints stake, their Zrx Tokens are deposited into this vault.
/// Similarly, when they burn stake, their Zrx Tokens are withdrawn from this vault.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
contract ZrxVault is
Authorizable,
IZrxVault,
MixinVaultCore
{
/// @dev This vault manages Zrx Tokens.
/// When a user mints stake, their Zrx Tokens are deposited into this vault.
/// Similarly, when they burn stake, their Zrx Tokens are withdrawn from this vault.
/// There is a "Catastrophic Failure Mode" that, when invoked, only
/// allows withdrawals to be made. Once this vault is in catostrophic
/// failure mode, it cannot be returned to normal mode; this prevents
/// corruption of related state in the staking contract.
using LibSafeMath for uint256;
// mapping from Owner to ZRX balance

View File

@@ -31,8 +31,8 @@ import * as MixinScheduler from '../generated-artifacts/MixinScheduler.json';
import * as MixinStake from '../generated-artifacts/MixinStake.json';
import * as MixinStakeBalances from '../generated-artifacts/MixinStakeBalances.json';
import * as MixinStakingPool from '../generated-artifacts/MixinStakingPool.json';
import * as MixinStakingPoolRewardVault from '../generated-artifacts/MixinStakingPoolRewardVault.json';
import * as MixinStakingPoolRewards from '../generated-artifacts/MixinStakingPoolRewards.json';
import * as MixinStakingPoolRewardVault from '../generated-artifacts/MixinStakingPoolRewardVault.json';
import * as MixinStorage from '../generated-artifacts/MixinStorage.json';
import * as MixinTimelockedStake from '../generated-artifacts/MixinTimelockedStake.json';
import * as MixinVaultCore from '../generated-artifacts/MixinVaultCore.json';