Liquid Staking

Stakelink
DeFiHardhatOracle
50,000 USDC
View results
Submission Details
Severity: low
Invalid

Splitters Can Be Constructed With Fees That Break Maximum Basis Point Invariants

Summary

The __totalFeesBasisPoints of the LSTRewardsSplitter must not be allowed to surpass 10_000, however this is not enforced on construction.

Vulnerability Details

Fees for an LSTRewardSplitter may never exceed 10_000 in total:

/**
* @notice Sdds a new fee
* @param _receiver receiver of fee
* @param _feeBasisPoints fee in basis points
**/
function addFee(address _receiver, uint256 _feeBasisPoints) external onlyOwner {
fees.push(Fee(_receiver, _feeBasisPoints));
if (_totalFeesBasisPoints() > 10000) revert FeesExceedLimit();
}

However, this limit isn't forced upon construction:

constructor(address _lst, Fee[] memory _fees, address _owner) {
controller = ILSTRewardsSplitterController(msg.sender);
lst = IERC677(_lst);
for (uint256 i = 0; i < _fees.length; ++i) {
fees.push(_fees[i]);
}
_transferOwnership(_owner);
}

Neither is this enforced by the LSTRewardsSplitterController:

/**
* @notice Deploys a new splitter
* @param _account address of account to deploy splitter for
* @param _fees list of splitter fees
*/
function addSplitter(
address _account,
LSTRewardsSplitter.Fee[] memory _fees
) external onlyOwner {
if (address(splitters[_account]) != address(0)) revert SplitterAlreadyExists();
address splitter = address(new LSTRewardsSplitter(lst, _fees, owner()));
splitters[_account] = ILSTRewardsSplitter(splitter);
accounts.push(_account);
IERC677(lst).safeApprove(splitter, type(uint256).max);
}

Consequently, the invariant is not respected.

Impact

Broken composablity of LstRewardsSplitter resulting in potentially undue excess fees.

Tools Used

Manual Review

Recommendations

Instead of manually assigning the fees, use addFee in the constructor to implictly enforce the upper bound on fees:

constructor(address _lst, Fee[] memory _fees, address _owner) {
controller = ILSTRewardsSplitterController(msg.sender);
lst = IERC677(_lst);
for (uint256 i = 0; i < _fees.length; ++i) {
- fees.push(_fees[i]);
+ addFee(_fees[i].reciever, _fees[i].basisPoints);
}
_transferOwnership(_owner);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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