This is a broad recommendation but it would save gas to declare internal functions, that would be called in external functions, instead of declaring all external functions as public to be able to reuse them in internal functions.
For example, we could have an internal _asset function:
wfCashERC4626.sol
convertToShares:
unitfCashValue
should be inlinedIn the
convertToShares
function, we storeunitfCashValue
in theunitfCashValue
variable on line 56.This value being only used once, we can inline it and save one mstore.
Constants.INTERNAL_TOKEN_PRECISION
being used twice, we can store it in a variable to avoid sloading and also casting touint256
twice.Recommendation:
convertToShares: the variable totalSupply should be re-used
In the
convertToShares
function,totalSupply()
is stored in thetotalSupply
variable on line 53.This variable should also be used to compute the amount of shares instead of calling
totalSupply()
again on line 60This change allows us to save 94 gas units.
Recommendation:
redeem: asset() should be stored in a variable and balanceAfter inlined
In the
redeem
function,asset()
is being called twice, on line 212 and line 219;We can store it in a variable and save one sload.
Recommendation:
balanceAfter
being only used once, we can inline it and save one mstore.Recommendation:
Use internal functions instead of public ones
This is a broad recommendation but it would save gas to declare internal functions, that would be called in external functions, instead of declaring all external functions as public to be able to reuse them in internal functions.
For example, we could have an internal
_asset
function:We can then call this
_asset
function in theredeem
function:wfCashLogic.sol
_sendTokensToReceiver: balanceAfter can be inlined
In the
_sendTokensToReceiver
function, we storebalanceAfter
in thebalanceAfter
variable on line 304.This variable being only used once, we can inline it and save one mstore.
Recommendation:
NotionalTradeModule.sol
_mintFCashPosition: preTradeSendTokenBalance and preTradeReceiveTokenBalance can be inlined
In the
_mintFCashPosition
function, we storepreTradeSendTokenBalance
andpreTradeReceiveTokenBalance
variables on lines 435 and 436.These variables being only used once, we can inline them in the
_updateSetTokenPositions
call and save two mstore.Recommendation:
_mint: minImpliedRate can be inlined
In the
_mint
function, we storeminImpliedRate
in a variable on line 519.This variable being only used once, we can inline it in the
encodeWithSelector
call and save one mstore.Recommendation:
_redeemFCashPosition: toUnderlying, preTradeReceiveTokenBalance and preTradeSendTokenBalance can be inlined
In the
_redeemFCashPosition
function, we storetoUnderlying
,preTradeReceiveTokenBalance
andpreTradeSendTokenBalance
variables from lines 469 to 471.These variables being only used once, we can inline them in the
_updateSetTokenPositions
call and save three mstore.Recommendation:
_redeemMaturedPositions: fCashBalance can be inlined
In the
_redeemMaturedPositions
function, we storefCashBalance
in a variable on line 404.This variable being only used once, we can inline it in the
_redeemFCashPosition
call and save one mstore.Recommendation:
initialize: modules.length should be stored in a variable
In the
initialize
function, we loop throughmodules
in the for loop from line 238 to 240.modules.length
should be stored in a variable to avoid doing a mload every time the for loop is ran.Recommendation:
removeModule: modules.length should be stored in a variable
In the
initialize
function, we loop throughmodules
in the for loop from line 254 to 258.modules.length
should be stored in a variable to avoid doing a mload every time the for loop is ran.Recommendation: