@0x/contracts-staking: Rename MixinHyperParameters -> MixinParams.

`@0x/contracts-staking`: Move params storage variables into `MixinStorage`.
`@0x/contracts-staking`: Add storage layout tests for new state vars.
`@0x/contracts-staking`: Add more migration tests.
`@0x/contracts-staking`: Add `_initMixinParams()` function that sets up `MixinParams` state.
This commit is contained in:
Lawrence Forman
2019-09-07 22:29:30 -04:00
parent 2a21d87193
commit 25787ea806
21 changed files with 197 additions and 125 deletions

View File

@@ -24,6 +24,7 @@ import "./fees/MixinExchangeManager.sol";
import "./stake/MixinZrxVault.sol";
import "./staking_pools/MixinStakingPoolRewardVault.sol";
import "./sys/MixinScheduler.sol";
import "./sys/MixinParams.sol";
import "./stake/MixinStakeBalances.sol";
import "./stake/MixinStake.sol";
import "./staking_pools/MixinStakingPool.sol";
@@ -37,7 +38,7 @@ contract Staking is
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters,
MixinParams,
MixinZrxVault,
MixinExchangeManager,
MixinStakingPoolRewardVault,
@@ -64,7 +65,8 @@ contract Staking is
onlyOwner
{
// DANGER! When performing upgrades, take care to modify this logic
// not to accidentally overwrite existing state.
// to prevent accidentally clearing prior state.
_initMixinScheduler();
_initMixinParams();
}
}

View File

@@ -21,8 +21,8 @@ pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "./libs/LibProxy.sol";
import "./immutable/MixinStorage.sol";
import "./immutable/MixinHyperParameters.sol";
import "./interfaces/IStorageInit.sol";
import "./interfaces/IStakingEvents.sol";
import "./interfaces/IStakingProxy.sol";
@@ -31,8 +31,7 @@ contract StakingProxy is
IStakingProxy,
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters
MixinStorage
{
using LibProxy for address;

View File

@@ -49,7 +49,6 @@ contract MixinExchangeFees is
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters,
MixinZrxVault,
MixinExchangeManager,
MixinStakingPoolRewardVault,

View File

@@ -125,4 +125,22 @@ contract MixinStorage is
// Rebate Vault (stores rewards for pools before they are moved to the eth vault on a per-user basis)
IStakingPoolRewardVault internal rewardVault;
// Minimum seconds between epochs.
uint256 internal epochDurationInSeconds;
// How much delegated stake is weighted vs operator stake, in ppm.
uint32 internal rewardDelegatedStakeWeight;
// Minimum amount of stake required in a pool to collect rewards.
uint256 internal minimumPoolStake;
// Maximum number of maker addresses allowed to be registered to a pool.
uint256 internal maximumMakersInPool;
// Numerator for cobb douglas alpha factor.
uint32 internal cobbDouglasAlphaNumerator;
// Denominator for cobb douglas alpha factor.
uint32 internal cobbDouglasAlphaDenomintor;
}

View File

