Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: medium
Valid

Inability to independently update Fee receivers without sending fees to old receivers

Summary

The contract lacks the ability for an admin/owner to update a receiver's address without affecting old fees or the fee structure. In situations where the admin needs to update an invalid or outdated receiver address, they may risk losing accrued fees to the old receiver account. This can also hinder the ability to manage fee recipients effectively, especially if the old receiver is no longer valid. A mechanism should be in place to allow updating the receiver address without altering the fee rate or causing a loss of already available funds.

Vulnerability Details

The current implementation of the `updateFee` function allows the owner to update the fee basis points and receiver address but requires a recalculation of strategy rewards before applying changes. This process locks the owner into sending old fees to the previous receiver before the update, even if the receiver is no longer valid. If the old receiver's address is compromised or invalid, the accrued fees are lost to that address, leading to potential fee loss.

The relevant part of the function: Vaultcontrollerstrategy.sol

/**
* @notice Updates an existing fee
@audit>> 1. >> * @dev stakingPool.updateStrategyRewards is called to credit all past fees at
@audit>> 1. >> * the old rate before the percentage changes
* @param _index index of fee
* @param _receiver receiver of fee
* @param _feeBasisPoints fee in basis points
**/
function updateFee(
uint256 _index,
@audit>> 2.issue >> address _receiver,
uint256 _feeBasisPoints
) external onlyOwner {
@audit>> 3. issue>> _updateStrategyRewards();
if (_feeBasisPoints == 0) {
fees[_index] = fees[fees.length - 1];
fees.pop();
} else {
@audit>> 4. >> fees[_index].receiver = _receiver;
fees[_index].basisPoints = _feeBasisPoints;
}
if (_totalFeesBasisPoints() > 3000) revert FeesTooLarge();
}

The line `_updateStrategyRewards()` ensures that past fees are credited to the old receiver before the update, but this prevents the admin from updating the receiver address without sending fees to an invalid address.

Impact

- **Potential Loss of Funds(fees)**: If the old receiver's address is no longer valid or has been compromised, fees already accrued may be sent to this invalid or unsafe address, leading to a permanent loss of funds.

Tools Used

Manual Code Review

Recommendations

1. **Allow Address-Only Updates**: Introduce a mechanism that allows the admin to update only the receiver address without recalculating or distributing accrued fees to the old address. This ensures that old fees are not lost to invalid receivers, and the protocol maintains its integrity.

- **Example Solution**: Add a boolean flag that checks if only the receiver address is being updated. If true, skip the call to `_updateStrategyRewards()` so the fee basis points remain unaffected, and the receiver can be updated safely.

/**
* @notice Updates an existing fee
* @dev stakingPool.updateStrategyRewards is called to credit all past fees at
* the old rate before the percentage changes
* @param _index index of fee
* @param _receiver receiver of fee
* @param _feeBasisPoints fee in basis points
**/
function updateFee(
uint256 _index,
address _receiver,
uint256 _feeBasisPoints,
++ bool onlyreceiver
) external onlyOwner {
++ if(onlyreceiver) {
++ fees[_index].receiver = _receiver;
++ }
_updateStrategyRewards();
if (_feeBasisPoints == 0) {
fees[_index] = fees[fees.length - 1];
fees.pop();
} else {
fees[_index].receiver = _receiver;
fees[_index].basisPoints = _feeBasisPoints;
}
if (_totalFeesBasisPoints() > 3000) revert FeesTooLarge();
}

2. **Graceful Address Updates**: Provide an option to update the receiver address even when the old receiver is no longer available or valid, without affecting past fee accrual or the calculation of present/future rewards.

Updates

Lead Judging Commences

inallhonesty Lead Judge 11 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Inability to independently update Fee receivers without sending fees to old receivers

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.