From 768387fea9d0da40ce13d13b055c0121faad398d Mon Sep 17 00:00:00 2001 From: Greg Hysen Date: Tue, 17 Sep 2019 14:31:38 -0700 Subject: [PATCH] Rebased and addressed PR comments --- contracts/staking/contracts/src/Staking.sol | 2 +- .../contracts/src/immutable/MixinStorage.sol | 2 +- .../src/interfaces/IStakingEvents.sol | 6 +- .../interfaces/IStakingPoolRewardVault.sol | 21 ++--- .../contracts/src/interfaces/IStructs.sol | 2 +- .../src/libs/LibStakingRichErrors.sol | 8 +- .../contracts/src/stake/MixinStake.sol | 29 +++---- .../src/staking_pools/MixinEthVault.sol | 81 ------------------- .../src/staking_pools/MixinStakingPool.sol | 43 ++++++---- .../staking_pools/MixinStakingPoolMakers.sol | 15 +--- .../MixinStakingPoolModifiers.sol | 32 ++------ .../MixinStakingPoolRewardVault.sol | 25 ++---- .../staking_pools/MixinStakingPoolRewards.sol | 36 +++++++-- .../src/vaults/StakingPoolRewardVault.sol | 40 +++------ .../test/actors/pool_operator_actor.ts | 4 +- contracts/staking/test/pools_test.ts | 12 +-- contracts/staking/test/rewards_test.ts | 8 +- contracts/staking/test/utils/api_wrapper.ts | 12 --- 18 files changed, 125 insertions(+), 253 deletions(-) delete mode 100644 contracts/staking/contracts/src/staking_pools/MixinEthVault.sol diff --git a/contracts/staking/contracts/src/Staking.sol b/contracts/staking/contracts/src/Staking.sol index 919262325a..21b7f7bb97 100644 --- a/contracts/staking/contracts/src/Staking.sol +++ b/contracts/staking/contracts/src/Staking.sol @@ -29,8 +29,8 @@ import "./fees/MixinExchangeFees.sol"; contract Staking is IStaking, MixinParams, - MixinStake, MixinStakingPool, + MixinStake, MixinExchangeFees { // this contract can receive ETH diff --git a/contracts/staking/contracts/src/immutable/MixinStorage.sol b/contracts/staking/contracts/src/immutable/MixinStorage.sol index 244541f606..62756e5e34 100644 --- a/contracts/staking/contracts/src/immutable/MixinStorage.sol +++ b/contracts/staking/contracts/src/immutable/MixinStorage.sol @@ -78,7 +78,7 @@ contract MixinStorage is mapping (address => IStructs.MakerPoolJoinStatus) public poolJoinedByMakerAddress; // mapping from Pool Id to Pool - mapping (bytes32 => IStructs.Pool) internal poolById; + mapping (bytes32 => IStructs.Pool) public poolById; // current epoch uint256 public currentEpoch = INITIAL_EPOCH; diff --git a/contracts/staking/contracts/src/interfaces/IStakingEvents.sol b/contracts/staking/contracts/src/interfaces/IStakingEvents.sol index c7133e71f4..eeb4f5f969 100644 --- a/contracts/staking/contracts/src/interfaces/IStakingEvents.sol +++ b/contracts/staking/contracts/src/interfaces/IStakingEvents.sol @@ -105,11 +105,11 @@ interface IStakingEvents { /// @dev Emitted by MixinStakingPool when a new pool is created. /// @param poolId Unique id generated for pool. - /// @param operatorAddress Address of creator/operator of pool. + /// @param operator The operator (creator) of pool. /// @param operatorShare The share of rewards given to the operator, in ppm. event StakingPoolCreated( bytes32 poolId, - address operatorAddress, + address operator, uint32 operatorShare ); @@ -148,7 +148,7 @@ interface IStakingEvents { /// @param oldOperatorShare Previous share of rewards owned by operator. /// @param newOperatorShare Newly decreased share of rewards owned by operator. event OperatorShareDecreased( - bytes32 poolId, + bytes32 indexed poolId, uint32 oldOperatorShare, uint32 newOperatorShare ); diff --git a/contracts/staking/contracts/src/interfaces/IStakingPoolRewardVault.sol b/contracts/staking/contracts/src/interfaces/IStakingPoolRewardVault.sol index cbecee1f36..2653ce4154 100644 --- a/contracts/staking/contracts/src/interfaces/IStakingPoolRewardVault.sol +++ b/contracts/staking/contracts/src/interfaces/IStakingPoolRewardVault.sol @@ -38,23 +38,11 @@ interface IStakingPoolRewardVault { /// @param member of the pool. /// @param poolId The pool the reward was deposited for. event PoolRewardTransferredToEthVault( - bytes32 poolId, - address member, + bytes32 indexed poolId, + address indexed member, uint256 amount ); - /// @dev Emitted when the eth vault is changed - /// @param newEthVault address of new Eth vault. - event EthVaultChanged( - address newEthVault - ); - - /// @dev Sets the Eth Vault. - /// Note that only the contract owner can call this. - /// @param ethVaultAddress Address of the Eth Vault. - function setEthVault(address ethVaultAddress) - external; - /// @dev Deposit an amount of ETH (`msg.value`) for `poolId` into the vault. /// Note that this is only callable by the staking contract. /// @param poolId that owns the ETH. @@ -65,11 +53,14 @@ interface IStakingPoolRewardVault { /// @dev Withdraw some amount in ETH of a pool member. /// Note that this is only callable by the staking contract. /// @param poolId Unique Id of pool. + /// @param member of pool to transfer funds to. /// @param amount Amount in ETH to transfer. + /// @param ethVaultAddress address of Eth Vault to send rewards to. function transferToEthVault( bytes32 poolId, address member, - uint256 amount + uint256 amount, + address ethVaultAddress ) external; diff --git a/contracts/staking/contracts/src/interfaces/IStructs.sol b/contracts/staking/contracts/src/interfaces/IStructs.sol index 46880b473f..cdd4aec185 100644 --- a/contracts/staking/contracts/src/interfaces/IStructs.sol +++ b/contracts/staking/contracts/src/interfaces/IStructs.sol @@ -96,7 +96,7 @@ interface IStructs { IStructs.Fraction cumulativeReward; } - /// @dev Holds the balances and other data for a staking pool. + /// @dev Holds the metadata for a staking pool. /// @param initialzed True iff the balance struct is initialized. /// @param operator of the pool. /// @param operatorShare Fraction of the total balance owned by the operator, in ppm. diff --git a/contracts/staking/contracts/src/libs/LibStakingRichErrors.sol b/contracts/staking/contracts/src/libs/LibStakingRichErrors.sol index 885e5d58a8..b0026eed36 100644 --- a/contracts/staking/contracts/src/libs/LibStakingRichErrors.sol +++ b/contracts/staking/contracts/src/libs/LibStakingRichErrors.sol @@ -233,7 +233,7 @@ library LibStakingRichErrors { function OnlyCallableByPoolOperatorError( address senderAddress, - address poolOperatorAddress + address operator ) internal pure @@ -242,13 +242,13 @@ library LibStakingRichErrors { return abi.encodeWithSelector( ONLY_CALLABLE_BY_POOL_OPERATOR_ERROR_SELECTOR, senderAddress, - poolOperatorAddress + operator ); } function OnlyCallableByPoolOperatorOrMakerError( address senderAddress, - address poolOperatorAddress, + address operator, address makerAddress ) internal @@ -258,7 +258,7 @@ library LibStakingRichErrors { return abi.encodeWithSelector( ONLY_CALLABLE_BY_POOL_OPERATOR_OR_MAKER_ERROR_SELECTOR, senderAddress, - poolOperatorAddress, + operator, makerAddress ); } diff --git a/contracts/staking/contracts/src/stake/MixinStake.sol b/contracts/staking/contracts/src/stake/MixinStake.sol index 9969652ac2..908cf9ba32 100644 --- a/contracts/staking/contracts/src/stake/MixinStake.sol +++ b/contracts/staking/contracts/src/stake/MixinStake.sol @@ -21,12 +21,17 @@ pragma experimental ABIEncoderV2; import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; import "../staking_pools/MixinStakingPoolRewards.sol"; +import "../staking_pools/MixinStakingPool.sol"; import "../libs/LibStakingRichErrors.sol"; /// @dev This mixin contains logic for managing ZRX tokens and Stake. contract MixinStake is - MixinStakingPoolRewards + MixinStorage, + MixinStakingPoolMakers, + MixinStakingPoolRewards, + MixinStakingPool + { using LibSafeMath for uint256; @@ -162,15 +167,8 @@ contract MixinStake is ) private { - // revert if pool with given poolId doesn't exist - if (rewardVault.operatorOf(poolId) == NIL_ADDRESS) { - LibRichErrors.rrevert( - LibStakingRichErrors.PoolExistenceError( - poolId, - false - ) - ); - } + // sanity check the pool we're delegating to exists + _assertStakingPoolExists(poolId); // cache amount delegated to pool by owner IStructs.StoredBalance memory initDelegatedStakeToPoolByOwner = _loadUnsyncedBalance(_delegatedStakeToPoolByOwner[owner][poolId]); @@ -197,15 +195,8 @@ contract MixinStake is ) private { - // revert if pool with given poolId doesn't exist - if (rewardVault.operatorOf(poolId) == NIL_ADDRESS) { - LibRichErrors.rrevert( - LibStakingRichErrors.PoolExistenceError( - poolId, - false - ) - ); - } + // sanity check the pool we're undelegating from exists + _assertStakingPoolExists(poolId); // cache amount delegated to pool by owner IStructs.StoredBalance memory initDelegatedStakeToPoolByOwner = _loadUnsyncedBalance(_delegatedStakeToPoolByOwner[owner][poolId]); diff --git a/contracts/staking/contracts/src/staking_pools/MixinEthVault.sol b/contracts/staking/contracts/src/staking_pools/MixinEthVault.sol deleted file mode 100644 index 1a022a96b9..0000000000 --- a/contracts/staking/contracts/src/staking_pools/MixinEthVault.sol +++ /dev/null @@ -1,81 +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 "../interfaces/IStakingEvents.sol"; -import "../interfaces/IEthVault.sol"; -import "../immutable/MixinStorage.sol"; - - -/// @dev This mixin contains logic for managing and interfacing with the Eth Vault. -/// (see vaults/EthVault.sol). -contract MixinEthVault is - IStakingEvents, - MixinConstants, - Ownable, - MixinStorage -{ - - /// @dev Set the Eth Vault. - /// @param ethVaultAddress Address of the Eth Vault. - function setEthVault(address ethVaultAddress) - external - onlyOwner - { - ethVault = IEthVault(ethVaultAddress); - } - - /// @dev Return the current Eth Vault - /// @return Eth Vault - function getEthVault() - public - view - returns (address) - { - return address(ethVault); - } - - /// @dev Transfers operator reward to the ETH vault. - /// @param poolId Unique Id of pool to transfer reward for, - /// @param operator of the pool. - /// @param amount of ETH to transfer. - function _transferOperatorRewardToEthVault( - bytes32 poolId, - address operator, - uint256 amount - ) - internal - { - // sanity check on eth vault - IEthVault _ethVault = ethVault; - if (address(_ethVault) == address(0)) { - LibRichErrors.rrevert( - LibStakingRichErrors.EthVaultNotSetError() - ); - } - - // perform transfer - _ethVault.depositFor.value(amount)(operator); - emit OperatorRewardTransferredToEthVault( - poolId, - operator, - amount - ); - } -} diff --git a/contracts/staking/contracts/src/staking_pools/MixinStakingPool.sol b/contracts/staking/contracts/src/staking_pools/MixinStakingPool.sol index 62719886ca..2b3a134b0b 100644 --- a/contracts/staking/contracts/src/staking_pools/MixinStakingPool.sol +++ b/contracts/staking/contracts/src/staking_pools/MixinStakingPool.sol @@ -28,6 +28,8 @@ import "./MixinStakingPoolMakers.sol"; contract MixinStakingPool is + MixinStorage, + MixinStakingPoolMakers, MixinStakingPoolRewards { using LibSafeMath for uint256; @@ -85,10 +87,10 @@ contract MixinStakingPool is external { // load pool and assert that we can decrease - IStructs.Pool memory pool = poolById[poolId]; + uint32 currentOperatorShare = poolById[poolId].operatorShare; _assertNewOperatorShare( poolId, - pool.operatorShare, + currentOperatorShare, newOperatorShare ); @@ -96,22 +98,11 @@ contract MixinStakingPool is poolById[poolId].operatorShare = newOperatorShare; emit OperatorShareDecreased( poolId, - pool.operatorShare, + currentOperatorShare, newOperatorShare ); } - /// @dev Returns the staking pool with `poolId` - /// @param poolId Unique id of pool - /// @return operator Operator of the pool - function getStakingPool(bytes32 poolId) - external - view - returns (IStructs.Pool memory) - { - return poolById[poolId]; - } - /// @dev Returns the unique id that will be assigned to the next pool that is created. /// @return Pool id. function getNextStakingPoolId() @@ -122,6 +113,14 @@ contract MixinStakingPool is return nextPoolId; } + function getStakingPool(bytes32 poolId) + public + view + returns (IStructs.Pool memory) + { + return poolById[poolId]; + } + /// @dev Computes the unique id that comes after the input pool id. /// @param poolId Unique id of pool. /// @return Next pool id after input pool. @@ -133,6 +132,22 @@ contract MixinStakingPool is return bytes32(uint256(poolId).safeAdd(POOL_ID_INCREMENT_AMOUNT)); } + function _assertStakingPoolExists(bytes32 poolId) + internal + view + returns (bool) + { + if (poolById[poolId].operator == NIL_ADDRESS) { + // we use the pool's operator as a proxy for its existence + LibRichErrors.rrevert( + LibStakingRichErrors.PoolExistenceError( + poolId, + false + ) + ); + } + } + function _assertNewOperatorShare( bytes32 poolId, uint32 currentOperatorShare, diff --git a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolMakers.sol b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolMakers.sol index f9c5de4031..71e01399e7 100644 --- a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolMakers.sol +++ b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolMakers.sol @@ -19,34 +19,27 @@ pragma solidity ^0.5.9; pragma experimental ABIEncoderV2; -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/IStructs.sol"; import "../interfaces/IStakingEvents.sol"; -import "../immutable/MixinConstants.sol"; import "../immutable/MixinStorage.sol"; -import "./MixinStakingPoolRewards.sol"; import "./MixinStakingPoolModifiers.sol"; /// @dev This mixin contains logic for staking pools. contract MixinStakingPoolMakers is IStakingEvents, - MixinConstants, - Ownable, MixinStorage, - MixinZrxVault, - MixinStakingPoolRewardVault, - MixinScheduler, - MixinStakeStorage, - MixinStakeBalances, - MixinStakingPoolRewards, MixinStakingPoolModifiers { using LibSafeMath for uint256; + using LibSafeDowncast for uint256; + /// @dev Allows caller to join a staking pool if already assigned. + /// @param poolId Unique id of pool. function joinStakingPoolAsMaker( bytes32 poolId ) diff --git a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolModifiers.sol b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolModifiers.sol index 5f730e3d4b..71be9b68dc 100644 --- a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolModifiers.sol +++ b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolModifiers.sol @@ -19,39 +19,21 @@ pragma solidity ^0.5.9; pragma experimental ABIEncoderV2; -import "@0x/contracts-utils/contracts/src/LibRichErrors.sol"; -import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; -import "../libs/LibStakingRichErrors.sol"; -import "../interfaces/IStructs.sol"; -import "../interfaces/IStakingEvents.sol"; -import "../immutable/MixinConstants.sol"; import "../immutable/MixinStorage.sol"; -import "./MixinStakingPoolRewards.sol"; contract MixinStakingPoolModifiers is - IStakingEvents, - MixinConstants, - Ownable, - MixinStorage, - MixinZrxVault, - MixinStakingPoolRewardVault, - MixinScheduler, - MixinStakeStorage, - MixinStakeBalances, - MixinStakingPoolRewards + MixinStorage { - using LibSafeMath for uint256; - /// @dev Asserts that the sender is the operator of the input pool. /// @param poolId Pool sender must be operator of. modifier onlyStakingPoolOperator(bytes32 poolId) { - address poolOperator = poolById[poolId].operator; - if (msg.sender != poolOperator) { + address operator = poolById[poolId].operator; + if (msg.sender != operator) { LibRichErrors.rrevert(LibStakingRichErrors.OnlyCallableByPoolOperatorError( msg.sender, - poolOperator + operator )); } @@ -62,15 +44,15 @@ contract MixinStakingPoolModifiers is /// @param poolId Pool sender must be operator of. /// @param makerAddress Address of a maker in the pool. modifier onlyStakingPoolOperatorOrMaker(bytes32 poolId, address makerAddress) { - address poolOperator; + address operator; if ( msg.sender != makerAddress && - msg.sender != (poolOperator = poolById[poolId].operator) + msg.sender != (operator = poolById[poolId].operator) ) { LibRichErrors.rrevert( LibStakingRichErrors.OnlyCallableByPoolOperatorOrMakerError( msg.sender, - poolOperator, + operator, makerAddress ) ); diff --git a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewardVault.sol b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewardVault.sol index 90f2e38c1d..703e115aff 100644 --- a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewardVault.sol +++ b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewardVault.sol @@ -58,15 +58,8 @@ contract MixinStakingPoolRewardVault is function _depositIntoStakingPoolRewardVault(uint256 amount) internal { - // cast to payable and sanity check + // cast to payable then transfer address payable rewardVaultAddress = address(uint160(address(rewardVault))); - if (rewardVaultAddress == NIL_ADDRESS) { - LibRichErrors.rrevert( - LibStakingRichErrors.RewardVaultNotSetError() - ); - } - - // perform transfer rewardVaultAddress.transfer(amount); } @@ -81,15 +74,11 @@ contract MixinStakingPoolRewardVault is ) internal { - // sanity check - IStakingPoolRewardVault _rewardVault = rewardVault; - if (address(_rewardVault) == NIL_ADDRESS) { - LibRichErrors.rrevert( - LibStakingRichErrors.RewardVaultNotSetError() - ); - } - - // perform transfer - _rewardVault.transferToEthVault(poolId, member, amount); + rewardVault.transferToEthVault( + poolId, + member, + amount, + address(ethVault) + ); } } diff --git a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol index 72fe0836e2..7c2a3dd976 100644 --- a/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol +++ b/contracts/staking/contracts/src/staking_pools/MixinStakingPoolRewards.sol @@ -19,10 +19,10 @@ pragma solidity ^0.5.9; pragma experimental ABIEncoderV2; +import "@0x/contracts-exchange-libs/contracts/src/LibMath.sol"; import "@0x/contracts-utils/contracts/src/LibFractions.sol"; import "@0x/contracts-utils/contracts/src/LibSafeMath.sol"; import "./MixinCumulativeRewards.sol"; -import "./MixinEthVault.sol"; contract MixinStakingPoolRewards is @@ -38,16 +38,16 @@ contract MixinStakingPoolRewards is { address member = msg.sender; - IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner = _loadAndSyncBalance(delegatedStakeToPoolByOwner[member][poolId]); + IStructs.StoredBalance memory finalDelegatedStakeToPoolByOwner = _loadAndSyncBalance(_delegatedStakeToPoolByOwner[member][poolId]); _syncRewardsForDelegator( poolId, member, - _loadUnsyncedBalance(delegatedStakeToPoolByOwner[member][poolId]), // initial balance + _loadUnsyncedBalance(_delegatedStakeToPoolByOwner[member][poolId]), // initial balance finalDelegatedStakeToPoolByOwner ); // update stored balance with synchronized version; this prevents redundant withdrawals. - delegatedStakeToPoolByOwner[member][poolId] = finalDelegatedStakeToPoolByOwner; + _delegatedStakeToPoolByOwner[member][poolId] = finalDelegatedStakeToPoolByOwner; } /// @dev Computes the reward balance in ETH of a specific member of a pool. @@ -104,10 +104,12 @@ contract MixinStakingPoolRewards is ); } - /// @dev Records a reward for delegators. This adds to the `_cumulativeRewardsByPool`. + /// @dev Handles a pool's reward. This will deposit the operator's reward into the Eth Vault and + /// the members' reward into the Staking Pool Vault. It also records the cumulative reward, which + /// is used to compute each delegator's portion of the members' reward. /// @param poolId Unique Id of pool. - /// @param reward to record for delegators. - /// @param amountOfDelegatedStake the amount of delegated stake that will split this reward. + /// @param reward received by the pool. + /// @param amountOfDelegatedStake the amount of delegated stake that will split the reward. /// @param epoch at which this was earned. function _handleStakingPoolReward( bytes32 poolId, @@ -289,4 +291,24 @@ contract MixinStakingPoolRewards is ); } } + + /// @dev Transfers operator reward to the ETH vault. + /// @param poolId Unique Id of pool to transfer reward for, + /// @param operator of the pool. + /// @param amount of ETH to transfer. + function _transferOperatorRewardToEthVault( + bytes32 poolId, + address operator, + uint256 amount + ) + private + { + // perform transfer and notify + ethVault.depositFor.value(amount)(operator); + emit OperatorRewardTransferredToEthVault( + poolId, + operator, + amount + ); + } } diff --git a/contracts/staking/contracts/src/vaults/StakingPoolRewardVault.sol b/contracts/staking/contracts/src/vaults/StakingPoolRewardVault.sol index 5013f7a729..3fdcaa1e92 100644 --- a/contracts/staking/contracts/src/vaults/StakingPoolRewardVault.sol +++ b/contracts/staking/contracts/src/vaults/StakingPoolRewardVault.sol @@ -38,21 +38,7 @@ contract StakingPoolRewardVault is using LibSafeMath for uint256; // mapping from poolId to Pool metadata - mapping (bytes32 => uint256) internal balanceByPoolId; - - // address of ether vault - IEthVault internal _ethVault; - - /// @dev Sets the Eth Vault. - /// Note that only the contract owner can call this. - /// @param ethVaultAddress Address of the Eth Vault. - function setEthVault(address ethVaultAddress) - external - onlyOwner - { - _ethVault = IEthVault(ethVaultAddress); - emit EthVaultChanged(ethVaultAddress); - } + mapping (bytes32 => uint256) internal _balanceByPoolId; /// @dev Deposit an amount of ETH (`msg.value`) for `poolId` into the vault. /// Note that this is only callable by the staking contract. @@ -60,35 +46,29 @@ contract StakingPoolRewardVault is function depositFor(bytes32 poolId) external payable - onlyStakingContract + onlyStakingProxy { - balanceByPoolId[poolId] = balanceByPoolId[poolId].safeAdd(msg.value); + _balanceByPoolId[poolId] = _balanceByPoolId[poolId].safeAdd(msg.value); emit EthDepositedIntoVault(msg.sender, poolId, msg.value); } /// @dev Withdraw some amount in ETH of a pool member. /// Note that this is only callable by the staking contract. /// @param poolId Unique Id of pool. + /// @param member of pool to transfer funds to. /// @param amount Amount in ETH to transfer. + /// @param ethVaultAddress address of Eth Vault to send rewards to. function transferToEthVault( bytes32 poolId, address member, - uint256 amount + uint256 amount, + address ethVaultAddress ) external onlyStakingProxy { - // sanity check on eth vault - IEthVault _ethVault = ethVault; - if (address(_ethVault) == address(0)) { - LibRichErrors.rrevert( - LibStakingRichErrors.EthVaultNotSetError() - ); - } - - // perform transfer - balanceByPoolId[poolId] = balanceByPoolId[poolId].safeSub(amount); - _ethVault.depositFor.value(amount)(member); + _balanceByPoolId[poolId] = _balanceByPoolId[poolId].safeSub(amount); + IEthVault(ethVaultAddress).depositFor.value(amount)(member); emit PoolRewardTransferredToEthVault( poolId, member, @@ -103,6 +83,6 @@ contract StakingPoolRewardVault is view returns (uint256) { - return balanceByPoolId[poolId]; + return _balanceByPoolId[poolId]; } } diff --git a/contracts/staking/test/actors/pool_operator_actor.ts b/contracts/staking/test/actors/pool_operator_actor.ts index a95adf8117..86d6078c88 100644 --- a/contracts/staking/test/actors/pool_operator_actor.ts +++ b/contracts/staking/test/actors/pool_operator_actor.ts @@ -35,10 +35,10 @@ export class PoolOperatorActor extends BaseActor { ); expect(poolIdOfMaker, 'pool id of maker').to.be.equal(poolId); // check the number of makers in the pool - const numMakersAfterRemoving = await this._stakingApiWrapper.stakingContract.numMakersByPoolId.callAsync( + const pool = await this._stakingApiWrapper.stakingContract.getStakingPool.callAsync( poolId, ); - expect(numMakersAfterRemoving, 'number of makers in pool').to.be.bignumber.equal(1); + expect(pool.numberOfMakers, 'number of makers in pool').to.be.bignumber.equal(1); } return poolId; } diff --git a/contracts/staking/test/pools_test.ts b/contracts/staking/test/pools_test.ts index 79995fb1d2..71f6e98163 100644 --- a/contracts/staking/test/pools_test.ts +++ b/contracts/staking/test/pools_test.ts @@ -138,8 +138,8 @@ blockchainTests('Staking Pool Management', env => { ); // check the number of makers in the pool - let numMakers = await stakingApiWrapper.stakingContract.numMakersByPoolId.callAsync(poolId); - expect(numMakers, 'number of makers in pool after adding').to.be.bignumber.equal(3); + let pool = await stakingApiWrapper.stakingContract.getStakingPool.callAsync(poolId); + expect(pool.numberOfMakers, 'number of makers in pool after adding').to.be.bignumber.equal(3); // remove maker from pool await Promise.all( @@ -149,8 +149,8 @@ blockchainTests('Staking Pool Management', env => { ); // check the number of makers in the pool - numMakers = await stakingApiWrapper.stakingContract.numMakersByPoolId.callAsync(poolId); - expect(numMakers, 'number of makers in pool after removing').to.be.bignumber.equal(0); + pool = await stakingApiWrapper.stakingContract.getStakingPool.callAsync(poolId); + expect(pool.numberOfMakers, 'number of makers in pool after removing').to.be.bignumber.equal(0); }); it('Should fail if maker already assigned to another pool tries to join', async () => { // test parameters @@ -337,8 +337,8 @@ blockchainTests('Staking Pool Management', env => { ); // check the number of makers in the pool - const numMakers = await stakingApiWrapper.stakingContract.numMakersByPoolId.callAsync(poolId); - expect(numMakers, 'number of makers in pool').to.be.bignumber.equal( + const pool = await stakingApiWrapper.stakingContract.getStakingPool.callAsync(poolId); + expect(pool.numberOfMakers, 'number of makers in pool').to.be.bignumber.equal( stakingConstants.DEFAULT_PARAMS.maximumMakersInPool, ); diff --git a/contracts/staking/test/rewards_test.ts b/contracts/staking/test/rewards_test.ts index cf536689e0..cb71829ca4 100644 --- a/contracts/staking/test/rewards_test.ts +++ b/contracts/staking/test/rewards_test.ts @@ -113,10 +113,12 @@ blockchainTests.resets('Testing Rewards', env => { ? _expectedEndBalances.poolRewardVaultBalance : ZERO, }; - const pool = await stakingApiWrapper.rewardVaultContract.poolById.callAsync(poolId); - const operatorBalance = pool[1]; - const membersBalance = pool[2]; + /* + const pool = await stakingApiWrapper.stakingContract.getStakingPool.callAsync(poolId); + const operatorBalance = pool[2]; + const membersBalance = pool[3]; const poolBalances = { poolBalance: operatorBalance.plus(membersBalance), operatorBalance, membersBalance }; + */ const finalEndBalancesAsArray = await Promise.all([ // staker 1 stakingApiWrapper.stakingContract.computeRewardBalanceOfDelegator.callAsync( diff --git a/contracts/staking/test/utils/api_wrapper.ts b/contracts/staking/test/utils/api_wrapper.ts index 253d25c47e..941dac3a73 100644 --- a/contracts/staking/test/utils/api_wrapper.ts +++ b/contracts/staking/test/utils/api_wrapper.ts @@ -208,16 +208,6 @@ export async function deployAndConfigureContractsAsync( rewardVaultContract.address, zrxVaultContract.address, ); - // set eth vault in staking contract - const setEthVaultCalldata = stakingContract.setEthVault.getABIEncodedTransactionData(ethVaultContract.address); - const setEthVaultCalldataTxData = { - from: ownerAddress, - to: stakingProxyContract.address, - data: setEthVaultCalldata, - }; - await env.web3Wrapper.awaitTransactionSuccessAsync( - await env.web3Wrapper.sendTransactionAsync(setEthVaultCalldataTxData), - ); // configure erc20 proxy to accept calls from zrx vault await erc20ProxyContract.addAuthorizedAddress.awaitTransactionSuccessAsync(zrxVaultContract.address); @@ -225,8 +215,6 @@ export async function deployAndConfigureContractsAsync( await zrxVaultContract.setStakingProxy.awaitTransactionSuccessAsync(stakingProxyContract.address); // set staking proxy contract in reward vault await rewardVaultContract.setStakingProxy.awaitTransactionSuccessAsync(stakingProxyContract.address); - // set the eth vault in the reward vault - await rewardVaultContract.setEthVault.awaitTransactionSuccessAsync(ethVaultContract.address); return new StakingApiWrapper( env, ownerAddress,