From 4e0b671bd8c5f5ae02fa744fd0dc110041d83e8b Mon Sep 17 00:00:00 2001 From: Elena Date: Thu, 6 Apr 2023 16:21:01 +0300 Subject: [PATCH] Integration test catastrophic mode in staking v3 (#691) * Integration test catastrophic mode * Update test for withdrawals in catastrophic mode * Test withdrawing delegator rewards work in catastrophic mode * Test top stakers can withdraw * Test more delegators rewards withdrawals * Add claiming rewards for a pool owner * Fix for forge coverage --- .../test/integration/GovernanceE2E.t.sol | 123 ++++++++++- .../governance/test/mocks/IStakingMock.sol | 192 +++++++++++++----- .../governance/test/mocks/IStorageMock.sol | 49 +++++ contracts/governance/test/mocks/IStructs.sol | 92 +++++++++ .../governance/test/mocks/IZrxVaultMock.sol | 83 ++++++++ 5 files changed, 482 insertions(+), 57 deletions(-) create mode 100644 contracts/governance/test/mocks/IStorageMock.sol create mode 100644 contracts/governance/test/mocks/IStructs.sol create mode 100644 contracts/governance/test/mocks/IZrxVaultMock.sol diff --git a/contracts/governance/test/integration/GovernanceE2E.t.sol b/contracts/governance/test/integration/GovernanceE2E.t.sol index 45516bd6b4..07dfdc5440 100644 --- a/contracts/governance/test/integration/GovernanceE2E.t.sol +++ b/contracts/governance/test/integration/GovernanceE2E.t.sol @@ -23,6 +23,7 @@ import "@openzeppelin/token/ERC20/IERC20.sol"; import "../mocks/IZeroExMock.sol"; import "../mocks/IZrxTreasuryMock.sol"; import "../mocks/IStakingMock.sol"; +import "../mocks/IZrxVaultMock.sol"; import "../BaseTest.t.sol"; import "../../src/ZRXWrappedToken.sol"; import "../../src/ZeroExVotes.sol"; @@ -34,6 +35,11 @@ contract GovernanceE2ETest is BaseTest { uint256 internal mainnetFork; string internal MAINNET_RPC_URL = vm.envString("MAINNET_RPC_URL"); + struct DelegatorPool { + address delegator; + bytes32 pool; + } + address internal constant ZRX_TOKEN = 0xE41d2489571d322189246DaFA5ebDe1F4699F498; address internal constant MATIC_TOKEN = 0x7D1AfA7B718fb893dB30A3aBc0Cfc608AaCfeBB0; address internal constant WCELO_TOKEN = 0xE452E6Ea2dDeB012e20dB73bf5d3863A3Ac8d77a; @@ -42,10 +48,25 @@ contract GovernanceE2ETest is BaseTest { address internal constant EXCHANGE_PROXY = 0xDef1C0ded9bec7F1a1670819833240f027b25EfF; address internal constant EXCHANGE_GOVERNOR = 0x618F9C67CE7Bf1a50afa1E7e0238422601b0ff6e; address internal constant TREASURY = 0x0bB1810061C2f5b2088054eE184E6C79e1591101; - address internal constant STAKING = 0xa26e80e7Dea86279c6d778D702Cc413E6CFfA777; - address internal staker = 0x5265Bde27F57E738bE6c1F6AB3544e82cdc92a8f; - bytes32 internal stakerPool = 0x0000000000000000000000000000000000000000000000000000000000000032; - bytes32[] internal staker_operated_poolIds = [stakerPool]; + address internal constant STAKING = 0xa26e80e7Dea86279c6d778D702Cc413E6CFfA777; // Holds ~$262K in WETH for rewards + address internal constant ZRX_VAULT = 0xBa7f8b5fB1b19c1211c5d49550fcD149177A5Eaf; // Holds ~$10m in staked ZRX + address internal constant STAKING_AND_VAULT_OWNER = 0x7D3455421BbC5Ed534a83c88FD80387dc8271392; + + address internal staker1 = 0x885c327cAD2aebb969dfaAb4c928B73CA17e3887; + address internal staker2 = 0x03c823e96F6964076C118395F08a2D7edF0f8a8C; + + address[] internal topStakers = [ + 0x5775afA796818ADA27b09FaF5c90d101f04eF600, + 0xE1bdcd3B70e077D2d66ADcbe78be3941F0BF380B, + 0xcCa71809E8870AFEB72c4720d0fe50d5C3230e05, + 0x828FD91d3e3a9FFa6305e78B9aE2Cfbc5B5D9f6B, + 0x4A36C3DA5d367B148d17265e7d7feafcf8fb4a21, + 0xEeff6fd32DeaFe1a9d3258A51c7F952F9FF0B2Ce, + 0x1D0738b927dFCBFBD59A9F0944BbD1860d3B9248, + 0x0C073E7248C1b548a08b27dD3af5D0f39c774280, + 0xA178FF321335BB777A7E21A56376592F69556b9c, + 0xD06CfBb59d2e8918F84D99d981039d7706DCA288 + ]; // voting power 1500000e18 address internal voter1 = 0x292c6DAE7417B3D31d8B6e1d2EeA0258d14C4C4b; @@ -89,7 +110,9 @@ contract GovernanceE2ETest is BaseTest { IZeroExMock internal exchange; IZrxTreasuryMock internal treasury; + IZrxVaultMock internal vault; IStakingMock internal staking; + IERC20 internal weth; ZRXWrappedToken internal wToken; ZeroExVotes internal votes; @@ -109,7 +132,9 @@ contract GovernanceE2ETest is BaseTest { exchange = IZeroExMock(payable(EXCHANGE_PROXY)); treasury = IZrxTreasuryMock(TREASURY); + vault = IZrxVaultMock(ZRX_VAULT); staking = IStakingMock(STAKING); + weth = IERC20(staking.getWethContract()); address protocolGovernorAddress; address treasuryGovernorAddress; @@ -142,7 +167,7 @@ contract GovernanceE2ETest is BaseTest { uint256 currentEpoch = staking.currentEpoch(); uint256 executionEpoch = currentEpoch + 2; - vm.startPrank(staker); + vm.startPrank(voter3); IZrxTreasuryMock.ProposedAction[] memory actions = new IZrxTreasuryMock.ProposedAction[](4); @@ -182,7 +207,7 @@ contract GovernanceE2ETest is BaseTest { actions, executionEpoch, "Z-5 Migrate to new treasury governor", - staker_operated_poolIds + voter3_operated_poolIds ); // Once a proposal is created, it becomes open for voting at the epoch after next (currentEpoch + 2) @@ -243,4 +268,90 @@ contract GovernanceE2ETest is BaseTest { uint256 wyvBalanceNewTreasury = wyvToken.balanceOf(address(treasuryGovernor)); assertEq(wyvBalanceNewTreasury, wyvBalance); } + + // Test entering catastrophic failure mode on the zrx vault to decomission v3 staking + function testCatastrophicFailureModeOnStaking() public { + DelegatorPool[5] memory delegatorPools = [ + DelegatorPool( + 0x0ee1F33A2EB0da738FdF035C48d62d75e996a3bd, + 0x0000000000000000000000000000000000000000000000000000000000000016 + ), + DelegatorPool( + 0xcAb3d8cBBb3dA1bDabfB003B9C828B27a821717f, + 0x0000000000000000000000000000000000000000000000000000000000000017 + ), + DelegatorPool( + 0x7f88b00Db27a500fBfA7EbC9c3CaA2Dea6F59d5b, + 0x0000000000000000000000000000000000000000000000000000000000000014 + ), + DelegatorPool( + 0xcE266E6123B682f7A7388097e2155b5379D9AC78, + 0x0000000000000000000000000000000000000000000000000000000000000014 + ), + DelegatorPool( + 0xBa4f44E774158408E2DC6c5cb65BC995F0a89180, // pool operator + 0x0000000000000000000000000000000000000000000000000000000000000017 + ) + ]; + + // Enter catastrophic failure mode on the zrx vault + vm.prank(STAKING_AND_VAULT_OWNER); + vault.enterCatastrophicFailure(); + vm.stopPrank(); + + // Stakes can still be withdrawn + // staker1 withdraws + uint256 stake1 = vault.balanceOf(staker1); + uint256 balance1 = token.balanceOf(staker1); + assertGt(stake1, 0); + + vm.prank(staker1); + vault.withdrawAllFrom(staker1); + vm.stopPrank(); + + assertEq(vault.balanceOf(staker1), 0); + assertEq(token.balanceOf(staker1), stake1 + balance1); + + // staker2 withdraws + uint256 stake2 = vault.balanceOf(staker2); + uint256 balance2 = token.balanceOf(staker2); + assertGt(stake2, 0); + + vm.prank(staker2); + vault.withdrawAllFrom(staker2); + vm.stopPrank(); + + assertEq(vault.balanceOf(staker2), 0); + assertEq(token.balanceOf(staker2), stake2 + balance2); + + // Test top stakers can withdraw + for (uint256 i = 0; i < topStakers.length; i++) { + address staker = topStakers[i]; + uint256 stake = vault.balanceOf(staker); + uint256 balance = token.balanceOf(staker); + assertGt(stake, 0); + + vm.prank(staker); + vault.withdrawAllFrom(staker); + vm.stopPrank(); + + assertEq(vault.balanceOf(staker), 0); + assertEq(token.balanceOf(staker), stake + balance); + } + + // Delegator can withdraw rewards + for (uint256 i = 0; i < delegatorPools.length; i++) { + address delegator = delegatorPools[i].delegator; + bytes32 pool = delegatorPools[i].pool; + uint256 reward = staking.computeRewardBalanceOfDelegator(pool, delegator); + assertGt(reward, 0); + uint256 balanceBeforeReward = weth.balanceOf(delegator); + + vm.prank(delegator); + staking.withdrawDelegatorRewards(pool); + vm.stopPrank(); + + assertEq(weth.balanceOf(delegator), balanceBeforeReward + reward); + } + } } diff --git a/contracts/governance/test/mocks/IStakingMock.sol b/contracts/governance/test/mocks/IStakingMock.sol index d4198ab8d2..8b5aca2e3b 100644 --- a/contracts/governance/test/mocks/IStakingMock.sol +++ b/contracts/governance/test/mocks/IStakingMock.sol @@ -17,36 +17,16 @@ */ +import "./IZrxVaultMock.sol"; +import "./IStructs.sol"; +import "./IStorageMock.sol"; + pragma solidity ^0.8.19; -interface IStakingMock { - /// @dev Statuses that stake can exist in. - /// Any stake can be (re)delegated effective at the next epoch - /// Undelegated stake can be withdrawn if it is available in both the current and next epoch - enum StakeStatus { - UNDELEGATED, - DELEGATED - } - - /// @dev Encapsulates a balance for the current and next epochs. - /// Note that these balances may be stale if the current epoch - /// is greater than `currentEpoch`. - /// @param currentEpoch The current epoch - /// @param currentEpochBalance Balance in the current epoch. - /// @param nextEpochBalance Balance in `currentEpoch+1`. - struct StoredBalance { - uint64 currentEpoch; - uint96 currentEpochBalance; - uint96 nextEpochBalance; - } - - /// @dev Holds the metadata for a staking pool. - /// @param operator Operator of the pool. - /// @param operatorShare Fraction of the total balance owned by the operator, in ppm. - struct Pool { - address operator; - uint32 operatorShare; - } +interface IStakingMock is IStorageMock { + /// @dev Adds a new exchange address + /// @param addr Address of exchange contract to add + function addExchangeAddress(address addr) external; /// @dev Create a new staking pool. The sender will be the operator of this pool. /// Note that an operator must be payable. @@ -55,26 +35,105 @@ interface IStakingMock { /// @return poolId The unique pool id generated for this pool. function createStakingPool(uint32 operatorShare, bool addOperatorAsMaker) external returns (bytes32 poolId); - /// @dev Returns the current staking epoch number. - /// @return epoch The current epoch. - function currentEpoch() external view returns (uint256 epoch); + /// @dev Decreases the operator share for the given pool (i.e. increases pool rewards for members). + /// @param poolId Unique Id of pool. + /// @param newOperatorShare The newly decreased percentage of any rewards owned by the operator. + function decreaseStakingPoolOperatorShare(bytes32 poolId, uint32 newOperatorShare) external; - /// @dev Returns the time (in seconds) at which the current staking epoch started. - /// @return startTime The start time of the current epoch, in seconds. - function currentEpochStartTimeInSeconds() external view returns (uint256 startTime); + /// @dev Begins a new epoch, preparing the prior one for finalization. + /// Throws if not enough time has passed between epochs or if the + /// previous epoch was not fully finalized. + /// @return numPoolsToFinalize The number of unfinalized pools. + function endEpoch() external returns (uint256); - /// @dev Returns the duration of an epoch in seconds. This value can be updated. - /// @return duration The duration of an epoch, in seconds. - function epochDurationInSeconds() external view returns (uint256 duration); + /// @dev Instantly finalizes a single pool that earned rewards in the previous + /// epoch, crediting it rewards for members and withdrawing operator's + /// rewards as WETH. This can be called by internal functions that need + /// to finalize a pool immediately. Does nothing if the pool is already + /// finalized or did not earn rewards in the previous epoch. + /// @param poolId The pool ID to finalize. + function finalizePool(bytes32 poolId) external; - /// @dev Returns a staking pool + /// @dev Initialize storage owned by this contract. + /// This function should not be called directly. + /// The StakingProxy contract will call it in `attachStakingContract()`. + function init() external; + + /// @dev Allows caller to join a staking pool as a maker. /// @param poolId Unique id of pool. - function getStakingPool(bytes32 poolId) external view returns (Pool memory); + function joinStakingPoolAsMaker(bytes32 poolId) external; + + /// @dev Moves stake between statuses: 'undelegated' or 'delegated'. + /// Delegated stake can also be moved between pools. + /// This change comes into effect next epoch. + /// @param from status to move stake out of. + /// @param to status to move stake into. + /// @param amount of stake to move. + function moveStake(IStructs.StakeInfo calldata from, IStructs.StakeInfo calldata to, uint256 amount) external; + + /// @dev Pays a protocol fee in ETH. + /// @param makerAddress The address of the order's maker. + /// @param payerAddress The address that is responsible for paying the protocol fee. + /// @param protocolFee The amount of protocol fees that should be paid. + function payProtocolFee(address makerAddress, address payerAddress, uint256 protocolFee) external payable; + + /// @dev Removes an existing exchange address + /// @param addr Address of exchange contract to remove + function removeExchangeAddress(address addr) external; + + /// @dev Set all configurable parameters at once. + /// @param _epochDurationInSeconds Minimum seconds between epochs. + /// @param _rewardDelegatedStakeWeight How much delegated stake is weighted vs operator stake, in ppm. + /// @param _minimumPoolStake Minimum amount of stake required in a pool to collect rewards. + /// @param _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. + /// @param _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. + function setParams( + uint256 _epochDurationInSeconds, + uint32 _rewardDelegatedStakeWeight, + uint256 _minimumPoolStake, + uint32 _cobbDouglasAlphaNumerator, + uint32 _cobbDouglasAlphaDenominator + ) external; + + /// @dev Stake ZRX tokens. Tokens are deposited into the ZRX Vault. + /// Unstake to retrieve the ZRX. Stake is in the 'Active' status. + /// @param amount of ZRX to stake. + function stake(uint256 amount) external; + + /// @dev Unstake. Tokens are withdrawn from the ZRX Vault and returned to + /// the staker. Stake must be in the 'undelegated' status in both the + /// current and next epoch in order to be unstaked. + /// @param amount of ZRX to unstake. + function unstake(uint256 amount) external; + + /// @dev Withdraws the caller's WETH rewards that have accumulated + /// until the last epoch. + /// @param poolId Unique id of pool. + function withdrawDelegatorRewards(bytes32 poolId) external; + + /// @dev Computes the reward balance in ETH of a specific member of a pool. + /// @param poolId Unique id of pool. + /// @param member The member of the pool. + /// @return reward Balance in ETH. + function computeRewardBalanceOfDelegator(bytes32 poolId, address member) external view returns (uint256 reward); + + /// @dev Computes the reward balance in ETH of the operator of a pool. + /// @param poolId Unique id of pool. + /// @return reward Balance in ETH. + function computeRewardBalanceOfOperator(bytes32 poolId) external view returns (uint256 reward); + + /// @dev Returns the earliest end time in seconds of this epoch. + /// The next epoch can begin once this time is reached. + /// Epoch period = [startTimeInSeconds..endTimeInSeconds) + /// @return Time in seconds. + function getCurrentEpochEarliestEndTimeInSeconds() external view returns (uint256); /// @dev Gets global stake for a given status. /// @param stakeStatus UNDELEGATED or DELEGATED /// @return balance Global stake for given status. - function getGlobalStakeByStatus(StakeStatus stakeStatus) external view returns (StoredBalance memory balance); + function getGlobalStakeByStatus( + IStructs.StakeStatus stakeStatus + ) external view returns (IStructs.StoredBalance memory balance); /// @dev Gets an owner's stake balances by status. /// @param staker Owner of stake. @@ -82,25 +141,56 @@ interface IStakingMock { /// @return balance Owner's stake balances for given status. function getOwnerStakeByStatus( address staker, - StakeStatus stakeStatus - ) external view returns (StoredBalance memory balance); + IStructs.StakeStatus stakeStatus + ) external view returns (IStructs.StoredBalance memory balance); - /// @dev Returns the total stake delegated to a specific staking pool, - /// across all members. - /// @param poolId Unique Id of pool. - /// @return balance Total stake delegated to pool. - function getTotalStakeDelegatedToPool(bytes32 poolId) external view returns (StoredBalance memory balance); + /// @dev Retrieves all configurable parameter values. + /// @return _epochDurationInSeconds Minimum seconds between epochs. + /// @return _rewardDelegatedStakeWeight How much delegated stake is weighted vs operator stake, in ppm. + /// @return _minimumPoolStake Minimum amount of stake required in a pool to collect rewards. + /// @return _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor. + /// @return _cobbDouglasAlphaDenominator Denominator for cobb douglas alpha factor. + function getParams() + external + view + returns ( + uint256 _epochDurationInSeconds, + uint32 _rewardDelegatedStakeWeight, + uint256 _minimumPoolStake, + uint32 _cobbDouglasAlphaNumerator, + uint32 _cobbDouglasAlphaDenominator + ); - /// @dev Returns the stake delegated to a specific staking pool, by a given staker. /// @param staker of stake. /// @param poolId Unique Id of pool. /// @return balance Stake delegated to pool by staker. function getStakeDelegatedToPoolByOwner( address staker, bytes32 poolId - ) external view returns (StoredBalance memory balance); + ) external view returns (IStructs.StoredBalance memory balance); - function endEpoch() external returns (uint256); + /// @dev Returns a staking pool + /// @param poolId Unique id of pool. + function getStakingPool(bytes32 poolId) external view returns (IStructs.Pool memory); - function finalizePool(bytes32 poolId) external; + /// @dev Get stats on a staking pool in this epoch. + /// @param poolId Pool Id to query. + /// @return PoolStats struct for pool id. + function getStakingPoolStatsThisEpoch(bytes32 poolId) external view returns (IStructs.PoolStats memory); + + /// @dev Returns the total stake delegated to a specific staking pool, + /// across all members. + /// @param poolId Unique Id of pool. + /// @return balance Total stake delegated to pool. + function getTotalStakeDelegatedToPool(bytes32 poolId) external view returns (IStructs.StoredBalance memory balance); + + /// @dev An overridable way to access the deployed WETH contract. + /// Must be view to allow overrides to access state. + /// @return wethContract The WETH contract instance. + function getWethContract() external view returns (address wethContract); + + /// @dev An overridable way to access the deployed zrxVault. + /// Must be view to allow overrides to access state. + /// @return zrxVault The zrxVault contract. + function getZrxVault() external view returns (IZrxVaultMock zrxVault); } diff --git a/contracts/governance/test/mocks/IStorageMock.sol b/contracts/governance/test/mocks/IStorageMock.sol new file mode 100644 index 0000000000..877ab8a673 --- /dev/null +++ b/contracts/governance/test/mocks/IStorageMock.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + + Copyright 2021 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.8.19; + +import "./IZrxVaultMock.sol"; +import "./IStructs.sol"; + +interface IStorageMock { + function stakingContract() external view returns (address); + + function lastPoolId() external view returns (bytes32); + + function numMakersByPoolId(bytes32 poolId) external view returns (uint256); + + function currentEpoch() external view returns (uint256); + + function currentEpochStartTimeInSeconds() external view returns (uint256); + + function protocolFeesThisEpochByPool(bytes32 poolId) external view returns (uint256); + + function validExchanges(address exchangeAddress) external view returns (bool); + + function epochDurationInSeconds() external view returns (uint256); + + function rewardDelegatedStakeWeight() external view returns (uint32); + + function minimumPoolStake() external view returns (uint256); + + function cobbDouglasAlphaNumerator() external view returns (uint32); + + function cobbDouglasAlphaDenominator() external view returns (uint32); +} diff --git a/contracts/governance/test/mocks/IStructs.sol b/contracts/governance/test/mocks/IStructs.sol new file mode 100644 index 0000000000..e86a992bf9 --- /dev/null +++ b/contracts/governance/test/mocks/IStructs.sol @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: Apache-2.0 +/* + + Copyright 2021 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.8.19; + +interface IStructs { + /// @dev Stats for a pool that earned rewards. + /// @param feesCollected Fees collected in ETH by this pool. + /// @param weightedStake Amount of weighted stake in the pool. + /// @param membersStake Amount of non-operator stake in the pool. + struct PoolStats { + uint256 feesCollected; + uint256 weightedStake; + uint256 membersStake; + } + + /// @dev Holds stats aggregated across a set of pools. + /// @param rewardsAvailable Rewards (ETH) available to the epoch + /// being finalized (the previous epoch). This is simply the balance + /// of the contract at the end of the epoch. + /// @param numPoolsToFinalize The number of pools that have yet to be finalized through `finalizePools()`. + /// @param totalFeesCollected The total fees collected for the epoch being finalized. + /// @param totalWeightedStake The total fees collected for the epoch being finalized. + /// @param totalRewardsFinalized Amount of rewards that have been paid during finalization. + struct AggregatedStats { + uint256 rewardsAvailable; + uint256 numPoolsToFinalize; + uint256 totalFeesCollected; + uint256 totalWeightedStake; + uint256 totalRewardsFinalized; + } + + /// @dev Encapsulates a balance for the current and next epochs. + /// Note that these balances may be stale if the current epoch + /// is greater than `currentEpoch`. + /// @param currentEpoch the current epoch + /// @param currentEpochBalance balance in the current epoch. + /// @param nextEpochBalance balance in `currentEpoch+1`. + struct StoredBalance { + uint64 currentEpoch; + uint96 currentEpochBalance; + uint96 nextEpochBalance; + } + + /// @dev Statuses that stake can exist in. + /// Any stake can be (re)delegated effective at the next epoch + /// Undelegated stake can be withdrawn if it is available in both the current and next epoch + enum StakeStatus { + UNDELEGATED, + DELEGATED + } + + /// @dev Info used to describe a status. + /// @param status of the stake. + /// @param poolId Unique Id of pool. This is set when status=DELEGATED. + struct StakeInfo { + StakeStatus status; + bytes32 poolId; + } + + /// @dev Struct to represent a fraction. + /// @param numerator of fraction. + /// @param denominator of fraction. + struct Fraction { + uint256 numerator; + uint256 denominator; + } + + /// @dev Holds the metadata for a staking pool. + /// @param operator of the pool. + /// @param operatorShare Fraction of the total balance owned by the operator, in ppm. + struct Pool { + address operator; + uint32 operatorShare; + } +} diff --git a/contracts/governance/test/mocks/IZrxVaultMock.sol b/contracts/governance/test/mocks/IZrxVaultMock.sol new file mode 100644 index 0000000000..e9a7d9799b --- /dev/null +++ b/contracts/governance/test/mocks/IZrxVaultMock.sol @@ -0,0 +1,83 @@ +/* + + 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.8.19; + +interface IZrxVaultMock { + /// @dev Emmitted whenever a StakingProxy is set in a vault. + event StakingProxySet(address stakingProxyAddress); + + /// @dev Emitted when the Staking contract is put into Catastrophic Failure Mode + /// @param sender Address of sender (`msg.sender`) + event InCatastrophicFailureMode(address sender); + + /// @dev Emitted when Zrx Tokens are deposited into the vault. + /// @param staker of Zrx Tokens. + /// @param amount of Zrx Tokens deposited. + event Deposit(address indexed staker, uint256 amount); + + /// @dev Emitted when Zrx Tokens are withdrawn from the vault. + /// @param staker of Zrx Tokens. + /// @param amount of Zrx Tokens withdrawn. + event Withdraw(address indexed staker, uint256 amount); + + /// @dev Emitted whenever the ZRX AssetProxy is set. + event ZrxProxySet(address zrxProxyAddress); + + /// @dev Sets the address of the StakingProxy contract. + /// Note that only the contract staker can call this function. + /// @param _stakingProxyAddress Address of Staking proxy contract. + function setStakingProxy(address _stakingProxyAddress) external; + + /// @dev Vault enters into Catastrophic Failure Mode. + /// *** WARNING - ONCE IN CATOSTROPHIC FAILURE MODE, YOU CAN NEVER GO BACK! *** + /// Note that only the contract staker can call this function. + function enterCatastrophicFailure() external; + + /// @dev Sets the Zrx proxy. + /// Note that only the contract staker can call this. + /// Note that this can only be called when *not* in Catastrophic Failure mode. + /// @param zrxProxyAddress Address of the 0x Zrx Proxy. + function setZrxProxy(address zrxProxyAddress) external; + + /// @dev Deposit an `amount` of Zrx Tokens from `staker` into the vault. + /// Note that only the Staking contract can call this. + /// Note that this can only be called when *not* in Catastrophic Failure mode. + /// @param staker of Zrx Tokens. + /// @param amount of Zrx Tokens to deposit. + function depositFrom(address staker, uint256 amount) external; + + /// @dev Withdraw an `amount` of Zrx Tokens to `staker` from the vault. + /// Note that only the Staking contract can call this. + /// Note that this can only be called when *not* in Catastrophic Failure mode. + /// @param staker of Zrx Tokens. + /// @param amount of Zrx Tokens to withdraw. + function withdrawFrom(address staker, uint256 amount) external; + + /// @dev Withdraw ALL Zrx Tokens to `staker` from the vault. + /// Note that this can only be called when *in* Catastrophic Failure mode. + /// @param staker of Zrx Tokens. + function withdrawAllFrom(address staker) external returns (uint256); + + /// @dev Returns the balance in Zrx Tokens of the `staker` + /// @return Balance in Zrx. + function balanceOf(address staker) external view returns (uint256); + + /// @dev Returns the entire balance of Zrx tokens in the vault. + function balanceOfZrxVault() external view returns (uint256); +}