Return of staked tokens
The function kickModeler
merely kicks out the modeler but does not return the staked tokens to the modeler. If there are malicious validators, they could use this method to make many modelers lose funds. A similar function, optOutModeler
, does have the operation of returning the staked tokens to the modeler.
function kickModeler(address modeler) external onlyValidator whenNotPaused {
modelers[modeler].optOutTime = block.timestamp;
emit ModelerKicked(msg.sender, modeler);
}
The second issue is that validator.currentStake
is directly assigned the value of validatorStakeAmount
rather than validator.currentStake += validatorStakeAmount
.
function registerValidator(address[] storage validatorAddresses, uint256 MAX_VALIDATORS, IERC20 validatorToken, DataTypes.ValidatorData storage validator, uint256 validatorStakeAmount, mapping(address => bool) storage isValRegistered) external {
require(validatorAddresses.length < MAX_VALIDATORS, "Max validators reached");
require(isValRegistered[msg.sender] == false || (validator.optOutTime > 0 && validator.optOutTime < block.timestamp - ONE_DAY) , "Validator already registered");
validatorToken.safeTransferFrom(msg.sender, address(this), validatorStakeAmount);
isValRegistered[msg.sender] = true;
validator.currentStake = validatorStakeAmount;
validator.optOutTime = ~uint256(0);
addValidatorRewardList(msg.sender, validatorAddresses, isValRegistered);
emit ValidatorRegistered(msg.sender);
}
In some cases, for example, if validator.optOutTime
> 0 and the validator's staked tokens are not returned (in the case that the validator be kicked out with emergencyOptOutValidator
), then these staked tokens could be permanently lost.