`LiquidInfrastructureERC20::distribute90` - Should have checks to ensure zero values for `entitlement` and/or `this.balanceOf(recipient)` are not processed, to rather skip over these cases via use of `continue;` and `break;` respectively. #732
When either entitlement or this.balanceOf(recipient) is zero, there is no reason to process those cases and spend the additional gas in an already highly gas constrained function.
Recommended improvements below.
Impact:
Not implementing the suggestions below would contribute to the risk of out of gas errors.
Recommendations:
At the start of this for loop cache erc20EntitlementPerUnit[j] to local variable _erc20EntitlementPerUnit then do if (_erc20EntitlementPerUnit == 0) continue; and use the cached _erc20EntitlementPerUnit in this line; ideally do similar(but use break; instead) for recipient balance of this ERC20 in case their balance is zero.
for (i = nextDistributionRecipient; i < limit; i++) {
address recipient = holders[i];
if (isApprovedHolder(recipient)) {
uint256[] memory receipts = new uint256[](distributableERC20s.length);
+ uint256 thisBalanceOfRecipient = this.balanceOf(recipient);
+ if (thisBalanceOfRecipient == 0) break;
for (uint256 j = 0; j < distributableERC20s.length; j++) {
+ uint256 _erc20EntitlementPerUnit = erc20EntitlementPerUnit[j];
+ if (_erc20EntitlementPerUnit == 0) continue;
IERC20 toDistribute = IERC20(distributableERC20s[j]);
- uint256 entitlement = erc20EntitlementPerUnit[j] * this.balanceOf(recipient);
+ uint256 entitlement = _erc20EntitlementPerUnit * thisBalanceOfRecipient; /// GAS optimization
if (toDistribute.transfer(recipient, entitlement)) {
receipts[j] = entitlement;
}
Lines of code
https://github.com/code-423n4/2024-02-althea-liquid-infrastructure/blob/3adc34600561077ad4834ee9621060afd9026f06/liquid-infrastructure/contracts/LiquidInfrastructureERC20.sol#L194
Vulnerability details
When either
entitlement
orthis.balanceOf(recipient)
is zero, there is no reason to process those cases and spend the additional gas in an already highly gas constrained function. Recommended improvements below.Impact:
Recommendations:
At the start of this
for
loop cacheerc20EntitlementPerUnit[j]
to local variable_erc20EntitlementPerUnit
then doif (_erc20EntitlementPerUnit == 0) continue;
and use the cached_erc20EntitlementPerUnit
in this line; ideally do similar(but usebreak;
instead) forrecipient
balance of this ERC20 in case their balance is zero.Assessed type
Invalid Validation