-
Notifications
You must be signed in to change notification settings - Fork 7
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
release v 1.1 #67
base: master
Are you sure you want to change the base?
release v 1.1 #67
Conversation
…ient-tests feat: add tests for add/remove allowed recipient factories
…gistry-tests feat: add tests for allowed recipient registry
… ERROR_ALLOWED_RECIPIENT_NOT_FOUND
Feature/tests for datetime lib
add more acceptance tests for single recipient setup
simple DVT related factories
chore: Update gh action syntax
function _validateInputData(SetNameInput[] memory _decodedCallData) private view { | ||
uint256 maxNameLength = nodeOperatorsRegistry.MAX_NODE_OPERATOR_NAME_LENGTH(); | ||
uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); | ||
|
||
require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); | ||
require( | ||
_decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, | ||
ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE | ||
); | ||
|
||
for (uint256 i = 0; i < _decodedCallData.length; ++i) { | ||
require( | ||
i == 0 || | ||
_decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, | ||
ERROR_NODE_OPERATORS_IS_NOT_SORTED | ||
); | ||
require( | ||
bytes(_decodedCallData[i].name).length > 0 && | ||
bytes(_decodedCallData[i].name).length <= maxNameLength, | ||
ERROR_WRONG_NAME_LENGTH | ||
); | ||
|
||
( | ||
/* bool active */, | ||
string memory name, | ||
/* address rewardAddress */, | ||
/* uint64 stakingLimit */, | ||
/* uint64 stoppedValidators */, | ||
/* uint64 totalSigningKeys */, | ||
/* uint64 usedSigningKeys */ | ||
) = nodeOperatorsRegistry.getNodeOperator( | ||
_decodedCallData[i].nodeOperatorId, | ||
true | ||
); | ||
|
||
require( | ||
keccak256(bytes(_decodedCallData[i].name)) != keccak256(bytes(name)), | ||
ERROR_SAME_NAME | ||
); | ||
} | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function _validateInputData(SetRewardAddressInput[] memory _decodedCallData) private view { | ||
uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); | ||
|
||
require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); | ||
require( | ||
_decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, | ||
ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE | ||
); | ||
|
||
for (uint256 i = 0; i < _decodedCallData.length; ++i) { | ||
require( | ||
i == 0 || | ||
_decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, | ||
ERROR_NODE_OPERATORS_IS_NOT_SORTED | ||
); | ||
require(_decodedCallData[i].rewardAddress != lido, ERROR_LIDO_REWARD_ADDRESS); | ||
require(_decodedCallData[i].rewardAddress != address(0), ERROR_ZERO_REWARD_ADDRESS); | ||
|
||
( | ||
/* bool active */, | ||
/* string memory name */, | ||
address rewardAddress, | ||
/* uint64 stakingLimit */, | ||
/* uint64 stoppedValidators */, | ||
/* uint64 totalSigningKeys */, | ||
/* uint64 usedSigningKeys */ | ||
) = nodeOperatorsRegistry.getNodeOperator( | ||
_decodedCallData[i].nodeOperatorId, | ||
false | ||
); | ||
|
||
require(_decodedCallData[i].rewardAddress != rewardAddress, ERROR_SAME_REWARD_ADDRESS); | ||
} | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function _getNodeOperatorData( | ||
uint256 _nodeOperatorId | ||
) private view returns (NodeOperatorData memory _nodeOperatorData) { | ||
( | ||
bool active, | ||
, | ||
address rewardAddress, | ||
uint64 stakingLimit, | ||
, | ||
uint64 totalSigningKeys, | ||
|
||
) = nodeOperatorsRegistry.getNodeOperator(_nodeOperatorId, false); | ||
|
||
_nodeOperatorData.id = _nodeOperatorId; | ||
_nodeOperatorData.active = active; | ||
_nodeOperatorData.rewardAddress = rewardAddress; | ||
_nodeOperatorData.stakingLimit = stakingLimit; | ||
_nodeOperatorData.totalSigningKeys = totalSigningKeys; | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function _getPeriodStartFromTimestamp(uint256 _timestamp) internal view returns (uint256) { | ||
// Get year and number of month of the timestamp: | ||
(uint256 year, uint256 month, ) = bokkyPooBahsDateTimeContract.timestampToDate(_timestamp); | ||
// We assume that the year will remain the same, | ||
// because the beginning of the current calendar period will necessarily be in the same year. | ||
uint256 periodStartYear = year; | ||
// Get the number of the start date month: | ||
uint256 periodStartMonth = _getFirstMonthInPeriodFromMonth(month, periodDurationMonths); | ||
// The beginning of the period always matches the calendar date of the beginning of the month. | ||
uint256 periodStartDay = 1; | ||
return | ||
bokkyPooBahsDateTimeContract.timestampFromDate( | ||
periodStartYear, | ||
periodStartMonth, | ||
periodStartDay | ||
); | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
function _validateInputData(VettedValidatorsLimitInput[] memory _decodedCallData) private view { | ||
uint256 nodeOperatorsCount = nodeOperatorsRegistry.getNodeOperatorsCount(); | ||
require(_decodedCallData.length > 0, ERROR_EMPTY_CALLDATA); | ||
require( | ||
_decodedCallData[_decodedCallData.length - 1].nodeOperatorId < nodeOperatorsCount, | ||
ERROR_NODE_OPERATOR_INDEX_OUT_OF_RANGE | ||
); | ||
|
||
for (uint256 i = 0; i < _decodedCallData.length; ++i) { | ||
require( | ||
i == 0 || | ||
_decodedCallData[i].nodeOperatorId > _decodedCallData[i - 1].nodeOperatorId, | ||
ERROR_NODE_OPERATORS_IS_NOT_SORTED | ||
); | ||
|
||
( | ||
bool active, | ||
/* string memory name */, | ||
/* address rewardAddress */, | ||
/* uint64 stakingLimit */, | ||
/* uint64 stoppedValidators */, | ||
uint64 totalSigningKeys, | ||
/* uint64 usedSigningKeys */ | ||
) = nodeOperatorsRegistry.getNodeOperator( | ||
_decodedCallData[i].nodeOperatorId, | ||
false | ||
); | ||
|
||
require( | ||
totalSigningKeys >= _decodedCallData[i].stakingLimit, | ||
ERROR_NOT_ENOUGH_SIGNING_KEYS | ||
); | ||
|
||
require( | ||
active == true, | ||
ERROR_NODE_OPERATOR_IS_NOT_ACTIVE | ||
); | ||
} | ||
} |
Check warning
Code scanning / Slither
Unused return Medium
address public token; | ||
|
||
/// @notice Address of AllowedRecipientsRegistry contract | ||
AllowedRecipientsRegistry public allowedRecipientsRegistry; |
Check warning
Code scanning / Slither
State variables that could be declared immutable Warning
// ------------- | ||
|
||
/// @notice Address of AllowedRecipientsRegistry | ||
AllowedRecipientsRegistry public allowedRecipientsRegistry; |
Check warning
Code scanning / Slither
State variables that could be declared immutable Warning
IFinance public immutable finance; | ||
|
||
/// @notice Address of payout token | ||
address public token; |
Check warning
Code scanning / Slither
State variables that could be declared immutable Warning
// ------------- | ||
|
||
/// @notice Address of AllowedRecipientsRegistry | ||
AllowedRecipientsRegistry public allowedRecipientsRegistry; |
Check warning
Code scanning / Slither
State variables that could be declared immutable Warning
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.
LGTM. Good job!
Overview
This pull request introduces features for payments and node operators registry management.
Generalized payments with limit
Plug-in factories for Easy Track to be used by the Lido DAO committees with intrusive on-chain enforcement of periodically spendable limits.
Contracts based on the existing RewardPrograms set (RewardProgramsRegistry, AddRewardProgram, RemoveRewardProgram, TopUpRewardProgram) have the following differences from the existing ones:
AllowedRecipientsBuilder
- provide ability to deploy payments setup with checksAllowedRecipientsFactory
- Factory for pauments related contractsAllowedRecipientsRegistry
- Registry of recipients and limitsAddAllowedRecipient
- creates EVMScript to add recipient from registryRemoveAllowedRecipient
- creates EVMScript to remove recipient from registryTopUpAllowedRecipients
- creates EVMScript to transfer ERC-20 token to recipientLimitsChecker
- stores limits params and provides limit-enforcement logicADR LIP-18 Audit
Factories set for node operators registry management
This bench of EasyTrack EVM factories to manage an instance of the Simple DVT NodeOperatorsRegistry. The high-view overview of the management flow is presented in the below diagram.
ActivateNodeOperators
- creates EVMScript to activate several node operatorsAddNodeOperators
- creates EVMScript to add a new batch of node operatorsDeactivateNodeOperators
- creates EVMScript to deactivate several node operatorsChangeNodeOperatorManagers
- creates EVMScript to change signing keys manager for several node operatorsIncreaseVettedValidatorsLimit
- creates EVMScript to increase the staking limit for a node operatorSetNodeOperatorNames
- creates EVMScript to set the name of several node operatorsSetNodeOperatorRewardAddresses
- creates EVMScript to set the reward address of several node operatorsSetVettedValidatorsLimits
- creates EVMScript to set the staking limit for node operatorsUpdateTargetValidatorLimits
- creates EVMScript to set the node operator's target validators limitSpecification Audit
Utils