Merge pull request #2186 from 0xProject/feat/3.0/delete-vaults

Delete `StakingPoolRewardVault` and `EthVault`
This commit is contained in:
Amir Bandeali 2019-09-23 18:05:53 -07:00 committed by GitHub
commit 2587cd380f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 466 additions and 1370 deletions

View File

@ -32,7 +32,6 @@ contract Staking is
IStakingEvents, IStakingEvents,
MixinAbstract, MixinAbstract,
MixinConstants, MixinConstants,
MixinDeploymentConstants,
Ownable, Ownable,
MixinStorage, MixinStorage,
MixinStakingPoolModifiers, MixinStakingPoolModifiers,
@ -60,13 +59,9 @@ contract Staking is
/// This function should not be called directly. /// This function should not be called directly.
/// The StakingProxy contract will call it in `attachStakingContract()`. /// The StakingProxy contract will call it in `attachStakingContract()`.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// @param _ethVaultAddress Address of the EthVault contract.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
function init( function init(
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address payable _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
public public
@ -77,8 +72,6 @@ contract Staking is
_initMixinScheduler(); _initMixinScheduler();
_initMixinParams( _initMixinParams(
_wethProxyAddress, _wethProxyAddress,
_ethVaultAddress,
_rewardVaultAddress,
_zrxVaultAddress _zrxVaultAddress
); );
} }

View File

