The impact of this finding is that an unauthorized party can manipulate the state of the vaultSettleStatus variable before executing critical operations related to penalty marking, fund distribution, and reward deposits. This can potentially disrupt the intended flow of funds and rewards, leading to financial losses or improper distribution.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;
// Import contract dependencies and interfaces
contract ValidatorWithdrawalVault {
bool internal vaultSettleStatus;
// Other contract functions and variables...
function settleFunds() external override {
uint8 poolId = VaultProxy(payable(address(this))).poolId();
uint256 validatorId = VaultProxy(payable(address(this))).id();
IStaderConfig staderConfig = VaultProxy(payable(address(this))).staderConfig();
address nodeRegistry = IPoolUtils(staderConfig.getPoolUtils()).getNodeRegistry(poolId);
if (msg.sender != nodeRegistry) {
revert CallerNotNodeRegistryContract();
}
(uint256 userSharePrelim, uint256 operatorShare, uint256 protocolShare) = calculateValidatorWithdrawalShare();
uint256 penaltyAmount = getUpdatedPenaltyAmount(poolId, validatorId, staderConfig);
if (operatorShare < penaltyAmount) {
ISDCollateral(staderConfig.getSDCollateral()).slashValidatorSD(validatorId, poolId);
penaltyAmount = operatorShare;
}
uint256 userShare = userSharePrelim + penaltyAmount;
operatorShare = operatorShare - penaltyAmount;
// Final settlement
vaultSettleStatus = true;
IPenalty(staderConfig.getPenaltyContract()).markValidatorSettled(poolId, validatorId);
IStaderStakePoolManager(staderConfig.getStakePoolManager()).receiveWithdrawVaultUserShare{value: userShare}();
UtilLib.sendValue(payable(staderConfig.getStaderTreasury()), protocolShare);
IOperatorRewardsCollector(staderConfig.getOperatorRewardsCollector()).depositFor{value: operatorShare}(
getOperatorAddress(poolId, validatorId, staderConfig)
);
emit SettledFunds(userShare, operatorShare, protocolShare);
}
}
Manual review
move line 75 after IOperatorRewardsCollector(staderConfig.getOperatorRewardsCollector()).depositFor{value: operatorShare}(
getOperatorAddress(poolId, validatorId, staderConfig)
);
IPenalty(staderConfig.getPenaltyContract()).markValidatorSettled(poolId, validatorId);
IStaderStakePoolManager(staderConfig.getStakePoolManager()).receiveWithdrawVaultUserShare{value: userShare}();
UtilLib.sendValue(payable(staderConfig.getStaderTreasury()), protocolShare);
IOperatorRewardsCollector(staderConfig.getOperatorRewardsCollector()).depositFor{value: operatorShare}(
getOperatorAddress(poolId, validatorId, staderConfig)
);
vaultSettleStatus = true;
Timing
The text was updated successfully, but these errors were encountered:
All reactions