The _calcCvxIntegral() function in ConvexStakingWrapper.sol doesn't use the same gas optimization that its sibling function _calcRewardIntegral() uses.
if (_isClaim || userI < cvxRewardIntegral) {
uint256 receiveable = cvx_claimable_reward[_accounts[u]] +
((_balances[u] * (cvxRewardIntegral - userI)) / 1e20);
if (_isClaim) {
if (receiveable > 0) {
cvx_claimable_reward[_accounts[u]] = 0;
IERC20(cvx).safeTransfer(_accounts[u], receiveable);
bal = bal - (receiveable);
}
} else {
cvx_claimable_reward[_accounts[u]] = receiveable;
}
cvx_reward_integral_for[_accounts[u]] = cvxRewardIntegral;
}
The related code from the _calcRewardIntegral() function has the receivable calculation inside the if (_isClaim) code branch to save gas if _isClaim is false.
This optimization would save gas each time _checkpoint() is called because _checkpoint() sets _isClaim to false and doesn't enter the if(_isClaim) branch.
Recommended Mitigation Steps
Modify the _calcCvxIntegral() function to place the receiveable calculation inside the if (_isClaim) code branch.
Handle
sirhashalot
Vulnerability details
Impact
The
_calcCvxIntegral()
function in ConvexStakingWrapper.sol doesn't use the same gas optimization that its sibling function_calcRewardIntegral()
uses.Proof of Concept
This code is from the
_calcCvxIntegral()
functionThe related code from the
_calcRewardIntegral()
function has the receivable calculation inside theif (_isClaim)
code branch to save gas if _isClaim is false.This optimization would save gas each time
_checkpoint()
is called because_checkpoint()
sets _isClaim to false and doesn't enter theif(_isClaim)
branch.Recommended Mitigation Steps
Modify the
_calcCvxIntegral()
function to place the receiveable calculation inside theif (_isClaim)
code branch.