diff --git a/contracts/staking/contracts/src/ZrxVaultBackstop.sol b/contracts/staking/contracts/src/ZrxVaultBackstop.sol index 68a47c9c5f..08f7ab2f99 100644 --- a/contracts/staking/contracts/src/ZrxVaultBackstop.sol +++ b/contracts/staking/contracts/src/ZrxVaultBackstop.sol @@ -23,9 +23,12 @@ import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; import "./interfaces/IStructs.sol"; import "./interfaces/IZrxVault.sol"; import "./interfaces/IStakingProxy.sol"; +import "./interfaces/IZrxVaultBackstop.sol"; -contract ZrxVaultBackstop { +contract ZrxVaultBackstop is + IZrxVaultBackstop +{ using LibSafeMath for uint256; diff --git a/contracts/staking/contracts/src/interfaces/IStaking.sol b/contracts/staking/contracts/src/interfaces/IStaking.sol index f0329f8cfd..fc336aefcc 100644 --- a/contracts/staking/contracts/src/interfaces/IStaking.sol +++ b/contracts/staking/contracts/src/interfaces/IStaking.sol @@ -19,11 +19,61 @@ pragma solidity ^0.5.9; pragma experimental ABIEncoderV2; +import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol"; import "./IStructs.sol"; +import "./IZrxVault.sol"; interface IStaking { + /// @dev Adds a new exchange address + /// @param addr Address of exchange contract to add + function addExchangeAddress(address addr) + external; + + /// @dev Create a new staking pool. The sender will be the operator of this pool. + /// Note that an operator must be payable. + /// @param operatorShare Portion of rewards owned by the operator, in ppm. + /// @param addOperatorAsMaker Adds operator to the created pool as a maker for convenience iff true. + /// @return poolId The unique pool id generated for this pool. + function createStakingPool(uint32 operatorShare, bool addOperatorAsMaker) + external + returns (bytes32 poolId); + + /// @dev Decreases the operator share for the given pool (i.e. increases pool rewards for members). + /// @param poolId Unique Id of pool. + /// @param newOperatorShare The newly decreased percentage of any rewards owned by the operator. + function decreaseStakingPoolOperatorShare(bytes32 poolId, uint32 newOperatorShare) + external; + + /// @dev Begins a new epoch, preparing the prior one for finalization. + /// Throws if not enough time has passed between epochs or if the + /// previous epoch was not fully finalized. + /// @return numPoolsToFinalize The number of unfinalized pools. + function endEpoch() + external + returns (uint256); + + /// @dev Instantly finalizes a single pool that earned rewards in the previous + /// epoch, crediting it rewards for members and withdrawing operator's + /// rewards as WETH. This can be called by internal functions that need + /// to finalize a pool immediately. Does nothing if the pool is already + /// finalized or did not earn rewards in the previous epoch. + /// @param poolId The pool ID to finalize. + function finalizePool(bytes32 poolId) + external; + + /// @dev Initialize storage owned by this contract. + /// This function should not be called directly. + /// The StakingProxy contract will call it in `attachStakingContract()`. + function init() + external; + + /// @dev Allows caller to join a staking pool as a maker. + /// @param poolId Unique id of pool. + function joinStakingPoolAsMaker(bytes32 poolId) + external; + /// @dev Moves stake between statuses: 'undelegated' or 'delegated'. /// Delegated stake can also be moved between pools. /// This change comes into effect next epoch. @@ -49,9 +99,153 @@ interface IStaking { external payable; - /// @dev Stake ZRX tokens. Tokens are deposited into the ZRX Vault. Unstake to retrieve the ZRX. - /// Stake is in the 'Active' status. + /// @dev Removes an existing exchange address + /// @param addr Address of exchange contract to remove + function removeExchangeAddress(address addr) + external; + + /// @dev Set all configurable parameters at once. + /// @param _epochDurationInSeconds Minimum seconds between epochs. + /// @param _rewardDelegatedStakeWeight How much delegated stake is weighted vs operator stake, in ppm. + /// @param _minimumPoolStake Minimum amount of stake required in a pool to collect rewards. + /// @param _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. + /// @param _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. + function setParams( + uint256 _epochDurationInSeconds, + uint32 _rewardDelegatedStakeWeight, + uint256 _minimumPoolStake, + uint32 _cobbDouglasAlphaNumerator, + uint32 _cobbDouglasAlphaDenominator + ) + external; + + /// @dev Stake ZRX tokens. Tokens are deposited into the ZRX Vault. + /// Unstake to retrieve the ZRX. Stake is in the 'Active' status. /// @param amount of ZRX to stake. function stake(uint256 amount) external; + + /// @dev Unstake. Tokens are withdrawn from the ZRX Vault and returned to + /// the staker. Stake must be in the 'undelegated' status in both the + /// current and next epoch in order to be unstaked. + /// @param amount of ZRX to unstake. + function unstake(uint256 amount) + external; + + /// @dev Withdraws the caller's WETH rewards that have accumulated + /// until the last epoch. + /// @param poolId Unique id of pool. + function withdrawDelegatorRewards(bytes32 poolId) + external; + + /// @dev Computes the reward balance in ETH of a specific member of a pool. + /// @param poolId Unique id of pool. + /// @param member The member of the pool. + /// @return totalReward Balance in ETH. + function computeRewardBalanceOfDelegator(bytes32 poolId, address member) + external + view + returns (uint256 reward); + + /// @dev Computes the reward balance in ETH of the operator of a pool. + /// @param poolId Unique id of pool. + /// @return totalReward Balance in ETH. + function computeRewardBalanceOfOperator(bytes32 poolId) + external + view + returns (uint256 reward); + + /// @dev Returns the earliest end time in seconds of this epoch. + /// The next epoch can begin once this time is reached. + /// Epoch period = [startTimeInSeconds..endTimeInSeconds) + /// @return Time in seconds. + function getCurrentEpochEarliestEndTimeInSeconds() + external + view + returns (uint256); + + /// @dev Gets global stake for a given status. + /// @param stakeStatus UNDELEGATED or DELEGATED + /// @return Global stake for given status. + function getGlobalStakeByStatus(IStructs.StakeStatus stakeStatus) + external + view + returns (IStructs.StoredBalance memory balance); + + /// @dev Gets an owner's stake balances by status. + /// @param staker Owner of stake. + /// @param stakeStatus UNDELEGATED or DELEGATED + /// @return Owner's stake balances for given status. + function getOwnerStakeByStatus( + address staker, + IStructs.StakeStatus stakeStatus + ) + external + view + returns (IStructs.StoredBalance memory balance); + + /// @dev Retrieves all configurable parameter values. + /// @return _epochDurationInSeconds Minimum seconds between epochs. + /// @return _rewardDelegatedStakeWeight How much delegated stake is weighted vs operator stake, in ppm. + /// @return _minimumPoolStake Minimum amount of stake required in a pool to collect rewards. + /// @return _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. + /// @return _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. + function getParams() + external + view + returns ( + uint256 _epochDurationInSeconds, + uint32 _rewardDelegatedStakeWeight, + uint256 _minimumPoolStake, + uint32 _cobbDouglasAlphaNumerator, + uint32 _cobbDouglasAlphaDenominator + ); + + /// @param staker of stake. + /// @param poolId Unique Id of pool. + /// @return Stake delegated to pool by staker. + function getStakeDelegatedToPoolByOwner(address staker, bytes32 poolId) + external + view + returns (IStructs.StoredBalance memory balance); + + /// @dev Returns a staking pool + /// @param poolId Unique id of pool. + function getStakingPool(bytes32 poolId) + external + view + returns (IStructs.Pool memory); + + /// @dev Get stats on a staking pool in this epoch. + /// @param poolId Pool Id to query. + /// @return PoolStats struct for pool id. + function getStakingPoolStatsThisEpoch(bytes32 poolId) + external + view + returns (IStructs.PoolStats memory); + + /// @dev Returns the total stake delegated to a specific staking pool, + /// across all members. + /// @param poolId Unique Id of pool. + /// @return Total stake delegated to pool. + function getTotalStakeDelegatedToPool(bytes32 poolId) + external + view + returns (IStructs.StoredBalance memory balance); + + /// @dev An overridable way to access the deployed WETH contract. + /// Must be view to allow overrides to access state. + /// @return wethContract The WETH contract instance. + function getWethContract() + external + view + returns (IEtherToken wethContract); + + /// @dev An overridable way to access the deployed zrxVault. + /// Must be view to allow overrides to access state. + /// @return zrxVault The zrxVault contract. + function getZrxVault() + external + view + returns (IZrxVault zrxVault); } diff --git a/contracts/staking/contracts/src/interfaces/IZrxVaultBackstop.sol b/contracts/staking/contracts/src/interfaces/IZrxVaultBackstop.sol new file mode 100644 index 0000000000..7994f8845c --- /dev/null +++ b/contracts/staking/contracts/src/interfaces/IZrxVaultBackstop.sol @@ -0,0 +1,29 @@ +/* + + 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; + + +interface IZrxVaultBackstop { + + /// @dev Triggers catastophic failure mode in the zrxzVault iff read-only mode + /// has been continuously set for at least 40 days. + function enterCatastrophicFailureIfProlongedReadOnlyMode() + external; +} diff --git a/contracts/staking/package.json b/contracts/staking/package.json index a9f31bcc25..8122b18e37 100644 --- a/contracts/staking/package.json +++ b/contracts/staking/package.json @@ -37,7 +37,7 @@ }, "config": { "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", - "abis": "./generated-artifacts/@(IStaking|IStakingEvents|IStakingProxy|IStorage|IStorageInit|IStructs|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibProxy|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolRewards|MixinStorage|ReadOnlyProxy|Staking|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestExchangeManager|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibProxy|TestLibProxyReceiver|TestLibSafeDowncast|TestMixinParams|TestMixinStake|TestMixinStakeStorage|TestProtocolFees|TestStaking|TestStakingNoWETH|TestStakingProxy|TestStorageLayoutAndConstants|ZrxVault|ZrxVaultBackstop).json" + "abis": "./generated-artifacts/@(IStaking|IStakingEvents|IStakingProxy|IStorage|IStorageInit|IStructs|IZrxVault|IZrxVaultBackstop|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibProxy|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolRewards|MixinStorage|ReadOnlyProxy|Staking|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestExchangeManager|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibProxy|TestLibProxyReceiver|TestLibSafeDowncast|TestMixinParams|TestMixinStake|TestMixinStakeStorage|TestProtocolFees|TestStaking|TestStakingNoWETH|TestStakingProxy|TestStorageLayoutAndConstants|ZrxVault|ZrxVaultBackstop).json" }, "repository": { "type": "git", diff --git a/contracts/staking/src/artifacts.ts b/contracts/staking/src/artifacts.ts index 797b33e51c..e92109f89a 100644 --- a/contracts/staking/src/artifacts.ts +++ b/contracts/staking/src/artifacts.ts @@ -12,6 +12,7 @@ import * as IStorage from '../generated-artifacts/IStorage.json'; import * as IStorageInit from '../generated-artifacts/IStorageInit.json'; import * as IStructs from '../generated-artifacts/IStructs.json'; import * as IZrxVault from '../generated-artifacts/IZrxVault.json'; +import * as IZrxVaultBackstop from '../generated-artifacts/IZrxVaultBackstop.json'; import * as LibCobbDouglas from '../generated-artifacts/LibCobbDouglas.json'; import * as LibFixedMath from '../generated-artifacts/LibFixedMath.json'; import * as LibFixedMathRichErrors from '../generated-artifacts/LibFixedMathRichErrors.json'; @@ -75,6 +76,7 @@ export const artifacts = { IStorageInit: IStorageInit as ContractArtifact, IStructs: IStructs as ContractArtifact, IZrxVault: IZrxVault as ContractArtifact, + IZrxVaultBackstop: IZrxVaultBackstop as ContractArtifact, LibCobbDouglas: LibCobbDouglas as ContractArtifact, LibFixedMath: LibFixedMath as ContractArtifact, LibFixedMathRichErrors: LibFixedMathRichErrors as ContractArtifact, diff --git a/contracts/staking/src/wrappers.ts b/contracts/staking/src/wrappers.ts index 70d0530291..2fc16fcce8 100644 --- a/contracts/staking/src/wrappers.ts +++ b/contracts/staking/src/wrappers.ts @@ -10,6 +10,7 @@ export * from '../generated-wrappers/i_storage'; export * from '../generated-wrappers/i_storage_init'; export * from '../generated-wrappers/i_structs'; export * from '../generated-wrappers/i_zrx_vault'; +export * from '../generated-wrappers/i_zrx_vault_backstop'; export * from '../generated-wrappers/lib_cobb_douglas'; export * from '../generated-wrappers/lib_fixed_math'; export * from '../generated-wrappers/lib_fixed_math_rich_errors'; diff --git a/contracts/staking/tsconfig.json b/contracts/staking/tsconfig.json index 69b05735ad..671d6184d3 100644 --- a/contracts/staking/tsconfig.json +++ b/contracts/staking/tsconfig.json @@ -10,6 +10,7 @@ "generated-artifacts/IStorageInit.json", "generated-artifacts/IStructs.json", "generated-artifacts/IZrxVault.json", + "generated-artifacts/IZrxVaultBackstop.json", "generated-artifacts/LibCobbDouglas.json", "generated-artifacts/LibFixedMath.json", "generated-artifacts/LibFixedMathRichErrors.json",