diff --git a/contracts/staking/contracts/src/interfaces/IZrxVault.sol b/contracts/staking/contracts/src/interfaces/IZrxVault.sol index 88dfd278cf..5a272d64f5 100644 --- a/contracts/staking/contracts/src/interfaces/IZrxVault.sol +++ b/contracts/staking/contracts/src/interfaces/IZrxVault.sol @@ -21,8 +21,87 @@ pragma solidity ^0.5.5; interface IZrxVault { - function depositFrom(address owner, uint256 amount) external; - function withdrawFrom(address owner, uint256 amount) external; - function withdrawAllFrom(address owner) external returns (uint256); - function balanceOf(address owner) external view returns (uint256); + /// @dev This vault manages Zrx Tokens. + /// When a user mints stake, their Zrx Tokens are deposited into this vault. + /// Similarly, when they burn stake, their Zrx Tokens are withdrawn from this vault. + /// There is a "Catastrophic Failure Mode" that, when invoked, only + /// allows withdrawals to be made. Once this vault is in catostrophic + /// failure mode, it cannot be returned to normal mode; this prevents + /// corruption of related state in the staking contract. + + /// @dev Emitted when Zrx Tokens are deposited into the vault. + /// @param sender Address of sender (`msg.sender`). + /// @param owner of Zrx Tokens. + /// @param amount of Zrx Tokens deposited. + event ZrxDepositedIntoVault( + address indexed sender, + address indexed owner, + uint256 amount + ); + + /// @dev Emitted when Zrx Tokens are withdrawn from the vault. + /// @param sender Address of sender (`msg.sender`). + /// @param owner of Zrx Tokens. + /// @param amount of Zrx Tokens withdrawn. + event ZrxWithdrawnFromVault( + address indexed sender, + address indexed owner, + uint256 amount + ); + + /// @dev Emitted when the ERC20 Proxy is changed. + /// @param erc20ProxyAddress Address of the new ERC20 proxy. + event Erc20ProxyChanged( + address erc20ProxyAddress + ); + + /// @dev Emitted when the Zrx Asset Data is changed. + /// @param zrxAssetData New Zrx Asset Data. + event ZrxAssetDataChanged( + bytes zrxAssetData + ); + + /// @dev Sets the ERC20 proxy. + /// Note that only the contract owner can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param erc20ProxyAddress Address of the 0x ERC20 Proxy. + function setErc20Proxy(address erc20ProxyAddress) + external; + + /// @dev Sets the Zrx Asset Data. + /// Note that only the contract owner can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param _zrxAssetData Zrx asset data for the ERC20 Proxy. + function setZrxAssetData(bytes calldata _zrxAssetData) + external; + + /// @dev Deposit an `amount` of Zrx Tokens from `owner` into the vault. + /// Note that only the Staking contract can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param owner of Zrx Tokens. + /// @param amount of Zrx Tokens to deposit. + function depositFrom(address owner, uint256 amount) + external; + + /// @dev Withdraw an `amount` of Zrx Tokens to `owner` from the vault. + /// Note that only the Staking contract can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param owner of Zrx Tokens. + /// @param amount of Zrx Tokens to withdraw. + function withdrawFrom(address owner, uint256 amount) + external; + + /// @dev Withdraw ALL Zrx Tokens to `owner` from the vault. + /// Note that this can only be called when *in* Catostrophic Failure mode. + /// @param owner of Zrx Tokens. + function withdrawAllFrom(address owner) + external + returns (uint256); + + /// @dev Returns the balance in Zrx Tokens of the `owner` + /// @return Balance in Zrx. + function balanceOf(address owner) + external + view + returns (uint256); } diff --git a/contracts/staking/contracts/src/stake/MixinZrxVault.sol b/contracts/staking/contracts/src/stake/MixinZrxVault.sol index 6757f0b3bf..0083a77263 100644 --- a/contracts/staking/contracts/src/stake/MixinZrxVault.sol +++ b/contracts/staking/contracts/src/stake/MixinZrxVault.sol @@ -31,13 +31,20 @@ contract MixinZrxVault is MixinOwnable { - function setZrxVault(address _zrxVault) + /// @dev This mixin contains logic for managing and interfacing with the Zrx Vault. + /// (see vaults/ZrxVault.sol). + + /// @dev Set the Zrx Vault. + /// @param zrxVaultAddress Address of the Zrx Vault. + function setZrxVault(address zrxVaultAddress) external onlyOwner { - zrxVault = IZrxVault(_zrxVault); + zrxVault = IZrxVault(zrxVaultAddress); } + /// @dev Return the current Zrx Vault + /// @return Zrx Vault function getZrxVault() public view @@ -46,12 +53,18 @@ contract MixinZrxVault is return address(zrxVault); } + /// @dev Deposits Zrx Tokens from the `owner` into the vault. + /// @param owner of Zrx Tokens + /// @param amount of tokens to deposit. function _depositFromOwnerIntoZrxVault(address owner, uint256 amount) internal { zrxVault.depositFrom(owner, amount); } + /// @dev Withdraws Zrx Tokens from to `owner` from the vault. + /// @param owner of deposited Zrx Tokens + /// @param amount of tokens to withdraw. function _withdrawToOwnerFromZrxVault(address owner, uint256 amount) internal { diff --git a/contracts/staking/contracts/src/vaults/ZrxVault.sol b/contracts/staking/contracts/src/vaults/ZrxVault.sol index 5c4ecbd43d..44d49c1dca 100644 --- a/contracts/staking/contracts/src/vaults/ZrxVault.sol +++ b/contracts/staking/contracts/src/vaults/ZrxVault.sol @@ -31,48 +31,86 @@ contract ZrxVault is MixinVaultCore { + /// @dev This vault manages Zrx Tokens. + /// When a user mints stake, their Zrx Tokens are deposited into this vault. + /// Similarly, when they burn stake, their Zrx Tokens are withdrawn from this vault. + /// There is a "Catastrophic Failure Mode" that, when invoked, only + /// allows withdrawals to be made. Once this vault is in catostrophic + /// failure mode, it cannot be returned to normal mode; this prevents + /// corruption of related state in the staking contract. + using LibSafeMath for uint256; // mapping from Owner to ZRX balance mapping (address => uint256) internal balances; + // 0x ERC20 Proxy IAssetProxy internal erc20Proxy; + // Zrx Token IERC20Token internal zrxToken; + // Asset data for the ERC20 Proxy bytes internal zrxAssetData; + /// @dev Constructor. + /// @param erc20ProxyAddress Address of the 0x ERC20 Proxy. + /// @param zrxTokenAddress Address of the Zrx Token. + /// @param _zrxAssetData Zrx asset data for the ERC20 Proxy. constructor( - address _erc20ProxyAddress, - address _zrxTokenAddress, + address erc20ProxyAddress, + address zrxTokenAddress, bytes memory _zrxAssetData ) public { - erc20Proxy = IAssetProxy(_erc20ProxyAddress); - zrxToken = IERC20Token(_zrxTokenAddress); + erc20Proxy = IAssetProxy(erc20ProxyAddress); + zrxToken = IERC20Token(zrxTokenAddress); zrxAssetData = _zrxAssetData; } - function setErc20Proxy(address _erc20ProxyAddress) + /// @dev Sets the ERC20 proxy. + /// Note that only the contract owner can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param erc20ProxyAddress Address of the 0x ERC20 Proxy. + function setErc20Proxy(address erc20ProxyAddress) external onlyOwner + onlyNotInCatostrophicFailure { - erc20Proxy = IAssetProxy(_erc20ProxyAddress); + erc20Proxy = IAssetProxy(erc20ProxyAddress); + emit Erc20ProxyChanged(erc20ProxyAddress); } + /// @dev Sets the Zrx Asset Data. + /// Note that only the contract owner can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param _zrxAssetData Zrx asset data for the ERC20 Proxy. function setZrxAssetData(bytes calldata _zrxAssetData) external onlyOwner + onlyNotInCatostrophicFailure { zrxAssetData = _zrxAssetData; + emit ZrxAssetDataChanged(_zrxAssetData); } + /// @dev Deposit an `amount` of Zrx Tokens from `owner` into the vault. + /// Note that only the Staking contract can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param owner of Zrx Tokens. + /// @param amount of Zrx Tokens to deposit. function depositFrom(address owner, uint256 amount) external onlyStakingContract onlyNotInCatostrophicFailure { + // update balance + balances[owner] = balances[owner]._add(amount); + + // notify + emit ZrxDepositedIntoVault(msg.sender, owner, amount); + // deposit ZRX from owner erc20Proxy.transferFrom( zrxAssetData, @@ -80,11 +118,13 @@ contract ZrxVault is address(this), amount ); - - // update balance - balances[owner] = balances[owner]._add(amount); } + /// @dev Withdraw an `amount` of Zrx Tokens to `owner` from the vault. + /// Note that only the Staking contract can call this. + /// Note that this can only be called when *not* in Catostrophic Failure mode. + /// @param owner of Zrx Tokens. + /// @param amount of Zrx Tokens to withdraw. function withdrawFrom(address owner, uint256 amount) external onlyStakingContract @@ -93,6 +133,9 @@ contract ZrxVault is _withdrawFrom(owner, amount); } + /// @dev Withdraw ALL Zrx Tokens to `owner` from the vault. + /// Note that this can only be called when *in* Catostrophic Failure mode. + /// @param owner of Zrx Tokens. function withdrawAllFrom(address owner) external onlyInCatostrophicFailure @@ -106,6 +149,8 @@ contract ZrxVault is return totalBalance; } + /// @dev Returns the balance in Zrx Tokens of the `owner` + /// @return Balance in Zrx. function balanceOf(address owner) external view @@ -114,6 +159,9 @@ contract ZrxVault is return balances[owner]; } + /// @dev Withdraw an `amount` of Zrx Tokens to `owner` from the vault. + /// @param owner of Zrx Tokens. + /// @param amount of Zrx Tokens to withdraw. function _withdrawFrom(address owner, uint256 amount) internal { @@ -121,6 +169,9 @@ contract ZrxVault is // note that this call will revert if trying to withdraw more // than the current balance balances[owner] = balances[owner]._sub(amount); + + // notify + emit ZrxWithdrawnFromVault(msg.sender, owner, amount); // withdraw ZRX to owner zrxToken.transfer(