The RWAVotingEscrow::split function will inefficiently perform two shares.length loops; once for calculating the sum of shares and once for the actual split of the NFT.
Example:
for (uint256 i = len; i != 0;) {
unchecked {
--i;
}
totalShares += shares[i];
}
// fetch voting escrow data storage
VotingEscrowStorage storage $ = _getVotingEscrowStorage();
// fetch remaining duration of tokenId
uint256 remainingVestingDuration = $._remainingVestingDuration[tokenId];
// fetch lockedBalance of tokenId
uint256 lockedBalance = $._lockedBalance[tokenId];
// store lockedBalance in another var (will be used later)
uint256 remainingBalance = lockedBalance;
// find timestamp of current block
uint48 mintingTimestamp = clock();
// start iterating through shares array
for (uint256 i = 1; i < len;) {
// grab current share
uint256 share = shares[i];
// locked balance for this NFT is percentage of shares * total locked balance
uint256 _lockedBalance = share * lockedBalance / totalShares;
Recommendation:
We advise the function to instead accept the totalShares as an argument, validating it after the for distribution loop concludes by summing it alongside the distributions.
RWV-06C: Potentially Inefficient Summation of Shares
Description:
The
RWAVotingEscrow::split
function will inefficiently perform twoshares.length
loops; once for calculating the sum of shares and once for the actual split of the NFT.Example:
Recommendation:
We advise the function to instead accept the
totalShares
as an argument, validating it after thefor
distribution loop concludes by summing it alongside the distributions.