@ -37,15 +37,11 @@ contract StakingProxy is
/// @param _stakingContract Staking contract to delegate calls to. /// @param _stakingContract Staking contract to delegate calls to.
/// @param _readOnlyProxy The address of the read only proxy. /// @param _readOnlyProxy The address of the read only proxy.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// @param _ethVaultAddress Address of the EthVault contract.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
constructor( constructor(
address _stakingContract, address _stakingContract,
address _readOnlyProxy, address _readOnlyProxy,
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
public public
@ -55,8 +51,6 @@ contract StakingProxy is
_attachStakingContract( _attachStakingContract(
_stakingContract, _stakingContract,
_wethProxyAddress, _wethProxyAddress,
_ethVaultAddress,
_rewardVaultAddress,
_zrxVaultAddress _zrxVaultAddress
); );
} }
@ -78,17 +72,11 @@ contract StakingProxy is
/// @param _stakingContract Address of staking contract. /// @param _stakingContract Address of staking contract.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// Use address in storage if NIL_ADDRESS is passed in. /// Use address in storage if NIL_ADDRESS is passed in.
/// @param _ethVaultAddress Address of the EthVault contract.
/// Use address in storage if NIL_ADDRESS is passed in.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// Use address in storage if NIL_ADDRESS is passed in.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
/// Use address in storage if NIL_ADDRESS is passed in. /// Use address in storage if NIL_ADDRESS is passed in.
function attachStakingContract( function attachStakingContract(
address _stakingContract, address _stakingContract,
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
external external
@ -97,8 +85,6 @@ contract StakingProxy is
_attachStakingContract( _attachStakingContract(
_stakingContract, _stakingContract,
_wethProxyAddress == NIL_ADDRESS ? address(wethAssetProxy) : _wethProxyAddress, _wethProxyAddress == NIL_ADDRESS ? address(wethAssetProxy) : _wethProxyAddress,
_ethVaultAddress == NIL_ADDRESS ? address(ethVault) : _ethVaultAddress,
_rewardVaultAddress == NIL_ADDRESS ? address(rewardVault) : _rewardVaultAddress,
_zrxVaultAddress == NIL_ADDRESS ? address(zrxVault) : _zrxVaultAddress _zrxVaultAddress == NIL_ADDRESS ? address(zrxVault) : _zrxVaultAddress
); );
} }
@ -225,20 +211,6 @@ contract StakingProxy is
)); ));
} }
if (address(ethVault) == NIL_ADDRESS) {
LibRichErrors.rrevert(
LibStakingRichErrors.InvalidParamValueError(
LibStakingRichErrors.InvalidParamValueErrorCode.InvalidEthVaultAddress
));
}
if (address(rewardVault) == NIL_ADDRESS) {
LibRichErrors.rrevert(
LibStakingRichErrors.InvalidParamValueError(
LibStakingRichErrors.InvalidParamValueErrorCode.InvalidRewardVaultAddress
));
}
if (address(zrxVault) == NIL_ADDRESS) { if (address(zrxVault) == NIL_ADDRESS) {
LibRichErrors.rrevert( LibRichErrors.rrevert(
LibStakingRichErrors.InvalidParamValueError( LibStakingRichErrors.InvalidParamValueError(
@ -250,14 +222,10 @@ contract StakingProxy is
/// @dev Attach a staking contract; future calls will be delegated to the staking contract. /// @dev Attach a staking contract; future calls will be delegated to the staking contract.
/// @param _stakingContract Address of staking contract. /// @param _stakingContract Address of staking contract.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// @param _ethVaultAddress Address of the EthVault contract.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
function _attachStakingContract( function _attachStakingContract(
address _stakingContract, address _stakingContract,
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
internal internal
@ -271,8 +239,6 @@ contract StakingProxy is
abi.encodeWithSelector( abi.encodeWithSelector(
IStorageInit(0).init.selector, IStorageInit(0).init.selector,
_wethProxyAddress, _wethProxyAddress,
_ethVaultAddress,
_rewardVaultAddress,
_zrxVaultAddress _zrxVaultAddress
) )
); );

View File

@ -25,7 +25,6 @@ import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "../libs/LibStakingRichErrors.sol"; import "../libs/LibStakingRichErrors.sol";
import "../libs/LibCobbDouglas.sol"; import "../libs/LibCobbDouglas.sol";
import "../immutable/MixinDeploymentConstants.sol";
import "../interfaces/IStructs.sol"; import "../interfaces/IStructs.sol";
import "../stake/MixinStakeBalances.sol"; import "../stake/MixinStakeBalances.sol";
import "../sys/MixinFinalizer.sol"; import "../sys/MixinFinalizer.sol";
@ -37,7 +36,6 @@ contract MixinExchangeFees is
IStakingEvents, IStakingEvents,
MixinAbstract, MixinAbstract,
MixinConstants, MixinConstants,
MixinDeploymentConstants,
Ownable, Ownable,
MixinStorage, MixinStorage,
MixinStakingPoolModifiers, MixinStakingPoolModifiers,
@ -74,7 +72,7 @@ contract MixinExchangeFees is
// WETH. // WETH.
if (msg.value == 0) { if (msg.value == 0) {
wethAssetProxy.transferFrom( wethAssetProxy.transferFrom(
WETH_ASSET_DATA, _getWethAssetData(),
payerAddress, payerAddress,
address(this), address(this),
protocolFeePaid protocolFeePaid
@ -99,6 +97,7 @@ contract MixinExchangeFees is
uint256 currentEpoch_ = currentEpoch; uint256 currentEpoch_ = currentEpoch;
mapping (bytes32 => IStructs.ActivePool) storage activePoolsThisEpoch = mapping (bytes32 => IStructs.ActivePool) storage activePoolsThisEpoch =
_getActivePoolsFromEpoch(currentEpoch_); _getActivePoolsFromEpoch(currentEpoch_);
IStructs.ActivePool memory pool = activePoolsThisEpoch[poolId]; IStructs.ActivePool memory pool = activePoolsThisEpoch[poolId];
// If the pool was previously inactive in this epoch, initialize it. // If the pool was previously inactive in this epoch, initialize it.
@ -127,6 +126,20 @@ contract MixinExchangeFees is
activePoolsThisEpoch[poolId] = pool; activePoolsThisEpoch[poolId] = pool;
} }
/// @dev Returns the total balance of this contract, including WETH,
/// minus any WETH that has been reserved for rewards.
/// @return totalBalance Total balance.
function getAvailableRewardsBalance()
external
view
returns (uint256 totalBalance)
{
totalBalance = address(this).balance.safeAdd(
_getAvailableWethBalance()
);
return totalBalance;
}
/// @dev Get information on an active staking pool in this epoch. /// @dev Get information on an active staking pool in this epoch.
/// @param poolId Pool Id to query. /// @param poolId Pool Id to query.
/// @return pool ActivePool struct. /// @return pool ActivePool struct.

View File

@ -18,8 +18,11 @@
pragma solidity ^0.5.9; pragma solidity ^0.5.9;
import "./MixinDeploymentConstants.sol";
contract MixinConstants
contract MixinConstants is
MixinDeploymentConstants
{ {
// 100% in parts-per-million. // 100% in parts-per-million.
uint32 constant internal PPM_DENOMINATOR = 10**6; uint32 constant internal PPM_DENOMINATOR = 10**6;

View File

@ -18,6 +18,7 @@
pragma solidity ^0.5.9; pragma solidity ^0.5.9;
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetData.sol"; import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetData.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol"; import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/LibBytes.sol"; import "@0x/contracts-utils/contracts/src/LibBytes.sol";
@ -50,23 +51,41 @@ contract MixinDeploymentConstants {
// bytes constant internal WETH_ASSET_DATA = hex"f47261b0000000000000000000000000c778417e063141139fce010982780140aa0cd5ab"; // bytes constant internal WETH_ASSET_DATA = hex"f47261b0000000000000000000000000c778417e063141139fce010982780140aa0cd5ab";
/// @dev Ensures that the WETH_ASSET_DATA is correct. /// @dev Ensures that the WETH_ASSET_DATA is correct.
constructor() public { constructor()
public
{
// Ensure that the WETH_ASSET_DATA is correct. // Ensure that the WETH_ASSET_DATA is correct.
if (!WETH_ASSET_DATA.equals( if (!WETH_ASSET_DATA.equals(
abi.encodeWithSelector(IAssetData(address(0)).ERC20Token.selector, WETH_ADDRESS) abi.encodeWithSelector(
IAssetData(address(0)).ERC20Token.selector,
WETH_ADDRESS
)
)) { )) {
LibRichErrors.rrevert(LibStakingRichErrors.InvalidWethAssetDataError()); LibRichErrors.rrevert(LibStakingRichErrors.InvalidWethAssetDataError());
} }
} }
/// @dev An overridable way to access the deployed WETH address. /// @dev An overridable way to access the deployed WETH contract.
/// Must be view to allow overrides to access state. /// Must be view to allow overrides to access state.
/// @return wethAddress The address of the configured WETH contract. /// @return wethContract The WETH contract instance.
function _getWETHAddress() function _getWethContract()
internal internal
view view
returns (address wethAddress) returns (IEtherToken wethContract)
{ {
return WETH_ADDRESS; wethContract = IEtherToken(WETH_ADDRESS);
return wethContract;
}
/// @dev An overridable way to access the deployed WETH assetData.
/// Must be view to allow overrides to access state.
/// @return wethAssetData The assetData of the configured WETH contract.
function _getWethAssetData()
internal
view
returns (bytes memory wethAssetData)
{
wethAssetData = WETH_ASSET_DATA;
return wethAssetData;
} }
} }

View File

@ -24,8 +24,6 @@ import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/Authorizable.sol"; import "@0x/contracts-utils/contracts/src/Authorizable.sol";
import "./MixinConstants.sol"; import "./MixinConstants.sol";
import "../interfaces/IZrxVault.sol"; import "../interfaces/IZrxVault.sol";
import "../interfaces/IEthVault.sol";
import "../interfaces/IStakingPoolRewardVault.sol";
import "../interfaces/IStructs.sol"; import "../interfaces/IStructs.sol";
import "../libs/LibStakingRichErrors.sol"; import "../libs/LibStakingRichErrors.sol";
@ -52,23 +50,23 @@ contract MixinStorage is
mapping (uint8 => IStructs.StoredBalance) public globalStakeByStatus; mapping (uint8 => IStructs.StoredBalance) public globalStakeByStatus;
// mapping from Owner to Amount of Active Stake // mapping from Owner to Amount of Active Stake
// (access using _loadAndSyncBalance or _loadUnsyncedBalance) // (access using _loadSyncedBalance or _loadUnsyncedBalance)
mapping (address => IStructs.StoredBalance) internal _activeStakeByOwner; mapping (address => IStructs.StoredBalance) internal _activeStakeByOwner;
// Mapping from Owner to Amount of Inactive Stake // Mapping from Owner to Amount of Inactive Stake
// (access using _loadAndSyncBalance or _loadUnsyncedBalance) // (access using _loadSyncedBalance or _loadUnsyncedBalance)
mapping (address => IStructs.StoredBalance) internal _inactiveStakeByOwner; mapping (address => IStructs.StoredBalance) internal _inactiveStakeByOwner;
// Mapping from Owner to Amount Delegated // Mapping from Owner to Amount Delegated
// (access using _loadAndSyncBalance or _loadUnsyncedBalance) // (access using _loadSyncedBalance or _loadUnsyncedBalance)
mapping (address => IStructs.StoredBalance) internal _delegatedStakeByOwner; mapping (address => IStructs.StoredBalance) internal _delegatedStakeByOwner;
// Mapping from Owner to Pool Id to Amount Delegated // Mapping from Owner to Pool Id to Amount Delegated
// (access using _loadAndSyncBalance or _loadUnsyncedBalance) // (access using _loadSyncedBalance or _loadUnsyncedBalance)
mapping (address => mapping (bytes32 => IStructs.StoredBalance)) internal _delegatedStakeToPoolByOwner; mapping (address => mapping (bytes32 => IStructs.StoredBalance)) internal _delegatedStakeToPoolByOwner;
// Mapping from Pool Id to Amount Delegated // Mapping from Pool Id to Amount Delegated
// (access using _loadAndSyncBalance or _loadUnsyncedBalance) // (access using _loadSyncedBalance or _loadUnsyncedBalance)
mapping (bytes32 => IStructs.StoredBalance) internal _delegatedStakeByPoolId; mapping (bytes32 => IStructs.StoredBalance) internal _delegatedStakeByPoolId;
// mapping from Owner to Amount of Withdrawable Stake // mapping from Owner to Amount of Withdrawable Stake
@ -84,6 +82,9 @@ contract MixinStorage is
// mapping from Pool Id to Pool // mapping from Pool Id to Pool
mapping (bytes32 => IStructs.Pool) internal _poolById; mapping (bytes32 => IStructs.Pool) internal _poolById;
// mapping from PoolId to balance of members
mapping (bytes32 => uint256) public rewardsByPoolId;
// current epoch // current epoch
uint256 public currentEpoch = INITIAL_EPOCH; uint256 public currentEpoch = INITIAL_EPOCH;
@ -105,12 +106,6 @@ contract MixinStorage is
// ZRX vault (stores staked ZRX) // ZRX vault (stores staked ZRX)
IZrxVault public zrxVault; IZrxVault public zrxVault;
// ETH Vault (stores eth balances of stakers and pool operators)
IEthVault public ethVault;
// Rebate Vault (stores rewards for pools before they are moved to the eth vault on a per-user basis)
IStakingPoolRewardVault public rewardVault;
/* Tweakable parameters */ /* Tweakable parameters */
// Minimum seconds between epochs. // Minimum seconds between epochs.
@ -151,6 +146,9 @@ contract MixinStorage is
/// @dev State for unfinalized rewards. /// @dev State for unfinalized rewards.
IStructs.UnfinalizedState public unfinalizedState; IStructs.UnfinalizedState public unfinalizedState;
/// @dev The WETH balance of this contract that is reserved for pool reward payouts.
uint256 _wethReservedForPoolRewards;
/// @dev Adds owner as an authorized address. /// @dev Adds owner as an authorized address.
constructor() constructor()
public public

View File

@ -1,70 +0,0 @@
/*
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;
/// @dev This vault manages Ether.
interface IEthVault {
/// @dev Emitted when Ether are deposited into the vault.
/// @param sender Address of sender (`msg.sender`).
/// @param owner of Ether.
/// @param amount of Ether deposited.
event EthDepositedIntoVault(
address indexed sender,
address indexed owner,
uint256 amount
);
/// @dev Emitted when Ether are withdrawn from the vault.
/// @param sender Address of sender (`msg.sender`).
/// @param owner of Ether.
/// @param amount of Ether withdrawn.
event EthWithdrawnFromVault(
address indexed sender,
address indexed owner,
uint256 amount
);
/// @dev Deposit an `amount` of WETH for `owner` into the vault.
/// The staking contract should have granted the vault an allowance
/// because it will pull the WETH via `transferFrom()`.
/// Note that this is only callable by the staking contract.
/// @param owner Owner of the WETH.
/// @param amount Amount of deposit.
function depositFor(address owner, uint256 amount)
external;
/// @dev Withdraw an `amount` of WETH to `msg.sender` from the vault.
/// @param amount of WETH to withdraw.
function withdraw(uint256 amount)
external;
/// @dev Withdraw ALL WETH to `msg.sender` from the vault.
function withdrawAll()
external
returns (uint256);
/// @dev Returns the balance in WETH of the `owner`
/// @return Balance in WETH.
function balanceOf(address owner)
external
view
returns (uint256);
}

View File

@ -96,8 +96,6 @@ interface IStakingEvents {
/// @param cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. /// @param cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor.
/// @param cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. /// @param cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor.
/// @param wethProxyAddress The address that can transfer WETH for fees. /// @param wethProxyAddress The address that can transfer WETH for fees.
/// @param ethVaultAddress Address of the EthVault contract.
/// @param rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param zrxVaultAddress Address of the ZrxVault contract. /// @param zrxVaultAddress Address of the ZrxVault contract.
event ParamsSet( event ParamsSet(
uint256 epochDurationInSeconds, uint256 epochDurationInSeconds,
@ -107,8 +105,6 @@ interface IStakingEvents {
uint256 cobbDouglasAlphaNumerator, uint256 cobbDouglasAlphaNumerator,
uint256 cobbDouglasAlphaDenominator, uint256 cobbDouglasAlphaDenominator,
address wethProxyAddress, address wethProxyAddress,
address ethVaultAddress,
address rewardVaultAddress,
address zrxVaultAddress address zrxVaultAddress
); );

View File

@ -1,73 +0,0 @@
/*
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;
/// @dev This vault manages staking pool rewards.
interface IStakingPoolRewardVault {
/// @dev Emitted when WETH is deposited into the vault.
/// @param sender Address of sender (`msg.sender`).
/// @param poolId that owns of WETH.
/// @param amount of WETH deposited.
event EthDepositedIntoVault(
address indexed sender,
bytes32 indexed poolId,
uint256 amount
);
/// @dev Emitted when rewards are transferred out of the vault.
/// @param poolId Unique Id of pool.
/// @param to Address to send funds to.
/// @param amount Amount of WETH to transfer.
event PoolRewardTransferred(
bytes32 indexed poolId,
address indexed to,
uint256 amount
);
/// @dev Deposit an amount of WETH for `poolId` into the vault.
/// The staking contract should have granted the vault an allowance
/// because it will pull the WETH via `transferFrom()`.
/// Note that this is only callable by the staking contract.
/// @param poolId Pool that holds the WETH.
/// @param amount Amount of deposit.
function depositFor(bytes32 poolId, uint256 amount)
external;
/// @dev Withdraw some amount in WETH from a pool.
/// Note that this is only callable by the staking contract.
/// @param poolId Unique Id of pool.
/// @param to Address to send funds to.
/// @param amount Amount of WETH to transfer.
function transfer(
bytes32 poolId,
address payable to,
uint256 amount
)
external;
/// @dev Returns the balance in WETH of `poolId`
/// @return Balance in WETH.
function balanceOf(bytes32 poolId)
external
view
returns (uint256);
}

View File

@ -47,17 +47,11 @@ interface IStakingProxy /* is IStaking */
/// @param _stakingContract Address of staking contract. /// @param _stakingContract Address of staking contract.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// Use address in storage if NIL_ADDRESS is passed in. /// Use address in storage if NIL_ADDRESS is passed in.
/// @param _ethVaultAddress Address of the EthVault contract.
/// Use address in storage if NIL_ADDRESS is passed in.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// Use address in storage if NIL_ADDRESS is passed in.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
/// Use address in storage if NIL_ADDRESS is passed in. /// Use address in storage if NIL_ADDRESS is passed in.
function attachStakingContract( function attachStakingContract(
address _stakingContract, address _stakingContract,
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
external; external;

View File

@ -21,8 +21,6 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetProxy.sol"; import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetProxy.sol";
import "../interfaces/IZrxVault.sol"; import "../interfaces/IZrxVault.sol";
import "../interfaces/IEthVault.sol";
import "../interfaces/IStakingPoolRewardVault.sol";
import "../interfaces/IStructs.sol"; import "../interfaces/IStructs.sol";
@ -93,16 +91,6 @@ interface IStorage {
view view
returns (IZrxVault); returns (IZrxVault);
function ethVault()
external
view
returns (IEthVault);
function rewardVault()
external
view
returns (IStakingPoolRewardVault);
function epochDurationInSeconds() function epochDurationInSeconds()
external external
view view

View File

@ -23,13 +23,9 @@ interface IStorageInit {
/// @dev Initialize storage owned by this contract. /// @dev Initialize storage owned by this contract.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// @param _ethVaultAddress Address of the EthVault contract.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
function init( function init(
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
external; external;

View File

@ -52,7 +52,7 @@ interface IStructs {
/// @dev Encapsulates a balance for the current and next epochs. /// @dev Encapsulates a balance for the current and next epochs.
/// Note that these balances may be stale if the current epoch /// Note that these balances may be stale if the current epoch
/// is greater than `currentEpoch`. /// is greater than `currentEpoch`.
/// Always load this struct using _loadAndSyncBalance or _loadUnsyncedBalance. /// Always load this struct using _loadSyncedBalance or _loadUnsyncedBalance.
/// @param isInitialized /// @param isInitialized
/// @param currentEpoch the current epoch /// @param currentEpoch the current epoch
/// @param currentEpochBalance balance in the current epoch. /// @param currentEpochBalance balance in the current epoch.

View File

@ -44,8 +44,6 @@ library LibStakingRichErrors {
InvalidMaximumMakersInPool, InvalidMaximumMakersInPool,
InvalidMinimumPoolStake, InvalidMinimumPoolStake,
InvalidWethProxyAddress, InvalidWethProxyAddress,
InvalidEthVaultAddress,
InvalidRewardVaultAddress,
InvalidZrxVaultAddress, InvalidZrxVaultAddress,
InvalidEpochDuration InvalidEpochDuration
} }
@ -121,14 +119,6 @@ library LibStakingRichErrors {
bytes4 internal constant POOL_EXISTENCE_ERROR_SELECTOR = bytes4 internal constant POOL_EXISTENCE_ERROR_SELECTOR =
0x9ae94f01; 0x9ae94f01;
// bytes4(keccak256("EthVaultNotSetError()"))
bytes4 internal constant ETH_VAULT_NOT_SET_ERROR_SELECTOR =
0xa067f596;
// bytes4(keccak256("RewardVaultNotSetError()"))
bytes4 internal constant REWARD_VAULT_NOT_SET_ERROR_SELECTOR =
0xe6976d70;
// bytes4(keccak256("InvalidStakeStatusError(uint256)")) // bytes4(keccak256("InvalidStakeStatusError(uint256)"))
bytes4 internal constant INVALID_STAKE_STATUS_ERROR_SELECTOR = bytes4 internal constant INVALID_STAKE_STATUS_ERROR_SELECTOR =
0xb7161acd; 0xb7161acd;
@ -382,26 +372,6 @@ library LibStakingRichErrors {
); );
} }
function EthVaultNotSetError()
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
ETH_VAULT_NOT_SET_ERROR_SELECTOR
);
}
function RewardVaultNotSetError()
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
REWARD_VAULT_NOT_SET_ERROR_SELECTOR
);
}
function InvalidProtocolFeePaymentError( function InvalidProtocolFeePaymentError(
ProtocolFeePaymentErrorCodes errorCode, ProtocolFeePaymentErrorCodes errorCode,
uint256 expectedProtocolFeePaid, uint256 expectedProtocolFeePaid,

View File

@ -216,8 +216,9 @@ contract MixinStake is
// Synchronizes reward state in the pool that the staker is delegating // Synchronizes reward state in the pool that the staker is delegating
// to. // to.
IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner = IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner =
_loadAndSyncBalance(_delegatedStakeToPoolByOwner[owner][poolId]); _loadSyncedBalance(_delegatedStakeToPoolByOwner[owner][poolId]);
_syncRewardsForDelegator(
_withdrawAndSyncDelegatorRewards(
poolId, poolId,
owner, owner,
initDelegatedStakeToPoolByOwner, initDelegatedStakeToPoolByOwner,
@ -255,8 +256,9 @@ contract MixinStake is
// synchronizes reward state in the pool that the staker is undelegating // synchronizes reward state in the pool that the staker is undelegating
// from // from
IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner = IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner =
_loadAndSyncBalance(_delegatedStakeToPoolByOwner[owner][poolId]); _loadSyncedBalance(_delegatedStakeToPoolByOwner[owner][poolId]);
_syncRewardsForDelegator(
_withdrawAndSyncDelegatorRewards(
poolId, poolId,
owner, owner,
initDelegatedStakeToPoolByOwner, initDelegatedStakeToPoolByOwner,

View File

@ -43,7 +43,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance( IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(
globalStakeByStatus[uint8(IStructs.StakeStatus.ACTIVE)] globalStakeByStatus[uint8(IStructs.StakeStatus.ACTIVE)]
); );
return IStructs.StakeBalance({ return IStructs.StakeBalance({
@ -59,7 +59,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance( IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(
globalStakeByStatus[uint8(IStructs.StakeStatus.INACTIVE)] globalStakeByStatus[uint8(IStructs.StakeStatus.INACTIVE)]
); );
return IStructs.StakeBalance({ return IStructs.StakeBalance({
@ -75,7 +75,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance( IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(
globalStakeByStatus[uint8(IStructs.StakeStatus.DELEGATED)] globalStakeByStatus[uint8(IStructs.StakeStatus.DELEGATED)]
); );
return IStructs.StakeBalance({ return IStructs.StakeBalance({
@ -103,7 +103,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(_activeStakeByOwner[owner]); IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(_activeStakeByOwner[owner]);
return IStructs.StakeBalance({ return IStructs.StakeBalance({
currentEpochBalance: storedBalance.currentEpochBalance, currentEpochBalance: storedBalance.currentEpochBalance,
nextEpochBalance: storedBalance.nextEpochBalance nextEpochBalance: storedBalance.nextEpochBalance
@ -118,7 +118,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(_inactiveStakeByOwner[owner]); IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(_inactiveStakeByOwner[owner]);
return IStructs.StakeBalance({ return IStructs.StakeBalance({
currentEpochBalance: storedBalance.currentEpochBalance, currentEpochBalance: storedBalance.currentEpochBalance,
nextEpochBalance: storedBalance.nextEpochBalance nextEpochBalance: storedBalance.nextEpochBalance
@ -133,7 +133,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(_delegatedStakeByOwner[owner]); IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(_delegatedStakeByOwner[owner]);
return IStructs.StakeBalance({ return IStructs.StakeBalance({
currentEpochBalance: storedBalance.currentEpochBalance, currentEpochBalance: storedBalance.currentEpochBalance,
nextEpochBalance: storedBalance.nextEpochBalance nextEpochBalance: storedBalance.nextEpochBalance
@ -160,7 +160,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(_delegatedStakeToPoolByOwner[owner][poolId]); IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(_delegatedStakeToPoolByOwner[owner][poolId]);
return IStructs.StakeBalance({ return IStructs.StakeBalance({
currentEpochBalance: storedBalance.currentEpochBalance, currentEpochBalance: storedBalance.currentEpochBalance,
nextEpochBalance: storedBalance.nextEpochBalance nextEpochBalance: storedBalance.nextEpochBalance
@ -176,7 +176,7 @@ contract MixinStakeBalances is
view view
returns (IStructs.StakeBalance memory balance) returns (IStructs.StakeBalance memory balance)
{ {
IStructs.StoredBalance memory storedBalance = _loadAndSyncBalance(_delegatedStakeByPoolId[poolId]); IStructs.StoredBalance memory storedBalance = _loadSyncedBalance(_delegatedStakeByPoolId[poolId]);
return IStructs.StakeBalance({ return IStructs.StakeBalance({
currentEpochBalance: storedBalance.currentEpochBalance, currentEpochBalance: storedBalance.currentEpochBalance,
nextEpochBalance: storedBalance.nextEpochBalance nextEpochBalance: storedBalance.nextEpochBalance

View File

@ -53,8 +53,8 @@ contract MixinStakeStorage is
} }
// load balance from storage and synchronize it // load balance from storage and synchronize it
IStructs.StoredBalance memory from = _loadAndSyncBalance(fromPtr); IStructs.StoredBalance memory from = _loadSyncedBalance(fromPtr);
IStructs.StoredBalance memory to = _loadAndSyncBalance(toPtr); IStructs.StoredBalance memory to = _loadSyncedBalance(toPtr);
// sanity check on balance // sanity check on balance
if (amount > from.nextEpochBalance) { if (amount > from.nextEpochBalance) {
@ -81,7 +81,7 @@ contract MixinStakeStorage is
/// was stored. /// was stored.
/// @param balancePtr to load and sync. /// @param balancePtr to load and sync.
/// @return synchronized balance. /// @return synchronized balance.
function _loadAndSyncBalance(IStructs.StoredBalance storage balancePtr) function _loadSyncedBalance(IStructs.StoredBalance storage balancePtr)
internal internal
view view
returns (IStructs.StoredBalance memory balance) returns (IStructs.StoredBalance memory balance)
@ -119,7 +119,7 @@ contract MixinStakeStorage is
internal internal
{ {
// Remove stake from balance // Remove stake from balance
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr); IStructs.StoredBalance memory balance = _loadSyncedBalance(balancePtr);
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeAdd(amount).downcastToUint96(); balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeAdd(amount).downcastToUint96();
balance.currentEpochBalance = uint256(balance.currentEpochBalance).safeAdd(amount).downcastToUint96(); balance.currentEpochBalance = uint256(balance.currentEpochBalance).safeAdd(amount).downcastToUint96();
@ -134,7 +134,7 @@ contract MixinStakeStorage is
internal internal
{ {
// Remove stake from balance // Remove stake from balance
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr); IStructs.StoredBalance memory balance = _loadSyncedBalance(balancePtr);
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeSub(amount).downcastToUint96(); balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeSub(amount).downcastToUint96();
balance.currentEpochBalance = uint256(balance.currentEpochBalance).safeSub(amount).downcastToUint96(); balance.currentEpochBalance = uint256(balance.currentEpochBalance).safeSub(amount).downcastToUint96();
@ -149,7 +149,7 @@ contract MixinStakeStorage is
internal internal
{ {
// Add stake to balance // Add stake to balance
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr); IStructs.StoredBalance memory balance = _loadSyncedBalance(balancePtr);
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeAdd(amount).downcastToUint96(); balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeAdd(amount).downcastToUint96();
// update state // update state
@ -163,7 +163,7 @@ contract MixinStakeStorage is
internal internal
{ {
// Remove stake from balance // Remove stake from balance
IStructs.StoredBalance memory balance = _loadAndSyncBalance(balancePtr); IStructs.StoredBalance memory balance = _loadSyncedBalance(balancePtr);
balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeSub(amount).downcastToUint96(); balance.nextEpochBalance = uint256(balance.nextEpochBalance).safeSub(amount).downcastToUint96();
// update state // update state

View File

@ -39,21 +39,22 @@ contract MixinStakingPoolRewards is
{ {
using LibSafeMath for uint256; using LibSafeMath for uint256;
/// @dev Syncs rewards for a delegator. This includes transferring rewards /// @dev Syncs rewards for a delegator. This includes transferring WETH
/// from the Reward Vault to the Eth Vault, and adding/removing /// rewards to the delegator, and adding/removing
/// dependencies on cumulative rewards. /// dependencies on cumulative rewards.
/// This is used by a delegator when they want to sync their rewards /// This is used by a delegator when they want to sync their rewards
/// without delegating/undelegating. It's effectively the same as /// without delegating/undelegating. It's effectively the same as
/// delegating zero stake. /// delegating zero stake.
/// @param poolId Unique id of pool. /// @param poolId Unique id of pool.
function syncDelegatorRewards(bytes32 poolId) function withdrawDelegatorRewards(bytes32 poolId)
external external
{ {
address member = msg.sender; address member = msg.sender;
IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner = IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner =
_loadAndSyncBalance(_delegatedStakeToPoolByOwner[member][poolId]); _loadSyncedBalance(_delegatedStakeToPoolByOwner[member][poolId]);
_syncRewardsForDelegator(
_withdrawAndSyncDelegatorRewards(
poolId, poolId,
member, member,
// Initial balance // Initial balance
@ -68,7 +69,6 @@ contract MixinStakingPoolRewards is
} }
/// @dev Computes the reward balance in ETH of the operator of a pool. /// @dev Computes the reward balance in ETH of the operator of a pool.
/// This does not include the balance in the ETH vault.
/// @param poolId Unique id of pool. /// @param poolId Unique id of pool.
/// @return totalReward Balance in ETH. /// @return totalReward Balance in ETH.
function computeRewardBalanceOfOperator(bytes32 poolId) function computeRewardBalanceOfOperator(bytes32 poolId)
@ -76,14 +76,16 @@ contract MixinStakingPoolRewards is
view view
returns (uint256 reward) returns (uint256 reward)
{ {
// Because operator rewards are immediately sent to the ETH vault // Because operator rewards are immediately withdrawn as WETH
// on finalization, the only factor in this function are unfinalized // on finalization, the only factor in this function are unfinalized
// rewards. // rewards.
IStructs.Pool memory pool = _poolById[poolId]; IStructs.Pool memory pool = _poolById[poolId];
// Get any unfinalized rewards. // Get any unfinalized rewards.
(uint256 unfinalizedTotalRewards, uint256 unfinalizedMembersStake) = _getUnfinalizedPoolRewards(poolId); (uint256 unfinalizedTotalRewards, uint256 unfinalizedMembersStake) =
_getUnfinalizedPoolRewards(poolId);
// Get the operators' portion. // Get the operators' portion.
(reward,) = _computeSplitStakingPoolRewards( (reward,) = _computePoolRewardsSplit(
pool.operatorShare, pool.operatorShare,
unfinalizedTotalRewards, unfinalizedTotalRewards,
unfinalizedMembersStake unfinalizedMembersStake
@ -92,7 +94,6 @@ contract MixinStakingPoolRewards is
} }
/// @dev Computes the reward balance in ETH of a specific member of a pool. /// @dev Computes the reward balance in ETH of a specific member of a pool.
/// This does not include the balance in the ETH vault.
/// @param poolId Unique id of pool. /// @param poolId Unique id of pool.
/// @param member The member of the pool. /// @param member The member of the pool.
/// @return totalReward Balance in ETH. /// @return totalReward Balance in ETH.
@ -105,13 +106,14 @@ contract MixinStakingPoolRewards is
// Get any unfinalized rewards. // Get any unfinalized rewards.
(uint256 unfinalizedTotalRewards, uint256 unfinalizedMembersStake) = (uint256 unfinalizedTotalRewards, uint256 unfinalizedMembersStake) =
_getUnfinalizedPoolRewards(poolId); _getUnfinalizedPoolRewards(poolId);
// Get the members' portion. // Get the members' portion.
(, uint256 unfinalizedMembersReward) = _computeSplitStakingPoolRewards( (, uint256 unfinalizedMembersReward) = _computePoolRewardsSplit(
pool.operatorShare, pool.operatorShare,
unfinalizedTotalRewards, unfinalizedTotalRewards,
unfinalizedMembersStake unfinalizedMembersStake
); );
return _computeRewardBalanceOfDelegator( return _computeDelegatorReward(
poolId, poolId,
_loadUnsyncedBalance(_delegatedStakeToPoolByOwner[member][poolId]), _loadUnsyncedBalance(_delegatedStakeToPoolByOwner[member][poolId]),
currentEpoch, currentEpoch,
@ -121,15 +123,14 @@ contract MixinStakingPoolRewards is
} }
/// @dev Syncs rewards for a delegator. This includes transferring rewards /// @dev Syncs rewards for a delegator. This includes transferring rewards
/// from the Reward Vault to the Eth Vault, and adding/removing /// withdrawing rewards and adding/removing dependencies on cumulative rewards.
/// dependencies on cumulative rewards.
/// @param poolId Unique id of pool. /// @param poolId Unique id of pool.
/// @param member of the pool. /// @param member of the pool.
/// @param initialDelegatedStakeToPoolByOwner The member's delegated /// @param initialDelegatedStakeToPoolByOwner The member's delegated
/// balance at the beginning of this transaction. /// balance at the beginning of this transaction.
/// @param finalDelegatedStakeToPoolByOwner The member's delegated balance /// @param finalDelegatedStakeToPoolByOwner The member's delegated balance
/// at the end of this transaction. /// at the end of this transaction.
function _syncRewardsForDelegator( function _withdrawAndSyncDelegatorRewards(
bytes32 poolId, bytes32 poolId,
address member, address member,
IStructs.StoredBalance memory initialDelegatedStakeToPoolByOwner, IStructs.StoredBalance memory initialDelegatedStakeToPoolByOwner,
@ -137,10 +138,10 @@ contract MixinStakingPoolRewards is
) )
internal internal
{ {
// Transfer any rewards from the transient pool vault to the eth vault; // Withdraw any rewards from.
// this must be done before we can modify the owner's portion of the // this must be done before we can modify the owner's portion of the
// delegator pool. // delegator pool.
_transferDelegatorRewardsToEthVault( _finalizePoolAndWithdrawDelegatorRewards(
poolId, poolId,
member, member,
initialDelegatedStakeToPoolByOwner, initialDelegatedStakeToPoolByOwner,
@ -175,7 +176,7 @@ contract MixinStakingPoolRewards is
/// will split the reward. /// will split the reward.
/// @return operatorReward Portion of `reward` given to the pool operator. /// @return operatorReward Portion of `reward` given to the pool operator.
/// @return membersReward Portion of `reward` given to the pool members. /// @return membersReward Portion of `reward` given to the pool members.
function _depositStakingPoolRewards( function _syncPoolRewards(
bytes32 poolId, bytes32 poolId,
uint256 reward, uint256 reward,
uint256 membersStake uint256 membersStake
@ -186,19 +187,20 @@ contract MixinStakingPoolRewards is
IStructs.Pool memory pool = _poolById[poolId]; IStructs.Pool memory pool = _poolById[poolId];
// Split the reward between operator and members // Split the reward between operator and members
(operatorReward, membersReward) = _computeSplitStakingPoolRewards( (operatorReward, membersReward) = _computePoolRewardsSplit(
pool.operatorShare, pool.operatorShare,
reward, reward,
membersStake membersStake
); );
// Deposit the operator's reward in the eth vault.
ethVault.depositFor(pool.operator, operatorReward);
if (membersReward == 0) { if (operatorReward > 0) {
return (0, 0); // Transfer the operator's weth reward to the operator
_getWethContract().transfer(pool.operator, operatorReward);
} }
// Deposit the members' reward in the reward vault.
rewardVault.depositFor(poolId, membersReward); if (membersReward > 0) {
// Increment the balance of the pool
_incrementPoolRewards(poolId, membersReward);
// Fetch the last epoch at which we stored an entry for this pool; // Fetch the last epoch at which we stored an entry for this pool;
// this is the most up-to-date cumulative rewards for this pool. // this is the most up-to-date cumulative rewards for this pool.
@ -224,6 +226,7 @@ contract MixinStakingPoolRewards is
currentEpoch, currentEpoch,
cumulativeReward cumulativeReward
); );
}
return (operatorReward, membersReward); return (operatorReward, membersReward);
} }
@ -237,7 +240,7 @@ contract MixinStakingPoolRewards is
/// to the pool in the epoch the rewards were earned. /// to the pool in the epoch the rewards were earned.
/// @return operatorReward Portion of `totalReward` given to the pool operator. /// @return operatorReward Portion of `totalReward` given to the pool operator.
/// @return membersReward Portion of `totalReward` given to the pool members. /// @return membersReward Portion of `totalReward` given to the pool members.
function _computeSplitStakingPoolRewards( function _computePoolRewardsSplit(
uint32 operatorShare, uint32 operatorShare,
uint256 totalReward, uint256 totalReward,
uint256 membersStake uint256 membersStake
@ -259,13 +262,12 @@ contract MixinStakingPoolRewards is
return (operatorReward, membersReward); return (operatorReward, membersReward);
} }
/// @dev Transfers a delegators accumulated rewards from the transient pool /// @dev Transfers a delegators accumulated rewards to the delegator.
/// Reward Pool vault to the Eth Vault. This is required before the /// This is required before the member's stake in the pool can be modified.
/// member's stake in the pool can be modified.
/// @param poolId Unique id of pool. /// @param poolId Unique id of pool.
/// @param member The member of the pool. /// @param member The member of the pool.
/// @param unsyncedStake Unsynced stake of the delegator to the pool. /// @param unsyncedStake Unsynced stake of the delegator to the pool.
function _transferDelegatorRewardsToEthVault( function _finalizePoolAndWithdrawDelegatorRewards(
bytes32 poolId, bytes32 poolId,
address member, address member,
IStructs.StoredBalance memory unsyncedStake, IStructs.StoredBalance memory unsyncedStake,
@ -277,7 +279,7 @@ contract MixinStakingPoolRewards is
finalizePool(poolId); finalizePool(poolId);
// Compute balance owed to delegator // Compute balance owed to delegator
uint256 balance = _computeRewardBalanceOfDelegator( uint256 balance = _computeDelegatorReward(
poolId, poolId,
unsyncedStake, unsyncedStake,
currentEpoch, currentEpoch,
@ -290,10 +292,11 @@ contract MixinStakingPoolRewards is
return; return;
} }
// Transfer from RewardVault to this contract. // Decrement the balance of the pool
rewardVault.transfer(poolId, address(uint160(address(this))), balance); _decrementPoolRewards(poolId, balance);
// Transfer to EthVault.
ethVault.depositFor(member, balance); // Withdraw the member's WETH balance
_getWethContract().transfer(member, balance);
} }
/// @dev Computes the reward balance in ETH of a specific member of a pool. /// @dev Computes the reward balance in ETH of a specific member of a pool.
@ -304,7 +307,7 @@ contract MixinStakingPoolRewards is
/// (if any). /// (if any).
/// @param unfinalizedMembersStake Unfinalized total members stake (if any). /// @param unfinalizedMembersStake Unfinalized total members stake (if any).
/// @return totalReward Balance in ETH. /// @return totalReward Balance in ETH.
function _computeRewardBalanceOfDelegator( function _computeDelegatorReward(
bytes32 poolId, bytes32 poolId,
IStructs.StoredBalance memory unsyncedStake, IStructs.StoredBalance memory unsyncedStake,
uint256 currentEpoch, uint256 currentEpoch,
@ -424,4 +427,24 @@ contract MixinStakingPoolRewards is
); );
} }
} }
/// @dev Increments rewards for a pool.
/// @param poolId Unique id of pool.
/// @param amount Amount to increment rewards by.
function _incrementPoolRewards(bytes32 poolId, uint256 amount)
private
{
rewardsByPoolId[poolId] = rewardsByPoolId[poolId].safeAdd(amount);
_wethReservedForPoolRewards = _wethReservedForPoolRewards.safeAdd(amount);
}
/// @dev Decrements rewards for a pool.
/// @param poolId Unique id of pool.
/// @param amount Amount to decrement rewards by.
function _decrementPoolRewards(bytes32 poolId, uint256 amount)
private
{
rewardsByPoolId[poolId] = rewardsByPoolId[poolId].safeSub(amount);
_wethReservedForPoolRewards = _wethReservedForPoolRewards.safeSub(amount);
}
} }

View File

@ -27,8 +27,8 @@ import "../interfaces/IStructs.sol";
contract MixinAbstract { contract MixinAbstract {
/// @dev Instantly finalizes a single pool that was active in the previous /// @dev Instantly finalizes a single pool that was active in the previous
/// epoch, crediting it rewards and sending those rewards to the reward /// epoch, crediting it rewards for members and withdrawing operator's
/// and eth vault. This can be called by internal functions that need /// rewards as WETH. This can be called by internal functions that need
/// to finalize a pool immediately. Does nothing if the pool is already /// to finalize a pool immediately. Does nothing if the pool is already
/// finalized or was not active in the previous epoch. /// finalized or was not active in the previous epoch.
/// @param poolId The pool ID to finalize. /// @param poolId The pool ID to finalize.

View File

@ -26,7 +26,6 @@ import "../libs/LibCobbDouglas.sol";
import "../libs/LibStakingRichErrors.sol"; import "../libs/LibStakingRichErrors.sol";
import "../immutable/MixinStorage.sol"; import "../immutable/MixinStorage.sol";
import "../immutable/MixinConstants.sol"; import "../immutable/MixinConstants.sol";
import "../immutable/MixinDeploymentConstants.sol";
import "../interfaces/IStakingEvents.sol"; import "../interfaces/IStakingEvents.sol";
import "../interfaces/IStructs.sol"; import "../interfaces/IStructs.sol";
import "../stake/MixinStakeBalances.sol"; import "../stake/MixinStakeBalances.sol";
@ -43,7 +42,6 @@ contract MixinFinalizer is
IStakingEvents, IStakingEvents,
MixinAbstract, MixinAbstract,
MixinConstants, MixinConstants,
MixinDeploymentConstants,
Ownable, Ownable,
MixinStorage, MixinStorage,
MixinScheduler, MixinScheduler,
@ -78,8 +76,11 @@ contract MixinFinalizer is
); );
} }
// Convert all ETH to WETH
_wrapEth();
// Set up unfinalized state. // Set up unfinalized state.
state.rewardsAvailable = _wrapBalanceToWETHAndGetBalance(); state.rewardsAvailable = _getAvailableWethBalance();
state.poolsRemaining = poolsRemaining = numActivePoolsThisEpoch; state.poolsRemaining = poolsRemaining = numActivePoolsThisEpoch;
state.totalFeesCollected = totalFeesCollectedThisEpoch; state.totalFeesCollected = totalFeesCollectedThisEpoch;
state.totalWeightedStake = totalWeightedStakeThisEpoch; state.totalWeightedStake = totalWeightedStakeThisEpoch;
@ -110,8 +111,8 @@ contract MixinFinalizer is
} }
/// @dev Instantly finalizes a single pool that was active in the previous /// @dev Instantly finalizes a single pool that was active in the previous
/// epoch, crediting it rewards and sending those rewards to the reward /// epoch, crediting it rewards for members and withdrawing operator's
/// and eth vault. This can be called by internal functions that need /// rewards as WETH. This can be called by internal functions that need
/// to finalize a pool immediately. Does nothing if the pool is already /// to finalize a pool immediately. Does nothing if the pool is already
/// finalized or was not active in the previous epoch. /// finalized or was not active in the previous epoch.
/// @param poolId The pool ID to finalize. /// @param poolId The pool ID to finalize.
@ -202,7 +203,7 @@ contract MixinFinalizer is
return (0, 0); return (0, 0);
} }
IStructs.ActivePool memory pool = _getActivePoolFromEpoch(epoch - 1, poolId); IStructs.ActivePool memory pool = _getActivePoolFromEpoch(epoch - 1, poolId);
reward = _getUnfinalizedPoolRewards(pool, unfinalizedState); reward = _getUnfinalizedPoolRewardsFromState(pool, unfinalizedState);
membersStake = pool.membersStake; membersStake = pool.membersStake;
} }
@ -238,27 +239,34 @@ contract MixinFinalizer is
return activePools; return activePools;
} }
/// @dev Converts the entire ETH balance of the contract into WETH and /// @dev Converts the entire ETH balance of this contract into WETH.
/// returns the total WETH balance of this contract. function _wrapEth()
/// @return The WETH balance of this contract.
function _wrapBalanceToWETHAndGetBalance()
internal internal
returns (uint256 balance)
{ {
IEtherToken weth = IEtherToken(_getWETHAddress());
uint256 ethBalance = address(this).balance; uint256 ethBalance = address(this).balance;
if (ethBalance != 0) { if (ethBalance != 0) {
weth.deposit.value((address(this).balance))(); _getWethContract().deposit.value(ethBalance)();
} }
balance = weth.balanceOf(address(this)); }
return balance;
/// @dev Returns the WETH balance of this contract, minus
/// any WETH that has already been reserved for rewards.
function _getAvailableWethBalance()
internal
view
returns (uint256 wethBalance)
{
wethBalance = _getWethContract().balanceOf(address(this))
.safeSub(_wethReservedForPoolRewards);
return wethBalance;
} }
/// @dev Computes the reward owed to a pool during finalization. /// @dev Computes the reward owed to a pool during finalization.
/// @param pool The active pool. /// @param pool The active pool.
/// @param state The current state of finalization. /// @param state The current state of finalization.
/// @return rewards Unfinalized rewards for this pool. /// @return rewards Unfinalized rewards for this pool.
function _getUnfinalizedPoolRewards( function _getUnfinalizedPoolRewardsFromState(
IStructs.ActivePool memory pool, IStructs.ActivePool memory pool,
IStructs.UnfinalizedState memory state IStructs.UnfinalizedState memory state
) )
@ -314,12 +322,12 @@ contract MixinFinalizer is
delete _getActivePoolsFromEpoch(epoch.safeSub(1))[poolId]; delete _getActivePoolsFromEpoch(epoch.safeSub(1))[poolId];
// Compute the rewards. // Compute the rewards.
uint256 rewards = _getUnfinalizedPoolRewards(pool, state); uint256 rewards = _getUnfinalizedPoolRewardsFromState(pool, state);
// Pay the pool. // Pay the pool.
// Note that we credit at the CURRENT epoch even though these rewards // Note that we credit at the CURRENT epoch even though these rewards
// were earned in the previous epoch. // were earned in the previous epoch.
(operatorReward, membersReward) = _depositStakingPoolRewards( (operatorReward, membersReward) = _syncPoolRewards(
poolId, poolId,
rewards, rewards,
pool.membersStake pool.membersStake

View File

@ -22,10 +22,7 @@ import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol"; import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetProxy.sol"; import "@0x/contracts-asset-proxy/contracts/src/interfaces/IAssetProxy.sol";
import "../immutable/MixinStorage.sol"; import "../immutable/MixinStorage.sol";
import "../immutable/MixinDeploymentConstants.sol";
import "../interfaces/IStakingEvents.sol"; import "../interfaces/IStakingEvents.sol";
import "../interfaces/IEthVault.sol";
import "../interfaces/IStakingPoolRewardVault.sol";
import "../interfaces/IZrxVault.sol"; import "../interfaces/IZrxVault.sol";
import "../libs/LibStakingRichErrors.sol"; import "../libs/LibStakingRichErrors.sol";
@ -33,7 +30,6 @@ import "../libs/LibStakingRichErrors.sol";
contract MixinParams is contract MixinParams is
IStakingEvents, IStakingEvents,
MixinConstants, MixinConstants,
MixinDeploymentConstants,
Ownable, Ownable,
MixinStorage MixinStorage
{ {
@ -45,8 +41,6 @@ contract MixinParams is
/// @param _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. /// @param _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor.
/// @param _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. /// @param _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// @param _ethVaultAddress Address of the EthVault contract.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
function setParams( function setParams(
uint256 _epochDurationInSeconds, uint256 _epochDurationInSeconds,
@ -56,8 +50,6 @@ contract MixinParams is
uint32 _cobbDouglasAlphaNumerator, uint32 _cobbDouglasAlphaNumerator,
uint32 _cobbDouglasAlphaDenominator, uint32 _cobbDouglasAlphaDenominator,
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address payable _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
external external
@ -71,8 +63,6 @@ contract MixinParams is
_cobbDouglasAlphaNumerator, _cobbDouglasAlphaNumerator,
_cobbDouglasAlphaDenominator, _cobbDouglasAlphaDenominator,
_wethProxyAddress, _wethProxyAddress,
_ethVaultAddress,
_rewardVaultAddress,
_zrxVaultAddress _zrxVaultAddress
); );
} }
@ -85,8 +75,6 @@ contract MixinParams is
/// @return _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. /// @return _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor.
/// @return _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. /// @return _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor.
/// @return _wethProxyAddress The address that can transfer WETH for fees. /// @return _wethProxyAddress The address that can transfer WETH for fees.
/// @return _ethVaultAddress Address of the EthVault contract.
/// @return _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @return _zrxVaultAddress Address of the ZrxVault contract. /// @return _zrxVaultAddress Address of the ZrxVault contract.
function getParams() function getParams()
external external
@ -99,8 +87,6 @@ contract MixinParams is
uint32 _cobbDouglasAlphaNumerator, uint32 _cobbDouglasAlphaNumerator,
uint32 _cobbDouglasAlphaDenominator, uint32 _cobbDouglasAlphaDenominator,
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
{ {
@ -111,20 +97,14 @@ contract MixinParams is
_cobbDouglasAlphaNumerator = cobbDouglasAlphaNumerator; _cobbDouglasAlphaNumerator = cobbDouglasAlphaNumerator;
_cobbDouglasAlphaDenominator = cobbDouglasAlphaDenominator; _cobbDouglasAlphaDenominator = cobbDouglasAlphaDenominator;
_wethProxyAddress = address(wethAssetProxy); _wethProxyAddress = address(wethAssetProxy);
_ethVaultAddress = address(ethVault);
_rewardVaultAddress = address(rewardVault);
_zrxVaultAddress = address(zrxVault); _zrxVaultAddress = address(zrxVault);
} }
/// @dev Initialize storage belonging to this mixin. /// @dev Initialize storage belonging to this mixin.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// @param _ethVaultAddress Address of the EthVault contract.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
function _initMixinParams( function _initMixinParams(
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address payable _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
internal internal
@ -142,8 +122,6 @@ contract MixinParams is
1, // cobbDouglasAlphaNumerator 1, // cobbDouglasAlphaNumerator
2, // cobbDouglasAlphaDenominator 2, // cobbDouglasAlphaDenominator
_wethProxyAddress, _wethProxyAddress,
_ethVaultAddress,
_rewardVaultAddress,
_zrxVaultAddress _zrxVaultAddress
); );
} }
@ -160,8 +138,6 @@ contract MixinParams is
cobbDouglasAlphaNumerator != 0 && cobbDouglasAlphaNumerator != 0 &&
cobbDouglasAlphaDenominator != 0 && cobbDouglasAlphaDenominator != 0 &&
address(wethAssetProxy) != NIL_ADDRESS && address(wethAssetProxy) != NIL_ADDRESS &&
address(ethVault) != NIL_ADDRESS &&
address(rewardVault) != NIL_ADDRESS &&
address(zrxVault) != NIL_ADDRESS address(zrxVault) != NIL_ADDRESS
) { ) {
LibRichErrors.rrevert( LibRichErrors.rrevert(
@ -172,26 +148,6 @@ contract MixinParams is
} }
} }
/// @dev Rescind the WETH allowance for `oldSpenders` and grant `newSpenders`
/// an unlimited allowance.
/// @param oldSpenders Addresses to remove allowance from.
/// @param newSpenders Addresses to grant allowance to.
function _transferWETHAllownces(
address[2] memory oldSpenders,
address[2] memory newSpenders
)
internal
{
IEtherToken weth = IEtherToken(_getWETHAddress());
// Grant new allowances.
for (uint256 i = 0; i < oldSpenders.length; i++) {
// Rescind old allowance.
weth.approve(oldSpenders[i], 0);
// Grant new allowance.
weth.approve(newSpenders[i], uint256(-1));
}
}
/// @dev Set all configurable parameters at once. /// @dev Set all configurable parameters at once.
/// @param _epochDurationInSeconds Minimum seconds between epochs. /// @param _epochDurationInSeconds Minimum seconds between epochs.
/// @param _rewardDelegatedStakeWeight How much delegated stake is weighted vs operator stake, in ppm. /// @param _rewardDelegatedStakeWeight How much delegated stake is weighted vs operator stake, in ppm.
@ -200,8 +156,6 @@ contract MixinParams is
/// @param _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. /// @param _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor.
/// @param _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. /// @param _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor.
/// @param _wethProxyAddress The address that can transfer WETH for fees. /// @param _wethProxyAddress The address that can transfer WETH for fees.
/// @param _ethVaultAddress Address of the EthVault contract.
/// @param _rewardVaultAddress Address of the StakingPoolRewardVault contract.
/// @param _zrxVaultAddress Address of the ZrxVault contract. /// @param _zrxVaultAddress Address of the ZrxVault contract.
function _setParams( function _setParams(
uint256 _epochDurationInSeconds, uint256 _epochDurationInSeconds,
@ -211,17 +165,10 @@ contract MixinParams is
uint32 _cobbDouglasAlphaNumerator, uint32 _cobbDouglasAlphaNumerator,
uint32 _cobbDouglasAlphaDenominator, uint32 _cobbDouglasAlphaDenominator,
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address payable _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
private private
{ {
_transferWETHAllownces(
[address(ethVault), address(rewardVault)],
[_ethVaultAddress, _rewardVaultAddress]
);
epochDurationInSeconds = _epochDurationInSeconds; epochDurationInSeconds = _epochDurationInSeconds;
rewardDelegatedStakeWeight = _rewardDelegatedStakeWeight; rewardDelegatedStakeWeight = _rewardDelegatedStakeWeight;
minimumPoolStake = _minimumPoolStake; minimumPoolStake = _minimumPoolStake;
@ -229,8 +176,6 @@ contract MixinParams is
cobbDouglasAlphaNumerator = _cobbDouglasAlphaNumerator; cobbDouglasAlphaNumerator = _cobbDouglasAlphaNumerator;
cobbDouglasAlphaDenominator = _cobbDouglasAlphaDenominator; cobbDouglasAlphaDenominator = _cobbDouglasAlphaDenominator;
wethAssetProxy = IAssetProxy(_wethProxyAddress); wethAssetProxy = IAssetProxy(_wethProxyAddress);
ethVault = IEthVault(_ethVaultAddress);
rewardVault = IStakingPoolRewardVault(_rewardVaultAddress);
zrxVault = IZrxVault(_zrxVaultAddress); zrxVault = IZrxVault(_zrxVaultAddress);
emit ParamsSet( emit ParamsSet(
@ -241,8 +186,6 @@ contract MixinParams is
_cobbDouglasAlphaNumerator, _cobbDouglasAlphaNumerator,
_cobbDouglasAlphaDenominator, _cobbDouglasAlphaDenominator,
_wethProxyAddress, _wethProxyAddress,
_ethVaultAddress,
_rewardVaultAddress,
_zrxVaultAddress _zrxVaultAddress
); );
} }

View File

@ -1,109 +0,0 @@
/*
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;
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "../interfaces/IEthVault.sol";
import "./MixinVaultCore.sol";
/// @dev This vault manages WETH.
contract EthVault is
IEthVault,
IVaultCore,
MixinVaultCore
{
using LibSafeMath for uint256;
// Address of the WETH contract.
IEtherToken public weth;
// mapping from Owner to WETH balance
mapping (address => uint256) internal _balances;
/// @param wethAddress Address of the WETH contract.
constructor(address wethAddress) public {
weth = IEtherToken(wethAddress);
}
/// @dev Deposit an `amount` of WETH for `owner` into the vault.
/// The staking contract should have granted the vault an allowance
/// because it will pull the WETH via `transferFrom()`.
/// Note that this is only callable by the staking contract.
/// @param owner Owner of the WETH.
/// @param amount Amount of deposit.
function depositFor(address owner, uint256 amount)
external
onlyStakingProxy
{
// Transfer WETH from the staking contract into this contract.
weth.transferFrom(msg.sender, address(this), amount);
// Credit the owner.
_balances[owner] = _balances[owner].safeAdd(amount);
emit EthDepositedIntoVault(msg.sender, owner, amount);
}
/// @dev Withdraw an `amount` of WETH to `msg.sender` from the vault.
/// @param amount of WETH to withdraw.
function withdraw(uint256 amount)
external
{
_withdrawFrom(msg.sender, amount);
}
/// @dev Withdraw ALL WETH to `msg.sender` from the vault.
function withdrawAll()
external
returns (uint256 totalBalance)
{
// get total balance
address payable owner = msg.sender;
totalBalance = _balances[owner];
// withdraw WETH to owner
_withdrawFrom(owner, totalBalance);
return totalBalance;
}
/// @dev Returns the balance in WETH of the `owner`
/// @return Balance in WETH.
function balanceOf(address owner)
external
view
returns (uint256)
{
return _balances[owner];
}
/// @dev Withdraw an `amount` of WETH to `owner` from the vault.
/// @param owner of WETH.
/// @param amount of WETH to withdraw.
function _withdrawFrom(address payable owner, uint256 amount)
internal
{
//Uupdate balance.
_balances[owner] = _balances[owner].safeSub(amount);
// withdraw WETH to owner
weth.transfer(msg.sender, amount);
// notify
emit EthWithdrawnFromVault(msg.sender, owner, amount);
}
}

View File

@ -1,97 +0,0 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "../libs/LibStakingRichErrors.sol";
import "../libs/LibSafeDowncast.sol";
import "../interfaces/IStakingPoolRewardVault.sol";
import "./MixinVaultCore.sol";
/// @dev This vault manages staking pool rewards.
contract StakingPoolRewardVault is
IStakingPoolRewardVault,
IVaultCore,
MixinVaultCore
{
using LibSafeMath for uint256;
// Address of the WETH contract.
IEtherToken public weth;
// mapping from poolId to Pool metadata
mapping (bytes32 => uint256) internal _balanceByPoolId;
/// @param wethAddress Address of the WETH contract.
constructor(address wethAddress) public {
weth = IEtherToken(wethAddress);
}
/// @dev Deposit an amount of WETH for `poolId` into the vault.
/// The staking contract should have granted the vault an allowance
/// because it will pull the WETH via `transferFrom()`.
/// Note that this is only callable by the staking contract.
/// @param poolId Pool that holds the WETH.
/// @param amount Amount of deposit.
function depositFor(bytes32 poolId, uint256 amount)
external
onlyStakingProxy
{
// Transfer WETH from the staking contract into this contract.
weth.transferFrom(msg.sender, address(this), amount);
// Credit the pool.
_balanceByPoolId[poolId] = _balanceByPoolId[poolId].safeAdd(amount);
emit EthDepositedIntoVault(msg.sender, poolId, amount);
}
/// @dev Withdraw some amount in WETH from a pool.
/// Note that this is only callable by the staking contract.
/// @param poolId Unique Id of pool.
/// @param to Address to send funds to.
/// @param amount Amount of WETH to transfer.
function transfer(
bytes32 poolId,
address payable to,
uint256 amount
)
external
onlyStakingProxy
{
_balanceByPoolId[poolId] = _balanceByPoolId[poolId].safeSub(amount);
weth.transfer(to, amount);
emit PoolRewardTransferred(
poolId,
to,
amount
);
}
/// @dev Returns the balance in WETH of `poolId`
/// @return Balance in WETH.
function balanceOf(bytes32 poolId)
external
view
returns (uint256 balance)
{
return _balanceByPoolId[poolId];
}
}

View File

@ -33,16 +33,12 @@ contract TestAssertStorageParams is
uint32 cobbDouglasAlphaNumerator; uint32 cobbDouglasAlphaNumerator;
uint32 cobbDouglasAlphaDenominator; uint32 cobbDouglasAlphaDenominator;
address wethProxyAddress; address wethProxyAddress;
address ethVaultAddress;
address rewardVaultAddress;
address zrxVaultAddress; address zrxVaultAddress;
} }
constructor() constructor()
public public
StakingProxy( StakingProxy(
NIL_ADDRESS,
NIL_ADDRESS,
NIL_ADDRESS, NIL_ADDRESS,
NIL_ADDRESS, NIL_ADDRESS,
NIL_ADDRESS, NIL_ADDRESS,
@ -60,13 +56,11 @@ contract TestAssertStorageParams is
cobbDouglasAlphaNumerator = params.cobbDouglasAlphaNumerator; cobbDouglasAlphaNumerator = params.cobbDouglasAlphaNumerator;
cobbDouglasAlphaDenominator = params.cobbDouglasAlphaDenominator; cobbDouglasAlphaDenominator = params.cobbDouglasAlphaDenominator;
wethAssetProxy = IAssetProxy(params.wethProxyAddress); wethAssetProxy = IAssetProxy(params.wethProxyAddress);
ethVault = IEthVault(params.ethVaultAddress);
rewardVault = IStakingPoolRewardVault(params.rewardVaultAddress);
zrxVault = IZrxVault(params.zrxVaultAddress); zrxVault = IZrxVault(params.zrxVaultAddress);
_assertValidStorageParams(); _assertValidStorageParams();
} }
function _attachStakingContract(address, address, address, address, address) function _attachStakingContract(address, address, address)
internal internal
{} {}
} }

View File

@ -42,7 +42,7 @@ contract TestCumulativeRewardTracking is
constructor(address wethAddress) public TestStaking(wethAddress) {} constructor(address wethAddress) public TestStaking(wethAddress) {}
function init(address, address, address payable, address) public {} function init(address, address) public {}
function _forceSetCumulativeReward( function _forceSetCumulativeReward(
bytes32 poolId, bytes32 poolId,

View File

@ -20,24 +20,12 @@ pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import "../src/interfaces/IStructs.sol"; import "../src/interfaces/IStructs.sol";
import "../src/interfaces/IStakingPoolRewardVault.sol";
import "../src/interfaces/IEthVault.sol";
import "./TestStakingNoWETH.sol"; import "./TestStakingNoWETH.sol";
contract TestDelegatorRewards is contract TestDelegatorRewards is
TestStakingNoWETH TestStakingNoWETH
{ {
event RecordDepositToEthVault(
address owner,
uint256 amount
);
event RecordDepositToRewardVault(
bytes32 poolId,
uint256 membersReward
);
event FinalizePool( event FinalizePool(
bytes32 poolId, bytes32 poolId,
uint256 operatorReward, uint256 operatorReward,
@ -51,17 +39,13 @@ contract TestDelegatorRewards is
uint256 membersStake; uint256 membersStake;
} }
constructor() public { constructor()
public
{
init( init(
address(1),
address(1),
address(1), address(1),
address(1) address(1)
); );
// Set this contract up as the eth and reward vault to intercept
// deposits.
ethVault = IEthVault(address(this));
rewardVault = IStakingPoolRewardVault(address(this));
} }
mapping (uint256 => mapping (bytes32 => UnfinalizedPoolReward)) private mapping (uint256 => mapping (bytes32 => UnfinalizedPoolReward)) private
@ -93,8 +77,8 @@ contract TestDelegatorRewards is
_initGenesisCumulativeRewards(poolId); _initGenesisCumulativeRewards(poolId);
} }
/// @dev Expose/wrap `_depositStakingPoolRewards`. /// @dev Expose/wrap `_syncPoolRewards`.
function depositStakingPoolRewards( function syncPoolRewards(
bytes32 poolId, bytes32 poolId,
address payable operatorAddress, address payable operatorAddress,
uint256 operatorReward, uint256 operatorReward,
@ -108,7 +92,7 @@ contract TestDelegatorRewards is
_setOperatorShare(poolId, operatorReward, membersReward); _setOperatorShare(poolId, operatorReward, membersReward);
_initGenesisCumulativeRewards(poolId); _initGenesisCumulativeRewards(poolId);
_depositStakingPoolRewards( _syncPoolRewards(
poolId, poolId,
operatorReward + membersReward, operatorReward + membersReward,
membersStake membersStake
@ -122,7 +106,7 @@ contract TestDelegatorRewards is
/// @dev Create and delegate stake that is active in the current epoch. /// @dev Create and delegate stake that is active in the current epoch.
/// Only used to test purportedly unreachable states. /// Only used to test purportedly unreachable states.
/// Also withdraws pending rewards to the eth vault. /// Also withdraws pending rewards.
function delegateStakeNow( function delegateStakeNow(
address delegator, address delegator,
bytes32 poolId, bytes32 poolId,
@ -137,7 +121,7 @@ contract TestDelegatorRewards is
_stake.currentEpochBalance += uint96(stake); _stake.currentEpochBalance += uint96(stake);
_stake.nextEpochBalance += uint96(stake); _stake.nextEpochBalance += uint96(stake);
_stake.currentEpoch = uint32(currentEpoch); _stake.currentEpoch = uint32(currentEpoch);
_syncRewardsForDelegator( _withdrawAndSyncDelegatorRewards(
poolId, poolId,
delegator, delegator,
initialStake, initialStake,
@ -147,7 +131,7 @@ contract TestDelegatorRewards is
/// @dev Create and delegate stake that will occur in the next epoch /// @dev Create and delegate stake that will occur in the next epoch
/// (normal behavior). /// (normal behavior).
/// Also withdraws pending rewards to the eth vault. /// Also withdraws pending rewards.
function delegateStake( function delegateStake(
address delegator, address delegator,
bytes32 poolId, bytes32 poolId,
@ -164,7 +148,7 @@ contract TestDelegatorRewards is
_stake.isInitialized = true; _stake.isInitialized = true;
_stake.nextEpochBalance += uint96(stake); _stake.nextEpochBalance += uint96(stake);
_stake.currentEpoch = uint32(currentEpoch); _stake.currentEpoch = uint32(currentEpoch);
_syncRewardsForDelegator( _withdrawAndSyncDelegatorRewards(
poolId, poolId,
delegator, delegator,
initialStake, initialStake,
@ -174,7 +158,7 @@ contract TestDelegatorRewards is
/// @dev Clear stake that will occur in the next epoch /// @dev Clear stake that will occur in the next epoch
/// (normal behavior). /// (normal behavior).
/// Also withdraws pending rewards to the eth vault. /// Also withdraws pending rewards.
function undelegateStake( function undelegateStake(
address delegator, address delegator,
bytes32 poolId, bytes32 poolId,
@ -191,7 +175,7 @@ contract TestDelegatorRewards is
_stake.isInitialized = true; _stake.isInitialized = true;
_stake.nextEpochBalance -= uint96(stake); _stake.nextEpochBalance -= uint96(stake);
_stake.currentEpoch = uint32(currentEpoch); _stake.currentEpoch = uint32(currentEpoch);
_syncRewardsForDelegator( _withdrawAndSyncDelegatorRewards(
poolId, poolId,
delegator, delegator,
initialStake, initialStake,
@ -199,33 +183,6 @@ contract TestDelegatorRewards is
); );
} }
/// @dev `IEthVault.depositFor()`,` overridden to just emit events.
function depositFor(
address owner,
uint256 amount
)
external
{
emit RecordDepositToEthVault(
owner,
amount
);
}
/// @dev `IStakingPoolRewardVault.depositFor()`,`
/// overridden to just emit events.
function depositFor(
bytes32 poolId,
uint256 membersReward
)
external
{
emit RecordDepositToRewardVault(
poolId,
membersReward
);
}
// solhint-disable no-simple-event-func-name // solhint-disable no-simple-event-func-name
/// @dev Overridden to realize `unfinalizedPoolRewardsByEpoch` in /// @dev Overridden to realize `unfinalizedPoolRewardsByEpoch` in
/// the current epoch and emit a event, /// the current epoch and emit a event,
@ -245,7 +202,7 @@ contract TestDelegatorRewards is
uint256 totalRewards = reward.operatorReward + reward.membersReward; uint256 totalRewards = reward.operatorReward + reward.membersReward;
membersStake = reward.membersStake; membersStake = reward.membersStake;
(operatorReward, membersReward) = (operatorReward, membersReward) =
_depositStakingPoolRewards(poolId, totalRewards, membersStake); _syncPoolRewards(poolId, totalRewards, membersStake);
emit FinalizePool(poolId, operatorReward, membersReward, membersStake); emit FinalizePool(poolId, operatorReward, membersReward, membersStake);
} }

View File

@ -57,8 +57,6 @@ contract TestFinalizer is
public public
{ {
init( init(
address(1),
address(1),
address(1), address(1),
address(1) address(1)
); );
@ -144,7 +142,7 @@ contract TestFinalizer is
} }
/// @dev Overridden to log and transfer to receivers. /// @dev Overridden to log and transfer to receivers.
function _depositStakingPoolRewards( function _syncPoolRewards(
bytes32 poolId, bytes32 poolId,
uint256 reward, uint256 reward,
uint256 membersStake uint256 membersStake
@ -153,7 +151,7 @@ contract TestFinalizer is
returns (uint256 operatorReward, uint256 membersReward) returns (uint256 operatorReward, uint256 membersReward)
{ {
uint32 operatorShare = _operatorSharesByPool[poolId]; uint32 operatorShare = _operatorSharesByPool[poolId];
(operatorReward, membersReward) = _computeSplitStakingPoolRewards( (operatorReward, membersReward) = _computePoolRewardsSplit(
operatorShare, operatorShare,
reward, reward,
membersStake membersStake

View File

@ -37,15 +37,11 @@ contract TestInitTarget is
event InitAddresses( event InitAddresses(
address wethProxyAddress, address wethProxyAddress,
address ethVaultAddress,
address rewardVaultAddress,
address zrxVaultAddress address zrxVaultAddress
); );
function init( function init(
address wethProxyAddress, address wethProxyAddress,
address ethVaultAddress,
address rewardVaultAddress,
address zrxVaultAddress address zrxVaultAddress
) )
external external
@ -58,8 +54,6 @@ contract TestInitTarget is
_initThisAddress = address(this); _initThisAddress = address(this);
emit InitAddresses( emit InitAddresses(
wethProxyAddress, wethProxyAddress,
ethVaultAddress,
rewardVaultAddress,
zrxVaultAddress zrxVaultAddress
); );
} }

View File

@ -1,54 +0,0 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "../src/interfaces/IEthVault.sol";
import "../src/interfaces/IStakingPoolRewardVault.sol";
import "../src/sys/MixinParams.sol";
// solhint-disable no-empty-blocks
contract TestMixinParams is
MixinParams
{
event WETHApprove(address spender, uint256 amount);
/// @dev Sets the eth and reward vault addresses.
function setVaultAddresses(
address ethVaultAddress,
address rewardVaultAddress
)
external
{
ethVault = IEthVault(ethVaultAddress);
rewardVault = IStakingPoolRewardVault(rewardVaultAddress);
}
/// @dev WETH `approve()` function that just logs events.
function approve(address spender, uint256 amount) external returns (bool) {
emit WETHApprove(spender, amount);
}
/// @dev Overridden return this contract's address.
function _getWETHAddress() internal view returns (address) {
return address(this);
}
}

View File

@ -48,8 +48,6 @@ contract TestProtocolFees is
// Use this contract as the ERC20Proxy. // Use this contract as the ERC20Proxy.
address(this), address(this),
// vault addresses must be non-zero // vault addresses must be non-zero
address(1),
address(1),
address(1) address(1)
); );
validExchanges[exchangeAddress] = true; validExchanges[exchangeAddress] = true;
@ -98,8 +96,8 @@ contract TestProtocolFees is
emit ERC20ProxyTransferFrom(assetData, from, to, amount); emit ERC20ProxyTransferFrom(assetData, from, to, amount);
} }
function getWethAssetData() external pure returns (bytes memory) { function getWethAssetData() external view returns (bytes memory) {
return WETH_ASSET_DATA; return _getWethAssetData();
} }
/// @dev Overridden to use test pools. /// @dev Overridden to use test pools.

View File

@ -20,6 +20,7 @@ pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
import "../src/Staking.sol"; import "../src/Staking.sol";
import "@0x/contracts-erc20/contracts/src/interfaces/IEtherToken.sol";
contract TestStaking is contract TestStaking is
@ -32,10 +33,27 @@ contract TestStaking is
} }
/// @dev Overridden to use testWethAddress; /// @dev Overridden to use testWethAddress;
function _getWETHAddress() internal view returns (address) { function _getWethContract()
internal
view
returns (IEtherToken)
{
// `testWethAddress` will not be set on the proxy this contract is // `testWethAddress` will not be set on the proxy this contract is
// attached to, so we need to access the storage of the deployed // attached to, so we need to access the storage of the deployed
// instance of this contract. // instance of this contract.
return TestStaking(address(uint160(stakingContract))).testWethAddress(); address wethAddress = TestStaking(address(uint160(stakingContract))).testWethAddress();
return IEtherToken(wethAddress);
}
function _getWethAssetData()
internal
view
returns (bytes memory)
{
address wethAddress = TestStaking(address(uint160(stakingContract))).testWethAddress();
return abi.encodeWithSelector(
IAssetData(address(0)).ERC20Token.selector,
wethAddress
);
} }
} }

View File

@ -28,17 +28,37 @@ import "../src/Staking.sol";
contract TestStakingNoWETH is contract TestStakingNoWETH is
Staking Staking
{ {
function _transferWETHAllownces( event Transfer(
address[2] memory oldSpenders, address indexed _from,
address[2] memory newSpenders address indexed _to,
) uint256 _value
);
function transfer(address to, uint256 amount)
external
returns (bool)
{
emit Transfer(address(this), to, amount);
return true;
}
function _wrapEth()
internal internal
{} {}
function _wrapBalanceToWETHAndGetBalance() function _getAvailableWethBalance()
internal internal
returns (uint256 balance) view
returns (uint256)
{ {
return address(this).balance; return address(this).balance;
} }
function _getWethContract()
internal
view
returns (IEtherToken)
{
return IEtherToken(address(this));
}
} }

View File

@ -33,23 +33,17 @@ contract TestStakingProxy is
_stakingContract, _stakingContract,
NIL_ADDRESS, NIL_ADDRESS,
NIL_ADDRESS, NIL_ADDRESS,
NIL_ADDRESS,
NIL_ADDRESS,
NIL_ADDRESS NIL_ADDRESS
) )
{} {}
function setAddressParams( function setAddressParams(
address _wethProxyAddress, address _wethProxyAddress,
address _ethVaultAddress,
address payable _rewardVaultAddress,
address _zrxVaultAddress address _zrxVaultAddress
) )
external external
{ {
wethAssetProxy = IAssetProxy(_wethProxyAddress); wethAssetProxy = IAssetProxy(_wethProxyAddress);
ethVault = IEthVault(_ethVaultAddress);
rewardVault = IStakingPoolRewardVault(_rewardVaultAddress);
zrxVault = IZrxVault(_zrxVaultAddress); zrxVault = IZrxVault(_zrxVaultAddress);
} }

View File

@ -1,141 +0,0 @@
/*
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.5;
import "../src/immutable/MixinStorage.sol";
import "../src/interfaces/IStructs.sol";
contract TestStorageLayout is
Ownable,
MixinStorage
{
function assertExpectedStorageLayout()
public
pure
{
assembly {
function revertIncorrectStorageSlot() {
// Revert with `Error("INCORRECT_STORAGE_SLOT")`
mstore(0, 0x504fe8ef00000000000000000000000000000000000000000000000000000000)
mstore(32, 0x0000002000000000000000000000000000000000000000000000000000000000)
mstore(64, 0x00000016494e434f52524543545f53544f524147455f534c4f54000000000000)
mstore(96, 0)
}
// The staking contract writes to state that's stored in the staking proxy contract; hence,
// we require that slots do not change across upgrades to the staking contract. We expect
// storage slots to match the ordering in MixinStorage.sol.
let slot := 0
if sub(owner_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(stakingContract_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_activeStakeByOwner_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_inactiveStakeByOwner_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_delegatedStakeByOwner_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_delegatedStakeToPoolByOwner_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_delegatedStakeByPoolId_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_withdrawableStakeByOwner_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(nextPoolId_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(poolJoinedByMakerAddress_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_poolById_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(currentEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(currentEpochStartTimeInSeconds_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_cumulativeRewardsByPool_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_cumulativeRewardsByPoolReferenceCounter_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_cumulativeRewardsByPoolLastStored_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(validExchanges_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(zrxVault_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(rewardVault_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(epochDurationInSeconds_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(rewardDelegatedStakeWeight_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(minimumPoolStake_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(maximumMakersInPool_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(cobbDouglasAlphaNumerator_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(cobbDouglasAlphaDenominator_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(totalFeesCollectedThisEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(totalWeightedStakeThisEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(_activePoolsByEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(numActivePoolsThisEpoch_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
if sub(unfinalizedState_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
}
}
}

View File

@ -37,7 +37,7 @@
}, },
"config": { "config": {
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.", "abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually.",
"abis": "./generated-artifacts/@(EthVault|IEthVault|IStaking|IStakingEvents|IStakingPoolRewardVault|IStakingProxy|IStorage|IStorageInit|IStructs|IVaultCore|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibProxy|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolMakers|MixinStakingPoolModifiers|MixinStakingPoolRewards|MixinStorage|MixinVaultCore|ReadOnlyProxy|Staking|StakingPoolRewardVault|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibProxy|TestLibProxyReceiver|TestLibSafeDowncast|TestMixinParams|TestMixinVaultCore|TestProtocolFees|TestStaking|TestStakingNoWETH|TestStakingProxy|TestStorageLayout|ZrxVault).json" "abis": "./generated-artifacts/@(IStaking|IStakingEvents|IStakingProxy|IStorage|IStorageInit|IStructs|IVaultCore|IZrxVault|LibCobbDouglas|LibFixedMath|LibFixedMathRichErrors|LibProxy|LibSafeDowncast|LibStakingRichErrors|MixinAbstract|MixinConstants|MixinCumulativeRewards|MixinDeploymentConstants|MixinExchangeFees|MixinExchangeManager|MixinFinalizer|MixinParams|MixinScheduler|MixinStake|MixinStakeBalances|MixinStakeStorage|MixinStakingPool|MixinStakingPoolMakers|MixinStakingPoolModifiers|MixinStakingPoolRewards|MixinStorage|MixinVaultCore|ReadOnlyProxy|Staking|StakingProxy|TestAssertStorageParams|TestCobbDouglas|TestCumulativeRewardTracking|TestDelegatorRewards|TestFinalizer|TestInitTarget|TestLibFixedMath|TestLibProxy|TestLibProxyReceiver|TestLibSafeDowncast|TestMixinVaultCore|TestProtocolFees|TestStaking|TestStakingNoWETH|TestStakingProxy|ZrxVault).json"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -5,11 +5,8 @@
*/ */
import { ContractArtifact } from 'ethereum-types'; import { ContractArtifact } from 'ethereum-types';
import * as EthVault from '../generated-artifacts/EthVault.json';
import * as IEthVault from '../generated-artifacts/IEthVault.json';
import * as IStaking from '../generated-artifacts/IStaking.json'; import * as IStaking from '../generated-artifacts/IStaking.json';
import * as IStakingEvents from '../generated-artifacts/IStakingEvents.json'; import * as IStakingEvents from '../generated-artifacts/IStakingEvents.json';
import * as IStakingPoolRewardVault from '../generated-artifacts/IStakingPoolRewardVault.json';
import * as IStakingProxy from '../generated-artifacts/IStakingProxy.json'; import * as IStakingProxy from '../generated-artifacts/IStakingProxy.json';
import * as IStorage from '../generated-artifacts/IStorage.json'; import * as IStorage from '../generated-artifacts/IStorage.json';
import * as IStorageInit from '../generated-artifacts/IStorageInit.json'; import * as IStorageInit from '../generated-artifacts/IStorageInit.json';
@ -42,7 +39,6 @@ import * as MixinStorage from '../generated-artifacts/MixinStorage.json';
import * as MixinVaultCore from '../generated-artifacts/MixinVaultCore.json'; import * as MixinVaultCore from '../generated-artifacts/MixinVaultCore.json';
import * as ReadOnlyProxy from '../generated-artifacts/ReadOnlyProxy.json'; import * as ReadOnlyProxy from '../generated-artifacts/ReadOnlyProxy.json';
import * as Staking from '../generated-artifacts/Staking.json'; import * as Staking from '../generated-artifacts/Staking.json';
import * as StakingPoolRewardVault from '../generated-artifacts/StakingPoolRewardVault.json';
import * as StakingProxy from '../generated-artifacts/StakingProxy.json'; import * as StakingProxy from '../generated-artifacts/StakingProxy.json';
import * as TestAssertStorageParams from '../generated-artifacts/TestAssertStorageParams.json'; import * as TestAssertStorageParams from '../generated-artifacts/TestAssertStorageParams.json';
import * as TestCobbDouglas from '../generated-artifacts/TestCobbDouglas.json'; import * as TestCobbDouglas from '../generated-artifacts/TestCobbDouglas.json';
@ -54,13 +50,11 @@ import * as TestLibFixedMath from '../generated-artifacts/TestLibFixedMath.json'
import * as TestLibProxy from '../generated-artifacts/TestLibProxy.json'; import * as TestLibProxy from '../generated-artifacts/TestLibProxy.json';
import * as TestLibProxyReceiver from '../generated-artifacts/TestLibProxyReceiver.json'; import * as TestLibProxyReceiver from '../generated-artifacts/TestLibProxyReceiver.json';
import * as TestLibSafeDowncast from '../generated-artifacts/TestLibSafeDowncast.json'; import * as TestLibSafeDowncast from '../generated-artifacts/TestLibSafeDowncast.json';
import * as TestMixinParams from '../generated-artifacts/TestMixinParams.json';
import * as TestMixinVaultCore from '../generated-artifacts/TestMixinVaultCore.json'; import * as TestMixinVaultCore from '../generated-artifacts/TestMixinVaultCore.json';
import * as TestProtocolFees from '../generated-artifacts/TestProtocolFees.json'; import * as TestProtocolFees from '../generated-artifacts/TestProtocolFees.json';
import * as TestStaking from '../generated-artifacts/TestStaking.json'; import * as TestStaking from '../generated-artifacts/TestStaking.json';
import * as TestStakingNoWETH from '../generated-artifacts/TestStakingNoWETH.json'; import * as TestStakingNoWETH from '../generated-artifacts/TestStakingNoWETH.json';
import * as TestStakingProxy from '../generated-artifacts/TestStakingProxy.json'; import * as TestStakingProxy from '../generated-artifacts/TestStakingProxy.json';
import * as TestStorageLayout from '../generated-artifacts/TestStorageLayout.json';
import * as ZrxVault from '../generated-artifacts/ZrxVault.json'; import * as ZrxVault from '../generated-artifacts/ZrxVault.json';
export const artifacts = { export const artifacts = {
ReadOnlyProxy: ReadOnlyProxy as ContractArtifact, ReadOnlyProxy: ReadOnlyProxy as ContractArtifact,
@ -71,10 +65,8 @@ export const artifacts = {
MixinConstants: MixinConstants as ContractArtifact, MixinConstants: MixinConstants as ContractArtifact,
MixinDeploymentConstants: MixinDeploymentConstants as ContractArtifact, MixinDeploymentConstants: MixinDeploymentConstants as ContractArtifact,
MixinStorage: MixinStorage as ContractArtifact, MixinStorage: MixinStorage as ContractArtifact,
IEthVault: IEthVault as ContractArtifact,
IStaking: IStaking as ContractArtifact, IStaking: IStaking as ContractArtifact,
IStakingEvents: IStakingEvents as ContractArtifact, IStakingEvents: IStakingEvents as ContractArtifact,
IStakingPoolRewardVault: IStakingPoolRewardVault as ContractArtifact,
IStakingProxy: IStakingProxy as ContractArtifact, IStakingProxy: IStakingProxy as ContractArtifact,
IStorage: IStorage as ContractArtifact, IStorage: IStorage as ContractArtifact,
IStorageInit: IStorageInit as ContractArtifact, IStorageInit: IStorageInit as ContractArtifact,
@ -99,9 +91,7 @@ export const artifacts = {
MixinFinalizer: MixinFinalizer as ContractArtifact, MixinFinalizer: MixinFinalizer as ContractArtifact,
MixinParams: MixinParams as ContractArtifact, MixinParams: MixinParams as ContractArtifact,
MixinScheduler: MixinScheduler as ContractArtifact, MixinScheduler: MixinScheduler as ContractArtifact,
EthVault: EthVault as ContractArtifact,
MixinVaultCore: MixinVaultCore as ContractArtifact, MixinVaultCore: MixinVaultCore as ContractArtifact,
StakingPoolRewardVault: StakingPoolRewardVault as ContractArtifact,
ZrxVault: ZrxVault as ContractArtifact, ZrxVault: ZrxVault as ContractArtifact,
TestAssertStorageParams: TestAssertStorageParams as ContractArtifact, TestAssertStorageParams: TestAssertStorageParams as ContractArtifact,
TestCobbDouglas: TestCobbDouglas as ContractArtifact, TestCobbDouglas: TestCobbDouglas as ContractArtifact,
@ -113,11 +103,9 @@ export const artifacts = {
TestLibProxy: TestLibProxy as ContractArtifact, TestLibProxy: TestLibProxy as ContractArtifact,
TestLibProxyReceiver: TestLibProxyReceiver as ContractArtifact, TestLibProxyReceiver: TestLibProxyReceiver as ContractArtifact,
TestLibSafeDowncast: TestLibSafeDowncast as ContractArtifact, TestLibSafeDowncast: TestLibSafeDowncast as ContractArtifact,
TestMixinParams: TestMixinParams as ContractArtifact,
TestMixinVaultCore: TestMixinVaultCore as ContractArtifact, TestMixinVaultCore: TestMixinVaultCore as ContractArtifact,
TestProtocolFees: TestProtocolFees as ContractArtifact, TestProtocolFees: TestProtocolFees as ContractArtifact,
TestStaking: TestStaking as ContractArtifact, TestStaking: TestStaking as ContractArtifact,
TestStakingNoWETH: TestStakingNoWETH as ContractArtifact, TestStakingNoWETH: TestStakingNoWETH as ContractArtifact,
TestStakingProxy: TestStakingProxy as ContractArtifact, TestStakingProxy: TestStakingProxy as ContractArtifact,
TestStorageLayout: TestStorageLayout as ContractArtifact,
}; };

View File

@ -3,11 +3,8 @@
* Warning: This file is auto-generated by contracts-gen. Don't edit manually. * Warning: This file is auto-generated by contracts-gen. Don't edit manually.
* ----------------------------------------------------------------------------- * -----------------------------------------------------------------------------
*/ */
export * from '../generated-wrappers/eth_vault';
export * from '../generated-wrappers/i_eth_vault';
export * from '../generated-wrappers/i_staking'; export * from '../generated-wrappers/i_staking';
export * from '../generated-wrappers/i_staking_events'; export * from '../generated-wrappers/i_staking_events';
export * from '../generated-wrappers/i_staking_pool_reward_vault';
export * from '../generated-wrappers/i_staking_proxy'; export * from '../generated-wrappers/i_staking_proxy';
export * from '../generated-wrappers/i_storage'; export * from '../generated-wrappers/i_storage';
export * from '../generated-wrappers/i_storage_init'; export * from '../generated-wrappers/i_storage_init';
@ -40,7 +37,6 @@ export * from '../generated-wrappers/mixin_storage';
export * from '../generated-wrappers/mixin_vault_core'; export * from '../generated-wrappers/mixin_vault_core';
export * from '../generated-wrappers/read_only_proxy'; export * from '../generated-wrappers/read_only_proxy';
export * from '../generated-wrappers/staking'; export * from '../generated-wrappers/staking';
export * from '../generated-wrappers/staking_pool_reward_vault';
export * from '../generated-wrappers/staking_proxy'; export * from '../generated-wrappers/staking_proxy';
export * from '../generated-wrappers/test_assert_storage_params'; export * from '../generated-wrappers/test_assert_storage_params';
export * from '../generated-wrappers/test_cobb_douglas'; export * from '../generated-wrappers/test_cobb_douglas';
@ -52,11 +48,9 @@ export * from '../generated-wrappers/test_lib_fixed_math';
export * from '../generated-wrappers/test_lib_proxy'; export * from '../generated-wrappers/test_lib_proxy';
export * from '../generated-wrappers/test_lib_proxy_receiver'; export * from '../generated-wrappers/test_lib_proxy_receiver';
export * from '../generated-wrappers/test_lib_safe_downcast'; export * from '../generated-wrappers/test_lib_safe_downcast';
export * from '../generated-wrappers/test_mixin_params';
export * from '../generated-wrappers/test_mixin_vault_core'; export * from '../generated-wrappers/test_mixin_vault_core';
export * from '../generated-wrappers/test_protocol_fees'; export * from '../generated-wrappers/test_protocol_fees';
export * from '../generated-wrappers/test_staking'; export * from '../generated-wrappers/test_staking';
export * from '../generated-wrappers/test_staking_no_w_e_t_h'; export * from '../generated-wrappers/test_staking_no_w_e_t_h';
export * from '../generated-wrappers/test_staking_proxy'; export * from '../generated-wrappers/test_staking_proxy';
export * from '../generated-wrappers/test_storage_layout';
export * from '../generated-wrappers/zrx_vault'; export * from '../generated-wrappers/zrx_vault';

View File

@ -10,8 +10,8 @@ import {
OperatorBalanceByPoolId, OperatorBalanceByPoolId,
OperatorByPoolId, OperatorByPoolId,
OperatorShareByPoolId, OperatorShareByPoolId,
RewardBalanceByPoolId,
RewardByPoolId, RewardByPoolId,
RewardVaultBalanceByPoolId,
} from '../utils/types'; } from '../utils/types';
import { BaseActor } from './base_actor'; import { BaseActor } from './base_actor';
@ -40,7 +40,7 @@ export class FinalizerActor extends BaseActor {
public async finalizeAsync(): Promise<void> { public async finalizeAsync(): Promise<void> {
// cache initial info and balances // cache initial info and balances
const operatorShareByPoolId = await this._getOperatorShareByPoolIdAsync(this._poolIds); const operatorShareByPoolId = await this._getOperatorShareByPoolIdAsync(this._poolIds);
const rewardVaultBalanceByPoolId = await this._getRewardVaultBalanceByPoolIdAsync(this._poolIds); const rewardBalanceByPoolId = await this._getRewardBalanceByPoolIdAsync(this._poolIds);
const delegatorBalancesByPoolId = await this._getDelegatorBalancesByPoolIdAsync(this._delegatorsByPoolId); const delegatorBalancesByPoolId = await this._getDelegatorBalancesByPoolIdAsync(this._delegatorsByPoolId);
const delegatorStakesByPoolId = await this._getDelegatorStakesByPoolIdAsync(this._delegatorsByPoolId); const delegatorStakesByPoolId = await this._getDelegatorStakesByPoolIdAsync(this._delegatorsByPoolId);
const operatorBalanceByPoolId = await this._getOperatorBalanceByPoolIdAsync(this._operatorByPoolId); const operatorBalanceByPoolId = await this._getOperatorBalanceByPoolIdAsync(this._operatorByPoolId);
@ -48,11 +48,11 @@ export class FinalizerActor extends BaseActor {
// compute expected changes // compute expected changes
const [ const [
expectedOperatorBalanceByPoolId, expectedOperatorBalanceByPoolId,
expectedRewardVaultBalanceByPoolId, expectedRewardBalanceByPoolId,
] = await this._computeExpectedRewardVaultBalanceAsyncByPoolIdAsync( ] = this._computeExpectedRewardBalanceByPoolId(
rewardByPoolId, rewardByPoolId,
operatorBalanceByPoolId, operatorBalanceByPoolId,
rewardVaultBalanceByPoolId, rewardBalanceByPoolId,
delegatorStakesByPoolId, delegatorStakesByPoolId,
operatorShareByPoolId, operatorShareByPoolId,
); );
@ -65,19 +65,19 @@ export class FinalizerActor extends BaseActor {
); );
// finalize // finalize
await this._stakingApiWrapper.utils.skipToNextEpochAndFinalizeAsync(); await this._stakingApiWrapper.utils.skipToNextEpochAndFinalizeAsync();
// assert reward vault changes // assert reward changes
const finalRewardVaultBalanceByPoolId = await this._getRewardVaultBalanceByPoolIdAsync(this._poolIds); const finalRewardBalanceByPoolId = await this._getRewardBalanceByPoolIdAsync(this._poolIds);
expect(finalRewardVaultBalanceByPoolId, 'final pool balances in reward vault').to.be.deep.equal( expect(finalRewardBalanceByPoolId, 'final pool reward balances').to.be.deep.equal(
expectedRewardVaultBalanceByPoolId, expectedRewardBalanceByPoolId,
); );
// assert delegator balances // assert delegator balances
const finalDelegatorBalancesByPoolId = await this._getDelegatorBalancesByPoolIdAsync(this._delegatorsByPoolId); const finalDelegatorBalancesByPoolId = await this._getDelegatorBalancesByPoolIdAsync(this._delegatorsByPoolId);
expect(finalDelegatorBalancesByPoolId, 'final delegator balances in reward vault').to.be.deep.equal( expect(finalDelegatorBalancesByPoolId, 'final delegator reward balances').to.be.deep.equal(
expectedDelegatorBalancesByPoolId, expectedDelegatorBalancesByPoolId,
); );
// assert operator balances // assert operator balances
const finalOperatorBalanceByPoolId = await this._getOperatorBalanceByPoolIdAsync(this._operatorByPoolId); const finalOperatorBalanceByPoolId = await this._getOperatorBalanceByPoolIdAsync(this._operatorByPoolId);
expect(finalOperatorBalanceByPoolId, 'final operator balances in eth vault').to.be.deep.equal( expect(finalOperatorBalanceByPoolId, 'final operator weth balance').to.be.deep.equal(
expectedOperatorBalanceByPoolId, expectedOperatorBalanceByPoolId,
); );
} }
@ -159,40 +159,40 @@ export class FinalizerActor extends BaseActor {
return delegatorBalancesByPoolId; return delegatorBalancesByPoolId;
} }
private async _computeExpectedRewardVaultBalanceAsyncByPoolIdAsync( private _computeExpectedRewardBalanceByPoolId(
rewardByPoolId: RewardByPoolId, rewardByPoolId: RewardByPoolId,
operatorBalanceByPoolId: OperatorBalanceByPoolId, operatorBalanceByPoolId: OperatorBalanceByPoolId,
rewardVaultBalanceByPoolId: RewardVaultBalanceByPoolId, rewardBalanceByPoolId: RewardBalanceByPoolId,
delegatorStakesByPoolId: DelegatorBalancesByPoolId, delegatorStakesByPoolId: DelegatorBalancesByPoolId,
operatorShareByPoolId: OperatorShareByPoolId, operatorShareByPoolId: OperatorShareByPoolId,
): Promise<[RewardVaultBalanceByPoolId, OperatorBalanceByPoolId]> { ): [RewardBalanceByPoolId, OperatorBalanceByPoolId] {
const expectedOperatorBalanceByPoolId = _.cloneDeep(operatorBalanceByPoolId); const expectedOperatorBalanceByPoolId = _.cloneDeep(operatorBalanceByPoolId);
const expectedRewardVaultBalanceByPoolId = _.cloneDeep(rewardVaultBalanceByPoolId); const expectedRewardBalanceByPoolId = _.cloneDeep(rewardBalanceByPoolId);
for (const poolId of Object.keys(rewardByPoolId)) { for (const poolId of Object.keys(rewardByPoolId)) {
const operatorShare = operatorShareByPoolId[poolId]; const operatorShare = operatorShareByPoolId[poolId];
[ [
expectedOperatorBalanceByPoolId[poolId], expectedOperatorBalanceByPoolId[poolId],
expectedRewardVaultBalanceByPoolId[poolId], expectedRewardBalanceByPoolId[poolId],
] = await this._computeExpectedRewardVaultBalanceAsync( ] = this._computeExpectedRewardBalance(
poolId, poolId,
rewardByPoolId[poolId], rewardByPoolId[poolId],
expectedOperatorBalanceByPoolId[poolId], expectedOperatorBalanceByPoolId[poolId],
expectedRewardVaultBalanceByPoolId[poolId], expectedRewardBalanceByPoolId[poolId],
delegatorStakesByPoolId[poolId], delegatorStakesByPoolId[poolId],
operatorShare, operatorShare,
); );
} }
return [expectedOperatorBalanceByPoolId, expectedRewardVaultBalanceByPoolId]; return [expectedOperatorBalanceByPoolId, expectedRewardBalanceByPoolId];
} }
private async _computeExpectedRewardVaultBalanceAsync( private _computeExpectedRewardBalance(
poolId: string, poolId: string,
reward: BigNumber, reward: BigNumber,
operatorBalance: BigNumber, operatorBalance: BigNumber,
rewardVaultBalance: BigNumber, rewardBalance: BigNumber,
stakeBalances: BalanceByOwner, stakeBalances: BalanceByOwner,
operatorShare: BigNumber, operatorShare: BigNumber,
): Promise<[BigNumber, BigNumber]> { ): [BigNumber, BigNumber] {
const totalStakeDelegatedToPool = BigNumber.sum(...Object.values(stakeBalances)); const totalStakeDelegatedToPool = BigNumber.sum(...Object.values(stakeBalances));
const stakeDelegatedToPoolByOperator = stakeBalances[this._operatorByPoolId[poolId]]; const stakeDelegatedToPoolByOperator = stakeBalances[this._operatorByPoolId[poolId]];
const membersStakeDelegatedToPool = totalStakeDelegatedToPool.minus(stakeDelegatedToPoolByOperator); const membersStakeDelegatedToPool = totalStakeDelegatedToPool.minus(stakeDelegatedToPoolByOperator);
@ -200,7 +200,7 @@ export class FinalizerActor extends BaseActor {
? reward ? reward
: reward.times(operatorShare).dividedToIntegerBy(PPM_100_PERCENT); : reward.times(operatorShare).dividedToIntegerBy(PPM_100_PERCENT);
const membersPortion = reward.minus(operatorPortion); const membersPortion = reward.minus(operatorPortion);
return [operatorBalance.plus(operatorPortion), rewardVaultBalance.plus(membersPortion)]; return [operatorBalance.plus(operatorPortion), rewardBalance.plus(membersPortion)];
} }
private async _getOperatorBalanceByPoolIdAsync( private async _getOperatorBalanceByPoolIdAsync(
@ -208,7 +208,7 @@ export class FinalizerActor extends BaseActor {
): Promise<OperatorBalanceByPoolId> { ): Promise<OperatorBalanceByPoolId> {
const operatorBalanceByPoolId: OperatorBalanceByPoolId = {}; const operatorBalanceByPoolId: OperatorBalanceByPoolId = {};
for (const poolId of Object.keys(operatorByPoolId)) { for (const poolId of Object.keys(operatorByPoolId)) {
operatorBalanceByPoolId[poolId] = await this._stakingApiWrapper.ethVaultContract.balanceOf.callAsync( operatorBalanceByPoolId[poolId] = await this._stakingApiWrapper.wethContract.balanceOf.callAsync(
operatorByPoolId[poolId], operatorByPoolId[poolId],
); );
} }
@ -225,14 +225,14 @@ export class FinalizerActor extends BaseActor {
return operatorShareByPoolId; return operatorShareByPoolId;
} }
private async _getRewardVaultBalanceByPoolIdAsync(poolIds: string[]): Promise<RewardVaultBalanceByPoolId> { private async _getRewardBalanceByPoolIdAsync(poolIds: string[]): Promise<RewardBalanceByPoolId> {
const rewardVaultBalanceByPoolId: RewardVaultBalanceByPoolId = {}; const rewardBalanceByPoolId: RewardBalanceByPoolId = {};
for (const poolId of poolIds) { for (const poolId of poolIds) {
rewardVaultBalanceByPoolId[poolId] = await this._stakingApiWrapper.rewardVaultContract.balanceOf.callAsync( rewardBalanceByPoolId[poolId] = await this._stakingApiWrapper.stakingContract.rewardsByPoolId.callAsync(
poolId, poolId,
); );
} }
return rewardVaultBalanceByPoolId; return rewardBalanceByPoolId;
} }
private async _getRewardByPoolIdAsync(poolIds: string[]): Promise<RewardByPoolId> { private async _getRewardByPoolIdAsync(poolIds: string[]): Promise<RewardByPoolId> {
@ -241,9 +241,7 @@ export class FinalizerActor extends BaseActor {
this._stakingApiWrapper.stakingContract.getActiveStakingPoolThisEpoch.callAsync(poolId), this._stakingApiWrapper.stakingContract.getActiveStakingPoolThisEpoch.callAsync(poolId),
), ),
); );
const totalRewards = await this._stakingApiWrapper.utils.getEthAndWethBalanceOfAsync( const totalRewards = await this._stakingApiWrapper.stakingContract.getAvailableRewardsBalance.callAsync();
this._stakingApiWrapper.stakingContract.address,
);
const totalFeesCollected = BigNumber.sum(...activePools.map(p => p.feesCollected)); const totalFeesCollected = BigNumber.sum(...activePools.map(p => p.feesCollected));
const totalWeightedStake = BigNumber.sum(...activePools.map(p => p.weightedStake)); const totalWeightedStake = BigNumber.sum(...activePools.map(p => p.weightedStake));
if (totalRewards.eq(0) || totalFeesCollected.eq(0) || totalWeightedStake.eq(0)) { if (totalRewards.eq(0) || totalFeesCollected.eq(0) || totalWeightedStake.eq(0)) {

View File

@ -155,8 +155,8 @@ export class StakerActor extends BaseActor {
); );
} }
public async syncDelegatorRewardsAsync(poolId: string, revertError?: RevertError): Promise<void> { public async withdrawDelegatorRewardsAsync(poolId: string, revertError?: RevertError): Promise<void> {
const txReceiptPromise = this._stakingApiWrapper.stakingContract.syncDelegatorRewards.awaitTransactionSuccessAsync( const txReceiptPromise = this._stakingApiWrapper.stakingContract.withdrawDelegatorRewards.awaitTransactionSuccessAsync(
poolId, poolId,
{ from: this._owner }, { from: this._owner },
); );

View File

@ -101,8 +101,6 @@ blockchainTests('Migration tests', env => {
it('should set the correct initial params', async () => { it('should set the correct initial params', async () => {
const wethProxyAddress = randomAddress(); const wethProxyAddress = randomAddress();
const ethVaultAddress = randomAddress();
const rewardVaultAddress = randomAddress();
const zrxVaultAddress = randomAddress(); const zrxVaultAddress = randomAddress();
const stakingProxyContractAddress = (await StakingProxyContract.deployFrom0xArtifactAsync( const stakingProxyContractAddress = (await StakingProxyContract.deployFrom0xArtifactAsync(
@ -113,8 +111,6 @@ blockchainTests('Migration tests', env => {
stakingContract.address, stakingContract.address,
stakingContract.address, stakingContract.address,
wethProxyAddress, wethProxyAddress,
ethVaultAddress,
rewardVaultAddress,
zrxVaultAddress, zrxVaultAddress,
)).address; )).address;
@ -131,9 +127,7 @@ blockchainTests('Migration tests', env => {
expect(params[4]).to.bignumber.eq(stakingConstants.DEFAULT_PARAMS.cobbDouglasAlphaNumerator); expect(params[4]).to.bignumber.eq(stakingConstants.DEFAULT_PARAMS.cobbDouglasAlphaNumerator);
expect(params[5]).to.bignumber.eq(stakingConstants.DEFAULT_PARAMS.cobbDouglasAlphaDenominator); expect(params[5]).to.bignumber.eq(stakingConstants.DEFAULT_PARAMS.cobbDouglasAlphaDenominator);
expect(params[6]).to.eq(wethProxyAddress); expect(params[6]).to.eq(wethProxyAddress);
expect(params[7]).to.eq(ethVaultAddress); expect(params[7]).to.eq(zrxVaultAddress);
expect(params[8]).to.eq(rewardVaultAddress);
expect(params[9]).to.eq(zrxVaultAddress);
}); });
}); });
@ -149,8 +143,6 @@ blockchainTests('Migration tests', env => {
initTargetContract.address, initTargetContract.address,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
{ {
from: notAuthorizedAddress, from: notAuthorizedAddress,
}, },
@ -164,8 +156,6 @@ blockchainTests('Migration tests', env => {
initTargetContract.address, initTargetContract.address,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
); );
await assertInitStateAsync(proxyContract); await assertInitStateAsync(proxyContract);
}); });
@ -175,8 +165,6 @@ blockchainTests('Migration tests', env => {
initTargetContract.address, initTargetContract.address,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
); );
const logsArgs = filterLogsToArguments<TestStakingProxyStakingContractAttachedToProxyEventArgs>( const logsArgs = filterLogsToArguments<TestStakingProxyStakingContractAttachedToProxyEventArgs>(
receipt.logs, receipt.logs,
@ -195,29 +183,18 @@ blockchainTests('Migration tests', env => {
initTargetContract.address, initTargetContract.address,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
); );
return expect(tx).to.revertWith(INIT_REVERT_ERROR); return expect(tx).to.revertWith(INIT_REVERT_ERROR);
}); });
it('calls init with initialized addresses if passed in args are null', async () => { it('calls init with initialized addresses if passed in args are null', async () => {
const wethProxyAddress = randomAddress(); const wethProxyAddress = randomAddress();
const ethVaultAddress = randomAddress();
const rewardVaultAddress = randomAddress();
const zrxVaultAddress = randomAddress(); const zrxVaultAddress = randomAddress();
await proxyContract.setAddressParams.awaitTransactionSuccessAsync( await proxyContract.setAddressParams.awaitTransactionSuccessAsync(wethProxyAddress, zrxVaultAddress);
wethProxyAddress,
ethVaultAddress,
rewardVaultAddress,
zrxVaultAddress,
);
const receipt = await proxyContract.attachStakingContract.awaitTransactionSuccessAsync( const receipt = await proxyContract.attachStakingContract.awaitTransactionSuccessAsync(
initTargetContract.address, initTargetContract.address,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
); );
const logsArgs = filterLogsToArguments<TestInitTargetInitAddressesEventArgs>( const logsArgs = filterLogsToArguments<TestInitTargetInitAddressesEventArgs>(
receipt.logs, receipt.logs,
@ -225,21 +202,15 @@ blockchainTests('Migration tests', env => {
); );
for (const args of logsArgs) { for (const args of logsArgs) {
expect(args.wethProxyAddress).to.eq(wethProxyAddress); expect(args.wethProxyAddress).to.eq(wethProxyAddress);
expect(args.ethVaultAddress).to.eq(ethVaultAddress);
expect(args.rewardVaultAddress).to.eq(rewardVaultAddress);
expect(args.zrxVaultAddress).to.eq(zrxVaultAddress); expect(args.zrxVaultAddress).to.eq(zrxVaultAddress);
} }
}); });
it('calls init with passed in addresses if they are not null', async () => { it('calls init with passed in addresses if they are not null', async () => {
const wethProxyAddress = randomAddress(); const wethProxyAddress = randomAddress();
const ethVaultAddress = randomAddress();
const rewardVaultAddress = randomAddress();
const zrxVaultAddress = randomAddress(); const zrxVaultAddress = randomAddress();
const receipt = await proxyContract.attachStakingContract.awaitTransactionSuccessAsync( const receipt = await proxyContract.attachStakingContract.awaitTransactionSuccessAsync(
initTargetContract.address, initTargetContract.address,
wethProxyAddress, wethProxyAddress,
ethVaultAddress,
rewardVaultAddress,
zrxVaultAddress, zrxVaultAddress,
); );
const logsArgs = filterLogsToArguments<TestInitTargetInitAddressesEventArgs>( const logsArgs = filterLogsToArguments<TestInitTargetInitAddressesEventArgs>(
@ -248,8 +219,6 @@ blockchainTests('Migration tests', env => {
); );
for (const args of logsArgs) { for (const args of logsArgs) {
expect(args.wethProxyAddress).to.eq(wethProxyAddress); expect(args.wethProxyAddress).to.eq(wethProxyAddress);
expect(args.ethVaultAddress).to.eq(ethVaultAddress);
expect(args.rewardVaultAddress).to.eq(rewardVaultAddress);
expect(args.zrxVaultAddress).to.eq(zrxVaultAddress); expect(args.zrxVaultAddress).to.eq(zrxVaultAddress);
} }
}); });
@ -259,8 +228,6 @@ blockchainTests('Migration tests', env => {
revertAddress, revertAddress,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
); );
return expect(tx).to.revertWith(STORAGE_PARAMS_REVERT_ERROR); return expect(tx).to.revertWith(STORAGE_PARAMS_REVERT_ERROR);
}); });
@ -273,8 +240,6 @@ blockchainTests('Migration tests', env => {
initTargetContract.address, initTargetContract.address,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
); );
const initCounter = await initTargetContract.getInitCounter.callAsync({ to: proxyContract.address }); const initCounter = await initTargetContract.getInitCounter.callAsync({ to: proxyContract.address });
expect(initCounter).to.bignumber.eq(2); expect(initCounter).to.bignumber.eq(2);
@ -284,32 +249,16 @@ blockchainTests('Migration tests', env => {
blockchainTests.resets('Staking.init()', async () => { blockchainTests.resets('Staking.init()', async () => {
it('throws if not called by an authorized address', async () => { it('throws if not called by an authorized address', async () => {
const tx = stakingContract.init.awaitTransactionSuccessAsync( const tx = stakingContract.init.awaitTransactionSuccessAsync(randomAddress(), randomAddress(), {
randomAddress(),
randomAddress(),
randomAddress(),
randomAddress(),
{
from: notAuthorizedAddress, from: notAuthorizedAddress,
}, });
);
const expectedError = new AuthorizableRevertErrors.SenderNotAuthorizedError(notAuthorizedAddress); const expectedError = new AuthorizableRevertErrors.SenderNotAuthorizedError(notAuthorizedAddress);
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
it('throws if already intitialized', async () => { it('throws if already intitialized', async () => {
await stakingContract.init.awaitTransactionSuccessAsync( await stakingContract.init.awaitTransactionSuccessAsync(randomAddress(), randomAddress());
randomAddress(), const tx = stakingContract.init.awaitTransactionSuccessAsync(randomAddress(), randomAddress());
randomAddress(),
randomAddress(),
randomAddress(),
);
const tx = stakingContract.init.awaitTransactionSuccessAsync(
randomAddress(),
randomAddress(),
randomAddress(),
randomAddress(),
);
const expectedError = new StakingRevertErrors.InitializationError(); const expectedError = new StakingRevertErrors.InitializationError();
return expect(tx).to.revertWith(expectedError); return expect(tx).to.revertWith(expectedError);
}); });
@ -441,26 +390,6 @@ blockchainTests('Migration tests', env => {
); );
expect(tx).to.revertWith(expectedError); expect(tx).to.revertWith(expectedError);
}); });
it('reverts if ethVault is 0', async () => {
const tx = proxyContract.setAndAssertParams.awaitTransactionSuccessAsync({
...stakingConstants.DEFAULT_PARAMS,
ethVaultAddress: constants.NULL_ADDRESS,
});
const expectedError = new StakingRevertErrors.InvalidParamValueError(
StakingRevertErrors.InvalidParamValueErrorCode.InvalidEthVaultAddress,
);
expect(tx).to.revertWith(expectedError);
});
it('reverts if rewardVault is 0', async () => {
const tx = proxyContract.setAndAssertParams.awaitTransactionSuccessAsync({
...stakingConstants.DEFAULT_PARAMS,
rewardVaultAddress: constants.NULL_ADDRESS,
});
const expectedError = new StakingRevertErrors.InvalidParamValueError(
StakingRevertErrors.InvalidParamValueErrorCode.InvalidRewardVaultAddress,
);
expect(tx).to.revertWith(expectedError);
});
it('reverts if zrxVault is 0', async () => { it('reverts if zrxVault is 0', async () => {
const tx = proxyContract.setAndAssertParams.awaitTransactionSuccessAsync({ const tx = proxyContract.setAndAssertParams.awaitTransactionSuccessAsync({
...stakingConstants.DEFAULT_PARAMS, ...stakingConstants.DEFAULT_PARAMS,

View File

@ -1,28 +1,22 @@
import { blockchainTests, constants, expect, filterLogsToArguments, randomAddress } from '@0x/contracts-test-utils'; import { blockchainTests, expect, filterLogsToArguments } from '@0x/contracts-test-utils';
import { AuthorizableRevertErrors, BigNumber } from '@0x/utils'; import { AuthorizableRevertErrors, BigNumber } from '@0x/utils';
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
import * as _ from 'lodash'; import * as _ from 'lodash';
import { import { artifacts, IStakingEventsParamsSetEventArgs, MixinParamsContract } from '../src/';
artifacts,
IStakingEventsParamsSetEventArgs,
TestMixinParamsContract,
TestMixinParamsEvents,
TestMixinParamsWETHApproveEventArgs,
} from '../src/';
import { constants as stakingConstants } from './utils/constants'; import { constants as stakingConstants } from './utils/constants';
import { StakingParams } from './utils/types'; import { StakingParams } from './utils/types';
blockchainTests('Configurable Parameters unit tests', env => { blockchainTests('Configurable Parameters unit tests', env => {
let testContract: TestMixinParamsContract; let testContract: MixinParamsContract;
let authorizedAddress: string; let authorizedAddress: string;
let notAuthorizedAddress: string; let notAuthorizedAddress: string;
before(async () => { before(async () => {
[authorizedAddress, notAuthorizedAddress] = await env.getAccountAddressesAsync(); [authorizedAddress, notAuthorizedAddress] = await env.getAccountAddressesAsync();
testContract = await TestMixinParamsContract.deployFrom0xArtifactAsync( testContract = await MixinParamsContract.deployFrom0xArtifactAsync(
artifacts.TestMixinParams, artifacts.MixinParams,
env.provider, env.provider,
env.txDefaults, env.txDefaults,
artifacts, artifacts,
@ -46,8 +40,6 @@ blockchainTests('Configurable Parameters unit tests', env => {
new BigNumber(_params.cobbDouglasAlphaNumerator), new BigNumber(_params.cobbDouglasAlphaNumerator),
new BigNumber(_params.cobbDouglasAlphaDenominator), new BigNumber(_params.cobbDouglasAlphaDenominator),
_params.wethProxyAddress, _params.wethProxyAddress,
_params.ethVaultAddress,
_params.rewardVaultAddress,
_params.zrxVaultAddress, _params.zrxVaultAddress,
{ from }, { from },
); );
@ -62,8 +54,6 @@ blockchainTests('Configurable Parameters unit tests', env => {
expect(event.cobbDouglasAlphaNumerator).to.bignumber.eq(_params.cobbDouglasAlphaNumerator); expect(event.cobbDouglasAlphaNumerator).to.bignumber.eq(_params.cobbDouglasAlphaNumerator);
expect(event.cobbDouglasAlphaDenominator).to.bignumber.eq(_params.cobbDouglasAlphaDenominator); expect(event.cobbDouglasAlphaDenominator).to.bignumber.eq(_params.cobbDouglasAlphaDenominator);
expect(event.wethProxyAddress).to.eq(_params.wethProxyAddress); expect(event.wethProxyAddress).to.eq(_params.wethProxyAddress);
expect(event.ethVaultAddress).to.eq(_params.ethVaultAddress);
expect(event.rewardVaultAddress).to.eq(_params.rewardVaultAddress);
expect(event.zrxVaultAddress).to.eq(_params.zrxVaultAddress); expect(event.zrxVaultAddress).to.eq(_params.zrxVaultAddress);
// Assert `getParams()`. // Assert `getParams()`.
const actual = await testContract.getParams.callAsync(); const actual = await testContract.getParams.callAsync();
@ -74,9 +64,7 @@ blockchainTests('Configurable Parameters unit tests', env => {
expect(actual[4]).to.bignumber.eq(_params.cobbDouglasAlphaNumerator); expect(actual[4]).to.bignumber.eq(_params.cobbDouglasAlphaNumerator);
expect(actual[5]).to.bignumber.eq(_params.cobbDouglasAlphaDenominator); expect(actual[5]).to.bignumber.eq(_params.cobbDouglasAlphaDenominator);
expect(actual[6]).to.eq(_params.wethProxyAddress); expect(actual[6]).to.eq(_params.wethProxyAddress);
expect(actual[7]).to.eq(_params.ethVaultAddress); expect(actual[7]).to.eq(_params.zrxVaultAddress);
expect(actual[8]).to.eq(_params.rewardVaultAddress);
expect(actual[9]).to.eq(_params.zrxVaultAddress);
return receipt; return receipt;
} }
@ -89,43 +77,6 @@ blockchainTests('Configurable Parameters unit tests', env => {
it('works if called by owner', async () => { it('works if called by owner', async () => {
return setParamsAndAssertAsync({}); return setParamsAndAssertAsync({});
}); });
describe('WETH allowance', () => {
it('rescinds allowance for old vaults and grants unlimited allowance to new ones', async () => {
const [oldEthVaultAddress, oldRewardVaultAddress, newEthVaultAddress, newRewardVaultAddress] = _.times(
4,
() => randomAddress(),
);
await testContract.setVaultAddresses.awaitTransactionSuccessAsync(
oldEthVaultAddress,
oldRewardVaultAddress,
);
const { logs } = await setParamsAndAssertAsync({
ethVaultAddress: newEthVaultAddress,
rewardVaultAddress: newRewardVaultAddress,
});
const approveEvents = filterLogsToArguments<TestMixinParamsWETHApproveEventArgs>(
logs,
TestMixinParamsEvents.WETHApprove,
);
expect(approveEvents[0]).to.deep.eq({
spender: oldEthVaultAddress,
amount: constants.ZERO_AMOUNT,
});
expect(approveEvents[1]).to.deep.eq({
spender: newEthVaultAddress,
amount: constants.MAX_UINT256,
});
expect(approveEvents[2]).to.deep.eq({
spender: oldRewardVaultAddress,
amount: constants.ZERO_AMOUNT,
});
expect(approveEvents[3]).to.deep.eq({
spender: newRewardVaultAddress,
amount: constants.MAX_UINT256,
});
});
});
}); });
}); });
// tslint:enable:no-unnecessary-type-assertion // tslint:enable:no-unnecessary-type-assertion

View File

@ -1,5 +1,5 @@
import { ERC20Wrapper } from '@0x/contracts-asset-proxy'; import { ERC20Wrapper } from '@0x/contracts-asset-proxy';
import { blockchainTests, describe, expect, shortZip } from '@0x/contracts-test-utils'; import { blockchainTests, constants, describe, expect, shortZip } from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils'; import { BigNumber } from '@0x/utils';
import * as _ from 'lodash'; import * as _ from 'lodash';
@ -46,8 +46,6 @@ blockchainTests.resets('Testing Rewards', env => {
minimumPoolStake: new BigNumber(2), minimumPoolStake: new BigNumber(2),
cobbDouglasAlphaNumerator: new BigNumber(1), cobbDouglasAlphaNumerator: new BigNumber(1),
cobbDouglasAlphaDenominator: new BigNumber(6), cobbDouglasAlphaDenominator: new BigNumber(6),
rewardVaultAddress: stakingApiWrapper.rewardVaultContract.address,
ethVaultAddress: stakingApiWrapper.ethVaultContract.address,
zrxVaultAddress: stakingApiWrapper.zrxVaultContract.address, zrxVaultAddress: stakingApiWrapper.zrxVaultContract.address,
}); });
// setup stakers // setup stakers
@ -75,47 +73,47 @@ blockchainTests.resets('Testing Rewards', env => {
describe('Reward Simulation', () => { describe('Reward Simulation', () => {
interface EndBalances { interface EndBalances {
// staker 1 // staker 1
stakerRewardVaultBalance_1?: BigNumber; stakerRewardBalance_1?: BigNumber;
stakerEthVaultBalance_1?: BigNumber; stakerWethBalance_1?: BigNumber;
// staker 2 // staker 2
stakerRewardVaultBalance_2?: BigNumber; stakerRewardBalance_2?: BigNumber;
stakerEthVaultBalance_2?: BigNumber; stakerWethBalance_2?: BigNumber;
// operator // operator
operatorEthVaultBalance?: BigNumber; operatorWethBalance?: BigNumber;
// undivided balance in reward pool // undivided balance in reward pool
poolRewardVaultBalance?: BigNumber; poolRewardBalance?: BigNumber;
membersRewardVaultBalance?: BigNumber; membersRewardBalance?: BigNumber;
} }
const validateEndBalances = async (_expectedEndBalances: EndBalances): Promise<void> => { const validateEndBalances = async (_expectedEndBalances: EndBalances): Promise<void> => {
const expectedEndBalances = { const expectedEndBalances = {
// staker 1 // staker 1
stakerRewardVaultBalance_1: stakerRewardBalance_1:
_expectedEndBalances.stakerRewardVaultBalance_1 !== undefined _expectedEndBalances.stakerRewardBalance_1 !== undefined
? _expectedEndBalances.stakerRewardVaultBalance_1 ? _expectedEndBalances.stakerRewardBalance_1
: ZERO, : constants.ZERO_AMOUNT,
stakerEthVaultBalance_1: stakerWethBalance_1:
_expectedEndBalances.stakerEthVaultBalance_1 !== undefined _expectedEndBalances.stakerWethBalance_1 !== undefined
? _expectedEndBalances.stakerEthVaultBalance_1 ? _expectedEndBalances.stakerWethBalance_1
: ZERO, : constants.ZERO_AMOUNT,
// staker 2 // staker 2
stakerRewardVaultBalance_2: stakerRewardBalance_2:
_expectedEndBalances.stakerRewardVaultBalance_2 !== undefined _expectedEndBalances.stakerRewardBalance_2 !== undefined
? _expectedEndBalances.stakerRewardVaultBalance_2 ? _expectedEndBalances.stakerRewardBalance_2
: ZERO, : constants.ZERO_AMOUNT,
stakerEthVaultBalance_2: stakerWethBalance_2:
_expectedEndBalances.stakerEthVaultBalance_2 !== undefined _expectedEndBalances.stakerWethBalance_2 !== undefined
? _expectedEndBalances.stakerEthVaultBalance_2 ? _expectedEndBalances.stakerWethBalance_2
: ZERO, : constants.ZERO_AMOUNT,
// operator // operator
operatorEthVaultBalance: operatorWethBalance:
_expectedEndBalances.operatorEthVaultBalance !== undefined _expectedEndBalances.operatorWethBalance !== undefined
? _expectedEndBalances.operatorEthVaultBalance ? _expectedEndBalances.operatorWethBalance
: ZERO, : constants.ZERO_AMOUNT,
// undivided balance in reward pool // undivided balance in reward pool
poolRewardVaultBalance: poolRewardBalance:
_expectedEndBalances.poolRewardVaultBalance !== undefined _expectedEndBalances.poolRewardBalance !== undefined
? _expectedEndBalances.poolRewardVaultBalance ? _expectedEndBalances.poolRewardBalance
: ZERO, : constants.ZERO_AMOUNT,
}; };
const finalEndBalancesAsArray = await Promise.all([ const finalEndBalancesAsArray = await Promise.all([
// staker 1 // staker 1
@ -123,40 +121,40 @@ blockchainTests.resets('Testing Rewards', env => {
poolId, poolId,
stakers[0].getOwner(), stakers[0].getOwner(),
), ),
stakingApiWrapper.ethVaultContract.balanceOf.callAsync(stakers[0].getOwner()), stakingApiWrapper.wethContract.balanceOf.callAsync(stakers[0].getOwner()),
// staker 2 // staker 2
stakingApiWrapper.stakingContract.computeRewardBalanceOfDelegator.callAsync( stakingApiWrapper.stakingContract.computeRewardBalanceOfDelegator.callAsync(
poolId, poolId,
stakers[1].getOwner(), stakers[1].getOwner(),
), ),
stakingApiWrapper.ethVaultContract.balanceOf.callAsync(stakers[1].getOwner()), stakingApiWrapper.wethContract.balanceOf.callAsync(stakers[1].getOwner()),
// operator // operator
stakingApiWrapper.ethVaultContract.balanceOf.callAsync(poolOperator.getOwner()), stakingApiWrapper.wethContract.balanceOf.callAsync(poolOperator.getOwner()),
// undivided balance in reward pool // undivided balance in reward pool
stakingApiWrapper.rewardVaultContract.balanceOf.callAsync(poolId), stakingApiWrapper.stakingContract.rewardsByPoolId.callAsync(poolId),
]); ]);
expect(finalEndBalancesAsArray[0], 'stakerRewardVaultBalance_1').to.be.bignumber.equal( expect(finalEndBalancesAsArray[0], 'stakerRewardBalance_1').to.be.bignumber.equal(
expectedEndBalances.stakerRewardVaultBalance_1, expectedEndBalances.stakerRewardBalance_1,
); );
expect(finalEndBalancesAsArray[1], 'stakerEthVaultBalance_1').to.be.bignumber.equal( expect(finalEndBalancesAsArray[1], 'stakerWethBalance_1').to.be.bignumber.equal(
expectedEndBalances.stakerEthVaultBalance_1, expectedEndBalances.stakerWethBalance_1,
); );
expect(finalEndBalancesAsArray[2], 'stakerRewardVaultBalance_2').to.be.bignumber.equal( expect(finalEndBalancesAsArray[2], 'stakerRewardBalance_2').to.be.bignumber.equal(
expectedEndBalances.stakerRewardVaultBalance_2, expectedEndBalances.stakerRewardBalance_2,
); );
expect(finalEndBalancesAsArray[3], 'stakerEthVaultBalance_2').to.be.bignumber.equal( expect(finalEndBalancesAsArray[3], 'stakerWethBalance_2').to.be.bignumber.equal(
expectedEndBalances.stakerEthVaultBalance_2, expectedEndBalances.stakerWethBalance_2,
); );
expect(finalEndBalancesAsArray[4], 'operatorEthVaultBalance').to.be.bignumber.equal( expect(finalEndBalancesAsArray[4], 'operatorWethBalance').to.be.bignumber.equal(
expectedEndBalances.operatorEthVaultBalance, expectedEndBalances.operatorWethBalance,
); );
expect(finalEndBalancesAsArray[5], 'poolRewardVaultBalance').to.be.bignumber.equal( expect(finalEndBalancesAsArray[5], 'poolRewardBalance').to.be.bignumber.equal(
expectedEndBalances.poolRewardVaultBalance, expectedEndBalances.poolRewardBalance,
); );
}; };
const payProtocolFeeAndFinalize = async (_fee?: BigNumber) => { const payProtocolFeeAndFinalize = async (_fee?: BigNumber) => {
const fee = _fee !== undefined ? _fee : ZERO; const fee = _fee !== undefined ? _fee : constants.ZERO_AMOUNT;
if (!fee.eq(ZERO)) { if (!fee.eq(constants.ZERO_AMOUNT)) {
await stakingApiWrapper.stakingContract.payProtocolFee.awaitTransactionSuccessAsync( await stakingApiWrapper.stakingContract.payProtocolFee.awaitTransactionSuccessAsync(
poolOperator.getOwner(), poolOperator.getOwner(),
takerAddress, takerAddress,
@ -166,7 +164,6 @@ blockchainTests.resets('Testing Rewards', env => {
} }
await finalizer.finalizeAsync(); await finalizer.finalizeAsync();
}; };
const ZERO = new BigNumber(0);
it('Reward balance should be zero if not delegated', async () => { it('Reward balance should be zero if not delegated', async () => {
// sanity balances - all zero // sanity balances - all zero
await validateEndBalances({}); await validateEndBalances({});
@ -193,7 +190,7 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// sanity check final balances - all zero // sanity check final balances - all zero
await validateEndBalances({ await validateEndBalances({
operatorEthVaultBalance: reward, operatorWethBalance: reward,
}); });
}); });
it(`Operator should receive entire reward if no delegators in their pool it(`Operator should receive entire reward if no delegators in their pool
@ -206,7 +203,7 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
operatorEthVaultBalance: reward, operatorWethBalance: reward,
}); });
}); });
it('Should give pool reward to delegator', async () => { it('Should give pool reward to delegator', async () => {
@ -220,9 +217,9 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: reward, stakerRewardBalance_1: reward,
poolRewardVaultBalance: reward, poolRewardBalance: reward,
membersRewardVaultBalance: reward, membersRewardBalance: reward,
}); });
}); });
it('Should split pool reward between delegators', async () => { it('Should split pool reward between delegators', async () => {
@ -239,10 +236,10 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: reward.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount), stakerRewardBalance_1: reward.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount),
stakerRewardVaultBalance_2: reward.times(stakeAmounts[1]).dividedToIntegerBy(totalStakeAmount), stakerRewardBalance_2: reward.times(stakeAmounts[1]).dividedToIntegerBy(totalStakeAmount),
poolRewardVaultBalance: reward, poolRewardBalance: reward,
membersRewardVaultBalance: reward, membersRewardBalance: reward,
}); });
}); });
it('Should split pool reward between delegators, when they join in different epochs', async () => { it('Should split pool reward between delegators, when they join in different epochs', async () => {
@ -276,10 +273,10 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: reward.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount), stakerRewardBalance_1: reward.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount),
stakerRewardVaultBalance_2: reward.times(stakeAmounts[1]).dividedToIntegerBy(totalStakeAmount), stakerRewardBalance_2: reward.times(stakeAmounts[1]).dividedToIntegerBy(totalStakeAmount),
poolRewardVaultBalance: reward, poolRewardBalance: reward,
membersRewardVaultBalance: reward, membersRewardBalance: reward,
}); });
}); });
it('Should give pool reward to delegators only for the epoch during which they delegated', async () => { it('Should give pool reward to delegators only for the epoch during which they delegated', async () => {
@ -299,14 +296,14 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(rewardForBothDelegators); await payProtocolFeeAndFinalize(rewardForBothDelegators);
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: rewardForOnlyFirstDelegator.plus( stakerRewardBalance_1: rewardForOnlyFirstDelegator.plus(
rewardForBothDelegators.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount), rewardForBothDelegators.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount),
), ),
stakerRewardVaultBalance_2: rewardForBothDelegators stakerRewardBalance_2: rewardForBothDelegators
.times(stakeAmounts[1]) .times(stakeAmounts[1])
.dividedToIntegerBy(totalStakeAmount), .dividedToIntegerBy(totalStakeAmount),
poolRewardVaultBalance: rewardForOnlyFirstDelegator.plus(rewardForBothDelegators), poolRewardBalance: rewardForOnlyFirstDelegator.plus(rewardForBothDelegators),
membersRewardVaultBalance: rewardForOnlyFirstDelegator.plus(rewardForBothDelegators), membersRewardBalance: rewardForOnlyFirstDelegator.plus(rewardForBothDelegators),
}); });
}); });
it('Should split pool reward between delegators, over several consecutive epochs', async () => { it('Should split pool reward between delegators, over several consecutive epochs', async () => {
@ -339,17 +336,15 @@ blockchainTests.resets('Testing Rewards', env => {
} }
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: rewardForOnlyFirstDelegator.plus( stakerRewardBalance_1: rewardForOnlyFirstDelegator.plus(
totalSharedRewards.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount), totalSharedRewards.times(stakeAmounts[0]).dividedToIntegerBy(totalStakeAmount),
), ),
stakerRewardVaultBalance_2: totalSharedRewards stakerRewardBalance_2: totalSharedRewards.times(stakeAmounts[1]).dividedToIntegerBy(totalStakeAmount),
.times(stakeAmounts[1]) poolRewardBalance: rewardForOnlyFirstDelegator.plus(totalSharedRewards),
.dividedToIntegerBy(totalStakeAmount), membersRewardBalance: rewardForOnlyFirstDelegator.plus(totalSharedRewards),
poolRewardVaultBalance: rewardForOnlyFirstDelegator.plus(totalSharedRewards),
membersRewardVaultBalance: rewardForOnlyFirstDelegator.plus(totalSharedRewards),
}); });
}); });
it('Should send existing rewards from reward vault to eth vault correctly when undelegating stake', async () => { it('Should withdraw existing rewards when undelegating stake', async () => {
const stakeAmount = toBaseUnitAmount(4); const stakeAmount = toBaseUnitAmount(4);
// first staker delegates (epoch 0) // first staker delegates (epoch 0)
await stakers[0].stakeWithPoolAsync(poolId, stakeAmount); await stakers[0].stakeWithPoolAsync(poolId, stakeAmount);
@ -358,7 +353,7 @@ blockchainTests.resets('Testing Rewards', env => {
// earn reward // earn reward
const reward = toBaseUnitAmount(10); const reward = toBaseUnitAmount(10);
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// undelegate (moves delegator's from the transient reward vault into the eth vault) // undelegate (withdraws delegator's rewards)
await stakers[0].moveStakeAsync( await stakers[0].moveStakeAsync(
new StakeInfo(StakeStatus.Delegated, poolId), new StakeInfo(StakeStatus.Delegated, poolId),
new StakeInfo(StakeStatus.Active), new StakeInfo(StakeStatus.Active),
@ -366,11 +361,11 @@ blockchainTests.resets('Testing Rewards', env => {
); );
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: ZERO, stakerRewardBalance_1: constants.ZERO_AMOUNT,
stakerEthVaultBalance_1: reward, stakerWethBalance_1: reward,
}); });
}); });
it('Should send existing rewards from reward vault to eth vault correctly when delegating more stake', async () => { it('Should withdraw existing rewards correctly when delegating more stake', async () => {
const stakeAmount = toBaseUnitAmount(4); const stakeAmount = toBaseUnitAmount(4);
// first staker delegates (epoch 0) // first staker delegates (epoch 0)
await stakers[0].stakeWithPoolAsync(poolId, stakeAmount); await stakers[0].stakeWithPoolAsync(poolId, stakeAmount);
@ -383,8 +378,8 @@ blockchainTests.resets('Testing Rewards', env => {
await stakers[0].stakeWithPoolAsync(poolId, stakeAmount); await stakers[0].stakeWithPoolAsync(poolId, stakeAmount);
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: ZERO, stakerRewardBalance_1: constants.ZERO_AMOUNT,
stakerEthVaultBalance_1: reward, stakerWethBalance_1: reward,
}); });
}); });
it('Should continue earning rewards after adding more stake and progressing several epochs', async () => { it('Should continue earning rewards after adding more stake and progressing several epochs', async () => {
@ -414,18 +409,18 @@ blockchainTests.resets('Testing Rewards', env => {
} }
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: rewardBeforeAddingMoreStake.plus( stakerRewardBalance_1: rewardBeforeAddingMoreStake.plus(
totalRewardsAfterAddingMoreStake totalRewardsAfterAddingMoreStake
.times(stakeAmounts[0]) .times(stakeAmounts[0])
.dividedBy(totalStake) .dividedBy(totalStake)
.integerValue(BigNumber.ROUND_DOWN), .integerValue(BigNumber.ROUND_DOWN),
), ),
stakerRewardVaultBalance_2: totalRewardsAfterAddingMoreStake stakerRewardBalance_2: totalRewardsAfterAddingMoreStake
.times(stakeAmounts[1]) .times(stakeAmounts[1])
.dividedBy(totalStake) .dividedBy(totalStake)
.integerValue(BigNumber.ROUND_DOWN), .integerValue(BigNumber.ROUND_DOWN),
poolRewardVaultBalance: rewardBeforeAddingMoreStake.plus(totalRewardsAfterAddingMoreStake), poolRewardBalance: rewardBeforeAddingMoreStake.plus(totalRewardsAfterAddingMoreStake),
membersRewardVaultBalance: rewardBeforeAddingMoreStake.plus(totalRewardsAfterAddingMoreStake), membersRewardBalance: rewardBeforeAddingMoreStake.plus(totalRewardsAfterAddingMoreStake),
}); });
}); });
it('Should stop collecting rewards after undelegating', async () => { it('Should stop collecting rewards after undelegating', async () => {
@ -453,8 +448,8 @@ blockchainTests.resets('Testing Rewards', env => {
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerEthVaultBalance_1: rewardForDelegator, stakerWethBalance_1: rewardForDelegator,
operatorEthVaultBalance: rewardNotForDelegator, operatorWethBalance: rewardNotForDelegator,
}); });
}); });
it('Should stop collecting rewards after undelegating, after several epochs', async () => { it('Should stop collecting rewards after undelegating, after several epochs', async () => {
@ -488,8 +483,8 @@ blockchainTests.resets('Testing Rewards', env => {
} }
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerEthVaultBalance_1: rewardForDelegator, stakerWethBalance_1: rewardForDelegator,
operatorEthVaultBalance: totalRewardsNotForDelegator, operatorWethBalance: totalRewardsNotForDelegator,
}); });
}); });
it('Should collect fees correctly when leaving and returning to a pool', async () => { it('Should collect fees correctly when leaving and returning to a pool', async () => {
@ -522,10 +517,10 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(rewardsForDelegator[1]); await payProtocolFeeAndFinalize(rewardsForDelegator[1]);
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: rewardsForDelegator[1], stakerRewardBalance_1: rewardsForDelegator[1],
stakerEthVaultBalance_1: rewardsForDelegator[0], stakerWethBalance_1: rewardsForDelegator[0],
operatorEthVaultBalance: rewardNotForDelegator, operatorWethBalance: rewardNotForDelegator,
poolRewardVaultBalance: rewardsForDelegator[1], poolRewardBalance: rewardsForDelegator[1],
}); });
}); });
it('Should collect fees correctly when re-delegating after un-delegating', async () => { it('Should collect fees correctly when re-delegating after un-delegating', async () => {
@ -559,13 +554,13 @@ blockchainTests.resets('Testing Rewards', env => {
); );
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: ZERO, stakerRewardBalance_1: constants.ZERO_AMOUNT,
stakerEthVaultBalance_1: rewardForDelegator, stakerWethBalance_1: rewardForDelegator,
operatorEthVaultBalance: ZERO, operatorWethBalance: constants.ZERO_AMOUNT,
poolRewardVaultBalance: ZERO, poolRewardBalance: constants.ZERO_AMOUNT,
}); });
}); });
it('Should withdraw delegator rewards to eth vault when calling `syncDelegatorRewards`', async () => { it('Should withdraw delegator rewards when calling `withdrawDelegatorRewards`', async () => {
// first staker delegates (epoch 0) // first staker delegates (epoch 0)
const rewardForDelegator = toBaseUnitAmount(10); const rewardForDelegator = toBaseUnitAmount(10);
const stakeAmount = toBaseUnitAmount(4); const stakeAmount = toBaseUnitAmount(4);
@ -579,15 +574,15 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(); await payProtocolFeeAndFinalize();
// this should go to the delegator // this should go to the delegator
await payProtocolFeeAndFinalize(rewardForDelegator); await payProtocolFeeAndFinalize(rewardForDelegator);
await stakingApiWrapper.stakingContract.syncDelegatorRewards.awaitTransactionSuccessAsync(poolId, { await stakingApiWrapper.stakingContract.withdrawDelegatorRewards.awaitTransactionSuccessAsync(poolId, {
from: stakers[0].getOwner(), from: stakers[0].getOwner(),
}); });
// sanity check final balances // sanity check final balances
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: ZERO, stakerRewardBalance_1: constants.ZERO_AMOUNT,
stakerEthVaultBalance_1: rewardForDelegator, stakerWethBalance_1: rewardForDelegator,
operatorEthVaultBalance: ZERO, operatorWethBalance: constants.ZERO_AMOUNT,
poolRewardVaultBalance: ZERO, poolRewardBalance: constants.ZERO_AMOUNT,
}); });
}); });
it(`payout should be based on stake at the time of rewards`, async () => { it(`payout should be based on stake at the time of rewards`, async () => {
@ -607,11 +602,11 @@ blockchainTests.resets('Testing Rewards', env => {
// finalize // finalize
const reward = toBaseUnitAmount(10); const reward = toBaseUnitAmount(10);
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// Sync rewards to move the rewards into the EthVault. // withdraw rewards
await staker.syncDelegatorRewardsAsync(poolId); await staker.withdrawDelegatorRewardsAsync(poolId);
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: toBaseUnitAmount(0), stakerRewardBalance_1: toBaseUnitAmount(0),
stakerEthVaultBalance_1: reward, stakerWethBalance_1: reward,
}); });
}); });
it(`should split payout between two delegators when syncing rewards`, async () => { it(`should split payout between two delegators when syncing rewards`, async () => {
@ -627,18 +622,18 @@ blockchainTests.resets('Testing Rewards', env => {
// finalize // finalize
const reward = toBaseUnitAmount(10); const reward = toBaseUnitAmount(10);
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
// Sync rewards to move rewards from RewardVault into the EthVault. // withdraw rewards
for (const [staker] of _.reverse(stakersAndStake)) { for (const [staker] of _.reverse(stakersAndStake)) {
await staker.syncDelegatorRewardsAsync(poolId); await staker.withdrawDelegatorRewardsAsync(poolId);
} }
const expectedStakerRewards = stakeAmounts.map(n => reward.times(n).dividedToIntegerBy(totalStakeAmount)); const expectedStakerRewards = stakeAmounts.map(n => reward.times(n).dividedToIntegerBy(totalStakeAmount));
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: toBaseUnitAmount(0), stakerRewardBalance_1: toBaseUnitAmount(0),
stakerRewardVaultBalance_2: toBaseUnitAmount(0), stakerRewardBalance_2: toBaseUnitAmount(0),
stakerEthVaultBalance_1: expectedStakerRewards[0], stakerWethBalance_1: expectedStakerRewards[0],
stakerEthVaultBalance_2: expectedStakerRewards[1], stakerWethBalance_2: expectedStakerRewards[1],
poolRewardVaultBalance: new BigNumber(1), // Rounding error poolRewardBalance: new BigNumber(1), // Rounding error
membersRewardVaultBalance: new BigNumber(1), // Rounding error membersRewardBalance: new BigNumber(1), // Rounding error
}); });
}); });
it(`delegator should not be credited payout twice by syncing rewards twice`, async () => { it(`delegator should not be credited payout twice by syncing rewards twice`, async () => {
@ -656,32 +651,30 @@ blockchainTests.resets('Testing Rewards', env => {
await payProtocolFeeAndFinalize(reward); await payProtocolFeeAndFinalize(reward);
const expectedStakerRewards = stakeAmounts.map(n => reward.times(n).dividedToIntegerBy(totalStakeAmount)); const expectedStakerRewards = stakeAmounts.map(n => reward.times(n).dividedToIntegerBy(totalStakeAmount));
await validateEndBalances({ await validateEndBalances({
stakerRewardVaultBalance_1: expectedStakerRewards[0], stakerRewardBalance_1: expectedStakerRewards[0],
stakerRewardVaultBalance_2: expectedStakerRewards[1], stakerRewardBalance_2: expectedStakerRewards[1],
stakerEthVaultBalance_1: toBaseUnitAmount(0), stakerWethBalance_1: toBaseUnitAmount(0),
stakerEthVaultBalance_2: toBaseUnitAmount(0), stakerWethBalance_2: toBaseUnitAmount(0),
poolRewardVaultBalance: reward, poolRewardBalance: reward,
membersRewardVaultBalance: reward, membersRewardBalance: reward,
}); });
// First staker will sync rewards to get rewards transferred to EthVault. // First staker will withdraw rewards.
const sneakyStaker = stakers[0]; const sneakyStaker = stakers[0];
const sneakyStakerExpectedEthVaultBalance = expectedStakerRewards[0]; const sneakyStakerExpectedWethBalance = expectedStakerRewards[0];
await sneakyStaker.syncDelegatorRewardsAsync(poolId); await sneakyStaker.withdrawDelegatorRewardsAsync(poolId);
// Should have been credited the correct amount of rewards. // Should have been credited the correct amount of rewards.
let sneakyStakerEthVaultBalance = await stakingApiWrapper.ethVaultContract.balanceOf.callAsync( let sneakyStakerWethBalance = await stakingApiWrapper.wethContract.balanceOf.callAsync(
sneakyStaker.getOwner(), sneakyStaker.getOwner(),
); );
expect(sneakyStakerEthVaultBalance, 'EthVault balance after first undelegate').to.bignumber.eq( expect(sneakyStakerWethBalance, 'WETH balance after first undelegate').to.bignumber.eq(
sneakyStakerExpectedEthVaultBalance, sneakyStakerExpectedWethBalance,
); );
// Now he'll try to do it again to see if he gets credited twice. // Now he'll try to do it again to see if he gets credited twice.
await sneakyStaker.syncDelegatorRewardsAsync(poolId); await sneakyStaker.withdrawDelegatorRewardsAsync(poolId);
/// The total amount credited should remain the same. /// The total amount credited should remain the same.
sneakyStakerEthVaultBalance = await stakingApiWrapper.ethVaultContract.balanceOf.callAsync( sneakyStakerWethBalance = await stakingApiWrapper.wethContract.balanceOf.callAsync(sneakyStaker.getOwner());
sneakyStaker.getOwner(), expect(sneakyStakerWethBalance, 'WETH balance after second undelegate').to.bignumber.eq(
); sneakyStakerExpectedWethBalance,
expect(sneakyStakerEthVaultBalance, 'EthVault balance after second undelegate').to.bignumber.eq(
sneakyStakerExpectedEthVaultBalance,
); );
}); });
}); });

View File

@ -1,19 +0,0 @@
import { blockchainTests, expect } from '@0x/contracts-test-utils';
import { artifacts, TestStorageLayoutContract } from '../src';
blockchainTests.resets('Storage layout tests', env => {
let testStorageLayoutContract: TestStorageLayoutContract;
before(async () => {
testStorageLayoutContract = await TestStorageLayoutContract.deployFrom0xArtifactAsync(
artifacts.TestStorageLayout,
env.provider,
env.txDefaults,
{},
);
});
it('should have the correct storage slots', async () => {
return expect(testStorageLayoutContract.assertExpectedStorageLayout.callAsync()).to.be.fulfilled('');
});
});

View File

@ -16,8 +16,7 @@ import {
artifacts, artifacts,
TestDelegatorRewardsContract, TestDelegatorRewardsContract,
TestDelegatorRewardsEvents, TestDelegatorRewardsEvents,
TestDelegatorRewardsRecordDepositToEthVaultEventArgs as EthVaultDepositEventArgs, TestDelegatorRewardsTransferEventArgs,
TestDelegatorRewardsRecordDepositToRewardVaultEventArgs as RewardVaultDepositEventArgs,
} from '../../src'; } from '../../src';
import { import {
@ -57,7 +56,7 @@ blockchainTests.resets('delegator unit rewards', env => {
}; };
// Generate a deterministic operator address based on the poolId. // Generate a deterministic operator address based on the poolId.
_opts.operator = poolIdToOperator(_opts.poolId); _opts.operator = poolIdToOperator(_opts.poolId);
await testContract.depositStakingPoolRewards.awaitTransactionSuccessAsync( await testContract.syncPoolRewards.awaitTransactionSuccessAsync(
_opts.poolId, _opts.poolId,
_opts.operator, _opts.operator,
new BigNumber(_opts.operatorReward), new BigNumber(_opts.operatorReward),
@ -123,9 +122,8 @@ blockchainTests.resets('delegator unit rewards', env => {
return [_operatorReward, _membersReward]; return [_operatorReward, _membersReward];
} }
type ResultWithDeposits<T extends {}> = T & { type ResultWithTransfers<T extends {}> = T & {
ethVaultDeposit: BigNumber; delegatorTransfers: BigNumber;
rewardVaultDeposit: BigNumber;
}; };
interface DelegateStakeOpts { interface DelegateStakeOpts {
@ -136,7 +134,7 @@ blockchainTests.resets('delegator unit rewards', env => {
async function delegateStakeNowAsync( async function delegateStakeNowAsync(
poolId: string, poolId: string,
opts?: Partial<DelegateStakeOpts>, opts?: Partial<DelegateStakeOpts>,
): Promise<ResultWithDeposits<DelegateStakeOpts>> { ): Promise<ResultWithTransfers<DelegateStakeOpts>> {
return delegateStakeAsync(poolId, opts, true); return delegateStakeAsync(poolId, opts, true);
} }
@ -144,7 +142,7 @@ blockchainTests.resets('delegator unit rewards', env => {
poolId: string, poolId: string,
opts?: Partial<DelegateStakeOpts>, opts?: Partial<DelegateStakeOpts>,
now?: boolean, now?: boolean,
): Promise<ResultWithDeposits<DelegateStakeOpts>> { ): Promise<ResultWithTransfers<DelegateStakeOpts>> {
const _opts = { const _opts = {
delegator: randomAddress(), delegator: randomAddress(),
stake: getRandomInteger(1, toBaseUnitAmount(10)), stake: getRandomInteger(1, toBaseUnitAmount(10)),
@ -152,11 +150,10 @@ blockchainTests.resets('delegator unit rewards', env => {
}; };
const fn = now ? testContract.delegateStakeNow : testContract.delegateStake; const fn = now ? testContract.delegateStakeNow : testContract.delegateStake;
const receipt = await fn.awaitTransactionSuccessAsync(_opts.delegator, poolId, new BigNumber(_opts.stake)); const receipt = await fn.awaitTransactionSuccessAsync(_opts.delegator, poolId, new BigNumber(_opts.stake));
const [ethVaultDeposit, rewardVaultDeposit] = getDepositsFromLogs(receipt.logs, poolId, _opts.delegator); const delegatorTransfers = getTransfersFromLogs(receipt.logs, _opts.delegator);
return { return {
..._opts, ..._opts,
ethVaultDeposit, delegatorTransfers,
rewardVaultDeposit,
}; };
} }
@ -164,42 +161,31 @@ blockchainTests.resets('delegator unit rewards', env => {
poolId: string, poolId: string,
delegator: string, delegator: string,
stake?: Numberish, stake?: Numberish,
): Promise<ResultWithDeposits<{ stake: BigNumber }>> { ): Promise<ResultWithTransfers<{ stake: BigNumber }>> {
const _stake = new BigNumber( const _stake = new BigNumber(
stake || stake ||
(await testContract.getStakeDelegatedToPoolByOwner.callAsync(delegator, poolId)).currentEpochBalance, (await testContract.getStakeDelegatedToPoolByOwner.callAsync(delegator, poolId)).currentEpochBalance,
); );
const receipt = await testContract.undelegateStake.awaitTransactionSuccessAsync(delegator, poolId, _stake); const receipt = await testContract.undelegateStake.awaitTransactionSuccessAsync(delegator, poolId, _stake);
const [ethVaultDeposit, rewardVaultDeposit] = getDepositsFromLogs(receipt.logs, poolId, delegator); const delegatorTransfers = getTransfersFromLogs(receipt.logs, delegator);
return { return {
stake: _stake, stake: _stake,
ethVaultDeposit, delegatorTransfers,
rewardVaultDeposit,
}; };
} }
function getDepositsFromLogs(logs: LogEntry[], poolId: string, delegator?: string): [BigNumber, BigNumber] { function getTransfersFromLogs(logs: LogEntry[], delegator?: string): BigNumber {
let ethVaultDeposit = constants.ZERO_AMOUNT; let delegatorTransfers = constants.ZERO_AMOUNT;
let rewardVaultDeposit = constants.ZERO_AMOUNT; const transferArgs = filterLogsToArguments<TestDelegatorRewardsTransferEventArgs>(
const ethVaultDepositArgs = filterLogsToArguments<EthVaultDepositEventArgs>(
logs, logs,
TestDelegatorRewardsEvents.RecordDepositToEthVault, TestDelegatorRewardsEvents.Transfer,
); );
for (const event of ethVaultDepositArgs) { for (const event of transferArgs) {
if (event.owner === delegator) { if (event._to === delegator) {
ethVaultDeposit = ethVaultDeposit.plus(event.amount); delegatorTransfers = delegatorTransfers.plus(event._value);
} }
} }
const rewardVaultDepositArgs = filterLogsToArguments<RewardVaultDepositEventArgs>( return delegatorTransfers;
logs,
TestDelegatorRewardsEvents.RecordDepositToRewardVault,
);
if (rewardVaultDepositArgs.length > 0) {
expect(rewardVaultDepositArgs.length).to.eq(1);
expect(rewardVaultDepositArgs[0].poolId).to.eq(poolId);
rewardVaultDeposit = rewardVaultDepositArgs[0].amount;
}
return [ethVaultDeposit, rewardVaultDeposit];
} }
async function advanceEpochAsync(): Promise<number> { async function advanceEpochAsync(): Promise<number> {
@ -216,16 +202,15 @@ blockchainTests.resets('delegator unit rewards', env => {
return testContract.computeRewardBalanceOfOperator.callAsync(poolId); return testContract.computeRewardBalanceOfOperator.callAsync(poolId);
} }
async function touchStakeAsync(poolId: string, delegator: string): Promise<ResultWithDeposits<{}>> { async function touchStakeAsync(poolId: string, delegator: string): Promise<ResultWithTransfers<{}>> {
return undelegateStakeAsync(poolId, delegator, 0); return undelegateStakeAsync(poolId, delegator, 0);
} }
async function finalizePoolAsync(poolId: string): Promise<ResultWithDeposits<{}>> { async function finalizePoolAsync(poolId: string): Promise<ResultWithTransfers<{}>> {
const receipt = await testContract.originalFinalizePool.awaitTransactionSuccessAsync(poolId); const receipt = await testContract.originalFinalizePool.awaitTransactionSuccessAsync(poolId);
const [ethVaultDeposit, rewardVaultDeposit] = getDepositsFromLogs(receipt.logs, poolId); const delegatorTransfers = getTransfersFromLogs(receipt.logs, poolId);
return { return {
ethVaultDeposit, delegatorTransfers,
rewardVaultDeposit,
}; };
} }
@ -384,8 +369,8 @@ blockchainTests.resets('delegator unit rewards', env => {
await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1. // rewards paid for stake in epoch 1.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake }); const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const { ethVaultDeposit: deposit } = await undelegateStakeAsync(poolId, delegator); const { delegatorTransfers: withdrawal } = await undelegateStakeAsync(poolId, delegator);
assertRoughlyEquals(deposit, reward); assertRoughlyEquals(withdrawal, reward);
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator); const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0); expect(delegatorReward).to.bignumber.eq(0);
}); });
@ -397,8 +382,8 @@ blockchainTests.resets('delegator unit rewards', env => {
await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1. // rewards paid for stake in epoch 1.
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake }); const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const { ethVaultDeposit: deposit } = await undelegateStakeAsync(poolId, delegator); const { delegatorTransfers: withdrawal } = await undelegateStakeAsync(poolId, delegator);
assertRoughlyEquals(deposit, reward); assertRoughlyEquals(withdrawal, reward);
await delegateStakeAsync(poolId, { delegator, stake }); await delegateStakeAsync(poolId, { delegator, stake });
const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator); const delegatorReward = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(delegatorReward).to.bignumber.eq(0); expect(delegatorReward).to.bignumber.eq(0);
@ -448,7 +433,7 @@ blockchainTests.resets('delegator unit rewards', env => {
// Pay rewards for epoch 1. // Pay rewards for epoch 1.
const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake }); const { membersReward: reward1 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
// add extra stake // add extra stake
const { ethVaultDeposit: deposit } = await delegateStakeAsync(poolId, { delegator, stake: stake2 }); const { delegatorTransfers: withdrawal } = await delegateStakeAsync(poolId, { delegator, stake: stake2 });
await advanceEpochAsync(); // epoch 3 (stake2 now active) await advanceEpochAsync(); // epoch 3 (stake2 now active)
// Pay rewards for epoch 2. // Pay rewards for epoch 2.
await advanceEpochAsync(); // epoch 4 await advanceEpochAsync(); // epoch 4
@ -459,7 +444,7 @@ blockchainTests.resets('delegator unit rewards', env => {
computeDelegatorRewards(reward1, stake1, rewardStake), computeDelegatorRewards(reward1, stake1, rewardStake),
computeDelegatorRewards(reward2, totalStake, rewardStake), computeDelegatorRewards(reward2, totalStake, rewardStake),
); );
assertRoughlyEquals(BigNumber.sum(deposit, delegatorReward), expectedDelegatorReward); assertRoughlyEquals(BigNumber.sum(withdrawal, delegatorReward), expectedDelegatorReward);
}); });
it('uses old stake for rewards paid in the epoch right after extra stake is added', async () => { it('uses old stake for rewards paid in the epoch right after extra stake is added', async () => {
@ -666,16 +651,16 @@ blockchainTests.resets('delegator unit rewards', env => {
}); });
describe('reward transfers', async () => { describe('reward transfers', async () => {
it('transfers all rewards to eth vault when touching stake', async () => { it('transfers all rewards to delegator when touching stake', async () => {
const poolId = hexRandom(); const poolId = hexRandom();
const { delegator, stake } = await delegateStakeAsync(poolId); const { delegator, stake } = await delegateStakeAsync(poolId);
await advanceEpochAsync(); // epoch 1 (stake now active) await advanceEpochAsync(); // epoch 1 (stake now active)
await advanceEpochAsync(); // epoch 2 await advanceEpochAsync(); // epoch 2
// rewards paid for stake in epoch 1 // rewards paid for stake in epoch 1
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake }); const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: stake });
const { ethVaultDeposit: deposit } = await touchStakeAsync(poolId, delegator); const { delegatorTransfers: withdrawal } = await touchStakeAsync(poolId, delegator);
const finalRewardBalance = await getDelegatorRewardBalanceAsync(poolId, delegator); const finalRewardBalance = await getDelegatorRewardBalanceAsync(poolId, delegator);
expect(deposit).to.bignumber.eq(reward); expect(withdrawal).to.bignumber.eq(reward);
expect(finalRewardBalance).to.bignumber.eq(0); expect(finalRewardBalance).to.bignumber.eq(0);
}); });
@ -697,7 +682,7 @@ blockchainTests.resets('delegator unit rewards', env => {
// touch the stake one last time // touch the stake one last time
stakeResults.push(await touchStakeAsync(poolId, delegator)); stakeResults.push(await touchStakeAsync(poolId, delegator));
// Should only see deposits for epoch 2. // Should only see deposits for epoch 2.
const allDeposits = stakeResults.map(r => r.ethVaultDeposit); const allDeposits = stakeResults.map(r => r.delegatorTransfers);
const expectedReward = computeDelegatorRewards(reward, stake, rewardStake); const expectedReward = computeDelegatorRewards(reward, stake, rewardStake);
assertRoughlyEquals(BigNumber.sum(...allDeposits), expectedReward); assertRoughlyEquals(BigNumber.sum(...allDeposits), expectedReward);
}); });
@ -725,7 +710,7 @@ blockchainTests.resets('delegator unit rewards', env => {
const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake }); const { membersReward: reward2 } = await rewardPoolAsync({ poolId, membersStake: rewardStake });
// touch the stake to claim rewards // touch the stake to claim rewards
stakeResults.push(await touchStakeAsync(poolId, delegator)); stakeResults.push(await touchStakeAsync(poolId, delegator));
const allDeposits = stakeResults.map(r => r.ethVaultDeposit); const allDeposits = stakeResults.map(r => r.delegatorTransfers);
const expectedReward = BigNumber.sum( const expectedReward = BigNumber.sum(
computeDelegatorRewards(reward1, stake, rewardStake), computeDelegatorRewards(reward1, stake, rewardStake),
computeDelegatorRewards(reward2, new BigNumber(stake).minus(unstake), rewardStake), computeDelegatorRewards(reward2, new BigNumber(stake).minus(unstake), rewardStake),
@ -743,11 +728,11 @@ blockchainTests.resets('delegator unit rewards', env => {
// rewards paid for stake in epoch 1 // rewards paid for stake in epoch 1
const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: totalStake }); const { membersReward: reward } = await rewardPoolAsync({ poolId, membersStake: totalStake });
// delegator A will finalize and collect rewards by touching stake. // delegator A will finalize and collect rewards by touching stake.
const { ethVaultDeposit: depositA } = await touchStakeAsync(poolId, delegatorA); const { delegatorTransfers: withdrawalA } = await touchStakeAsync(poolId, delegatorA);
assertRoughlyEquals(depositA, computeDelegatorRewards(reward, stakeA, totalStake)); assertRoughlyEquals(withdrawalA, computeDelegatorRewards(reward, stakeA, totalStake));
// delegator B will collect rewards by touching stake // delegator B will collect rewards by touching stake
const { ethVaultDeposit: depositB } = await touchStakeAsync(poolId, delegatorB); const { delegatorTransfers: withdrawalB } = await touchStakeAsync(poolId, delegatorB);
assertRoughlyEquals(depositB, computeDelegatorRewards(reward, stakeB, totalStake)); assertRoughlyEquals(withdrawalB, computeDelegatorRewards(reward, stakeB, totalStake));
}); });
it('delegator B collects correct rewards after delegator A finalizes', async () => { it('delegator B collects correct rewards after delegator A finalizes', async () => {
@ -767,11 +752,11 @@ blockchainTests.resets('delegator unit rewards', env => {
}); });
const totalRewards = BigNumber.sum(prevReward, unfinalizedReward); const totalRewards = BigNumber.sum(prevReward, unfinalizedReward);
// delegator A will finalize and collect rewards by touching stake. // delegator A will finalize and collect rewards by touching stake.
const { ethVaultDeposit: depositA } = await touchStakeAsync(poolId, delegatorA); const { delegatorTransfers: withdrawalA } = await touchStakeAsync(poolId, delegatorA);
assertRoughlyEquals(depositA, computeDelegatorRewards(totalRewards, stakeA, totalStake)); assertRoughlyEquals(withdrawalA, computeDelegatorRewards(totalRewards, stakeA, totalStake));
// delegator B will collect rewards by touching stake // delegator B will collect rewards by touching stake
const { ethVaultDeposit: depositB } = await touchStakeAsync(poolId, delegatorB); const { delegatorTransfers: withdrawalB } = await touchStakeAsync(poolId, delegatorB);
assertRoughlyEquals(depositB, computeDelegatorRewards(totalRewards, stakeB, totalStake)); assertRoughlyEquals(withdrawalB, computeDelegatorRewards(totalRewards, stakeB, totalStake));
}); });
it('delegator A and B collect correct rewards after external finalization', async () => { it('delegator A and B collect correct rewards after external finalization', async () => {
@ -793,11 +778,11 @@ blockchainTests.resets('delegator unit rewards', env => {
// finalize // finalize
await finalizePoolAsync(poolId); await finalizePoolAsync(poolId);
// delegator A will collect rewards by touching stake. // delegator A will collect rewards by touching stake.
const { ethVaultDeposit: depositA } = await touchStakeAsync(poolId, delegatorA); const { delegatorTransfers: withdrawalA } = await touchStakeAsync(poolId, delegatorA);
assertRoughlyEquals(depositA, computeDelegatorRewards(totalRewards, stakeA, totalStake)); assertRoughlyEquals(withdrawalA, computeDelegatorRewards(totalRewards, stakeA, totalStake));
// delegator B will collect rewards by touching stake // delegator B will collect rewards by touching stake
const { ethVaultDeposit: depositB } = await touchStakeAsync(poolId, delegatorB); const { delegatorTransfers: withdrawalB } = await touchStakeAsync(poolId, delegatorB);
assertRoughlyEquals(depositB, computeDelegatorRewards(totalRewards, stakeB, totalStake)); assertRoughlyEquals(withdrawalB, computeDelegatorRewards(totalRewards, stakeB, totalStake));
}); });
}); });
}); });

View File

@ -8,11 +8,9 @@ import * as _ from 'lodash';
import { import {
artifacts, artifacts,
EthVaultContract,
IStakingEventsEpochEndedEventArgs, IStakingEventsEpochEndedEventArgs,
IStakingEventsStakingPoolActivatedEventArgs, IStakingEventsStakingPoolActivatedEventArgs,
ReadOnlyProxyContract, ReadOnlyProxyContract,
StakingPoolRewardVaultContract,
StakingProxyContract, StakingProxyContract,
TestCobbDouglasContract, TestCobbDouglasContract,
TestStakingContract, TestStakingContract,
@ -31,8 +29,6 @@ export class StakingApiWrapper {
// The StakingProxy.sol contract as a StakingProxyContract // The StakingProxy.sol contract as a StakingProxyContract
public stakingProxyContract: StakingProxyContract; public stakingProxyContract: StakingProxyContract;
public zrxVaultContract: ZrxVaultContract; public zrxVaultContract: ZrxVaultContract;
public ethVaultContract: EthVaultContract;
public rewardVaultContract: StakingPoolRewardVaultContract;
public zrxTokenContract: DummyERC20TokenContract; public zrxTokenContract: DummyERC20TokenContract;
public wethContract: WETH9Contract; public wethContract: WETH9Contract;
public cobbDouglasContract: TestCobbDouglasContract; public cobbDouglasContract: TestCobbDouglasContract;
@ -122,8 +118,6 @@ export class StakingApiWrapper {
new BigNumber(_params.cobbDouglasAlphaNumerator), new BigNumber(_params.cobbDouglasAlphaNumerator),
new BigNumber(_params.cobbDouglasAlphaDenominator), new BigNumber(_params.cobbDouglasAlphaDenominator),
_params.wethProxyAddress, _params.wethProxyAddress,
_params.ethVaultAddress,
_params.rewardVaultAddress,
_params.zrxVaultAddress, _params.zrxVaultAddress,
); );
}, },
@ -144,8 +138,6 @@ export class StakingApiWrapper {
'cobbDouglasAlphaNumerator', 'cobbDouglasAlphaNumerator',
'cobbDouglasAlphaDenominator', 'cobbDouglasAlphaDenominator',
'wethProxyAddress', 'wethProxyAddress',
'ethVaultAddress',
'rewardVaultAddress',
'zrxVaultAddress', 'zrxVaultAddress',
], ],
await this.stakingContract.getParams.callAsync(), await this.stakingContract.getParams.callAsync(),
@ -180,16 +172,12 @@ export class StakingApiWrapper {
stakingProxyContract: StakingProxyContract, stakingProxyContract: StakingProxyContract,
stakingContract: TestStakingContract, stakingContract: TestStakingContract,
zrxVaultContract: ZrxVaultContract, zrxVaultContract: ZrxVaultContract,
ethVaultContract: EthVaultContract,
rewardVaultContract: StakingPoolRewardVaultContract,
zrxTokenContract: DummyERC20TokenContract, zrxTokenContract: DummyERC20TokenContract,
wethContract: WETH9Contract, wethContract: WETH9Contract,
cobbDouglasContract: TestCobbDouglasContract, cobbDouglasContract: TestCobbDouglasContract,
) { ) {
this._web3Wrapper = env.web3Wrapper; this._web3Wrapper = env.web3Wrapper;
this.zrxVaultContract = zrxVaultContract; this.zrxVaultContract = zrxVaultContract;
this.ethVaultContract = ethVaultContract;
this.rewardVaultContract = rewardVaultContract;
this.zrxTokenContract = zrxTokenContract; this.zrxTokenContract = zrxTokenContract;
this.wethContract = wethContract; this.wethContract = wethContract;
this.cobbDouglasContract = cobbDouglasContract; this.cobbDouglasContract = cobbDouglasContract;
@ -253,22 +241,6 @@ export async function deployAndConfigureContractsAsync(
env.txDefaults, env.txDefaults,
artifacts, artifacts,
); );
// deploy eth vault
const ethVaultContract = await EthVaultContract.deployFrom0xArtifactAsync(
artifacts.EthVault,
env.provider,
env.txDefaults,
artifacts,
wethContract.address,
);
// deploy reward vault
const rewardVaultContract = await StakingPoolRewardVaultContract.deployFrom0xArtifactAsync(
artifacts.StakingPoolRewardVault,
env.provider,
env.txDefaults,
artifacts,
wethContract.address,
);
// deploy zrx vault // deploy zrx vault
const zrxVaultContract = await ZrxVaultContract.deployFrom0xArtifactAsync( const zrxVaultContract = await ZrxVaultContract.deployFrom0xArtifactAsync(
artifacts.ZrxVault, artifacts.ZrxVault,
@ -287,8 +259,6 @@ export async function deployAndConfigureContractsAsync(
stakingContract.address, stakingContract.address,
readOnlyProxyContract.address, readOnlyProxyContract.address,
erc20ProxyContract.address, erc20ProxyContract.address,
ethVaultContract.address,
rewardVaultContract.address,
zrxVaultContract.address, zrxVaultContract.address,
); );
// deploy cobb douglas contract // deploy cobb douglas contract
@ -303,18 +273,12 @@ export async function deployAndConfigureContractsAsync(
await erc20ProxyContract.addAuthorizedAddress.awaitTransactionSuccessAsync(zrxVaultContract.address); await erc20ProxyContract.addAuthorizedAddress.awaitTransactionSuccessAsync(zrxVaultContract.address);
// set staking proxy contract in zrx vault // set staking proxy contract in zrx vault
await zrxVaultContract.setStakingProxy.awaitTransactionSuccessAsync(stakingProxyContract.address); await zrxVaultContract.setStakingProxy.awaitTransactionSuccessAsync(stakingProxyContract.address);
// set staking proxy contract in reward vault
await rewardVaultContract.setStakingProxy.awaitTransactionSuccessAsync(stakingProxyContract.address);
// set staking proxy contract in eth vault
await ethVaultContract.setStakingProxy.awaitTransactionSuccessAsync(stakingProxyContract.address);
return new StakingApiWrapper( return new StakingApiWrapper(
env, env,
ownerAddress, ownerAddress,
stakingProxyContract, stakingProxyContract,
stakingContract, stakingContract,
zrxVaultContract, zrxVaultContract,
ethVaultContract,
rewardVaultContract,
zrxTokenContract, zrxTokenContract,
wethContract, wethContract,
cobbDouglasContract, cobbDouglasContract,

View File

@ -18,8 +18,6 @@ export const constants = {
cobbDouglasAlphaNumerator: new BigNumber(1), cobbDouglasAlphaNumerator: new BigNumber(1),
cobbDouglasAlphaDenominator: new BigNumber(2), cobbDouglasAlphaDenominator: new BigNumber(2),
wethProxyAddress: randomAddress(), wethProxyAddress: randomAddress(),
ethVaultAddress: randomAddress(),
rewardVaultAddress: randomAddress(),
zrxVaultAddress: randomAddress(), zrxVaultAddress: randomAddress(),
}, },
PPM, PPM,

View File

@ -111,8 +111,6 @@ export class CumulativeRewardTrackingSimulation {
this.getTestCumulativeRewardTrackingContract().address, this.getTestCumulativeRewardTrackingContract().address,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS, constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
constants.NULL_ADDRESS,
); );
const testLogs = await this._executeActionsAsync(testActions); const testLogs = await this._executeActionsAsync(testActions);
CumulativeRewardTrackingSimulation._assertTestLogs(expectedTestLogs, testLogs); CumulativeRewardTrackingSimulation._assertTestLogs(expectedTestLogs, testLogs);

View File

@ -12,8 +12,6 @@ export interface StakingParams {
cobbDouglasAlphaNumerator: Numberish; cobbDouglasAlphaNumerator: Numberish;
cobbDouglasAlphaDenominator: Numberish; cobbDouglasAlphaDenominator: Numberish;
wethProxyAddress: string; wethProxyAddress: string;
ethVaultAddress: string;
rewardVaultAddress: string;
zrxVaultAddress: string; zrxVaultAddress: string;
} }
@ -103,7 +101,7 @@ export interface StakeBalances {
totalDelegatedStakeByPool: StakeBalanceByPool; totalDelegatedStakeByPool: StakeBalanceByPool;
} }
export interface RewardVaultBalanceByPoolId { export interface RewardBalanceByPoolId {
[key: string]: BigNumber; [key: string]: BigNumber;
} }

View File

@ -3,11 +3,8 @@
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true }, "compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"], "include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
"files": [ "files": [
"generated-artifacts/EthVault.json",
"generated-artifacts/IEthVault.json",
"generated-artifacts/IStaking.json", "generated-artifacts/IStaking.json",
"generated-artifacts/IStakingEvents.json", "generated-artifacts/IStakingEvents.json",
"generated-artifacts/IStakingPoolRewardVault.json",
"generated-artifacts/IStakingProxy.json", "generated-artifacts/IStakingProxy.json",
"generated-artifacts/IStorage.json", "generated-artifacts/IStorage.json",
"generated-artifacts/IStorageInit.json", "generated-artifacts/IStorageInit.json",
@ -40,7 +37,6 @@
"generated-artifacts/MixinVaultCore.json", "generated-artifacts/MixinVaultCore.json",
"generated-artifacts/ReadOnlyProxy.json", "generated-artifacts/ReadOnlyProxy.json",
"generated-artifacts/Staking.json", "generated-artifacts/Staking.json",
"generated-artifacts/StakingPoolRewardVault.json",
"generated-artifacts/StakingProxy.json", "generated-artifacts/StakingProxy.json",
"generated-artifacts/TestAssertStorageParams.json", "generated-artifacts/TestAssertStorageParams.json",
"generated-artifacts/TestCobbDouglas.json", "generated-artifacts/TestCobbDouglas.json",
@ -52,13 +48,11 @@
"generated-artifacts/TestLibProxy.json", "generated-artifacts/TestLibProxy.json",
"generated-artifacts/TestLibProxyReceiver.json", "generated-artifacts/TestLibProxyReceiver.json",
"generated-artifacts/TestLibSafeDowncast.json", "generated-artifacts/TestLibSafeDowncast.json",
"generated-artifacts/TestMixinParams.json",
"generated-artifacts/TestMixinVaultCore.json", "generated-artifacts/TestMixinVaultCore.json",
"generated-artifacts/TestProtocolFees.json", "generated-artifacts/TestProtocolFees.json",
"generated-artifacts/TestStaking.json", "generated-artifacts/TestStaking.json",
"generated-artifacts/TestStakingNoWETH.json", "generated-artifacts/TestStakingNoWETH.json",
"generated-artifacts/TestStakingProxy.json", "generated-artifacts/TestStakingProxy.json",
"generated-artifacts/TestStorageLayout.json",
"generated-artifacts/ZrxVault.json" "generated-artifacts/ZrxVault.json"
], ],
"exclude": ["./deploy/solc/solc_bin"] "exclude": ["./deploy/solc/solc_bin"]

View File

@ -25,8 +25,6 @@ export enum InvalidParamValueErrorCode {
InvalidMaximumMakersInPool, InvalidMaximumMakersInPool,
InvalidMinimumPoolStake, InvalidMinimumPoolStake,
InvalidWethProxyAddress, InvalidWethProxyAddress,
InvalidEthVaultAddress,
InvalidRewardVaultAddress,
InvalidZrxVaultAddress, InvalidZrxVaultAddress,
InvalidEpochDuration, InvalidEpochDuration,
} }
@ -190,18 +188,6 @@ export class InvalidParamValueError extends RevertError {
} }
} }
export class EthVaultNotSetError extends RevertError {
constructor() {
super('EthVaultNotSetError', 'EthVaultNotSetError()');
}
}
export class RewardVaultNotSetError extends RevertError {
constructor() {
super('RewardVaultNotSetError', 'RewardVaultNotSetError()');
}
}
export class InvalidStakeStatusError extends RevertError { export class InvalidStakeStatusError extends RevertError {
constructor(status?: BigNumber) { constructor(status?: BigNumber) {
super('InvalidStakeStatusError', 'InvalidStakeStatusError(uint256 status)', { status }); super('InvalidStakeStatusError', 'InvalidStakeStatusError(uint256 status)', { status });
@ -247,7 +233,6 @@ export class PreviousEpochNotFinalizedError extends RevertError {
const types = [ const types = [
AmountExceedsBalanceOfPoolError, AmountExceedsBalanceOfPoolError,
BlockTimestampTooLowError, BlockTimestampTooLowError,
EthVaultNotSetError,
ExchangeAddressAlreadyRegisteredError, ExchangeAddressAlreadyRegisteredError,
ExchangeAddressNotRegisteredError, ExchangeAddressNotRegisteredError,
InitializationError, InitializationError,
@ -267,7 +252,6 @@ const types = [
PoolExistenceError, PoolExistenceError,
PreviousEpochNotFinalizedError, PreviousEpochNotFinalizedError,
ProxyDestinationCannotBeNilError, ProxyDestinationCannotBeNilError,
RewardVaultNotSetError,
WithdrawAmountExceedsMemberBalanceError, WithdrawAmountExceedsMemberBalanceError,
]; ];