@@ -29,10 +29,11 @@ library LibStakingRichErrors {
}
enum InitializationErrorCode {
MixinSchedulerAlreadyInitialized
MixinSchedulerAlreadyInitialized,
MixinParamsAlreadyInitialized
}
enum InvalidTuningValueErrorCode {
enum InvalidParamValueErrorCode {
InvalidCobbDouglasAlpha,
InvalidRewardDelegatedStakeWeight,
InvalidMaximumMakersInPool
@@ -129,9 +130,9 @@ library LibStakingRichErrors {
bytes4 internal constant INITIALIZATION_ERROR_SELECTOR =
0x0b02d773;
// bytes4(keccak256("InvalidTuningValue(uint8)"))
bytes4 internal constant INVALID_TUNING_VALUE_ERROR_SELECTOR =
0xbbfd10bb;
// bytes4(keccak256("InvalidParamValue(uint8)"))
bytes4 internal constant INVALID_PARAM_VALUE_ERROR_SELECTOR =
0x7b40eece;
// bytes4(keccak256("InvalidProtocolFeePaymentError(uint8,uint256,uint256)"))
bytes4 internal constant INVALID_PROTOCOL_FEE_PAYMENT_ERROR_SELECTOR =
@@ -435,13 +436,13 @@ library LibStakingRichErrors {
);
}
function InvalidTuningValue(InvalidTuningValueErrorCode code)
function InvalidParamValue(InvalidParamValueErrorCode code)
internal
pure
returns (bytes memory)
{
return abi.encodeWithSelector(
INVALID_TUNING_VALUE_ERROR_SELECTOR,
INVALID_PARAM_VALUE_ERROR_SELECTOR,
uint8(code)
);
}

View File

@@ -24,9 +24,11 @@ import "../immutable/MixinConstants.sol";
import "../immutable/MixinStorage.sol";
import "../interfaces/IStakingEvents.sol";
import "./MixinZrxVault.sol";
import "../staking_pools/MixinStakingPoolRewardVault.sol";
import "../staking_pools/MixinStakingPoolRewards.sol";
import "../sys/MixinScheduler.sol";
import "../libs/LibStakingRichErrors.sol";
import "./MixinZrxVault.sol";
import "./MixinStakeBalances.sol";
import "./MixinStakeStorage.sol";
@@ -37,7 +39,6 @@ contract MixinStake is
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters,
MixinZrxVault,
MixinStakingPoolRewardVault,
MixinScheduler,

View File

@@ -35,7 +35,6 @@ contract MixinStakeBalances is
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters,
MixinZrxVault,
MixinScheduler,
MixinStakeStorage

View File

@@ -33,7 +33,6 @@ contract MixinStakeStorage is
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters,
MixinScheduler
{
using LibSafeMath for uint256;

View File

@@ -57,7 +57,6 @@ contract MixinStakingPool is
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters,
MixinZrxVault,
MixinStakingPoolRewardVault,
MixinScheduler,

View File

@@ -32,7 +32,6 @@ contract MixinStakingPoolRewards is
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters,
MixinZrxVault,
MixinStakingPoolRewardVault,
MixinScheduler,

View File

@@ -20,43 +20,32 @@ pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "../immutable/MixinConstants.sol";
import "../immutable/MixinStorage.sol";
import "../interfaces/IStakingEvents.sol";
import "../libs/LibStakingRichErrors.sol";
import "./MixinConstants.sol";
contract MixinHyperParameters is
contract MixinParams is
IStakingEvents,
MixinConstants,
Ownable
Ownable,
MixinStorage
{
// Minimum seconds between epochs.
uint256 internal epochDurationInSeconds = 2 weeks;
// How much delegated stake is weighted vs operator stake, in ppm.
uint32 internal rewardDelegatedStakeWeight = (90 * PPM_DENOMINATOR) / 100; // 90%
// Minimum amount of stake required in a pool to collect rewards.
uint256 internal minimumPoolStake = 100 * MIN_TOKEN_VALUE; // 100 ZRX
// Maximum number of maker addresses allowed to be registered to a pool.
uint256 internal maximumMakersInPool = 10;
// Numerator for cobb douglas alpha factor.
uint256 internal cobbDouglasAlphaNumerator = 1;
// Denominator for cobb douglas alpha factor.
uint256 internal cobbDouglasAlphaDenomintor = 2;
/// @dev Set all hyperparameters at once.
/// @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 _maximumMakersInPool Maximum number of maker addresses allowed to be registered to a pool.
/// @param _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor.
/// @param _cobbDouglasAlphaDenomintor Denominator for cobb douglas alpha factor.
function tune(
function setParams(
uint256 _epochDurationInSeconds,
uint32 _rewardDelegatedStakeWeight,
uint256 _minimumPoolStake,
uint256 _maximumMakersInPool,
uint256 _cobbDouglasAlphaNumerator,
uint256 _cobbDouglasAlphaDenomintor
uint32 _cobbDouglasAlphaNumerator,
uint32 _cobbDouglasAlphaDenomintor
)
external
onlyOwner
@@ -85,14 +74,14 @@ contract MixinHyperParameters is
);
}
/// @dev Retrives all tuned values.
/// @dev Retrives 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 _maximumMakersInPool Maximum number of maker addresses allowed to be registered to a pool.
/// @return _cobbDouglasAlphaNumerator Numerator for cobb douglas alpha factor.
/// @return _cobbDouglasAlphaDenomintor Denominator for cobb douglas alpha factor.
function getHyperParameters()
function getParams()
external
view
returns (
@@ -100,8 +89,8 @@ contract MixinHyperParameters is
uint32 _rewardDelegatedStakeWeight,
uint256 _minimumPoolStake,
uint256 _maximumMakersInPool,
uint256 _cobbDouglasAlphaNumerator,
uint256 _cobbDouglasAlphaDenomintor
uint32 _cobbDouglasAlphaNumerator,
uint32 _cobbDouglasAlphaDenomintor
)
{
_epochDurationInSeconds = epochDurationInSeconds;
@@ -112,41 +101,68 @@ contract MixinHyperParameters is
_cobbDouglasAlphaDenomintor = cobbDouglasAlphaDenomintor;
}
/// @dev Initialzize storage belonging to this mixin.
function _initMixinParams() internal {
// Ensure state is uninitialized.
if (epochDurationInSeconds != 0 &&
rewardDelegatedStakeWeight != 0 &&
minimumPoolStake != 0 &&
maximumMakersInPool != 0 &&
cobbDouglasAlphaNumerator != 0 &&
cobbDouglasAlphaDenomintor != 0
) {
LibRichErrors.rrevert(
LibStakingRichErrors.InitializationError(
LibStakingRichErrors.InitializationErrorCode.MixinParamsAlreadyInitialized
)
);
}
// Set up defaults.
epochDurationInSeconds = 2 weeks;
rewardDelegatedStakeWeight = (90 * PPM_DENOMINATOR) / 100; // 90%
minimumPoolStake = 100 * MIN_TOKEN_VALUE; // 100 ZRX
maximumMakersInPool = 10;
cobbDouglasAlphaNumerator = 1;
cobbDouglasAlphaDenomintor = 2;
}
/// @dev Asserts that cobb douglas alpha values are valid.
/// @param numerator Numerator for cobb douglas alpha factor.
/// @param denominator Denominator for cobb douglas alpha factor.
function _assertValidCobbDouglasAlpha(
uint256 numerator,
uint256 denominator
uint32 numerator,
uint32 denominator
)
private
pure
{
if (int256(numerator) < 0
|| int256(denominator) <= 0
|| numerator > denominator
) {
// Alpha must be 0 < x < 1
if (numerator > denominator || denominator == 0) {
LibRichErrors.rrevert(
LibStakingRichErrors.InvalidTuningValue(
LibStakingRichErrors.InvalidTuningValueErrorCode.InvalidCobbDouglasAlpha
LibStakingRichErrors.InvalidParamValue(
LibStakingRichErrors.InvalidParamValueErrorCode.InvalidCobbDouglasAlpha
));
}
}
/// @dev Asserts that a stake weight is valid.
/// @param weight How much delegated stake is weighted vs operator stake, in ppm.
function _assertValidRewardDelegatedStakeWeight(
uint256 weight
uint32 weight
)
private
pure
{
if (weight > PPM_DENOMINATOR) {
LibRichErrors.rrevert(
LibStakingRichErrors.InvalidTuningValue(
LibStakingRichErrors.InvalidTuningValueErrorCode.InvalidRewardDelegatedStakeWeight
LibStakingRichErrors.InvalidParamValue(
LibStakingRichErrors.InvalidParamValueErrorCode.InvalidRewardDelegatedStakeWeight
));
}
}
/// @dev Asserts that a maximum makers value is valid.
/// @param amount Maximum number of maker addresses allowed to be registered to a pool.
function _assertValidMaximumMakersInPool(
uint256 amount
)
@@ -155,8 +171,8 @@ contract MixinHyperParameters is
{
if (amount == 0) {
LibRichErrors.rrevert(
LibStakingRichErrors.InvalidTuningValue(
LibStakingRichErrors.InvalidTuningValueErrorCode.InvalidMaximumMakersInPool
LibStakingRichErrors.InvalidParamValue(
LibStakingRichErrors.InvalidParamValueErrorCode.InvalidMaximumMakersInPool
));
}
}

View File

@@ -21,7 +21,6 @@ pragma solidity ^0.5.9;
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
import "@0x/contracts-utils/contracts/src/LibSafeMath.sol";
import "../libs/LibStakingRichErrors.sol";
import "../immutable/MixinHyperParameters.sol";
import "../immutable/MixinConstants.sol";
import "../immutable/MixinStorage.sol";
import "../interfaces/IStructs.sol";
@@ -38,8 +37,7 @@ contract MixinScheduler is
IStakingEvents,
MixinConstants,
Ownable,
MixinStorage,
MixinHyperParameters
MixinStorage
{
using LibSafeMath for uint256;

View File

@@ -20,18 +20,18 @@ pragma experimental ABIEncoderV2;
import "@0x/contracts-utils/contracts/src/Ownable.sol";
import "../src/immutable/MixinStorage.sol";
import "../src/immutable/MixinHyperParameters.sol";
contract TestInitTarget is
Ownable,
MixinStorage,
MixinHyperParameters
MixinStorage
{
// We can't store state in this contract before it is attached, so
// we will grant this predefined address a balance to indicate that
// `init()` should revert.
address public constant SHOULD_REVERT_ADDRESS = 0x5ed6A38c6bEcEd15b0AB58566b6fD7A00463d2F7;
// Counter that is incremented with every call to `init()`.
uint256 private _initCounter = 0;
// `msg.sender` of the last `init()` call.
address private _initSender = address(0);
// `address(this)` of the last `init()` call.
@@ -39,8 +39,9 @@ contract TestInitTarget is
function init() external {
if (SHOULD_REVERT_ADDRESS.balance != 0) {
revert("WHOOPSIE!");
revert("FORCED_REVERT");
}
_initCounter += 1;
_initSender = msg.sender;
_initThisAddress = address(this);
}
@@ -56,4 +57,8 @@ contract TestInitTarget is
initSender = _initSender;
initThisAddress = _initThisAddress;
}
function getInitCounter() external view returns (uint256) {
return _initCounter;
}
}

View File

@@ -107,6 +107,24 @@ contract TestStorageLayout is
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(cobbDouglasAlphaDenomintor_slot, slot) { revertIncorrectStorageSlot() }
slot := add(slot, 1)
}
}
}