Hello, I recently got feedback on a smartcontract to locally cache storage values inside variables to save some gas.
Before:
function getTotalClaimableRewards() external view override returns (uint256) {
if (address(_rewardToken) == address(0)) {
return 0;
}
address[] memory assets = new address[](1);
assets[0] = address(_aToken);
uint256 freshRewards = _incentivesController.getUserRewards(
assets,
address(this),
address(_rewardToken)
);
return _rewardToken.balanceOf(address(this)) + freshRewards;
}
After:
function getTotalClaimableRewards() external view override returns (uint256) {
address rewardToken = address(_rewardToken); // local caching of storage
if (rewardToken == address(0)) {
return 0;
}
address[] memory assets = new address[](1);
assets[0] = address(_aToken);
uint256 freshRewards = _incentivesController.getUserRewards(
assets,
address(this),
rewardToken
);
return IERC20(rewardToken).balanceOf(address(this)) + freshRewards;
}
I was super surprised to see that this actually has meaningful effects on the functions gas consumption. Shouldn’t it be relatively easy for the compiler to optimize this? I would assume static code analysis could easily detect that:
-
rewardToken
isn’t mutated - there’s space left on the stack
What’s the reason for not optimizing this away in the compiler?
(Tested on solc Version: 0.8.10+commit.fc410830.Linux.g++
)