-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Require non-zero delegation fee #521
Changes from all commits
6384bb5
7d48d55
4d38afb
e4f4ef4
22ccbd4
1d8c975
06c487c
7bcdef6
5cb1c8c
0e20bd0
70aa435
ccec42d
1d204da
0dc8562
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,8 +27,12 @@ abstract contract PoSValidatorManager is IPoSValidatorManager, ValidatorManager | |
uint256 _maximumStakeAmount; | ||
/// @notice The minimum amount of time a validator must be staked for. | ||
uint64 _minimumStakeDuration; | ||
/// @notice The minimum fee rate in basis points charged to the delegators by the validator. | ||
uint256 _minimumDelegationFeeRate; | ||
/// @notice The reward calculator for this validator manager. | ||
IRewardCalculator _rewardCalculator; | ||
/// @notice Maps the validationID to the delegation fee rate. | ||
mapping(bytes32 validationID => uint256) _validatorDelegationFeeRates; | ||
/// @notice Maps the delegationID to the delegator information. | ||
mapping(bytes32 delegationID => Delegator) _delegatorStakes; | ||
} | ||
|
@@ -39,6 +43,9 @@ abstract contract PoSValidatorManager is IPoSValidatorManager, ValidatorManager | |
bytes32 private constant _POS_VALIDATOR_MANAGER_STORAGE_LOCATION = | ||
0x4317713f7ecbdddd4bc99e95d903adedaa883b2e7c2551610bd13e2c7e473d00; | ||
|
||
// The maximum delegation fee rate in basis points. This is 99.99% | ||
uint256 public constant MAXIMUM_DELEGATION_FEE_RATE = 1e4 - 1; | ||
|
||
// solhint-disable ordering | ||
function _getPoSValidatorManagerStorage() | ||
private | ||
|
@@ -61,6 +68,7 @@ abstract contract PoSValidatorManager is IPoSValidatorManager, ValidatorManager | |
settings.minimumStakeAmount, | ||
settings.maximumStakeAmount, | ||
settings.minimumStakeDuration, | ||
settings.minimumDelegationFeeRate, | ||
settings.rewardCalculator | ||
); | ||
} | ||
|
@@ -70,8 +78,13 @@ abstract contract PoSValidatorManager is IPoSValidatorManager, ValidatorManager | |
uint256 minimumStakeAmount, | ||
uint256 maximumStakeAmount, | ||
uint64 minimumStakeDuration, | ||
uint256 minimumDelegationFeeRate, | ||
IRewardCalculator rewardCalculator | ||
) internal onlyInitializing { | ||
require( | ||
minimumDelegationFeeRate > 0 && minimumDelegationFeeRate < MAXIMUM_DELEGATION_FEE_RATE, | ||
"PoSValidatorManager: invalid minimum delegation fee rate" | ||
); | ||
PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); | ||
$._minimumStakeAmount = minimumStakeAmount; | ||
$._maximumStakeAmount = maximumStakeAmount; | ||
|
@@ -92,6 +105,18 @@ abstract contract PoSValidatorManager is IPoSValidatorManager, ValidatorManager | |
_initializeEndValidation(validationID); | ||
} | ||
|
||
// This should only be called from inside the initializeValidatorRegistration functions | ||
// of the child contracts. | ||
function _setDelegationFeeRate(bytes32 validationID, uint256 feeRate) internal { | ||
PoSValidatorManagerStorage storage $ = _getPoSValidatorManagerStorage(); | ||
require( | ||
feeRate >= $._minimumDelegationFeeRate && feeRate <= MAXIMUM_DELEGATION_FEE_RATE, | ||
"PoSValidatorManager: invalid delegation fee rate" | ||
); | ||
$._validatorDelegationFeeRates[validationID] = feeRate; | ||
emit DelegationFeeRateSet(validationID, feeRate); | ||
} | ||
Comment on lines
+110
to
+118
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should add documentation to this function regarding when it can/should be called |
||
|
||
function completeEndValidation(uint32 messageIndex) external { | ||
Validator memory validator = _completeEndValidation(messageIndex); | ||
_unlock(validator.startingWeight, validator.owner); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,10 @@ abstract contract PoSValidatorManagerTest is ValidatorManagerTest { | |
address public constant DEFAULT_DELEGATOR_ADDRESS = | ||
address(0x1234123412341234123412341234123412341234); | ||
|
||
// This is the rate that will be passed into the child contract `initializeValidatorRegistration` calls | ||
// It is set here to avoid having to pass irrelevant initializers to the parent contract. | ||
uint256 public delegationFeeRate; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not set on this stateful solution being the cleanest way to pass in delegationFeeRate to child test contracts. Happy to hear alternatives. |
||
|
||
PoSValidatorManager public posValidatorManager; | ||
|
||
event DelegatorAdded( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to track this here or in
Validator
? This makes it more specific to the PoS and maintains less state by not adding it to the delegation. The tradeoff that it's an additional thing that needs to be cleaned up once all delegators have exited.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do like keeping the staking specific settings in the staking contract. We should think about if this is also the simplest solution given the PoA -> PoS upgrade potential, which I think it does? If we allow Validators to set their fee rate to 0 to disable delegation, then we could automatically get the property of PoA validators not being able to be delegated to, I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that I love overloading the function of the fee rate, but this might be the cheapest/cleanest way of doing this. I will give it a try and consider alternatives.